--- url: /Changelog.md --- # ✨ Changelog > 📝 本页记录 Home Assistant OS 极速版除官方更新外的所有优化与变更。由于系统版本号与官方同步,部分更新将在下一个 OTA 版本(或全新安装时)生效,非实时生效。 > 📝 有些更新并非一开始没有优化到位,是随着官方的升级导致的一些对国内使用有影响的内容需要重新优化 :::tip 2026年10月8日 ❌ 优化:移除 `HACS 自动安装`,自官方 `2026年11月` 版本起已内置 HACS,无需再自动安装 ::: :::tip 2026年5月16日 📦 优化:增加完整镜像包版本,提升新用户安装与初始化的体验 ::: :::info 2026年4月26日 🐳 优化:更新 Docker 镜像,兼容新版 Docker 环境 ::: :::tip 2025年10月7日 🛠️🇨🇳 优化:增加`Beta`通道,方便尝鲜用户可以跟`官方稳定版`同步,默认版本不受影响,还是保留一个月一次的更新频率 ::: :::tip 2025年9月30日 🐳🇨🇳 优化:因公共镜像源的限制与不稳定,将主要的系统镜像地址迁移至`自有服务器` ::: :::tip 2025年9月19日 🔗🇨🇳 优化:因官方代码添加,修正一处`默认镜像`地址链接 ::: :::tip 2025年9月17日 🔄 优化:因原服务器赞助商停机,新服务器赞助更有保障,`商业使用`将不再受限 🔄 优化:下一个系统版本会将商业限制改成赞助商致谢 ::: :::tip 2025年8月19日 🚦🇨🇳 优化:移除一处`加载项的的定义`,提升启动运行速度 ::: :::tip 2025年8月6日 🛠️🇨🇳 优化:将 OS 错误日志上报切换至国内`自有服务器` ::: :::tip 2025年7月10日 🐳🇨🇳 优化:将加载项构建隔离镜像 `docker.io/library/docker` 迁移至 `docker.m.daocloud.io/library/docker`,加速构建体验 ::: :::info 2025年6月18日 🐳 新增:在系统底层集成 [`docker hub`](https://github.com/dongyubin/DockerHub) 镜像,显著提升国外加载项的安装成功率 ::: :::note 2025年6月8日 ⏰ 优化:将系统终端默认时区调整为 `Asia/Shanghai` ::: :::warning 2025年4月24日 ⚠️ 新增:系统终端页面增加`商业使用限制`声明 ::: :::warning 2025年4月12日 ⚡ 优化:HACS 极速版下载逻辑,优先检测公网网络,仅在可用时进行下载 ::: :::warning 2025年4月8日 ⏳ 优化:将系统默认时间同步服务器由 `time.cloudflare.com` 迁移至国内 `cn.ntp.org.cn` ::: :::info 2025年4月7日 🚀 优化:内置 HACS 极速版下载源由 GitHub 切换至`自有服务器`,下载速度大幅提升 ::: :::tip 2025年4月5日 🔒 修复:解决证书不一致导致无法 OTA 的问题 ::: :::tip 2025年4月1日 🗜️ 新增:系统底层支持解压 zip 文件(支持预装集成时自动解压) 🛡️ 优化:网络检测服务迁移至`国内`自购服务器(阿里云) 🏫 优化:镜像拉取服务迁移至[`南京大学`](https://mirror.nju.edu.cn/)节点 🔄 优化:OTA 升级服务全面迁移`至国`内自购服务器(阿里云) ⚡ 优化:系统下载地址优化至`国内`高速节点 ❌ 优化:移除不稳定的 `官方加载项源` ❌ 优化:移除不稳定的 `官方社区源` ❌ 优化:移除不稳定的 `Music Assistant 源` ❌ 优化:移除不稳定的 `ESP Home 源` ✅ 新增:添加经过全面优化与汉化的 [`默认加载项源`](/addoncn.md)(上述移除内容均已包含在内) ::: *** :::note 🚩 感谢每一位支持和参与的朋友,未来我们一起见证更多精彩! ::: --- url: /MajorEvents.md --- # ✨ 主要事件 :::note 历史回顾 记录 Home Assistant 中文站以及公众号发展历程的重要时刻 ::: *** :::tip 2024年10月 开始撰写 Home Assistant 公众号,并取名:`老王杂谈说` ::: :::tip 2024年10月 创建第一份`加载项商店` ::: :::tip 2025年1月 将国内外重要的加载项`全收集到一起`,并做了`国内优化加速`及`AI翻译` ::: :::tip 2025年3月 建立Home Assistant `中国版汉化网站` ::: :::tip 2025年3月 发布首版 `Home Assistant OS 极速版`(内测版) ::: :::tip 2025年4月初 发布 `Home Assistant OS 极速版`(公测版) ::: :::tip 2025年4月末 发布 `Home Assistant OS 极速版`(正式版) ::: :::tip 2025年5月 受委托,举办 `Home Assistant Community Day` [官网链接](https://www.home-assistant.io/blog/2025/06/24/community-day-2025-wrap-up/) ::: :::tip 2025年6月 受邀为易微联适配 `Sonoff iHost` 的 Home Assistant OS 极速版 ::: :::tip 2025年8月 大量开源内容被人盗用占为己有,联系抄袭方标明出处均未得到有效回复,于是决定`只开源`,不开放系统与加载项的`构建流程` ::: :::tip 2025年9月 Home Assistant OS 极速版重要服务器迁移到 `自架服务器`,不再依赖于公共服务器,服务器赞助商改为`深圳酷宅科技有限公司` ::: :::tip 2025年11月 受`浙江省科企新质生产力研究院`邀成为特约嘉宾,共话下一代家居体验。[新闻报道](https://www.chinanews.com.cn/cj/2025/11-06/10511171.shtml) ::: :::tip 2026年3月10日 举办中国第二届 `Home Assistant Community Day` [官网链接](https://newsletter.openhomefoundation.org/why-were-investing-in-the-human-touch/) ::: :::tip 2026年9月21日 作为`全国唯一`受邀者,出席 `OpenHomeFoundation Summit 2026` [公众号推文](https://mp.weixin.qq.com/s/SIrpfMTtwuxvi_-S1i4Xxg) ::: *** :::note 🚩 感谢每一位支持和参与的朋友,未来我们一起见证更多精彩! ::: --- url: /QandA.md --- # Home Assistant OS 极速版 :::info 名称由来 中文名:`Home Assistant OS 极速版` 名称剽窃自《HACS极速版》因为HACS极速版就是加速了HACS的连接与使用,我这OS也是一样的作用 英文名:`🇨🇳 Home Assistant OS Turbo` 一方面体现速度上的优势,另一方面标识中国 ::: :::tip 为什么制作极速版? 看到太多的网友没法正常使用 Home Assistant 原版,无论是系统初始化,还是升级,因此力所能及的想做一些方便大家的事情。 ::: :::tip 这个版本和官方原版有什么区别? 除了下载静像换成了国内的,确实有一些区别 (目的只有一个,为了加速),具体可参考[这里](/haoscn.md) 或者[这里](/Changelog.md) 移除了所有国内不稳定或者无法访问的官方自带的应用源( [官方应用](https://github.com/home-assistant/addons) ,[官方社区应用](https://github.com/hassio-addons/repository) ,[音乐助手](https://github.com/music-assistant/home-assistant-addon)),换成了加速源 [查看链接](https://gitcode.com/ha-china/ha-apps) 同时集成了极速版HACS(Alone)[HACS China](https://github.com/hacs-china) 免github帐号,免科学无损使用HACS ::: :::tip 国内已经有冬瓜版了,你为什么重复劳动? 我有系统洁癖,包括也有很多网友有跟我一样的问题,只喜欢原版系统,冬瓜闭源,我看不到系统里到底改了什么。 ::: :::tip 这个版本和冬瓜的版本有什么区别? 最大的区别就是闭源与开源的区别,具体我不知道,我没有办法去评估一个闭源的产品代码里具体有什么。 ::: :::tip 目前支持哪些硬件?将来会不会适配官方以外的硬件? 目前仅编译了官方默认支持的硬件,等版本稳定之后,会考虑编译更多的固件。但是因为手里没有对应的硬件,所以这个进度可能不会太快,当然如果有人正好手里有,能提交到我的仓库,这样进度会快一点。 ::: :::tip 会有Docker极速版吗? 不会!Docker版跟我系统里的Core一模一样,都是拉取官方的镜像,所以你只要会找加速镜像站就可以安装Docker版。会提出这个问题的人,说明还有没有达到使用Docker版的技术能力,建议你直接使用OS。 ::: :::tip 系统开源吗? 现在开,未来也开,**一直开源** [Github 地址](https://github.com/ha-china/HAOS-CN),但不保证整个`编译过程`是是开放的,以防止有心之人占为己有(已有发生) ::: :::tip 为什么选择开源,没选择闭源? 我喜欢共享 让那些认为我系统里有后门的网络傻X闭嘴 ::: :::tip 这个加速方案会失效吗? 应该不会,系统里只能做一个加速方案,手头有备用链接 ::: :::tip 如果公开的加速方案都失效了怎么办? 我会去寻求赞助(不仅仅是服务器的赞助,还有技术支持的赞助)采用自建服务器的方式来部署 ::: :::tip 现有的源如果失效,切换系统源需要重新安装吗? 不需要 ::: :::tip 你会停更这个系统吗 不会,95%以上的步骤全部自动化。哪怕我别的事忙的不可开交,这个系统也能自动编译分发。 ::: :::tip 我是公司可以用这个免费系统吗 可以,如果你愿意[支持项目](/sponsor.md)一直持续下去,在下感激不尽。 ::: :::tip 这系统将来会商业化吗 不会,就像我上一个问题答案,这个系统大量的资源都是取自于其它人或者组织的贡献,一方面我没有脸拿这个去赚钱,另一方面这跟我推动Home Assistant在中国的发展相违背 就算商业化,在保留开源版本的前提之下另起分支,加入定制功能,这样既能保证开源版本的稳定性,又能保证商业版本的定制性。 ::: :::tip 你现在最缺的资源是什么 有爱的人,有能力有设备能适配机型愿意奉献的人才。 ::: --- url: /about.md --- # 🏠 关于 :::tip 📱 关于我 一个开源界的混子,IT运维及管理背景,非专业码哥,技术只是纯兴趣 ::: ## 🎯 建站初衷 * **🌐 本土化支持**:方便用户快速找到并使用本土化内容 * **🚀 简化使用**:让用户无需复杂知识即可轻松上手 Home Assistant ## 🌟 项目说明 * **🎯 项目性质**:非盈利个人项目,专注知识分享与经验交流 * **🚀 项目目标**:打造最适合中国用户的Home Assistant学习平台 * **💡 项目特色**:本土化优化,解决国内用户使用痛点 * **🤝 参与方式**:欢迎贡献与反馈,共建Home Assistant社区 ## 📚 内容说明 * **📖 文档状态**:持续更新中,部分内容可能尚未完成翻译 * **🕒 更新频率**:根据用户需求调整优先级不定期更新 * **📝 翻译支持**:如需特定内容翻译,请通过微信公众号联系我们 ## ⚖️ 版权声明 * **©️ 原内容版权**:归原作者所有 * **📜 翻译版权**:归《老王杂谈说》所有 * **🔗 引用说明**:引用时请注明出处,尊重原作者劳动成果 ### 微信公众号 ![微信公众号二维码](./images/WeChat_QRCode.png) --- url: /addoncn.md --- # 🇨🇳 Home Assistant 应用源 欢迎使用专为国人优化的 Home Assistant 应用库!这里收录优质第三方作品以及本人开发的作品。 * 🐳 **高效便捷,无需魔法,开箱即用** * 💬 **欢迎留言建议,定制你需要的应用** * ✉️ **如有侵权请联系,第一时间处理** * 🌐 **所有内容仅为提升国人用户体验,保障网络畅通** * ⚠️ **请合法合规使用,因个人操作产生的后果自负** * 🚫 **不收录逆向、模拟登录、侵权及违法内容** ## 📥 安装指南 :::tip 以下方法二选一即可,如果已经用了 `Home Assistant OS 极速版`,则无需安装,已内置 ::: ### 🚀 方法一:手动添加仓库 1. 🔍 **进入** Home Assistant 实例 2. ⚙️ **导航至** `设置` → `应用` → `应用商店` 3. 📂 **点击右上角** ⋮(更多选项),选择 `仓库` 4. 📋 **复制下方仓库地址,粘贴到输入框,点击添加** ➕ ```text https://gitcode.com/ha-china/ha-apps.git ``` 5. ✅ **现在,仓库中的所有应用都可以在应用商店中直接安装啦!** *** ### ✨ 方法二:一键自动添加 [![添加应用到 Home Assistant](https://img.shields.io/badge/Home%20Assistant-Apps-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https://gitcode.com/ha-china/ha-apps.git) 点击上方按钮,自动将仓库添加到您的 Home Assistant,无需手动复制粘贴。 *** ### 🛠️ 支持与反馈 如在使用过程中遇到任何问题或有疑问,欢迎在**公众号后台留言**,我会尽快回复您。\ 📩 **感谢您的支持!** --- url: /blueprints.md --- # 🌐 Blueprints (Blueprints) 汉化资源库 欢迎来到 **Home Assistant Blueprints 汉化资源共享库**! 这里收集和分享各类 Home Assistant Blueprints 的中文汉化版本,欢迎大家积极参与贡献与交流。 *** ## 📦 Blueprints 目录 ### 💡 灯光控制 | 蓝图名称 | 一键导入 | |---------|---------| | 【灯光】传感器灯光 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FLights-Sensor-Light.yaml) | | 【灯光】手动灯光 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FLights-Manual-Light.yaml) | | 【灯光】智能灯光 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FLights-Smart-Light.yaml) | | 【灯光】色温选择器 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FLights-Color-Temperature-Selector.yaml) | | 传感器灯光拓展 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FSensor-Light-Extended.yaml) | | 智能照明 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FSmart-Lighting.yaml) | | 运动感应灯 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FMotion-Sensor-Light.yaml) | | 传感器灯光 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FSensor-Light.yaml) | | 手动灯光 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FManual-Light.yaml) | | 智能灯光 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FSmart-Light.yaml) | | 区域色温选择器 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FArea-Color-Temperature-Selector.yaml) | ### 🔌 开关控制 | 蓝图名称 | 一键导入 | |---------|---------| | 【开关】按下按钮 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FSwitches-Press-Button.yaml) | | 【开关】切换开关控制 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FSwitches-Toggle-Switch-Control.yaml) | | 【开关】多开关联动控制 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FSwitches-Multi-Gang-Linkage-Control.yaml) | | 【开关】Sonoff无线按钮 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FSwitches-Sonoff-Wireless-Button.yaml) | | 【开关】领普H2 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FSwitches-Linptek-H2.yaml) | | 【开关】领普KS1Pro | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FSwitches-Linptek-KS1Pro.yaml) | | 【开关】领普KS2 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FSwitches-Linptek-KS2.yaml) | | 【开关】米家8键开关 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FSwitches-Mijia-8-Key-Switch.yaml) | | 【开关】小燕白鹭开关 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FSwitches-Xiaoyan-Egret-Switch.yaml) | | Hue旋钮开关 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FHue-Dial-Switch.yaml) | | 小燕智能开关 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FXiaoyan-Smart-Switch.yaml) | | 切换开关 - 打开和关闭实体 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FToggle-Switch-Open-Close-Entity.yaml) | | 开关 - 开启和关闭实体 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FSwitch-Turn-On-Off-Entity.yaml) | | 按下按钮 - 开关实体 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FPress-Button-Switch-Entity.yaml) | ### 📅 定时任务 | 蓝图名称 | 一键导入 | |---------|---------| | 【定时】定时器 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FTimers-Timer.yaml) | | 【定时】触发器定时运行 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FTimers-Trigger-Scheduled-Run.yaml) | | 【定时】实体运行计时器 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FTimers-Entity-Runtime-Timer.yaml) | | 定时器 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FTimer.yaml) | | 触发器 - 定时运行 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FTrigger-Scheduled-Run.yaml) | | 实体 - 运行计时器 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FEntity-Runtime-Timer.yaml) | ### 📢 通知提醒 | 蓝图名称 | 一键导入 | |---------|---------| | 【通知】通知与公告 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FNotifications-Notification-Announcement.yaml) | | 【通知】低电量通知与动作 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FNotifications-Low-Battery-Notification-Action.yaml) | | 【通知】门窗通知 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FNotifications-Door-Window-Notification.yaml) | | 通知和公告 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FNotification-and-Announcement.yaml) | | 摄像头快照 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FCamera-Snapshot.yaml) | | 接触传感器通知 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FContact-Sensor-Notification.yaml) | | 家电通知 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FAppliance-Notification.yaml) | | 电量通知与自动化 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FBattery-Notification-Automation.yaml) | | 低电量通知与动作 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FLow-Battery-Notification-Action.yaml) | | 通知与公告 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FNotification-Announcement.yaml) | ### 🏠 家电控制 | 蓝图名称 | 一键导入 | |---------|---------| | 【空调】智能净化器 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FAir-Conditioners-Smart-Purifier.yaml) | | 【空调】智能空调 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FAir-Conditioners-Smart-AC.yaml) | | 【空调】窗户联动控制 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FAir-Conditioners-Window-Linkage-Control.yaml) | | 多设备状态联动 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FMulti-Device-Status-Linkage.yaml) | | 卷帘控制自动化 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FRoller-Shade-Control-Automation.yaml) | | 卫生间排气扇 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FBathroom-Exhaust-Fan.yaml) | ### 📹 摄像头监控 | 蓝图名称 | 一键导入 | |---------|---------| | 【摄像头】AI智能分析 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FCameras-AI-Smart-Analysis.yaml) | | 【摄像头】相机通知 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FCameras-Camera-Notification.yaml) | ### 🌡️ 环境舒适度 | 蓝图名称 | 一键导入 | |---------|---------| | ASHRAE 55 自适应舒适度 v2 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2Fashrae55_adaptive_comfort_v2.yaml) | ### 🪟 窗帘控制 | 蓝图名称 | 一键导入 | |---------|---------| | 【窗帘】智能窗帘 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FCurtains-Smart-Curtain.yaml) | ### ⚙️ 系统管理 | 蓝图名称 | 一键导入 | |---------|---------| | 【系统】HACS更新管理 | [![导入](https://img.shields.io/badge/导入-Blueprint-41BDF5?style=for-the-badge\&logo=home-assistant\&logoColor=white)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgitee.com%2Fha-china%2FTranslated%2Fraw%2Fmaster%2FBlueprints%2FSystem-HACS-Update-Management.yaml) | *** ## 📥 使用说明 点击对应蓝图名称可预览源码,点击"导入"按钮可自动将蓝图导入到你的 Home Assistant 实例中。 *** 感谢你的参与和贡献,让更多国人更好地体验 Home Assistant 自动化的乐趣! --- url: /brand.md --- # 🏷️ 直接支持接入 Home Assistant 的品牌 :::info 什么是“直接支持”? `直接支持`指在中国地区,用户可以非常轻松、直接买到的品牌或协议设备。 部分开放协议(如 Zigbee、Z-Wave、Wi-Fi 等)涵盖品牌众多,无法一一列举 只记录开放标准可以轻松接入的,不收录需要通过复杂的逆向工程以及模拟登录等产品 ::: ## 🏆 国内常见`直接支持`的主流品牌(持续补充中) | 品牌/协议/接入方式 | 典型产品 | 网址 | 备注 | |:--------:|:--------:|:-----|:-----| | Matter | | | | | 公版zigbee 3.0 | | | | | KNX | | | | | Z-WAVE | | | | | Modbus (485) | | | | | BT-Home | | | | | BLE | | | 不是所有的BLE都可以,对应生态环境的BLE才行 | | 易微联 、 Sonoff | | | | | Apple (HomeKit) | | | 苹果 | | MQTT | | | 部分需要自定义转化成实体 | | ESPHome | | https://www.esphome.io/ | Home Assistant的亲儿子 | | Tuya | | | 涂鸦生态 | | Xiaomi | | | 小米生态 | | Aqara | | | | | RSTP / ONVIF | | | 支持接入的摄像头协议 | :::danger 什么是“不支持”? `不支持`是指不能在合法合规的前提下顺利接入Home Assistant ::: ## 🚫 国内常见~~不支持~~的主流品牌(持续补充中) | 品牌/协议/接入方式 | 典型产品 | 网址 | 备注 | |:--------:|:--------:|:-----|:-----| | 私有 Zigbee | | | | | 私有 BLE | | | | | 私有 485 | | | | | Tmall | | | 天猫生态 | | Huawei | | | 华为生态 | --- url: /community.md --- # 🎉 加入社群 & 联系我 ## 📲 扫码加好友 :::tip 请注意 有太多的朋友只是填了表,未加好友,导致我无法将他拉入群聊,因此将二维码放顶上,记得先加好友再填表。 ::: ![community](./images/community.png) ## 📝 申请表 * ✅ **解释**:因为有不同的人有不同的需求联系我,为了节约大家时间,以申请表的方式申请 * ✅ **填写申请表**:[点击填写](https://doc.weixin.qq.com/smartsheet/form/1_wp930jdgAAJHCjP6OsrJLjdS6j2eVFeg_7a6361) (`手机端请在微信中打开此链接`) > 申请`玩家进阶群`请认真阅读本页面全部内容,并按要求填写申请表 * ✅ **扫码添加管理员**:页面底部有管理员二维码 ## 📋 入群须知 * ✅ **关注本公众号**:[扫码关注](/about.md#微信公众号) * ✅ **明确身份**(商家/个人)\ *注:商家指以Home Assistant为商业化产品盈利的机构或公司* > ⚠️ **注意:**\ > 根据之前的教训:为避免只为了问一个眼前的问题,解决完了就成僵尸了,然后真正想要一起沟通的人被分割在了2个群,特在`玩家进阶群`中增加了`入群门槛`,让真正想进群沟通的人能在一个群里 *** ## 📚 社群规范 > **请大家认真阅读并遵守以下守则,共建和谐、有序、专业的社区氛围。** *** ### 🏷️ 1. 群昵称设置 * **格式:昵称(设备型号 + 系统版本)** * 例如:小王(NUC11 + HAOS)、老王(盒子 + Docker) * 商家、厂家或落地商:可以将昵称设置为店铺名或自定义昵称,如“小王店铺(NUC11 + HAOS)”、“老王公司(盒子 + Docker)” *** ### 🗣️ 2. 话题管理 * 🚫 严禁讨论违法违规内容,包括但不限于政治、宗教、色情、暴力、恐怖主义、种族歧视等 * 🌐 尽量避免分享国内无法访问的链接,更不应直接发送上述内容于群中 * ⚖️ 不讨论灰色地带内容(如抓包、逆向工程、模拟登录、爬数据等),以合规为原则 *** ### ❓ 3. 提问规范 * 🤗 此群不扫盲,扫盲问题请看第6条所提供的资源,文档不愿看的,在群里也得不到你想要的答案 * 📝 提问时请提供完整、清晰的问题描述 * 🙏 保持礼貌,感谢每一位群友的解答 * 📖 公众号已有内容请先查阅,重复问题可能不予回答 * 🖥️ 日志请用电脑版截图或上传日志文件,禁止以消息的形式大量发送 *** ### 🎁 4. 分享与推广 * 👍 欢迎分享优质产品使用心得 * 🤝 拼团链接请**先询问是否有人有需求**,询问时带上以下信息:原价、拼团价、还差多少人成团、产品介绍等 * 🚫 禁止直接发布广告,违规者首次警告,二次违规将被移除群聊 * 🛒 群友有需求且您有相关产品,可适度推荐 * 🏷️ 不要黑任何品牌,需保持客观中立。品牌名建议用“某”或“X”等字眼,不要出现具体品牌名 * 💰 个人发自家产品请先询问是否有需求,且群友价不得高于市场平台价 * 🧪 厂家/商家需玩家测评,请先询问有无人愿意,有人愿意后再发要求。测品无需付费或归还,如玩家恶意白嫖、不按要求测试,踢群处理 * 💼 厂家如需有偿服务请明码标价,尊重群友付出,禁止以“白嫖”或廉价劳动力心态寻求合作 *** ### 🤗 5. 文明交流 * 🚷 严禁任何人身攻击,包括但不限于性别、年龄、职业、地域、宗教、性取向等,杜绝一切歧视和侮辱 *** ### ⏳ 6. 问题回复 * 💬 群友均为自愿帮助解答问题,解答不代表需为问题负责 * 🕰️ 如未获及时回复,请耐心等待,可能群友正忙或问题描述过于模糊 * 🤖 公众号已接入AI助手(可直接与公众号聊天获取支持),建议先问AI助手,AI无法解决再请教群友 * 📚 知识库与资源:[HA及周边知识库](https://ima.qq.com/wiki/?shareId=65fd12acb33dba9197c9134e5bd00f703cce40a7d973dc52b76a347dee22e15f) * 🌐 中文版网站: *** ### 🚪 7. 加人/踢人规则 * 🔒 本群不接受任何邀请进群,仅限自然流量加入 * 👋 仅为加群而关注,入群后取消关注者将被移除 * ⚠️ 违反群规将立即移除群聊 * 🤖 本群由机器人代管,禁止发送不合规内容(如:小程序、语音/视频消息、聊天记录转发、消息长度超80行、10秒内连续发10条等刷屏消息) * 🧹 群满时,将根据群友活跃度和公告遵守情况随机移除,优先移除未填写同意书/不同意群公告→未改名→未关注公众号→未发言者 *** ### 🛑 8. 声明 * ✏️ 尊重劳动成果,任何群内内容未经原作者同意,禁止私自发到任何平台 * 👤 群主不参与任何群友之间的交易、纠纷、矛盾,请大家自觉遵守群规,理性交流 *** ## 📲 扫码加入 :::tip 请注意 任何上面提到的内容,未完成,或者未按要求完成的请求都将不予回复 若已经完成了,添加好友之后请发提醒:入群要求申请均已完成 ::: ![community](./images/community.png) --- url: /companion/android-auto/index.md --- # 概览 Android Home Assistant 提供 Android Auto (AA) 和 Android Automotive OS (AAOS) 体验。这允许您在驾驶时安全地与各种实体交互。它还允许您导航到任何具有关联位置的 `zone`、`person`、`sensor` 或 `device_tracker`\*。 \* 被认为在家 (`home`) 的设备追踪器实体不会显示在导航屏幕中。 ### 设置 要在车辆中使用应用,您需要登录手机(如果使用 AA)或车辆(如果使用 AAOS)。登录后,您就可以使用车辆主屏幕上的 Home Assistant 图标了。 ### 支持的可操作域 * `alarm_control_panel` 如果不需要代码,将允许 `arm_away` 和 `disarm`,否则无操作 * `button` * `cover` * `fan` * `input_boolean` * `input_button` * `light` * `lock` * `scene` * `script` * `switch` :::note 显示的实体数量取决于车辆设定的限制。 ::: ### 收藏 如果您想快速访问特定实体,可以选择它们在应用中显示。停车时,转到[设置](https://my.home-assistant.io/redirect/config/) > **伴侣应用** > **Android Auto 收藏**(或 **驾驶收藏**)并选择您想查看的实体。 :::tip 使用 Home Assistant 2025.12 或更高版本时,您还可以通过打开实体的**更多信息**(点击实体或通过溢出菜单访问)将实体设置为收藏。在**更多信息**中,选择**添加到**并选择添加驾驶收藏。您必须在希望收藏出现的设备上执行此操作。 Home Assistant 更多信息对话框添加到菜单 ::: 添加收藏后,下次在车辆中启动 Home Assistant 应用时,将显示您收藏的实体。您可以在那里切换实体、导航到实体、查看所有实体以及更换服务器。 除了添加上述支持的域之外,您还可以将 `binary_sensor` 和 `sensor` 实体添加到收藏中,以便在驾驶界面中查看它们的状态。 :::info 如果您是从 AAOS 车辆上的 Google Play 商店安装的应用,则目前无法设置您收藏的实体。在此期间,您可以自由使用 AA 应用。 ::: ### 通知 默认情况下,Home Assistant 通知不会显示在 AA 界面中。要在 AA 中显示 Home Assistant 通知,请在通知数据中添加 [`car_ui: true`](/companion/notifications/basic.md#android-auto-visibility)。通知现在将显示在您的手机上以及 AA 中。从 AA 打开通知将打开 Home Assistant 的驾驶界面。 AA 中的通知与您的手机共享设置,并且不支持所有通知功能。例如,要让通知在 AA 中显示在当前屏幕之上,通知渠道也需要设置为在手机上弹出。为获得最佳体验,建议为应在 AA 中可见的通知使用特定的[渠道](/companion/notifications/basic.md#notification-channels)。示例: ```yaml - alias: 发送门未锁警报 trigger: ... action: - action: notify.mobile_app_ data: title: "门未锁" message: "大家都离开了家,但门仍然未锁" data: car_ui: true notification_icon: "mdi:door-open" channel: "门未锁" importance: high ``` ### 传感器 AA 和 AAOS 可用的传感器在主[传感器](/companion/core/sensors.md#android-sensors)页面上有描述。以下传感器列表是 AA 和 AAOS 特有的: * [Android Auto 连接](/companion/core/sensors.md#android-auto) * [汽车传感器](/companion/core/sensors.md#car-sensors) 只有在车辆停放时才能启用或禁用传感器。如何更改启用的传感器取决于您安装应用的方式: * 从 Play Store 安装 1. 在另一台设备上,转到[**设置** > **设备与服务**](https://my.home-assistant.io/redirect/integrations/) > **设备**,然后选择您的车辆。 2. 选择您想更改的传感器,点击齿轮图标,然后打开或关闭**启用**。 3. 在车辆中启动应用以更新传感器。 4. 如果您启用了任何需要特殊权限的传感器,应用将发布通知以完成启用。点击通知打开应用,再次启用传感器并授予任何请求的权限。 * 从汽车制造商商店安装 1. 点击屏幕右上角的**原生模式**。 2. 转到**设置** > **伴侣应用** > **管理传感器**,然后启用或禁用您的传感器。 --- url: /companion/apple-watch/actions.md --- # (旧版)iOS 操作 :::info 继续之前 您可以通过将脚本/场景添加到手表[配置](/companion/apple-watch/index.md#home)来直接运行脚本和激活场景。 iOS 操作将不再获得未来支持。请迁移到其他解决方案,如 **脚本** 小部件或 Apple Watch 配置。 ::: 从 Apple Watch 触发的操作将以与 iPhone 上触发的操作相同的方式传送到 Home Assistant 事件总线,使用 `ios.action_fired` 事件,但事件的负载会略有不同以阐明事件的来源。Apple Watch 触发的操作将把 `triggerSource` 键设置为 `watch`。 在 Apple Watch 上触发的事件的 `ios.action_fired` 负载示例: ```json { "event_type": "ios.action_fired", "data": { "sourceDeviceID": "my_iphone", "actionID": "09CEA437-4585-4A97-B946-79D2C8B3145A", "sourceDevicePermanentID": "BCEE1730-E6BE-453B-B9E5-9601FA182C64", "actionName": "MyActionName", "triggerSource": "watch", "sourceDeviceName": "My iPhone" }, "origin": "REMOTE", "time_fired": "2020-06-13T14:40:43.009700+00:00", "context": { "id": "d2f58b921b2f41809af9fce444416aab", "parent_id": null, "user_id": "3831508509fe4124abaf1d144c2e8ca4" } } ``` --- url: /companion/apple-watch/complications.md --- # 复杂功能 复杂功能允许您在 Apple Watch 表盘上显示 Home Assistant 传感器的值。Home Assistant Apple Watch 应用包含适用于大多数 Apple Watch 表盘的复杂功能。 ## 前提条件 下面描述的所有模板化功能要求用户是[管理员](https://www.home-assistant.io/integrations/person/#adding-a-person-to-home-assistant)。 ## 创建复杂功能 复杂功能是通过配对 iPhone 上的 Home Assistant 伴侣应用创建的,在[配置](https://my.home-assistant.io/redirect/config/)的伴侣应用部分的 Apple Watch 页面中。 复杂功能按其位置列出,并按表盘类型分组。对于某些位置,有多个模板可用,选择位置后可以选择所需的模板。复杂功能值使用 [Jinja2 模板](https://www.home-assistant.io/docs/configuration/templating/)设置。除了设置显示文本的模板外,还可以选择图标。每行文本和图标的颜色可以独立设置。有关不同复杂功能的概述以及它们在不同表盘上的显示方式,请参阅[这些 Apple 开发者指南](https://developer.apple.com/design/human-interface-guidelines/components/system-experiences/complications/)。 ## 为新的"模块化"表盘创建复杂功能 WatchOS 9 移除了旧的"模块化"表盘,并将"信息图表模块化"重命名为"模块化"。为新的"模块化"表盘创建新复杂功能时,请从"图形"部分选择"圆形"或"矩形"。"模块化"部分中的复杂功能不再工作。 ![新复杂功能](https://github.com/user-attachments/assets/46541b65-48da-4228-8035-06b90da73689) 示例: ![图形圆形示例](https://github.com/user-attachments/assets/57a69fd3-38b7-4b48-b401-2941504515f1) ## 环形/仪表复杂功能 要设置开放式或封闭式环形复杂功能的填充程度,请将模板产生的值标准化为 `0.0` 到 `1.0` 之间的数字。值为 `0.0` 将给出一个空环,`1.0` 将给出一个满环。您可以使用如下模板来实现: ```yaml {{ (value - minimum) / (maximum - minimum) }} ``` 例如,要在设定值之间显示温度传感器: ```yaml {% set original = states("sensor.living_room_temperature") | float %} {% set minimum = 16.0 %} {% set maximum = 24.0 %} {% set adjusted = min(maximum, max(minimum, original)) %} {{ (adjusted - minimum) / (maximum - minimum) }} ``` 您也可以使最小值和最大值动态化。例如,基于当前天气预报: ```yaml {% set forecast = state_attr("weather.openweathermap", "forecast") | first %} {% set original = state_attr("weather.openweathermap", "temperature") %} {% set minimum = forecast["templow"] %} {% set maximum = forecast["temperature"] %} {% set adjusted = min(maximum, max(minimum, original)) %} {{ (adjusted - minimum) / (maximum - minimum) }} ``` 这两个示例都注意避免返回 <0 或 >1.0 的值,这正是 'adjusted' 变量所做的事情。 ## 自动更新 复杂功能大约在每小时的 :00、:15、:30 和 :45 更新;确切时间由系统决定。编辑复杂功能会立即将其同步到手表,但您可能需要启动手表应用才能更新复杂功能。 应用保持非活动复杂功能的更新,以便于切换表盘。如果 Home Assistant 应用不在您的活动表盘上,它的更新频率会低得多,您可能会发现在切换表盘时显示的是旧信息。 ## 手动更新 复杂功能也可以使用[通知命令](/companion/notifications/commands.md)进行更新。这些更新受系统限制,每天 50 次,您可以在[配置](https://my.home-assistant.io/redirect/config/)的伴侣应用部分的 Apple Watch 部分查看当前限制。 更新完全应用可能需要几秒钟或几分钟。 iOS 手动更新需要 2021.6 版本。 ```yaml - action: notify.mobile_app_ data: message: update_complications ``` :::info 使用本地推送时,通过命令手动更新尚不起作用。 ::: --- url: /companion/apple-watch/index.md --- # 概览 Home Assistant 与 Apple Watch 深度集成。您可以直接在表盘上以复杂功能的形式显示 Home Assistant 信息,并且从应用版本 2024.9 开始,可以运行脚本、激活场景和 iOS 操作。 ## 主页 从 iOS 应用版本 2024.9 开始,您现在可以使用 `脚本`、`场景` 和 `iOS 操作` 来自定义您的 Home Assistant 手表体验。 使用您的 iPhone,打开伴侣应用设置,在 **Apple Watch** 部分下查找 **配置**。如果您已经创建了 **iOS 操作**,它们将迁移到配置屏幕中。选择 **保存** 并在您的手表上重新加载。 手表配置屏幕 :::info 要求 Apple Watch 集成需要 watchOS 8。要安装 watchOS 8,您必须拥有 Apple Watch Series 3 或更新机型。您可以在[这里](https://support.apple.com/HT204507)识别您的 Apple Watch 型号。 ::: ## 复杂功能类型 Apple Watch 有多种表盘和复杂功能。参考[人机界面指南](https://developer.apple.com/design/human-interface-guidelines/complications)了解不同系列的示例以及特定复杂功能的显示方式很有帮助。您可以在复杂功能中放入 4 种主要类型的信息: * 文本,可以渲染为[模板](https://www.home-assistant.io/docs/configuration/templating/),根据模板类型以不同的字重和大小显示。 * 环形和仪表,显示为圆形线条。开放式变体显示为完整的圆,封闭式变体在图标中有具体的起始和结束位置。环形和仪表需要 `0.0`(空)到 `1.0`(满)之间的数值,并支持[模板](https://www.home-assistant.io/docs/configuration/templating/)。 * 图像可以从应用支持的 [Material Design Icons](http://materialdesignicons.com) 中选择。 :::info 支持的复杂功能类型 从 watchOS 9 开始,Apple 不再支持几种(旧版)复杂功能类型。以下复杂功能类型可用于 watchOS 9 及更高版本:图形圆形、图形角落、图形矩形和模块化大型。有关不同类型的更多详细信息,请参阅[人机界面指南](https://developer.apple.com/design/human-interface-guidelines/complications)。 ::: :::note 应用版本 环形和仪表功能在 2020.7 之前的应用版本中不起作用。 ::: --- url: /companion/carplay/index.md --- # 概览 iOS Home Assistant 提供 CarPlay 体验。这允许您在驾驶时安全地与各种实体交互。 ### 设置 要使用此集成,您需要一部 iPhone 以及支持 CarPlay 的车载信息娱乐系统。用 iPhone 登录后,您就可以使用 CarPlay 主屏幕上的 Home Assistant 图标了。 默认情况下,您不会在 CarPlay 中看到任何相关信息,您需要打开 ***伴侣应用设置 → CarPlay***,并创建您的配置。您可以选择要显示的标签页。 ### 标签页 CarPlay 有 4 个标签页: * **快速访问:** 在 CarPlay 配置中,您可以决定在 **快速访问** 标签页上显示哪些实体。 * **区域:** 方便您从家中区域访问实体。 * **控制:** 让您按域分组访问实体。 * **服务器:** 允许您在服务器之间切换。 ![CarPlay](/companion-assets/ios/CarPlay.png) ### 支持的可操作域 * `button` * `cover` * `input_boolean` * `input_button` * `light` * `lock` * `scene` * `script` * `switch` --- url: /companion/core/actions.md --- # 操作 Apple 专属 操作是一个通用系统,允许您轻松将 Home Assistant 自动化系统集成到 iOS、[Apple Watch](/companion/apple-watch/index.md) 和 CarPlay 的多个区域。 ## 创建操作 您可以在应用内部或 Home Assistant 的 `configuration.yaml` 中创建操作。 ### 在应用中创建操作 操作是在 iOS 版 Companion 应用的 [配置](https://my.home-assistant.io/redirect/config/) 页面的 Companion App 部分中的"操作"部分创建的。每个操作都有必填字段,具体取决于您的设备: * `Name`:操作的名称,将在应用触发的 [Home Assistant 事件](https://www.home-assistant.io/docs/configuration/events/) 中返回。 * `Server`:如果您连接了多个 Home Assistant 服务器,请选择操作应发送到的服务器。 * `Text`:在手机和手表上显示的描述性文本。最好保持相对简短,因为每个操作按钮的空间有限。 * `Text Color`\*:上述文本的颜色。 * `Background Color`\*:为操作创建的按钮的背景颜色。**(需要启用 `use_custom_colors`)** * `Icon`:在操作按钮的文本左侧显示的图标。 * `Icon Color`:操作按钮上图标的颜色。 * `Show in CarPlay`:布尔值,用于在 CarPlay 中显示或隐藏操作。 * `Show in Watch`:布尔值,用于在 Apple Watch 中显示或隐藏操作。 * `Use custom colors`\*\*:布尔值,用于在小部件和 Apple Watch 中启用自定义颜色。最初提供的是平铺卡片 UI,启用此选项后可以更改背景和文本颜色。(iOS App v2024.7.1 起可用) \* 需要 `use_custom_colors` 为 **true** \*\* iOS App v2024.7.1 起可用 对于三个颜色字段,通过点击每个字段中的颜色选择器圆圈来选择颜色。 ### 在 Home Assistant 中创建操作 您可以在 Home Assistant 的 `configuration.yaml` 中定义操作。这需要至少 Home Assistant 0.115 和版本 2020.6。以下是示例条目。 ```yaml ios: actions: - name: Fred background_color: "#000000" # 需要 `use_custom_colors` label: text: "Hello, World" color: "#ff0000" # 需要 `use_custom_colors` icon: icon: earth color: "#ffffff" show_in_carplay: false show_in_watch: true use_custom_colors: true ``` 颜色应为十六进制格式,图标应来自 [mdi](https://materialdesignicons.com/) 图标集。 保存这些更改后,您需要重启 Home Assistant,然后在 Companion 应用中,进入 [配置](https://my.home-assistant.io/redirect/config/) 的 Companion App 部分的"操作"部分。它应该会自动同步,但您也可以下拉刷新来同步。 当多个服务器连接到应用时,无需在 `configuration.yaml` 中指定 `server` 值,应用会在导入时自动检测操作的来源。 ## 使用操作 填写完所有操作数据(文本、名称等)后,点击 **创建自动化** 按钮。 *或者:* 当按下操作按钮时,Home Assistant 的事件总线上会触发 `ios.action_fired` 事件。事件数据由与操作相关的属性组成的 JSON 格式字典组成。 | 属性 | 值 | | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `context` | 与触发事件的用户和事件 ID 相关的子字典 | | `data` | 包含有关操作及其来源的关键信息的子字典 | | `event_type` | 始终为 `ios.action_fired` | | `origin` | 始终为 `REMOTE` | | `time_fired` | 操作触发的时间,格式为 [ISO 时间戳](https://en.wikipedia.org/wiki/ISO_8601),例如拉普兰(东欧时间,UTC+2)圣诞节午夜的格式为 `2019-12-25T00:00.000000+02:00`。 | `data` 中包含的属性有: | 属性 | 值 | | ------ | ------ | | `actionID` | 操作的唯一标识符。 | | `actionName` | 在 iOS 中创建操作时在 `Name` 字段中给出的操作名称,或在 Android 中使用 `action` 字段时给出的名称。 | | `sourceDeviceID` | 在您设备的 [配置](https://my.home-assistant.io/redirect/config/) 的 Companion App 部分中设置的设备 ID。 | | `sourceDeviceName` | 触发操作的设备名称。这是在 iOS 的设置应用 > 通用 > 关于本机中设置的设备名称,或在 Android 中是在设置 > 关于手机中设置的。 | | `sourceDevicePermanentID` | 触发操作的设备的唯一标识符 | | `triggerSource` | 操作从 iOS 的哪个部分触发。可能是:`widget`(今日屏幕)、`appShortcut`(通过 3D Touch 访问的快捷操作)或 `watch`(从 Apple Watch 触发)。从 Apple 的 CarPlay 触发时,来源将是 `carPlay`。 | `context` 中包含的属性有: | 属性 | 值 | | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | | `id` | 事件的一次性唯一 ID。 | | `parent_id` | 始终为 `null`。 | | `user_id` | 用于授权 Companion 应用与 Home Assistant 连接的 [用户 ID](https://www.home-assistant.io/docs/authentication/#user-accounts)。 | 操作可用于触发 Home Assistant 中的自动化。示例 `configuration.yaml` 条目可能如下: 示例 ```yaml automation: - alias: "操作关闭灯光" initial_state: true trigger: - platform: event event_type: ios.action_fired event_data: actionName: "睡觉时间" action: - action: light.turn_off entity_id: group.all_lights ``` 请注意,位于 `data` 和 `context` 中的属性分别通过自动化中的 `event_data` 和 `event_context` 访问。 您可以使用 Home Assistant 开发者工具中的事件页面,通过订阅 `ios.action_fired` 并从您的设备触发操作来显示特定事件包含的所有信息。 ## Apple Watch [Apple Watch 应用](/companion/apple-watch/index.md) 提供对您创建的操作的访问。在操作页面创建操作后,打开 Home Assistant 手表应用,操作列表应该会同步。在 Apple Watch 上触发的操作带有[略有不同的负载](/companion/apple-watch/actions.md)。 ## 主屏幕快捷操作 [主屏幕快捷操作](https://support.apple.com/guide/iphone/keep-apps-handy-iph414564dba/ios#iph1ffcbd691) 提供了访问您的操作的便捷快捷方式。要访问它,请在主屏幕上长按 Home Assistant Companion 应用图标。 ## 今日视图小部件 **(iOS App v2024.8 起已停用,请改用 iOS 小部件)** [今日视图小部件](https://support.apple.com/en-gb/HT207122) 是另一个可以触发操作的途径。要将 Home Assistant 小部件添加到您的今日视图: 1. 在主屏幕或锁屏界面上向右滑动。 2. 滑动到最底部,点击编辑按钮。 3. 在"更多小部件"列表中找到"Home Assistant - 操作"小部件,然后点击绿色 + 按钮添加它。 4. 按您的喜好重新排列,然后点击完成。 --- url: /companion/core/android-flavors.md --- # Android 版本 Android Android 应用提供两种不同的版本:`完整版`(full)或 `精简版`(minimal)。应用的 `完整版` 通过 [Play 商店](https://play.google.com/store/apps/details?id=io.homeassistant.companion.android) 提供,因为它需要 Google Play 服务,所以具有完整的功能集。`完整版` 同时提供正式版和[测试版](https://play.google.com/apps/testing/io.homeassistant.companion.android)。 应用的 `精简版` 不需要 Google Play 服务,可以在 GitHub 的[发布](https://github.com/home-assistant/android/releases)部分以 APK 形式获取。它也可以从 [F-Droid](https://f-droid.org/en/packages/io.homeassistant.companion.android.minimal) 安装。但是,由于 F-Droid 独立构建新版本,更新可能会有延迟。此版本不支持位置追踪。此外,以下传感器不可用:[活动传感器](/companion/core/sensors.md#activity-sensors)。 除了这两种版本,用户还可以在 GitHub 上每个拉取请求的 [actions](https://github.com/home-assistant/android/actions) 部分找到 `调试版` APK。应用的 `调试版` 可以与正式版或测试版并排安装。这允许用户帮助测试即将推出的功能和修复。`精简版` 和 `完整版` 都提供 `调试版`。
证书指纹 以下是签名证书的 SHA-256 指纹。 Play 商店/GitHub 发布版: `11:19:4B:A8:09:B4:2D:DF:0E:1A:7D:EC:68:42:A5:9C:7F:F1:11:9C:54:82:E9:5F:EB:FF:D5:C6:01:4D:AA:5A` F-Droid 发布版: `17:48:52:50:A0:3A:0F:2B:3F:29:2A:05:4F:59:5A:9E:79:4B:EE:F8:0C:F9:10:F7:B3:BB:B8:09:8A:BF:6D:50` 您可以使用 `apksigner verify --print-certs app-(full/minimal)-release.apk` 或 [AppVerifier](https://github.com/soupslurpr/AppVerifier) 与您下载的 apk / 已安装的应用进行比较
--- url: /companion/core/index.md --- # 功能概览 Home Assistant Companion 应用提供了一种便捷的方式来查看和控制您的 Home Assistant 实例,但它还通过允许您的设备作为数据源来扩展实例的功能。Home Assistant Companion 应用添加了大量 [传感器](/companion/core/sensors.md)(如电池和网络状态等)、创建一个 `device_tracker` 实体以允许从设备发送 [位置](/companion/core/location.md) 更新,并提供 [操作快捷方式](/companion/core/actions.md) 来触发脚本或自动化。 目前并非所有功能都支持 Android,但最终大多数功能都会得到支持。查找 Android Android 标志以查看当前支持的功能。 ## 功能对比:
集成 Android 完整版 Android 精简版 iOS macOS
操作 ✅ ✅
Android 设备控制 ✅ ✅
Android 快速设置 ✅ ✅
Android 快捷方式 ✅ ✅
Android WebView ✅ ✅
Android 小部件 ✅ ✅
应用事件 ✅ ✅ ✅ ✅
触觉反馈 ✅
Siri 快捷指令 ✅
分享 ✅ ✅ ✅ ✅
主题 ✅ ✅ ✅ ✅
URL 处理器 ✅ ✅ ✅ ✅
通用链接 ✅ ✅
X-Callback-URL ✅ ✅
位置更新 Android 完整版 Android 精简版 iOS macOS
应用打开 ✅ ✅ ✅
应用刷新 ✅ ✅
后台 ✅ ✅
进入/离开区域 ✅ ✅
iBeacon ✅ ✅
Intent ✅
通知 ✅ ✅ ✅
显著位置变化 ✅ ✅ ✅
URL 处理器 ✅ ✅
X-Callback-URL ✅ ✅
通知 Android 完整版 Android 精简版 iOS macOS
可操作通知 ✅ ✅ ✅
仅提醒一次 ✅
角标 ✅ ✅
频道 ✅
已清除 ✅ ✅ ✅
颜色 ✅
命令 ✅ ✅ ✅
关键警报 ✅ ✅
动态附件 ✅
分组 ✅ ✅ ✅
HTML 格式化 ✅
图标 ✅
图片 ✅ ✅ ✅
重要性 ✅
LED 颜色 ✅
本地推送 ✅ ✅
消息 ✅ ✅ ✅
打开 URL ✅ ✅ ✅
持久通知 ✅
呈现选项 ✅ ✅
可替换通知 ✅ ✅ ✅
请求位置更新 ✅ ✅ ✅
声音 ✅ ✅
状态栏图标 ✅
粘性 ✅
主题 / 副标题 ✅ ✅ ✅
文字转语音 ✅
超时 ✅
标题 ✅ ✅ ✅
振动模式 ✅
视频 ✅ ✅ ✅ ✅
传感器 Android 完整版 Android 精简版 iOS macOS
活动传感器 ✅
活动摄像头 ✅
活动麦克风 ✅
活动传感器 ✅ ✅
Android Auto 传感器 ✅ ✅
Android OS 传感器 ✅ ✅
应用数据传感器 ✅ ✅
应用重要性传感器 ✅ ✅
应用内存传感器 ✅ ✅
应用使用传感器 ✅ ✅
音频传感器 ✅ ✅
平均活动步速 ✅
电池电量 ✅ ✅ ✅ ✅
电池状态 ✅ ✅ ✅ ✅
蓝牙传感器 ✅ ✅
BSSID ✅ ✅ ✅ ✅
摄像头使用中 ✅
连接类型 ✅ ✅ ✅ ✅
当前时区 ✅ ✅
当前版本 ✅ ✅
显示器 ✅ ✅ ✅
距离 ✅
勿扰模式 ✅ ✅
休眠模式 ✅ ✅
动态颜色 ✅ ✅
上楼层数 ✅
下楼层数 ✅
最前应用 ✅
地理编码位置 ✅ ✅
Health Connect ✅
高精度模式 ✅
高精度更新间隔 ✅
交互状态 ✅ ✅
锁屏传感器 ✅ ✅
最后重启 ✅ ✅
最后更新触发器 ✅ ✅ ✅ ✅
最后使用应用 ✅ ✅
光线 ✅ ✅
麦克风使用中 ✅
移动数据传感器 ✅ ✅
通知传感器 ✅ ✅
电话传感器 ✅ ✅
省电模式 ✅ ✅
压力 ✅ ✅
主显示器 ID 和名称 ✅
距离 ✅ ✅
公网 IP ✅ ✅
下次闹钟 ✅ ✅
SIM 卡 1 ✅ ✅ ✅
SIM 卡 2 ✅ ✅ ✅
SSID ✅ ✅
步数 ✅ ✅ ✅
存储 ✅ ✅ ✅ ✅
流量统计 ✅ ✅
工作配置文件 ✅ ✅
--- url: /companion/core/location.md --- # 位置 ## 概述 在以下情况下,位置更新会从您的设备发送到 Home Assistant: * 当您进入或退出 Home Assistant 中定义的[区域](https://www.home-assistant.io/components/zone/)时。对于 Android,请确保在 [配置](https://my.home-assistant.io/redirect/config/) 的 Companion App 部分启用了基于区域的追踪开关。 * 当检测到或丢失 iBeacon 时(见[下文](#ibeacons))。iOS * 当应用打开且未在后台运行时。 * 通过自动后台获取。 * 当通过[特殊通知](/companion/notifications/commands.md#request-location-updates)请求更新时 * 当打开 [URL 处理器](/companion/integrations/url-handler.md) 链接时。iOS * 当通过 [X-Callback-URL](/companion/integrations/x-callback-url.md) 调用应用时。iOS * 当您的设备检测到[显著位置变化](#location-tracking-when-outside-a-home-assistant-zone)时。 * 手动刷新应用时(在页面顶部下拉)或从 3D Touch 应用图标打开的快捷菜单中刷新。iOS * 当通过[发送 intent](#sending-an-intent) 请求更新时。Android 您可以通过检查 `sensor.last_update_trigger` 的值来查看最近一次位置更新的原因 iOS 根据您的设置,位置数据直接从您的手机发送到 Home Assistant 实例,或通过 Home Assistant 云服务发送。这取决于 [配置](https://my.home-assistant.io/redirect/config/) 中 Companion App 部分的连接设置中指定的 URL。位置数据不会通过任何其他服务器或组织发送。当然,如果您决定不授予 Home Assistant Companion App 位置权限,或者您随后移除了位置权限(iOS 设置>隐私>定位服务 或 Android 设置>隐私>权限),则不会从您的设备向 Home Assistant 发送任何位置数据。**需要注意的是,如果在 iOS 上禁用位置功能,则所有[传感器](/companion/core/sensors.md)都无法工作!iOS,而在 Android 上 Android,您仍然可以看到一些不依赖于位置权限的传感器**。另一种方法是从[实体注册表](https://www.home-assistant.io/integrations/config/#entity-registry)中禁用 `device_tracker.` 实体。 ## 入门 首次安装并打开 Home Assistant Companion App 后,将创建一个新的 `device_tracker.` 实体。默认情况下,该实体的名称格式为 `device_tracker.`,其中 `` 是您设置的设备名称(iOS 设置>通用>关于本机 或 Android 设置>关于手机)。您可以在 Home Assistant 中访问侧边栏配置页面的[集成仪表板](https://my.home-assistant.io/redirect/integrations/),点击或点按您设备的 Mobile App 集成,然后滚动浏览实体列表来检查实体名称。如果需要,您可以根据需要编辑实体的 `name` 属性。 以下是一个基本示例,用于在天黑后进入您的 *home* 区域时打开灯光。 ```yaml automation: - alias: "回家时打开门灯" trigger: - platform: state entity_id: device_tracker. to: "home" condition: - condition: sun after: sunset action: - action: light.turn_on data: entity_id: light.frontdoor ``` ## 实体属性 新创建的 `device_tracker` 实体可能根据您的操作系统提供以下某些属性。 | 名称 | 单位 | | ------------------- | ------------------------------ | | `source` | *无* | | `battery_level` | 百分比 | | `latitude` | 度 | | `longitude` | 度 | | `gps_accuracy` | 米 | | `altitude` | 米 | | `course` | 度 | | `speed` | 米每秒 | | `vertical_accuracy` | 米 | | `floor` | 楼层 iOS | 如果您想了解更多关于这些属性的详细信息,请参阅您操作系统的相关文档: [Android](https://developer.android.com/reference/android/location/Location) 或 [iOS](https://developer.apple.com/documentation/corelocation/cllocation) ## 管理位置追踪级别 当使用核心 2022.2 或更高版本时,您可以在 Companion App 设置中配置位置的发送方式: * iOS 该设置可以针对每个服务器进行管理。打开服务器设置,在隐私下更改位置发送设置。 * Android 启用位置追踪可以针对每个服务器进行管理,精确/仅区域名称适用于所有服务器。前往管理传感器 > 后台位置,更改位置发送设置。 可用选项: * **精确** 发送您设备的 GPS 坐标。 * **仅区域名称** 仅发送区域名称(或 `not_home`),这对于不暴露位置的存在检测很有用。仅考虑相关服务器的区域。 * **iOS 从不** 或 **Android 禁用** 将不会发送 GPS 坐标或区域信息。 ## 在 Home Assistant 区域外的位置追踪 iOS Home Assistant Companion App 从 iOS 接收\_显著位置变化\_。每当收到更新时,它会发送到 Home Assistant。大致上,每次您的设备转移到新的蜂窝塔、经过了大量时间(通常几小时)或连接状态发生变化且系统注意到您的位置最近发生了变化时,都会收到更新。 Apple [定义][apple-location-programming-guide] 显著位置变化更新为: > 显著变化位置服务仅在设备位置发生显著变化时(例如 500 米或更多)才会传递更新。 他们在 [能效指南][apple-energy-guide] 中还表示: > 显著变化位置更新每隔 15 分钟至少唤醒系统和您的应用一次,即使没有发生位置变化。 最后,我认为 [Stack Overflow][stackoverflow] 的这个回答说得最好: > 显著位置变化是所有位置监控类型中最不准确的。它仅在蜂窝塔转换或变化时获取更新。这可能意味着根据用户所在位置有不同的准确性和更新级别。城市区域,更多的塔,更多的更新。城外、州际公路,更少的塔和变化。 关于显著变化位置更新的真实情况是什么?谁知道呢,因为 Apple 将其保密。 ## 在 Home Assistant 区域内的位置追踪 启动时,Home Assistant for iOS 会为您的 Home Assistant 配置中的所有区域设置地理围栏。进入和退出通知会发送到 Home Assistant。对于 Android,您需要确保在应用配置页面启用了基于区域的追踪。 ### 配置 在您的 [区域配置](https://my.home-assistant.io/redirect/zones/) 中添加 `track_ios: false` 可禁用所有已连接 iOS 应用的区域位置追踪。iOS ### iBeacons iOS 该应用基本支持使用 iBeacon 触发进入/退出更新。要配置它们,请将您的 iBeacon 详细信息添加到您的区域,如下所示: ```yaml zone.home: beacon: uuid: B9407F30-F5F8-466E-AFF9-25556B57FE6D major: 60042 minor: 43814 ``` 重启 Home Assistant 和 iOS 应用。然后它将开始使用 iBeacon *而不是您的位置* 来触发区域周围的进入(但不是退出)触发器。要将 iBeacon 添加到 `zone.home`,请将上述内容添加到您的 `customize` 下。 [apple-energy-guide]: https://developer.apple.com/library/content/documentation/Performance/Conceptual/EnergyGuide-iOS/LocationBestPractices.html#//apple_ref/doc/uid/TP40015243-CH24-SW4 [apple-location-programming-guide]: https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html#//apple_ref/doc/uid/TP40009497-CH2-SW9 [stackoverflow]: http://stackoverflow.com/a/13331625/486182 ## 发送 intent Android 发送 intent 是一项高级功能,适用于熟悉 Android 自动化应用的用户。用户可以使用 Tasker 或任何其他允许用户发送 intent 的自动化应用发送 intent 来请求位置更新。您需要确保应用在[后台](/companion/troubleshooting/errors.md#device-tracker-is-not-updating-in-android-app)运行,并且启用了单次精确定位传感器,以便更新正确触发。 以下步骤是使用 Tasker 发送 intent 的示例: 1. 创建一个新任务 2. 向任务添加一个步骤 3. 选择"发送 Intent" 4. 在 Action 中输入 `io.homeassistant.companion.android.background.REQUEST_ACCURATE_UPDATE` 5. 在 Package 中输入 `io.homeassistant.companion.android` 6. 保存任务 7. 将任务与任何 Tasker 配置文件一起使用来请求位置更新 ## Android 位置传感器 Android Android 用户可以在 [设置](https://my.home-assistant.io/redirect/config/) > Companion App > 管理传感器 > 位置传感器下找到位置追踪的自定义传感器设置。这些传感器都要求应用具有适当的位置权限且设备上已启用位置功能,如果不满足这两个要求中的任何一个,传感器将变为禁用状态。 * 第一个传感器是 `后台位置`,该传感器负责使用 [Google 的 Fused Location API](https://developers.google.com/location-context/fused-location-provider) 注册频繁的后台更新。更新通常在 1-3 分钟之间,但当您使用 Google 地图等导航时,可能每 30 秒就有一次更新。 * `后台位置` 还提供[高精度模式](#high-accuracy-mode),以便您可以获得更快的更新。此模式的状态可以通过下一个位置传感器 `高精度模式` 来确定,它只是报告该模式是否启用。此传感器与您从 Google 获得的位置更新没有直接关系。 * 第三个位置传感器是 `位置区域`,启用后,该传感器将获取所有配置的 [`zones`](https://www.home-assistant.io/integrations/zone/) 列表,并使用 Google 的位置服务创建包含 `zone` 数据的地理围栏。这将允许更快的进入和退出检测,同时保持电池友好。 :::info Android 应用最多可以创建 100 个地理围栏。如果您有超过 100 个区域,Home Assistant 将只为前 100 个区域创建地理围栏并接收事件。 当与高精度模式结合使用时,[带有触发范围约束的区域](/companion/core/location.md#zone-when-using-the-high-accuracy-mode-trigger-range-for-zone-meters-option-value-greater-than-0),约束中包含的每个区域将创建 2 个地理围栏。例如,如果您有 2 个区域,其中 1 个配置了触发范围,则应用将创建 3 个地理围栏。 ::: * 最后一个位置传感器是 `单次精确定位`,该传感器仅在报告的精度不符合[传感器设置](#location-sensor-settings)中设置的标准时才会使用。当应用收到[通知命令](/companion/notifications/commands.md#request-location-updates)或 [intent](#sending-an-intent) 时,也会使用此传感器。 ### 位置传感器设置 设置允许您调整报告给 Home Assistant 的位置所需的精度。从 Google 收到的每个位置报告都包含报告的精度,有时这个数字可能很高或很低,取决于某些环境条件。通常,数字越高,报告越不准确。您可以独立于后台位置、位置区域和单次精确定位调整此设置。这将允许您在应用在后台时获得更快的区域检测,同时也保持准确。默认值为 `200`,在大多数用例中不需要更改,但在[故障排除](/companion/troubleshooting/errors.md#device-tracker-is-not-updating-in-android-app)期间,您可能会发现某些报告被跳过。在这种情况下,您可以将此数字调高以捕获那些被跳过的报告。 单次精确定位传感器允许您调整发送到服务器的更新之间的最小时间,默认设置为 1 分钟(60000 毫秒)。单次精确定位传感器还有一个设置,允许您将位置更新作为传感器更新的一部分包含在内,请注意,启用后可能会导致过多的位置结果。通常您不需要调整这些设置。 ### 高精度模式 Android :::caution 请注意,启用此选项后,由于持续使用 GPS,您的电池消耗会比正常情况更快。 ::: 后台位置传感器还有在高精度模式下运行的选项。启用 `高精度模式(可能会快速消耗电池)` 选项后,位置每 X 秒更新一次(通过 `高精度间隔` 选项定义。默认 5 秒,最小 5 秒),通过 GPS 更新。 您可以定义蓝牙和/或区域约束来限制高精度模式的使用。 :::info 如果您同时使用两个约束(蓝牙、区域),则默认情况下只需满足一个约束即可启用高精度模式。 您可以通过启用相应选项来启用两个约束的组合。请参阅[组合](/companion/core/location.md#combination-of-zones-constraint-and-bluetooth-constraint)。 ::: #### 蓝牙约束 您还可以使用 `仅在连接到蓝牙设备时使用高精度模式` 选项仅在连接到特定蓝牙设备时启用高精度模式。请确保同时启用 `高精度模式(可能会快速消耗电池)` 选项。 #### 区域约束 此外,您可以使用 `进入区域时启用高精度模式` 选项在进入特定区域时启用高精度模式。如果您想在进入区域之前启用高精度模式,可以使用 `区域的高精度模式触发范围(米)` 选项。启用此选项后,将在原始区域周围创建一个扩展区域(仅应用内部)。当您到达该扩展区域时,高精度模式将被启用,然后在到达原始区域时被禁用。请查看区域示例。 这两个选项都要求您启用 `位置区域` 传感器。 ##### 区域示例 ![区域](/companion-assets/Zone.png) ###### 使用 `区域的高精度模式触发范围(米)` 选项时的区域(值大于 0) 在这种情况下,区域由扩展区域(zone.home\_expanded)减去原始区域(zone.home)定义。图中以蓝色显示。 到达家庭区域: * 进入 `zone.home_expanded` -> 高精度模式 **启用** * 进入 `zone.home`,因此退出 `zone.home_expanded` -> 高精度模式 **禁用** 离开家庭区域: * 退出 `zone.home`,因此进入 `zone.home_expanded` -> 高精度模式 **启用** * 退出 `zone.home_expanded` -> 高精度模式 **禁用** ###### 不使用 `区域的高精度模式触发范围(米)` 选项时的区域(值等于 0) 在这种情况下,仅使用原始区域(zone.home)。图中以橙色显示。 到达家庭区域: * 进入 `zone.home` -> 高精度模式 **启用** 离开家庭区域: * 退出 `zone.home` -> 高精度模式 **禁用** ###### 区域约束和蓝牙约束的组合 可以以两种方式组合。首先是默认的简单或组合,当相应开关关闭时使用。如上面的信息框所述,只需满足一个约束即可启用高精度模式。 但是,如果组合开关打开,则必须同时满足两个约束才能启用高精度模式。 启用状态的示例:您通过蓝牙连接到汽车,并且当您的设备识别到您进入特定区域或其周围半径时,高精度模式将打开。如果您离开该区域但仍与汽车保持连接(例如,继续行驶),高精度模式将被禁用。同样,如果您在家中走动但未连接到汽车,高精度模式将保持禁用。 #### 通知 如果启用了高精度模式,您将看到一个包含位置详细信息的通知。由于 Android 系统的要求,此通知是永久的。但您可以通过系统的通知设置隐藏/最小化位置通知。 如果同时启用了地理编码传感器,通知将显示您当前的地址。否则,它将显示您当前的坐标。此外,它还将显示最后找到的位置的精度。 高精度模式也可以通过通知命令启用/禁用。[详见此处](/companion/notifications/commands.md#high-accuracy-mode)。 高精度模式的状态可以通过启用[传感器](/companion/core/sensors.md#high-accuracy-mode)来查看。 高精度模式的更新间隔也可以通过启用[传感器](/companion/core/sensors.md#high-accuracy-mode)来查看。 --- url: /companion/core/sensors.md --- # 传感器 除了提供[位置服务](/companion/core/location.md)外,Companion 应用还向 Home Assistant 添加了多个额外的传感器。如果您不想要 `device_tracker` 实体但仍想让传感器更新,只需在[实体注册表](https://www.home-assistant.io/integrations/config/#entity-registry)中禁用该实体即可停止位置更新并保持传感器更新。 Companion 应用提供的传感器取决于您使用的应用,请参阅下面的列表。 ## 多服务器支持 如果多个服务器连接到 Companion 应用,您可以配置是否针对每个服务器发送传感器数据。目前传感器设置对于所有连接的服务器都是通用的。 iOS 在 [设置](https://my.home-assistant.io/redirect/config/) > Companion App 中,打开服务器设置并在隐私下更改传感器发送设置。可用选项: * **全部** 发送所有已启用的传感器。 * **无** 不发送任何传感器。 Android 在 [设置](https://my.home-assistant.io/redirect/config/) > Companion App 中,前往管理传感器并选择您要管理的传感器。点击屏幕顶部的展开/折叠图标可更改特定服务器的设置。 ## iOS 和 macOS 传感器 ### 传感器何时更新 在 iOS 上,传感器在有限的情况下更新:当您的位置发生变化时、应用在前台运行时定期更新、下拉刷新网页视图时、在后台以 iOS 确定的速率更新时,以及执行"更新传感器"或通过"发送位置"快捷方式或推送通知时。当 iOS 2022.6 或更高版本中启用并可用 本地推送 时,也将执行定期更新。 在 macOS 上,传感器在上述相同情况下以及某些传感器发生变化时立即更新。 ### iOS 从 2025.5 起 并非所有 iOS 传感器都默认启用。如果您在 Home Assistant 中看不到您的传感器,请前往 **Companion App 设置** > **传感器**,并手动启用它。 ### 传感器列表 | 传感器 | 属性 | 描述 | | --------- | --------- | ----------- | | `sensor.battery_level` | 无 | 设备的当前电池电量。 | | `sensor.battery_state` | `低电量模式` | 设备的当前充电状态(`充电中`、`未充电` 或 `已充满`)。 | | `sensor.bssid` | 无 | 您手机连接的无线接入点的 MAC 地址。当不在 Wi-Fi 上时,此传感器将报告 `未连接`。 | | `sensor.connection_type` | iOS: `蜂窝网络技术`
macOS: `名称`, `硬件地址` | 设备正在使用的当前数据连接。在 macOS 上,这需要应用版本 2021.2 或更高版本。 | | `binary_sensor.focus` | 无 | 专注模式当前是否启用。需要 iOS-2021.10 或更高版本,今年晚些时候的 macOS 12 更新。如果 Home Assistant 在"允许的通知"列表中,则不会工作,详见[中断级别](/companion/notifications/basic.md#interruption-level)。 | | `sensor.geocoded_location` | [见下文](#geocoded-location-sensor) | 基于 GPS 数据计算的地址。 | | `sensor.last_update_trigger` | 无 | 从设备到 Home Assistant 的位置和传感器数据最后更新的原因 | | `sensor.ssid` | 无 | 设备当前连接的 Wi-Fi 网络的人类可读名称。当不在 Wi-Fi 上时,此传感器将报告 `未连接`。 | | `sensor.storage` | [见下文](#storage-sensor) | 设备上的总存储量和可用存储量。 | iOS专属传感器 | 传感器 | 属性 | 描述 | | --------- | --------- | ----------- | | `sensor.activity` | `confidence`, `types` | iOS 计算的当前活动类型。需要启用运动权限。 | | `sensor.app_version` | 无 | 当前的 **Home Assistant iOS 版 Companion App** 应用版本。 | | `sensor.average_active_pace` | 无 | iOS 从计步器数据计算的平均配速。单位:米每秒,m/s | | `sensor.distance` | 无 | 自当地午夜以来用户步行的估计距离。单位:米,m | | `sensor.floors_ascended` | 无 | 自当地午夜以来步行上楼的近似楼层数。 | | `sensor.floors_descended` | 无 | 步行下楼的近似楼层数。 | | `sensor.location_permission` | 无 | 用户选择的位置权限。可以通过位置权限弹窗设置或在 iOS 设置中修改。 | | `sensor.sim_1` | [见下文](#cellular-provider-sensor) | 您的蜂窝运营商名称。 | | `sensor.sim_2` | [见下文](#cellular-provider-sensor) | 您的蜂窝运营商名称。 | | `sensor.steps` | 无 | 用户走的步数。 | | `sensor.watch_battery_level` | 无 | 1 个配对 Apple Watch 的电池电量。需要在您的表盘上安装任何 Home Assistant 复杂功能。 | | `sensor.watch_battery_state` | 无 | 1 个配对 Apple Watch 的当前充电状态(充电中、未充电或已充满)。需要在您的表盘上安装任何 Home Assistant 复杂功能。 | macOS专属传感器 | 传感器 | 属性 | 描述 | | --------- | --------- | ----------- | | `binary_sensor.active` | [见下文](#active-sensor) | 设备是否正在被主动使用。 | | `sensor.active_camera` | `全部`, `活动` | 活动摄像头的名称,如果未使用则为 `非活动`。 | | `sensor.active_audio_input` | `全部`, `活动` | 活动音频输入(麦克风)的名称,如果未使用则为 `非活动`。 | | `sensor.active_audio_output` | `全部`, `活动` | 需要应用版本 2021.12 或更高版本。活动音频输出(扬声器)的名称,如果未使用则为 `非活动`。 | | `sensor.frontmost_app` | [见下文](#frontmost-app-sensor) | 需要应用版本 2021.2 或更高版本。当前最前端应用的名称。 | | `binary_sensor.camera_in_use` | 无 | 系统上的摄像头当前是否正在使用。 | | `binary_sensor.audio_input_in_use` | 无 | 系统上的音频输入(麦克风)当前是否正在使用。 | | `binary_sensor.audio_output_in_use` | 无 | 需要应用版本 2021.12 或更高版本。系统上的音频输出(扬声器)当前是否正在使用。 | | `sensor.displays` | `显示器 ID`, `显示器名称` | 需要应用版本 2021.2 或更高版本。连接到设备的显示器数量。 | | `sensor.primary_display_id` | 无 | 需要应用版本 2021.2 或更高版本。当前主显示器的 ID,即带有菜单栏的显示器。格式为 UUID,例如 `BE82E2E6-EA40-4963-93AD-A0BDC9D2F18F`。 | | `sensor.primary_display_name` | 无 | 需要应用版本 2021.2 或更高版本。当前主显示器的名称,即带有菜单栏的显示器。 | 可以通过模板访问 `蜂窝网络技术` 等属性: ``` {{ states.sensor.connection_type.attributes['Cellular Technology'] }} ``` ## Android 传感器 下面的每个 Android 传感器都可以通过导航到 [设置](https://my.home-assistant.io/redirect/config/) > Companion App > 管理传感器来启用。默认情况下,大多数传感器都是禁用的,除了 `battery_level`、`battery_state`、`charger_type` 以及在引导过程中获得权限的传感器。启用后,传感器将开始向您的 Home Assistant 服务器发送数据,如果您稍后选择禁用它,传感器将停止更新。启用传感器时,如果需要,应用将请求权限。如果您没有在下面看到列出的传感器,则您的设备不支持它。下面的某些传感器为其各自的需求提供自定义设置,请阅读每个传感器的说明以了解其提供的功能。这些设置可以在启用传感器的同一位置找到。 ### 传感器如何更新 所有传感器在 15 分钟的定期间隔期间更新,如果满足某些其他条件,它们也会更新。阅读下面每个传感器的说明以了解预期更新的频率。在 15 分钟更新间隔期间,会临时创建一个低优先级前台通知,以防止 Android 系统停止工作器。除非用户安装了拦截通知并决定发出声音的第三方应用,否则此通知不会发出声音。如果您使用的是 Android 8.0+,您可以自由地最小化和/或关闭 `SensorWorker` 的通知渠道。 您可以通过导航到 [设置](https://my.home-assistant.io/redirect/config/) > Companion App > 传感器更新频率来更改传感器更新的频率。您可以选择正常、充电时快速或始终快速。正常是上一段中提到的默认设置。设置为始终快速时,更新将每分钟进行一次。设置为充电时快速时,只有在设备充电时才会每分钟更新一次,否则将使用默认间隔。更改此选项后,您需要重启应用。 ### 传感器列表 | 传感器 | 属性 | 描述 | | --------- | --------- | ----------- | | `binary_sensor.doze` | [见下文](#doze-sensor) | 设备是否处于打盹模式。 | | `binary_sensor.interactive` | 无 | 设备是否处于交互状态。 | | `binary_sensor.nfc_state` | 无 | 设备是否启用了 NFC 传感器。 | | `binary_sensor.power_save` | 无 | 设备是否处于省电模式。 | | [活动传感器](#activity-sensors) | 见下文 | Google 计算的当前活动类型、睡眠置信度和睡眠片段。在支持的设备上需要活动识别权限。 | | `binary_sensor.android_auto` | [见下文](#android-auto) | 一个二进制传感器,用于指示设备是否连接到 Android Auto。 | | [Android OS 传感器](#android-os-sensors) | 无 | 关于 Android OS 的几个不同传感器。 | | [应用数据传感器](#app-data-sensors) | 无 | 显示应用发送或接收了多少数据的传感器。 | | [应用重要性传感器](#app-importance-sensor) | 无 | 应用的当前重要性,以确定它是在前台还是缓存中。 | | `sensor.app_memory` | [见下文](#app-memory-sensor) | 关于应用可用内存的信息。 | | [应用使用传感器](#app-usage-sensors) | 无 | 表示根据使用情况如何对待应用的传感器。 | | [音频传感器](#audio-sensors) | 无 | 关于设备不同类型音频检测的几个不同传感器。 | | [电池传感器](#battery-sensors) | 无 | 关于设备电池状态的几个不同传感器。 | | [蓝牙传感器](#bluetooth-sensors) | [见下文](#bluetooth-sensors) | 关于设备蓝牙状态的几个不同传感器。还有用于信标传输和监控的传感器。 | | [汽车传感器](#car-sensors) | [见下文](#car-sensors) | 关于汽车状态的几个不同传感器。 | | `sensor.current_time_zone` | [见下文](#current-time-zone-sensor) | 设备所在的当前时区。 | | `sensor.current_version` | 无 | 应用当前安装的版本。 | | [显示传感器](#display-sensors)| [见下文](#display-sensors) | 关于设备显示器状态的几个传感器。 | | [动态颜色](#dynamic-color-sensor) | RGB 颜色 | 当前设备主题中使用的强调色的十六进制颜色值。 | | `sensor.do_not_disturb` | 无 | 设备上的免打扰状态。 | | `sensor.geocoded_location` | [见下文](#geocoded-location-sensor) | 基于 GPS 数据计算的地址。 | | [Health Connect 传感器](#health-connect-sensors) | 多种 | 存储在您设备的 Health Connect 中由其他应用提供的健康和健身数据。 | | `binary_sensor.high_accuracy_mode` | 无 | 设备上高精度模式的状态。 | | `sensor.high_accuracy_update_interval` | 无 | 设备上高精度模式的更新间隔。 | | [Keyguard 传感器](#keyguard-sensors) | 无 | 表示设备锁定或安全各种状态的传感器。 | | `sensor.last_reboot` | [见下文](#last-reboot-sensor) | 设备上次重启的时间戳。 | | `sensor.last_update` | 无 | 状态将反映导致最后更新发送的意图。 | | `sensor.last_used_app` | 无 | 设备上最后使用的应用。 | | `sensor.light` | 无 | 设备检测到的当前照度级别。 | | [移动数据传感器](#mobile-data-sensors) | 无 | 关于移动数据状态的几个不同传感器。 | | `sensor.next_alarm` | [见下文](#next-alarm-sensor) | 下一个计划闹钟的日期。 | | [通知传感器](#notification-sensors) | 见下文 | 设备上通知的详细信息。 | | [电话传感器](#phone-sensors) | 无 | 表示电话调制解调器不同状态的传感器。 | | `sensor.pressure` | 无 | 设备的压力读数。 | | `sensor.proximity` | 无 | 设备的当前接近读数,某些设备只会显示 `近` 或 `远` 的布尔值。 | | `sensor.public_ip` | 无 | 由 ipify API 生成的设备的公共 IP 地址。 | | `sensor.sim_1` | [见下文](#cellular-provider-sensor) | 您的蜂窝运营商名称。 | | `sensor.sim_2` | [见下文](#cellular-provider-sensor) | 您的蜂窝运营商名称。 | | `sensor.steps` | 无 | 自上次设备重启以来用户的步数。在支持的设备上需要活动识别权限。 | | [存储传感器](#storage-sensor) | [见下文](#storage-sensor) | Android 设备上内部和外部存储的总量和可用量。 | | [流量统计传感器](#traffic-stats-sensor) | 无 | 自上次重启以来移动设备和总设备使用传输和接收的数据量。 | | [WiFi 传感器](#connection-type-sensor) | 无 | 关于 WiFi 状态的几个不同传感器。 | | [工作配置文件](#work-profile-sensor) | 无 | 设备上的工作配置文件当前是否处于活动状态。 | ## 活动传感器 macOS `sensor.active` 提供设备当前是否正在被使用,基于几个不同的输入,这些输入作为属性提供以供参考。 | 属性 | 描述 | | --------- | --------- | | `Idle` | 当机器不是以下任何属性,但输入设备在几分钟内未被使用时为 `true`。 | | `Screensaver` | 当屏幕保护程序开始播放以变为非活动状态时为 `true` | | `Locked` | 当设备显示登录屏幕时为 `true` | | `Screen Off` | 当屏幕已关闭时为 `true` | | `Fast User Switched` | 当切换到另一个用户时为 `true` | | `Sleeping` | 当设备正在睡眠时为 `true` | | `Terminating` | 当应用退出可用时为 `true`。需要应用版本 2021.2 或更高版本。 | 此传感器有一个设置来决定被视为"空闲"的持续时间。 ## 活动传感器 iOS `sensor.activity` 提供 iOS 计算的当前运动活动以及计算的置信度。iOS 已知并由 `sensor.activity` 提供的活动有: * `Stationary`(静止) * `Walking`(步行) * `Running`(跑步) * `Automotive`(乘车) * `Cycling`(骑行) 如果 iOS 无法从运动数据计算活动,将给出 `Unknown`(未知)。 可能返回多个活动,例如 `Cycling` 和 `Stationary`(如果您正在骑行但在红灯处停车),传感器的状态只是 iOS 返回的第一个(不一定是最可能的)。完整的计算活动列表由 `types` 属性给出。有关不同场景如何产生多个活动的描述,请参阅 [nshipster](https://nshipster.com/) 上 [@Mattt](https://x.com/mattt) 的[这篇文章](https://nshipster.com/cmmotionactivity/#traveling-without-moving)。 `confidence` 属性对应 iOS 对当前活动报告准确程度的判断。可能的值有: * `Low`(低) * `Medium`(中) * `High`(高) Android 此传感器仅在 Google Play 商店中找到的 Android 应用完整版本上可用,最小版本不可用。对于 Android,用户将有一组不同的状态: * `in_vehicle`(在车辆中) * `on_bicycle`(在自行车上) * `on_foot`(步行) * `running`(跑步) * `still`(静止) * `tilting`(倾斜) * `walking`(步行) * `unknown`(未知) 状态的属性将反映来自 [Activity Recognition API](https://developers.google.com/location-context/activity-recognition) 的 `confidence` 评级。此传感器需要 [Activity Recognition 权限](https://developer.android.com/reference/android/Manifest.permission#ACTIVITY_RECOGNITION)。 Android 睡眠置信度和睡眠片段传感器利用 Google 服务的新的 [Sleep API](https://developers.google.com/location-context/sleep)。睡眠片段大约每天更新一次,睡眠置信度大约每 10 分钟更新一次。所有数据由 Google 提供。 ## Android Auto Android 此传感器用于确定设备是否连接到 Android Auto。属性将返回特定的连接类型。 ## Android OS 传感器 Android 关于 Android OS 构建的几个不同传感器。这些传感器使用 [android.os.Build](https://developer.android.com/reference/android/os/Build)。 | 传感器 | 描述 | |-----------------------------|--------------------------------------------------------------------------------------------| | `android_os_version` | Android OS 版本(例如 13)。 | | `android_os_security_patch` | Android OS 安全补丁(例如 2023-03-05)。 | ## 应用数据传感器 Android 这些传感器将表示自上次设备重启以来 Home Assistant Android 应用传输和接收了多少数据。这些传感器使用 [Traffic Stats API](https://developer.android.com/reference/kotlin/android/net/TrafficStats)。 ## 应用重要性传感器 Android 此传感器将表示应用的状态,以反映它是在 `foreground`(前台)、`service`(服务)还是其他任何状态。每当任何其他传感器有更新时,此传感器都会更新。请参阅 [ActivityManager](https://developer.android.com/reference/android/app/ActivityManager.RunningAppProcessInfo) 中的所有重要性变量以了解它们的含义。 可能的状态有: * `cached`(缓存) * `cant_save_state`(无法保存状态) * `foreground`(前台) * `foreground_service`(前台服务) * `gone`(已消失) * `not_running`(未运行) * `perceptible`(可感知) * `service`(服务) * `top_sleeping`(顶部睡眠) * `visible`(可见) ## 应用内存传感器 Android 此传感器将表示应用正在使用多少内存。属性将包括应用有多少可用内存。此传感器使用 [Runtime API](https://developer.android.com/reference/java/lang/Runtime)。 ## 应用使用传感器 Android 这些传感器将表示 Android 系统如何根据使用情况对待应用。有一个二进制传感器 `app_inactive`,它将报告系统当前是否认为应用处于非活动状态。另一个传感器 `app_standby_bucket` 将反映 Android 系统为应用考虑的当前待机桶。待机桶决定应用在运行后台任务(如作业和闹钟)时受到多少限制。这两个传感器都使用 [UsageStatsManager API](https://developer.android.com/reference/android/app/usage/UsageStatsManager)。 `app_standby_bucket` 传感器的可能状态(请参阅上面链接的 API 以获取其定义): * `active`(活动) * `frequent`(频繁) * `rare`(稀有) * `restricted`(受限) * `working_set`(工作集) * `never`(从不) ## 音频传感器 Android
这些传感器使用 [AudioManager API](https://developer.android.com/reference/kotlin/android/media/AudioManager?hl=en) 来检索它们的状态。查看下表以了解有关每个传感器的更多信息,包括它们更新的频率。 | 传感器 | 属性 | 描述 | | --------- | --------- | --------- | | `audio_mode` | 无 | 设备的当前音频模式可以是:`normal`、`ringing`(与[电话传感器](#phone-state-sensor)相同)、`call_redirect`、`communication_redirect`、`in_call`、`in_communication` 或 `unknown`。此传感器将在正常间隔期间更新。 | | `is_headphones` | 无 | 如果插入耳机或耳机则为布尔值,一旦设备检测到变化就会更新。 | | `is_mic_muted` | 无 | 如果麦克风当前静音则为布尔值,Android 10+ 将随着此值的变化而更新。 | | `is_music_active` | 无 | 如果设备正在主动播放音乐则为布尔值,此传感器将在正常间隔期间更新。 | | `is_speakerphone_on` | 无 | 如果设备扬声器已启用则为布尔值,Android 10+ 将随着此值的变化而更新。 | | `ringer_mode` | 无 | 设备上的铃音模式,可能的值为 `normal`、`vibrate` 或 `silent`。此传感器将在铃音模式变化时立即更新。
在 Android 9 及更高版本上,当免打扰开启时,铃音模式始终为 `silent`。 | | [`volume_level_*`](#volume-levels) | [见下文](#volume-levels) | 给定音量流的当前设备音量级别。 | ### 音量级别 给定音量流(`volume_level_*`)的当前设备音量级别。这些传感器将在正常间隔期间更新,或在检测到变化时立即更新。 可能的音量流有: * `accessibility`(无障碍) * `alarm`(闹钟) * `call`(通话) * `dtmf` * `music`(音乐) * `notification`(通知) * `ring`(铃声) * `system`(系统) BETA 属性指示最小和最大值。 | 属性 | 描述 | | --------- | --------- | | `min` | 提供音量级别的最小值。通常这是 `0`,但根据 Android 版本和设备制造商也可能不同。 | | `max` | 提供音量级别的最大值。此值因 Android 版本和设备制造商而异。 | ## 电池传感器 iOS
电池状态传感器(`sensor.battery_state`)提供有关设备电池当前状态的信息。当设备充电 100% 时,三个可能的值是 `Charging`(充电中)、`Not Charging`(未充电)或 `Full`(已充满)。电池电量传感器(`sensor.battery_level`)报告设备从 0–100% 的当前电池电量。电量级别反映在传感器图标中。此外还有一个"低电量模式"属性,根据您的 iOS 设备是否处于[低电量模式](https://support.apple.com/en-us/HT205234),报告 `true` 或 `false`。 Android
下面列出的电池传感器描述了电池在几个不同数据点的状态。传感器的图标反映充电状态和正在使用的充电类型。当设备连接或断开充电器时,`battery_state`、`charger_type` 和 `is_charging` 传感器将更新。当任何其他传感器更新时,以及当设备报告低电量或从低电量警报恢复时,`battery_health`、`battery_level`、`battery_power` 和 `battery_temperature` 传感器都会更新。所有这些传感器都使用 [BatteryManager](https://developer.android.com/reference/android/os/BatteryManager)。 | 传感器 | 描述 | | --------- | --------- | | `battery_cycle_count` | 电池完成的充电周期数。需要 Android 14 或更新版本。注意:并非所有设备都会报告或更新周期计数。 | | `battery_health` | 电池的健康状况 | | `battery_level` | 剩余电池百分比 | | `battery_power` | 设备上的当前瓦数 | | `battery_state` | 设备上的充电状态 | | `battery_temperature` | 当前电池温度 | | `charger_type` | 设备上正在使用的充电器类型 | | `is_charging` | 设备是否正在主动充电 | | `remaining_charge_time` | 计算的剩余充电时间(分钟)。如果无法计算时间则返回 `unavailable`:要么没有足够的当前数据来做出决定,要么电池当前正在放电。如果计算未完成但设备当前正在充电则返回 `0`。需要 Android 9 或更新版本。 | :::info `battery_power` 传感器将设备返回的值转换为安培和伏特。但是,某些设备不遵循 Android 文档,可能以不同的单位返回值,这会导致传感器不正确。对于这些设备,您可能需要调整传感器设置中的"电池电流除数"以正确将 `current` 转换为安培,或调整"电池电压除数"以正确将 `voltage` 转换为伏特。 电池电流除数的常见值:1000000(默认,微安)、1000(毫安)、1000000000(纳安) 电池电压除数的常见值:1000(默认,毫伏)、1(无需转换,伏特) ::: ## 蓝牙传感器 Android
蓝牙连接状态将是已连接蓝牙设备的总数。一旦设备的蓝牙状态发生变化,传感器就会更新。此传感器使用 Android 的 [Bluetooth](https://developer.android.com/reference/android/bluetooth/package-summary?hl=en) 包。 | 属性 | 描述 | | --------- | --------- | | `Connected Paired Devices` | 当前已连接的配对设备列表。 | | `Connected Not Paired Devices` | 已连接但未配对的设备列表。 | | `Paired Devices` | 已配对的设备列表。 | 还会有一个 `bluetooth_state` 的二进制传感器,表示设备上的蓝牙是否已开启。每当蓝牙状态发生变化时,此传感器都会更新。 Android BLE 发射器传感器允许您的设备发射 BLE iBeacon。如果您的设备发送设备名称([见此处原因](https://github.com/home-assistant/android/pull/2941#issuecomment-1272379540)),iBeacon 可以被 [iBeacon 集成](https://www.home-assistant.io/integrations/ibeacon) 检测到。如果您的设备不发送其设备名称,如果您通过 iBeacon 集成选项明确允许 UUID,它仍然可以被检测到。此传感器也可以与 [roomassistant](https://www.room-assistant.io/) 和 [esp32-mqtt-room](https://jptrsn.github.io/ESP32-mqtt-room/) 等项目一起使用,以允许房间级别的追踪。当前发射 ID(UUID-Major-Minor)作为属性报告,可以复制用于这些系统。 :::caution 此传感器可能会影响电池寿命,特别是当发射功率设置为高时。iBeacon 每秒发射一次(低延迟以节省电池,但足以用于房间存在检测)。 ::: 设置可用于更改 UUID、Major 和 Minor 掩码。这些可用于更改整体标识符,以及允许分组,例如家庭手机设备可以有特定的 Major 值,可以在 roomassistant 等应用中列入白名单。这些设置经过验证:UUID 应为[标准格式](https://en.wikipedia.org/wiki/Universally_unique_identifier),Major 和 Minor 需要在 0 和 65535 之间。 还有设置可以更改: * 发射功率(超低、低、中和高之间) * 广播模式(低功耗(1Hz)、平衡(3Hz)和低延迟(10Hz)之间) * 1 米处的测量功率(必须为负数) * 是否仅在家用 WiFi 网络 SSID 上启用发射 发射设置开关将启动或停止 BLE 发射。此设置以及上述大多数设置可以通过[通知命令](/companion/notifications/commands.md#ble-beacon-transmitter)更改。 Android
信标监视器显示扫描 BLE iBeacon。传感器的状态显示应用是否正在监视。范围内所有信标及其距离都列在属性中。当有新的距离测量可用时,此传感器将更新。 设置可用于更改扫描周期和间隔,这对于节省电池寿命很有用。设置过滤迭代和过滤 RSSI 乘数可以调整以获得更稳定的测量结果。所有这些设置都会影响传感器的响应性。还有一个 UUID 过滤器,用于将报告的信标限制为匹配(或不匹配)UUID 列表的信标。 监视设置开关将启动或停止扫描 - 此设置也可以通过[通知命令](/companion/notifications/commands.md#beacon-monitor)调整。 当应用主动扫描信标时,将显示通知以使后台扫描更可靠。如果您使用的是 Android 8.0+,您可以自由地最小化和/或关闭 `Beacon Monitor Scanning` 的通知渠道。 ## 汽车传感器 Android 下面列出的传感器描述了汽车在几个不同数据点的状态。目前这仅适用于 Android Auto。根据您的手机和/或汽车软件,这些传感器可能无法提供数据。如果您看到 `unknown` 状态,请检查 `status` 属性以了解没有数据的原因。 :::caution 请注意,您需要在每次将手机连接到汽车时在 Android Auto 屏幕上启动 Home-Assistant 应用,以允许这些传感器工作(一旦启动,您可以关闭应用)。如果应用未启动,状态将为 `unavailable`。 为了简化操作,您可能希望使用 [`car_ui` 参数](/companion/android-auto/index.md#notifications)在[连接手机](/companion/core/sensors.md#android-auto)时在汽车上显示通知。 ::: | 传感器 | 描述 | | --------- | --------- | | `car_battery` | 剩余电池百分比 | | `car_charging_status` | 汽车的充电状态(仅适用于电动车)。充电端口的状态在属性中 | | `car_ev_connector` | 汽车可用的电动车连接器列表 | | `car_fuel` | 剩余燃油百分比 | | `car_fuel_type` | 汽车可用的燃料类型列表。 | | `car_name` | 汽车的名称。制造商名称和制造年份在属性中 | | `car_odometer` | 汽车里程表的值(米) | | `car_range_remaining` | 汽车的剩余续航里程(米) | | `car_speed` | 汽车的速度(米每秒) | ## 蜂窝运营商传感器 蜂窝运营商传感器显示有关用户蜂窝服务提供商的信息,例如其唯一标识符以及是否允许在其网络上进行 VoIP 呼叫。`sensor.sim_1` 对应于安装的物理 SIM 卡,`sensor.sim_2` 对应于 eSIM(仅在启用 eSIM 时显示)。 Android Android 用户将在网络发生变化时看到这些传感器更新,这使用 [SubscriptionManager](https://developer.android.com/reference/android/telephony/SubscriptionManager?hl=en)。这些传感器需要 [Read Phone State 权限](https://developer.android.com/reference/android/Manifest.permission#READ_PHONE_STATE)。 | 属性 | 描述 | | --------- | --------- | | `Carrier Name` | 用户蜂窝服务提供商的名称。 | | `Current Radio Technology` | 仅 iOS。 | | `ISO Country Code` | 用户蜂窝服务提供商的 ISO 国家代码。 | | `Mobile Country Code` | 用户蜂窝服务提供商的移动国家代码(MCC)。 | | `Mobile Network Code` | 用户蜂窝服务提供商的移动网络代码(MNC)。 | | `Carrier ID` | | | `Allows VoIP` | 指示运营商是否允许在其网络上进行 VoIP 呼叫。iOS | | `Is Opportunistic` | 临时订阅连接到功能和/或覆盖范围受限的网络。Android | | `Data Roaming` | 设备是否启用了数据漫游。Android | ## 连接类型传感器 iOS
以下连接类型是 Companion 应用已知的: * `Wi-Fi` * `Cellular`(蜂窝网络) * `No Connection`(无连接) 可以在传感器的 `Cellular Technology` 属性中找到数据连接的更具体描述(仅在蜂窝网络上时出现)。此属性的可能值有: * `4G` * `3G` * `2G` * `Cellular`(蜂窝网络) * `No Connection`(无连接) 如果无法识别连接类型,将返回 `Unknown` 或 `Unknown Technology`。 Android
对于 Android,有多种不同类型的连接传感器可用,当检测到网络状态变化时它们将更新: | 传感器 | 描述 | | --------- | --------- | | `wifi_connection` | 当前连接网络的名称 | | `bssid` | 当前连接网络的 MAC 地址 | | `frequency` | 连接网络的频段 | | `wifi_ip_address` | 设备在网络上的当前 IP 地址 | | `link_speed` | 设备到连接网络的当前链路速度 | | `signal_strength` | 设备到 WiFi 网络的信号强度 | | `wifi_state` | 设备上的 WiFi 是否已开启 | | `transport_type` | 当前网络连接的传输类型。属性将反映当前网络是否按流量计费。 | | `hotspot_state` | 设备当前是否正在广播 WiFi 热点。(在 Wear OS 上不可用) | | `ip6_addresses` | 绑定到当前活动网络的 ip6\_addresses | Android `bssid` 传感器提供设置让您重命名当前的 MAC 地址,以避免在自动化和前端中使用模板和秘密。如果您有多个接入点并想要一种简单的方法来区分它们,这通常很有用。这些设置默认关闭。这些传感器需要 [Background Location](https://developer.android.com/reference/android/Manifest.permission#ACCESS_BACKGROUND_LOCATION) 或 [Fine Location](https://developer.android.com/reference/android/Manifest.permission#ACCESS_FINE_LOCATION) 权限,具体取决于您运行的 Android 版本。 ## 当前时区传感器 Android 此传感器将表示设备所在的当前时区。还有一些属性来帮助描述此时区。数据由 [TimeZone API](https://developer.android.com/reference/java/util/TimeZone.html) 提供。 | 属性 | 描述 | | --------- | ----------- | | `in_daylight_time` | 时区当前是否正在观察夏令时。 | | `time_zone_id` | 时区的显示名称。 | | `time_zone_short` | 时区的简称。 | | `uses_daylight_time` | 当前时区是否观察夏令时。 | ## 当前版本传感器 Android 此传感器将表示 Android 应用的当前安装版本。 ## 显示传感器 ### 屏幕亮度传感器 Android
此传感器将报告屏幕亮度值作为其状态。如果屏幕当前正在使用自动亮度模式,也存在一个属性。此传感器使用 [Settings.System API](https://developer.android.com/reference/android/provider/Settings.System)。 ### 屏幕关闭超时传感器 Android
此传感器将报告屏幕关闭超时值作为其状态,单位为毫秒。此传感器使用 [Settings.System API](https://developer.android.com/reference/android/provider/Settings.System)。 ### 屏幕方向传感器 Android
此传感器报告屏幕的方向,当屏幕开启且方向变化时,此传感器将立即更新。此传感器使用 [Orientation API](https://developer.android.com/reference/android/content/res/Configuration.html#orientation)。 ### 屏幕旋转传感器 Android
此传感器报告相对于设备"自然"方向的旋转度数。此传感器仅针对以下旋转角度更新:`0`、`90`、`180` 和 `270`。此传感器使用 [Rotation API](https://developer.android.com/reference/android/view/Display.html#getRotation\(\))。 ## 免打扰传感器 Android 仅限 6+
此传感器将表示设备上免打扰(DND)的状态。DND 的功能取决于 Android 版本。可能的状态值有 `off`、`priority_only`、`total_silence`、`alarms_only`、`unavailable` 或 `unknown`。并非所有状态都会在所有 Android 版本上显示,例如 Pixel 4 XL 只会显示 `off` 或 `priority_only`。如果您从未使用过 DND,您可能会看到 `unavailable`,直到您更改设备上的设置。一旦 DND 状态发生变化,此传感器就会更新。此传感器使用 [NotificationManager API](https://developer.android.com/reference/android/app/NotificationManager#getCurrentInterruptionFilter\(\))。 ## 动态颜色传感器 Android 仅在支持 Material 3 动态颜色的设备上可用。 此传感器的状态将是当前设备主题中使用的强调色的十六进制颜色值。[动态颜色](https://m3.material.io/styles/color/dynamic-color/overview)可以来自壁纸或由用户选择。还有一个 `rgb_color` 属性,如果您想在自动化中为 [`light.turn_on`](https://www.home-assistant.io/integrations/light/#service-lightturn_on) 服务调用使用此颜色。此传感器使用 [Dynamic Colors API](https://developer.android.com/reference/com/google/android/material/color/DynamicColors)。 ## 打盹传感器 Android
状态将反映设备是否处于打盹模式。状态将在状态变化时立即更新,数据由 [PowerManager](https://developer.android.com/reference/android/os/PowerManager.html) 提供。有一个属性 `ignoring_battery_optimizations`,如果 Companion 应用正在忽略电池优化,将显示 `true` 或 `false`。如果您好奇状态实际上如何变化,可以按照这些[概述的步骤](https://developer.android.com/training/monitoring-device-state/doze-standby#testing_doze)进行测试。 ## 最前端应用传感器 macOS
当最前端的应用发生变化时,此传感器会立即更新。 | 属性 | 描述 | | --------- | --------- | | `Bundle Identifier` | 应用的包标识符。例如,`io.home-assistant.example`。 | | `Is Hidden` | 应用是否隐藏。 | | `Launch Date` | 应用启动的日期(ISO 8601,RFC 3339 格式)。例如,`2021-01-06T22:17:30-08:00`。 | | `Owns Menu Bar` | 应用是否"拥有"菜单栏。例如,仅菜单栏的应用不会更改菜单栏的内容,即使它是最前端的应用,也不一定是主要的。 | ## 地理编码位置传感器 [地理编码](https://en.wikipedia.org/wiki/Geocoding)位置传感器提供用户当前位置坐标的用户友好描述,通常包含地点名称、地址和其他相关信息。此传感器报告许多详细属性,允许您创建有用的[模板传感器](https://www.home-assistant.io/components/template/)。 地理编码由 iOS 的 [MapKit](https://developer.apple.com/documentation/mapkit) 和 [Core Location](https://developer.apple.com/documentation/corelocation/converting_between_coordinates_and_user-friendly_place_names) 服务直接处理。在 Android 中,地理编码由内部 [Geocoder](https://developer.android.com/reference/android/location/Geocoder) 处理。 | 属性 | 描述 | | --------- | --------- | | `Location` | 地标的纬度和经度坐标。 | | `Name` | 地标的名称。仅 iOS 和 Android | | `Country` | 与地标关联的国家名称。 | | `ISOCountryCode` | 缩写的国家名称。 | | `TimeZone` | 与地标关联的时区。仅 iOS | | `AdministrativeArea` | 与地标关联的州或省。 | | `SubAdministrativeArea` | 地标的额外行政区域信息。 | | `PostalCode` | 与地标关联的邮政编码。 | | `Locality` | 与地标关联的城市。 | | `SubLocality` | 地标的额外城市级信息。 | | `Thoroughfare` | 与地标关联的街道地址。 | | `SubThoroughfare` | 地标的额外街道级信息。 | | `AreasOfInterest` | 与地标相关的感兴趣区域。仅 iOS | | `Ocean` | 与地标关联的海洋名称。仅 iOS | | `InlandWater` | 与地标关联的内陆水域名称。仅 iOS | | `phone` | 地标的电话号码(如果有)。Android | | `premises` | 地标的前提(如果有)。Android | | `url` | 地标的 URL(如果有)。Android | Android Android 用户将有一个传感器设置用于最小所需精度,默认为 200 米。如果用户发现报告不准确或报告不足,可以根据自己的需求调整此设置。此传感器需要 [Background Location](https://developer.android.com/reference/android/Manifest.permission#ACCESS_BACKGROUND_LOCATION) 或 [Fine Location](https://developer.android.com/reference/android/Manifest.permission#ACCESS_FINE_LOCATION) 权限,具体取决于您运行的 Android 版本。所有属性都将小写,所有空格都替换为下划线。传感器只会在准确和最新时发送更新。在 `full` 版本中,如果启用了位置追踪,传感器也会随位置变化更新。有一个设置可以让传感器与位置更新保持同步。默认情况下,此设置是关闭的。 iOS 和 macOS 用户将有一个传感器设置,用于是否使用活动区域的名称(如果存在)而不是地理编码状态,默认不使用。 ## Health Connect 传感器 Android 9+ 带 Play Store 版本 • (Android 14+ 所有版本 BETA) :::note 在 Android 13 或更早版本上,您需要安装并设置 [Health Connect 应用](https://play.google.com/store/apps/details?id=com.google.android.apps.healthdata)才能使用这些传感器。 ::: 这些传感器将反映存储在您设备 [Health Connect](https://health.google/health-connect-android/) 中由其他应用提供的健康和健身数据。除非另有说明,否则仅使用最近 30 天的数据。 | 传感器 | 单位 | 描述 | | --------- | ---- | --------- | | `health_connect_active_calories_burned` | 千卡 | 活动卡路里消耗的最后估计值,不包括基础代谢率(BMR)。 | | `health_connect_blood_glucose` | 毫克每分升 | 最后记录的血糖读数。 | | `health_connect_body_fat` | 百分比 | 最后记录的体脂百分比。 | | `health_connect_diastolic_blood_pressure` | 毫米汞柱 | 最后记录的舒张压。 | | `health_connect_distance` | 米 | 自午夜以来的总行程距离。 | | `health_connect_elevation_gained` | 米 | 自午夜以来的总海拔增益。 | | `health_connect_floors_climbed` | 楼层 | 自午夜以来的总爬楼层数。 | | `health_connect_heart_rate` | 每分钟心跳 | 最后记录的心率。 | | `health_connect_heart_rate_variability` | 毫秒 | 最后记录的心率变异性。 | | `health_connect_oxygen_saturation` | 百分比 | 最后记录的血氧饱和度百分比。 | | `health_connect_respiratory_rate` | 每分钟呼吸 | 最后记录的呼吸频率。 | | `health_connect_resting_heart_rate` | 每分钟心跳 | 最后记录的静息心率。 | | `health_connect_sleep_duration` | 分钟 | 最后记录的睡眠时长。 | | `health_connect_steps` | 步数 | 自午夜以来的总步数。 | | `health_connect_systolic_blood_pressure` | 毫米汞柱 | 最后记录的收缩压。 | | `health_connect_total_calories_burned` | 千卡 | 自午夜以来消耗的总卡路里,包括活动和基础能量消耗(BMR)。 | | `health_connect_vo2_max` | 毫升每分钟每千克 | 最后记录的 VO2 max 得分。 | | `health_connect_weight` | 克 | 最后记录的体重。 | ## 高精度模式 Android 此传感器的状态将反映设备当前是否启用了[高精度模式](/companion/core/location.md#high-accuracy-mode)。一旦高精度模式状态发生变化,此传感器就会更新,直到首次启用高精度模式,传感器才会出现。 ## 高精度更新间隔 Android 此传感器的状态将反映[高精度模式](/companion/core/location.md#high-accuracy-mode)的设备更新间隔(秒)。一旦值发生变化(手动或通过[通知命令](/companion/notifications/commands.md#high-accuracy-mode)),此传感器就会更新。 ## 交互传感器 Android 此传感器的状态将反映设备是否处于交互状态。这通常是屏幕开启和关闭时,但可能因设备而异。一旦检测到状态变化,此传感器就会更新,数据由 [PowerManager](https://developer.android.com/reference/android/os/PowerManager.html) 提供。 使用 [History Stats 集成](https://www.home-assistant.io/integrations/history_stats/),可以监控每日屏幕时间 `type: time` 以及当天屏幕开启的次数 `type: count`。 ## Keyguard 传感器 Android 这些传感器将反映来自 [Keyguard Manager](https://developer.android.com/reference/android/app/KeyguardManager) 的各种状态。您将能够确定设备是否主动锁定、是否设置了密码,甚至设备是否需要密码才能解锁。这些传感器将在定期传感器间隔期间更新。 ## 上次重启传感器 Android
此传感器的状态将是设备上次重启的日期和时间,采用 UTC 格式。传感器将在正常传感器更新间隔期间更新。如果无法确定时间戳,状态将为 `unavailable`。此传感器使用 [SystemClock](https://developer.android.com/reference/android/os/SystemClock?hl=en) 和当前 [System](https://developer.android.com/reference/java/lang/System?hl=en) 时间来计算时间戳。此传感器提供一个死区设置,默认为 1 分钟,以解决某些运营商上看到的时间计算问题。 | 属性 | 描述 | | --------- | --------- | | `Local Time` | 上次重启的本地日期和时间。 | | `Time in Milliseconds` | 上次重启的日期和时间(毫秒)。 | ## 上次更新触发器传感器 Android 对于 Android,此传感器的状态将反映最近发送更新的[意图](https://developer.android.com/reference/android/content/Intent)。此外,传感器提供设置允许用户从广播意图的其他 Android 应用接收[应用事件](/companion/integrations/app-events.md)。用户可以根据需要注册任意数量的意图,一旦收到意图,就会向 Home Assistant 发送事件。保存意图后,请务必重启应用以注册意图。 如果您注意到您在设置中注册的意图不再被应用触发,那么您需要添加意图期望的类别。您可以通过编辑意图的设置并在意图后添加 `,` 后跟类别来添加类别。如果需要多个类别,则需要添加每个类别后跟 `,`,直到没有更多类别要添加。例如,如果您的意图需要 2 个类别,格式将是:`intent,category1,category2`。保存意图和类别后,确保重启应用。 iOS
此传感器准确显示导致从设备到 Home Assistant 的位置和传感器数据最后更新的原因。 | 状态 | 描述 | | --------- | --------- | | Manual | 当用户下拉刷新时触发手动更新。 | | Launch | 初始应用启动时更新传感器。 | | Periodic | 根据 [配置](https://my.home-assistant.io/redirect/config/) -> Companion App -> 传感器中的设置定期更新。 | | Significant Location Change | 当设备的位置发生显著变化时触发,例如 500 米或更多。有关更多详细信息,请参阅[位置](/companion/core/location.md)。 | | Geographic Region Entered | 当进入任何用户指定的 Home Assistant [区域](https://www.home-assistant.io/components/zone/)(也称为地理围栏)时触发。 | | Geographic Region Exited | 当退出任何用户指定的 Home Assistant [区域](https://www.home-assistant.io/components/zone/)(也称为地理围栏)时触发。 | | Push Notification | 通过推送通知[请求位置更新](/companion/notifications/commands.md#request-location-updates)。 | | Background Fetch | 当应用在后台刷新传感器信息时。 | | Siri | 通过 [Siri 快捷方式](/companion/integrations/siri-shortcuts.md) "发送位置"快捷方式触发的位置更新。 | | iBeacon Region Entered | 当看到与已知区域对应的 iBeacon 时触发。 | | Registration | 当应用首次连接到您的 Home Assistant 实例时触发一次。 | | Signaled | 当应用在运行时检测到变化(例如电池状态变化)时触发。 | ## 上次使用的应用传感器 Android 6+
传感器的状态将始终是上次使用的应用的包名称,以确保它始终是唯一值。应用的标签将是传感器的一个属性(如果已知)。此传感器在正常传感器更新间隔期间更新,并使用 [UsageStatsManager API](https://developer.android.com/reference/android/app/usage/UsageStatsManager)。 ## 光线传感器 Android
此传感器将反映设备检测到的当前照度级别。传感器在正常传感器更新间隔期间或与其他传感器更新一起更新,并使用 [环境传感器](https://developer.android.com/guide/topics/sensors/sensors_environment)。 ## 移动数据传感器 Android
关于移动数据状态的几个不同传感器。这些传感器使用 [Settings.Global](https://developer.android.com/reference/kotlin/android/provider/Settings.Global?hl=en) 和 [TelephonyManager](https://developer.android.com/reference/android/telephony/TelephonyManager?hl=en) 来获取移动数据状态。 | 传感器 | 描述 | | ------ | ----------- | | `mobile_data` | 设备上的移动数据是否已开启。 | | `mobile_data_roaming` | 设备上的移动数据漫游是否已开启。 | ## 下一个闹钟传感器 Android
此传感器的状态将是下一个闹钟的日期和时间,采用 UTC 格式。一旦计划了下一个闹钟,传感器就会更新。当没有下一个闹钟时,状态将为 `unavailable`。此传感器使用 [AlarmManager](https://developer.android.com/reference/android/app/AlarmManager?hl=en) 来获取下一个计划的闹钟,该闹钟可以由任何应用在任何时间设置。此传感器有设置,允许您通过选择要从中获取闹钟事件的包来创建允许列表,请记住 API 只能获取下一个计划的闹钟。此设置默认关闭。 | 属性 | 描述 | | --------- | --------- | | `Local Time` | 下一个闹钟的本地日期和时间。 | | `Package` | 计划下一个闹钟的包。 | | `Time in Milliseconds` | 下一个闹钟的日期和时间(毫秒)。 | ## NFC 状态传感器 Android 此传感器的状态将反映设备是否当前启用了 NFC 传感器。一旦检测到状态变化,此传感器就会更新。数据由 [NfcAdapter](https://developer.android.com/reference/android/nfc/NfcAdapter) 提供。 ## 通知传感器 Android
注意:带有允许列表的传感器在允许的应用之一收到新通知之前,不会在 Home Assistant 中显示为新实体。 ### 最后一个通知 此传感器将反映设备上发布的最后一个通知。此传感器需要一个特殊权限,应用会将用户带到该权限以授予通知访问权限。此传感器的状态默认为通知的文本,如果不可用则为发布包名称。此传感器提供一个允许列表设置,让用户选择他们希望从哪些包获取通知数据,Home Assistant 发送的通知始终被忽略。您需要创建一个允许列表或启用"禁用允许列表要求"的设置。请记住,没有允许列表,此传感器有可能消耗大量电池。我们强烈建议创建允许列表而不是禁用此要求。这对于集成任何发送通知但不提供直接集成的应用(例如:外卖应用或 2FA 短信代码)非常有用。用户可以期待看到几个属性,尽管并非所有属性都包含数据。此传感器使用 [NotificationListenerService API](https://developer.android.com/reference/android/service/notification/NotificationListenerService#onNotificationRemoved\(android.service.notification.StatusBarNotification\))。有关每个属性的更多详细信息可以在 [Notification Extras](https://developer.android.com/reference/android/app/Notification) 中找到。 ### 最后删除的通知 此传感器与最后一个通知类似,不同之处在于当通知已从设备中删除(由用户或应用程序)时,它将更新。您可以为此传感器期待类似的属性,其中一些概述如下。此传感器需要与上面提到的相同的权限。此传感器也有一个允许列表,其功能类似于最后一个通知。 ### 活动通知计数 此传感器将反映设备上的活动通知总数。此计数将包括持久和/或静默的通知。有时它甚至可能包括传感器工作器通知。每当任何其他传感器有更新时,此传感器都会更新。此传感器需要与最后一个通知中提到的相同的权限。此传感器没有允许列表。

下面您可以找到某些通知可以提供的详细信息。除非您禁用相应的传感器设置,否则这些将作为属性提供。 | 属性 | 描述 | | --------- | --------- | | `android.appInfo` | 包含包名称的应用信息。 | | `android.infoText` | 通知的信息文本。 | | `android.largeIcon` | 通知的大图标。 | | `android.progress` | 通知的进度(如果有进度条)。 | | `android.progressIndeterminate` | 进度是否可以确定。 | | `android.progressMax` | 进度的最大位置(例如:100% 为 100)。 | | `android.reduced.images` | 通知上的图像是否已缩小。 | | `android.remoteInputHistory` | 通知的最近输入。 | | `android.showChronometer` | 是否显示计时器。 | | `android.showWhen` | 通知是否应在特定时间显示。 | | `android.subText` | 通知的副标题。 | | `android.text` | 通知的文本。 | | `android.title` | 通知的标题。 | | `is_clearable` | 通知是否可以清除。 | | `is_ongoing` | 通知是否在设备上持久存在。 | | `package` | 发布通知的包。 | | `post_time` | 通知在设备上发布的时间。 | | `channel_id` | 通知发布到的频道的 ID。此属性仅在 Android 8+ 上可用。 | | `group_id` | 通知发布到的组的 ID。 | | `category` | 通知定义的类别。 | ### 媒体会话传感器 Android
此传感器需要通知权限才能启用并发送数据。状态将是主媒体会话的播放状态。如果没有活动的媒体会话,则状态将为 `unavailable`。属性将包括活动会话的总数以及按包名称分隔的所有活动会话的媒体数据。此传感器将在正常传感器更新间隔期间更新。为了充分利用此传感器,我们建议使用[最后一个通知](#last-notification)来挂钩您的媒体应用以发送更快的更新。此传感器使用 [MediaController](https://developer.android.com/reference/android/media/session/MediaController) 和 [MediaSessionManager](https://developer.android.com/reference/android/media/session/MediaSessionManager) API 来获取数据。 ## 计步器传感器 iOS
计步器传感器从设备内置的运动处理器提供步数数据。它们记录您的日常步行活动,并在午夜重置。这些传感器需要启用运动权限。 | 传感器 | 描述 | | --------- | --------- | | `sensor.steps` | 用户走的步数。 | | `sensor.distance` | 用户行走的估计距离(米)。 | | `sensor.average_active_pace` | 用户的平均配速,以秒每米测量。 | | `sensor.floors_ascended` | 步行上楼的近似楼层数。 | | `sensor.floors_descended` | 步行下楼的近似楼层数。 | Android Android 用户将只有一个 `sensor.steps` 实体,它将表示自上次设备重启以来的总步数。获取每日步数的推荐方法是使用 `cycle: daily` 的 [Utility Meter 集成](https://www.home-assistant.io/integrations/utility_meter)。此传感器将在正常传感器更新间隔期间更新,并使用 [运动传感器](https://developer.android.com/guide/topics/sensors/sensors_motion?hl=en)。此传感器需要 [Activity Recognition 权限](https://developer.android.com/reference/android/Manifest.permission#ACTIVITY_RECOGNITION)。 ## 电话传感器 ### 数据网络类型传感器 Android
SIM 插槽为数据传输提供的无线电技术(网络类型)。数据由 [TelephonyManager](https://developer.android.com/reference/android/telephony/TelephonyManager?hl=en) 提供。 :::info 并非所有 5G 网络都是平等的,因此某些网络可能会识别为 LTE ::: ### 电话状态传感器 Android
只有当用户在设备的应用信息屏幕中明确授予应用 `Phone` 权限时,此传感器才会显示。此传感器跟踪的唯一数据是以下状态:`idle`、`ringing`、`offhook`。每当检测到电话状态变化时,此传感器都会更新,并使用 [TelephonyManager](https://developer.android.com/reference/android/telephony/TelephonyManager?hl=en)。此传感器需要 [Read Phone State 权限](https://developer.android.com/reference/android/Manifest.permission#READ_PHONE_STATE)。 ### 信号强度传感器 Android
一个传感器,表示 SIM 插槽提供的蜂窝信号强度(dBm)。属性将存在信号质量以及任意强度单位。由于省电,此数据可能并不总是最新的。数据由 [TelephonyManager](https://developer.android.com/reference/android/telephony/TelephonyManager?hl=en) 提供。 ## 省电传感器 Android
此传感器将显示设备上省电模式的状态。根据设备的不同,这通常是一个用户可配置的选项,用于指示设备何时应进入特殊省电模式。一旦检测到状态变化,状态就会更新,传感器使用 [PowerManager](https://developer.android.com/reference/android/os/PowerManager.html)。 ## 压力传感器 Android
此传感器将显示设备的当前压力读数。此传感器将在正常传感器更新间隔期间更新,并使用 [环境传感器](https://developer.android.com/guide/topics/sensors/sensors_environment)。 ## 接近传感器 Android
此传感器将显示设备的当前接近读数。此传感器将在正常传感器更新间隔期间更新。并非所有设备都报告实际读数,因此这些设备将根据传感器的最大范围是否为 `5` 来显示 `near` 或 `far`。此传感器使用 [位置传感器](https://developer.android.com/guide/topics/sensors/sensors_position?hl=en)。 ## 公共 IP 传感器 Android
此传感器使用 [ipify API](https://www.ipify.org/) 来确定设备的公共 IP 地址。此传感器将在正常传感器更新间隔期间更新。 ## 存储传感器 iOS
此传感器显示设备存储的信息。报告的文件大小采用十进制。 | 属性 | 描述 | | --------- | --------- | | `Available` | 设备上剩余的可用存储量。 | | `Available (Important)` | 卷的可用容量(字节),用于存储重要资源。 | | `Available (Opportunistic)` | 卷的可用容量(字节),用于存储非必要资源。 | | `Total` | 设备的总存储容量。 | Android
对于 Android,由于两个操作系统的差异,行为略有不同。状态将与 iOS 相同,我们显示可用空间的百分比,属性不会相同。这些传感器将在正常传感器更新间隔期间更新,计算借助于 [StatFs](https://developer.android.com/reference/android/os/StatFs?hl=en) 完成。 `sensor.internal_storage` | 属性 | 描述 | | --------- | --------- | | `Free internal storage` | 设备上剩余的可用内部存储空间。 | | `Total internal storage` | 设备的总内部存储容量。 | `sensor.external_storage` | 属性 | 描述 | | --------- | --------- | | `Free external storage` | SD 卡上剩余的可用外部存储,对于没有 SD 卡的设备,它将反映 `No SD Card`。 | | `Total external storage` | SD 卡的总外部存储,对于没有 SD 卡的设备,它将反映 `No SD Card`。 | ## 流量统计传感器 Android
这些传感器将显示设备传输和接收的总数据。有总传感器和移动传感器可供使用,统计数据在设备重启时重置。这些传感器使用 [Traffic Stats API](https://developer.android.com/reference/android/net/TrafficStats)。 ## 工作配置文件传感器 Android
如果设备的工作配置文件已启用,此传感器将为 `on`,否则为 `off`。此传感器使用 [Device Policy Manager API](https://developer.android.com/reference/android/app/admin/DevicePolicyManager)。 --- url: /companion/gallery/index.md --- # Android 截图画廊 Android 截图 ## 引导流程 ### 欢迎 应用的第一屏 ### 发现 此屏幕将显示所有发现的 Home Assistant 实例,如果发现失败,您可以选择 `手动输入地址` ### 手动设置 在此屏幕上,您可以手动输入您的 Home Assistant 实例,以防发现未能找到它。 ### 认证 在此屏幕上,您将登录到您的 Home Assistant 服务器 ### 最后一步 在此屏幕上,您可以更改默认设备名称,如果您使用的是 Play Store 版本,还可以启用位置追踪。 ## 设置 配置 > 伴侣应用中的所有设置




### 管理传感器 所有传感器的列表,您可以使用顶部的筛选器仅显示已启用的传感器,也可以进行搜索 ### 传感器详情 传感器的所有详细信息,包括状态和属性。您还可以从此页面配置传感器设置。 ### NFC 创建和读取 NFC 标签 ### 持久连接设置 管理持久连接以获取本地推送通知 ### 通知历史 最近 25 条通知,您可以使用顶部的筛选器显示最近 100 条,也可以搜索所有通知。 ### 通知详情 通知的完整详情 ### 管理快捷设置磁贴 设置和编辑快捷设置磁贴,它们需要先在应用中配置才能使用 ### 管理启动器快捷方式 设置和编辑启动器快捷方式,以快速导航到前端的任何位置。 ### 管理小部件 在主屏幕上创建和编辑小部件 ### 日志 查看和分享设备上的日志 ## 小部件 小部件的配置页面 ### 实体状态小部件 ### 服务调用小部件 ### 媒体播放器小部件 ### 模板小部件 ### 小部件主屏幕 所有小部件在主屏幕上的外观 --- url: /companion/getting_started/connection_security_level.md --- # 连接安全级别 如果您想使用非加密 URL 连接到 Home Assistant(例如本地连接的本地 IP 地址),您必须设置连接安全级别。您可以在应用中选择两个安全选项。 :::note 在添加新服务器时需要选择一个选项。如果您在添加连接安全级别选项之前添加了服务器,启动应用时会要求您选择一个。 ::: ## 选项 1:最安全(推荐) 此选项确保应用仅在您当前位于指定的家庭网络时才连接到非加密 URL(例如 `http://homeassistant.local:8123`)。当您不在指定的家庭网络时,应用会显示一个阻止访问的屏幕,并描述连接要求。这也意味着后台活动将被阻止,直到可以建立安全连接。 您可以指定您的 Wi-Fi SSID(例如 "GrandmaHome5G")作为您的家庭网络。要更改设置,请随时打开 [**设置**](https://my.home-assistant.io/redirect/config/) > **Companion 应用** > **\[服务器名称]**。
**附加选项** **Android** 您还可以将使用 VPN 或以太网访问设置为家庭网络。 **macOS** 您可以将"硬件地址"定义为家庭网络,这对于有线连接很有用。
要检索上述信息,应用需要您设备的位置访问权限,因为网络信息可用于位置定位。我们理解这对所有用户来说都不理想,但此限制是由 Apple 平台和 Android 强加的。您的位置永远不会用于检索网络信息以外的任何用途。您始终可以控制是否要将位置共享到本地 Home Assistant 服务器。 :::warning 重要 位置权限必须设置为 **始终** 和 **精确**(iOS)以及 **始终允许**(Android),应用才能在后台正常运行。 ::: ## 选项 2:较不安全 如果您不授予位置权限或在操作系统级别禁用位置,但仍需要访问非加密 URL(例如 `http://homeassistant.local:8123`),您可以选择此选项。仅在绝对必要时使用;**不建议使用**,因为它可能会使您的 Home Assistant 数据暴露于网络窃听,尤其是在公共 Wi-Fi 上。 ## 为什么存在这些选项 引入这些安全选项是为了在使用非加密连接时保护您的 Home Assistant 实例免受潜在安全风险。 当您使用非加密 URL(例如 `http://homeassistant.local:8123`)连接到 Home Assistant 时,您的设备和 Home Assistant 之间传输的所有数据都以纯文本形式发送。这包括您的登录凭据和您发送的任何命令。在您的家庭网络上,这通常是可以接受的,因为流量保留在您的本地网络内。但是,如果您意外地从公共 Wi-Fi 网络或不受信任的位置连接,恶意行为者可能会拦截您的 Home Assistant 数据。 **最安全**选项通过确保非加密连接仅在您位于家庭网络时才工作来防止这些风险。**较不安全**选项移除了此保护,不建议大多数用户使用。 为了最大程度的安全性,我们建议始终使用具有有效 SSL 证书的 HTTPS 连接,尤其是在远程访问 Home Assistant 时。 要了解更多关于网络的信息,请查看我们的 [故障排除部分](/companion/troubleshooting/networking.md)。 ## 常见问题 ### 为什么我看到连接安全提示? 从 2025.11 版本开始,如果您的设置包含非加密 URL(HTTP 而不是 HTTPS),Companion 应用会要求您选择安全级别。此提示有助于保护您的 Home Assistant 凭据免于在公共网络上暴露。 如果您所有 URL 都使用 HTTPS 但仍看到此提示,请更新到最新版本的应用。 ### "最安全"和"较不安全"是什么意思? * **最安全**:应用仅在您位于指定的家庭网络时才使用非加密连接。这需要位置权限,以便应用可以检查您当前的 Wi-Fi SSID。 * **较不安全**:无论您在哪个网络上,应用都会使用非加密连接。如果您曾经连接到公共 Wi-Fi 网络,不建议使用此选项。 :::warning 如果您从公共网络连接,选择"较不安全"可能会暴露您的 Home Assistant 凭据。使用此选项时,请确保您信任所有连接的网络。 ::: ### 启用"最安全"后,当我不在家庭网络时会发生什么? 应用会阻止访问并显示一个说明情况的屏幕。后台活动(例如小部件和传感器)也会暂停,直到可以建立安全连接。 不在家庭网络时显示的阻止屏幕 发生这种情况是因为应用无法验证您是否在可信网络上,因此它拒绝通过潜在不安全的连接发送凭据。一旦您返回家庭网络(或通过 HTTPS 连接),应用将自动恢复正常运行。 如果您看到带有附加提示的阻止屏幕,这意味着应用需要某些东西才能正常工作——例如位置权限或家庭网络配置。 需要操作的阻止屏幕 ### 如何设置我的家庭网络? 1. 在提示时授予位置权限(**最安全**选项需要)。 2. 连接到您的家庭 Wi-Fi 网络。 3. 进入 [**设置**](https://my.home-assistant.io/redirect/config/) > **Companion 应用** > **\[您的服务器]** > **内部 URL**。 4. 将您的家庭 Wi-Fi SSID 添加到列表中。 如果您有多个家庭网络,可以添加多个 SSID。 ### 我可以指定硬件地址(以太网)而不仅仅是 SSID 吗? 在 macOS 上可以。 在 Android 和 iOS 上,目前不可用。对于 iOS,这是由于平台限制。 ### 当我通过 VPN 连接时,此功能是否有效?
**Android** 您可以在 [**设置**](https://my.home-assistant.io/redirect/config/) > **Companion 应用** > **\[您的服务器]** > **家庭网络** 中选择 **VPN 已连接** 选项作为家庭网络。 :::note 此选项仅检测连接到*任何* VPN。由于平台限制,无法检测连接到特定 VPN。 :::
**iOS** 不可以。连接安全级别功能使用您的 Wi-Fi SSID 来确定您是否在家。通过 VPN 连接时,应用无法通过 Wi-Fi 检测您的物理位置。 如果您依赖 VPN 进行远程访问,则需要以不同方式配置您的设置: 1. 将您的本地 Home Assistant 地址设置为 **外部 URL**(因为无论在家还是外出,您都以相同方式访问它)。 2. 确保每当您想远程与 Home Assistant 交互时都连接 VPN。 :::warning 如果您将本地 (HTTP) 地址设置为外部 URL,并且忘记在公共网络上连接 VPN,这可能会暴露您的 Home Assistant 凭据。 :::
### 我使用 VPN 进行所有远程访问。我应该启用此功能吗? 如果您已将本地地址设置为外部 URL,连接安全级别设置不会影响应用的连接方式:它将始终使用该外部 URL。 但是,对于高级用例,您可能仍希望使用不同的内部和外部 URL。在这种情况下,启用**最安全**选项以确保您的内部(可能是 HTTP)URL 仅在您实际在家时使用。 ### 如果 Home Assistant 不可达,应用会发送我的凭据吗? 是的,应用会尝试使用您配置的 URL 进行连接,例如,当检索实体状态以在小部件中显示或在快捷指令应用中执行快捷方式时。 如果您的外部 URL 是 HTTP(不建议用于远程访问),当应用尝试连接时,凭据将以非加密方式发送。要防止此行为,请使用**最安全**选项。 ### 我选择了"较不安全",但现在想更改它。如何操作? 进入 [**设置**](https://my.home-assistant.io/redirect/config/) > **Companion 应用** > **\[您的服务器]** > **连接安全级别** 随时更改您的偏好。要定义您的家庭网络,请进入 [**设置**](https://my.home-assistant.io/redirect/config/) > **Companion 应用** > **\[您的服务器]** > **内部 URL**。 ### 如果我不授予位置权限会发生什么? 没有位置权限,应用无法确定您当前连接到哪个网络。如果您选择**最安全**但不授予位置访问权限,应用将只能使用您的外部 (HTTPS) URL。 如果您需要使用非加密的内部 URL 并且不想授予位置权限,您需要选择"较不安全"——但请[注意安全影响](#选项-2较不安全)。 --- url: /companion/getting_started/index.md --- # 入门指南 ## 系统要求 | 平台 | 最低版本 | 备注 | |----------|-----------------|-------| | ![iOS](/companion-assets/iOS.svg) iOS | iOS 15+ | iPhone 6s 或更新机型 | | ![Android](/companion-assets/android.svg) Android | Android 6+ | 提供 `完整版` 和 `精简版` [两种版本](/companion/core/android-flavors.md) | 需要 [Home Assistant](https://www.home-assistant.io/installation/) 0.104.0 或更新版本。了解更多关于 [Home Assistant Cloud](https://support.nabucasa.com/hc/en-us/categories/24734619902749) 和 [远程访问](https://support.nabucasa.com/hc/en-us/sections/26496346499997)。 ## 设置步骤 如果您与 Home Assistant 服务器在同一网络,应用会自动检测到它。或者,如果您的 Home Assistant 服务器已配置 [远程访问](https://www.home-assistant.io/docs/configuration/remote/),您可以从任何位置设置应用。 ### 逐步设置 1. **下载应用**:获取 [Home Assistant Companion 应用](/download.md)。 2. **欢迎界面**:打开应用,选择 **连接到我的 Home Assistant 服务器** 开始设置。 3. **网络发现**:应用会搜索您网络上的 Home Assistant 服务器。
**自动发现服务器** 如果只发现一个 Home Assistant 服务器,应用会自动提示您连接。 Home Assistant Companion 应用显示单个已发现的服务器准备连接
**发现多个服务器** 如果发现多个 Home Assistant 服务器,您会看到一个列表供选择。点击您要连接的服务器。 Home Assistant Companion 应用显示多个已发现服务器的列表供选择
**未发现服务器或远程连接** 如果未发现服务器,或者您从家庭网络外部连接: 1. 点击 **手动输入地址** 2. 输入您的 Home Assistant URL
Home Assistant Companion 应用显示未发现服务器,带有手动输入地址按钮 Home Assistant Companion 应用手动服务器输入界面,带有 URL 输入框
:::tip 推荐使用 [Home Assistant Cloud](https://www.nabucasa.com/config/remote/) 远程访问来实现安全的远程连接。 :::
4. **登录**:输入您的 Home Assistant 凭据进行身份验证。 :::info 始终使用您的 Home Assistant 凭据登录。如果您启用了 [可信网络](https://www.home-assistant.io/docs/authentication/providers/#trusted-networks),请避免在应用中使用它,否则应用只能在可信网络上工作。 ::: 5. **设备命名**:为您的设备选择一个名称,它将显示在 Home Assistant 中。此名称用于标识您的设备实体,以及在自动化和操作中。 6. **位置权限**:应用会请求位置访问权限以启用自动化和安全连接。 * 位置共享可启用 [自动化](/companion/core/location.md),例如当您离开家时关闭暖气 * 您的位置数据保留在家中,永远不会发送给第三方 * 位置还有助于加强您与 Home Assistant 连接的安全性 * 选择 **共享我的位置** 或 **不共享我的位置**
**Android** 应用需要 **位置:始终允许** 和 **附近的设备** 权限,以便后台位置更新正常工作。
Home Assistant 应用位置共享提示 Android 位置权限对话框 Android 附近设备权限对话框 Android 系统位置权限设置为始终允许
**iOS** 您的设备会显示标准的位置权限对话框。 * 选择 **允许一次**、**使用应用时允许** 或 **不允许** * 要获得完整功能,包括后台自动化,请选择 **使用应用时允许**,然后在下一个提示中选择 **始终允许**
7. **连接安全级别**:如果使用非加密 URL(如本地 IP 地址),请选择安全级别: * **最安全**:仅当您在家庭网络时允许非加密连接(需要位置权限) * **较不安全**:允许来自任何网络的非加密连接(不建议在公共网络使用) * 了解更多关于 [连接安全级别](/companion/getting_started/connection_security_level.md) 8. **设置您的家庭网络**(仅限最安全):如果您在上一步选择了 **最安全**,系统会要求您确认您的家庭网络。 * 应用会检测您当前的 Wi-Fi 网络 (SSID) 并将其预填为您的家庭网络 * ![Android](/companion-assets/android.svg) 在 Android 上,您还可以使用 VPN 或以太网作为可信网络 * 这允许应用知道您何时在家,可以安全地使用非加密连接 * 您稍后可以在 [**设置**](https://my.home-assistant.io/redirect/config/) > **Companion 应用** > **\[您的服务器]** 中添加其他可信网络 9. **设置完成**:应用会完成连接并带您进入 Home Assistant 仪表板。 :::tip 如果您在设置应用时遇到困难,请参阅 [故障排除指南](/companion/troubleshooting/setup.md)。 ::: ### 通知 设置完成后,系统会要求您启用通知。这允许 Home Assistant 向您发送自动化警报、提醒和更新通知。 :::info 在 iOS 上,系统还会要求您允许 **关键通知**。这些是高优先级警报,即使您的设备处于静音模式或启用了勿扰模式,也会播放声音。 ::: 了解更多关于如何从 Home Assistant [发送通知](/companion/notifications/basic.md)。 ## 添加其他服务器 :::note 需要 Home Assistant 2021.10 或更新版本。 ::: 设置好第一个服务器后,您可以添加其他 Home Assistant 服务器: 1. 在 Companion 应用中,进入 [**设置**](https://my.home-assistant.io/redirect/config/) > **Companion 应用**。 2. 选择 **添加服务器**。 * 同一局域网上的服务器会自动被发现。 3. 如果服务器未列出,点击 **手动输入地址** 并提供 URL。 ## TLS 客户端认证 ![Android](/companion-assets/android.svg) 如果您的 Home Assistant 需要 TLS 客户端认证(因为它位于配置为执行 TLS 客户端认证的反向代理后面),应用会请求证书。如果没有安装或提供匹配的证书,您可能会看到错误或空白屏幕,具体取决于您的设置。 请参阅您的设备和 Android 版本文档以安装证书。确保将证书安装为"VPN 和应用用户证书"。Pixel 手机的示例可在此处找到:[添加和删除证书](https://support.google.com/pixelphone/answer/2844832?hl=en)。 :::info Wear OS 不支持使用已安装的证书进行认证。应用无法自动将证书传输到 Wear OS 应用,因此在 Wear OS 应用引导过程中会要求您提供证书。证书和密钥需要以 PKCS12 格式作为单个文件提供。如果这不起作用,请参阅 [故障排除步骤](/companion/troubleshooting/networking.md#tls-client-authentication)。 ::: --- url: /companion/index.md --- # Home Assistant 配套应用文档 - iOS、Android 与移动端接入 | 老王杂谈说 --- url: /companion/integrations/android-device-controls.md --- # Android 设备控制 Android Android 应用将自动集成到运行 Android 11 或更高版本且支持此功能的设备上的[智能家居设备控制](https://developer.android.com/guide/topics/ui/device-control)功能。所需的是您能够登录应用并远程使用它。 要开始使用,请在您的设备上打开设备控制。您会在哪里找到它们取决于设备制造商和 Android 版本,一些常见的地方是:在快速设置面板中、在通知抽屉中或在电源菜单中。点击"添加控制"并选择 Home Assistant 应用。下面列出的所有域都可以添加到设备控制面板中。 点击磁贴将其打开或关闭。某些域还允许您通过在磁贴上前后滑动手指来增加或减少范围。 支持以下域: * `automation` 开/关 * `button` 按下 * `camera` 快照图像(仅在 Android 12 或更高版本上支持) * `climate` 温度滑块,循环切换模式 * `cover` 打开/关闭 * `fan` 开/关,速度滑块 * `humidifier` 开/关 * `input_boolean` 开/关 * `input_button` 按下 * `input_number` 数字控制滑块 * `light` 开/关,亮度控制滑块 * `lock` 锁定/解锁 * `media_player` 播放/暂停,音量控制滑块 * `number` 数字控制滑块 * `remote` 开/关 * `scene` 开启场景 * `script` 开启脚本 * `siren` 开/关 * `switch` 开/关 * `vacuum` 启动/返回或开/关,取决于吸尘器类型 ## 锁定时使用 在 Android 11 上,您可以在设备锁定时使用添加的控件。 在 Android 12 上,您不能在设备锁定时使用添加的控件。 在 Android 13 及更高版本上,您可以控制在设备锁定时使用添加的控件。首先,确保您已在系统设置中启用了锁定时使用设备控制的选项(设置应用 > 显示 > 锁定屏幕)。现在您可以在设备锁定时使用添加的控件!如果您想更改特定控件或实体的设置,请打开 Home Assistant 并转到[设置](https://my.home-assistant.io/redirect/config/) > 伴侣应用 > 管理设备控制。 ## 使用仪表板代替内置控件 从 Android 14 开始,在支持的设备上,您还可以在使用设备控制功能时显示 Home Assistant 仪表板而不是内置控件。两种模式各有优势:内置控件易于使用,允许您管理每个实体的锁定设置并并排控制多个服务器,而仪表板支持所有 Home Assistant 功能并允许完全自定义控件以满足您的需求。上面的文档描述了内置控件。 要在模式之间切换,请打开应用并转到[设置](https://my.home-assistant.io/redirect/config/) > 伴侣应用 > 管理设备控制,然后选择"内置"或"仪表板"。选择仪表板后,您还可以输入要使用的仪表板路径(例如:`/lovelace/default_view` 或 `/lovelace-dashboardname/viewname`)以使用与默认不同的仪表板。 :::info 从内置设备控件切换到仪表板时:如果您之前使用过内置设备控件,您可能需要在显示仪表板之前删除所有控件。 ::: ## 将多个服务器拆分为单独的页面 如果您在伴侣应用中登录了多个服务器,您可以将这些服务器拆分为单独的"结构"。这将使每个服务器的控件显示在设备控制内的不同页面上(就像您有其他应用输入到设备控制一样)。 默认情况下这是禁用的,但如果您希望启用它,您必须在应用中添加了多个服务器。要启用它,请打开应用并转到[设置](https://my.home-assistant.io/redirect/config/) > 伴侣应用 > 管理设备控制,然后切换"将多个服务器拆分为设备控制内的单独页面"。您可能需要删除并重新添加设备控制,以便在设备控制中显示拆分。 --- url: /companion/integrations/android-home-app-launcher.md --- # Android 主屏幕应用(启动器) Android Home Assistant 伴侣应用可以设置为设备的默认主屏幕应用(启动器)。这会将您的 Android 设备变成专用的 Home Assistant 控制面板,非常适合壁挂式平板电脑或信息亭。 ## 什么是主屏幕应用? 主屏幕应用(也称为"启动器")是您按下主页按钮时显示的应用。通过将 Home Assistant 设置为您的主屏幕应用,您的设备会直接启动到 Home Assistant,使其成为专用智能家居控制的理想选择。 ## 使用场景 * 壁挂式平板电脑:为您的家创建一个专用控制面板。 * 厨房显示屏:快速访问计时器、购物清单和家居控制。 * 床头平板电脑:从床头柜控制灯光、闹钟和媒体。 * 信息亭模式:为访客或家庭成员设置访问受限的设备。 * 数字标牌:显示仪表板、摄像头或信息屏幕。 ## 预期效果 当 Home Assistant 是您的默认主屏幕应用时: * 没有应用抽屉:按下主页按钮时,您不会看到已安装应用的常规列表。 * 无法直接启动应用:您不能以传统方式启动其他应用。请按照[将 Home Assistant 用作主屏幕应用时打开其他应用](#将-home-assistant-用作主屏幕应用时打开其他应用)中的步骤操作 * 主页按钮:返回 Home Assistant(如果已打开则刷新)。 * 返回按钮:当导航栈为空时,按下返回将刷新应用而不是什么都不做。 * 启动:设备在重启后自动打开 Home Assistant。 ## 启用 Home Assistant 作为主屏幕应用 1. 打开 Home Assistant 应用。 2. 转到[**设置**](https://my.home-assistant.io/redirect/config/) > **伴侣应用**。 3. 向下滚动到 **设备主屏幕**。 4. 启用 **用作主屏幕应用(启动器)**。 显示允许作为主屏幕应用的截图 5. 要打开允许您选择主屏幕应用的系统屏幕,请选择 **更改主屏幕应用**。 显示选择主屏幕应用系统屏幕的截图 ## 禁用 Home Assistant 作为主屏幕应用 如果您想切换回常规主屏幕应用: 1. 打开 Home Assistant 应用。 2. 转到[**设置**](https://my.home-assistant.io/redirect/config/) > **伴侣应用**。 3. 向下滚动到 **设备主屏幕**。 4. 要打开允许您选择 Home Assistant 以外的主屏幕应用的系统屏幕,请选择 **更改主屏幕应用**。 显示选择主屏幕应用系统屏幕的截图 ## 创建信息亭模式设置 为了获得最佳的信息亭或壁挂平板体验,请考虑这些附加设置: ### 启用本地推送 启用[本地推送](/companion/notifications/local.md)以利用: * 无限通知:来自您自动化的警报没有每日限制 * 无限命令:控制设备没有每日限制(更改音量、打开应用) * 更快的响应:通知和命令以更低的延迟到达和运行 * 无需互联网即可工作:只要您有网络连接,即使互联网断开也能继续工作 ### 保持屏幕开启 要防止屏幕关闭,请转到[**设置**](https://my.home-assistant.io/redirect/config/) > **伴侣应用**并向下滚动到 **其他设置**并启用 **保持屏幕开启**。 ### 信息亭模式仪表板 通过设置专用仪表板创建简化的体验: 1. 在 Home Assistant 中创建一个仅包含该设备所需控件的仪表板。 2. 在[**设置**](https://my.home-assistant.io/redirect/config/) > **仪表板** > 选择您的仪表板 > **在此设备上设置为默认**中为设备用户设置为默认。 :::tip 为每个信息亭设备创建一个专用的 Home Assistant 用户。这允许您为每个设备设置不同的默认仪表板。 ::: ## 将 Home Assistant 用作主屏幕应用时打开其他应用 由于 Home Assistant 没有应用抽屉,这里有两种启动其他应用的方法: ### 通过 Android 设置 1. 从屏幕顶部向下滑动以打开通知栏。 2. 点击 **设置齿轮** 图标。 3. 转到 **应用**,选择您想要的应用,然后点击 **打开**。 ### 从您的仪表板 使用[通知命令](/companion/notifications/commands.md)创建直接启动应用的按钮。这对于快速访问摄像头查看器或音乐播放器等应用很有用。 --- url: /companion/integrations/android-quick-settings.md --- # Android 快速设置 Android
Android 应用支持快速设置[磁贴](https://developer.android.com/reference/android/service/quicksettings/TileService),允许您从通知下拉菜单快速执行脚本/场景、按下(输入)按钮或切换支持的域。您可以完全自定义这些磁贴的外观,并可以按您认为合适的方式重新排列它们。此功能适用于运行 Android 7.0+ 的设备。要开始使用,请导航到[设置](https://my.home-assistant.io/redirect/config/) > 伴侣应用 > 管理磁贴。 应用目前提供最多 40 个磁贴供设置。每个磁贴必须设置标签,在 Android 10 或更高版本上可以选择设置子标签。选择标签和实体后,您将能够更新磁贴数据。更新后,磁贴就可以使用了:编辑设备的快速设置面板,并将 Home Assistant 磁贴从磁贴列表拖到活动部分。 添加磁贴后,状态、标签和图标将更新以反映实体的状态和磁贴设置。当您选择磁贴时,您会看到磁贴短暂亮起,同时应用调用服务器。如果成功,磁贴将返回显示实体的状态,如果失败,磁贴将变为禁用状态并显示错误消息。 支持以下域: * `automation` 切换 * `button` 按下 * `cover` 切换 * `fan` 切换 * `humidifier` 切换 * `input_boolean` 切换 * `input_button` 按下 * `light` 切换 * `lock` 锁定/解锁 * `media_player` 切换 * `remote` 切换 * `siren` 切换 * `scene` 开启场景 * `script` 开启脚本 * `switch` 切换 可选的附加设置: * 磁贴默认使用实体图标。点击图标可为磁贴使用不同的图标。 * 可以启用点击时振动,以便在点击磁贴时振动一次,如果操作失败则振动两次。 * 可以启用需要解锁设备,以便仅在设备解锁时才允许与磁贴交互。 --- url: /companion/integrations/android-shortcuts.md --- # Android 快捷方式 Android Android 应用支持动态和固定[快捷方式](https://developer.android.com/guide/topics/ui/shortcuts)。快捷方式允许用户直接从主屏幕导航到特定的仪表板页面或实体,而无需先启动应用。支持的设备将在[设置](https://my.home-assistant.io/redirect/config/)的伴侣应用下看到管理快捷方式部分。在那里,用户必须提供在启动器中显示的标签(Google 推荐 10 个字符)。还必须提供描述,因为某些启动器可能更喜欢显示它(Google 推荐 25 个字符)。 目前支持 2 种快捷方式类型:仪表板或实体。默认快捷方式类型是仪表板,您必须输入仪表板路径(例如:`/dashboard-name/viewname`、`/lovelace/default_view` 或 `/lovelace-dashboardname/viewname`)才能创建快捷方式。如果您选择了实体,您将看到一个新的实体字段,其中包含来自您的 Home Assistant 服务器的所有实体列表供您选择。选择后,您将能够创建快捷方式。 动态快捷方式在 Android 7.1+ 的设备上受支持。这些快捷方式需要从[设置](https://my.home-assistant.io/redirect/config/)中的伴侣应用添加,以便用户在长按应用图标后可以将其拖到主屏幕上。需要注意的是,Android 只支持在长按菜单下显示 5 个动态快捷方式,但是,大多数启动器只支持显示 4 个。所有 5 个快捷方式都可以更新,也可以从应用长按菜单中删除。 固定快捷方式在 Android 8.0+ 的设备上受支持。这些快捷方式只能从[设置](https://my.home-assistant.io/redirect/config/)中的伴侣应用创建,可以手动拖动或从此屏幕自动添加。它们不会显示在应用长按菜单下,而是直接显示在主屏幕上。用户可以添加的快捷方式数量没有限制。固定快捷方式可以随时更新。 --- url: /companion/integrations/android-webview.md --- # Android WebView Android ## 自动播放视频 Android Android 应用能够在加载更多信息面板时自动播放视频。某些设备可能默认已经这样做,但其他设备可能需要在[设置](https://my.home-assistant.io/redirect/config/) > 伴侣应用中启用此设置。启用此设置可能会意外增加数据使用量,请谨慎操作。 ## 应用启动时始终显示第一个视图 Android Android 应用能够在打开应用时始终打开用户选择的默认仪表板的第一个视图。第一个视图是 Home Assistant 标题栏上的第一个标签页。 ![第一个视图](/companion-assets/ha_first_view.png) 这非常有用,如果您的第一个视图包含有关智能家居的所有重要信息。如果您随后在另一个*不太重要的视图*上关闭应用,稍后再次打开应用时,您将立即在第一个视图上再次看到您的重要智能家居信息。 :::caution 如果您在 Home Assistant 配置或伴侣应用配置中,则打开应用时不会显示仪表板的第一个视图! ::: ## 保持屏幕开启 Android Android 应用能够通过在[设置](https://my.home-assistant.io/redirect/config/) > 伴侣应用中启用相应设置,在 WebView 活动处于活动状态时保持屏幕开启。这让您的设备屏幕可以无限期保持开启,并忽略 Android 内置的睡眠设置。 此功能也可以通过通知命令控制,[参见详情](/companion/notifications/commands.md#screen-on)。 ## 链接 Android Android 应用能够拦截某些类型的链接,允许用户直接启动设备上找到的其他应用(如果未找到,则带用户去安装应用)。用户还可以使用[意图方案](https://developer.chrome.com/docs/multidevice/android/intents/#syntax)执行应用支持的任何操作。 使用 Lovelace 实体卡片 [weblink](https://www.home-assistant.io/dashboards/entities/#weblink) 的示例: 此示例将在设备上安装了 X 时启动它,否则将打开 Google Play 商店应用或网站。 ```yaml - type: weblink name: X url: "app://com.twitter.android" ``` 此示例将通过意图方案启动条形码扫描应用准备扫描,如果应用未安装,用户将被引导去安装它。 ```yaml - type: weblink name: 扫描 url: "intent://scan/#Intent;scheme=zxing;package=com.google.zxing.client.android;end" ``` ## 屏幕方向 Android Android 应用能够通过在[设置](https://my.home-assistant.io/redirect/config/) > 伴侣应用中启用相应设置来固定 WebView 横向/纵向/系统方向。 ## 双指缩放 Android Android 应用能够启用双指缩放以允许多点触控缩放,方法是在[设置](https://my.home-assistant.io/redirect/config/) > 伴侣应用中启用相应设置。 ## 远程调试 Android Android 应用能够启用 [Chrome 远程调试](https://developer.chrome.com/docs/devtools/remote-debugging/)以便更容易地排查前端问题。您可以在[设置](https://my.home-assistant.io/redirect/config/) > 伴侣应用 > 故障排除中启用此设置。 --- url: /companion/integrations/android-widgets.md --- # Android 小部件 Android Android 应用允许用户在主屏幕上创建小部件,以便用户可以执行各种操作,如执行操作、显示实体状态甚至渲染模板。您可以像任何应用一样,根据设备启动器正常添加小部件。当启用数据节省模式时,小部件将不起作用,您还需要确保应用的后台数据已启用。如果您发现小部件不再工作,请尝试重新创建它。也可以通过导航到[设置](https://my.home-assistant.io/redirect/config/) > 伴侣应用 > 管理小部件来编辑小部件,如果您使用的是 Android 12,还可以通过长按小部件并点击编辑图标来编辑它。 只要设备支持,也可以从管理小部件设置页面添加小部件。 :::tip 使用 Home Assistant 2025.12 或更高版本时,您还可以通过打开实体的**更多信息**(点击实体或通过溢出菜单访问)直接从实体创建小部件。在**更多信息**中,选择**添加到**并选择添加小部件。请注意,此功能仅支持[兼容的实体类型](#可用小部件),您必须在希望小部件出现的设备上执行此操作。 Home Assistant 更多信息对话框添加到 ::: :::note 默认情况下,小部件在屏幕开启时每 30 分钟更新一次。在最近的 Android 版本中,除非您向应用授予额外权限,否则小部件无法更频繁地更新。 为确保您的小部件保持最新,请按照以下步骤操作: 1. 打开 **Android 设置**。 2. 导航到 **通知** > **(隐私部分)通知读取、回复和控制**。 3. 找到 **Home Assistant** 应用。 4. 启用 **允许通知访问**。您可以只勾选第一项(`实时`)。 这允许应用实时更新小部件。请记住,频繁更新可能会影响电池寿命,尤其是当小部件中使用的实体经常更改时。 ::: ## 可用小部件 ### 操作按钮 此小部件在被点击时执行一个操作。如果调用成功,用户将看到绿色勾号,如果失败则显示红色。红色表示小部件设置不当、Home Assistant 服务器不可用或 Home Assistant 日志中指出的其他错误。 您可以设置"需要认证"复选框。如果设置了,则在执行操作之前需要设备凭据(即 PIN、图案、生物识别...)。 1. 长按主屏幕上的任何空白区域 2. 在小部件列表中向下滚动到 Home Assistant 3. 将操作按钮小部件拖到主屏幕上的空白区域 4. 选择您希望执行的操作 5. 填写所选操作的必需操作数据 6. 为小部件提供名称和图标 7. 保存小部件 ### 实体状态 此小部件将在实体状态更改或手动刷新时更新。此小部件允许用户选择他们希望获取状态和属性的任何实体,以及设置文本大小并在状态和属性之间添加自定义分隔符。 1. 长按主屏幕上的任何空白区域 2. 在小部件列表中向下滚动到 Home Assistant 3. 将实体状态小部件拖到主屏幕上的空白区域 4. 输入您希望查看状态的实体 ID 5. 如果需要,选择属性复选框并选择您希望添加到状态的属性 6. 如果需要,调整小部件文本大小 7. 如果需要,添加一个自定义分隔符放在状态和属性之间 8. 如果支持,选择小部件的点击操作:切换实体或手动刷新状态(如果不支持,点击将刷新) 9. 为小部件提供名称 10. 保存小部件 ### 媒体播放器 --- url: /companion/integrations/app-events.md --- # 应用事件 ## 概述 为了帮助运行自动化,例如清除应用图标角标,或您可能希望根据应用使用情况触发的其他任务,Home Assistant 伴侣应用会在某些情况下向 Home Assistant [事件总线](https://www.home-assistant.io/docs/configuration/events/)触发不同的事件。 iOS
| 事件 | 原因 | | ----- | ----- | | `ios.finished_launching` | 应用在尚未在后台运行时打开。这也会触发 `ios.became_active`。 | | `ios.entered_background` | 应用关闭但继续在后台运行(通过按主页按钮或在没有主页按钮的机型上向上滑动)。 | | `ios.became_active` | 应用打开,无论它是否已在后台。 | | `ios.zone_entered` | 进入区域。如果此区域小于 100m,这将包含一个 `multi_region_zone_id` 键。 | | `ios.zone_exited` | 离开区域。如果此区域小于 100m,这将包含一个 `multi_region_zone_id` 键。 | Android | 事件 | 原因 | | ----- | ----- | | `android.intent_received` | 当应用收到来自[上次更新传感器](/companion/core/sensors.md#last-update-trigger-sensor)的注册意图的广播意图时。事件数据将包含意图操作字符串和任何意图附加信息(如果有)。 | | `android.navigation_started` | 当从 Android Auto/Automotive 中选择 `导航` 类别下的实体时。事件数据将包含选定的实体 ID。 | | `android.zone_entered` | 进入区域。事件数据将包含所有位置数据,包括触发区域。仅限 [`full` 版本](/companion/core/android-flavors.md)用户可用。 | | `android.zone_exited` | 离开区域。事件数据将包含所有位置数据,包括触发区域。仅限 [`full` 版本](/companion/core/android-flavors.md)用户可用。 | | `mobile_app.migration_failed` | 应用数据库已损坏,并在迁移期间重置以允许应用打开。传感器需要重新启用,小部件需要重新创建。设备上也会发布通知告知用户该问题。 | 您可以使用 Home Assistant 开发者工具中的事件页面来显示特定事件的所有信息,方法是订阅您感兴趣的事件,并在您的设备上执行相应的操作。 --- url: /companion/integrations/gestures.md --- # 手势 Android, iOS
您可以在使用 Home Assistant 主界面时设置手势以执行快速操作。 要查看和更改您的手势,请转到[设置](https://my.home-assistant.io/redirect/config/) > 伴侣应用 > 手势。对于每个手势,您可以从多个操作中选择或将手势禁用(通过将操作设置为"无")。 :::info 对于 Android 设备:如果您的设备有可在任何应用中工作的手势,例如截屏,它们可能会覆盖 Home Assistant 手势。 ::: ## 可用操作 * **无**:禁用手势。 ### Home Assistant * **快速搜索**:使用[快速搜索对话框](https://www.home-assistant.io/docs/tools/quick-search/)搜索任何内容。 * **搜索实体**:使用带有实体过滤器的[快速搜索对话框](https://www.home-assistant.io/docs/tools/quick-search/)搜索实体。 * **搜索设备**:使用带有设备过滤器的[快速搜索对话框](https://www.home-assistant.io/docs/tools/quick-search/)搜索设备。 * **搜索命令**:使用[快速搜索对话框](https://www.home-assistant.io/docs/tools/quick-search/)命令面板搜索命令。 * **显示侧边栏**:从任何屏幕打开侧边栏。 * **打开 Assist**:打开 [Assist](https://www.home-assistant.io/voice_control/) 对话框。 ### 导航 * **转到上一页**:如果可用,转到上一页。 * 仅限 iOS。在 Android 上,您可以使用 Android 的返回按钮或手势。 * **转到下一页**:如果可用,转到下一页。 * **转到默认仪表板**:转到为您的用户设置的默认仪表板。 * 仅限 Android。 * **重新加载页面**:强制重新加载当前页面。 * 仅限 Android。在 iOS 上,当位于页面顶部时继续向下滚动以强制重新加载当前页面。 ### 服务器 * **服务器列表**:显示添加到应用的所有服务器列表,以便快速在服务器之间切换。 * **下一个服务器**:如果您有多个服务器,激活列表中的下一个服务器。 * **上一个服务器**:如果您有多个服务器,激活列表中的上一个服务器。 ### 应用 * **打开应用设置**:打开伴侣应用设置(设置 > 伴侣应用)。 * **打开应用故障排除/打开调试**:打开伴侣应用的故障排除/调试选项(设置 > 伴侣应用 > 故障排除/调试)。 --- url: /companion/integrations/haptics.md --- # 触觉反馈 Home Assistant 伴侣应用具有触觉反馈功能,在与 UI 交互时提供物理反馈。您会感受到触觉反馈的区域包括开关(灯光、开关、输入布尔值)和输入选择。某些场景(如无效操作错误)也会产生触觉反馈。 iOS
支持触觉反馈的 iPhone 机型包括 iPhone 7 和 7 Plus、iPhone 8 和 8 Plus、iPhone X、XR、XS、XS Max、iPhone 11 和 11 Pro。 Android 具有触觉反馈支持和/或振动马达的 Android 设备可以预期会感受到某种类型的反馈。 ## 禁用触觉反馈 Home Assistant 伴侣应用遵循操作系统级别的禁用触觉反馈设置。在 iOS 设置中,导航到"声音与触感",然后在屏幕底部关闭"系统触感"。有关更多信息,请参阅 [Apple 支持文档](https://support.apple.com/guide/iphone/change-the-sounds-and-vibrations-iph07c867f28/ios)。在 Android 上,您可以从 Home Assistant 用户配置文件页面禁用振动来禁用此功能。 ## 开发者:将触觉反馈集成到自定义卡片中 待办:将触觉反馈支持集成到自定义卡片的说明将放在这里。当您的自定义卡片被交互时,您可以触发一个事件,iOS 应用将监听该事件并将其重新解释为触觉反馈。 Home Assistant 伴侣应用支持 [Apple 人机界面指南](https://developer.apple.com/design/human-interface-guidelines/ios/user-interaction/feedback/)定义的所有七个触觉强度级别。Android 将尝试尽力使用现有的[触觉反馈常量](https://developer.android.com/reference/android/view/HapticFeedbackConstants#constants_1)和/或[振动效果](https://developer.android.com/reference/android/os/VibrationEffect.html#constants_1)来匹配这些级别。 | 触觉反馈 | 描述 | | ------ | ------ | | `success` | 表示任务或操作已完成。 | | `warning` | 表示任务或操作产生了某种警告。 | | `failure` | 表示任务或操作已失败。 | | `light` | 提供补充视觉体验的物理隐喻。 | | `medium` | 提供补充视觉体验的物理隐喻。 | | `heavy` | 提供补充视觉体验的物理隐喻。 | | `selection` | 表示选择正在主动更改。 | **使用触觉反馈的自定义卡片:** * [Button Card](https://github.com/custom-cards/button-card) 作者 RomRider * [RadialMenu](https://github.com/custom-cards/radial-menu) 作者 Ian Richardson * [Harmony Card](https://github.com/sbryfcz/harmony-card) 作者 Sam Bryfczynski * [Simple Thermostat Card](https://github.com/nervetattoo/simple-thermostat) 作者 Raymond Julin --- url: /companion/integrations/iOS-widgets.md --- # iOS 小部件 iOS 应用自带几个内置小部件。从 iOS 应用版本 2025.3 开始,现在有一个"自定义小部件"(测试版)选项可以创建自定义的瓷砖卡片式小部件。 每个小部件都有一些选项。要配置,点击小部件进入编辑模式。 iOS、iPadOS 和 macOS 有不同的小部件尺寸可用: * 系统 * 小 * 中 * 大 * 超大 **(macOS)** * 附件 **(iOS 和 iPadOS 锁屏)** * 圆形 * 内联 * 矩形 ### 应用内助手 应用内助手小部件允许您使用您喜欢的管道在应用内打开助手。要编辑小部件选项,请将小部件添加到主屏幕并再次点击它。 ***可用于***
系统小 附件圆形
应用内助手小部件 应用内助手小部件配置
### 脚本 **脚本**小部件允许您执行脚本。 要在脚本执行后接收通知,请在其配置对话框中启用该选项。 ***可用于***
系统小 系统中 系统大 系统超大 (macOS) 附件圆形
脚本小部件 脚本小部件配置
### 传感器 **传感器**小部件显示传感器值,使用 iOS 允许的最小更新间隔(约 15 分钟)。不要使用此小部件显示应该实时显示更新的数据。 ***可用于***
系统小 系统中 系统大
传感器小部件 传感器小部件配置
### 打开页面 **打开页面**小部件允许您打开任何 Home Assistant 侧边栏页面。 ***可用于***
系统小 系统中 系统大 系统超大 (macOS) 附件圆形
打开页面小部件 打开页面小部件配置
### 仪表小部件(高级) **仪表**小部件允许您使用 Home Assistant 模板创建仪表表示 **(用户需要是管理员才能使用此功能)**,决定最小值、最大值和当前值,以及小部件中心和底部的显示文本(或表情符号 🥳)。 ***可用于***
附件圆形
对于仪表类型"普通": * **值模板:** 用于显示仪表图表的当前值。 * **值标签模板:** 将显示在小部件中心的文本/表情符号 * **最小标签模板:** 将显示在左下角的最小值 * **最大标签模板:** 将显示在右下角的最大值 对于仪表类型"普通(单个标签)": * **值模板:** 用于显示仪表图表的当前值。 * **值标签模板:** 将显示在小部件中心的文本/表情符号 * **标签模板:** 将显示在底部中心的文本/表情符号 对于仪表类型"容量": * **值模板:** 用于显示仪表图表的当前值。 * **值标签模板:** 将显示在小部件中心的文本/表情符号 还有一个运行 iOS 旧版操作的选项,这将很快转换为"运行脚本"。
仪表小部件 仪表小部件配置
### 详情(高级) **详情**小部件允许您使用 Home Assistant 模板显示最多 3 行信息 **(用户需要是管理员才能使用此功能)**。 ***可用于***
附件内联 附件圆形
详情小部件 详情小部件配置
### 自定义小部件(测试版) 最可定制的小部件,您可以在应用内通过 **伴侣应用设置 > 小部件 > 创建** 创建其配置,决定显示哪些实体、选择它们的图标、图标颜色、显示文本、文本颜色、背景颜色、"点击时"操作以及是否在运行前需要确认。 **"点击时"操作选项有:** * 默认(对于大多数实体会切换它们,如果不可能则只会刷新小部件) * 导航:与"打开页面小部件"相同的功能,但具有定义任何导航路径的灵活性。 * 运行脚本 * 助手 * 无(它刷新小部件但不执行其他操作) **在小部件配置对话框中(从主屏幕访问的那个),您有 3 个选项:** * 小部件:选择您在应用内创建的小部件 * 显示上次更新时间:这在小部件底部显示上次更新的时间,因为我们无法在 iOS 小部件中显示实时信息。 * 显示状态:您可以决定是否显示实体状态,目前显示处于测试版状态,因为我们无法保证始终是最新状态。启用时,它也可能会延迟小部件 UI 从确认状态(如果启用了"需要确认")转换回默认视图。 **更频繁更新状态的解决方法:** 在 iOS 中,我们有小部件可以更新的次数的有限预算,即使当我们请求此更新(在后台)时,也不能保证它会发生,iOS 会考虑用户对应用的使用、屏幕是否开启/关闭、小部件是否可见以及几个其他因素。 要增加刷新次数,您可以[发送带有"update\_widgets"命令的无声推送通知](/companion/notifications/commands.md),您甚至可以创建一个自动化在特定实体状态更改时发送此推送。 ***可用于***
系统小 系统中 系统大
自定义小部件 自定义小部件配置
自定义小部件创建视图 自定义小部件项目自定义视图
--- url: /companion/integrations/index.md --- # 集成 Home Assistant 伴侣应用在 iOS 和 Android 中提供深度集成。主要功能包括使用[触觉反馈](/companion/integrations/haptics.md)在应用内提供反馈。应用本身可以使用 Home Assistant 中定义的主题。应用可以通过 [URL 处理器](/companion/integrations/url-handler.md)触发操作或事件。查找 Android Android 图标,了解 Android 应用当前支持的功能。 --- url: /companion/integrations/sharing.md --- # 分享 此功能将在以下应用版本中可用: | iOS | Android Android | | ----------------------------- | --------------------------------------- | | 2020.7 | 2.5.0 | 伴侣应用允许您从任何支持分享功能的应用程序分享到您的 Home Assistant 服务器。应用将触发一个 `mobile_app.share` 事件,并提供一些事件数据供您进行自动化。 两个应用都会根据分享来源的应用提供 `url` 或 `text` 的事件数据。iOS 用户将获得 `entered` 的事件数据,其中包含分享时发送的任何文本。Android 用户将获得 `caller` 的事件数据,其中包含分享事件来源的应用。 Android 应用的事件数据示例: ```json { "event_type": "mobile_app.share", "data": { "caller": "android-app://com.android.chrome", "subject": "网页标题", "url": "https://www.example.xom", "text": "TEXT", "device_id": "DEVICE_ID" }, "origin": "REMOTE", "time_fired": "2020-09-25T01:06:48.512587+00:00", "context": { "id": "ID", "parent_id": null, "user_id": "USER_ID" } } ``` iOS 应用的事件数据示例: ```json { "event_type": "mobile_app.share", "data": { "entered": "我输入的文本", "sourceDeviceID": "iphone_11_pro_debug", "sourceDeviceName": "iPhone 11 Pro", "sourceDevicePermanentID": "DEVICE_ID", "text": "Home Assistant automations system into multiple areas of iOS ", "url": "https://www.example.com" }, "origin": "REMOTE", "time_fired": "2020-09-25T01:07:48.926946+00:00", "context": { "id": "ID", "parent_id": null, "user_id": "USER_ID" } } ``` --- url: /companion/integrations/siri-shortcuts.md --- # Siri 快捷指令 iOS
使用 iOS 13 或更高版本以及 Home Assistant 伴侣应用,您可以利用 Siri 快捷指令的强大功能,通过点击或语音命令执行 Home Assistant 任务。 ## 入门 - 示例快捷指令 例如,如果您想创建一个快捷指令来打开灯(此示例中为 `light.porch`): 1. 打开快捷指令应用(iOS 默认包含,如果删除了可以从 [App Store](https://apps.apple.com/app/id915249334) 重新安装) 2. 点击右上角的加号图标创建新快捷指令。 3. 点击添加操作并添加一个"字典"项目。 4. 在字典项目中,点击"添加新项目",点击"文本",然后添加 `entity_id` 作为键,`light.porch` 作为文本。 5. 点击大加号添加另一个操作,搜索"Home Assistant"并选择"调用服务"。 6. 点击"调用服务并传递数据"中突出显示的"服务"。 7. 滚动可用服务列表并找到 `light.turn_on`。 8. 点击"调用服务并传递数据"行末尾的箭头,在"服务器"字段中选择您希望执行操作的 Home Assistant 服务器。 9. 只要字典操作在 Home Assistant 操作之上,就不需要输入更多详细信息。如果您不想使用字典操作,可以选择"显示更多"并在"服务数据"字段中以 JSON 格式输入操作数据。 10. 点击下一步,输入或录制一个名称/短语,用于"嘿 Siri"来触发快捷指令。 最终的快捷指令应该类似于这样: 如上所述的已完成 Siri 快捷指令示例 ## 快捷指令流程 在前面的示例中,我们使用字典操作来定义我们的操作数据,这是一个操作向快捷指令流程中的后续操作提供数据的示例。这些数据可以来自其他应用或 Home Assistant 提供的其他操作,例如渲染文本以获取 Home Assistant 中实体的状态。默认情况下,如果没有提供其他流程或负载数据,空字段将尝试使用设备剪贴板上的数据。 ## 操作 ### 调用服务 您可以调用 Home Assistant 中设置的任何操作(参见[开发者工具中的操作页面](https://www.home-assistant.io/docs/tools/dev-tools/))。如[上面的示例](#入门---示例快捷指令)所示。 ### 触发事件 在 [Home Assistant 事件总线](https://www.home-assistant.io/docs/configuration/events/)上触发事件 :::tip 必须是有效的 JSON。 ::: ### 获取摄像头图像 从摄像头实体获取单帧静止图像,并将其放到剪贴板或在后续操作中使用。 ### 执行操作 执行一个[操作](/companion/core/actions.md)。 ### 渲染模板 渲染一个[模板](https://www.home-assistant.io/docs/configuration/templating/),然后可以在后续操作中使用。 ### 发送位置 向 Home Assistant 发送位置。将尝试使用剪贴板内容作为位置,否则将使用当前位置。 ### 更新传感器 更新所有传感器。 ## 启动快捷指令 快捷指令深度集成到操作系统中。创建后,您有多种方式可以启动它们。 * **Siri / 语音** - 您可以使用 Siri 从 iPhone、iPad、HomePod 或 Apple Watch 启动任何已创建的快捷指令。如果您的快捷指令名为"Bedtime",命令将是"嘿 Siri,Bedtime。" * **小组件** - 快捷指令在今日视图中有一个小组件,可以通过从主屏幕或锁屏向右滑动来访问。在小组件屏幕底部,按"编辑",然后按绿色加号按钮将小组件添加到今日视图。 * **快捷指令应用** - 在"我的快捷指令"标签页上,只需点击您想启动的快捷指令。如果需要,顶部有一个搜索栏可以快速筛选您的快捷指令列表。 * **Apple Watch (watchOS 7)** - 使用 iOS 14 和 watchOS7,您可以从快捷指令 Apple Watch 应用或通过 Siri 表盘上的复杂功能启动快捷指令。 * **Spotlight 搜索** - 在 iOS 设备主屏幕上,从主屏幕中心向下滑动以显示 Spotlight 搜索。在这里您可以输入快捷指令的名称并一键运行。 * **添加到主屏幕** - 编辑任何快捷指令时,按右上角的 (...) 按钮查看选项,然后按"添加到主屏幕"按钮。您可以根据需要自定义名称并提供自定义图标。 * **推送通知** - 快捷指令可以[通过推送通知](#通过-home-assistant-通知执行快捷指令)启动。 * **背面轻点 (iOS 14)** - 在 iOS 设置 > 辅助功能 > 触控 > 背面轻点下,您可以通过双击或三击 iPhone 背面来启动任何快捷指令。 ## 通过 Home Assistant 通知执行快捷指令 您可以使用通知从 Home Assistant 触发快捷指令,如下所示: ```yaml - action: notify.mobile_app_ data: message: "触发快捷指令!" data: shortcut: name: "快捷指令名称" # 您可以提供任意数量的键和值 # 所有值必须是字符串(例如不能是数字、数组、字典等) key_for_shortcut: "提供给快捷指令的值" another_key: "另一个值" ``` 当您点击通知启动 Home Assistant 时,它会将您重定向到快捷指令应用以执行给定的快捷指令。您可以使用上面 `shortcut` 中的以下键自定义此行为: | 键 | 值 | 说明 | | --- | ------ | ----- | | `ignore_result` | 任何字符串,例如 `"ignore"` | 设置后,完成时不会重新打开 Home Assistant 应用。也会阻止以下事件触发。 | :::note 如果快捷指令不需要任何输入,可能看起来快捷指令应用根本没有启动。检查执行的事件以查看结果。 ::: 完成快捷指令后,它会返回 Home Assistant 并触发一个事件。触发的事件是 `ios.shortcut_run`,带有快捷指令的结果,包含以下键: | 键 | 值 | 描述 | | -- | -- | -- | | `status` | `success`、`failure`、`cancelled` | 执行状态 | | `result` | 可变 | 快捷指令本身提供的结果 | | `error` | 字典,键为 `error-Code` 和 `errorMessage` | 如果失败,来自快捷指令应用的错误描述 | | `input` | 可变 | 操作中的 `shortcut` 值 | | `name` | 可变 | 操作中的 `shortcut.name` 值 | ## 个人自动化 使用快捷指令个人自动化,您可以兼得两者 - 通过使用 iOS 触发器执行 Home Assistant 操作。以下是一些有用的 iOS + Home Assistant 组合示例,供您参考: * 在 iPhone 上停止或暂停唤醒闹钟后,触发您的 Home Assistant"早晨例程"自动化。 * 在 Apple Watch 上开始锻炼时,使用 Home Assistant 播放您的锻炼播放列表。在 Apple Watch 上完成锻炼时,使用 Home Assistant 打开风扇降温。 * 当您连接或断开 CarPlay,或连接到汽车蓝牙系统时,通过切换 Home Assistant 中的 `input_boolean` 来在 Home Assistant 中获得完美的车辆在场检测。 * 您可以通过创建带有"充电器"触发器 (iOS 17) 的快捷指令个人自动化以及"发送位置" Home Assistant 应用操作,确保任何使用 iOS 应用"电池状态"传感器的 Home Assistant 自动化立即运行。这方面的一个使用示例是在晚上插入手机后立即触发您的睡前例程自动化,而不是等待下一次传感器后台更新。 * 在药瓶盖上贴一个 NFC 贴纸。每次服药时,用 iPhone 扫描 NFC 贴纸。Home Assistant 可以记录您服药的确切时间,增加一个[计数器](https://www.home-assistant.io/integrations/counter/)来帮助您了解何时补充处方,等等。 要在快捷指令应用中创建个人自动化,转到"自动化"标签页,按右上角的"+"按钮,然后点击"创建个人自动化"按钮。如果您在快捷指令应用中没有任何现有自动化,只需点击"创建个人自动化"按钮。iOS 17 上有 21 个触发器可用。有关创建个人自动化的更多信息,请参阅 Apple 的[快捷指令用户指南](https://support.apple.com/guide/shortcuts/apdfbdbd7123/)。 在 iOS 17 中,所有个人自动化触发器类型都可以自动运行,无需任何交互,但"通勤前"触发器除外。 --- url: /companion/integrations/theming.md --- # 主题 ## 使用的颜色 Android   Android

颜色应以十六进制格式指定(例如 `#0099ff`),不支持通过变量名定义元素颜色。 * `primary-background-color` 用于导航栏背景颜色 Android * `app-header-background-color` 用于状态栏背景颜色 Android iOS

从 2020.3 版本开始,iOS 应用将接受以十六进制、rgb、hsl、rgba、hsla 格式指定的颜色,或使用有效的 [HTML 颜色名称](https://www.w3schools.com/colors/colors_names.asp);虽然识别带有 alpha 值的格式,但使用小于 100%(或 1)的 alpha 值目前会导致颜色不匹配。2020.2 及更早版本的应用要求颜色以十六进制指定。 * `primary-background-color` 用于 Web 视图的背景颜色 iOS * `app-header-background-color` 用于状态栏背景颜色 iOS * `primary-color` 用于下拉刷新控件/加载器 iOS ## 设置应用主题 让应用与 Home Assistant 主题匹配所需的过程因使用的应用版本而异。 ### 2020.2 之后版本的 iOS 应用 应用将自动匹配 Home Assistant 中选择的主题,并在主题更改时实时更新。 ### 2020.1 或更旧版本的 iOS 应用和 Android 应用 要更改应用的主题,您必须在 Home Assistant 中使用[服务调用](https://www.home-assistant.io/docs/scripts/service-calls/)来调用 `frontend.set_theme`。这将触发应用可以检测到的事件。 --- url: /companion/integrations/universal-links.md --- # 通用链接、NFC 和 QR 标签 对这些功能的支持正在积极开发中,可能尚未完全发布。 | 功能 | iOS | Android Android | | --------- | ----------------------------- | --------------------------------------- | | NFC 标签 | 2020.5 | 2.2.0 | | QR 标签 | 2020.5 | 2.2.0 | | 旧式链接 | 2019.1 | 不支持 | ## NFC 标签和二维码 Home Assistant 支持扫描标签作为自动化的触发器。扫描的标签会在[设置中的标签面板](https://my.home-assistant.io/redirect/tags/)中收集。这允许您轻松管理已使用的标签并为它们提供友好的名称。 Home Assistant NFC 标签或二维码包含一个 URL,该 URL 将触发 Home Assistant 中触发标签扫描事件。格式是一个 URL `https://www.home-assistant.io/tag/<标签ID>`,以便 Android/iOS 知道将其路由到我们的应用。应用将提取标签标识符并将其直接发送到您的实例。 * iOS将您的设备靠近 NFC 标签或扫描二维码将显示一个通知,点击后将启动应用并触发一个事件。 * Android 在 Android 上,将您的设备靠近 Home Assistant NFC 标签或扫描二维码将触发一个事件。 触发的事件在 iOS 和 Android 上是相同的:`tag_scanned`。例如,在自动化中,您可以使用[标签触发器](https://www.home-assistant.io/docs/automation/trigger/#tag-trigger)来处理这些事件: ```yaml # 对于 https://www.home-assistant.io/tag/50A3C7C8-1FE7-4BE8-8DC9-06E07D41B63D automation: - alias: 开门 trigger: - platform: tag tag_id: 50A3C7C8-1FE7-4BE8-8DC9-06E07D41B63D action: # ... ``` 两个应用都支持读取和写入 NFC 标签。您可以使用随机生成的标签值(如上所示)或自定义值。 :::info 某些 NFC 标签是只读的,不能用作 Home Assistant NFC 标签。其他标签可能只允许写入一次,之后就会变成只读。 ::: ## 写入 NFC 标签 您可以通过打开应用 -> [设置](https://my.home-assistant.io/redirect/config/) -> 伴侣应用 -> NFC 卡片 -> 写入来写入 NFC 标签。
## 旧式通用链接 iOS
通用链接是 [URL 处理器](/companion/integrations/url-handler.md)和 [X-Callback-URL](/companion/integrations/x-callback-url.md)的替代方案。 应用已将 `https://www.home-assistant.io/ios/` 下的所有 URL 注册为有效的通用链接。但是,目前应用只理解一个通用链接: `https://www.home-assistant.io/ios/nfc/?url=<您可以使用现有 URL 处理器的 URL>` 这允许 NFC 支持。您可以使用上述 URL 写入 NFC 标签,当您的设备看到该 NFC 标签时,将显示一个通知让您打开应用。 一旦您打开应用,它将执行您在 URL 中告诉它的任何操作。 如果多个服务器连接到 iOS 或 mac 应用,在打开通用链接时将提示您选择一个服务器。 --- url: /companion/integrations/url-handler.md --- # URL 处理器 Home Assistant 支持通过 URL 从其他应用打开。 ## 平台兼容性 不同类型深度链接的平台支持会有所不同,请查阅下表了解您的平台可用的深度链接类型。
深度链接类型 Android Android iOS & macOS
导航 ✅ ✅
调用服务 ✅
触发事件 ✅
发送位置 ✅
## 导航 这允许您通过深度链接更新前端页面位置。要构建深度链接,请按照以下步骤操作: 1. 在 Web 应用中导航到您想要深度链接的链接,例如 `http://homeassistant.local:8123/dashboard-mobile/my-subview` 2. 复制 URL 的路径部分,在这个例子中是 `/dashboard-mobile/my-subview` 3. 通过以 `homeassistant://navigate` 开头并添加路径来构建您的 URL,例如 `homeassistant://navigate/dashboard-mobile/my-subview` :::info 默认情况下,如果您有多个服务器,应用会询问您要导航到哪个服务器。 要定义您要导航到哪个服务器,请使用查询参数 `?server=`,如下例所示:

当您的服务器名称是 `My Home` 时使用 `homeassistant://navigate/webcams?server=My%20home`,或者如果您想导航到第一个可用服务器,请使用 `?server=default`。 ::: ## 调用服务 示例:`homeassistant://call_service/device_tracker.see?entity_id=device_tracker.entity` 查询参数作为字典传递到调用中。 :::info 如果多个服务器连接到一个应用,`call_service` 链接将使用列表中的第一个服务器处理。 ::: ## 触发事件 您可以创建一个[事件触发器](https://www.home-assistant.io/docs/automation/trigger/#event-trigger)并触发该事件。 示例:`homeassistant://fire_event/custom_event?entity_id=MY_CUSTOM_EVENT` 查询参数作为字典传递到调用中。 :::info 如果多个服务器连接到一个应用,`fire_event` 链接将使用列表中的第一个服务器处理。 ::: ## 发送位置 示例:`homeassistant://send_location/` --- url: /companion/integrations/x-callback-url.md --- # X-Callback-URL iOS
应用完全支持 [X-Callback-URL](http://x-callback-url.com/),这是一种标准化方式,让 Google Chrome、Drafts 和快捷指令等应用通过 URL 处理器相互交互。 URL 处理器支持的所有功能也通过 X-Callback-URL 支持。 --- url: /companion/meta-quest/index.md --- # 概览 Android
Home Assistant 已开始在 Meta Quest 上提供 Android 应用的[精简版本](/companion/core/android-flavors.md)。该应用可在 [SideQuest](https://www.sidequestvr.com) 找到,这是 Meta Quest 的替代应用商店。 \ 在 SideQuest 下载

| 型号 | 是否支持? | | ----- | --------- | | Meta Quest | 是 | | Meta Quest 2 | 是 | | Meta Quest Pro | 是 | | Meta Quest 3/3S | 是 | 由于 Quest 运行 Android,该应用具有主要版本提供的许多传感器。请查看设置中的管理传感器屏幕,了解当前支持的传感器。要了解每个 Android 传感器以及传感器的一般工作原理,请务必查看[传感器](/companion/core/sensors.md#android-sensors)文档。 并非 Android 应用的所有功能都能在 Meta Quest 上运行,因为它运行的是经过大量修改的 Android 分支。没有 Google 服务,没有小部件,没有快捷方式,也没有标准通知。 在此页面上,我们将介绍为 Meta Quest 构建的特定功能和传感器,请继续关注更多更新! ### 传感器列表 | 传感器 | 属性 | 描述 | | --------- | --------- | ----------- | |`binary_sensor.in_use` | 无 | 头显是否正在使用(立即更新) | --- url: /companion/notifications/actionable.md --- # 可操作通知 可操作通知是一种独特的通知类型,它允许用户在通知中添加按钮,点击后可以向 Home Assistant 发送[事件](https://www.home-assistant.io/docs/configuration/events/)。然后可以在自动化中使用此事件,允许您执行各种操作。这些通知可以发送到 iOS 或 Android。 可操作通知的一些实用示例: * 当您外出或睡觉时,家中检测到移动时发送通知。通知旁边显示"响起警报"操作按钮,点击后将响起防盗警报。 * 有人按响前门门铃。您收到一条带有访客[实时摄像头画面](/companion/notifications/dynamic-content.md)的通知,以及锁定或解锁前门的操作按钮。 * 车库门打开时收到通知,带有打开或关闭车库的操作按钮。 ![可操作通知允许用户向 Home Assistant 发送命令。](/companion-assets/ios/actions.png) iOS 如果您将多个服务器连接到 iOS 或 mac 应用,通知操作将在发送通知的服务器上触发。 :::caution 版本兼容性 iOS 和 macOS 上基于类别的通知已弃用。请参阅[迁移指南](#migrating-from-categories)了解如何转换现有通知。 ::: :::info Apple Watch watchOS 上的操作需要安装 Watch 应用。您可以在系统 Watch 应用中安装它。 ::: ## 构建可操作通知 您可以在操作中包含 `actions` 数组。 Android Android 允许 3 个通知操作。\ iOS 允许约 10 个通知操作。更多操作会导致通知操作的系统界面出现滚动问题。 ```yaml action: notify.mobile_app_ data: message: "家里发生了一些事情!" data: actions: - action: "ALARM" # 您为事件发送的键 title: "响起警报" # 按钮标题 - action: "URI" # 如果您计划使用 URI,必须设置为 URI title: "打开网址" uri: "https://google.com" # 选择操作时打开的 URL,也可以是 lovelace 视图/仪表板 ``` 每个操作可以包含以下键: | 键 | 含义 | 备注 | | --- | --- | --- | | `action` | **必需**。在事件中传回的标识符 | 当设置为 `REPLY` 时,系统会提示您输入要随事件发送的文本。 | | `title` | **必需**。通知中显示的按钮标题 | | | `uri` | **可选**。点击时打开的 URL | Android Android 需要将 `action` 设置为 `URI` 才能使用此键。请参阅[下面的说明](#uri-values)。 | | `behavior` | **可选**。设置为 `textInput` 以提示输入文本并随事件返回。当将操作设置为 `REPLY` 时也会发生这种情况。 | 使用此键可以让您使用 `action` 键来区分操作。 | ### Android Android 专属选项 以下所有键都是可选的。 | 键 | 含义 | 备注 | | --- | --- | --- | | *无* | 目前没有 Android 特定的键。 | | ### iOS iOS 专属选项 以下所有键都是可选的。 | 键 | 含义 | 备注 | | --- | --- | --- | | `activationMode` | 设置为 `foreground` 以在点击时启动应用。默认为 `background`,仅触发事件。 | 当提供 `uri` 时,此选项会自动设置为 `foreground`。 | | `authenticationRequired` | 设置为 `true` 以要求输入密码才能使用该操作。 | | | `destructive` | 设置为 `true` 以将操作标题显示为红色,表示破坏性操作。 | | | `textInputButtonTitle` | 用于提示输入文本的操作的文本输入按钮标题。 | | | `textInputPlaceholder` | 用于提示输入文本的操作的文本输入占位符。 | | | `icon` | 用于通知的图标。 | 需要版本 2021.10。请参阅下面的说明。 | #### 图标值 :::note 版本兼容性 这需要 iOS 应用版本 2021.10 或更高版本(iOS 15 或更高版本),或 macOS 应用的未来版本(macOS 12 或更高版本)。 ::: 通知操作的图标仅允许来自 [SF Symbols 库](https://developer.apple.com/sf-symbols/),这与 Home Assistant 中来自 [Material Design Icons 库](https://materialdesignicons.com/)的其他图标不同。这是由于 Apple 对这些操作的限制。 您必须在目录中的图标名称前加上 `sfsymbols:` 前缀(类似于在其他地方加上 `mdi:` 前缀),因为我们希望将来扩展此功能以支持 MDI。例如: ```yaml action: - action: notify.mobile_app_ data: message: "家里发生了一些事情!" data: actions: - action: "ALARM" title: "响起警报" icon: "sfsymbols:bell" - action: "SILENCE" title: "静音警报" icon: "sfsymbols:bell.slash" ``` ### URI 值 要导航到前端页面,请使用格式 `/lovelace/test`,其中 `test` 替换为定义视图中的 [`path`](https://www.home-assistant.io/dashboards/views/#path)。如果您计划使用仪表板,格式为 `/lovelace-dashboard/view`,其中 `/lovelace-dashboard/` 替换为您定义的 [`dashboard`](https://www.home-assistant.io/dashboards/dashboards) URL,`view` 替换为该仪表板中定义的 [`path`](https://www.home-assistant.io/dashboards/views/#path)。例如: ```yaml - action: "URI" title: "打开摄像头" uri: "/lovelace/cameras" ``` #### Android Android 专属 如果您想打开应用程序,需要将操作设置为 `URI`。格式为 `app://`,其中 `` 替换为您希望打开的包(例如:`app://com.twitter.android`)。如果设备没有安装该应用程序,则 Home Assistant 应用程序将打开默认页面。 ```yaml - action: "URI" title: "打开 X" # 您想要打开的应用程序包名 uri: "app://com.twitter.android" ``` 将操作设置为 `URI`,您还可以触发任何实体的更多信息面板。格式为 `entityId:`,其中 `` 替换为您希望查看的实体 ID。例如:`entityId:sun.sun` ```yaml - action: "URI" title: "查看太阳" uri: "entityId:sun.sun" ``` 您还可以在使用格式 `settings://notification_history` 时打开通知历史记录 ```yaml - action: "URI" title: "通知历史" uri: "settings://notification_history" ``` Android 您还可以使用 [intent scheme URI](https://developer.chrome.com/docs/multidevice/android/intents/#syntax) 在已安装的应用程序中启动操作。 ```yaml - action: "URI" title: "Intent Scheme" uri: "intent://scan/#Intent;scheme=zxing;package=com.google.zxing.client.android;end" ``` Android 您可以通过使用 `deep-link://` 向应用发送特定的[深层链接](https://developer.android.com/training/app-links#deep-links),其中 `` 是您希望发送的实际深层链接。 例如,拨打电话: ```yaml - action: "URI" title: "拨打必胜客" uri: "deep-link://tel:2125551212" ``` #### iOS iOS 专属 您还可以使用启动应用程序的 URL。例如,拨打电话: ```yaml - action: "CALL" title: "拨打必胜客" uri: "tel:2125551212" ``` 或在默认浏览器中启动页面: ```yaml - action: "OPEN" title: "打开 Safari" uri: "https://example.com" ``` ## 构建通知操作脚本 在构建可操作通知时,有一些重要事项需要注意: 1. 您的脚本或自动化可能会多次运行 2. 通知的操作在所有通知之间共享 为避免问题,您可以为每次脚本运行创建唯一的操作。通过结合上下文和变量,这可以相当简单: ```yaml # 在自动化操作或脚本序列中 - alias: "为操作设置变量" variables: # 在操作中包含 id 允许我们识别此脚本运行 # 而不会意外触发其他通知操作 action_open: "{{ 'OPEN_' ~ context.id }}" action_close: "{{ 'CLOSE_' ~ context.id }}" - alias: "询问是否关闭或打开百叶窗" action: notify.mobile_app_ data: message: "百叶窗处于半开状态。您想调整吗?" data: actions: - action: "{{ action_open }}" title: 打开 - action: "{{ action_close }}" title: 关闭 - alias: "等待响应" wait_for_trigger: - platform: event event_type: mobile_app_notification_action event_data: # 等待特定操作可以避免意外继续 # 另一个脚本/自动化的通知操作 action: "{{ action_open }}" - platform: event event_type: mobile_app_notification_action event_data: action: "{{ action_close }}" - alias: "执行操作" choose: - conditions: "{{ wait.trigger.event.data.action == action_open }}" sequence: - action: cover.open_cover target: entity_id: cover.some_cover - conditions: "{{ wait.trigger.event.data.action == action_close }}" sequence: - action: cover.close_cover target: entity_id: cover.some_cover ``` 上面的示例发送通知,等待响应,然后执行所请求的操作。 当执行通知操作时,`mobile_app_notification_action` 事件会触发,包含以下数据: ```javascript { "event_type": "mobile_app_notification_action", "data": { "action": "OPEN_", // 将会出现: // - 当使用 `REPLY` 作为操作标识符时 // - 当 `behavior` 设置为 `textInput` 时 "reply_text": "用户的回复", // 仅限 iOS,如果在通知中发送,将被包含 "action_data": { "entity_id": "light.test", "my_custom_data": "foo_bar" }, // Android 用户还可以在此响应中看到随通知发送的所有数据字段,如 "tag" "tag": "TEST" }, "origin": "REMOTE", "time_fired": "2020-02-02T04:45:05.550251+00:00", "context": { "id": "abc123", "parent_id": null, "user_id": "123abc" } } ``` ## 进一步考虑 ### 阻塞行为 上面的示例将等待,直到执行通知操作。这可能会导致意外行为,具体取决于脚本的[自动化模式](https://www.home-assistant.io/docs/automation/modes/)。对于"single"模式,如果之前的通知操作尚未执行,这将导致脚本不会再次执行的情况。对于"queue"和"parallel"模式,如果一定数量的通知尚未执行,则会发生这种情况。对于"restart"模式,这意味着一旦脚本再次触发,脚本的旧实例的通知操作将不会触发相应的操作。根据使用情况,有几种选择: * 您可以使用[超时](https://www.home-assistant.io/docs/scripts/#wait-timeout)来允许脚本的新执行。但是,这会导致手机上出现悬空通知。 * 可以[清除通知](/companion/notifications/basic.md#clearing),这可以与超时和并行执行模式结合使用以获得良好的结果。 * 在 Android 中,您可以监听通知关闭时触发的[通知清除事件](/companion/notifications/cleared.md),并进行相应处理。这可以通过添加以下行来实现 ``` - platform: event event_type: mobile_app_notification_cleared event_data: action_1_key: '{{ action_open }}' ``` 和 ``` - conditions: "{{ wait.trigger.event.event_type == 'mobile_app_notification_cleared' }}" sequence: - action: persistent_notification.create data: title: 应用通知结果 message: 通知已关闭 ``` 请记住,当 Home Assistant 应用崩溃或关闭时,事件不会被触发,因此仍应考虑超时。 ### 通用触发器 您还可以创建为任何通知操作触发的自动化。例如,如果您想在各种通知中包含 `SILENCE` 操作,但只在一个地方处理它: ```yaml automation: - alias: "静音警报" trigger: - platform: event event_type: mobile_app_notification_action event_data: action: "SILENCE" action: ... ``` ## 从类别迁移 从 iOS 版本 2021.5 开始,操作在内联通知中指定。要迁移,请执行以下操作: 1. 将 `actions` 数组添加到每个通知。例如: ```yaml # 原始 action: - action: notify.mobile_app_ data: message: "家里发生了一些事情!" data: push: category: "ALARM" url: _: "/lovelace/cameras" # 如果点击通知本身 ALARM: "/lovelace/alarm" # 如果点击 'ALARM' 操作 # 替换 action: - action: notify.mobile_app_ data: message: "家里发生了一些事情!" data: url: "/lovelace/cameras" # 如果未选择任何操作则启动 actions: # 为了兼容性,可以使用 YAML 定义的操作 # 例如,您可以使用 `identifier` 而不是 `action` - action: "ALARM" title: "响起警报" destructive: true uri: "/lovelace/alarm" - action: "SILENCE" title: "静音警报" ``` 2. 将事件触发器转换为新值 ```yaml # 原始 automation: - alias: "响起警报 iOS" trigger: - platform: event event_type: ios.notification_action_fired event_data: actionName: "ALARM" action: ... # 替换 automation: - alias: "响起警报 iOS" trigger: - platform: event event_type: mobile_app_notification_action event_data: action: "ALARM" action: ... ``` 以上是迁移所需的最低限度。您还可以像前面的示例那样重写自动化以使用 `wait_for_trigger`,尽管这需要更多工作且并非严格必要。 ## 不同设备的兼容性 iOS专属 ### iOS 13 及更高版本 * 所有设备都支持通过从右向左滑动并按"查看"在锁屏上展开通知,或长按展开,但在支持 3D Touch 的设备上,您可能仍需要施加一些力量才能完成。如果您不在锁屏上,也可以下拉通知以展开它。 ### iOS 13 之前 * 对于支持 3D Touch 的设备 - 用力按压通知将展开它,在下方显示操作按钮。支持的设备包括 iPhone 6S、iPhone 6S Plus、iPhone 7、iPhone 7 Plus、iPhone 8、iPhone 8 Plus、iPhone X、iPhone XS 和 iPhone XS Max。如果不在锁屏上,您也可以下拉通知以展开它。 * 对于不支持"3D Touch"的设备(如 iPhone 6 及以下、iPhone SE、iPhone XR 和 iPad),您需要在通知上从左向右滑动,然后点击"查看"按钮。这将展开通知并在下方显示相关操作按钮。如果不在锁屏上,您需要下拉通知以展开它。 --- url: /companion/notifications/attachments.md --- # 标准附件 通知可以包含图像、视频或音频文件附件,与通知一起显示。请参阅[支持的媒体表格](#supported-media-types)了解各平台的支持情况。 ## 下载 附件是在收到通知时下载到设备的图像、视频或音频文件,并与通知一起显示。当通知未展开时显示缩略图。当通知展开时显示完整大小的附件。 有几个位置可以保存文件,您可以使用 [`camera.snapshot`](https://www.home-assistant.io/integrations/camera#action-snapshot) 操作保存快照。 :::note 附件必须可从互联网访问,但不一定需要无需认证。请参阅下面的来源。 ::: ### `media_source`(推荐) [`media_source` 集成](https://www.home-assistant.io/integrations/media_source)的优势在于访问需要认证头(Home Assistant 会将其提供给伴侣应用)。这意味着内容不会公开可用。 您可以在此集成中使用相对 URL 格式 `/media/local/direct.jpg`。 :::info 磁盘上存储在 `/media/file.jpg` 的文件在通知中表示为 `/media/local/file.jpg`。注意路径中添加了 `local` 部分。 ::: ### `www` 文件夹 您需要将图像存储在 Home Assistant [配置目录](https://www.home-assistant.io/docs/configuration/)中的 `www` 文件夹中。这将使图像暴露给互联网,以便您可以在通知中使用它并在任何地方接收它们。 您可以在此集成中使用 URL 格式 `/local/file.jpg`。 :::info 磁盘上存储在 `/www/file.jpg` 的文件在通知中表示为 `/local/file.jpg`。注意路径中的 `local` 部分发生了变化。 ::: ## 自动快照 Android Android 用户还可以使用 `/api/camera_proxy/camera.name`,其中 `camera.name` 替换为您希望使用的摄像头实体 ID。 iOS iOS 用户可以使用[动态附件中的摄像头流](/companion/notifications/dynamic-content.md#camera-stream)。 :::tip 在 3D Touch 设备上展开通知,只需用力触摸任何通知。在非 3D Touch 设备上,滑动并点击"查看"按钮。 ::: ## 图像实体 来自图像实体的图像可以使用 `/api/image_proxy/image.name`,其中 `image.name` 替换为您希望使用的图像实体实体 ID。 ## 支持的媒体类型 请确保您的附件符合以下标准,否则将不会显示。 | 附件类型 | 最大文件大小 | 允许的格式 | 支持的平台 | | :-------: | --------------- | ------------------|------------------------- | | 图像 | 10 MB | JPEG, GIF, PNG | Android Android & iOS | | 视频 | 50 MB | MPEG, MPEG2, MPEG4, AVI | Android Android & iOS | | 音频 | 5 MB | AIFF, WAV, MP3, MPEG4 Audio | iOS | iOS 版本 2021.5 或更高版本将在打开内容时尝试重新下载超过大小限制的较大文件。 ## 参数 您可以使用以下键添加附件。请参阅上面的支持媒体类型。提供的所有 URL 必须可通过互联网访问。 | 键 | 示例值 | | -- | -- | | `video` | `/media/local/video.mp4`

`https://example.com/video.mp4` | | `image` | `/media/local/photo.jpg`

`https://example.com/image.jpg` | | `audio` | `/media/local/audio.mp3`

`https://example.com/audio.mp3` | 当存在多个值时,将按上表的顺序使用。例如,您可以指定 `audio` 和 `image`,iOS 将选择音频,而 Android 将选择图像。 :::info Android   备注: * 如果您设置了 [`icon_url`](/companion/notifications/basic.md#notification-icon) 和 `image` 属性,则设备上只会显示图像。 * 如果您设置了 `image` 和 `video` 属性,则设备上只会显示视频。 * 视频将显示为从视频文件捕获的一系列帧。对于时长 < 10 秒的视频效果不佳。 * GIF 仅在 Android 14+ 的通知栏中才会动画显示。 ::: ## 示例操作 ```yaml automation: - alias: 通知移动应用附件 trigger: ... action: - action: notify.mobile_app_ data: message: "家里发生了一些事情!" data: # 绝对 URL 示例 image: "https://www.home-assistant.io/images/default-social.png" # 相对 URL 示例 image: "/media/local/image.png" # 视频同样适用 video: "/media/local/video.mp4" # 音频同样适用 audio: "/media/local/audio.mp3" ``` ## 视觉效果示例 带有图像附件的未展开推送通知: ![带有附件的未展开推送通知。](/companion-assets/ios/attachment.png) 同一通知展开后显示完整大小的图像附件: ![同一通知展开后显示完整大小的附件](/companion-assets/ios/expanded_attachment.png) ## 配置 iOS专属
[请参阅支持的媒体表格](#supported-media-types) 您可以使用以下格式自定义通知上的附件: ```yaml - action: notify.mobile_app_ data: message: "家里发生了一些事情!" data: attachment: # 隐藏缩略图,仅在长按/3D触摸通知时显示 hide-thumbnail: true ``` * **url** (*可选*): 用作附件的内容 URL。此 URL *必须*可从互联网访问,或者接收设备必须与托管内容在同一网络上。这将覆盖任何 `image`、`video` 或 `audio` 值。 * **content-type** (*可选*): 默认情况下,如果提供了 `url`,将检查 URL 的扩展名以确定文件类型,或者从 `image`、`video` 和 `audio` 键的使用中推断。如果没有扩展名/无法确定,您可以手动提供文件扩展名。 * **hide-thumbnail** (*可选*): 如果设置为 `true`,缩略图将不会显示在通知上。内容只能通过展开查看。 * **lazy** (*可选*): 需要 iOS v2021.5 或更高版本。如果设置为 `true`,附件不会立即下载,只有在查看通知时才会加载。使用此选项可避免下载明显过大的附件,但如果它们只是偶尔过大,则不应提供此键,因为应用可以同时尝试两种方式。 Android Android 专属 [请参阅支持的媒体表格](#supported-media-types) * `GIF` 文件类型仅在 Android 14+ 的通知栏中才会动画显示 --- url: /companion/notifications/basic.md --- # 简介 `mobile_app` 通知平台接受通知平台使用的标准 `title`(标题)、`message`(消息)和 `target`(目标)参数。mobile\_app 通知平台支持目标作为服务。只要您在设置过程中授予了通知权限,您将在通知操作中找到所有设备列为目标,名称前缀为 `notify.mobile_app_` 后跟您设备的设备 ID。这可以在 [Home Assistant 配置菜单](https://my.home-assistant.io/redirect/config/) 的 Companion App 菜单中检查,默认为 iOS/macOS 设置应用中的通用>关于或 Android 设置中的关于>电话中指定的名称(空格和非字母数字字符替换为下划线)。通知平台的要求是您必须在负载中指定至少 `message:`。通知的最小工作示例是: ```yaml automation: - alias: '发送通知' trigger: ... action: - action: notify.mobile_app_ data: message: "通知文本" ``` mobile\_app 平台为上面生成的简单通知提供了许多增强功能。例如,下图显示了一个 [iOS 可操作通知](/companion/notifications/actionable.md),允许您从每个按钮触发不同的自动化。 ![一个推送通知,显示所有基本选项 title 和 message 以及 subtitle 和操作。](/companion-assets/ios/example.png) :::info Wear OS 应用支持某些通知功能。请查看[文档](/companion/wear-os/index.md#notifications)以了解当前支持的功能。 ::: ## 向多个设备发送通知 要向多个设备发送通知,请创建一个[通知组](https://www.home-assistant.io/integrations/group#notify-groups): ```yaml notify: - name: ALL_DEVICES platform: group services: - action: mobile_app_iphone_one - action: mobile_app_iphone_two - action: mobile_app_ipad_one - action: mobile_app_pixel_4_xl ``` 现在,您可以使用以下方式向组中的每个人发送通知: ```yaml automation: - alias: "通知移动应用组" trigger: ... action: - action: notify.ALL_DEVICES data: message: "家里发生了一些事情!" ``` ## 通用选项 ### 附件 您可以将媒体和其他内容附加到通知中。请参阅[附件](/companion/notifications/attachments.md)。 ### 打开 URL 当点击通知时,您可以选择打开一个 URL,它可以属于以下类别之一: * Home Assistant 实例的相对 URL,如 `/lovelace/test`。 * iOS 如果您将多个服务器连接到 iOS 或 mac 应用,相对 URL 将相对于发送通知的服务器处理。 * 完整的 URL,如 `https://example.com` * 对于可操作通知中的特定操作,请参阅[其文档](/companion/notifications/actionable.md)。 * Android 使用 `app://` 的应用程序,其中 `` 替换为您希望打开的实际包。 * Android 使用 `entityId:` 的实体的更多信息面板,其中 `` 替换为您希望查看的实体 ID。例如:`entityId:sun.sun`。 * Android 您还可以使用 `settings://notification_history` 打开通知历史记录 * Android 您还可以使用 [intent scheme URI](https://developer.chrome.com/docs/multidevice/android/intents/#syntax) 在已安装的应用程序中启动操作。 * Android 您可以使用 `deep-link://` 向应用发送特定的[深层链接](https://developer.android.com/training/app-links#deep-links),其中 `` 是您希望发送的实际深层链接。 * Android 如果您希望默认不打开应用而是什么都不做,可以使用 `noAction`。 对于相对 URL,您可以以 `/lovelace/test` 格式打开 lovelace 视图,其中 `test` 替换为定义视图中的 [`path`](https://www.home-assistant.io/dashboards/views#path),或以 `/lovelace-dashboard/view` 格式打开 lovelace 仪表板,其中 `/lovelace-dashboard/` 替换为您定义的 [`dashboard`](https://www.home-assistant.io/dashboards/dashboards/) URL,`view` 替换为该仪表板中定义的 [`path`](https://www.home-assistant.io/dashboards/views#path)。 ```yaml automation: - alias: "通知运动点击操作" trigger: ... action: - action: notify.mobile_app_ data: title: "后院检测到运动" message: "后院可能有人。" data: # iOS URL url: "https://google.com" # Android URL clickAction: "https://google.com" ``` ```yaml automation: - alias: "发送带链接的通知" trigger: ... action: - action: notify.mobile_app_ data: title: "后院检测到运动" message: "后院可能有人。" data: # iOS URL url: "/lovelace/cameras" # Android URL clickAction: "/lovelace/cameras" ``` :::info 下面关于[分组](#grouping)、[替换](#replacing)和[清除](#clearing)的部分不考虑多个服务器。如果您为 `group` 或 `tag` 使用相同的文本,无论哪个服务器发送通知,您都应该期望看到相同的行为。您可以考虑将服务器名称添加到当前文本中,以使行为特定于服务器。 ::: ### 分组 将通知在视觉上组合在一起。 iOS 不支持[关键通知](/companion/notifications/critical.md)的分组。 ```yaml automation: - alias: "通知移动应用分组" trigger: ... action: - action: notify.mobile_app_ data: title: "智能家居警报" message: "家里发生了一些事情!" data: group: "example-notification-group" ``` ### 替换 使用通知的标签替换现有通知。所有后续通知将替换具有相同标签的通知。 iOS 不支持[关键通知](/companion/notifications/critical.md)的替换。 ```yaml automation: - alias: "通知运动 iOS 替换" trigger: ... action: - action: notify.mobile_app_ data: title: "后院检测到运动" message: "后院可能有人。" data: tag: "backyard-motion-detected" ``` :::info Android 不要在不同的 `group` 中使用相同的 `tag`,以避免意外行为。 ::: ### 清除 :::note iOS 版本要求 在 iOS 上清除通知需要应用版本 2021.5 或更高版本。 ::: 您可以通过发送 `clear_notification` 来清除具有标签的现有通知。 平台限制可能需要 Companion 应用最近被使用过才能清除通知:这适用于所有 iOS 通知以及任何未标记为关键的 Android 通知。 iOS 只会清除给定标签的最近一个[关键通知](/companion/notifications/critical.md)。 ```yaml automation: - alias: "通知运动清除通知" trigger: ... action: - action: notify.mobile_app_ data: message: "clear_notification" data: tag: "backyard-motion-detected" ``` ### 副标题 / 主题 副标题和主题是您可以在通知中使用的次要标题,超出标题属性之外。 iOS macOS
除了标题和消息外,还会显示 `subtitle`。 Android
根据您的设备,`subject` 可能会取代较长的内容(超过 6 行)。 ```yaml automation: - alias: "通知移动应用副标题" trigger: ... action: - action: notify.mobile_app_ data: title: "智能家居警报" message: "家里发生了一些事情!" data: # iOS 示例 subtitle: "副标题在这里" # Android 示例 subject: "长文本主题" ``` ## Android 专属 ### 通知颜色 在 Android 中,您可以设置通知的 `color`,您可以使用颜色名称或十六进制代码。 ```yaml automation: - alias: "通知运动颜色" trigger: ... action: - action: notify.mobile_app_ data: title: "后院检测到运动" message: "后院可能有人。" data: color: "#2DF56D" # 或 "red" ``` ### 粘性通知 您可以设置是否在选择通知后将其关闭。将 `sticky` 设置为 `'true'` 将阻止通知在用户选择时被关闭。将其设置为 `'false'`(默认)将在选择时关闭通知。 ```yaml automation: - alias: "通知运动粘性" trigger: ... action: - action: notify.mobile_app_ data: title: "后院检测到运动" message: "后院可能有人。" data: sticky: "true" # 或 "false" ``` ### 通知渠道 通知渠道(在某些设备上:*通知类别*)允许您轻松分离通知(例如闹钟与洗衣),并自定义通知声音和许多其他设备特定功能等方面。运行 Android 8.0+ 的设备能够使用自动化动态创建和管理通知渠道。一旦创建了渠道,您可以导航到通知设置,您将找到新创建的渠道,从那里您可以根据设备允许的内容自定义行为。 #### 创建渠道 为了创建通知,您需要指定要使用的 `channel`。默认情况下,如果未定义 `channel`,所有通知都使用 `General`。 在下面的示例中,将创建一个名为 `Motion` 的新渠道: ```yaml automation: - alias: "通知运动渠道" trigger: ... action: - action: notify.mobile_app_ data: title: "后院检测到运动" message: "后院可能有人。" data: channel: "Motion" # 您希望创建或使用的渠道名称 ``` 如果未提供,渠道的默认值如下: * 重要性:默认,意味着默认通知重要性:随处显示,发出声音,但不会在视觉上打扰。 * 振动模式:振动已禁用 * LED 颜色:LED 已禁用 #### 删除渠道 如果您希望删除渠道,您需要发送 `message: remove_channel` 以及您希望删除的 `channel`。 删除渠道不会将设置重置为默认值,它只是将其从通知渠道列表中删除。如果您向已删除的渠道发送通知,它将恢复它。真正删除渠道的唯一方法是清除应用数据,这将删除所有内容。 根据您安装应用的时间,您可能希望向 `channel: default` 发送 `remove_channel` 以清理旧的默认渠道: ```yaml automation: - alias: 删除运动渠道 trigger: ... action: - action: notify.mobile_app_ data: message: "remove_channel" data: channel: "Motion" # 您希望删除的渠道名称 ``` #### 特定渠道属性 :::info 如果您的设备是 Android 8.0+,以下属性将在首次设置时成为 `channel` 的默认值: * [`vibrationPattern`](#notification-vibration-pattern) * [`ledColor`](#notification-led-color) * [`importance`](#notification-channel-importance) 这些选项一旦为特定渠道设置,将被忽略,只有降低 `importance` 才有效(如果用户尚未修改此设置)。 运行 Android 6-7.1.2 的设备没有渠道,无需担心此说明。 ::: ### 通知渠道重要性 当您为通知设置 `channel` 时,您还可以选择为每个通知设置渠道的 `importance`。此属性的可能值有 `high`、`low`、`max`、`min` 和 `default`。要了解更多关于每个值的作用,请参阅 [FCM 文档](https://developer.android.com/training/notify-user/channels#importance)。对于 Android 8.0 之前的设备,此属性可以像 `priority` 一样使用,具有上面描述的相同选项。 有关此属性的重要行为,请参阅[特定渠道属性](#specific-channel-properties)。 ```yaml automation: - alias: "通知运动渠道重要性" trigger: ... action: - action: notify.mobile_app_ data: message: "检测到运动" data: channel: "Motion" # 仅适用于 Android 8.0+ 的设备 importance: high ``` ### 通知振动模式 您可以通过设置 `vibrationPattern` 属性来设置渠道的振动模式。可能的值是数字列表。例如:"100, 1000, 100, 1000, 100" 等。模式规范是"关闭时间、开启时间、关闭时间、开启时间、关闭时间"等。 有关此属性的重要行为,请参阅[特定渠道属性](#specific-channel-properties)。 ```yaml automation: - alias: "通知运动振动" trigger: ... action: - action: notify.mobile_app_ data: message: "检测到运动" data: vibrationPattern: "100, 1000, 100, 1000, 100" # 您希望设置的振动模式 channel: "Motion" # 仅适用于 Android 8.0+ 的设备 ``` ### 通知 LED 颜色 某些 Android 设备具有多色通知 LED。通过设置 `ledColor` 属性,您可以控制 LED 闪烁的颜色。可能的值与 [color](#notification-color) 属性相同,例如 '#2DF56D' # 或 'red'。 有关此属性的重要行为,请参阅[特定渠道属性](#specific-channel-properties)。 ```yaml automation: - alias: "通知运动 LED 颜色" trigger: ... action: - action: notify.mobile_app_ data: message: 检测到运动 data: ledColor: "red" # 将 LED 设置为红色 channel: "Motion" # 仅适用于 Android 8.0+ 的设备 ``` ### 持久通知 持久通知是无法通过滑动关闭的通知。如果您有重要的事情,如触发警报,这些通知非常有用。要使用此属性,您还必须设置 `tag` 属性。`persistent` 属性只接受布尔值(`true/false`),默认为 `false`。持久通知在选择后仍会被关闭,要避免这种情况,请使用 `sticky: true` 使通知保持。 在下面的示例中,我们将创建一个通知,然后在稍后删除它。 ```yaml automation: - alias: "通知运动持久" trigger: ... action: - action: notify.mobile_app_ data: message: "检测到运动" data: persistent: true # 设置为 true 以创建持久通知 tag: "motion" # 持久通知需要一个标签,它可以是任何值 ``` :::info 从 [Android 14](https://developer.android.com/about/versions/14/behavior-changes-all#non-dismissable-notifications) 开始,持久通知将可以被关闭,除非设备被锁定或选择了"全部清除"按钮。 ::: 要删除持久通知,我们向定义的 `tag` 发送 `clear_notification`。 ```yaml automation: - alias: "通知运动持久删除" trigger: ... action: - action: notify.mobile_app_ data: message: "clear_notification" data: tag: "motion" # 您希望清除的持久通知的标签 ``` ### 通知超时 您可以设置通知在用户设备上显示多长时间后自动删除/关闭。您可以使用 `timeout` 属性和以秒为单位的值来实现这一点。 ```yaml automation: - alias: "通知运动超时" trigger: ... action: - action: notify.mobile_app_ data: message: "检测到运动" data: timeout: 600 # 设备应该收到通知的秒数 ``` ### 通知消息 HTML 格式 您可以在通知的 `message` 中添加一些自定义 HTML 标签。 ```yaml automation: - alias: "通知运动 HTML" trigger: ... action: - action: notify.mobile_app_ data: message: > 这是一个 HTML 文本

这是新行后的文本 title: "酷炫的 HTML 格式" ``` :::note 设备兼容性 并非所有设备都支持通知中的 HTML 格式,某些格式在深色模式下可能不会显示。不支持时,通知将显示未格式化的文本。无效的 HTML 可能导致文本缺失或显示不当。 ::: ### 通知图标 您可以通过提供 `icon_url` 来设置通知的图标。提供的 URL 必须是公开可访问的,或者是相对路径(即 `/local/icon/icon.png`),更多详细信息可以在[附件](/companion/notifications/attachments.md)中找到。重要的是要注意,如果您设置了 `image`,Android 将不会显示通知的图标,`image` 将在其位置显示。因此 `message` 将与 `image` 一起显示,并以图像作为图标。 ```yaml automation: - alias: "通知运动图标" trigger: ... action: - action: notify.mobile_app_ data: message: "检测到运动" data: icon_url: "https://github.com/home-assistant/brands/blob/master/core_integrations/_homeassistant/icon.png?raw=true" ``` ### 通知敏感度 / 锁屏可见性 您可以使用 `visibility` 选项更改通知在锁屏上的可见程度。此属性的可能值有: * `public`:始终显示所有通知内容 * `private`(默认):可见性取决于您在系统设置应用 > 通知中的设置;如果锁屏时显示敏感通知的选项已启用,则将显示所有通知内容,否则只显示基本信息,如图标和应用名称 * `secret`:始终在锁屏上隐藏通知 :::info 当您在系统设置中更改 *专门针对 Home Assistant 通知* 的锁屏可见性以在锁屏时隐藏敏感通知内容时,这也会将任何 `public` 通知视为 `private`,您将无法在锁定的设备上看到内容。 ::: ```yaml automation: - alias: "通知丢失设备" trigger: ... action: - action: notify.mobile_app_ data: message: "此手机已丢失,请归还至..." data: visibility: public ``` ### 文字转语音通知 您可以让设备朗读通知,而不是在设备上发布通知。此通知与其他通知不同。您将设置 `message: TTS`,实际要朗读的文本在 `tts_text` 中。当前支持仅限于设备上设置的当前文字转语音区域设置。如果处理消息时出错,您将在设备上看到 toast 消息。请确保 [语音识别和合成](https://play.google.com/store/apps/details?id=com.google.android.tts) 引擎是最新的并设置为默认,以防遇到任何问题。 ```yaml automation: - alias: 通知运动 TTS trigger: ... action: - action: notify.mobile_app_ data: message: "TTS" data: tts_text: "已检测到运动" ``` 默认情况下,文字转语音通知使用音乐流,因此只要设备的音量未设置为 0,它们将绕过设备上的铃声模式。您可以选择使用 `media_stream: alarm_stream` 让您的通知无论音乐音量如何都能朗读出来。 ```yaml automation: - alias: "通知运动 TTS 闹钟" trigger: ... action: - action: notify.mobile_app_ data: message: TTS data: tts_text: "已检测到运动" media_stream: "alarm_stream" ``` 如果您发现闹钟流音量太低,可以使用 `media_stream: alarm_stream_max`,它会临时将闹钟流音量设置为最大级别,播放通知,然后恢复到原始音量级别。 ```yaml automation: - alias: "通知警报触发" trigger: ... action: - action: notify.mobile_app_ data: message: "TTS" data: tts_text: "警报已触发" media_stream: "alarm_stream_max" ``` 您可能不希望在某些情况下朗读 TTS 通知(例如,如果铃声模式不是 `normal` 或 DND 已启用)。这可以通过在自动化中添加检查[其他传感器](/companion/core/sensors.md)状态的条件来实现。以下是一些示例: ```yaml automation: - alias: "带条件的运动通知" trigger: ... condition: - condition: state entity_id: sensor._ringer_mode # 仅当铃声为正常时朗读(不是振动或静音) state: normal - condition: state entity_id: sensor._do_not_disturb_sensor # 仅当 DND 未启用时朗读 state: 'off' - condition: state entity_id: sensor._audio_mode # 仅当电话空闲时朗读(不是响铃或通话中) state: normal - condition: state entity_id: binary_sensor._music_active # 仅当电话未播放音乐时朗读 state: 'off' action: - action: notify.mobile_app_ data: message: TTS data: tts_text: 已检测到运动 ``` ### 计时器通知 您可以通过传递 `chronometer` 和 `when` 选项创建带有向上/向下计时器(计时器)的通知。此功能至少需要 Android 7.0。 请注意,当计时器达到 0 时,通知不会消失。相反,它将继续递减为负值。 您可能希望使用[通知超时](#notification-timeout)或在计时器归零时[替换通知](#replacing)。 * chronometer - 设置为 true 以启用计时器模式 * when - 要向上或向下计数的时间戳(自 1970 年 1 月 1 日以来的秒数) * when\_relative - 设置为 true 使 "when" 的值相对,以秒为单位,如 "timeout" ```yaml automation: - alias: 通知下一个闹钟时间 trigger: ... action: - action: notify.mobile_app_ data: title: "下一个闹钟" message: >- 下一个闹钟时间 {{ states('sensor._next_alarm') }} data: timeout: 120 chronometer: true when: 120 when_relative: true ``` ### 进度通知 您可以通过传递 `progress` 选项创建带有进度条的通知。 通知需要持续更新以跟踪进度。确保使用 `tag` 来[替换](#replacing)现有通知。一旦进程完成,您可以通过发送进度值 `-1` 来删除进度条。 * progress - 当前进度值 * progress\_max - 进度的最大值(默认为 `1`) * progress\_indeterminate - 设置为 `true` 使进度条不显示特定进度,而是显示连续动画(默认为 `false`) ```yaml automation: - alias: 通知文件传输进度 trigger: ... action: - action: notify.mobile_app_ data: title: "文件传输" message: "文件传输进行中:6 / 32 MB" data: tag: file-transfer progress: 6 progress_max: 32 ``` ### 实时更新 BETA {#live-updates} 在 Android 16.0+ 上,您可以创建"实时更新"通知。这些通知固定在通知栏顶部,并显示在锁屏和常亮显示上。它们还将作为芯片显示在状态栏中,带有可选的短文本。这可能因制造商而异。 要使通知显示为"实时更新"通知,必须提供 `title`。 * `live_update` - 设置为 `true` 以显示为"实时更新"通知 * `critical_text` - 设置一个可选的短文本显示在状态栏芯片中 * `live_update` 必须同时设置为 `true` * 如果状态栏中没有足够的空间显示文本,则只会显示图标 * 如果使用 `chronometer` 参数,它将替换 `critical_text` 值 #### 基本配置 ```yaml automation: - alias: 通知实时更新 trigger: ... action: - action: notify.mobile_app_ data: title: "实时更新" message: "这将显示在常亮显示上" data: live_update: true critical_text: "42%" ``` 这些截图显示通知在状态栏中的显示方式(带或不带关键文本) ![状态栏芯片](/companion-assets/android/live_updates_without_critical_text.png) ![使用关键文本时的状态栏芯片](/companion-assets/android/live_updates_with_critical_text.png) #### 与进度、计时器、标签和图标组合的配置 ```yaml automation: - alias: 通知实时更新 trigger: ... action: - action: notify.mobile_app_ data: title: 显示进度的示例通知 message: 当前进度为 42% data: live_update: true chronometer: true when: 315 when_relative: true progress: 42 progress_max: 100 tag: live_progress_notification notification_icon: mdi:progress-helper ``` 此截图显示上述配置在常亮显示上的外观 ![常亮显示上显示进度和计时器的示例通知](/companion-assets/android/live_updates_always_on_display.png) ### 仅警报一次 在 Android 上,您可以选择使通知仅在设备上警报一次。这意味着它只会在第一次发出声音、振动和/或闪烁 LED。虽然这不是 Android 的要求,但如果您没有设置 [`tag`](#replacing),此功能将无法正常工作。此设置默认为 `false`,因为每个通知都会提醒用户。此功能使用 [Alert Once API](https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder#setOnlyAlertOnce\(boolean\)) ```yaml - alias: 通知一次 trigger: ... action: - action: notify.mobile_app_ data: title: "一次" message: "这只会在第一次提醒我" data: tag: "Alarm" alert_once: true ``` ### 通知状态栏图标 Android
在 Android 上,您还可以选择将通知状态栏图标更改为 [Material Design](https://materialdesignicons.com/) 上的任何图标。默认情况下,将显示 Home Assistant 图标。预期格式与 Home Assistant 中的相同 `mdi:cellphone`。如果您提供无效的图标名称,则不会显示图标。 ```yaml - alias: 检查您的手机 trigger: ... action: - action: notify.mobile_app_ data: title: "手机图标" message: "这将在状态栏中显示手机图标" data: notification_icon: "mdi:cellphone" ``` ### Android Auto 可见性 默认情况下,Home Assistant 通知不会显示在 Android Auto 界面中。通过添加 `car_ui: true`,通知将变得可见,并且从 Android Auto 打开它们将启动驾驶界面。有关通知在 Android Auto 中如何工作的更多详细信息,请[查看 Android Auto 文档](/companion/android-auto/index.md#notifications)。 ```yaml - alias: 发送门未锁警报 trigger: ... action: - action: notify.mobile_app_ data: title: "门未锁" message: "所有人都离开了家,但门仍然未锁" data: car_ui: true ``` ## iOS/macOS 专属 ### 声音 默认情况下,收到通知时会播放默认通知声音(iOS 上为 Tri-tone)。有关可用声音以及如何添加自定义声音的详细信息,请参阅[声音文档](/companion/notifications/sounds.md)。可以通过在数据负载中将 `sound` 设置为 `none` 来禁用默认通知声音(Tri-tone): ```yaml automation: - alias: 发出一些噪音 trigger: ... action: - action: notify.mobile_app_ data: message: "叮咚" data: push: sound: none ``` ### 徽章 您可以在负载中设置应用图标徽章。以下示例将使应用图标徽章显示 5: ```yaml automation: - alias: "通知移动应用更新徽章" trigger: ... action: - action: notify.mobile_app_ data: title: "智能家居警报" message: "家里发生了一些事情!" data: push: badge: 5 ``` 通过将消息设置为 `delete_alert`,您可以在后台静默更新应用图标徽章,而无需向手机发送通知。 iOS 2021.7 将在启动应用时自动将徽章重置为 0。您可以在 [配置](https://my.home-assistant.io/redirect/config/) > Companion App > 通知中控制此行为。 ### 中断级别 在 iOS 15 上,您可以设置通知的中断级别,它有以下类型: | 值 | 描述 | 覆盖专注模式 | | -- | -- | -- | | `passive` | 安静的通知,不唤醒屏幕 | 否 | | `active` | 默认行为 | 否 | | `time-sensitive` | 重要通知 | 是 | | `critical` | [关键通知](/companion/notifications/critical.md) | 是,甚至静音 | :::note iOS 要求 `time-sensitive` 需要 iOS/macOS-2021.12 或更高版本。 ::: 您可以在 [Apple 文档](https://developer.apple.com/design/human-interface-guidelines/ios/system-capabilities/notifications/) 中阅读有关这些级别的更多信息。 默认情况下,`time-sensitive` 通知将作为公告朗读。您可以在系统设置应用 > 通知 > 公告通知 > Home Assistant 中控制哪些通知被公告。 此级别在负载中设置。以下示例传递一个 `passive` 通知: ```yaml automation: - alias: "通知移动应用香蕉状态" trigger: ... action: - action: notify.mobile_app_ data: title: "香蕉状态更新" message: "香蕉熟了。" data: push: interruption-level: passive ``` ### 展示选项 默认情况下,如果通知到达时应用处于打开状态(在前台),它将显示与应用未活动(在后台)时相同的方式,带有显示通知内容的视觉警报、徽章更新(如果通知中发送了一个)和您选择的声音。您可以通过设置 `presentation_options` 字符串数组来控制应用在前台时如何显示通知。允许的值有 `alert`、`badge` 和 `sound`。 ```yaml automation: - alias: "通知移动应用展示" trigger: ... action: - action: notify.ALL_DEVICES data: message: "家里发生了一些事情!" data: presentation_options: - alert - badge ``` ### 执行快捷方式 您可以在启动通知时执行快捷方式,并从结果中触发事件。请参阅 [Siri 快捷方式文档](/companion/integrations/siri-shortcuts.md#executing-a-shortcut-via-home-assistant-notifications)。 --- url: /companion/notifications/cleared.md --- # 通知清除 Android 当通知被清除时,Android 会通知伴侣应用此事件。除了确保组被取消外,应用还会向您的 Home Assistant 实例发送 `mobile_app_notification_cleared` 事件。此事件将包含发送到设备的所有通知数据。此事件将在每个被清除的通知上触发。如果您手动从通知状态栏滑动清除,或点击"全部清除"按钮,则视为通知已清除。如果点击通知打开应用,则不会发送事件。 示例事件数据: ```json { "event_type": "mobile_app_notification_cleared", "data": { "message": "test", "device_id": "DEVICE_ID" }, "origin": "REMOTE", "time_fired": "2020-10-06T05:36:12.864583+00:00", "context": { "id": "ID", "parent_id": null, "user_id": "USER_ID" } } ``` --- url: /companion/notifications/commands.md --- # 通知命令 伴侣应用提供许多不同的通知选项。您可以发送命令作为 `message` 来触发手机上的某些操作,而不是在设备上发布实际通知。请阅读以下内容,了解每个平台支持哪些命令。 iOS | 命令 | 描述 | | ------- | ----------- | | `request_location_update` | 从设备请求位置更新,有关此命令的影响,[见下文](#request-location-updates)。 | | `clear_badge` | 静默地从应用图标中移除徽章,而不显示通知。 | | `clear_notification` | 移除通知,[更多详情](/companion/notifications/basic.md#clearing)。 | | `update_complications` | 更新配对 Apple Watch 上的复杂功能。[更多详情](/companion/apple-watch/complications.md)。 | | `update_widgets`\* | 更新应用 v2024.7 中引入的"仪表"和"详情"小部件(iOS 将决定是否允许更新,所以如果它不总是工作,请不要担心)。 | \* 在 iOS 上,手动小部件重新加载限制为每 24 小时约 40-70 次,具体取决于您查看小部件的频率。这不会总是在午夜整点重置。 Android | 命令 | 描述 | | ------- | ----------- | | `clear_notification`\* | 从状态栏移除通知,[更多详情](/companion/notifications/basic.md#clearing)。 | | `command_activity` | 使用指定的 URI 启动任何应用的活动,[更多详情](#activity)和下面的用例。 | | `command_app_lock` | 更改伴侣应用锁定设置,[更多详情](#app-lock)和下面的用例。 | | `command_auto_screen_brightness` | 控制是否启用自动屏幕亮度。 | | `command_bluetooth` | 打开或关闭蓝牙。 | | `command_ble_transmitter` | 打开或关闭 BLE 信标发射器。 | | `command_beacon_monitor` | 打开或关闭信标监控。 | | `command_broadcast_intent` | 向另一个应用发送广播意图,[见下文](#broadcast-intent)了解其工作原理和要求。 | | `command_dnd` | 控制设备上的勿扰模式,[见下文](#do-not-disturb)了解其工作原理和要求。 | | `command_flashlight` | 打开或关闭手电筒 LED。 | | `command_high_accuracy_mode` | 控制后台位置传感器的高精度模式,[见下文](#high-accuracy-mode)了解其工作原理和要求。 | | `command_launch_app` | 启动应用程序,[见下文](#launch-app)了解其工作原理和要求。 | | `command_media` | 控制设备上播放的媒体,[见下文](#media)了解其工作原理和要求。 | | `command_ringer_mode` | 控制设备上的铃响模式,[见下文](#ringer-mode)了解其工作原理和要求。 | | `command_screen_brightness_level` | 控制设备上的屏幕亮度级别。 | | `command_screen_off_timeout` | 控制设备上的屏幕关闭超时。 | | `command_screen_on` | 打开设备屏幕。 | | `command_stop_tts`\* | 如果当前正在使用文本转语音,则停止它。 | | `command_persistent_connection` | 切换持久连接模式,[见下文](#persistent)了解可用模式。 | | `command_update_sensors` | 更新所有已启用的传感器,如果自上次更新以来状态已更改。 | | `command_volume_level` | 控制所有可用音频流的音量,[见下文](#volume-level)了解其工作原理和要求。 | | `command_wake_word_detection` | 打开或关闭助手唤醒词检测。测试版 | | `command_webview` | 打开应用到主页或任何仪表板或视图,[见下文](#webview)了解如何操作。 | | `remove_channel`\* | 从设备设置中移除通知渠道,[更多详情](/companion/notifications/basic.md#removing-a-channel)。 | | `request_location_update` | 从设备请求位置更新,[见下文](#request-location-updates)了解此命令的影响。 | \* 这些命令将始终工作,即使其他命令被禁用。 ## Activity Android 在 Android 上,您可以发送 `message: command_activity` 来启动任何活动。此命令需要特定权限,应用无法提示或自动接受。相反,通过首次发送命令,应用将启动一个活动,允许用户启用 Home Assistant 访问设备的"在其他应用上显示"策略。这是应用获得对此设置控制权所必需的。 `intent_action` 参数需要设置为意图操作字符串,否则通知将正常发布。如果活动需要 URI,则需要将其设置为 `intent_uri`,否则通知将正常发布。`intent_package_name` 可以设置为要启动活动的包,否则 Android 将尽力选择默认值。如果找不到包,则通知将正常发布。您必须知道预期的 URI(如果需要)、操作和包来启动活动。通常,如果应用支持,这将是一个记录的功能。 [Extras](https://developer.android.com/reference/android/content/Intent#putExtra\(java.lang.String,%20java.lang.String\)) 也在 `intent_extras` 参数下支持。由于可以向意图添加任意数量的额外内容,我们需要用逗号 `,` 分隔每个额外内容。然后每个额外内容名称和值需要用冒号 `:` 分隔。请参阅[广播意图](#broadcast-intent)中的示例以查看正确的格式。 如果需要设置 MIME 类型,也可以将 `intent_type` 设置为 MIME 类型。如果活动需要,您需要知道 MIME 类型字符串。 某些应用还需要提供类或组件。对于这些应用,您需要将包作为 `intent_package_name` 提供,并将完整且完整的类名在 `intent_class_name` 参数下提供。您需要知道提供什么类名,因为每个应用都不同。 下面的示例遵循 [Google 的文档](https://developers.google.com/maps/documentation/urls/android-intents#launch-turn-by-turn-navigation),通过启动 Google 地图导航向您展示此功能的工作原理。 示例: ```yaml automation: - alias: 导航 trigger: ... action: - action: notify.mobile_app_ data: message: "command_activity" data: intent_package_name: "com.google.android.apps.maps" intent_action: "android.intent.action.VIEW" intent_uri: "google.navigation:q=arbys" ``` 继续上面的示例,您还可以使用以下内容启动[搜索结果](https://developer.android.com/guide/components/intents-common#Maps): ```yaml automation: - alias: 搜索谷歌地图 trigger: ... action: - action: notify.mobile_app_ data: message: "command_activity" data: intent_package_name: "com.google.android.apps.maps" intent_action: "android.intent.action.VIEW" intent_uri: "geo:0,0?q=1600+Amphitheatre+Parkway%2C+CA" ``` 为了使用意图操作 `android.intent.action.CALL`,您还需要授予应用电话权限。如果未授予,应用将引导您到应用信息屏幕授予权限,并显示一条 toast 消息让您知道缺少的权限。 ## 应用锁定 Android 要控制 Android 伴侣应用的安全性,用户可以使用 `message: command_app_lock` 更改应用锁定设置。与应用锁定相关的所有设置都可以在单个命令中配置。以下设置可通过通知命令访问: | 参数 | 类型 | 描述 | |---------|---------|--------| | `app_lock_enabled` | 布尔值 | 是否启用生物识别/屏幕锁定 | | `app_lock_timeout` | 整数 | 会话超时时间(秒) | | `home_bypass_enabled` | 布尔值 | 连接到家庭 WiFi 时是否绕过锁定 | 示例: ```yaml automation: - alias: 将应用锁定重置为默认值 trigger: ... action: - action: notify.mobile_app_ data: message: "command_app_lock" data: app_lock_enabled: true app_lock_timeout: 60 home_bypass_enabled: false ``` ## 自动屏幕亮度 Android 您可以使用 `message: command_auto_screen_brightness` 控制设备上是否启用自动亮度,`command` 为 `turn_off` 或 `turn_on`。如果 `command` 为空、未设置或不是上述预期值之一,则通知将正常发布。 示例: ```yaml automation: - alias: 关闭自动屏幕亮度 trigger: ... action: - action: notify.mobile_app_ data: message: "command_auto_screen_brightness" data: command: "turn_off" ``` ## BLE 信标发射器 Android 用户可以使用 `message: command_ble_transmitter` 打开或关闭 iBeacon 发射器,`command` 为 `turn_off` 或 `turn_on`。如果 `command` 为空、未设置或不是上述预期值之一,则通知将正常发布。 示例: ```yaml automation: - alias: 关闭 BLE 发射器 trigger: ... action: - action: notify.mobile_app_ data: message: "command_ble_transmitter" data: command: "turn_off" ``` 您还可以调整 BLE 发射器的广播模式和发射功率。要调整广播模式,您需要将 `command` 设置为 `ble_set_advertise_mode`,然后将 `ble_advertise` 参数设置为 `ble_advertise_low_latency`、`ble_advertise_balanced` 或 `ble_advertise_low_power` ```yaml automation: - alias: 更改 BLE 发射器广播模式 trigger: ... action: - action: notify.mobile_app_ data: message: "command_ble_transmitter" data: command: "ble_set_advertise_mode" ble_advertise: "ble_advertise_balanced" ``` 要调整发射功率,您需要将 `command` 设置为 `ble_set_transmit_power`,然后将 `ble_transmit` 参数设置为 `ble_transmit_high`、`ble_transmit_medium`、`ble_transmit_low` 或 `ble_transmit_ultra_low` ```yaml automation: - alias: 更改 BLE 发射器发射功率 trigger: ... action: - action: notify.mobile_app_ data: message: "command_ble_transmitter" data: command: "ble_set_transmit_power" ble_transmit: "ble_transmit_high" ``` 用户还可以使用以下命令及其各自的参数更改报告的 UUID、Major 和 Minor 参数。您可以为 UUID、Major 和 Minor 属性发送任何类型的字符串值。如果缺少任何数据,通知将在设备上正常发布。 | 命令 | 参数 | |---------|---------| | `ble_set_uuid` | `ble_uuid` | | `ble_set_major` | `ble_major` | | `ble_set_minor` | `ble_minor` | 更改发射器 UUID 的示例: ```yaml automation: - alias: 更改 BLE 发射器 UUID trigger: ... action: - action: notify.mobile_app_ data: message: "command_ble_transmitter" data: command: "ble_set_uuid" ble_uuid: "b4306bba-0e3a-44df-9518-dc74284e8214" ``` 用户还可以更改 1 米处的测量功率,以帮助改善其设备的检测。此数字必须为负数。在某些情况下,如垃圾字符、缺少数据或数字为正数时,将设置默认值 `-59`,通知将在设备上正常发布。 ```yaml automation: - alias: 更改 BLE 发射器测量功率 trigger: ... action: - service: notify.mobile_app_ data: message: command_ble_transmitter data: command: ble_set_measured_power ble_measured_power: "-75" ``` ## 信标监控 Android
您可以使用 `message: command_beacon_monitor` 打开或关闭信标监控,`command` 为 `turn_off` 或 `turn_on`。如果 `command` 为空、未设置或不是上述预期值之一,则通知将正常发布。 示例: ```yaml automation: - alias: 关闭信标监控 trigger: ... action: - action: notify.mobile_app_ data: message: "command_beacon_monitor" data: command: "turn_off" ``` ## 蓝牙 Android  Android 12 或更早版本 用户可以使用 `message: command_bluetooth` 打开或关闭蓝牙,`command` 为 `turn_off` 或 `turn_on`。如果 `command` 为空、未设置或不是上述预期值之一,则通知将正常发布。 示例: ```yaml automation: - alias: 命令蓝牙 trigger: ... action: - action: notify.mobile_app_ data: message: "command_bluetooth" data: command: "turn_off" ``` ## 广播意图 Android 使用通知命令,您现在可以向另一个应用发送广播意图,以便根据意图控制该应用。并非所有应用都支持意图,如果支持,它们可能会为用户记录它以进行控制。您必须设置 `message: command_broadcast_intent`,`intent_action` 必须包含意图操作,而 `intent_package_name` 必须包含意图的包。包名和操作由您希望发送意图的应用提供。 某些应用还需要提供类或组件。对于这些应用,您需要将包作为 `intent_package_name` 提供,并将完整且完整的类名在 `intent_class_name` 参数下提供。您需要知道提供什么类名,因为每个应用都不同。 如果发送了无效格式,您可能会看到通知或 toast 消息。 示例: ```yaml automation: - alias: 发送广播意图 trigger: ... action: - action: notify.mobile_app_ data: message: "command_broadcast_intent" data: intent_package_name: "package-name" intent_action: "action" ``` 接受广播意图的应用示例是 [Sleep as Android](https://docs.sleep.urbandroid.org/devs/intent_api.html#action-intents-to-control-sleep)。要启动睡眠跟踪事件,格式如下: ```yaml automation: - alias: 发送广播意图开始睡眠跟踪 trigger: ... action: - action: notify.mobile_app_ data: message: "command_broadcast_intent" data: intent_package_name: "com.urbandroid.sleep" intent_action: "com.urbandroid.sleep.alarmclock.START_SLEEP_TRACK" ``` [Extras](https://developer.android.com/reference/android/content/Intent#putExtra\(java.lang.String,%20java.lang.String\)) 也在 `intent_extras` 参数下支持。由于可以向意图添加任意数量的额外内容,我们需要用逗号 `,` 分隔每个额外内容。然后每个额外内容名称和值需要用冒号 `:` 分隔。下面的示例向您展示如何在 Sleep as Android 应用中打开标记为 `work` 的闹钟。在此示例中,有 2 个额外内容添加到意图中。 ```yaml automation: - alias: 发送带额外内容的广播意图 trigger: ... action: - action: notify.mobile_app_ data: message: "command_broadcast_intent" data: intent_package_name: "com.urbandroid.sleep" intent_extras: "alarm_label:work,alarm_enabled:false" intent_action: "com.urbandroid.sleep.alarmclock.ALARM_STATE_CHANGE" ``` 如果您不指定特定类型,则根据您的输入猜测类型。数字将转换为整数,`true` 或 `false` 将转换为布尔值。否则意图额外内容将设置为字符串。 您尝试发送的数据包含特殊字符或用作解析 intent\_extra 参数时的分隔符的字符(`,`、`:` 或 `;`)的情况并不少见。在这种情况下,建议您通过在末尾附加另一个冒号 `:` 将数据类型指定为 `String.urlencoded`。例如,要将 JSON 格式的额外内容发送到 Gadgetbridge,您可以使用以下内容: ```yaml automation: - alias: 发送带 JSON 格式额外内容的广播意图 trigger: ... action: - action: notify.mobile_app_ data: message: "command_broadcast_intent" data: intent_package_name: "nodomain.freeyourgadget.gadgetbridge" intent_extras: "EXTRA_CONFIG_JSON:%7B%22push%22%3A%7B%22set%22%3A%7B%22widgetCustom0._.config.upper_text%22%3A%22Hi%22%7D%7D%7D:String.urlencoded" intent_action: "nodomain.freeyourgadget.gadgetbridge.Q_PUSH_CONFIG" ``` 字符串可以通过应用[过滤器](https://www.home-assistant.io/docs/configuration/templating/#string-filters) `urlencode` 在模板中进行 urlencoded。例如,模板 `{{ ",:;" | urlencode }}` 结果为 `%2C%3A%3B`。 如果您尝试将数据作为数组或 ArrayList 发送,则各个值用分号 `;` 分隔。以这种方式发送值时必须指定数组的类型,例如 `float[]`。例如,您可以使用[可穿戴集成 API](https://docs.sleep.urbandroid.org/devs/wearable_api.html#send-movement-data) 将多个传感器值作为运动数据发送到 Sleep as Android: ```yaml automation: - alias: 发送带 float 数组运动数据的广播意图到 Sleep as Android trigger: ... action: - action: notify.mobile_app_ data: message: "command_broadcast_intent" data: intent_package_name: "com.urbandroid.sleep" intent_extras: "MAX_RAW_DATA:0.2;0.2;0.4;0.3;5.4;6.8;1.2:float[]" intent_action: "com.urbandroid.sleep.watch.DATA_UPDATE" ``` 除了上述类型外,您还可以向意图额外内容添加其他特定类型。然后,您的值将根据您指定的类型进行转换。确保类型转换是可能/有意义的。 目前支持的类型有: |类型|示例| |----|-------| |[Integer](https://developer.android.com/reference/android/content/Intent#putExtra\(java.lang.String,%20int\))|`EXTRA:101:int`| |[Integer Array](https://developer.android.com/reference/android/content/Intent#putExtra\(java.lang.String,%20int[]\))|`EXTRA:101;102;103:int[]`| |[ArrayList\](https://developer.android.com/reference/android/content/Intent#putIntegerArrayListExtra\(java.lang.String,%20java.util.ArrayList%3Cjava.lang.Integer%3E\))|`EXTRA:1;2;3:ArrayList`| |[Double](https://developer.android.com/reference/android/content/Intent#putExtra\(java.lang.String,%20double\))|`EXTRA:10.1:double`| |[Double Array](https://developer.android.com/reference/android/content/Intent#putExtra\(java.lang.String,%20double[]\))|`EXTRA:10.1;10.2;10.3:double[]`| |[Float](https://developer.android.com/reference/android/content/Intent#putExtra\(java.lang.String,%20float\))|`EXTRA:10.1:float`| |[Float Array](https://developer.android.com/reference/android/content/Intent#putExtra\(java.lang.String,%20float[]\))|`EXTRA:10.1;10.2;10.3:float[]`| |[Long](https://developer.android.com/reference/android/content/Intent#putExtra\(java.lang.String,%20long\))|`EXTRA:101:long`| |[Long Array](https://developer.android.com/reference/android/content/Intent#putExtra\(java.lang.String,%20long[]\))|`EXTRA:101;102;103:long[]`| |[Short](https://developer.android.com/reference/android/content/Intent#putExtra\(java.lang.String,%20short\))|`EXTRA:1:short`| |[Short Array](https://developer.android.com/reference/android/content/Intent#putExtra\(java.lang.String,%20short[]\))|`EXTRA:1;2;3:short[]`| |[Byte](https://developer.android.com/reference/android/content/Intent#putExtra\(java.lang.String,%20byte\))|`EXTRA:127:byte`| |[Byte Array](https://developer.android.com/reference/android/content/Intent#putExtra\(java.lang.String,%20byte[]\))|`EXTRA:127;64:byte[]`| |[Boolean](https://developer.android.com/reference/android/content/Intent#putExtra\(java.lang.String,%20boolean\))|`EXTRA:true:boolean`| |[Boolean Array](https://developer.android.com/reference/android/content/Intent#putExtra\(java.lang.String,%20boolean[]\))|`EXTRA:true;true;false:boolean[]`| |[Char](https://developer.android.com/reference/android/content/Intent#putExtra\(java.lang.String,%20char\))|`EXTRA:a:char`| |[Char Array](https://developer.android.com/reference/android/content/Intent#putExtra\(java.lang.String,%20char[]\))|`EXTRA:a;b;c:char[]`| |[String](https://developer.android.com/reference/android/content/Intent#putExtra\(java.lang.String,%20java.lang.String\))|`EXTRA:abc:String`| |[String (urlencoded)](https://developer.android.com/reference/android/content/Intent#putExtra\(java.lang.String,%20java.lang.String\))|`EXTRA:%2C%3A%3B:String.urlencoded` 或 `EXTRA:%2C%3A%3B:urlencoded`| |[String Array](https://developer.android.com/reference/android/content/Intent#putExtra\(java.lang.String,%20java.lang.String[]\))|`EXTRA:a;b;c:String[]`| |[String Array (urlencoded)](https://developer.android.com/reference/android/content/Intent#putExtra\(java.lang.String,%20java.lang.String[]\))|`EXTRA:colon%3A;semicolon%3B;comma%2C:String[].urlencoded`| |[ArrayList\](https://developer.android.com/reference/android/content/Intent#putStringArrayListExtra\(java.lang.String,%20java.util.ArrayList%3Cjava.lang.String%3E\))|`EXTRA:a;b;c:ArrayList`| |[ArrayList\ (urlencoded)](https://developer.android.com/reference/android/content/Intent#putStringArrayListExtra\(java.lang.String,%20java.util.ArrayList%3Cjava.lang.String%3E\))|`EXTRA:colon%3A;semicolon%3B;comma%2C:ArrayList.urlencoded`| ## 勿扰模式 Android 在 Android 上,您可以发送 `message: command_dnd` 来控制设备上的勿扰模式状态。此命令需要特定权限,应用无法提示或自动接受。相反,通过首次发送命令,应用将启动一个活动,允许您启用 Home Assistant 访问设备的通知策略。这是应用获得对此设置控制权所必需的。 除了发送 `message` 外,您还必须提供您希望设置的勿扰模式状态作为 `command`,请参阅下表了解接受的内容。如果 `command` 与列出的命令之一不匹配,则通知将正常发布,命令将不会处理。 :::info 在 Android 15 及更高版本上,Android 将跟踪哪些应用正在启用/禁用勿扰模式,并且只允许应用调整之前由应用设置的设置。这意味着: * 如果多个应用启用勿扰模式,Android 将使用最严格的勿扰模式过滤器。例如,如果您发送一个仅闹钟的通知命令,而另一个应用将勿扰模式设置为无中断,则无中断过滤器将"胜出"。 * 应用只能禁用勿扰模式(`off`),如果它之前是使用来自 Home Assistant 的通知命令启用的。 :::
| `command` | 描述 | | ------- | ----------- | | `alarms_only` | 仅闹钟中断过滤器 - 除闹钟类别中的通知外,所有通知都被抑制。某些音频流被静音。 | | `off` | 正常中断过滤器 - 没有通知被抑制。 | | `priority_only` | 优先中断过滤器 - 除符合优先级标准的通知外,所有通知都被抑制。某些音频流被静音。 | | `total_silence` | 无中断过滤器 - 所有通知都被抑制,所有音频流(用于电话呼叫的除外)和振动都被静音。 | | 其他 | 通知将作为正常通知发布,命令将不会处理。 |
```yaml automation: - alias: 命令勿扰模式 trigger: ... action: - action: notify.mobile_app_ data: message: "command_dnd" data: command: "priority_only" ``` ## 手电筒 Android 此命令允许您直接从通知打开或关闭手电筒,无需打开应用即可控制设备的手电筒。要使用它,发送 `message: command_flashlight`,并将 `command` 参数设置为 `turn_on` 或 `turn_off` 来控制手电筒状态。 示例: ```yaml automation: - alias: 打开手电筒 trigger: ... action: - action: notify.mobile_app_ data: message: "command_flashlight" data: command: "turn_on" ``` ## 高精度模式 Android 用户可以使用 `message: command_high_accuracy_mode` 打开或关闭后台位置传感器的高精度模式,`command` 为 `turn_off`、`turn_on`、`force_off` 或 `force_on`。如果 `command` 为空、未设置或不是上述预期值之一,则通知将正常发布。`turn` 和 `force` 之间的区别仅在高精度模式设置中设置了区域和/或蓝牙约束时才相关。在这种情况下,`force_on` 将使高精度模式保持活动,直到发送 `force_off`,或者约束从活动变为非活动。类似地,`force_off` 将关闭高精度模式,直到发送 `force_on`,或者约束从非活动变为活动。 示例: ```yaml automation: - alias: 关闭高精度模式 trigger: ... action: - action: notify.mobile_app_ data: message: "command_high_accuracy_mode" data: command: "turn_off" ``` 您还可以按照以下示例调整高精度模式的更新间隔。您必须发送一个有效值,不能小于 `5`。其他任何值都将导致通知发布到设备。执行此命令后,高精度模式将重新启动,这可能需要几秒钟才能完成。 ```yaml automation: - alias: 设置高精度更新间隔 trigger: ... action: - action: notify.mobile_app_ data: message: "command_high_accuracy_mode" data: high_accuracy_update_interval: 60 command: "high_accuracy_set_update_interval" ``` ## 启动应用 Android 如果您只想简单地启动一个应用程序,可以使用 `message: command_launch_app` 来启动设备上安装的任何应用程序。您必须使用 `package_name` 参数发送您希望打开的包名,如果未设置,则您将看到通知正常发布。如果设备上未安装该应用程序,用户将被引导到 Google Play 商店安装该应用程序。此命令需要"在其他应用上绘制"权限,第一次发送此命令时,您将被引导授予 Home Assistant 应用此特殊权限。 ```yaml automation: - alias: 启动应用 trigger: ... action: - action: notify.mobile_app_ data: message: "command_launch_app" data: package_name: "com.twitter.android" ``` ## 媒体 Android 用户可以控制其设备上的任何活动媒体会话。您必须设置 `message: command_media`,`media_command` 必须是下面列表中的一个。`media_package_name` 必须设置为您希望控制的包名。如果必填字段之一为空、数据不正确或媒体会话未活动,通知将正常发布。 接受的 `media_command` 媒体命令列表: * `fast_forward` * `next` * `pause` * `play` * `play_pause` * `previous` * `rewind` * `stop` 示例: ```yaml automation: - alias: 暂停 Spotify trigger: ... action: - action: notify.mobile_app_ data: message: "command_media" data: media_command: "pause" media_package_name: "com.spotify.music" ``` ## 请求位置更新 Android iOS :::caution 由于下面提到的时间限制,不要依赖此功能。 ::: 您可以通过发送特殊通知强制设备尝试报告其位置。通知对设备所有者不可见,仅在应用运行或处于后台时工作。 iOS 成功时,sensor.last_update_trigger 将更改为"Push Notification"。 ```yaml automation: - alias: 请求位置更新 trigger: ... action: - action: notify.mobile_app_ data: message: "request_location_update" ``` 假设设备收到通知,它将尝试在 5 秒内获取位置更新并将其报告给 Home Assistant。这有点碰运气,因为 Apple 对应用处理通知和位置更新的最大时间有限制,有时由于等待 GPS 获取等因素而需要比平时更长的时间。 :::danger 虽然可以在 Home Assistant 中创建自动化来定期调用此操作以更新传感器,但不建议这样做,因为这样做太频繁可能会对设备的电池寿命和健康状况产生负面影响。 ::: ## 铃响模式 Android 在 Android 上,您可以通过发送 `message: command_ringer_mode` 并附加上下表中概述的适当 `command` 来控制设备的铃响模式。某些设备需要授予特殊权限,如果尚未授予权限,将在收到第一个命令时出现。这与上面的[勿扰模式](#do-not-disturb)权限相同。如果设备启用了勿扰模式,则设置为 `normal` 或 `vibrate` 将关闭它。如果设备未启用勿扰模式,则 `silent` 将打开它。
| `command` | 描述 | | ------- | ----------- | | `normal` | 将设备设置为正常铃响模式,如果启用且支持,将关闭勿扰模式。 | | `silent` | 将设备设置为静音铃响模式,如果禁用且支持,将打开勿扰模式。 | | `vibrate` | 将设备设置为振动铃响模式,如果启用且支持,将关闭勿扰模式。 | | 其他 | 通知将作为正常通知发布,命令将不会处理。 |
```yaml automation: - alias: 命令铃响模式 trigger: ... action: - action: notify.mobile_app_ data: message: "command_ringer_mode" data: command: "vibrate" ``` ## 屏幕亮度级别 Android 您可以通过发送 `message: command_screen_brightness_level` 来控制设备上的屏幕亮度级别,`command` 为屏幕应有的亮度级别。有效值在 `0` 到 `255` 之间。如果您不发送数字或发送空值,则通知将正常发布。如果您发送低于 `0` 或高于 `255` 的值,则应用将分别默认为 `0` 或 `255`。 ```yaml automation: - alias: 设置屏幕亮度级别 trigger: ... action: - action: notify.mobile_app_ data: message: "command_screen_brightness_level" data: command: 50 ``` ## 屏幕关闭超时 Android 您可以通过发送 `message: command_screen_off_timeout` 来控制设备上的屏幕关闭超时,`command` 为超时值(毫秒)。如果您不发送数字或发送空值,则通知将正常发布。这些值将遵守 android 系统定义的最小值和最大值,例如在 Pixel 设备上,低于 `10000` 的任何值将被视为 10 秒超时。 ```yaml automation: - alias: 设置屏幕关闭超时 trigger: ... action: - action: notify.mobile_app_ data: message: "command_screen_off_timeout" data: command: 10000 ``` ## 屏幕开启 Android 在 Android 上,您可以通过简单地发送 `message: command_screen_on` 使用通知打开屏幕。这不会移除或禁用您在设备上设置的任何锁屏。原因是与应用无法将设备策略设置回去(应用崩溃)或设备在移除后需要再次设置策略相关的风险。所有这些都超出了应用的控制范围。您可能需要调整设备上的屏幕超时设置来控制屏幕何时会重新关闭。 您还可以选择添加 `command: keep_screen_on` 来启用[配置](https://my.home-assistant.io/redirect/config/)中伴侣应用部分内的[保持屏幕开启](https://companion.home-assistant.io/docs/integrations/android-webview#keep-screen-on)功能。屏幕将仅在 webview 活动当前处于活动状态时保持开启,否则它将重新关闭。`command` 具有另一个值的通知将此设置重置为默认禁用状态。 ```yaml automation: - alias: 屏幕开启 trigger: ... action: - action: notify.mobile_app_ data: message: "command_screen_on" data: command: "keep_screen_on" ``` ## 停止 TTS Android 如果您希望停止设备完成其文本转语音通知,可以通过发送命令 `message: command_stop_tts` 来停止它。 ```yaml automation: - alias: 停止 TTS trigger: ... action: - action: notify.mobile_app_ data: message: "command_stop_tts" ``` ## 持久连接 Android 在 Android 上,您可以通过发送 `message: command_persistent_connection` 并传递 `data -> persistent: (always, home_wifi, screen_on, never)` 来使用通知切换持久连接模式。 ```yaml automation: - alias: 打开持久连接 trigger: ... action: - action: notify.mobile_app_ data: message: "command_persistent_connection" data: persistent: always ``` ## 更新传感器 Android
应用将检查所有已启用的传感器是否有更新,如果自上次更新以来状态已更改,它将发送更新。查看[传感器](/companion/core/sensors.md)文档以获取有关传感器的更多详细信息。 ```yaml automation: - alias: 更新传感器 trigger: ... action: - action: notify.mobile_app_ data: message: "command_update_sensors" ``` ## 音量级别 Android 在 Android 上,您可以通过发送 `message: command_volume_level` 并附带必须是数字的适当 `command` 来控制设备的音量级别。如果 `command` 大于最大级别,则将使用最大级别,或者如果 `command` 小于 `0`,则我们将默认为 `0`,其他任何值都将导致通知发布到设备。还需要 `media_stream`,如下表所述。某些设备需要授予特殊权限,如果尚未授予权限,将在收到第一个命令时出现。这与上面的[勿扰模式](#do-not-disturb)权限相同。更改音量级别将直接影响勿扰模式和铃响模式,行为因设备而异。
| `media_stream` | 描述 | | ------- | ----------- | | `alarm_stream` | 设置闹钟流的音量级别。 | | `call_stream` | 设置语音通话流的音量级别。 | | `dtmf_stream` | 设置 DTMF 音调的音量级别。 | | `music_stream` | 设置音乐流的音量级别。 | | `notification_stream` | 设置通知流的音量级别。 | | `ring_stream` | 设置铃声流的音量级别。 | | `system_stream` | 设置系统流的音量级别。 | | 其他 | 通知将作为正常通知发布,命令将不会处理。 |
```yaml automation: - alias: 命令音量级别 trigger: ... action: - action: notify.mobile_app_ data: message: "command_volume_level" data: media_stream: "music_stream" command: 20 ``` ## 唤醒词检测 Android 测试版 当 Home Assistant 设置为设备上的默认数字助手应用时,您可以启用使用唤醒词打开助手。此命令允许您使用通知而不是打开应用来启用或禁用唤醒词检测。要使用它,发送 `message: command_wake_word_detection`,并将 `command` 参数设置为 `turn_on` 或 `turn_off` 来控制唤醒词检测状态。 :::warning 唤醒词检测可能会消耗大量电池,请使用此命令仅在需要时通过自动化启用它。 ::: 示例: ```yaml automation: - alias: 打开唤醒词检测 trigger: ... action: - action: notify.mobile_app_ data: message: "command_wake_word_detection" data: command: "turn_on" ``` ## Webview Android 如果您只想打开伴侣应用到任何页面甚至主页,您将需要发送 `message: command_webview`。如果您希望导航到特定[视图](https://www.home-assistant.io/lovelace/views/)或[仪表板](https://www.home-assistant.io/lovelace/dashboards/),您将需要使用 `command` 指定[`path`](https://www.home-assistant.io/lovelace/views/#path)(例如:`/lovelace/settings`)。您还可以通过使用以下格式的 `command` 打开任何实体的更多信息面板:`entityId:sun.sun`,只需将 `sun.sun` 替换为您希望打开的实体。如果未提供 `command`,用户将被引导到主页。第一次发送此命令时,您将被带到权限屏幕以授予应用访问"在其他应用上显示"策略的权限。此权限对于功能在后台工作是必要的,我们无法提示用户授予它。 示例: ```yaml automation: - alias: 打开 Android webview trigger: ... action: - action: notify.mobile_app_ data: message: "command_webview" data: command: "/lovelace/settings" ``` --- url: /companion/notifications/critical.md --- # 关键通知 关键通知的配置和行为在 iOS 和 Android 之间有所不同。 ## iOS 关键通知在 iOS 12 中引入,旨在发送您不希望错过的高优先级通知 - 例如安全系统、水泄漏传感器和烟雾/CO2 警报警报。 iOS 对此类通知给予特殊优先级。关键警报始终显示在锁屏顶部,位于所有其他通知之上,即使启用了勿扰模式或 iPhone 处于静音状态也会播放声音。因为我们永远不希望您错过关键通知,所以它们也被允许绕过应用[通知速率限制](/companion/notifications/details.md)。 iOS示例 ```yaml automations: - alias: "检测到火灾 iOS" trigger: - platform: state entity_id: sensor.smoke_alarm to: "smoke" action: - action: notify.mobile_app_ data: title: "快醒醒!" message: "房子着火了,猫被困在烘干机里!" data: push: sound: name: "default" critical: 1 volume: 1.0 ``` 如果您之前阅读过[声音文档](/companion/notifications/sounds.md),此语法应该大部分熟悉。注意示例扩展了 `sound` 属性以包含 `critical: 1` 标志,以及 `volume: 1.0` 将音量设置为 100%。 或者,您可以使用 [`interruption-level` 语法](/companion/notifications/basic.md#interruption-level)使通知变为关键通知。 ```yaml automations: - alias: "狗叫得很响" trigger: - platform: numeric_state entity_id: sensor.dog_bark_decibel_meter above: "90" action: - action: notify.mobile_app_ data: title: "史努比要吵醒邻居了" message: "狗在叫,很可能会吵醒邻居!" data: push: interruption-level: critical ``` 对于 **CarPlay** 用户,还值得一提的是,关键通知是唯一可以出现在汽车内置显示屏上的通知,如果您想在开车时知道发生了什么关键事件,这非常有用。 ## Android :::info 以下选项仅在未使用[本地推送通知](/companion/notifications/local.md)时生效。如果您使用的是精简版本,则无需担心此问题。 ::: 对于 Android,通知在大多数情况下会立即显示。但是,在某些情况下(例如手机静止或屏幕长时间关闭),默认通知不会响铃,直到屏幕打开。 要覆盖该行为,请设置 `priority: high` 和 `ttl: 0`。 默认情况下,它们也不会覆盖勿扰设置,如果您想覆盖此设置,则需要使用[通知渠道](/companion/notifications/basic.md#notification-channels)。 Android   Android 示例 ```yaml automations: - alias: "检测到火灾 Android" trigger: - platform: state entity_id: sensor.smoke_alarm to: "smoke" action: - action: notify.mobile_app_ data: title: "快醒醒!" message: "房子着火了,猫被困在烘干机里!" data: ttl: 0 priority: high ``` ### Android 闹钟流 您还可以强制通知从闹钟流播放,这样即使设备处于振动/静音铃声模式也会响铃。Android 7 及以下版本的用户仍可以使用下面的 `channel` 示例,因为我们只是用它来覆盖默认的通知声音行为。要使通知立即显示并无论铃声模式如何都发出声音,请按照以下示例之一操作。 使用此方法可以发送普通通知: ```yaml automations: - alias: "检测到火灾 Android 闹钟流" trigger: - platform: state entity_id: sensor.smoke_alarm to: "smoke" action: - action: notify.mobile_app_ data: title: "快醒醒!" message: "房子着火了,猫被困在烘干机里!" data: ttl: 0 priority: high channel: alarm_stream ``` ### Android 文字转语音闹钟流 或者您可以使用文字转语音来朗读通知: ```yaml automations: - alias: "检测到火灾 TTS 闹钟" trigger: - platform: state entity_id: sensor.smoke_alarm to: "smoke" action: - action: notify.mobile_app_ data: message: TTS data: ttl: 0 priority: high media_stream: alarm_stream tts_text: "房子着火了,猫被困在烘干机里!" ``` ### Android 文字转语音闹钟流最大音量 或者使用文字转语音,您还可以让通知以最大音量播放,然后恢复到原始音量级别: ```yaml automations: - alias: "检测到火灾 TTS 大声" trigger: - platform: state entity_id: sensor.smoke_alarm to: "smoke" action: - action: notify.mobile_app_ data: message: TTS data: ttl: 0 priority: high media_stream: alarm_stream_max tts_text: "房子着火了,猫被困在烘干机里!" ``` --- url: /companion/notifications/details.md --- # 隐私、速率限制和安全 ## 隐私 通知内容不会存储在远程服务器上。仅保留所需的推送注册数据以及每个设备每天发送的推送通知总数的简单计数器(用于速率限制目的)。 ## 架构 为了提供通知服务,应用使用 Google 的 Firebase 云消息传递服务。有关 Firebase 的更多信息,请[点击这里](https://firebase.google.com/docs/cloud-messaging)。 iOS
如果您不希望与 Google 的服务器交换数据,可以在使用应用时在[配置](https://my.home-assistant.io/redirect/config/)的伴侣应用设置的隐私部分选择退出 Firebase 服务。这样做将停止通知功能。 ## 速率限制 目前,每个设备每天最多允许发送 500 条推送通知。速率限制每天 UTC 午夜重置。这是为了确保服务的维护成本保持低廉。将来我们可能会添加支持升级以允许更多通知。 iOS 应用中的应用内通知设置屏幕显示您当天的当前速率限制,分为以下类别:尝试、已送达、错误、总计,以及到下次每日重置的确切时间。对于 Android,您可以在[配置](https://my.home-assistant.io/redirect/config/)的伴侣应用屏幕上找到这些详细信息。或者,您也可以通过为 [`logger`](https://www.home-assistant.io/integrations/logger/) 集成设置 `homeassistant.components.mobile_app.notify: info` 来查看它们。 如果发送通知时发生错误,则不计入您的速率限制。[关键警报](/companion/notifications/critical.md)和[通知命令](/companion/notifications/commands.md)也不计入您的速率限制。 ## 安全 您的 Home Assistant 实例、推送基础架构和设备操作系统之间的所有流量都使用 SSL 加密。通知内容在 Firebase 云消息传递服务上未加密,因此可能被 Google 处理。 --- url: /companion/notifications/dynamic-content.md --- # 动态附件 iOS 专属
地图和摄像头流等动态内容可以作为通知的一部分显示,而无需打开应用。 ## 地图 将显示一个居中的地图,在给定坐标处有一个红色图钉。 ```yaml action: notify.mobile_app_ data: message: 家里发生了一些事情! data: action_data: latitude: "40.785091" longitude: "-73.968285" ``` ### 2021.5 之前的 iOS 版本 在 iOS 版本 2021.5 之前,您需要像这样包含一个 `category`: ```yaml action: notify.mobile_app_ data: message: 家里发生了一些事情! data: action_data: latitude: "40.785091" longitude: "-73.968285" # 兼容 2021.5 之前的 iOS 版本 push: category: map ``` 请注意,要发送地图,您必须发送一个名为 `map`、`map1`、`map2`、`map3` 或 `map4` 的推送 `category`,否则您将无法收到地图。 ### 缩放级别 要更改地图的默认缩放级别,可以使用 `action_data` 下的以下属性。如果未设置,将使用默认值 `0.1` 度。 | 名称 | 类型 | 描述 | | ------------ | ------------- | ------------- |\ | `latitude_delta:` | string | 要显示的南北距离(以度为单位)。 | | `longitude_delta:` | string | 要显示的东西距离(以度为单位)。 | ### 显示第二个图钉 您可以使用 `action_data` 下的以下属性显示第二个图钉。如果使用,第一个图钉将是红色,第二个图钉将是绿色。 | 名称 | 类型 | 描述 | | ------------ | ------------- | ------------- |\ | `second_latitude:` | string | 第二个图钉的纬度。 | | `second_longitude:` | string | 第二个图钉的经度。 | | `shows_line_between_points:` | boolean | 显示连接第一个和第二个图钉的线。 | ### 额外配置 您还可以在 `action_data` 下传递以下选项属性,以各种方式修改地图。此处列出的所有选项都接受布尔值(`true` / `false`)。 | 名称 | 类型 | 描述 | | ------------ | ------------- | ------------- | | `shows_compass:` | boolean | 在地图上显示指南针控件。 | | `shows_points_of_interest:` | boolean | 在地图上显示兴趣点(POI)信息。 | | `shows_scale:` | boolean | 在地图上显示比例尺信息。 | | `shows_traffic:` | boolean | 在地图上显示交通信息。 | | `shows_user_location:` | boolean | 尝试在地图上显示用户的位置。 | ![地图动态内容示例。](/companion-assets/ios/map.png) ## 摄像头流 通知的预览缩略图将显示摄像头的静态图像。展开时,如果摄像头支持,通知内容将显示实时 MJPEG 流。 您可以使用附件参数 `content-type` 和 `hide-thumbnail` 与摄像头一起控制缩略图。 ```yaml action: notify.mobile_app_ data: message: 客厅检测到移动 data: entity_id: camera.living_room_camera ``` ### 2021.5 之前的 iOS 版本 在 iOS 版本 2021.5 之前,您需要像这样包含一个 `category`: ```yaml action: notify.mobile_app_ data: message: 客厅检测到移动 data: entity_id: camera.living_room_camera # 兼容 2021.5 之前的 iOS 版本 push: category: camera ``` 请注意,要发送摄像头图像,您必须发送一个名为 `camera`、`camera1`、`camera2`、`camera3` 或 `camera4` 的推送类别,否则您将无法收到摄像头图像。 ## 与 2021.5 之前 iOS 版本的可操作通知结合使用 在 2021.5 之前的版本中,`category` 键用于告诉设备使用哪种内容扩展。您可以在自己的自定义[操作](/companion/notifications/actionable.md)中使用相同的类别标识符,向内容扩展添加操作。 例如,此配置向摄像头内容消息添加操作。 ```yaml ios: push: categories: - name: 带操作的摄像头 identifier: 'camera' actions: - identifier: 'OPEN_COVER' title: '打开遮盖' activationMode: 'background' authenticationRequired: true destructive: no - identifier: 'CLOSE_COVER' title: '关闭遮盖' activationMode: 'background' authenticationRequired: true destructive: true ``` ## 故障排除 如果您在接收这些特殊通知时遇到问题,请先尝试重启手机。扩展有时直到重启才能正确注册。 --- url: /companion/notifications/local.md --- # 本地推送 本地推送使用 [WebSocket API](https://developers.home-assistant.io/docs/api/websocket) 将通知传递到您的设备,而不是使用 Apple 的推送通知服务或 Google 的 Firebase 云消息传递。 | 平台 | 版本 | | -------- | ------- | | iOS | 2021.7 | | macOS | 2021.7 | | Android | 2022.2 | :::info 本地推送需要 HA core-2021.6 或更高版本,并结合上述支持的平台。 ::: ## 要求 iOS 有一些限制: 1. 本地推送仅在通过内部 URL 连接时发生,并且需要配置 SSIDs 以将其视为内部。这是操作系统的限制,因为此功能是为低或最小连接情况设计的。 2. 虽然很小,但当启用本地推送时,电池使用量会增加少量,因为它会保持与您的 HA 服务器的持续连接。您可以在服务器的连接设置中禁用它。 macOS 只要应用正在运行,就会始终维持本地推送连接,并且不会对电池产生额外影响。 Android 将按照您的配置维持本地推送连接。为了保持此连接,应用需要创建一个持久通知,您将能够在设备上最小化 `Persistent Connection` 的通知渠道以隐藏它。根据您的设置,这可能会对电池寿命产生不利影响。如果您使用的是精简版本,您需要将此设置保持为"始终",并考虑授予应用后台访问权限以使连接更可靠。 ## 速率限制 通过本地推送传递的通知不计入[速率限制](/companion/notifications/details.md)。 ## 配置 iOS 可以通过编辑服务器的内部连接设置来禁用本地推送。转到[设置](https://my.home-assistant.io/redirect/config/),然后伴侣应用,点击服务器行,然后点击内部 URL。 macOS 没有禁用本地推送的选项,请参阅上面的要求了解更多信息。 Android 可以在[设置](https://my.home-assistant.io/redirect/config/)中配置本地推送设置,然后伴侣应用,点击服务器行,然后选择持久连接。 ## 查看状态 iOS 和 macOS: 您可以在[设置](https://my.home-assistant.io/redirect/config/)的伴侣应用服务器部分查看本地推送的状态。这将显示以下几种状态之一: * 已禁用,当连接设置关闭或当前不在内部网络时。 * 不支持,当 iOS 版本不支持本地推送时。 * 不可用,当核心版本不支持本地推送时。 * 正在建立,当它最初连接到服务器时。 * 可用,当它已连接并准备好接收推送时。后面的数字表示自连接开始以来收到的消息数,这对于调试很有用。 --- url: /companion/notifications/received.md --- # 通知接收 Android 当设备收到通知时,您可以接收一个事件。要接收此事件,您需要在通知操作中将 `confirmation: true` 设置为参数。所有通知数据将出现在事件类型 `mobile_app_notification_received` 的事件数据中。如果您未设置此参数,则收到通知时设备不会发送任何事件。 示例: ```yaml automation: - alias: 通知接收确认 trigger: ... action: - action: notify.mobile_app_ data: message: "此通知已被接收" data: confirmation: true ``` 示例事件数据: ```json { "event_type": "mobile_app_notification_received", "data": { "message": "test", "device_id": "DEVICE_ID" }, "origin": "REMOTE", "time_fired": "2020-10-06T05:36:12.864583+00:00", "context": { "id": "ID", "parent_id": null, "user_id": "USER_ID" } } ``` --- url: /companion/notifications/sounds.md --- # 声音 为通知添加自定义声音可以让您轻松识别通知,甚至无需查看设备。如何设置自定义声音取决于操作系统。 * Android 在 Android 上,通知声音与[通知渠道/类别](/companion/notifications/basic.md#notification-channels)相关联。在您的设备上,编辑渠道设置以将通知声音更改为其他系统声音或选择您自己的声音。 * iOS iOS 版 Home Assistant 预装了一些通知声音,但您也可以上传自己的声音。 :::info 下面的信息描述了在 iOS 上使用自定义通知声音。对于 Android,请转到[设置](https://my.home-assistant.io/redirect/config/) > 伴侣应用 > 通知渠道以更改声音,并参考您的设备设置。 ::: 以下是使用预装声音之一的通知示例。 ```yaml automation: - alias: "通知移动应用声音" trigger: ... action: - action: notify.mobile_app_ data: message: "您的室友到了" data: push: sound: "US-EN-Morgan-Freeman-Roommate-Is-Arriving.wav" ``` > 您必须在负载中使用完整的文件名(包括扩展名)。 ## 自定义推送通知声音 iOS 应用允许您在推送通知中使用自己的自定义声音。声音必须格式化为 32位浮点 48000Hz wav 文件。确保您知道声音的文件名,因为您需要在通知负载的 `sound` 字段中引用它。要添加声音,请按照以下两种方法之一操作: > * 您可能需要在播放通知声音之前重启整个设备。 > * 上传与现有文件同名的文件将覆盖原始文件。 ### 通过 iTunes 1. 将设备连接到运行最新版本 iTunes 的 PC 或 Mac。 2. 在 iTunes 中转到设备。 3. 在左侧菜单中选择"文件共享"。 4. 选择 Home Assistant。 5. 拖放正确格式的声音(32位浮点 48000Hz wav 文件)。 6. 点击右下角的同步。 7. 同步完成后,将设备与计算机断开连接。 8. 在您的 iOS 设备上,打开 Home Assistant 应用。 9. 转到[配置](https://my.home-assistant.io/redirect/config/) -> 伴侣应用 -> 通知 -> 声音。 10. 点击"从 iTunes 文件共享导入声音"按钮。 假设您正确格式化了声音,它们现在可以在推送通知中使用了。 ### 通过云存储: 此方法需要您有一个云存储应用(如 [Dropbox](https://www.dropbox.com)、[Google Drive](https://www.google.com/drive/)、[iCloud](https://www.icloud.com/)、[OneDrive](https://www.microsoft.com/microsoft-365/onedrive/online-cloud-storage) 等)。 1. 如果您还没有云存储的 iOS 应用,请在 App Store 中找到适当的应用,安装并登录。 2. 将您想要的通知声音上传到云存储中的方便位置。 3. 在 Home Assistant 伴侣应用中,从侧边栏打开[配置](https://my.home-assistant.io/redirect/config/)菜单,转到伴侣应用部分。 4. 在设置下,点击通知,然后点击声音。 5. 点击"导入自定义声音"。 6. 导航到包含您想要添加的声音的文件夹。注意,您可以使用左上角的位置按钮在云提供商之间切换。 7. 点击选择,然后点击您想要添加的文件。选择完所有想要的文件后,点击完成。 8. 重启您的设备。 ## 从 iOS 导入声音 除了三全音(默认短信音,可以通过 `sound: default` 访问)之外,iOS 系统声音不会导入到 Home Assistant 伴侣应用中。但可以通过以下步骤导入它们: 1. 在 Home Assistant 伴侣应用中,从 Home Assistant [配置菜单](https://my.home-assistant.io/redirect/config/)打开伴侣应用页面。 2. 在设置下,点击通知,然后点击声音。 3. 点击"系统"标签,然后点击"导入系统声音"。 4. 几秒钟后,您应该会收到文件已成功导入的通知。 5. 重启您的设备。 6. 现在 iOS 声音可以使用了。
点击这里查看从 iOS 导入的声音完整列表。 此列表代表 iOS 12,实际导入的声音列表可能因您的设备配置和 iOS 版本而异。 ```text 3rdParty_DirectionDown_Haptic.caf 3rdParty_DirectionUp_Haptic.caf 3rdParty_Failure_Haptic.caf 3rdParty_Retry_Haptic.caf 3rdParty_Start_Haptic.caf 3rdParty_Stop_Haptic.caf 3rdParty_Success_Haptic.caf access_scan_complete.caf AccessSanComplete_Haptic acknowledgment_received.caf acknowledgment_sent.caf alarm.caf Alarm_Haptic.caf Alarm_Nightstand_Haptic.caf Alert_3rdParty_Haptic.caf Alert_3rdParty_Salient_Haptic.caf Alert_ActivityFriendsGoalAttained_Haptic.caf Alert_ActivityGoalAttained_Haptic.caf Alert_ActivityGoalAttained_Salient_Haptic.caf Alert_ActivityGoalBehind_Haptic.caf Alert_ActivityGoalBehind_Salient_Haptic.caf Alert_ActivityGoalClose_Haptic.caf Alert_BatteryLow_10p_Haptic.caf Alert_BatteryLow_5p_Haptic.caf Alert_BatteryLow_5p_Salient_Haptic.caf Alert_Calendar_Haptic.caf Alert_Calendar_Salient_Haptic.caf Alert_Health_Haptic.caf Alert_Mail_Haptic.caf Alert_Mail_Salient_Haptic.caf Alert_MapsDirectionsInApp_Haptic.caf Alert_Messages_1_Haptic.caf Alert_Messages_1_Salient_Haptic.caf Alert_Messages_2_Haptic.caf Alert_Messages_3_Haptic.caf Alert_PassbookBalance_Haptic.caf Alert_PassbookGeofence_Haptic.caf Alert_PassbookGeofence_Salient_Haptic.caf Alert_PhotostreamActivity_Haptic.caf Alert_ReminderDue_Haptic.caf Alert_ReminderDue_Salient_Haptic.caf Alert_SpartanConnected_LowLatency_Haptic.caf Alert_SpartanConnecting_Haptic.caf Alert_SpartanConnecting_LowLatency_Haptic.caf Alert_SpartanDisconnected_LowLatency_Haptic.caf Alert_Voicemail_Haptic.caf Alert_Voicemail_Salient_Haptic.caf Alert_WalkieTalkie_Haptic.caf Anticipate.caf AutoUnlock_Haptic.caf BatteryMagsafe_Haptic.caf Beat_Haptic.caf begin_record.caf Bloom.caf BuddyMigrationStart_Haptic.caf BuddyPairingFailure_Haptic.caf BuddyPairingRemoteConnection_Haptic.caf BuddyPairingRemoteTap_Haptic.caf BuddyPairingSuccess_Haptic.caf busy_tone_ansi.caf busy_tone_cept.caf call_waiting_tone_ansi.caf call_waiting_tone_cept.caf Calypso.caf camera_shutter_burst.caf camera_shutter_burst_begin.caf camera_shutter_burst_end.caf camera_timer_countdown.caf camera_timer_final_second.caf CameraCountdownImminent_Haptic.caf CameraCountdownTick_Haptic.caf CameraShutter_Haptic.caf Choo_Choo.caf connect_power.caf ct-busy.caf ct-call-waiting.caf ct-congestion.caf ct-error.caf ct-keytone2.caf ct-path-ack.caf Descent.caf Detent_Haptic.caf DoNotDisturb_Haptic.caf dtmf-0.caf dtmf-1.caf dtmf-2.caf dtmf-3.caf dtmf-4.caf dtmf-5.caf dtmf-6.caf dtmf-7.caf dtmf-8.caf dtmf-9.caf dtmf-pound.caf dtmf-star.caf end_call_tone_cept.caf end_record.caf engage_power.caf engage_power_short.caf ET_BeginNotification_Haptic.caf ET_BeginNotification_Salient_Haptic.caf ET_RemoteTap_Receive_Haptic.caf ET_RemoteTap_Send_Haptic.caf Fanfare.caf focus_change_app_icon.caf focus_change_keyboard.caf focus_change_large.caf focus_change_small.caf go_to_sleep_alert.caf GoToSleep_Haptic.caf HealthNotificaiton.caf HourlyChime_Haptic.caf HummingbirdCompletion_Haptic.caf HummingbirdNotification_Haptic.caf jbl_ambiguous.caf jbl_begin.caf jbl_cancel.caf jbl_confirm.caf jbl_no_match.caf key_press_click.caf key_press_delete.caf key_press_modifier.caf keyboard_press_clear.caf keyboard_press_delete.caf keyboard_press_normal.caf Ladder.caf lock.caf long_low_short_high.caf low_power.caf mail-sent.caf MessagesIncoming_Haptic.caf MessagesOutgoing_Haptic.caf middle_9_short_double_low.caf Minuet.caf multiway_invitation.caf MultiwayInvitation.caf MultiwayJoin.caf MultiwayLeave.caf navigation_pop.caf navigation_push.caf NavigationGenericManeuver_Haptic.caf NavigationGenericManeuver_Salient_Haptic.caf NavigationLeftTurn_Haptic.caf NavigationLeftTurn_Salient_Haptic.caf NavigationRightTurn_Haptic.caf NavigationRightTurn_Salient_Haptic.caf new-mail.caf News_Flash.caf nfc_scan_complete.caf Noir.caf Notification_Haptic.caf Notification_Salient_Haptic.caf OnOffPasscodeFailure_Haptic.caf OnOffPasscodeUnlock_Haptic.caf OnOffPasscodeUnlockCampanion_Haptic.caf OrbExit_Haptic.caf OrbLayers_Haptic.caf payment_failure.caf payment_success.caf PhoneAnswer_Haptic.caf PhoneHangUp_Haptic.caf PhoneHold_Haptic.caf photoShutter.caf PhotosZoomDetent_Haptic.caf Preview_AudioAndHaptic.caf QB_Dictation_Haptic.caf QB_Dictation_Off_Haptic.caf ReceivedMessage.caf RemoteCameraShutterBurstBegin_Haptic.caf RemoteCameraShutterBurstEnd_Haptic.caf ringback_tone_ansi.caf ringback_tone_aus.caf ringback_tone_cept.caf ringback_tone_hk.caf ringback_tone_uk.caf RingerChanged.caf Ringtone_2_Ducked_Haptic-sashimi.caf Ringtone_2_Haptic-sashimi.caf Ringtone_UK_Haptic.caf Ringtone_US_Haptic.caf RingtoneDucked_UK_Haptic.caf RingtoneDucked_US_Haptic.caf SalientNotification_Haptic.caf SedentaryTimer_Haptic.caf SedentaryTimer_Salient_Haptic.caf SentMessage.caf shake.caf Sherwood_Forest.caf short_double_high.caf short_double_low.caf short_low_high.caf SIMToolkitCallDropped.caf SIMToolkitGeneralBeep.caf SIMToolkitNegativeACK.caf SIMToolkitPositiveACK.caf SIMToolkitSMS.caf SiriAutoSend_Haptic.caf SiriStart_Haptic.caf SiriStopFailure_Haptic.caf SiriStopSuccess_Haptic.caf sms-received1.caf sms-received1.caf sms-received2.caf sms-received3.caf sms-received4.caf sms-received5.caf sms-received6.caf SOSEmergencyContactTextPrompt_Haptic.caf SOSFallDetection_Haptic-Newton.caf Spell.caf Stockholm_Haptic.caf StockholmActive_Haptic.caf StockholmActiveSingleCycle_Haptic.caf StockholmFailure_Haptic.caf StopwatchLap_Haptic.caf StopwatchReset_Haptic.caf StopwatchStart_Haptic.caf StopwatchStop_Haptic.caf Suspense.caf Swish.caf SwTest1_Haptic.caf SystemStartup_Haptic.caf Telegraph.caf Timer_Haptic.caf TimerCancel_Haptic.caf TimerPause_Haptic.caf TimerStart_Haptic.caf TimerWheelHoursDetent_Haptic.caf TimerWheelMinutesDetent_Haptic.caf Tink.caf Tiptoes.caf Tock.caf tweet_sent.caf Typewriters.caf UISwipe_Haptic.caf UISwitch_Off_Haptic.caf UISwitch_On_Haptic.caf Update.caf ussd.caf vc~ended.caf vc~invitation-accepted.caf vc~ringing.caf vc~ringing_watch.caf VoiceOver_Click_Haptic.caf WalkieTalkieActiveEnd_Haptic.caf WalkieTalkieActiveStart_Haptic.caf WalkieTalkieReceiveEnd_Haptic.caf WalkieTalkieReceiveStart_Haptic.caf warsaw.caf Warsaw_Haptic.caf wheels_of_time.caf WorkoutComplete_Haptic.caf WorkoutCompleteAutoDetect.caf WorkoutCountdown_Haptic.caf WorkoutPaceAbove.caf WorkoutPaceBelow.caf WorkoutPaused_Haptic.caf WorkoutPressStart_Haptic.caf WorkoutResumed_Haptic.caf WorkoutResumedAutoDetect.caf WorkoutSaved_Haptic.caf WorkoutSelect_Haptic.caf WorkoutStartAutoDetect.caf ```
## 预装通知声音
点击这里查看应用附带的声音完整列表。 ```text US-EN-Alexa-Back-Door-Opened.wav US-EN-Alexa-Back-Door-Unlocked.wav US-EN-Alexa-Basement-Door-Opened.wav US-EN-Alexa-Basement-Door-Unlocked.wav US-EN-Alexa-Boyfriend-Is-Arriving.wav US-EN-Alexa-Daughter-Is-Arriving.wav US-EN-Alexa-Front-Door-Opened.wav US-EN-Alexa-Front-Door-Unlocked.wav US-EN-Alexa-Garage-Door-Opened.wav US-EN-Alexa-Girlfriend-Is-Arriving.wav US-EN-Alexa-Good-Morning.wav US-EN-Alexa-Good-Night.wav US-EN-Alexa-Husband-Is-Arriving.wav US-EN-Alexa-Mail-Has-Arrived.wav US-EN-Alexa-Motion-At-Back-Door.wav US-EN-Alexa-Motion-At-Front-Door.wav US-EN-Alexa-Motion-Detected-Generic.wav US-EN-Alexa-Motion-In-Back-Yard.wav US-EN-Alexa-Motion-In-Basement.wav US-EN-Alexa-Motion-In-Front-Yard.wav US-EN-Alexa-Motion-In-Garage.wav US-EN-Alexa-Patio-Door-Opened.wav US-EN-Alexa-Patio-Door-Unlocked.wav US-EN-Alexa-Smoke-Detected-Generic.wav US-EN-Alexa-Smoke-Detected-In-Basement.wav US-EN-Alexa-Smoke-Detected-In-Garage.wav US-EN-Alexa-Smoke-Detected-In-Kitchen.wav US-EN-Alexa-Son-Is-Arriving.wav US-EN-Alexa-Water-Detected-Generic.wav US-EN-Alexa-Water-Detected-In-Basement.wav US-EN-Alexa-Water-Detected-In-Garage.wav US-EN-Alexa-Water-Detected-In-Kitchen.wav US-EN-Alexa-Welcome-Home.wav US-EN-Alexa-Wife-Is-Arriving.wav US-EN-Daisy-Back-Door-Motion.wav US-EN-Daisy-Back-Door-Open.wav US-EN-Daisy-Front-Door-Motion.wav US-EN-Daisy-Front-Door-Open.wav US-EN-Daisy-Front-Window-Open.wav US-EN-Daisy-Garage-Door-Open.wav US-EN-Daisy-Guest-Bath-Leak.wav US-EN-Daisy-Kitchen-Sink-Leak.wav US-EN-Daisy-Kitchen-Window-Open.wav US-EN-Daisy-Laundry-Room-Leak.wav US-EN-Daisy-Master-Bath-Leak.wav US-EN-Daisy-Master-Bedroom-Window-Open.wav US-EN-Daisy-Office-Window-Open.wav US-EN-Daisy-Refrigerator-Leak.wav US-EN-Daisy-Water-Heater-Leak.wav US-EN-Morgan-Freeman-Back-Door-Closed.wav US-EN-Morgan-Freeman-Back-Door-Locked.wav US-EN-Morgan-Freeman-Back-Door-Opened.wav US-EN-Morgan-Freeman-Back-Door-Unlocked.wav US-EN-Morgan-Freeman-Basement-Door-Closed.wav US-EN-Morgan-Freeman-Basement-Door-Locked.wav US-EN-Morgan-Freeman-Basement-Door-Opened.wav US-EN-Morgan-Freeman-Basement-Door-Unlocked.wav US-EN-Morgan-Freeman-Boss-Is-Arriving.wav US-EN-Morgan-Freeman-Boyfriend-Is-Arriving.wav US-EN-Morgan-Freeman-Cleaning-Supplies-Closet-Opened.wav US-EN-Morgan-Freeman-Coworker-Is-Arriving.wav US-EN-Morgan-Freeman-Daughter-Is-Arriving.wav US-EN-Morgan-Freeman-Friend-Is-Arriving.wav US-EN-Morgan-Freeman-Front-Door-Closed.wav US-EN-Morgan-Freeman-Front-Door-Locked.wav US-EN-Morgan-Freeman-Front-Door-Opened.wav US-EN-Morgan-Freeman-Front-Door-Unlocked.wav US-EN-Morgan-Freeman-Garage-Door-Closed.wav US-EN-Morgan-Freeman-Garage-Door-Opened.wav US-EN-Morgan-Freeman-Girlfriend-Is-Arriving.wav US-EN-Morgan-Freeman-Good-Morning.wav US-EN-Morgan-Freeman-Good-Night.wav US-EN-Morgan-Freeman-Liquor-Cabinet-Opened.wav US-EN-Morgan-Freeman-Motion-Detected.wav US-EN-Morgan-Freeman-Motion-In-Basement.wav US-EN-Morgan-Freeman-Motion-In-Bedroom.wav US-EN-Morgan-Freeman-Motion-In-Game-Room.wav US-EN-Morgan-Freeman-Motion-In-Garage.wav US-EN-Morgan-Freeman-Motion-In-Kitchen.wav US-EN-Morgan-Freeman-Motion-In-Living-Room.wav US-EN-Morgan-Freeman-Motion-In-Theater.wav US-EN-Morgan-Freeman-Motion-In-Wine-Cellar.wav US-EN-Morgan-Freeman-Patio-Door-Closed.wav US-EN-Morgan-Freeman-Patio-Door-Locked.wav US-EN-Morgan-Freeman-Patio-Door-Opened.wav US-EN-Morgan-Freeman-Patio-Door-Unlocked.wav US-EN-Morgan-Freeman-Roommate-Is-Arriving.wav US-EN-Morgan-Freeman-Searching-For-Car-Keys.wav US-EN-Morgan-Freeman-Setting-The-Mood.wav US-EN-Morgan-Freeman-Smartthings-Detected-A-Flood.wav US-EN-Morgan-Freeman-Smartthings-Detected-Carbon-Monoxide.wav US-EN-Morgan-Freeman-Smartthings-Detected-Smoke.wav US-EN-Morgan-Freeman-Smoke-Detected-In-Basement.wav US-EN-Morgan-Freeman-Smoke-Detected-In-Garage.wav US-EN-Morgan-Freeman-Smoke-Detected-In-Kitchen.wav US-EN-Morgan-Freeman-Someone-Is-Arriving.wav US-EN-Morgan-Freeman-Son-Is-Arriving.wav US-EN-Morgan-Freeman-Starting-Movie-Mode.wav US-EN-Morgan-Freeman-Starting-Party-Mode.wav US-EN-Morgan-Freeman-Starting-Romance-Mode.wav US-EN-Morgan-Freeman-Turning-Off-All-The-Lights.wav US-EN-Morgan-Freeman-Turning-Off-The-Air-Conditioner.wav US-EN-Morgan-Freeman-Turning-Off-The-Bar-Lights.wav US-EN-Morgan-Freeman-Turning-Off-The-Chandelier.wav US-EN-Morgan-Freeman-Turning-Off-The-Family-Room-Lights.wav US-EN-Morgan-Freeman-Turning-Off-The-Hallway-Lights.wav US-EN-Morgan-Freeman-Turning-Off-The-Kitchen-Light.wav US-EN-Morgan-Freeman-Turning-Off-The-Light.wav US-EN-Morgan-Freeman-Turning-Off-The-Lights.wav US-EN-Morgan-Freeman-Turning-Off-The-Mood-Lights.wav US-EN-Morgan-Freeman-Turning-Off-The-TV.wav US-EN-Morgan-Freeman-Turning-On-The-Air-Conditioner.wav US-EN-Morgan-Freeman-Turning-On-The-Bar-Lights.wav US-EN-Morgan-Freeman-Turning-On-The-Chandelier.wav US-EN-Morgan-Freeman-Turning-On-The-Family-Room-Lights.wav US-EN-Morgan-Freeman-Turning-On-The-Hallway-Lights.wav US-EN-Morgan-Freeman-Turning-On-The-Kitchen-Light.wav US-EN-Morgan-Freeman-Turning-On-The-Light.wav US-EN-Morgan-Freeman-Turning-On-The-Lights.wav US-EN-Morgan-Freeman-Turning-On-The-Mood-Lights.wav US-EN-Morgan-Freeman-Turning-On-The-TV.wav US-EN-Morgan-Freeman-Vacate-The-Premises.wav US-EN-Morgan-Freeman-Water-Detected-In-Basement.wav US-EN-Morgan-Freeman-Water-Detected-In-Garage.wav US-EN-Morgan-Freeman-Water-Detected-In-Kitchen.wav US-EN-Morgan-Freeman-Welcome-Home.wav US-EN-Morgan-Freeman-Wife-Is-Arriving.wav ```
--- url: /companion/troubleshooting/beta-cleaning.md --- # Beta 测试:构建之间的清理 iOS 参与过 2.0 版本 Beta 测试的用户可能经历了许多构建,并获得了一些现在已经冗余的传感器。Android 安装了 [Play Store Beta 构建](https://play.google.com/apps/testing/io.homeassistant.companion.android) 的 Android 用户也可能发现他们需要重新开始一个新的集成来清理问题。以下步骤将允许您从 Home Assistant 实例中彻底删除以前构建的所有痕迹,并重新开始运行。 :::tip 在大多数情况下,可以通过从 Home Assistant 中删除相关的"Mobile App"集成来完全删除 Home Assistant 和伴侣应用之间的连接。这可以在"配置"中找到,然后是"集成"。完成此操作后,您可以从设备上卸载伴侣应用,并(如果需要)重新安装。如果您有 Apple Watch,值得在重新安装之前检查 Home Assistant 伴侣应用是否已从您的 Watch 上卸载。 ::: 如果上述方法不起作用,您可以按照以下步骤从 Home Assistant 中完全删除伴侣应用的所有痕迹。这些步骤假设您在 Beta 期间只使用了一台设备,或者希望从所有设备中删除以前 Beta 构建的所有痕迹。 0. **备份您的 Home Assistant。不要跳过此步骤!** 1. 转到 Home Assistant 配置页面上的[集成](https://my.home-assistant.io/redirect/integrations/)。 2. 选择 Mobile App: `<设备 ID>`(其中设备 ID 是您设备的名称)。 3. 通过点击右上角的垃圾桶删除集成。如果在上一个页面有多个 Mobile App 条目,请对每个条目重复此步骤。 4. 返回 Home Assistant 配置页面并打开[实体注册表](https://my.home-assistant.io/redirect/entities/)。 5. 删除右侧列出 `mobile_app` 的所有条目,此步骤可能不需要,因为它们可能已经在上面的步骤 3 之后被删除。 6. 使用您喜欢的方法编辑 Home Assistant 实例上的文件,打开 `.storage` 文件夹并删除 `mobile_app` 文件。 7. 打开 `known_devices.yaml` 并删除(可能是最后一个)由 32 个字符的唯一 ID 组成的条目,代表您设备的 `device_tracker`。此步骤可能不需要,因为该实体可能已经在上面的步骤 3 之后被删除。 8. 重启 Home Assistant。 9. 从您的设备中删除 Home Assistant 应用。如果您有 Apple Watch,请在 Watch 应用中检查 Home Assistant 伴侣应用是否也已从中卸载。 10. 从 TestFlight(Beta 测试期间)、AppStore、Google Play Store 或 Firebase 重新安装 Home Assistant 应用。 11. 打开应用并按照设置过程操作。 --- url: /companion/troubleshooting/errors.md --- # 错误 以下是您可能遇到的所有错误代码列表,以及有关发生原因和处理方法的详细文档。 ## 设置和连接 ### "Invalid Client ID or Redirect URI" 和 "OS Error while looking up redirect\_uri" 检查您的 `home-assistant.log` 文件中是否有关于 `indieauth` 的错误。如果还提到 OS Error,您很可能有损坏的 IPv6 实现。您可以通过在运行 Home Assistant 的机器上运行 `curl -v6 https://home-assistant.io/iOS/beta-auth` 来确认这一点。如果您收到关于无法连接到服务器的错误,您的 IPv6 栈已损坏,您应该禁用它。 ### "Invalid Client ID or Redirect URI" 和 "Timeout while while looking up redirect\_uri" 检查您的 `home-assistant.log` 文件中是否有关于 `indieauth` 的错误。如果还提到 Timeout,您的 DNS 可能存在异常行为的问题。您可以通过在运行 Home Assistant 的机器上运行 `dig home-assistant.io` 和 `nslookup home-assistant.io` 来确认这一点。如果您看到任何错误,可能存在 DNS 问题。 解决此问题的方法因您的设置而异 - 但值得尝试使用 Google DNS 服务器 `8.8.8.8` 和 `1.1.1.1`。如果您运行的是 hassOS 设置,可以使用 `ha dns options --servers dns://8.8.8.8 --servers dns://1.1.1.1` 来完成。 ### SSL error while looking up redirect\_uri 此错误意味着您的 Home Assistant 无法协商与 的加密连接。此问题曾在运行在 MacOS 上的安装中出现,其中安装程序关于证书的通知被跳过和忽略。来自 Python 3.7.5 自述文件: > 证书验证和 OpenSSL > 此软件包包含其自己的 OpenSSL 1.1.1 私有副本。由 Keychain Access 应用程序和 security 命令行工具管理的系统和用户钥匙串中的信任证书不会被 Python `ssl` 模块用作默认值。`/Applications/Python 3.7` 中包含一个示例命令脚本,用于安装来自第三方 [certifi](https://pypi.org/project/certifi/) 包的精选默认根证书包。双击 `Install Certificates` 运行它。 > 捆绑的 pip 有其自己的默认证书存储用于验证下载连接。 ### "Setup failed for dependencies: `zeroconf`" 此错误通常由以下两个问题之一引起: * 您正在运行两个具有相同名称的 Home Assistant 实例。解决方案是重命名其中一个。 * 您的 `configuration.yaml` 文件中缺少 `default_config:`。可以只将 `zeroconf:` 添加到 `configuration.yaml`,但添加 `default_config:` 将连同 `zeroconf:` 一起添加[几个有用的集成](https://www.home-assistant.io/integrations/default_config/)。 ### Response status code was unacceptable: 400 当设置期间发送的数据不符合 Home Assistant 的期望时会发生这种情况。这最常发生在两种情况下: * 您运行的 Home Assistant 版本低于最低要求(目前为 0.104.0) * 您的设备名称中有意外字符。在设置移动应用集成时,我们尝试删除非标准字符和表情符号(从 Home Assistant 0.112 开始)。但是,如果您收到此错误,值得简化您的设备名称以删除此类字符。 ### URLSessionTask failed with error 此错误通常由以下两个问题之一引起: * 您拒绝了应用的本地网络访问。要在 iOS 上解决此问题,打开系统设置中的 Home Assistant 条目并验证本地网络是否已启用。 * 您在实例中配置了错误的外部 URL。例如,当将外部端口 443 转发到您的实例端口(通常为 8123)时,您不必在 URL 中附加端口。 * 您[登录了 Home Assistant Cloud](https://support.nabucasa.com/hc/articles/25649130769949) 但没有订阅,并尝试通过反向代理访问您的实例。只需从您的 Home Assistant Cloud 帐户注销即可。 --- url: /companion/troubleshooting/integrations.md --- # 集成 集成故障排除 --- url: /companion/troubleshooting/more-help.md --- # 获取更多帮助 如果在阅读此处的文档后仍有问题,请尝试以下资源。 **一般帮助和配置建议** * 访问 [Companion Apps 频道](https://discord.com/channels/330944238910963714/1284965926336335993) * 在 [iOS 论坛](https://community.home-assistant.io/c/mobile-apps/ios) 或 [Android 论坛](https://community.home-assistant.io/c/mobile-apps/android-companion) 发帖。 **错误报告** * 请在 [iOS GitHub 仓库](https://github.com/home-assistant/iOS) 或 [Android GitHub 仓库](https://github.com/home-assistant/android) 提交问题。 **功能请求** * 要请求新功能,请在 Home Assistant GitHub 组织中开启讨论。使用相关平台的讨论页面: * [Android 讨论页面](https://github.com/orgs/home-assistant/discussions/new?category=android) * [iOS 和 macOS 讨论页面](https://github.com/orgs/home-assistant/discussions/new?category=ios-macos)。 **关于本文档的问题、更正或修改** * 使用您想修改的页面上的编辑按钮(文档使用 [Markdown](https://daringfireball.net/projects/markdown/syntax) 编写),您需要一个 [GitHub](https://www.github.com) 帐户来提交更改;或 * 在文档的 [GitHub 仓库](https://github.com/home-assistant/companion.home-assistant) 提交问题。 --- url: /companion/troubleshooting/networking.md --- # 伴侣应用网络 让您的家庭在您去的任何地方都可以使用很重要,无论您是忘记关炉子还是因为警报想检查摄像头视图。 因为我们希望您的智能家居在网络上私密且安全,所以拼图的许多部分需要正确对齐,以便一切都按您的预期工作。本指南旨在帮助您了解设置对 Home Assistant 实例的网络访问的要求、一些复杂性以及我们推荐的典型解决方案: ## 基础:应用如何与您的 Home Assistant 通信 为了让应用与 HA 通信,它需要知道其地址。就在您的家庭网络内,您可能知道您的 Home Assistant 在像 `192.168.1.4` 这样的 IP 上,监听端口 8123。如果您使用 Home Assistant OS 并且没有更改任何默认设置,Home Assistant 也可以通过 访问。 这一切都很好,只要您从不将手机或平板电脑带出家门就可以完美工作,但如果您这样做呢? 最简单的方法是[订阅 Home Assistant Cloud](https://support.nabucasa.com/hc/articles/25649130769949),每月支付[费用](https://www.nabucasa.com/pricing/)。此费用有助于支持 Home Assistant 的进一步开发。Home Assistant Cloud 充当互联网上的"智能"代理,以加密方式将您的前端从家庭隧道传输到您的手机,无论您在哪里,都不需要向来自互联网的入站流量开放您的家庭网络。 如果您不想使用 Home Assistant Cloud(这没关系,但您仍然应该订阅并享受支持 Home Assistant 的温暖感觉),您需要 Home Assistant 可以从互联网访问。这需要在路由器上打开端口并为您的 Home Assistant 在互联网上获取一个名称。虽然可以让您的 Home Assistant 在内部使用端口 8123,并让您的路由器从例如默认的 HTTPS 端口 443 进行端口转发到 8123,但出于简单性的原因,我们建议您不要这样做,这将在后面解释。您还需要为您的 Home Assistant 起一个名称,因为 `homeassistant.local` 是互联网上不存在的私有域后缀。 ## 动态 DNS 大多数非商业互联网连接至少有以下两个缺点之一:您的互联网服务提供商通常不会给您静态 IP(意味着您的调制解调器/路由器分配的公共 IP 地址每隔一段时间甚至每 24 小时就会更改一次),一些 ISP 甚至不给您"真实"的 IP 地址,因为它们没有足够的地址可以分发。最后这种情况在有线电视提供商中非常常见,尤其是在亚洲/太平洋地区。如果您的 ISP 说他们使用运营商级 NAT(CG-NAT)或类似双栈精简版(DS-lite)之类的东西,您可能会遇到此问题。如果您受到影响,请参阅 CG-NAT 和 IPv6 附录。 对于动态的公共 IP 地址,解决方案很简单:通常用户选择动态 DNS 服务,例如 [duckdns.org](https://github.com/home-assistant/addons/blob/master/duckdns/README.md),它将创建一个唯一的名称(例如 `my-home.duckdns.org`),支持通过您的路由器更新以始终指向您的公共地址。如果您在路由器的公共接口上创建了 TCP 8123 到内部 Home Assistant IP(例如 `192.168.1.4`)上的 TCP 8123 的端口转发,您的 Home Assistant 现在可以在网络上使用。此时您可以宣布胜利并停止,但不要这样做——因为此时一切都是未加密的,我们希望您以私密、安全的方式享受 HA。 ## Hairpin NAT 在设置的这一点上,我们需要检查路由器的一项能力:Hairpin NAT(也称为 NAT 反射或 NAT 回环)。这意味着路由器能够将其内部(LAN)接口的请求镜像到其外部(WAN)地址,然后再返回到内部 IP 地址(在这种情况下是您的 Home Assistant),从而反射或发夹流量。检查这是否工作很容易:只需在连接到家庭网络的同时在手机或 PC 上打开浏览器,然后打开 `http://my-home.duckdns.org:8123`——如果它工作,您就有 Hairpin NAT 工作并可以继续下一部分。大多数当前的路由器开箱即支持 NAT hairpinning,但是有一些路由器(尤其是从 ISP 获得的路由器)没有此能力或已禁用。如果是这种情况,您需要检查是否可以在路由器上启用它,或者如果不能,您将需要设置 Split Brain DNS。 ## 保护连接 我们将继续使用 DuckDNS 示例。使用 `http://my-home.duckdns.org:8123` 可以工作,但任何人都可以读取您的流量。让我们改变这一点!DuckDNS 插件将创建一个免费、受信任且有效的 LetsEncrypt SSL 证书,供您在 Home Assistant 上使用。只需按照[这里](https://github.com/home-assistant/addons/tree/master/duckdns)和[这里](https://github.com/home-assistant/addons/blob/master/duckdns/README.md)的安装说明操作,您将拥有安全、公共的 Home Assistant 访问权限。使用 DuckDNS 插件的好处是它使用 LetsEncrypt DNS 挑战,在请求证书期间通过创建临时 DNS 记录来证明域名的"所有权"。如果您使用 DuckDNS 以外的其他 DNS 提供商,可以使用 `Home Assistant` 的 [LetsEncrypt](https://github.com/home-assistant/addons/tree/master/letsencrypt) 插件,它支持通过 DNS 或 http 挑战证明名称所有权。后者需要在路由器上将 TCP 端口 80 端口转发到内部 Home Assistant IP 上的 TCP 端口 80。 有了 Hairpin NAT 工作和 SSL 在您的 DNS 域上,您现在可以在互联网和家中安全地访问 Home Assistant,您应该将 `external_url: my-home.duckdns.org:8123` 添加到 configuration.yaml 的 `homeassistant:` 部分。这不是严格必要的,但将有助于 iOS 应用入门期间的自动检测,因为应用将知道在哪里以及如何到达您的 Home Assistant。 ## Split Brain DNS 那么什么是 split brain DNS(也称为 split horizon DNS、split-DNS),为什么我需要它?如果您的路由器不做 Hairpin NAT,您仍然需要通过公共 DNS 名称(例如 `my-home.duckdns.org`)访问您的 Home Assistant。为什么会这样?因为通过 https 和 SSL 证书的有效加密只适用于公共 DNS 名称。这意味着您服务器上的证书名称需要与您在浏览器或应用中输入的 DNS 名称匹配。这对于有 Hairpin NAT 可用时没问题,但在没有时就成为问题。在这种情况下,您需要"拆分"浏览器/应用在查找 `my-home.duckdns.org` 背后的 IP 地址时得到的答案——您需要一个答案指向家庭网络上的设备,指向您 Home Assistant 的内部 IP 地址(例如 `192.168.1.4`),另一个答案用于当您外出时(例如 `104.25.25.31`)。 最简单的解决方案是使用 Home Assistant 的 [AdGuard Home](https://github.com/hassio-addons/addon-adguard-home) 插件。这也可以在某些路由器上设置(例如 pfSense 或 UniFi Security Gateways),但我们将继续使用我们的示例指南和通过 Home Assistant 提供的工具:所以您现在安装了 AdGuard Home 插件并将路由器 DHCP 设置中的 DNS 服务器更改为您的 Home Assistant 地址。您现在应该转到[插件面板](https://my.home-assistant.io/redirect/supervisor/)中的 AdGuard Home 设置页面,然后转到 `Settings` -> `Filters` 并选择:`DNS rewrites` 在这里点击 `Add DNS rewrite` 并输入您的 `my-home.duckdns.org` 和您 Home Assistant 的内部 IP `192.168.1.4`,然后点击 `save`。现在发生的是,所有来自家庭网络内部的 `my-home.duckdns.org` 地址的 DNS 查询都将由 AdGuard 通过其自己的重写表回答,从而指向您 Home Assistant 的内部地址,而不是询问网络上的公共 DNS 服务器,这些服务器都将用您路由器的公共 IP 回答。 即使您不需要 split brain DNS,您可能也想设置这个,因为它将使您能够在互联网连接断开且 Hairpin NAT 无法工作时通过其公共名称访问 Home Assistant。减少一个对云的依赖! ## 设置应用 如果您遵循了我们所有的建议,您的应用应该会在入门期间连接到家庭 wifi 网络时自动找到您的 Home Assistant 实例。您也可以通过手动输入 `https://my-home.duckdns.org:8123` 在连接到互联网的任何地方进行入门,设置将在应用连接设置的 `External URL` 字段中完成该地址。不需要输入内部 URL,因为无论您的手机连接到哪里,相同的地址都可以工作。 如果您想(或必须)使用 Home Assistant Cloud 或根据您连接的网络使用不同的 URL,则需要更多步骤: * 在系统设置中,将 Home Assistant 的位置访问权限在 iOS 上设置为"始终",在 Android 上设置为"始终允许"。这是必需的,因为 iOS 13 及更新版本和所有 Android 版本只允许具有此类权限的应用访问 wifi SSID,应用使用它来确定是使用内部还是外部 URL。 * 授予权限后,将您的 Home Assistant 地址添加到内部 URL(如果您从本文顶部开始,这可能是 `http://homeassistant.local:8123`) * iOS 如果您在 Home Assistant 中设置了 Home Assistant Cloud,那么"通过云连接"复选框现在应该可用。一旦您激活复选框,外部 URL 将变为停用状态。 * Android 手动将您的 Home Assistant 外部 URL 更改为您的 Home Assistant Cloud URL。 :::note 使用 BSSID 而不是 SSID Android 您还可以在应用设置中输入 wifi 网络 BSSID,以防您有多个具有相同 SSID 的接入点,并且只想在连接到特定接入点时使用内部 URL。为此,添加一个新的 SSID,名称为 `BSSID:` 后跟 BSSID(例如:`BSSID:1A:2B:3C:4D:5E:6F`)。 ::: ## 附录:CG-NAT 如果您的 ISP 不给您公共 IPv4 地址,您基本上只有两个解决方案:您可以致电您的 ISP 并询问他们是否可以给您一个真实地址,或者您的连接是否有可用的升级(奇怪的是,友好地询问对许多 ISP 都有效),或者使用 Home Assistant Cloud。 ## 附录:IPv6 由于 IPv6 在过去 20 年中一直在推出,很可能连同 IPv4 地址,您的家庭网络也被提供了来自 ISP 的 IPv6 地址。所以您的 Home Assistant 主机可能有其 IPv4 地址 `192.168.1.4` 以及 IPv6 地址 `2001:db8:1042::51c1:28d8:3bdc:6724`。这就是我们建议不要更改转发到 Home Assistant 的 TCP 端口的地方: * Home Assistant 将监听 `192.168.1.4:8123` *和* `[2001:db8:1042::51c1:28d8:3bdc:6724]:8123` 上的流量 * 如果您真的想让您的设置面向未来,您将有两条 `my-home.duckdns.org` 的 DNS 记录:一条指向您路由器公共 IPv4 地址的 A 记录,该地址将端口转发到您 HA 主机的内部地址,以及一条 AAAA 记录,直接指向您 HA 主机的 IPv6 地址。现在,当您远程访问 HA 时,可以使用任一协议,因为您输入的只是 `https://my-home.duckdns.org:8123`。如果您将路由器上的端口更改为 https 默认的 443,那么如果您突然有了工作的 IPv6 设置,连接现在将失败,因为没有任何东西在监听 `[2001:db8:1042::51c1:28d8:3bdc:6724]:443`。 ## 附录:通过 NGINX 反向代理 有些情况下,让 Home Assistant 提供 https 是不可能的或与您的某些设备不兼容。这对于通过 RestAPI 通信且只是没有能力进行 SSL 加密的基于 ESP 的低功耗 IoT 硬件来说尤其如此。一个例子是 [konnected.io 集成](https://www.home-assistant.io/integrations/konnected/),它需要 Home Assistant 可以通过 http 访问。 所以为了适应这一点并仍然为外部访问提供加密,我们使用像 [NGINX](https://www.home-assistant.io/docs/ecosystem/nginx/) 这样的反向代理。反向代理的作用是作为客户端(浏览器或应用)的中间人。客户端通过 https 与反向代理安全通信,代理通过未加密的 http 连接将此流量传递给 Home Assistant。继续我们的 Home Assistant 示例,我们假设您已经设置了 DuckDNS 和 LetsEncrypt。您现在应该安装 Home Assistant 的 [NGINX Home Assistant SSL proxy](https://www.home-assistant.io/addons/nginx_proxy/) 插件并根据文档进行配置。 在您的 configuration.yaml 文件中需要进行以下更改: ``` homeassistant: external_url: https://my-home.duckdns.org # 注意这里不再有 :8123 端口 http: use_x_forwarded_for: true # 确保 HA 理解客户端请求来自反向代理 trusted_proxies: - 172.30.32.0/23 # 在 Home Assistant 中,我们需要添加 Docker 子网 - 127.0.0.1 # 添加 localhost IPv4 地址 - ::1 # 添加 localhost IPv6 地址 # 注释或删除 SSL 证书行: # ssl_certificate: /ssl/fullchain.pem # ssl_key: /ssl/privkey.pem ``` 完成后,您的路由器的端口转发应该是 `TCP 443` 到您的 Home Assistant 内部 IP `192.168.1.4 端口 443`。不要创建到 `192.168.1.4 端口 8123` 的转发,因为那是未加密的 http,应该只能从本地网络访问。 您现在可以通过 `https://my-home.duckdns.org` 在内部和外部访问您的 Home Assistant,同时让 `http://192.168.1.4:8123` 可用作未加密端点,用于像 `konnected.io` 这样的事情。 注意:如果您不使用 NGINX Home Assistant 插件而是自己搭建,请确保启用了 websockets 支持。 ### TLS 客户端认证 Android 如果您的 Home Assistant 需要 TLS 客户端认证(因为它位于配置为执行 TLS 客户端认证的反向代理后面),应用将请求证书。 请参阅您的设备和 Android 版本文档以安装证书,Pixel 手机的示例如下[添加和移除证书](https://support.google.com/pixelphone/answer/2844832)。 Wear OS 不支持使用已安装证书进行认证。应用无法自动将证书传输到 Wear OS 应用,因此在 Wear OS 应用入门期间会要求您提供证书。如果需要新证书,您必须通过从 Wear OS 应用注销来重新开始入门过程。证书(和密钥)必须作为 PKCS12 容器提供。对当前默认 PKCS12 加密方法的支持有限,但如果您的手机和手表足够新,可能会工作,所以请先尝试。只有在使用这种新格式入门失败的情况下,您才可以尝试使用旧版 PKCS12 容器。例如使用 OpenSSL,这可以通过在生成容器文件时使用 `-legacy` 标志来实现。 从 2024 年 2 月开始,[Let's Encrypt 已开始迁移到提供不再由 IdenTrust 的根 CA 证书交叉签名的密钥](https://letsencrypt.org/2023/07/10/cross-sign-expiration.html),而是使用他们自己现在广泛受信任的根 CA 证书。未收到更新的受信任证书颁发机构列表的旧客户端会将较新的 Let's Encrypt SSL 密钥视为无效,其中包括早于 7.1.1 的 Android 版本。这将导致 Chrome 或伴侣应用显示 SSL 错误。一个简单的解决方法是使用 Firefox 访问 Home Assistant,因为它随自己更新的受信任证书颁发机构列表一起分发。另一个解决方法是手动将 Let's Encrypt 的活动 ISRG Root X1 自签名 PEM(不是 DST Root X3)安装到 Android 凭据存储中。 --- url: /companion/troubleshooting/setup.md --- # 故障排除 以下是常见问题列表和解决这些问题的故障排除建议。如需更多支持,请[查看更多帮助页面](/companion/troubleshooting/more-help.md) ## 应用在设置时崩溃 如果您运行的是 Home Assistant 0.110,并且应用在设置期间点击"继续"后崩溃,您需要为 `internal_url` 和 `external_url` 添加值。这可以通过用户界面在您的[常规设置](https://my.home-assistant.io/redirect/general/)中完成。如果您没有看到此部分,可能需要先从个人资料页面打开"高级模式"。如果这些字段被禁用,很可能是您的配置存储在 `configuration.yaml` 中,在这种情况下,在 `homeassistant:` 下添加条目,即: ```yaml homeassistant: ... external_url: URL internal_url: URL ``` 将 `URL` 替换为您用于访问 Home Assistant 实例的地址。`internal_url` 和 `external_url` 的值可以相同,并且应该与您在 `configuration.yaml` 的 `http:` 中的 `url:` 相同。 当您保存这些更改后,重启 Home Assistant,在 Home Assistant 完成重启后,重新打开应用。 ## 我在 `dev-services` 面板中看不到我设备的 `notify.mobile_app` 操作 一旦您[设置](/companion/getting_started/index.md)了伴侣应用,您需要重启 Home Assistant 才能注册 `notify.mobile_app` 操作。在 iOS 上,如果您在设置期间授予了通知权限,将创建 `notify.mobile_app_` 操作;在 Android 上,操作将在重启后出现。如果您看不到这个,请在 iOS 上[强制退出](https://support.apple.com/HT201330)或在 Android 上强制停止。然后重新启动伴侣应用,最后重启您的 Home Assistant 实例。该操作现在应该列在 `开发者工具 > 操作` 面板中。 iOS 如果您在 iOS 上看不到该操作,请检查应用内的通知设置(向右滑动以显示侧边栏,然后点击"[设置](https://my.home-assistant.io/redirect/config/)",然后点击"伴侣应用",再点击"通知")。如果"Push ID"框为空,请点击其下方的重置按钮。 Android 如果您在 Android 上仍然看不到该操作,请按照步骤[重新开始](#重新开始使用-android-应用)。 ## 我有 `notify.mobile_app_` 操作但没有收到通知 首先,检查您的消息负载是否有效。查看[通知文档](/companion/notifications/basic.md)中的示例,或在 `开发者工具 > 服务` 页面上尝试向您的 `notify.mobile_app_` 服务发送以下简单示例。 ```json {"message": "Hello World"} ``` 如果此通知被送达,问题很可能出在您的负载上。 如果上述方法不起作用,请尝试以下操作: 1. *检查您的消息限制:* 为了让我们提供免费的通知服务,每个应用目标每天限制 500 条通知。[位置更新](/companion/notifications/commands.md#request-location-updates)和其他特殊通知不计入此限制。iOS 在 iOS 中,您可以在伴侣应用中检查剩余通知,方法是向右滑动打开侧边栏,点击"[设置](https://my.home-assistant.io/redirect/config/)",然后点击"伴侣应用"再点击"通知",滚动到页面底部。限制每天午夜 UTC 重置。 2. *重置您的 Push ID 令牌:* iOS 如果您检查后仍有剩余通知,您可以在[设置](https://my.home-assistant.io/redirect/config/)的"伴侣应用"页面内的"通知"页面顶部重置您的通知。执行此操作后,您可能需要[强制退出](https://support.apple.com/HT201330) iOS 伴侣应用,然后重新打开应用,最后重启您的 Home Assistant 实例。 3. *检查您的系统设置:* * iOS 在 iOS 设置应用中,导航到通知,然后选择 Home Assistant,并确保"允许通知"已打开。 * Android 在 Android 设置应用中,导航到应用,然后选择 Home Assistant,然后选择通知,并确保"所有 Home Assistant 通知"已打开。如果您只收到部分通知,请检查您使用的[通知渠道](/companion/notifications/basic.md)#notification-channels)是否已打开。 4. *重新开始使用 Android 应用:* Android 如果您仍然无法在 Android 应用中收到通知,请尝试[重新开始](#重新开始使用-android-应用)。 ## 我收到 SSL 错误和/或离家时无法连接到我的 Home Assistant 实例 这通常发生在您启用了 [Home Assistant Cloud](https://www.home-assistant.io/cloud/) 但没有打开[远程 UI](https://www.nabucasa.com/config/remote/) 时。要解决此问题,请启用[远程 UI](https://www.nabucasa.com/config/remote/),或向右滑动打开侧边栏,点击"设置",然后点击"伴侣应用",在"设置"下点击"连接"。确保"通过云连接"旁边的开关已关闭,并在"外部 URL"字段中输入您的 Home Assistant 实例的远程地址。此地址必须是加密连接,有关设置到 Home Assistant 实例的加密远程连接的说明,请参阅 [Home Assistant 文档](https://www.home-assistant.io/docs/configuration/remote/)或[此使用 Duck DNS 设置 Let's Encrypt 的指南](https://www.home-assistant.io/docs/ecosystem/certificates/lets_encrypt/)。 如果您根本没有设置 [Home Assistant Cloud](https://www.home-assistant.io/cloud/),问题很可能是远程连接不安全。伴侣应用需要加密连接来进行远程连接。请参阅 [Home Assistant 文档](https://www.home-assistant.io/docs/configuration/remote/)或[此使用 Duck DNS 设置 Let's Encrypt 的指南](https://www.home-assistant.io/docs/ecosystem/certificates/lets_encrypt/)以获取设置安全连接的说明。 ## Home Assistant 中的某些功能在桌面上的工作方式不同 这可能不是伴侣应用的问题,而更可能是 Home Assistant 或表现异常的特定组件的问题。要测试原因,请尝试以下步骤。 1. 首先,在 iOS 伴侣应用中向下滑动以刷新您的视图。在 Android 应用中强制停止应用程序并重新启动它。 2. 如果问题仍然存在,在 Safari/Chrome 浏览器中打开您的 Home Assistant 实例(您可能需要登录)。如果问题在 Safari/Chrome 中存在,请在 [Home Assistant 前端 GitHub](https://github.com/home-assistant/frontend/issues) 或如果是自定义组件,与该组件的开发者提出问题。在您的问题报告中,说明问题在移动浏览器上查看时存在,不一定是伴侣应用。 3. 如果问题在 Safari 中没有发生,请在 [iOS 伴侣应用 GitHub](https://github.com/home-assistant/iOS/issues) 或 [Android 伴侣应用 GitHub](https://github.com/home-assistant/android/issues) 提出问题。请说明您遵循了这些步骤,问题只发生在伴侣应用中。 ## 状态栏(顶部带有手机/Wi-Fi 信号强度的栏)与我的主题不匹配 如果您使用的是 2020.2 之前的 iOS 应用或 Android 应用,要将状态栏的颜色更改为与您的 Home Assistant 主题匹配,请使用 [`frontend.set_theme`](https://www.home-assistant.io/components/frontend/#theme-automation) 操作而不是 Home Assistant 个人资料页面中的下拉菜单。使用该操作将生成一个事件,允许伴侣应用检测主题更改并将正确的颜色应用于状态栏。有关使用哪些键的详细信息,请参阅[主题](/companion/integrations/theming.md)文档。请注意,颜色必须在您的主题中指定为十六进制值(例如 `#0099ff`),不支持通过变量名指定元素颜色。 ## 我在多个设备上运行伴侣应用,`sensor` 名称太相似且令人困惑,我该怎么办? 从 Home Assistant Core 0.106 开始,默认传感器名称将在 iOS 设置应用或 Android 伴侣应用配置页面中设置您的设备名称注册。目前,您需要按照以下步骤从 Home Assistant 配置页面的[集成仪表板](https://my.home-assistant.io/redirect/integrations/)中重命名每个传感器。 1. 转到配置中的[集成仪表板](https://my.home-assistant.io/redirect/integrations/)。 2. 找到与您希望重命名传感器的设备对应的"移动应用:*设备名称*"集成并打开它 3. 对于您希望重命名的每个传感器,点击或点击传感器名称,然后点击齿轮符号。 4. 在"实体 ID"下,根据需要更改实体 ID。**不要**更改 ID 的 `sensor.` 或 `device_tracker.` 部分 5. 对您希望重命名的每个传感器重复步骤 4 和 5 ## 下拉手动刷新应用/更新位置时出现 `kCLError` 要解决此问题,请在 iOS 设置 > 隐私 > 位置服务中将 Home Assistant 应用的位置权限更改为"始终"。 ## 人员实体未更新最近位置 如果您使用的是 `person` 实体而不是提供的 `device_tracker` 实体,您有时可能会注意到 `person` 实体状态没有按您的预期更新。默认情况下,您使用应用登录的任何新设备都将作为跟踪器添加到登录的人员中,这可能会导致此问题。您可以按照以下步骤检查 `person` 实体: 1. 转到[人员](https://my.home-assistant.io/redirect/people/) 2. 选择有跟踪器问题的人员 3. 查看属于此人员的设备 4. 移除任何位于家中或不再使用的设备。在此列表中只保留与您一起出行的设备。 5. 保存更改 ## 重新开始使用 Android 应用 Android 有时您可能需要重新开始使用 Android 应用,因为新功能可能无法正常工作或出现一些奇怪的情况。请确保精确遵循每一步,不要跳过任何内容。 :::info 并非所有但有些问题可以通过简单地从应用注销并重新登录来解决。如果您在服务器中设置了[受信任的网络](https://www.home-assistant.io/docs/authentication/providers/#trusted-networks),请确保输入您的凭据登录应用,以便应用在不在受信任网络时仍能继续工作。如果您尝试注销并重新登录后问题仍然存在,请继续执行以下步骤。 ::: 1. 检查 Home Assistant Core、[Android 应用](https://play.google.com/store/apps/details?id=io.homeassistant.companion.android)和 [Android System WebView](https://play.google.com/store/apps/details?id=com.google.android.webview) 是否都是最新的。 2. 清除 Android 应用中的存储或应用数据。不要假设卸载和重新安装是安全的,因为这会触发自动备份,而我们要避免这种情况。 3. 在 Home Assistant 中导航到[集成仪表板](https://my.home-assistant.io/redirect/integrations/)。移除相关设备的移动应用条目。如果您看到超过 1 个,请全部移除。 4. 重启 Home Assistant。 5. 重新登录 Android 应用。如果您有超过 1 个设备,请确保在入门期间重命名设备。记得使用您的凭据而不是受信任网络登录。 ## Android 应用中设备跟踪器未更新 Android 如果您发现设备跟踪器没有按您的预期更新,请按照以下步骤确保最佳设置。 1. 确保您的设备和服务器满足位置跟踪的先决条件: * 为您的服务器启用[远程访问](https://www.home-assistant.io/docs/configuration/remote/)。 * 在[设置](https://my.home-assistant.io/redirect/config/) > 伴侣应用 > 管理传感器中,启用以下**位置传感器**:后台位置、位置区域和单次精确位置。 * 如果您使用多个服务器,请确保每个传感器在正确的服务器上已启用。 * 如果您不是从 Play 商店安装的应用,请验证您使用的是[`full` 版本](/companion/core/android-flavors.md)。 * 如果您使用 `person` 实体进行跟踪,请仔细检查它是否[设置正确](#人员实体未更新最近位置)。 2. 确保应用已授予位置权限,始终允许。(在 Android 12 及更新版本上,提示时允许精确位置) 3. 确保设备上已启用位置(GPS)。 4. 允许后台访问并为应用关闭"电池优化"。 * 您可以在[设置](https://my.home-assistant.io/redirect/config/) > 伴侣应用中检查后台访问。设置应显示勾号 ✔️。 * 某些制造商可能会添加额外的电池节省功能(例如:省电模式),请确保也禁用所有这些功能。您通常可以从系统设置应用访问这些功能。 5. 为应用开启无限制数据。 * 如果数据节省模式开启,Home Assistant 可能无法正确发送/接收数据。 有时上述步骤仍然不会导致位置更新到达您的服务器。应用可能会收到大量位置更新并跳过其中一些。要确定原因,请查看应用位置历史日志。 转到[设置](https://my.home-assistant.io/redirect/config/) > 伴侣应用 > 故障排除 > 位置跟踪并启用位置历史。应用现在将保留过去 48 小时内收到的所有位置更新的日志。 * 每次更新将显示来源(例如,"后台位置")和结果(例如,"已发送")。应用在发送之前会验证位置是否有效,更新可能会由于时间、准确性、重复或其他原因而被跳过。 * 应用应该每小时多次接收更新。如果您在启用历史记录后没有看到更新,请确保遵循前面提到的步骤。没有位置历史通常是由于 Home Assistant 应用的后台访问受限,或 Android 系统杀死了应用。 * 如果由于准确性而跳过多次更新,请检查 GPS 坐标以确保它们正确,并考虑增加[准确性的传感器设置](/companion/core/location.md#location-sensor-settings)。例如,如果您看到有效位置被跳过,准确性约为 `350`,则将最小准确性设置设为 `400` 作为缓冲。较大的值也可能导致不一致的结果,因此以日志中的有效报告为准。
手动审查步骤 您还可以使用[崩溃日志](#android-crash-logs)手动查看位置历史以确定发生了什么。这些日志包含更多详细信息,但仅在应用打开时保留。整个位置决策过程都会打印到日志中,以帮助您了解正在发生的事情。当您查看日志时,请注意包含 `LocBroadcastReceiver` 的行以跟踪决策。请记住,您需要大约 10 分钟的日志,因此您可能需要在问题发生时保持应用打开以生成更长的日志。 下面是一个您可以期望看到的示例,以确保位置更新传到手机。应用在将其发送回去之前会验证位置是否有效。这些是收到重复位置时您可以期望看到的日志。如果自上次更新发送以来位置没有更改 15 分钟,应用将不会向服务器发送相同的位置更新。 ``` 2021-02-03 09:03:00.900 7306-7306/? D/LocBroadcastReceiver: Received location update. 2021-02-03 09:03:00.903 7306-7306/? D/LocBroadcastReceiver: Last Location: Coords:(37.4220656, -122.0840897) Accuracy: 4.663 Bearing: 86.759346 2021-02-03 09:03:00.903 7306-7306/? D/LocBroadcastReceiver: Begin evaluating if location update should be skipped 2021-02-03 09:03:00.903 7306-7306/? D/LocBroadcastReceiver: Received location that is 74 milliseconds old, 1612371780829 compared to 1612371780903 with source fused 2021-02-03 09:03:00.903 7306-7306/? D/LocBroadcastReceiver: Duplicate location received, not sending to HA ``` 下面您将找到成功位置结果的预期日志。如果您没有看到这样的行,请确保遵循前面提到的步骤。 ``` 2021-02-03 09:06:34.241 7306-7306/? D/LocBroadcastReceiver: Received location update. 2021-02-03 09:06:34.245 7306-7306/? D/LocBroadcastReceiver: Last Location: Coords:(37.4220656, -122.0840897) Accuracy: 13.279 Bearing: 0.0 2021-02-03 09:06:34.245 7306-7306/? D/LocBroadcastReceiver: Begin evaluating if location update should be skipped 2021-02-03 09:06:34.245 7306-7306/? D/LocBroadcastReceiver: Received location that is 1126 milliseconds old, 1612371993119 compared to 1612371994245 with source fused 2021-02-03 09:06:34.309 7306-7430/? D/LocBroadcastReceiver: Location update sent successfully ``` 日志将指示报告是否由于时间、准确性、重复或其他原因而被跳过。
如果您在遵循上述步骤后仍然没有收到位置更新,并认为这不正确,请提交 GitHub [问题](https://github.com/home-assistant/android/issues/new?assignees=\&labels=bug\&template=Bug_report.md\&title=)。如果可能,请附上此故障排除步骤的至少 10 分钟日志,以便其他人更容易帮助您(可能会被请求)。 ## 在 Android 上使用自签名证书导致空白页面 Android 如果您在 Android 上使用自签名证书,那么在输入和/或选择您的 Home Assistant 实例后,您可能会卡在空白屏幕上。要解决此问题,您需要确保 URL 有效,并将证书导入到 Android 的受信任证书中。执行此操作的步骤可以在[这里](https://support.google.com/nexus/answer/2844832?hl=en)找到。这些步骤是为 Android 9+ 的设备编写的,但对于较旧的受支持设备非常接近。 ## Android 小部件不工作 Android 如果您发现小部件不再工作,这些步骤可能会帮助您解决问题。 1. 检查设备上的数据节省模式是否已禁用,小部件在启用时将不工作。 2. 检查 Home Assistant 应用的后台数据是否已启用。 3. 移除并重新创建小部件。 ## 通知操作太相似或在 Android 中不显示 如果您有超过 1 台相同型号的设备,并且登录后在伴侣应用配置中没有重命名您的设备,那么您可能会有冲突。 1. 在侧边栏中导航到[设置](https://my.home-assistant.io/redirect/config/)。 2. 点击"伴侣应用" 3. 在设备注册下更改设备名称。 4. 重启 Home Assistant 以注册新的通知操作。(即 `notify.mobile_app_`) ## 传感器缺失或未更新 iOS 当应用不在前台时,传感器更新与位置更新绑定,因此您需要确保在 iOS 设置中将位置权限设置为"始终允许"。 应用也会尝试在后台发送更新,但是这些更新的频率由 iOS 决定,并且为了保护电池寿命而受到严格限制。iOS 使用一个内部指标(对应用开发者不可见)来优先处理应用的后台活动。您更多使用的应用将被允许更频繁地在后台做更多事情,这意味着您越多使用伴侣应用,iOS 将学习到该应用对您很重要,并允许通过后台获取更频繁地更新。 如果您想确保在设备开始充电或电池电量低于或高于某个限制时更新传感器,最可靠的方法是在 iOS 的[快捷指令](/companion/integrations/siri-shortcuts.md)应用中使用自动化。将"When"部分设置为所需条件,在"Do"部分选择 Home Assistant 的"更新传感器"操作。您很可能想要关闭"运行前询问"以避免在发送更新之前被提示。由于 iOS 的限制,当这些更新发送时,您将始终看到来自快捷指令应用的通知。 Android 在 Android 上,传感器会在有更新时显示。有些会在启用后立即显示,其他的会在授予权限并检索状态后显示。如果您没有看到传感器,您可能需要等待传感器获取状态更新,以便它可以将其发送到您的 Home Assistant 服务器。 ## 文本转语音通知不工作 Android 检查[语音识别与合成](https://play.google.com/store/apps/details?id=com.google.android.tts)是否已更新。检查它是否也设置为默认的文本转语音引擎,这可能是某些制造商所要求的。 ## Android 崩溃日志 Android Android 应用使用 Google 的 ADB [Logcat](https://developer.android.com/studio/command-line/logcat) 功能来记录错误。有时您可能希望检查日志,或者开发者可能会要求提供崩溃日志以解决您的问题。在[设置](https://my.home-assistant.io/redirect/config/)伴侣应用 > 故障排除 > 显示和分享日志下有一个选项。此功能使刷新、分享和查看日志变得更加容易。然后,当您想要创建[问题](https://github.com/home-assistant/android/issues/new?assignees=\&labels=bug\&template=Bug_report.md\&title=)或当开发者要求它们来解决问题时,可以使用这些日志。需要注意的是,设备日志可能包含也可能不包含敏感信息,如您的 Home Assistant URL,因此在分享之前确保删除敏感信息。 ## Android 应用电池消耗 Android Android 应用提供许多功能,其中一些可能比其他功能消耗更多电池。应用上的默认设置力求使应用尽可能省电。可能会出现您启用某个功能导致比预期更多电池消耗的情况。本节将列出在您决定[重新开始](#重新开始使用-android-应用)之前需要在应用程序上检查的所有内容。对于以下选项,您需要转到伴侣应用设置逐个检查并禁用它们。 1. 如果在完整版上,检查高精度模式是否没有一直启用。 2. 如果在完整版上,检查单次精确位置传感器是否没有启用"包含在传感器更新中"选项。 3. 检查持久连接是否设置为"从不"。 4. 如果蓝牙发射器传感器已启用,检查发射器是否没有一直开启,只在您希望使用时启用它。 5. 检查传感器更新频率是否设置为"正常"。 6. 检查没有任何通知传感器在其各自的设置中禁用允许列表。您总是希望定义一个允许列表以防止严重的电池使用。 7. 如果您的默认仪表板包含任何类型的直播流,请尝试移除或将默认仪表板替换为没有直播流的仪表板。 --- url: /companion/wear-os/index.md --- # 概览 Android 8+ only 您可以直接从 Wear OS 手表访问 Home Assistant,即使在没有连接手机的情况下,也可以使用手表上的 WiFi 或蜂窝网络连接。 该应用不支持所有 Home Assistant 功能。请关注此页面,随着应用新增功能!查看[传感器!](/companion/wear-os/sensors.md) ## 前提条件 要在手表上设置 Home Assistant,您需要一部已安装 Home Assistant 应用的配对 Android 手机来登录。登录后,不再使用手机应用。 ## 主屏幕 登录并选择后,当前支持切换/执行的域列表如下: * `button` * `cover` * `fan` * `input_boolean` * `input_button` * `light` * `lock` * `scene` * `script` * `switch` ### 收藏 用户可以转到 Wear OS 应用中的设置,设置将显示在列表顶部的收藏实体。这些实体将在其余实体加载之前出现,以便在启动应用时可以立即执行。如果您从 Home Assistant 实例中删除了一个实体,还有一个设置选项可以清除收藏以删除过期实体。 收藏也可以从手机应用管理,方法是转到应用配置 > Wear OS 应用 > 管理收藏。手机应用还允许您拖放实体以更改它们在主屏幕上显示的顺序。 如果您只想显示收藏实体而不显示 Wear OS 应用中的其他内容,可以通过打开应用并导航到设置,然后选择"仅显示收藏"选项来实现。这将隐藏区域和域,使您只能看到收藏。 ### 区域 如果任何设备或实体已添加到 Home Assistant 中的区域,这些区域将显示在 Wear OS 应用的收藏下方。点击区域将显示该区域中的所有主要实体。任何未添加到区域的主要实体域将显示在列表底部附近,作为"更多实体"。配置和诊断实体以及隐藏实体仅显示在列表底部的"所有实体"中。 ### 更多详情 长按任何实体可打开更多详情屏幕。此屏幕包含有关状态和实体上次更新时间的更多信息。详情屏幕提供以下选项,具体取决于实体支持的功能: * `fan`: 速度控制 * `light`: 亮度控制和色温控制 ### 设置 设置屏幕位于主屏幕底部。您可以在此处添加手表上的收藏以及配置磁贴。您还可以找到启用触觉反馈和/或 toast 确认的选项,以了解何时选择了实体。这些设置将反映在主屏幕和快捷方式磁贴上。 ## 磁贴 * 快捷方式磁贴显示最多 7 个快捷方式,可以从 Wear OS 应用的设置部分选择。您将能够选择与主屏幕上可访问的相同实体集。从 Wear OS 3 开始,可以添加任意数量的可单独配置的磁贴,仅受 Wear OS 的磁贴总数限制。 * 模板磁贴显示渲染的模板。模板只能从 Android 伴侣应用设置。注意:磁贴中无法滚动,模板应适合手表屏幕。 * 摄像头磁贴显示所选摄像头的快照。 * Assist 磁贴允许您快速[在手表上打开 Assist](https://www.home-assistant.io/voice_control/android/#assist-on-wear-os)。 * 恒温器磁贴允许您查看和控制气候实体的目标温度。 :::note 关于磁贴刷新 Wear OS 限制应用更新磁贴的频率以及交互程度。对于摄像头、模板和恒温器磁贴,您可以选择刷新间隔,向系统指示磁贴应多久刷新一次。 * 手动(仅在点击刷新按钮时更新) * 在视图中(仅在将磁贴滚动到视图中时更新) * 每 x 分钟/小时(在后台更新磁贴,即使未查看) 对于除"手动"以外的间隔,系统不保证更新:如果磁贴未放置在磁贴列表的开头或结尾,它们的更新频率可能会低得多。您可能会在磁贴更新时看到旧版本 1-2 秒。 每 x 分钟/小时更新的选项在查看时仍会更新磁贴。例如:选择 1 小时的更新间隔将向系统指示磁贴应在查看时更新,并自上次查看以来每小时在后台更新。 ::: ### 设置模板磁贴样式 您可以使用 HTML 来格式化显示的文本。目前支持以下标签: * 添加新行:`
` * 更改文本样式:`粗体`、`斜体` 或 `下划线` * 更改文本大小:`大` 或 `小` * 更改颜色:`彩色文本` * 使用标题:`

标题

`、`

副标题

` 等 ### 恒温器磁贴 恒温器磁贴可用于按步长上下更改气候实体的目标温度。由于磁贴刷新受限,显示的目标温度可能不再准确。因此,如果用户通过磁贴更改温度,当前目标温度总是先刷新。如果用户快速多次更改温度,每次点击都会相对于上一次点击的结果更改温度,而不是从服务器获取目标温度。这样做是为了抵消某些恒温器更改目标温度的延迟。 ## 复杂功能 * 实体状态复杂功能可以显示在您的表盘上。复杂功能将显示所选实体的当前状态,以及可选的测量名称和单位。根据表盘的不同,复杂功能可能还会显示实体名称和图标,并支持"短文本"和"长文本"复杂功能类型。 当您将实体添加到表盘时,可以选择要显示的实体。这仅在手錶上编辑表盘时有效,而不是在手机上的手表应用中。要更改所选实体,只需更改复杂功能并再次选择实体状态复杂功能。每当屏幕打开以及大约每 15 分钟,复杂功能会自动更新。您可以通过在表盘上点击复杂功能来强制更新。 提示:使用[模板传感器](https://www.home-assistant.io/integrations/template/#state-based-template-binary-sensors-buttons-numbers-selects-and-sensors)以获得完全的灵活性。 * Assist 复杂功能可用于直接从表盘快速与 Assist 功能交互。 ## 通知 Wear OS 设备默认会转发连接设备上任何应用的[通知](/companion/notifications/basic.md),这意味着通知需要先发送到连接设备,然后才能到达可穿戴设备。Wear OS 应用允许将通知直接发送到手錶本身,跳过连接设备。由于平台限制,并非连接设备支持的所有通知功能都被 Wear OS 应用支持。 目前仅支持以下参数。 * [`channel`](/companion/notifications/basic.md#notification-channels) * `message` * [`notification_icon`](/companion/notifications/basic.md#notification-status-bar-icon)(并非所有设备都会显示图标) * [`tag`](/companion/notifications/basic.md#replacing)(支持仅限于替换通知) * `title` * [`vibrationPattern`](/companion/notifications/basic.md#notification-vibration-pattern)(如果您的设备默认不振动的可能需要设置振动,模式可能不会根据设备被遵守) 示例: ```yaml automation: - alias: '发送可穿戴通知' trigger: ... action: - action: notify.mobile_app_ data: message: "通知消息" title: "通知标题" data: notification_icon: "mdi:fire" tag: "notification" ``` :::info 为了加快通知传递,您可能需要使用[文档](/companion/notifications/critical.md#android)中列出的第一种关键通知格式。闹钟流通知目前在 Wear OS 中不受支持。 ::: ### 通知命令 Wear OS 应用对[通知命令](/companion/notifications/commands.md)有基本支持。不幸的是,并非所有命令都能在应用中得到支持。目前支持以下命令: * [BLE 发射器](/companion/notifications/commands.md#ble-beacon-transmitter) * [信标监视器](/companion/notifications/commands.md#beacon-monitor) * [清除通知](/companion/notifications/basic.md#clearing) * [停止 TTS](/companion/notifications/commands.md#stop-tts) * [更新传感器](/companion/notifications/commands.md#update-sensors) ### 通知清除 Wear OS 应用还支持[通知清除](/companion/notifications/cleared.md)事件。当通知被清除时,伴侣应用将发送一个事件。 ### 文字转语音通知 Wear OS 应用还支持[文字转语音通知](/companion/notifications/basic.md#text-to-speech-notifications)。请参考上面的链接了解使用的格式以及使用注意事项。 --- url: /companion/wear-os/sensors.md --- # 传感器 Wear OS 应用还提供[传感器](/companion/core/sensors.md#android-sensors),以便在 Home Assistant 中使用您的可穿戴数据,请参考链接了解有关 Android 上传感器更新的更多信息。并非手机应用提供的所有传感器都由 Wear OS 应用提供。请查看以下列表,了解 Wear OS 应用当前支持的传感器。如果传感器需要权限,系统会提示您接受,否则传感器将不会启用和发送数据。 需要注意的是,传感器更新需要应用向设备发送通知,以防止被操作系统终止。您可以转到 Wear 设备设置并关闭 SensorWorker 通知渠道,以停止这些通知在手腕上震动。 :::info 传感器更新取决于手表是否有数据连接以及应用是否被允许发送更新。某些设备实施了比其他设备更严格的省电技术,因此更新可能不会像您预期的那样频繁。 目前不支持传感器设置。因此,某些传感器可能无法完全运行。例如,BLE 发射器和信标监视器传感器只能启用,目前无法更改任何设置。在我们努力添加传感器设置的同时,这些传感器可能无法完全正常工作,默认设置将允许主要功能。 ::: ## 传感器列表 | 传感器 | 属性 | 描述 | | --------- | --------- | ----------- | | [应用数据](/companion/core/sensors.md#app-data-sensors) | 无 | 显示应用发送或接收了多少数据的传感器。 | | [应用重要性](/companion/core/sensors.md#app-importance-sensor) | 无 | 应用当前的重要性,用于确定它是在前台还是被缓存。 | | [应用内存](/companion/core/sensors.md#app-memory-sensor) | 无 | 关于应用可用内存的信息。 | | [应用使用](/companion/core/sensors.md#app-usage-sensors) | 无 | 表示应用根据使用情况如何被对待的传感器。 | | [音频](/companion/core/sensors.md#audio-sensors) | 无 | 关于设备不同类型音频检测的几个不同传感器。 | | [电池](/companion/core/sensors.md#battery-sensors)(默认启用) | 无 | 关于设备电池状态的几个不同传感器。默认仅启用 `battery_level`、`battery_state` 和 `charger_type`。 | | `binary_sensor.bedtime_mode` | 无 | 反映设备上就寝模式状态的传感器。为获得最佳效果,请启用勿扰或交互传感器。仅在 Wear OS 3 设备上可用 | | [蓝牙传感器](/companion/core/sensors.md#bluetooth-sensors) | [参见属性](/companion/core/sensors.md#bluetooth-sensors) | 关于设备蓝牙状态的几个不同传感器。还提供用于信标发射和监视的传感器。 | | `sensor.current_time_zone` | [参见属性](/companion/core/sensors.md#current-time-zone-sensor) | 设备所在的当前时区。 | | [当前版本](/companion/core/sensors.md#current-version-sensor) | 无 | 应用当前安装的版本。 | | [勿扰](/companion/core/sensors.md#do-not-disturb-sensor) | 无 | 设备上勿扰模式的状态。 | | [休眠](/companion/core/sensors.md#doze-sensor) | 无 | 设备是否处于休眠模式。 | | [健康服务](#health-services) | [见下文](#health-services) | 由健康服务 API 提供的一组传感器。 | | `sensor.heart_rate` | 准确度 | 当前心率(每分钟心跳数)。此传感器使用[心率传感器](https://developer.android.com/reference/android/hardware/Sensor#TYPE_HEART_RATE)。 | | [交互](/companion/core/sensors.md#interactive-sensor) | 无 | 设备是否处于交互状态。 | | [键盘锁传感器](/companion/core/sensors.md#keyguard-sensors) | 无 | 表示设备被锁定或安全等各种状态的传感器。 | | `sensor.last_reboot` | [参见属性](/companion/core/sensors.md#last-reboot-sensor) | 设备上次重启的时间戳。 | | [上次更新](/companion/core/sensors.md#last-update-trigger-sensor) | 无 | 状态将反映导致发送上次更新的意图。 | | `sensor.light_sensor` | 无 | 设备检测到的当前照度级别。 | | [移动数据传感器](/companion/core/sensors.md#mobile-data-sensors) | 无 | 关于移动数据状态的几个不同传感器。 | | `binary_sensor.nfc_state` | 无 | 设备是否启用了 NFC 传感器。 | | `sensor.phone_state` | 无 | 唯一跟踪的状态是 `idle`、`ringing` 或 `offhook`,不访问其他信息。 | | `sensor.pressure_sensor` | 无 | 设备的压力读数。 | | `sensor.proximity_sensor` | 无 | 设备当前的近距离读数,某些设备只会显示 `near` 或 `far` 的布尔值。 | | [网络](/companion/core/sensors.md#connection-type-sensor) | 无 | 关于 WiFi 状态的几个不同传感器。 | | [下次闹钟](/companion/core/sensors.md#next-alarm-sensor) | [参见属性](/companion/core/sensors.md#next-alarm-sensor) | 下一个计划闹钟的日期。 | | `binary_sensor.on_body_sensor` | 无 | 指示可穿戴设备是否认为它在身上的传感器。此传感器使用[低延迟离身检测](https://developer.android.com/reference/android/hardware/Sensor#TYPE_LOW_LATENCY_OFFBODY_DETECT)传感器。 | | [省电](/companion/core/sensors.md#power-save-sensor) | 无 | 设备是否处于省电模式。 | | `sensor.screen_brightness` | [参见属性](/companion/core/sensors.md#screen-brightness-sensor) | 屏幕亮度的当前值。 | | `sensor.screen_off_timeout` | 无 | 屏幕关闭超时设置的当前值。 | | `sensor.sim_1` | [参见属性](/companion/core/sensors.md#cellular-provider-sensor) | 您的蜂窝运营商名称。 | | `sensor.sim_2` | [参见属性](/companion/core/sensors.md#cellular-provider-sensor) | 您的蜂窝运营商名称。 | | [步数](/companion/core/sensors.md#pedometer-sensors) | 无 | 自上次设备重启以来用户的步数。在支持的设备上需要活动识别权限。 | | [存储传感器](/companion/core/sensors.md#storage-sensor) | [参见属性](/companion/core/sensors.md#storage-sensor) | Android 设备上内部和外部存储的总量和可用量。 | | `binary_sensor.theater_mode` | 无 | 反映设备上影院模式状态的传感器。为获得最佳效果,请启用交互传感器。 | | [流量统计传感器](/companion/core/sensors.md#traffic-stats-sensor) | 无 | 自上次重启以来移动设备和总设备使用传输和接收的数据量。 | | `binary_sensor.wet_mode` | 无 | 指示当前设备上湿模式的传感器。此传感器在某些设备上也称为触摸锁或水锁。这是一种特殊模式,用户必须按住表冠/电源按钮 2 秒钟才能重新启用触摸。 | ### 健康服务 仅限 Wear OS 3+
包含 Google [健康服务 API](https://developer.android.com/training/wearables/health-services/passive#useractivityinfo) 提供的数据的传感器列表。 以下传感器可用(如果您的设备支持): | 传感器 | 属性 | 描述 | | --------- | --------- | ----------- | | `sensor.activity_state` | 运动类型,时间 | 反映当前用户活动状态的传感器,可以是:睡眠、运动、被动或未知。| | `sensor.daily_calories` | 无 | 一天内的总卡路里数(包括基础代谢率和活动卡路里),前一天结束和新的一天开始于当地时间上午 12:00。 | | `sensor.daily_distance` | 无 | 一天内的总距离,前一天结束和新的一天开始于当地时间上午 12:00。 | | `sensor.daily_floors` | 无 | 一天内爬楼的总层数,前一天结束和新的一天开始于当地时间上午 12:00。 | | `sensor.daily_steps` | 无 | 一天内的总步数,前一天结束和新的一天开始于当地时间上午 12:00。 | --- url: /developers/ai_policy.md --- 我们支持在贡献 Open Home Foundation 项目时使用 AI(即 LLMs)作为工具。然而,你对你提交的所有贡献负责,我们对合并并发布的所有贡献负责。我们对我们项目的所有贡献都持高标准。 我们的维护者投入时间和精力来审查贡献。提交你自己未经审查和理解的 AI 生成内容会浪费这些时间,将不会被接受。 ## 自主代理(Autonomous agents) **我们不允许使用自主代理来为我们的项目做贡献。** 我们将关闭任何我们认为由自主代理创建的 pull request 或 issue,并可能将自动化评论标记为垃圾信息。这包括绕过所提供的 issue 或 pull request 模板的贡献。 ## issue、pull request 和代码审查中的沟通 如果你使用 AI 工具来帮助你写作,我们并不介意。但是,不要让工具替你在未审查的情况下发布内容。保持回复内容最低限度,仅需传达你的意图即可。我们可能会隐藏我们认为属于未审查 AI 输出的任何评论。 如果你正在发起一个 pull request,我们期望你能用自己的话解释所提出的更改。这包括 pull request 描述以及对问题的回复。如果你使用 AI 帮助生成 pull request 摘要,你必须审查其技术准确性。 **不要使用 AI 来生成对维护者问题的回答。** 你应该理解并能够解释自己的工作。使用 AI 来改善语法或清晰度是可以的,但回复的内容必须是出自你自己的。 如果你希望在评论中引用与 AI 交互的内容,必须使用引用块(例如使用 `>`)并加以披露。必须附上你自己的评论,解释该上下文的相关性和影响。不要分享长篇片段。 ## 非英语母语使用者 我们理解,作为非英语母语使用者时,AI 是有用的。使用 AI 来改善你自己所写文本的语法或清晰度是可以的。如果你使用 AI 来翻译你的评论,请确保翻译准确反映了你的意图。在 details 块中附上你的原文可以展示你贡献背后的努力,有助于维护者在需要时验证翻译,并保持对话的可读性。 ## 代码和文档贡献 AI 可以成为编写代码和文档的有用工具。然而,由于我们项目的基础开源性质,我们要求有人类参与循环,理解 AI 产生的工作。 所有贡献在提交前必须经过贡献者审查和理解。你应该能够解释你在 pull request 中提交的每一个更改。看起来像未审查 AI 输出的 pull request 将在不经过审查的情况下被关闭。 ## 我们对 AI 的使用 我们的一些项目使用 AI 工具来辅助代码审查、issue 分类、报告和其他项目管理任务。这些工具可能会在 pull request 或 issue 上留下评论。与任何自动化工具一样,这些评论并不总是正确的。 如果 AI 工具在你的贡献上留下评论,请将其视为任何其他审查评论一样对待。如果你认为它不正确,请说明;简要解释就足够了。维护者始终拥有最终决定权。如有疑问,请咨询维护者。 ## 执行 不符合本政策的贡献将被关闭。反复违规可能会导致被禁止贡献到 OHF 项目。如果你认为你的贡献被错误关闭,欢迎你联系维护者进行讨论。 --- url: /developers/android.md --- ## 欢迎加入 Home Assistant Android 项目 你是否准备在智能家居技术领域做出改变?**Home Assistant Android 应用**是一个开源项目,使用户能够无缝地控制他们的智能家居。无论你是开发者、设计师还是爱好者,**你的贡献很重要**! **[浏览 GitHub 仓库](https://ossinsight.io/analyze/home-assistant/android#overview)**,看看我们已经取得了多大的进展,以及你可以在哪里帮忙! *** ## 为什么要贡献? * **产生影响**:改善全球数千用户的生活。 * **展示你的技能**:通过为广受认可的开源项目做贡献来建立你的作品集。 * **学习和成长**:与热情的社区合作,提升你的技术专长。 * **成为社区的一员**:加入全球开发者与智能家居爱好者的网络。 *** ## 你如何帮忙 我们欢迎各种形式的贡献!以下是一些你可以参与的方式: * **加入 [beta](https://play.google.com/apps/testing/io.homeassistant.companion.android)**:帮助我们在问题进入生产环境之前发现它们。 * **代码贡献**:修复 bug、添加功能或改进性能。 * **代码审查**:通过审查他人的工作并提供建设性反馈来帮助他们。 * **文档**:保持我们的指南清晰、简洁且最新。 * **测试**:确保应用在各种设备上完美运行。 * **反馈**:分享你的想法和建议,让应用变得更好。 *** ## 准备好开始了吗? 1. **[查看我们的入门指南](/developers/android/get_started.md)**,获取逐步说明。 2. **[加入我们的 Discord 社区](https://www.home-assistant.io/jjoin-chat)**,确保选择开发者角色,然后前往 **[Android](https://discord.com/channels/330944238910963714/1346948551892009101)** 项目线程与其他贡献者联系。 让我们一起创造非凡的事物。让我们一起构建智能家居的未来,一次一个贡献! --- url: /developers/android/app_flavors.md --- :::info 只有 `:app` 和 `:automotive` 模块受这些 flavors 影响。 ::: ## 概述 Android 应用构建了两个 flavor:`full` 和 `minimal`。这些 flavor 使我们能够迎合不同的用户偏好。本文档解释了 flavor 之间的区别、它们的功能以及实现它们背后的原因。 ## App 变体 ### 共享代码 我们尽量将所有内容都放在 flavor 无关的 `main` source set 中,以便所有人都能受益于新功能。只要有可能,我们总是优先选择开源方案。 ### 完整变体 `full` flavor 使用 **Google Play Services**,启用以下功能: * 位置跟踪 * Push 通知 * 与 Wear OS 设备通信 该 flavor 通过 Google Play Store 分发。 ### 精简变体 `minimal` flavor 旨在为偏好或需要无 **Google Play Services** 应用的场景设计。它具有以下限制: * ❌ 不支持 [存在检测](https://www.home-assistant.io/getting-started/presence-detection/#adding-zone-presence-detection-with-a-mobile-phone) 的位置跟踪 * ❌ 不支持 push 通知(除通过 WebSocket 使用 [本地通知](https://companion.home-assistant.io/docs/notifications/notification-local#requirements) 外) * ❌ 不支持与 Wear OS 设备通信 * ❌ 不支持崩溃报告 尽管有这些限制,`minimal` flavor 使我们能够向更广泛的受众提供应用,包括没有 Google Play Services 的设备用户。如果找到了可行的替代 Google Play Services 功能的开源方案,可能会考虑将其纳入 `minimal` flavor 以移除这些限制。 该 flavor 被用于以下场景: * 手动下载 APK 或通过 F-Droid 获取。 * Meta Quest 设备。 * OEM 的 Automotive 构建。 --- url: /developers/android/architecture/frontend_screen.md --- Frontend screen 是 [UI 架构](/developers/android/architecture/ui_architecture.md) 的参考实现,也是应用中最复杂的 screen。它在 [WebView](https://developer.android.com/reference/android/webkit/WebView) 内渲染 Home Assistant frontend,并包装了原生功能(身份验证、手势、下载、NFC、Matter/Thread、媒体播放等)。它的输入(用户、WebView、[external bus](/developers/frontend/external-bus.md)、系统回调、超时)正是该模式所针对的"许多并发源"。代码位于 [`frontend/`](https://github.com/home-assistant/android/tree/main/app/src/main/kotlin/io/homeassistant/companion/android/frontend) 包中。 依赖图遵循该模式的层级。在运行时,结果通过每层暴露的 flow 向上流回:manager 推送 screen 渲染的待处理状态,handler 推送 ViewModel 归约的结果,repository 发射 handler 消费的 typed 消息。 ```mermaid flowchart TB subgraph nav["Navigation"] Nav["frontendScreen() NavGraphBuilder"] EventHandler["FrontendEventHandler"] end subgraph viewl["View (Compose)"] Screen["FrontendScreen
(持有 WebView)"] end subgraph vml["Screen 协调"] VM["FrontendViewModel
viewState · events · webViewActions"] end subgraph handlers["Handler"] Handlers["FrontendMessageHandler · FrontendMatterThreadHandler · FrontendHttpAuthHandler · ..."] end subgraph managers["Manager"] Managers["Permission · Dialog · FileChooser · Gesture · EntityAddTo · Url · Download · ExoPlayer · ..."] end subgraph repos["Repository"] Repos["FrontendExternalBusRepository · ServerSessionManager · PrefsRepository · ..."] end Nav --> Screen Nav --> EventHandler Screen --> VM VM --> Handlers VM --> Managers VM --> Repos Handlers --> Managers Handlers --> Repos Managers --> Repos ``` ## 概览 | 模式角色 | Frontend 实现 | |---|---| | 导航 + 事件消费 | `frontendScreen()`、`FrontendEventHandler` | | View | `FrontendScreen` / `FrontendScreenContent` | | ViewModel | `FrontendViewModel` | | 状态 | `FrontendViewState` | | 事件 | `FrontendEvent` | | 动作 | `WebViewAction` | | 提示 | 带 `FrontendDialog`、`PermissionRequest`、`FileChooserRequest` 的 `SingleSlotQueue` | | Handler | `FrontendMessageHandler`、`FrontendMatterThreadHandler`、`FrontendHttpAuthHandler` 等 | | Manager | `PermissionManager`、`FrontendDialogManager`、`FileChooserManager`、`FrontendUrlManager`、`FrontendDownloadManager`、`FrontendExoPlayerManager`、`FrontendGestureManager`、`FrontendEntityAddToManager` 等 | | Repository | `FrontendExternalBusRepository`、`ServerSessionManager` | ## 状态生命周期与叠加层 `FrontendScreen` 总是在底层渲染 WebView,然后在上面绘制一个叠加层,由当前的 `FrontendViewState` 决定(对 sealed 状态进行 `when`)。WebView 在底层保持挂载状态,因此在叠加层变化时它保留已加载的页面。 | `FrontendViewState` | WebView 之上的叠加层 | |---|---| | `LoadServer`、`Loading` | 加载指示器 | | `Content` | 无,WebView 显示出来 | | `SecurityLevelRequired` | 安全级别配置 screen | | `Insecure` | "不安全连接"阻塞 screen | | `Error` | 连接错误 screen | ViewModel 将 URL 解析、页面加载回调、超时和用户重试归约为这些状态之间的转换: ```mermaid stateDiagram-v2 [*] --> LoadServer LoadServer --> Loading: URL 已解析 LoadServer --> Insecure: HTTP 被阻止 LoadServer --> SecurityLevelRequired: 未设置偏好 LoadServer --> Error: 未找到 / 未连接 Loading --> Content: 页面完成 Loading --> Error: 加载超时 / 错误 Content --> Error: 加载错误 Error --> LoadServer: 重试 Insecure --> LoadServer: 重试 SecurityLevelRequired --> LoadServer: 偏好已选择 ``` `LoadServer` 是入口点(它还会在下一次 URL 解析时清空 WebView)。切换服务器会从任何状态以新的 server id 重新进入 `LoadServer`。一个终止用例:携带 `FrontendConnectionError.UnrecoverableError` 的 `Error`(例如,系统的 WebView 初始化失败)无法重试,ViewModel 会忽略任何进一步离开它的转换。 ## 错误处理 连接错误 UI 与 onboarding 共享,因此它不能依赖 `FrontendViewModel`。相反,它依赖一个窄能力接口 `FrontendConnectionErrorStateProvider`,只暴露错误 screen 所需的内容: ```kotlin interface FrontendConnectionErrorStateProvider { val urlFlow: StateFlow val errorFlow: StateFlow val connectivityCheckState: StateFlow fun runConnectivityChecks() } ``` `FrontendConnectionErrorScreen` 基于此接口编写,`FrontendViewModel` 实现了它,因此错误叠加层直接将 ViewModel 作为其 provider。`FrontendConnectionErrorStateProvider.noOp` 用于驱动预览和测试。 这是跨 screen 复用 UI 或逻辑而不将其耦合到具体 ViewModel 的通用技巧:为可复用部分所需的精确内容定义一个小接口,并让每个 ViewModel 实现它。依赖关系随后指向接口,而不是某个具体的 ViewModel。 ## WebView `FrontendScreen` 通过可复用的 `HAWebView` composable 挂载 WebView,它在 `AndroidView` 内部创建平台的 `WebView`,应用基线设置,在 nav host 之前将返回按钮路由到 WebView 的历史记录,在预览和截图测试下显示占位符,并报告创建失败(ViewModel 会将其转换为不可恢复的 `Error` 状态)。`FrontendScreen` 然后在上面叠加 frontend 特定配置:它附加了下面两个 client,并连接了 cookie、下载和手势监听器。 两个 client 都由 ViewModel 创建: * `HAWebViewClient` 由 `HAWebViewClientFactory` 构建。它拥有 TLS 客户端证书身份验证,将加载/SSL 错误映射到 `FrontendConnectionError`,报告页面完成、暴露 HTTP Basic-auth 挑战,并从渲染进程崩溃中恢复。 * `HAWebChromeClient` 由 `viewModel.createWebChromeClient(...)` 构建。它处理运行时权限请求(摄像头/麦克风)、JavaScript `confirm()` 对话框、文件选择器和全屏 custom-view 移交。 :::note 故意的例外 ViewModel 通常不引用任何平台 UI 类型。WebView client 是被接受的唯一例外:它们必须与 ViewModel 逻辑(错误映射、页面加载回调、HTTP auth、权限)连接,因此 ViewModel 构建并拥有它们。这不损害单元测试能力:client 来自一个测试可以伪造的工厂,而 chrome client 只有在 screen 请求时才构建,因此 ViewModel 的归约逻辑仍然可以作为纯 JVM 单元测试运行。 ::: ## Frontend ↔ 原生通信 Frontend(JavaScript)和原生代码通过 JavaScript bridge 进行通信。这就是驱动 [external authentication](/developers/frontend/external-authentication.md) 和 [external bus](/developers/frontend/external-bus.md) 消息传递的基础。`FrontendScreen` 是唯一持有 WebView 的地方;它下面的所有代码都保持 UI 无关,并通过 `Flow` 通信。 ```mermaid flowchart TB subgraph ui["UI (Compose)"] JS["Home Assistant frontend (JS)
window.externalApp / externalAppV2
window.externalBus"] Screen["FrontendScreen
(承载 WebView)"] VM["FrontendViewModel"] end subgraph bridge["Bridge"] JsBridge["FrontendJsBridge
(FrontendJsCallback)"] Handler["FrontendMessageHandler
(FrontendJsHandler + FrontendBusObserver)"] end subgraph data["Data"] BusRepo["FrontendExternalBusRepository"] SessionMgr["ServerSessionManager"] end Screen -->|"attachToWebView() / loadUrl()"| JS Screen -->|"在 WebView 上运行 WebViewAction"| JS VM -->|"创建 bridge,暴露 frontendJsCallback"| JsBridge VM -->|"webViewActions / messageResults"| Screen JS -->|"getExternalAuth / revokeExternalAuth / externalBus"| JsBridge JsBridge -->|"BridgeMessage → FrontendJsHandler"| Handler Handler -->|"onMessageReceived() / send()"| BusRepo BusRepo -->|"incomingMessages()"| Handler Handler -->|"getExternalAuth() / revokeExternalAuth()"| SessionMgr SessionMgr -->|"ExternalAuthResult / RevokeAuthResult"| Handler BusRepo -->|"webViewActions() (Flow)"| VM Handler -->|"messageResults() (Flow)"| VM ``` `FrontendJsBridge` 是注册到 WebView 的 JavaScript 接口。它接收来自 frontend 的原始调用,将其解析为类型化的 `BridgeMessage` 变体,并将其分派给 `FrontendMessageHandler`。`FrontendExternalBusRepository` 拥有类型化的、双向的 bus 通道:传入的 JSON 被反序列化为 `IncomingExternalBusMessage`(以向前兼容的方式处理未知类型),而传出的 `OutgoingExternalBusMessage` 被序列化为排队的 `WebViewAction.EvaluateScript`。 消息流程通过 `Flow` 与 WebView 解耦。ViewModel 和下层从不直接调用 WebView API;它们发射只有 `FrontendScreen` 运行的 `WebViewAction`: * 入站(frontend → 原生):frontend 调用 bridge(`externalBus`)→ `FrontendJsBridge` 解析 `BridgeMessage` 并分派它 → `FrontendMessageHandler` 将其交给 `FrontendExternalBusRepository.onMessageReceived()` → repository 反序列化并在 `incomingMessages()` 上发射 → handler 通过 `messageResults()` 将其映射为 `FrontendHandlerEvent` → ViewModel 将其归约为状态、事件或动作。 * 出站(原生 → frontend):组件使用类型化的 `OutgoingExternalBusMessage` 调用 `FrontendExternalBusRepository.send()` → 它被序列化为包裹在 `WebViewAction.EvaluateScript` 中的 `externalBus(...)` 脚本 → 通过 `webViewActions()` 暴露 → `FrontendScreen` 在 WebView 中执行它,调用 `window.externalBus`。 * 身份验证(单独的通道):frontend 调用 `getExternalAuth`/`revokeExternalAuth` → handler 询问 `ServerSessionManager` → 生成的回调脚本在 WebView 中执行,调用已验证的 frontend 回调(`externalAuthSetToken`/`externalAuthRevokeToken`)。 动作和事件 flow 是缓冲的 `SharedFlow`,因此在 WebView 暂时不可用时不会丢弃命令。 `FrontendJsBridge` 根据服务器版本注册两个协议之一: * V1(`window.externalApp`):通过 [`WebView.addJavascriptInterface`](https://developer.android.com/reference/android/webkit/WebView#addJavascriptInterface\(java.lang.Object,%20java.lang.String\)) 的遗留协议;frontend 直接调用命名方法。 * V2(`window.externalAppV2`):在 Home Assistant 2026.4.2 中通过 [`WebViewCompat.addWebMessageListener`](https://developer.android.com/reference/androidx/webkit/WebViewCompat) 引入;所有消息都作为带有 `type` 判别器的 JSON envelope 通过 `postMessage` 传递,带有 origin 和 iframe 过滤以实现安全性。 当服务器支持 V2 且设备的 WebView 支持 [`WEB_MESSAGE_LISTENER`](https://developer.android.com/reference/androidx/webkit/WebViewFeature#WEB_MESSAGE_LISTENER) 特性时,应用选择 V2;否则回退到 V1。 ## 依赖注入与作用域 Per-session 的 block 是 `@ViewModelScoped`,因此每个 `FrontendViewModel` 获得新的实例,而一个 screen 会话内的每个消费者共享它们。这包括 `FrontendExternalBusRepository`:bus 只对一个 screen 的 WebView 存在,因此将其作用域设置为会话可防止一个访问的缓冲消息泄漏到下一个。`FrontendHandlerModule` 在 `ViewModelComponent` 中将 `FrontendMessageHandler` 绑定到 `FrontendJsHandler` 和 `FrontendBusObserver`。 ## 测试 Frontend screen | 层 | 测试类型 | 关注点 | |---|---|---| | `FrontendViewModel` | 单元(JUnit5 + Turbine) | 归约逻辑:哪个输入产生哪个状态 / 事件 / 动作。 | | Manager 和 handler | 单元 | 每个关注点隔离;断言返回的 sealed 结果或发射的待处理状态。 | | `FrontendScreenContent` | Compose UI | 每种状态下的渲染,以及交互是否调用了正确的回调。 | | `FrontendEventHandler` | Compose UI | 发射每个 `FrontendEvent` 时是否调用了正确的 host 回调(导航、snackbar 等)。 | | `FrontendScreen` | 截图 | 仅视觉回归(无逻辑)。 | --- url: /developers/android/architecture/overview.md --- ## 介绍 Home Assistant 的 Android 项目始于 2019 年。自那时以来,Android 生态发生了巨大变化,许多贡献者塑造了该项目。因此,你可能会遇到不符合当前最佳实践的陈旧代码。本文档作为应用架构和开发实践的真实来源。 Home Assistant 一直是 [PWA](https://en.wikipedia.org/wiki/Progressive_web_app) 开发领域的领先者,这一理念也体现在原生应用中。应用的核心是一个 [WebView](https://developer.android.com/reference/android/webkit/WebView),它与 Home Assistant 的 frontend 集成。随着时间的推移,原生功能(如后台传感器数据采集)被逐步添加。 ## 核心原则 ### Kotlin 优先 整个代码库使用 [Kotlin](https://kotlinlang.org) 编写,确保现代化、简洁且类型安全的开发。 ### Android 版本支持 * **Target SDK**: 我们力求紧跟最新的 Android SDK 发布,并在新版本发布时对其进行测试。 * **Min SDK**: 为了确保广泛的兼容性,应用支持 Android [Lollipop](https://en.wikipedia.org/wiki/Android_Lollipop)(API 21)。 ## 应用架构 我们遵循 Google 推荐的 [Android 架构](https://developer.android.com/topic/architecture),并从 [NowInAndroid 仓库](https://github.com/android/nowinandroid) 中汲取灵感。单个 screen 如何构建(ViewModel、其输出以及它下面的各个 block)在 [UI 架构](/developers/android/architecture/ui_architecture.md) 中有描述;它适用于每个 screen,而不仅仅是 frontend。 ### 构建逻辑 项目使用多个 Gradle 模块。共享逻辑集中放在一个名为 `build-logic` 的独立 Gradle 项目中,并通过 `includeBuild` 包含在主项目中。 ### 通用 Gradle 模块 为了在不同应用间共享代码,我们使用一个名为 `:common` 的通用 Gradle 模块。 ## UI 开发 ### 原生 UI 所有新的 UI 组件均使用 [Jetpack Compose](https://developer.android.com/compose) 构建,确保采用现代化和声明式的 UI 开发方法。 ### 遗留 UI 应用中仍存在部分遗留的 XML 布局、`databinding` 和 `viewbinding`。这些应作为持续现代化工作的一部分,替换为 Compose。 ### 主题 应用使用多个主题来支持遗留的 XML 和基于 Compose 的 UI。所有新组件应使用 `HomeAssistantAppTheme`,它基于 [Material Design](https://developer.android.com/develop/ui/compose/components)。 ## 关键特性 ### 依赖注入 (DI) 我们广泛使用 [Hilt](https://developer.android.com/training/dependency-injection/hilt-android) 进行依赖注入,确保代码模块化且可测试。 ### 并发 所有并发都使用 [Kotlin Coroutines](https://kotlinlang.org/docs/coroutines-overview.html) 处理,提供了一种结构化且高效的方式来管理异步任务。 ### 服务 我们使用 [Foreground Services](https://developer.android.com/develop/background-work/services/fgs) 异步获取传感器值并将其上传到 Home Assistant Core。 ### WebSocket 应用使用 [OkHttp](https://square.github.io/okhttp/) 维护与 Home Assistant Core WebSocket 的直接连接。这对于 Assist 和实时讨论等功能至关重要。 ### REST API 与 Home Assistant 的 REST API 通信使用 [Retrofit](https://square.github.io/retrofit/) 处理,实现了与后端的无缝交互。 ### 本地存储 * **Room**: 用户数据使用 [Room](https://developer.android.com/training/data-storage/room) 存储在本地,它提供了强大的数据库解决方案。 * **SharedPreferences**: 对于应用特定的设置,我们使用带有名为 `LocalStorage` 抽象层的 [SharedPreferences](https://developer.android.com/reference/android/content/SharedPreferences)。 ### 深度链接 应用使用 `homeassistant://` URL 支持深度链接,以导航到应用的特定部分。更多细节请参阅[用户文档](https://companion.home-assistant.io/docs/integrations/url-handler/)。 ## 平台特定功能 ### 车载 Automotive 应用复用了 `:app` 模块的源代码,简化了开发。 ### Wear OS Wear OS 应用使用 [Messaging API](https://developer.android.com/training/wearables/data/messages) 与移动应用通信,以获取 Home Assistant 服务器的凭据和其他配置。它只与 `full` flavor 一起工作,因为它需要 Google Play Services。一旦初始设置完成,所有进一步的通信都通过 WebSocket 以及为该应用创建的 [webhook](/developers/api/native-app-integration/sending-data.md) 直接与 Home Assistant 进行。 ## Frontend 通信 Home Assistant 的 frontend 渲染在 [WebView](https://developer.android.com/reference/android/webkit/WebView) 内部,应用通过 [external authentication](/developers/frontend/external-authentication.md) 和 [external bus](/developers/frontend/external-bus.md) 与其通信。承载它的 screen、JavaScript bridge、消息流程以及 V1/V2 协议记录在 [Frontend screen](/developers/android/architecture/frontend_screen.md) 中。 --- url: /developers/android/architecture/ui_architecture.md --- 本页描述了 screen 在应用中是如何构建的。它是 [Google 推荐的应用架构](https://developer.android.com/topic/architecture) 的一种类似 MVI 的诠释:同样的 UI、domain 和 data 层,但对 screen 的输入和输出如何流动定义了更严格的契约。新的 UI 应遵循它,现有的 screen 随时间逐步迁移到它。[Frontend screen](/developers/android/architecture/frontend_screen.md) 是参考实现。 ## 该模式 一个 screen 通常有很多并发的输入源:用户、系统回调(权限、文件选择器)、计时器以及外部通道。该模式将它们全部归约为少数几个定义良好的输出,使 screen 保持可预测且可测试。 它也是保持 screen 可维护性的关键。应用拥有许多功能,单个 screen 可能会引入大量功能。如果没有结构,会导致 screen 类或 ViewModel 知道一切,且无法安全地进行测试或更改。相反,每个关注点都存在于自己独立的、职责单一的小 block 中(参见[构建模块](#building-blocks)),因此随着 screen 的增长,它仍然易于处理。 ### 单向数据流 输入(用户交互、回调、外部消息、系统结果)向下进入 ViewModel,ViewModel 将工作委托给下面的各个 block,并将它们的结果归约为向上传输回各 channel: * 单一状态:要渲染什么; * 一次性事件:导航和其他 fire-and-forget 副作用; * 动作:针对由 view 拥有的对象的命令式操作。 给定的输入只产生它需要的输出,通常只是一个新状态,有时一个都没有。动作仅存在于 view 拥有命令式对象(如 `WebView`)的 screen 中;大多数 screen 不需要它们(参见[动作](#actions))。 ```mermaid flowchart LR View -->|"user interactions · callbacks"| ViewModel ViewModel -->|"state · events · actions"| View ViewModel -->|"delegates to"| Blocks["Handlers · Managers · Use cases · Repositories"] Blocks -->|"results · flows"| ViewModel ``` ### 构建模块 每个 block 都有单一职责和与邻居通信的明确方式。 #### View 视图 Compose screen。它根据当前状态进行渲染,持有下层绝不能触碰的任何 UI handle(如 `WebView`、列表的滚动状态等),运行针对这些 handle 排队的[动作](#actions),观察 manager 暴露的待处理状态,并通过回调将用户交互报告回 ViewModel。 将其拆分为有状态的入口点和无状态的内容 composable,以便预览和 Compose 测试可以直接驱动它: ```kotlin @Composable internal fun SettingsScreen(viewModel: SettingsViewModel) { val viewState by viewModel.viewState.collectAsStateWithLifecycle() SettingsScreenContent( viewState = viewState, onNameChange = viewModel::onNameChange, ) } @Composable internal fun SettingsScreenContent(viewState: SettingsViewState, onNameChange: (String) -> Unit) { // 无状态:渲染 viewState 并通过回调报告交互。 } ``` #### ViewModel 视图模型 ViewModel 拥有 screen 的输出 channel,并将下面的各个 block 连接在一起:它将每个输入归约为一个新状态、一个一次性事件或一个排队的动作。典型的形态: ```kotlin val viewState: StateFlow // 要渲染什么 val events: SharedFlow // 一次性副作用 val actions: Flow // 仅在 view 拥有命令式 handle 时 ``` 重新发射相同状态必须是空操作(no-op):归约可能产生一个与当前值相等的值,这绝不能触发工作或渲染。`StateFlow` 通过跳过等于当前值的发射来保证这一点,这也是状态类必须实现结构相等的原因(data class 即可)。 它从不引用 Compose 或平台 UI 类型,因此其逻辑可以作为纯 JVM 单元测试运行。它还会比配置变更更长寿:只有当 screen 永久消失时,`viewModelScope` 才会被取消,因此旋转不会取消并重新启动加载或 flow 收集等长时间运行的工作。 保持其瘦小。小 screen 的 ViewModel 可以直接持有其功能逻辑。随着 screen 的增长,将内聚的逻辑提取到[下面的 block](#blocks) 中,而不是让 ViewModel 混合无关的关注点。它自身的工作是协调:拥有 channel 并路由输入,而不是每个功能的内部实现。 ##### 状态 用于描述渲染什么内容的单一真实来源。ViewModel 将其保存在 `StateFlow` 中。 状态类必须是不可变的:使用 `val` 属性和不可变集合,并为每次更改生成一个新实例(通过 `copy()`)。就地突变会破坏 Compose 的变更检测和单向流。 状态还必须易于读取。Compose 在重组期间在主线程上读取它,因此不要暴露一个计算任何内容的 `get()`(排序、过滤、格式化):它会在每次重组时再次运行。请在创建状态时预先计算这样的值,可以在 ViewModel 或它下面的 block 中完成,这样工作可以在后台 dispatcher 上运行: ```kotlin // 错误:在主线程上、每次重组时构建下拉项 data class UiState(val servers: List) { val serverItems: List> get() = servers.map { HADropdownItem(key = it.id, label = it.friendlyName) } } // 正确:在创建状态时映射一次 data class UiState(val serverItems: List>) ``` 按照 screen 的形状来设计: * 当 screen 始终具有相同的形状且只有其字段发生变化时,使用一个 data class; * 当 screen 具有真正不同的模式时使用 sealed 层级,例如: ```kotlin sealed interface UiState { data object Loading : UiState data class Content(val items: List) : UiState data class Error(val error: ErrorReason) : UiState } ``` 对于 sealed 层级,编译器强制要求穷尽处理,而且一种模式的字段不会泄漏到另一种模式中,这与扁平模型不同,扁平模型的 nullable 字段和布尔值可以表达不可能的组合。 ##### 事件 一次性、fire-and-forget 的效果:导航、显示 snackbar、打开链接。将它们建模为 sealed interface(当变体共享字段时也可以是 sealed class),这样效果的集合就是封闭的,事件处理程序的 `when` 就是穷尽的;编译器会标记任何未处理的事件: ```kotlin sealed interface UiEvent { data object NavigateBack : UiEvent data class ShowSnackbar(@StringRes val messageResId: Int) : UiEvent data class OpenExternalLink(val uri: Uri) : UiEvent } ``` 在 `Flow` 上发射它们,并精确地消费每个事件一次,通常在导航层,该层持有导航控制器和 host 回调。事件绝不能被持久化或重放:在重组时重放一个 "navigate" 会导致导航两次。如果 UI 必须在配置变更后再次显示它,那么它就是状态,而不是事件。 ##### 动作 某些命令式对象必须存在于 view 中,因为 UI 框架在组合内部创建了它们:一个 `WebView`、一个 `LazyListState`、一个 focus requester。ViewModel 绝不能持有对其中一个的引用,那会使其与平台 UI 类型绑定并破坏其单元测试能力。然而,对它们的一些操作确实是命令式的("立即重新加载"、"滚动到顶部"、"执行此脚本"),无法表示为声明式状态。 动作队列解决了这种张力:ViewModel 将类型化的动作发射到一个 `Flow` 上,view 收集它并在自己拥有的 handle 上运行它。与事件一样,将动作建模为 sealed interface,使命令的集合是封闭的,每个变体都携带自己针对该 handle 的 `run`: ```kotlin sealed interface WebViewAction { fun run(webView: WebView) data object Reload : WebViewAction { override fun run(webView: WebView) = webView.reload() } data class EvaluateScript(val script: String) : WebViewAction { override fun run(webView: WebView) { webView.evaluateJavascript(script, null) } } } // 在 view 中,唯一持有 WebView 的地方: LaunchedEffect(webView) { webViewActions.collect { action -> action.run(webView) } } ``` 可等待的变体携带一个 `CompletableDeferred`,以便调用者可以等待结果,例如脚本的返回值。 该 flow 是一个一次性消费的 `SharedFlow`,经过缓冲,以便在 view 暂时不可用时不会丢弃命令。它被刻意地不作状态处理:作为状态持有的命令会在每次重组时重新运行。它也不是事件:事件是 host 做出反应的信号(导航、snackbar),而动作驱动该 screen 拥有的特定对象。 将动作保留给必须存在于 view 中的对象。下层可以拥有的任何东西都应在那里拥有:例如,媒体播放器由 manager 持有,并通过状态暴露,不涉及动作队列。在实践中,一个 screen 最多拥有一个这样的 handle,通常一个都没有。 #### Block 构建块 ViewModel 将功能逻辑委托给四种 block。它们共同构成了 screen 的 domain 和 data 层。 ##### Handler 处理器 Handler 是从 ViewModel 中提取出来的、使用一个或多个 manager 的逻辑。协调就发生在这里:ViewModel 应保持瘦小,而 manager 绝不能依赖另一个 manager。Handler 可以是一次性的翻译器(将一个输入映射到类型化的结果),也可以是跨异步往返驱动几个 manager 的多步骤流程;它可以是无状态的,或者持有瞬时的 flow 状态。这些都不是定义它的要素:依赖 manager 才是。 它将自己的工作作为 sealed 结果(拉取)或结果流(推送)交回给 ViewModel。它可以保持自己 feature 范围内的状态,ViewModel 将其映射到 screen 状态中。screen 的单一状态始终属于 ViewModel,而非 handler。 ##### Manager 管理器 Manager 拥有恰好一个功能关注点的逻辑和内存状态。它只依赖于 repository、use case 和平台 API,绝不依赖于另一个 manager。如果它需要一个,那么这种协调是[handler](#handlers) 的工作。它以一种或多种以下方式与 ViewModel 和 view 通信: * 推送待处理状态:暴露一个 `StateFlow`,view 观察并渲染它; * 拉取结果:一个 `suspend` 函数,返回 ViewModel 处理的 sealed 结果; * 拉取流:一个 `Flow` 结果流,ViewModel 收集它。 Manager 也是用户提示存在的地方:必须显示 UI 并等待用户答案的交互,例如对话框、权限请求或文件选择器。对于这些,请使用 `SingleSlotQueue`,当一次只能有一个提示在屏幕上时它会进行序列化。队列本身是当前请求的 `StateFlow`(它通过委托实现该接口),因此 manager 将其作为待处理状态暴露给 view 渲染,而 `awaitResult { onResult -> ... }` 会挂起调用者,直到 UI 调用 `onResult`,然后释放该 slot 给下一个请求。提示不是第四个输出 channel:它将渲染的待处理状态与作为常规输入到达的答案组合起来,而 `awaitResult` 将该往返折叠为一个挂起调用。 ##### Use case 用例 Use case 是单个可复用的操作,无状态,以其执行的动作命名,并暴露为简单的方法或 `operator fun invoke(...)`: ```kotlin class CheckLocalNetworkPermissionUseCase @Inject constructor( private val serverManager: ServerManager, ... ) { suspend operator fun invoke() { ... } } ``` 当某段逻辑被多于一个调用者需要,或者会让 ViewModel 或 manager 变得臃肿,但它自身没有状态时,就选择它。Use case 可以依赖 repository,但绝不能依赖 manager 或 handler。代码库中的示例:`CheckLocalNetworkPermissionUseCase`、`ServerChooserItemsUseCase`。 ##### Repository 仓库 Repository 是某个数据源或通信通道的单一真实来源,抽象化数据所在的位置(存储、网络、外部通道)。它没有 UI 关注点。数据库访问也通过 repository 进行,repository 通过其 DAO 与 [Room](https://developer.android.com/training/data-storage/room) 数据库通信:DAO 是数据源,repository 是应用的其余部分看到的抽象。 Repository 不应依赖另一个 repository:合并多个数据源是逻辑,而逻辑存在于 use case、manager 或 handler 中。 ### 层与依赖规则 这些 block 映射到 [Google 推荐架构](https://developer.android.com/topic/architecture) 的层:view 和 ViewModel 是 UI 层,handler、manager 和 use case 构成 domain 层,repository 是 data 层。依赖只能向下指向,因此图在结构上就是无环的: ```mermaid flowchart TB subgraph ui["UI 层"] direction TB Screen["Compose screen + view 拥有的 handle"] VM["ViewModel
拥有 state · events · actions"] end subgraph domain["Domain 层"] Handlers["Handler
使用 manager"] Managers["Manager
拥有一个功能关注点"] UseCases["Use case
单个无状态操作"] end subgraph data["Data 层"] Repos["Repository"] end Screen --> VM VM --> Handlers VM --> Managers VM --> UseCases VM --> Repos Handlers --> Managers Handlers --> UseCases Handlers --> Repos Managers --> UseCases Managers --> Repos UseCases --> Repos ``` 每一条边都向下指向。在运行时,数据通过每一层暴露的 flow 以状态、事件和动作的形式向上流回。 * 一条规则决定层级。Manager 只依赖 repository、use case 和平台 API;handler 是任何依赖 manager 的东西。一个需要另一个 manager 的 manager,按此定义就是一个 handler,因此 `manager → manager` 不可能发生。 * 只能向下。没有 `handler → handler`(在 ViewModel 中协调 handler),没有 `repository → repository`(在 use case、manager 或 handler 中合并数据源),也没有向上的边(use case 或 manager 绝不依赖 handler)。 * ViewModel 可以直接访问任何层。当逻辑较小时,它直接使用 manager、use case 或 repository;只有当跨 manager 的协调会使其变得臃肿时,它才提取 handler(参见 [ViewModel](#viewmodel))。 这使得每个 block 都能独立测试,并防止隐藏的循环。 #### 作用域 根据状态必须存活的时间长短为每个 block 设置作用域。与一个 screen 绑定的 block 是 `@ViewModelScoped`:每个 screen 会话一个共享实例,因此注入它的所有代码都看到相同的状态,而且该状态在会话结束时重置。代表应用级关注点的 repository 或 manager 通常是 `@Singleton`。 共享实例部分对于任何被多处依赖的有状态 block 都很重要。如果 ViewModel 和 handler 都注入了它,它们必须获得相同的对象,否则它们对状态的视图会分叉;无作用域的绑定会给每个消费者一个独立的副本。 :::note 通过 Hilt 提供所有东西。永远不要手动实例化这些 block。 ::: ### 选择输出 询问输出是什么,而不是它在哪里产生: | 如果输出... | 使用 | 原因 | |---|---|---| | 决定了要渲染什么内容,并且必须在重组/旋转后存活 | [状态](#state) | 持久的 UI;重新发射相同值必须是空操作 | | 是一次性副作用,必须恰好触发一次且不能被重放 | [事件](#events) | 重放它(例如在重组时)会导致双重导航或双重 toast | | 是针对 view 拥有 handle 的命令式操作 | [动作](#actions) | ViewModel 保持 UI 无关;只有 view 持有该 handle | | 需要提示用户并等待串行化的响应 | [提示](#managers) | 一次一个提示;调用者挂起直到用户回答 | ### 选择构建模块 自上而下地进行;第一行匹配即胜: | 你拥有的是什么 | 选择 | 决定性问题 | |---|---|---| | 对数据源或通信通道的访问 | [Repository](#repositories) | "某些数据/IO 的单一真实来源?" | | 单个可复用操作,自身无状态 | [Use case](#use-cases) | "一个无状态操作?" | | 一个功能的关注点,带有自己的内存状态 | [Manager](#managers) | "它是否只依赖 repository 和 use case?" | | 协调一个或多个 manager 的逻辑 | [Handler](#handlers) | "它是否依赖 manager?" | | 组合功能并拥有屏幕上显示的内容 | [ViewModel](#viewmodel) | "screen 级状态或协调?" | Handler vs manager 归结为一个问题:它是否依赖 manager?不要去找 "无状态 vs 有状态" 或 "翻译 vs 协调",handler 可以是其中任何一种。依赖关系就是全部测试,也是使 `manager → manager` 从结构上不可能的原因。 有状态性影响的是作用域:有状态的 block 必须设置作用域,使其状态具有正确的生命周期,并使每个消费者共享一个实例(参见 [作用域](#scoping))。 命名遵循 block:`*Repository`、`*UseCase`、`*Manager`、`*Handler`。 ### 测试 这种分离使 screen 变得可测试: | 层 | 测试类型 | 关注点 | |---|---|---| | ViewModel | 单元 | 归约逻辑:哪个输入产生哪个状态 / 事件 / 动作。 | | Handler、manager、use case | 单元 | 每个关注点隔离;断言返回的 sealed 结果或发射的待处理状态。 | | 无状态的 screen 内容 | Compose UI | 每种状态下的渲染,以及交互是否调用了正确的回调。 | | 事件处理程序 | Compose UI | 每个事件在发射时是否触发了正确的导航 / 副作用。 | | Screen | 截图 | 仅视觉回归(无逻辑)。 | ViewModel 及其下面的每个 block 都不包含 Compose 和平台 UI 类型,这就是它们可以作为普通 JVM 单元测试运行的原因。关于项目的约定,请参阅[测试概述](/developers/android/testing/introduction.md)、[单元测试](/developers/android/testing/unit_testing.md)和[截图测试](/developers/android/testing/screenshot_testing.md)。 --- url: /developers/android/best_practices.md --- ## 通用原则 总体而言,我们应当遵循标准开发原则,例如: * **SOLID**: 单一职责、开闭原则、里氏替换、接口隔离、依赖倒置。了解更多请参阅 [Kotlin SOLID Principles Examples](https://medium.com/huawei-developers/kotlin-solid-principles-tutorial-examples-192bf8c049dd) * **KISS**: Keep It Simple, Stupid。 * **DRY**: Don't Repeat Yourself * **社区指南**: 遵循 [NowInAndroid](https://github.com/android/nowinandroid) 仓库中展示的实践。 * **保持直接**: 不要为了单个实现或假设性的未来需求而引入抽象。直接使用经过验证的库或 API,只有在出现第二个真实用例时才进行抽象,或者用于隐藏某模块内部的实现细节(例如,在 `common` 中定义一个 public 接口,其 `internal` 实现通过 DI 绑定)。同样,不要存储那些可以从现有状态推导出的值。 * **先找根因再修复**: Bug 修复应说明实际原因以及如何复现。避免用猜测性的变通方法去修补症状。 ## 文档 代码中的文档应当具有价值,并随代码库一起演进。请注意以下几点: * **保持更新**: 文档必须随代码变更而更新。 * **平衡注释**: 避免过度注释,但也不要忘记在必要时添加注释。 * **面向未来**: 问自己,*“6 个月后我还看得懂自己做过的东西吗?”* :::info 文档应该提供帮助,而不是造成阻碍。 ::: ## 日志记录 日志记录至关重要,但应谨慎使用。正如 Jake Wharton 在他的 [Timber](https://github.com/JakeWharton/timber) 库中所说: > 每次在生产环境中记录一条日志,就有一只小狗死去。 * 避免在生产环境中过度记录日志。 * 使用结构化、有意义的日志消息。 * 借助 Timber 等工具有效管理日志记录。 ## 时间与时长 在处理时间、日期或时长时,避免使用基本类型。取而代之,应使用强类型以避免单位混淆。 :::note\[示例] #### ❌ 不要这样做 ```kotlin const val THRESHOLD = 600000 fun main() { val now = System.currentTimeMillis() if (now > THRESHOLD) { // 执行某操作 } } ``` #### ✅ 应该这样做 ```kotlin val THRESHOLD = Instant.ofEpochSecond(60) fun main() { val now = Instant.now() if (now > THRESHOLD) { // 执行某操作 } } ``` ::: :::warning 如果必须使用基本类型,请确保变量名中包含单位(例如,使用 `THRESHOLD_MS` 而非 `THRESHOLD`),以减少歧义。 ::: * 对日期、时长和时间戳应用同样的逻辑。 * 对于使用 `long` 表示时间戳的 API(例如,毫秒与秒的区别),应尽快将值转换为强类型,以尽量减少暴露于无类型单位的风险。 ## 并发 并发功能强大,但需要谨慎处理,以避免内存泄漏和竞态条件等问题。 ### Coroutine 作用域 将你的协程绑定到 Android 生命周期(例如,`viewModelScope` 或 `lifecycleScope`),以防止内存泄漏。 ### 并发访问 * 确保在协程外部访问的任何引用都是线程安全的。 * 如果某个引用不安全,要么使其安全,要么不要使用它。 * 调试并发问题(例如,竞态条件)可能极其困难,因此请仔细设计。 关于竞态条件的更多细节,请参阅 [Race Condition](https://en.wikipedia.org/wiki/Race_condition#In_software)。 ## 使用强类型而非字符串来控制逻辑 字符串应用于存储和显示文本,而不是用于控制代码中的逻辑或行为。依赖字符串来控制逻辑——例如传递一个字符串来决定目标页面或行为——可能会引入拼写错误等错误,并使代码更难以追踪或重构。相反,请使用强类型(例如 `sealed` 类,或在必要时使用 `enum`)来表示这些概念。将字符串保留用于第三方来源的原始值或 UI 显示。如果必须使用字符串,请将其定义为 `const val`(遵循我们的 [编码风格](/developers/android/codestyle.md#avoid-magic-numbers-and-strings)),或将其包装在强类型中,例如 [inline value class](https://kotlinlang.org/docs/inline-classes.html)。 :::note\[示例] #### ❌ 避免这种模式 ```kotlin fun newInstance(destination: String): Intent { // 基于字符串值的逻辑 return Intent().apply { putExtra("destination", destination) } } ``` #### ✅ 优先采用这种方案 ```kotlin private const val DESTINATION_KEY = "destination" @Parcelize sealed interface Destination : Parcelable { data object General : Destination data object Notifications : Destination data object Privacy : Destination } fun newInstance(destination: Destination): Intent { return Intent().apply { putExtra(DESTINATION_KEY, destination) } } fun onIntent(intent: Intent) { val destination = IntentCompat.getParcelableExtra(intent, DESTINATION_KEY, Destination::class.java) when (destination) { Destination.General -> // 处理 General Destination.Notifications -> // 处理 Notifications Destination.Privacy -> // 处理 Privacy null -> // 处理缺失的 destination } } ``` ::: 对目标页面使用强类型有助于防止错误、改善代码导航,并使重构更加可靠。使用 `sealed` 类配合 `when` 时,编译器可以捕获缺失的分支,IDE 也能快速定位某个特定目标的所有用法,从而使更新和维护更加轻松。 ### 为什么 sealed 类比 enum 更好 Sealed 类比 enum 提供了更大的灵活性和安全性。使用 sealed 类,你可以定义带有自己属性的子类,从而为每种类型传递所需的数据。这使得你的 API 更具表达力和适应性。 例如,如果 `Notifications` 目标需要一个 `title` 参数,可以这样定义: ```kotlin private const val DESTINATION_KEY = "destination" @Parcelize sealed interface Destination : Parcelable { data object General : Destination data class Notifications(val title: String) : Destination data object Privacy : Destination } fun onIntent(intent: Intent) { val destination = IntentCompat.getParcelableExtra(intent, DESTINATION_KEY, Destination::class.java) when (destination) { Destination.General -> // 处理 General is Destination.Notifications -> { val title = destination.title // 使用 title 处理 Notifications } Destination.Privacy -> // 处理 Privacy null -> // 处理缺失的 destination } } ``` :::note 当你在 sealed 类上使用 `when` 时,请避免添加 `else` 分支。这样可以确保当你新增一个分支时,编译器会要求你处理它,使代码更安全、更易于维护。 ::: 通过使用 sealed 类,你可以安全地添加带有各自必需字段的新目标类型,编译器会强制要求处理所有分支。这种方法比使用 enum 或字符串来控制逻辑更加健壮、更易维护,且不容易出错。 有关 sealed 修饰符的更多信息,请参阅 [Kotlin 文档](https://kotlinlang.org/docs/sealed-classes.html)。 ## 代码组织 ### 保持类小巧 * 大型类往往承担了过多职责,导致难以审查、测试和维护。 * 目标是小类,并实现适当的关注点分离和抽象。 ### 保持函数小巧且有意义 * 函数应当小巧,专注于单一职责。 * 函数名应清晰描述其功能。如果很难命名,说明该函数可能做了太多事情。 * 命名良好的小函数可以减少文档需求,使代码自解释。 :::note 命名很困难,但更小的函数使你更容易选择有意义的名称。 ::: ## 保持 PR 小巧 * **为什么?** 较小的 PR 更易于审查、减少延迟并降低挫败感。 * **怎么做?** 将大型变更拆分为小而可合并的步骤,使应用在每一步都能正常运行。如果重构的工作太大,无法通过一个小型 PR 一次性完成,请将新路径隐藏在 `WIPFeature` 对象的标志后面,这样你仍可以以小步合并,而用户则继续使用旧路径:在那里添加一个标志(通常仅在 debug 构建中通过 `BuildConfig.DEBUG` 启用),用它在新路径与旧路径之间切换,并在功能完全发布后将其移除。 更多细节请参阅 [submit](/developers/android/submit.md)。 ## 依赖注入 (DI) 我们使用依赖注入 (DI) 来帮助编写模块化、可测试且可维护的代码。通过使用 DI,我们可以将类与其依赖项解耦,从而使切换实现、编写单元测试和管理复杂的对象图变得更加容易。DI 还能提高代码可读性,并帮助执行单一职责原则。 ### 使用显式限定注解而非 `@Named` 当你需要注入同一类型的多个实现(或基本类型)时,必须使用限定符来区分它们。虽然 `@Named` 注解是一种常见方法,但它依赖于字符串标识符,容易出错且难以重构。使用自定义限定注解而非 `@Named` 具有多项优势: * **可发现性**: 自定义限定符使在代码库中查找某个特定依赖项的使用位置更加容易。 * **可重构性**: 重命名自定义注解简单且安全,而修改字符串标识符则需要搜索所有字符串使用位置。 * **类型安全**: 自定义注解在编译时进行检查,减少了字符串出现拼写错误或匹配错误的可能性。 * **清晰性**: 自定义限定符使代码更自解释、更易于理解。 :::note\[示例] #### ❌ 不要这样做 ```kotlin @Inject @Named("keyChainRepository") lateinit var keyChainRepository: KeyChainRepository ``` #### ✅ 应该这样做 ```kotlin @Inject @NamedKeyChain lateinit var keyChainRepository: KeyChainRepository ``` 定义注解如下: ```kotlin package io.homeassistant.companion.android.common.data.keychain import javax.inject.Qualifier /** * [KeyChainRepository] 的限定符,用于选择 key chain。 */ @Qualifier @Retention(AnnotationRetention.RUNTIME) annotation class NamedKeyChain ``` ::: 有关从 `@Named("keyChainRepository")` 迁移到 `@NamedKeyChain` 的真实示例,请参阅 [这个 pull request](https://github.com/home-assistant/android/pull/5667)。 ## 快速失败 (Fail fast) 开发进度越深,调试问题就越困难。不要忽略错误,即使是你认为不太可能发生的错误。始终力求在构建时捕获错误,而不是在运行时。尽可能使用 Kotlin 编译器特性,如果无法在编译时强制进行检查,请考虑添加 [lint 规则](/developers/android/linter.md)。 当同一个问题在审查中反复出现时,请将约定编码到工具中(自定义 [lint 规则](/developers/android/linter.md)、KTLint 覆盖、`FailFast` 检查或测试监听器),而不是依赖每个人记住它。 ### 利用 Kotlin 编译器 Kotlin 编译器可以帮助你尽早发现问题。例如,在 `sealed` 类/接口上使用 `when` 运算符可以确保所有分支都被处理。 :::note 在设计类时,优先考虑[组合优于继承](https://en.wikipedia.org/wiki/Composition_over_inheritance)。组合允许你从更简单、可复用的组件构建复杂行为,而不是依赖于僵化的类层级,从而生成更灵活、更易于维护且更易于测试的代码。 ::: **示例:** ```kotlin sealed interface Shape { class Rectangle: Shape class Oval: Shape } fun foo(shape: Shape) { when(shape) { is Shape.Oval -> TODO() is Shape.Rectangle -> TODO() } } ``` 如果你添加了一个新的实现 `Shape` 的类,编译器将会构建失败,直到你处理该新分支为止。当接口在代码库中被广泛使用时,这一点特别有用。请注意,只有在不添加 `else` 分支时,这种机制才有效。 ### 不要静默忽略异常 虽然捕获异常以防止崩溃很重要,但静默忽略它们可能会掩盖更深层次的问题,并使调试更加困难。例如,考虑一个需要用 API key 进行初始化的第三方库。如果初始化失败且异常被捕获但没有适当记录,那么当某些功能停止工作时,就很难识别根本原因。 **示例:** ```kotlin fun foo() { // 始终捕获错误并继续执行回退值 val value = try { ExternalThirdPartyJavaAPI.value() } catch (e: Exception) { // 幸运的是我们记录了错误以便排查问题 Timber.w(e, "Couldn't get ExternalThirdParty value, current state: ${ExternalThirdPartyJavaAPI.state()}") "fallback" } } ``` 适当的日志记录可确保用户和开发者能够在日志中发现错误,并有效报告问题。 为了进一步改善开发过程中的错误处理,请使用 `FailFast` API。该 API 遵循进攻性编程原则,在发生错误时使 `debug` 风味(flavor)的应用崩溃,从而让问题在开发早期阶段更加可见。 **示例:** ```kotlin import io.homeassistant.companion.android.common.util.FailFast fun foo() { // 如果发生失败,将在日志中打印消息和堆栈跟踪。在 debug 构建中, // 它还会使应用崩溃;而在生产环境中,它将使用回退值而非崩溃。 val value = FailFast.failOnCatch( message = { "Couldn't get ExternalThirdParty value, current state: ${ExternalThirdPartyJavaAPI.state()}" }, fallback = "fallback", ) { ExternalThirdPartyJavaAPI.value() } } ``` 通过快速失败并清晰地记录错误,你可以在问题到达生产环境之前更容易地识别、调试并修复问题。 当 FailFast API 被触发时,它会生成一条清晰可见的日志条目,便于发现和调查: ```log 2025-06-12 10:53:20.841 29743-29743 CrashFailFastHandler io....stant.companion.android.debug E ██████████████████████ 2025-06-12 10:53:20.841 29743-29743 CrashFailFastHandler io....stant.companion.android.debug E !!! CRITICAL FAILURE: FAIL-FAST !!! 2025-06-12 10:53:20.841 29743-29743 CrashFailFastHandler io....stant.companion.android.debug E ██████████████████████ 2025-06-12 10:53:20.841 29743-29743 CrashFailFastHandler io....stant.companion.android.debug E 2025-06-12 10:53:20.841 29743-29743 CrashFailFastHandler io....stant.companion.android.debug E An unrecoverable error has occurred, and the FailFast mechanism 2025-06-12 10:53:20.841 29743-29743 CrashFailFastHandler io....stant.companion.android.debug E has been triggered. The application cannot continue and will now exit. 2025-06-12 10:53:20.841 29743-29743 CrashFailFastHandler io....stant.companion.android.debug E 2025-06-12 10:53:20.841 29743-29743 CrashFailFastHandler io....stant.companion.android.debug E ACTION REQUIRED: This error must be investigated and resolved. 2025-06-12 10:53:20.841 29743-29743 CrashFailFastHandler io....stant.companion.android.debug E Review the accompanying stack trace for details. 2025-06-12 10:53:20.841 29743-29743 CrashFailFastHandler io....stant.companion.android.debug E ---------------------------------------------------------------- 2025-06-12 10:53:20.841 29743-29743 CrashFailFastHandler io....stant.companion.android.debug E 2025-06-12 10:53:20.841 29743-29743 CrashFailFastHandler io....stant.companion.android.debug E 2025-06-12 10:53:20.841 29743-29743 CrashFailFastHandler io....stant.companion.android.debug E io.homeassistant.companion.android.common.util.FailFastException: Couldn't get ExternalThirdParty value, current state: null 2025-06-12 10:53:20.841 29743-29743 CrashFailFastHandler io....stant.companion.android.debug E at io.homeassistant.companion.android.developer.DevPlaygroundActivityKt.DevPlayGroundScreen$lambda$14$lambda$13$lambda$12(DevPlaygroundActivity.kt:80) ``` --- url: /developers/android/ci.md --- ## Android 持续集成与持续交付 本文档概述了 Android 项目的持续集成 (CI) 和持续交付 (CD) 流程。我们使用 **GitHub Actions** 作为 CI/CD 平台,并配置了多个工作流,以确保代码质量、自动化构建并简化部署。 ## 概述 我们的 CI/CD 流程的主要目标是: * ✅ 验证一切是否按预期工作。 * 🚨 在出现问题时通知相关人员。 * 🚀 支持应用的完全自动化持续交付。 * 🔄 通过将公共代码提取为 `.github/actions` 下的可复用本地 action,避免重复。 ## 版本控制 我们遵循与核心项目相同的版本控制约定,使用 [CalVer](日历版本号)。这确保了所有版本发布之间的一致性。 ## 工作流 ### Pull request 时 当 pull request (PR) 被创建或更新时,会触发 `pr.yml` 工作流。其目标是: * 🧹 验证代码是否符合我们的 [linter](/developers/android/linter.md) 要求。 * 🔨 确保代码构建成功。 * ✅ 运行所有测试以验证正确性。 * 📦 在 GitHub Actions 选项卡中持久保存生成的 APK 以供审查。 如果任何步骤失败: * CI 会通知 PR 所有者。 * PR 在问题解决之前会被阻止合并。 * 修复必须提交,这将自动重新启动工作流。 :::note 对于给定的 PR,同时只运行一个工作流。如果在短时间内连续推送多个提交,CI 会取消正在进行的构建,仅处理最新的提交。 ::: #### Debug 构建 为了在 CI 中以 debug 模式构建应用,我们使用位于 `/.github/mock-google-services.json` 的 mock Google services 文件。 #### 仪器化测试 ##### Android(Emulator.wtf 上) Android 应用的仪器化测试运行在 [Emulator.wtf](https://emulator.wtf) 上。每次 pull request,都会针对我们支持的每个 Android API 级别执行完整的测试套件,整个过程只需几秒钟即可完成,使得反馈循环极快。 ##### Wear OS 和 Automotive(GitHub Actions 上) Wear OS 和 Automotive 的仪器化测试运行在 [GitHub Actions](https://github.com/features/actions) 上经典的 Android 模拟器中,速度明显较慢,因此对于这些目标我们只覆盖少数几个 API 级别。 #### 从 pull request 下载 APK 请参阅 [Testing pull request builds](/developers/android/tips/testing_pr_builds.md) 技巧,了解如何从 pull request 下载并安装 APK 的说明。 ### 推送到 `main` 时 当提交推送到 `main` 分支时,会触发 `onPush.yml` 工作流。其目标是: * 🌐 从 [Lokalise](/developers/translations.md) 下载翻译。 * 📝 生成发布说明。 * 🔧 构建所有应用的 release 变体。 * 📤 将应用部署到 Firebase。 * 🛒 部署到 Play Store 的内部轨道。 * 📦 在 GitHub Actions 选项卡中持久保存生成的 APK。 * 🔐 注入发布所需的 secrets 和文件。 我们使用 [Fastlane](https://fastlane.tools/) 来简化向不同商店的部署。所有 Fastlane 配置均可在 `fastlane` 文件夹中找到。 :::note 该工作流也可以通过 `beta` 标志手动触发,以将某个构建提升到商店的 beta 轨道。 ::: ### 每周构建 每周日 UTC 时间凌晨 4:00,`weekly.yml` 工作流会自动触发。其目标是: * 🛠 创建一个每周的 GitHub pre-release。 * 🚀 调用 `onPush.yml` 工作流,并将 `beta` 标志设置为 `true`。 这确保了每周都会向 Play Store 的 beta 轨道推送一个新版本的应用。 ### 每月版本标签 在每月的第一天,`monthly.yml` 工作流运行,以创建一个格式为 `YYYY.MM.0` 的初始版本标签。这符合我们的 [CalVer] 版本控制策略。 ### 发布 `release.yml` 工作流由手动触发,以将最新的 beta 构建提升到生产环境。这确保了只有稳定且经过测试的构建才会发布给最终用户。 #### F-Droid 上的发布 [F-Droid](https://f-droid.org) 商店会在我们推送 GitHub release 时自行构建应用。该过程使用 [metadata](https://gitlab.com/fdroid/fdroiddata/-/blob/master/metadata/io.homeassistant.companion.android.minimal.yml)。 每个 GitHub release 包含以下 F-Droid 使用的文件: * `version_code.txt` - 用于应用的版本控制(每次从 `main` 分支发布时创建) * `strings.zip` - 在构建时包含来自 Lokalise 的所有应用翻译 * `locales_config.xml` - 根据下载的应用翻译生成的 [locales 配置](https://developer.android.com/guide/topics/resources/app-languages#use-localeconfig) :::warning 我们无法保证在发布后应用何时会在 F-Droid 上可用。你可以在 [F-Droid](https://f-droid.org/packages/io.homeassistant.companion.android.minimal/) 上找到该应用。 ::: ### 创建 pre-release 或月度标签时 当创建一个处于 `pre-release` 状态的发布或推送月度标签时,会触发 `prepareNextRelease.yml` 工作流。该工作流会创建一个 pull request,将 `changelog_master.xml` 文件更新以反映新版本。需要对该 pull request 进行手动批准。此过程有助于保持 changelog 版本与应用版本的一致性。 ## 工作流汇总 | Workflow | Trigger | Goals | |-------------------|-----------------------------|----------------------------------------------------------------------| | `pr.yml` | PR 创建或更新时 | Lint、构建、测试并持久保存 APK。 | | `onPush.yml` | 推送到 `main` 时 | 构建、部署并发布到 Firebase 和 Play Store。 | | `weekly.yml` | 每周日凌晨 4:00 | 创建 pre-release 并将 beta 构建推送到 Play Store。 | | `monthly.yml` | 每月第一天 | 创建初始版本标签(`YYYY.MM.0`)。 | | `release.yml` | 手动触发 | 将 beta 构建提升到生产环境。 | | `prepareNextRelease.yml` | 创建 pre-release 或月度标签时 | 在 PR 中更新 `changelog_master.xml`。 | *** ## 注意事项与最佳实践 * 🛠 将公共代码提取为 `.github/actions` 下的可复用 action,以避免重复。 * 🕒 注意工作流触发条件,避免不必要的资源消耗。 * 🔒 确保 secrets 和敏感文件在工作流中得到了妥善管理和注入。 [CalVer]: https://calver.org/ --- url: /developers/android/codestyle.md --- ## 为什么要强制编码风格 我们的目标是维护一个**一致且标准的代码库**。通过强制编码风格: * 我们减少了 PR 上不必要的评论,使审查者能够专注于逻辑而非格式。 * 我们确保代码更易于阅读和维护。 ## 语言指南 * 所有代码必须使用**英文**编写。 * 避免拼写错误和语法错误。虽然错误是可以接受的(因为许多贡献者是非母语者),但鼓励审查者提出修正建议。 * 使用拼写检查器来辅助纠错。 ## KTLint 格式化器 我们使用 [KTLint](https://pinterest.github.io/ktlint) 来强制 Kotlin 代码风格。它已集成到我们的 Gradle 模块中,并通过 `.editorconfig` 文件进行配置。 ### 自定义规则 我们在必要时会覆盖部分 KTLint 规则。要启用或禁用某条规则: 1. 提交一个**专门的 PR**,并对变更进行适当说明。 2. 如果变更影响代码库,请创建**两个提交**: * 一个用于更新规则。 * 另一个用于应用变更。 :::note 在 `.editorconfig` 文件中的覆盖规则上方添加注释,说明更改的原因。如果需要更多解释,可以链接到 GitHub issue。 ::: ### 运行 KTLint 你可以通过 Gradle 使用 KTLint 自动重新格式化代码: ```bash ./gradlew :build-logic:convention:ktlintFormat ktlintFormat ``` ### CI 集成 如果检测到 KTLint 错误,CI 将会失败,GitHub 会使用生成的 [SARIF](/developers/android/tips/sarif_reports.md) 报告以评论的形式将其报告到 PR 中。 ## Yamllint 我们使用 [Yamllint](https://github.com/adrienverge/yamllint) 来强制 YAML 格式。仓库中所有 YAML 文件都遵循 `github` 格式。 ### 运行 Yamllint 在仓库根目录运行以下命令来检查 YAML 格式: ```bash yamllint --strict --format github . ``` :::note Yamllint 不会重新格式化你的代码,它只会报告需要修复的错误。请使用 IDE 的代码格式化器或手动修复问题。 ::: ### CI 集成 如果 YAML 格式无效,CI 将阻止该 PR。 ## 避免使用 TODO 代码中的 TODO 往往会随着时间推移而被遗忘。当以后有人再读到它们时,通常已经过时或不相关了。我们建议避免在代码中使用 TODO。但是,如果在审查过程中你与审查者达成一致认为某事需要在以后处理,你应该创建一个 `TODO`。为了妥善跟踪 TODO,请始终将它们与 GitHub issue 关联。 ### 示例 ```bash // TODO Missing feature https://github.com/home-assistant/android/issues/404 ``` 始终使用完整的 HTTP 链接引用 GitHub,切勿使用裸 `#404`——在 GitHub 之外,数字具有歧义且不可点击。链接到代码(文件或行)时,请使用永久链接(在 GitHub 上按 y 获取固定到提交的 URL),以确保链接在文件移动和编辑后依然有效。 ## 常量 ### 命名约定 我们遵循 [Kotlin 属性命名指南](https://kotlinlang.org/docs/coding-conventions.html#property-names)。 ### 避免魔法数字和字符串 代码中的魔法数字或字符串会让人难以理解某个值的用途,导致可维护性差。请始终用命名常量替换魔法数字或字符串。 #### ❌ 不要这样做 ```kotlin if (value == 42) { // 执行某操作 } ``` 在这个例子中,不清楚为什么要使用值 42。至少,你应该添加注释说明其用途。最好将其定义为常量,因为这样可以提供一个清晰、描述性的名称,使代码更易于阅读、理解和维护。此外,在一个地方定义值便于在代码库中复用,例如在测试中或函数、类或其他模块内。这种方法简化了未来的变更,因为在一个地方更新常量会自动将变更传播到所有使用它的地方。它还允许你通过 IDE 轻松找到常量使用的地方,避免像在整个代码库中搜索 "42" 那样产生不相关的搜索结果。 #### ✅ 应该这样做 ```kotlin // 关于为什么选择 42 的解释或链接 const val SUPER_IMPORTANT_THRESHOLD = 42 if (value == SUPER_IMPORTANT_THRESHOLD) { // 执行某操作 } ``` ### 常量的组织 常量应当有组织地定义,以确保清晰、可维护性和一致性。请遵循以下指南来决定在哪里以及如何定义常量: 1. 如果常量暴露到文件之外,导入时应能通过其自身名称或其父级名称轻松识别它。 2. 大多数常量应定义在与其关联的类所在的同一文件中(如果可能,放在 `companion object` 之外)。 3. 如果某个文件中的常量过多,请将它们移动到专门的文件中,并在一个 `object` 下分组以提供命名空间。 :::note 这条指南是近期引入的,以标准化代码库中常量的使用。因此,你可能会遇到违反此指南的情况。在遇到这些问题时,请随时予以纠正,以帮助提高代码质量。 ::: #### 与类一起定义 对于与某个特定类紧密耦合的常量,在与该类相同的文件中定义它们。除非绝对必要,否则避免使用 `companion object`。相反,将私有常量放在文件顶部、类定义之外。这种方法减少了样板代码,并使类保持专注。 **示例:** ```kotlin // filepath: UserRepository.kt package io.homeassistant.companion.android.user private const val DEFAULT_USER_ID = "guest" class UserRepository { fun getUserById(userId: String = DEFAULT_USER_ID): User { // 实现代码 } } ``` :::note 如果你需要在测试中使用该常量,以避免将其暴露给生产代码的其他部分,请使用 `VisibleForTesting` 注解。 ```kotlin @VisibleForTesting const val DEFAULT_USER_ID = "guest" ``` ::: #### 使用 companion object 何时使用 companion object: * **为外部使用提供命名空间**: 当常量或工具函数必须被外部访问时(例如,public 或 internal)。 * **有意的命名冲突**: 当同一文件中的多个类或实体对概念上相似的常量使用相同名称时(例如,EMPTY、DEFAULT)。 **示例:** ```kotlin // filepath: ApiClient.kt package io.homeassistant.companion.android.network class RestApiClient { companion object { val DEFAULT_TIMEOUT = 60.seconds } } class WSClient { companion object { val DEFAULT_TIMEOUT = 10.seconds } } ``` #### 在专用文件中通过 object 定义 如果某个文件中的常量过多,或者常量在多个类或模块间共享,请将它们移动到专用文件中。使用 object 对相关的常量进行分组并提供命名空间。文件名后缀应为 `*Constants.kt`。 ```kotlin // filepath: NetworkConstants.kt package io.homeassistant.companion.android.network object NetworkConstants { val TIMEOUT = 30.seconds const val BASE_URL = "https://api.example.com" } object WSConstants { val KEEP_ALIVE_INTERVAL = 5.seconds } ``` --- url: /developers/android/get_started.md --- ## 开始 Home Assistant Android 开发 欢迎使用 Home Assistant Android 开发指南!本文档将帮助你设置环境、fork 仓库并构建你的第一个应用。 ## 设置开发环境 要开始,请安装最新稳定版的 [Android Studio](https://developer.android.com/studio)。这是你构建应用所需的唯一工具。 ## Fork、clone 并创建分支 ### Fork 仓库 1. 打开 [Home Assistant Android 仓库](https://github.com/home-assistant/android)。 2. 点击 **Fork** 创建你自己的仓库副本。 :::tip 如果遇到任何问题,请参阅 [GitHub 关于 fork 仓库的文档](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo)。 ::: ### Clone 你 fork 的仓库 fork 仓库后,使用以下命令将其克隆到本地机器: ```bash git clone https://github.com//android.git ``` 或者,你可以使用 Android Studio: 1. 进入 `File -> New -> Project from Version Control...`。 2. 输入你的仓库 URL 并 clone 它。 ### 创建分支 在进行任何更改之前,创建一个能反映你所做工作的、有意义的分支名。例如: ```bash git checkout -b feature/add-new-feature ``` :::tip 如果你是 Git 新手,请参阅 [Git 分支指南](https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging)。你也可以直接在 Android Studio 中创建分支。 ::: ## 构建 Home Assistant 应用 在本地 clone 仓库后,你可以使用 Android Studio 或终端来构建应用。 ### 从 Android Studio 1. 在 Android Studio 中打开项目。 2. 同步 Gradle 文件。 3. 点击顶部栏的绿色 **Play** 按钮。Android Studio 会自动创建模拟器并为你运行应用。 :::note 项目需要安装 **NDK**(Native Development Kit)和 **CMake**。这些通常在项目同步期间自动安装。如果自动安装失败,你可以手动安装: 1. 打开 **Android Studio > Settings > Languages & Frameworks > Android SDK > SDK Tools**。 2. 勾选 **NDK (Side by side)** 和 **CMake**。 3. 安装项目根目录下 `libs.versions.toml` 文件中定义的特定版本。 ::: ### 从终端 :::info 你需要将 `JAVA_HOME` 环境变量设置为一个 JDK。我们目前使用的是 JDK 21。 ::: #### 在 macOS/Linux 上 ```bash ./gradlew assembleDebug ``` #### 在 Windows 上 ```powershell gradlew.bat assembleDebug ``` :::info 如果你需要创建 release 构建,请遵循 [release 构建说明](/developers/android/tips/release.md)。 ::: ## Firebase 设置 Firebase 用于通知。如果你不需要这些功能,应该使用 mock Firebase 配置。 :::info 你仍然可以通过 WebSocket 发送通知,而无需使用 Firebase。 ::: ### 设置 mock Firebase 项目 如果你不需要真实的 Firebase 功能,可以使用 mock 配置: 1. 复制位于 `/.github/mock-google-services.json` 的文件。 2. 将该文件的副本重命名并放置为 `google-services.json` 到以下每个文件夹中: * `/app` * `/automotive` * `/wear` 3. 完成此步骤后,你的项目中应包含以下文件: * `/app/google-services.json` * `/automotive/google-services.json` * `/wear/google-services.json` ### 设置真实的 Firebase 项目 请遵循我们的 [Push 通知指南](/developers/android/tips/fcm_push_notification.md) 获取更多设置说明。 ## 下一步是什么? 在构建应用后,浏览其余文档以加深对项目的理解。一个好的起点是 [架构指南](/developers/android/architecture/overview.md),它解释了代码库的整体结构。 ## 需要帮助吗? 如果你遇到问题,请随时寻求帮助! **[加入我们的 Discord 社区](https://www.home-assistant.io/join-chat)**,确保选择开发者角色,并前往 **[Android](https://discord.com/channels/330944238910963714/1346948551892009101)** 项目线程,与其他贡献者联系以获取帮助。 --- url: /developers/android/linter.md --- ## 什么是 linter? Linter 是一种静态代码分析器,有助于识别代码中已知问题和潜在改进。它超越了编译器的功能,通过确保语言的正确使用和遵循最佳实践来实现这一点。编译器根据语法规则验证代码,而 linter 则专注于代码质量和架构。 :::note Linter 没有提出任何意见并不意味着一切都完美。仍然需要另一位开发者的审查来再次确认。 ::: ## 为什么要使用 linter? 使用 linter 可确保: * **一致性**: 强制执行标准代码风格,类似于我们的 [编码风格](/developers/android/codestyle.md)。 * **专注**: 使审查者能够专注于逻辑,而不是格式或琐碎问题。 * **预防**: 通过捕获常见错误来帮助避免崩溃和 bug,例如使用了目标 Android API 级别不支持的 API。 例如,在使用不支持的 API 之前未检查 Android API 版本,可能会导致崩溃。 ## 项目中使用的 Linter ### KTLint 我们使用 [KTLint](https://pinterest.github.io/ktlint) 作为我们的 Kotlin linter,通过 [Gradle 插件](https://github.com/JLLeitschuh/ktlint-gradle) 集成。配置位于主 `build.gradle.kts` 文件中。我们大多使用默认配置,但启用了 [SARIF](/developers/android/tips/sarif_reports.md) 报告,以便 GitHub Actions 在 pull request 中标注问题。 #### 忽略问题 请始终尝试修复问题,而不是忽略它们。如果必须忽略,请遵循以下步骤: 1. 对特定构造使用 `@Suppress` 注解: ```kotlin @Suppress("trailing-comma-on-call-site") fun myCallSiteExample() { myFunction( "value1", "value2", // 这个尾随逗号通常会引发警告 ) } ``` 2. 对于项目范围的抑制,根据[此指南](https://pinterest.github.io/ktlint/0.49.1/faq/#how-do-i-globally-disable-a-rule-without-editorconfig) 更新 `.editorconfig` 文件。打开一个专门的 PR 并附上禁用该规则的说明: ```ini ... # Allow trailing commas but do not enforce it to follow Kotlin convention ktlint_standard_trailing-comma-on-call-site = disabled ij_kotlin_allow_trailing_comma_on_call_site = true ktlint_standard_trailing-comma-on-declaration-site = disabled ij_kotlin_allow_trailing_comma = true ``` #### 在本地运行 KTLint 运行以下命令以检查仓库中的所有代码: ```bash ./gradlew ktlintCheck :build-logic:convention:ktlintCheck --continue ``` :::note 使用 `--continue` 以获取 Gradle 模块中的所有问题,而不是在第一次失败时停止。 ::: 你可以通过运行以下命令,将此检查添加为通过 git [pre-commit hook](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) 自动运行的任务: ```bash ./gradlew addKtlintCheckGitPreCommitHook ``` ### Android 检查器 Android linter 对所有变体启用,以确保全面检查。其配置位于 `build-logic/convention/src/main/kotlin/AndroidCommonConventionPlugin.kt`。会生成 SARIF 报告,以便 GitHub Actions 在 pull request 中标注问题。 #### 忽略问题 请遵循以下步骤来忽略问题: 1. 对特定构造使用 `@Suppress` 注解。 2. 将问题添加到 `lint-baseline.xml` 文件中。(参见 [如何操作](#updating-the-baseline)) 3. 直接在 lint 设置中禁用该问题。 如果你禁用了某个问题,请打开一个专门的 PR 并附上说明。 #### 在本地运行 Android linter 运行以下命令: ```bash ./gradlew lintDebug --continue ``` :::note 使用 `--continue` 以获取 Gradle 模块中的所有问题,而不是在第一次失败时停止。 ::: ## 管理 lint 规则 ### 更改问题的 lint 级别 Android linter 内置了预定义规则,打包在 Android Gradle 插件中。一些库(如 [Timber](https://github.com/JakeWharton/timber))也提供自定义 lint 规则。 要更改规则的严重级别,请更新 `build-logic/convention/src/main/kotlin/AndroidCommonConventionPlugin.kt` 中的 Gradle 配置: ```kotlin lint { ... disable += "MissingTranslation" error += "LogNotTimber" } ``` * **`LogNotTimber`**: 从警告提升为错误,以强制使用 Timber 而非经典 logger。 * **`MissingTranslation`**: 已禁用,因为翻译只在 CI 发布构建时添加。 对 lint 级别的更改应通过 PR 进行,并附上清晰的说明。 ## 基线管理 ### 什么是基线? 基线是每个 Gradle 模块中的一个 XML 文件(`lint-baseline.xml`),列出了被忽略的错误。它在首次启用 linter 时创建,以避免修复数百个已存在的问题。 :::note 通过修复基线中的问题来移除它们,是一个极好的首次贡献。 ::: ### 更新基线 在更新 Android Gradle Plugin 时,可能会产生新的 lint 问题,或现有问题会发生变化。要重新生成基线: ```bash ./gradlew updateLintBaseline ``` 更新后,请审查被忽略的错误,以确定是现在就解决还是以后处理。根据需要打开 GitHub PR 或 issue。 ## 扩展 lint 规则 我们鼓励你提出针对我们项目的特定 linter 规则。这些规则可以帮助识别 API 的误用或强制使用我们希望在项目中采用的设计模式。 ### 项目中的自定义 lint 规则 一个专用的 Gradle 模块 `:lint` 包含了我们所有的自定义 lint 规则。 * **MissingSerializableAnnotationIssue**: 在使用 [Kotlinx.serialization](https://github.com/Kotlin/kotlinx.serialization) 时检测缺失的 `@Serializable` 注解。 ## 对贡献者的建议 * 尽可能修复 lint 问题,而不是忽略它们。 * 在 PR 中为 lint 配置或基线的任何更改提供清晰的说明。 * 在本地使用 linter 尽早发现问题,并节省 CI 资源。 快乐 lint! 🚀 --- url: /developers/android/release.md --- ## Android 发布流程 本文档概述了将 Android 应用从本地开发交付到最终用户生产环境所需执行的步骤。它还涵盖了 CI/CD 流水线、内部测试、beta 测试以及 Google Play Store 验证的角色。 ## 发布工作流:从 debug 到生产环境 ### 开发与 debug 构建 * 开发期间,你通常会在本地机器上构建 **debug 应用**。 * 一旦更改准备就绪,你就向仓库推送一个 **Pull Request (PR)**。 ### 持续集成 (CI) * CI 系统会自动: * 构建应用。 * 运行 linter 和测试,以确保代码质量。 * 如果 PR 获得批准并合并到 `main` 分支: * CI 会构建 **release 应用**。 * release 构建会被推送到 Google Play Store 和 Firebase 上的**内部测试员组**。 :::note 你可以从 [GitHub Actions 页面](https://github.com/home-assistant/android/actions/workflows/onPush.yml) 下载 `main` 分支上每个提交的预构建 APK。 ::: ### 内部测试 * 内部测试员验证 release 构建,以确保其功能正常。 * 每个获得批准并合并的 PR 都会被推送到 Google Play Store 的内部 beta 渠道,以获取即时反馈。这也是对 Android Auto/Automotive 进行真实世界测试的唯一方式,因为 debug 构建不会在真实车辆中显示。 * 由于应用的复杂性,在此阶段无法对所有功能进行详尽测试。 ### 每周 beta 发布 * 每周六美西时间晚上 9 点,最新的 `main` 构建会被推送到**公开 beta** 渠道。 * 在该截止时间(周五或周六)之前,请更新 beta changelog,以突出新功能和不兼容变更。 * 公开 beta 用户帮助在真实场景下测试应用并报告问题。 :::note 你可以直接通过 [Google Play Store](https://play.google.com/apps/testing/io.homeassistant.companion.android) 加入 beta 计划。 ::: ### 生产发布 如果 beta 版本稳定并获得了维护者的批准,它将被提升到**生产环境**,对所有用户开放。详细检查清单如下文 [发布流程(将 beta 提升到生产环境)](#release-process-promoting-beta-to-production) 中所述。 :::note 你可以在 [Google Play Store](https://play.google.com/store/apps/details?id=io.homeassistant.companion.android) 上找到该应用。 ::: ## Google Play Store 验证 * Google 会在应用推送到**公开 beta** 阶段时进行验证。 * 验证时间可能有所不同: * 在某些情况下可能需要一周以上。 * 由于发布是每周进行的,当新的 beta 提交时,之前的 beta 发布可能仍在验证中。如果发生这种情况,之前的 beta 将被移除,且不会被 Google 验证。 * 这种延迟不会阻碍发布流程,但需要仔细规划,以确保及时更新。 ## 发布流程(将 beta 提升到生产环境) 该提升由维护者按照以下检查清单执行: ### 提升之前 * 在 beta 发布后等待几天,给 beta 用户时间发现回归问题。 * 检查应用内 changelog(`app/src/main/res/xml/changelog_master.xml`)是否为最新,并且其版本与正在提升的 beta 相匹配。版本递增通过 [`prepareNextRelease.yml` 工作流](/developers/android/ci.md#on-pre-release-or-monthly-tag) 创建的 PR 自动进行,但内容应手动验证。 * 打开 Sentry dashboard,查看 beta 版本是否存在异常高数量的问题。 * 打开 [Google Play Console](https://play.google.com/console),查看是否有报告的任何异常(崩溃、ANR、Android vitals)。 * 准备一个 [companion docs](https://github.com/home-assistant/companion.home-assistant) PR,移除本次发布中所有带 beta 标签的功能。 ### 提升 * 在 [GitHub](https://github.com/home-assistant/android/releases) 上编辑最新的 beta 发布:保留生成的所有提交列表,但手动在其顶部添加一个 **Highlights of this release** 部分,与应用内 changelog XML 文件的内容相匹配(参见 [2026.6.1](https://github.com/home-assistant/android/releases/tag/2026.6.1) 作为示例),取消勾选 **pre-release** 复选框,并将其设置为 **latest** 发布。 * 取消勾选 pre-release 复选框会自动触发 [`release.yml` 工作流](/developers/android/ci.md#releases),该工作流使用 Fastlane 在 Play Store 上将 beta 轨道提升到移动端、Wear OS 和 Automotive 应用的生产环境。 :::note 提升后,发布并不会立即上线:Google 会先进行审查,这通常需要几天时间。审查期间无需采取任何操作;其余步骤将在[发布可用后](#after-the-release-is-available-on-stores)执行。 ::: ### 其他商店 Play Store 提升仅覆盖 `full` 风味。其他商店的更新方式如下: * 将 automotive `minimal` 风味发送到 Harman Ignite 商店。 * 在 [Amazon 开发者控制台](https://developer.amazon.com/apps-and-games/console/apps/list.html) 中手动提交发布以供审查。APK 和 changelog 在通过 `onPush.yml` 工作流中的 `prep_amazon` Fastlane lane 创建 beta 时已经上传。 * 在 Meta Quest 商店上发布 `minimal` 风味。 * F-Droid 会在几天后通过从 GitHub 发布构建来自动获取该发布(参见 [F-Droid 上的发布](/developers/android/ci.md#release-on-f-droid))。 ### 发布在商店上可用后 * 一旦发布在 Play Store 上可用,合并那个移除 beta 标签的 companion docs PR。 * 如果本次发布自上次生产发布以来修复了任何安全问题,请更新 GitHub 发布说明中的 CVE 披露信息。在亮点之后手动向发布说明中添加一个 **Disclosed security advisories** 部分,并附上指向每个已发布公告的链接。 :::note 如果发布包含重大变更或出色的新功能,请请求社区经理协助推广(博客文章、社交媒体等)。 ::: --- url: /developers/android/submit.md --- ## 提交你的第一个贡献 首先,感谢你的贡献!现在该获取反馈并为真实用户准备你的工作了。请遵循 [GitHub 文档](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork) 从你的 fork 创建一个 pull request (PR)。 ### 提交 PR 检查清单 在创建 PR 时,GitHub 会使用检查清单预填充描述。请确保遵循所有步骤。以下是一份扩展的检查清单以帮助你: * **PR 描述**: 提供关于你更改的清晰完整的描述。 * **测试**: 遵循我们的 [测试指南](/developers/android/testing/introduction.md) 添加所有必要的测试。 * **文档**: 确保代码已妥善记录。 * **UI 更改**: 如果 UI 被修改,请附上截图。 * **用户文档**: 如果需要更新用户文档,请在 [GitHub](https://github.com/home-assistant/companion.home-assistant) 上打开一个 PR。 * **开发者文档**: 如果本文档需要更新,请在 [GitHub](https://github.com/home-assistant/developers.home-assistant/) 上打开一个 PR。 * **构建**: 验证所有内容(应用、automotive、wear)在本地构建正常。 * **最佳实践**: 遵循 [最佳实践](/developers/android/best_practices.md)。 * **编码风格**: 遵循 [编码风格](/developers/android/codestyle.md)。 * **Linting**: 确保没有引入 lint 问题([linter](/developers/android/linter.md))。 ### 打开 draft PR 如果你的 PR 还没有准备好进行正式审查,但你希望获得反馈,你可以以 **draft 模式** 打开它。这在处理 CI 相关更改或不完整的功能时特别有用。 #### CI 触发 如果你是新贡献者,每次 CI 运行都需要维护者批准。 :::warning **避免不必要的 CI 运行** 运行 CI 工作流会消耗大量资源。如果你的工作尚未完成,请推迟打开 PR(即使是 draft 模式),除非确有必要。请留意资源使用和我们共同的地球。🌍 但这并不妨碍你定期推送以避免丢失工作。 ::: ### 更新你的分支 有时你的分支可能会落后于 `main`。在你的 pull request 合并之前,你可能需要解决冲突。你可以通过以下两种方式来更新你的分支: * **Merge** `main` 分支到你的分支中,并[解决任何冲突](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-using-the-command-line)。 * 按照 [Git rebase 文档](https://docs.github.com/en/get-started/using-git/about-git-rebase) 将你的分支 **Rebase** 到 `main` 上。 请遵循以下指南: * 如果你的 pull request **尚未**被审查,你可以 rebase 或 merge。 * 如果你的 pull request **已被审查**,请使用 merge 而不是 rebase。在审查后 rebase 可能会破坏之前的评论并移除有价值的反馈。 在审查前 rebase 是可选的;merge 始终允许。本仓库使用 [squash and merge](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges#squash-and-merge-your-commits) 策略,以保持提交历史干净且有意义。 ### 审查流程 #### 谁可以审查? 任何人都可以评论你的 PR,因为它是公开的。我们通过审查鼓励贡献。审查往往比编写代码更快,即使是 10 分钟的审查也很有价值。 如果你对**审查**没有信心,你仍然可以通过以下方式提供帮助: * 通过安装 APK 来测试该功能(可在 PR 的 Checks 选项卡中找到;你必须登录 GitHub 账户才能访问它)。 * 提供关于 UI/UX 的反馈。 * 报告崩溃或 bug。 #### 获得维护者的批准 一旦你的 PR 满足检查清单要求,请等待维护者审查。请记住,维护者是利用业余时间贡献的志愿者。请保持尊重、耐心和友善。 来自维护者的反馈会以以下形式出现: * **评论**: 对代码的建议或必要更改。 * **问题**: 关于某事如何运作的问题。 ### 收到反馈后 #### 重新请求审查 如果你已处理反馈并将更改推送到 PR,你可以请求维护者重新审查。请确保在执行此操作前 CI 状态为绿色。 ### 合并你的 PR * 保持你的 PR 与 `main` 分支同步。 * 一旦一切状态为绿色并获得维护者批准,他们会合并你的 PR。你无需采取任何进一步的操作。 ### 自动关闭 issue 和 PR 我们的 bot 会在**90 天**不活动后将 issue/PR 标记为陈旧。如果**7 天**后仍没有活动,issue/PR 将被自动关闭。 *** 感谢你为 Home Assistant 作出的贡献!🎉 --- url: /developers/android/targets.md --- ## Android 目标 本文档概述了 Home Assistant 应用支持的各种 Android 目标。每个目标都有自己特定的要求和注意事项。 ## 📱 应用(主要目标) 主要目标基于 Gradle `:app` 模块。它支持**最低 API 级别 21**。这是大多数用户主要使用的应用。 ## 🚗 Automotive Automotive 目标也基于 `:app` 模块,但包含了专门为 automotive 用例定制的 manifest 条目。它与主应用共享相同的源代码,并支持**最低 API 级别 29**。 ## 📺 TV 该应用可以安装到 Android TV 上,尽管目前的导航体验并不理想。为了提供更好的体验,需要专门的 Gradle 模块和改进的导航支持。 ## ⌚ Wear OS Wear OS 目标将 Home Assistant 功能带入可穿戴设备。它支持**最低 API 级别 26**。它是一个**独立的应用**,但在 onboarding 和连接到服务器时需要移动应用。 --- url: /developers/android/testing/integration_testing.md --- ## 为什么要进行集成测试? [单元测试](/developers/android/testing/unit_testing.md)很棒,应是你编写测试时的首选。然而,集成测试确保在真实 Android 环境中应用的行为得到验证。集成测试通过模拟器在真实的 Android 操作系统上运行,使用终端用户也将使用的相同 JVM。 ### 在真实 JVM 上测试 在开发过程中,你可能只在最新的 Android 操作系统版本或本地安装的 JVM(很可能是 JDK 21)上测试。但请记住以下几点: * Android API 21 仅部分支持[Java 8 语言特性](https://developer.android.com/studio/write/java8-support)。 * Android 使用专用的[runtime](https://source.android.com/docs/core/runtime),与开发环境中使用的那个(通常用于执行单元测试)不同。 #### 具体示例 考虑 [Jackson 库](https://github.com/FasterXML/jackson)。从 2.14 版本开始,它要求最低 Android 版本为 26。遗憾的是,此错误仅在运行时才会出现,这意味着捕获它的唯一方式是通过 instrumentation tests 或用户报告的崩溃。你可以在这个 [PR](https://github.com/home-assistant/android/pull/5108) 中看到此问题的具体示例。 ### 有 UI 还是无 UI? 集成测试并不总是涉及显示 UI。它们也用于测试[foreground services](https://developer.android.com/develop/background-work/services/fgs),此时不显示 UI。在这些情况下,我们仅验证数据以及与系统的交互。 ### 使用对应的 Home Assistant Core 版本进行测试 :::note 这些测试目前仍在开发中 ::: 我们旨在针对 Home Assistant Core 的最新版本运行集成测试。这确保当前代码能与核心版本无缝工作。 ### 不使用 Home Assistant Core 进行测试 我们的大部分测试不应依赖 Home Assistant Core,以避免引入额外的错误来源。这些测试旨在验证 screen 在用户交互期间的行为。为此,我们使用 [Espresso](https://developer.android.com/training/testing/espresso) 框架。 在此场景中,与 core 的交互可以使用 [mockk](https://mockk.io/) 的 mock 来替换,甚至更好的方式是使用 fake 对象来控制行为。 ## Android 模拟器中的 flakiness Android 模拟器以不可靠而闻名。偶尔,某个平台可能因未知原因失败。唯一的解决方案是重启该任务。请注意,只有维护者才能重新运行任务。 ## 在 Android 5(API 21)上测试 如果你的测试需要 WebView,你可能需要遵循这些[Lollipop 模拟器提示](/developers/android/tips/lollipop_emulator.md)。 --- url: /developers/android/testing/introduction.md --- ## 为什么要写测试? 测试是软件开发的重要组成部分。虽然测试有不同的种类,每种都有独特的用途,但它们存在的根本原因相同:人都会犯错。测试旨在开发过程中尽早捕获这些错误。 通过在问题到达生产环境之前识别它们,我们为节省用户的挫败感和我们自己的调试时间。写测试起初可能感觉像是额外的工作,但当测试在问题影响终端用户之前捕获它时,其价值就变得显而易见。 ### 写测试的好处 * **早期问题检测**:在问题到达生产环境之前捕获 bug。 * **提升代码质量**:测试鼓励更好的设计和可维护性。 * **节省时间**:调试生产问题比在开发过程中解决问题要耗时得多。 * **用户满意度**:生产环境中更少的 bug 带来更好的用户体验。 ## 如何编写有效的测试 为确保清晰性和可维护性,测试函数应始终(在可能的情况下)写成描述性语句。理想情况下,它们应遵循 [GIVEN-WHEN-THEN](https://en.wikipedia.org/wiki/Given-When-Then) 结构。这种方法使测试即使对于复杂场景也易于一眼理解。 一个命名良好的测试示例: ```kotlin @Test fun `Given a user with Home Assistant when they open the app then they see the default dashboard`() { // 此处填写测试实现 } ``` ### 为什么使用 GIVEN-WHEN-THEN? * **GIVEN**:描述初始上下文或设置。 * **WHEN**:指定正在测试的操作或事件。 * **THEN**:定义预期结果。 这种结构确保测试既易于阅读又自解释,使开发者无需深入实现即可理解测试的目的。 ## 测试类型 虽然本文档聚焦于 Android 测试,但了解不同类型的测试及其用途很重要: 1. **单元测试**:隔离验证各个组件或函数。 2. **集成测试**:确保应用程序的不同部分按预期协同工作。 3. **UI 测试**:验证用户界面和用户交互。 4. **端到端测试**:从头到尾测试整个应用程序流程。 每种测试类型在开发过程中都有其位置,测试完善的应用通常包含所有这些类型的组合。 ## 编写测试的最佳实践 * **保持测试小而专注**:每个测试应验证单一行为或场景。 * **使用描述性名称**:测试名称应清晰描述正在测试的内容和预期结果。 * **避免依赖**:测试之间应保持相互独立以确保可靠性。 * **Mock 外部依赖**:使用 mock 或 fake 来隔离被测代码。 遵循这些指南,你可以编写既有效又可维护的测试。 --- url: /developers/android/testing/screenshot_testing.md --- ## 为什么要进行截图测试? 截图测试用于验证当前 UI 是否与仓库中存储的参考 UI 匹配。通过这样做,我们可以确保任何影响 UI 的更改都是有意为之且经过验证的。这些测试的范围仅限于 UI。 我们应该在各种设备形状和尺寸上测试,从小屏幕(例如 Wear OS 设备)到大屏幕(例如 55" 电视)。 ### 截图测试的好处 * **UI 一致性**:确保 UI 在更新中保持一致。 * **库更新**:验证 UI 库的更新不会引入意外更改。 * **广泛的设备覆盖**:跨多个屏幕尺寸和形状进行测试以确保兼容性。 ### 实际示例 在使用 Wear Compose 库等库的 beta 版本时,截图测试已证明很有用,因为库中的更改可能影响 UI。 ## Compose 截图测试 我们使用 [Compose Preview Screenshot Testing](https://developer.android.com/studio/preview/compose-screenshot-testing) 框架来断言 UI 没有意外更改。 ### Compose 截图测试的优点 * **不需要模拟器**:这些测试不需要模拟器,使它们资源消耗较少且比[集成测试](/developers/android/testing/integration_testing.md)快得多。 * **快速反馈**:开发者可以快速验证 UI 更改而无需等待模拟器启动时间。 ### 参考截图 参考截图存储在每个 Gradle 模块的 `src/debug/screenshotTest/reference` 下。要更新参考截图,请运行以下命令: ```bash ./gradlew updateDebugScreenshotTest updateFullDebugScreenshotTest ``` ### CI 集成 我们的[CI 流水线](/developers/android/ci.md)会验证测试报告中是否有任何错误。如果发现差异,CI 将阻止 pull request,直到问题解决。 ## 避免 Compose 预览中的重复 为避免在测试中重复 Compose 预览,请确保尽可能复用现有的 composable 和预览注解。这减少了冗余并确保预览与测试之间的一致性。 ## 为测试配置注解 编写截图测试时,使用适当的配置注解来定义设备尺寸、主题和其他参数。这确保测试准确反映预期的 UI。 ## 处理阈值更新 在不同操作系统上运行截图测试时可能会失败,因为渲染中的细微差异,例如抗锯齿。此问题在此 [Google issue tracker](https://issuetracker.google.com/issues/348590914) 中有详细讨论。 ### 当前方法 我们将阈值保持在尽可能低以避免掩盖真实问题。 :::info 在 CI 上更新截图的工作流仅限于具有写权限的用户,且仅适用于主仓库内的分支。目前不适用于 fork 或外部贡献者。 ::: 提供了一个 GitHub Action 工作流 `update_screenshots.yml`,可由仓库维护者手动触发来更新截图以匹配验证主机配置。如果你的截图测试因阈值差异而失败,维护者将在审查过程中处理此问题。 :::note 此工作流直接提交到分支,但不会自动触发 pull request 工作流。要在更新后触发工作流,请在更新后向分支提交一个新的 commit。 ::: ## 截图测试最佳实践 * **跨设备测试**:确保测试覆盖一系列屏幕尺寸和形状。 * **保持参考截图更新**:定期更新参考截图以反映有意的 UI 更改,并在 PR 中解释更改内容。 * **最小化阈值**:使用尽可能小的阈值以避免隐藏真实问题。 * **复用预览**:通过复用现有的 composable 和注解来避免重复 Compose 预览。 遵循这些实践,你可以确保 UI 在更新和设备配置中保持可靠和一致。 --- url: /developers/android/testing/unit_testing.md --- ## 为什么要进行单元测试? 单元测试帮助你自信地构建功能,并确保代码行为符合预期。它应是协助开发的工具,而非负担。[测试驱动开发 (Test-Driven Development, TDD)](https://en.wikipedia.org/wiki/Test-driven_development) 是一种知名方法,在编写实际代码之前或同时编写测试。这种方法允许你快速验证代码而无需等待整个应用运行。 :::info 不要为了写测试而写测试。测试应在开发过程中提供帮助,或帮助未来的开发者维护代码库。 ::: 单元测试专注于测试**你的代码**。除非绝对必要,否则避免测试外部库的行为。如果你发现自己正在测试库的行为,请考虑为该库做贡献并将测试添加在那里。 :::note 此规则有例外情况。有时我们添加测试以确保库的行为不会随时间改变。在这种情况下,请明确记录测试的原因。 ::: ## 测试公共接口 专注于测试你类的**公共 API**,而不是每个单独的函数。为所有函数(尤其是小型函数)编写测试可能会导致大量难以维护的测试。通过集中测试公共接口,确保测试保持相关性并对内部变更具有弹性。 当你需要访问类的私有部分进行测试时,考虑使用 [VisibleForTesting](https://developer.android.com/reference/kotlin/androidx/annotation/VisibleForTesting) 注解。此注解允许你仅出于测试目的暴露私有方法或属性。[linter](/developers/android/linter.md) 确保此暴露仅限于测试作用域。 :::note 除非绝对必要,否则避免使用 `VisibleForTesting`。最好以不需要暴露私有成员的方式设计代码。 ::: ## 测试框架和 mocking 项目已配置使用 [JUnit 5](https://junit.org/junit5/),应作为你的主要测试框架。 ### 模拟 编写单元测试时,你通常需要 mock 被测代码的依赖来隔离它。项目使用 [MockK](https://mockk.io/)。使用该工具为外部依赖创建 mock 或 fake,确保测试保持聚焦于你的代码行为。 ### 在 Gradle 模块间共享代码 项目包含一个名为 `:testing-unit` 的 Gradle 模块,用于在其他 Gradle 模块间共享代码。如果代码在多个模块中使用,请将其添加到此模块。确保 `:testing-unit` 与 `:common` 等模块保持独立,以避免循环依赖。 ## 使用 Android API 进行测试 对于代码与无法正确 mock 或 fake 的 Android API 交互的情况,项目包含 [Robolectric](https://robolectric.org/)。Robolectric 允许你在 JVM 环境中运行 Android 特定测试,避免了对模拟器的需要。 ### 何时使用 Robolectric * 当测试难以 mock 或 fake 的 Android API 时使用 Robolectric。 * 在可能的情况下,优先使用 Robolectric 而非 instrumentation tests,因为 instrumentation tests 需要更多资源且设置更复杂。 ### 注意事项 * Robolectric 不与 JUnit 5 一起工作(请参见此 [issue](https://github.com/robolectric/robolectric/issues/3477))。为解决此问题,项目包含了 JUnit 4 的依赖,用于需要 Robolectric 的测试。 * 确保被测代码不依赖于 Android API 的状态,因为这样可能导致不可靠的测试。如果情况如此,考虑编写[instrumented test](/developers/android/testing/integration_testing.md)。 ## 单元测试最佳实践 * **与代码同步编写测试**:在开发时编写测试,确保代码可测试并降低 bug 风险。 * **聚焦行为**:测试代码的行为,而非其实现细节。 * **保持测试小而专注**:每个测试应验证单一行为或场景。 * **使用描述性测试名称**:测试名称应清晰描述测试的场景和预期结果。 * **Mock 外部依赖**:使用 mock 或 fake 来隔离被测代码。 * **避免过度测试**:除非对功能至关重要,否则不要为琐碎方法或内部实现细节编写测试。 ## 示例:编写单元测试 以下是一个使用 JUnit 5 和 MockK 的结构性良好的单元测试示例: ```kotlin @Test fun `Given a valid user ID when fetching user details then return user data`() { // Given val userId = "12345" val expectedUser = User(id = userId, name = "John Doe") every { userRepository.getUser(userId) } returns expectedUser // When val result = userService.getUserDetails(userId) // Then assertEquals(expectedUser, result) } ``` --- url: /developers/android/tips/compose_101.md --- ## 如何在现有应用中创建新的 screen 并快速迭代 要在应用中创建新的 screen 并快速迭代,请遵循以下步骤: 1. **提取 Compose UI screen**: 为你的 Compose UI screen 创建一个专用的 Kotlin 文件。使用 `@Preview` 注解以在 IDE 中启用预览功能。这也能使 screen 与[截图测试](/developers/android/testing/screenshot_testing.md)兼容。 2. **利用 hot reload**: 首次构建应用后,导航到你的 screen。Jetpack Compose 原生提供 hot reload 能力,允许你实时查看更改。但请注意存在一些限制,例如无法重新加载某些结构性元素的更改。 3. **有效使用预览**: 使用多个 `@Preview` 注解来在不同配置下测试你的 screen(例如,浅色/深色模式、不同的屏幕尺寸)。这有助于确保你的 UI 能很好地适应各种场景。 ## 主题/设计系统 我们使用自定义 Compose 主题 `io.homeassistant.companion.android.util.compose.HomeAssistantAppTheme`,基于 [Material Design 2](https://m2.material.io/)。你必须使用此主题以确保与应用整体 UI 的一致性。 ### 关键点 * **Material Design 2**:该主题遵循 Material Design 2 原则,确保统一的视觉和体验。 * **自定义组件**:如果你需要创建自定义组件,请确保它们与现有主题和设计系统保持一致。 * **深色模式支持**:该主题同时支持浅色和深色模式。请在两种模式下测试你的 screen 以确保正确的样式。 ## 使用 Jetpack Compose 的最佳实践 * **保持 UI 代码模块化**:将 UI 分解为小型、可复用的 composable。这提高了可读性,并使测试更容易。 * **使用 state hoisting**:遵循[state hoisting 模式](https://developer.android.com/jetpack/compose/state#state-hoisting)以有效管理状态。这确保你的 composable 保持无状态且可复用。 * **使用预览进行测试**:使用 `@Preview` 注解以隔离测试你的 composable。添加参数来模拟不同的状态和配置。 * **遵循无障碍指南**:通过提供有意义的 content description 并使用无障碍工具测试,确保你的 UI 是无障碍的。 * **使用样式**:为文本组件应用适当的样式。 ## 示例:创建新的 screen 以下是如何创建一个带预览的 Compose screen 的示例: ```kotlin // filepath: /path/to/your/screen/MyNewScreen.kt @Composable fun MyNewScreen( title: String, onButtonClick: () -> Unit ) { HomeAssistantAppTheme { Column( modifier = Modifier .fillMaxSize() .padding(16.dp), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { Text(text = title, style = MaterialTheme.typography.h4) Spacer(modifier = Modifier.height(16.dp)) Button(onClick = onButtonClick) { Text(text = "Click Me") } } } } @Preview(showBackground = true) @Composable fun MyNewScreenPreview() { MyNewScreen( title = "Welcome to Home Assistant", onButtonClick = {} ) } ``` --- url: /developers/android/tips/dependencies.md --- ## 版本目录 我们使用[version catalog](https://docs.gradle.org/current/userguide/version_catalogs.html)来管理项目中直接使用的所有库。这是添加依赖的**唯一允许方式**。为保持一致性和可追溯性,严禁在 catalog 之外添加依赖。 ### 使用 version catalog 的好处 * **集中管理**:所有依赖定义在一个位置(`gradle/libs.versions.toml`),使其更容易跟踪和更新。 * **一致性**:确保所有模块使用共享依赖的相同版本。 * **简化更新**:使跨整个项目更新依赖变得更加容易。 ## 管理依赖和 lockfile 本项目利用 Gradle 的[dependency locking](https://docs.gradle.org/current/userguide/dependency_locking.html)功能,通过跟踪所有使用库的精确版本,确保构建的一致性和可重现性。 ### 为什么使用 dependency locking * **可重现的构建**:通过锁定所有依赖的精确版本,确保不同环境下的构建保持一致。 * **避免意外**:防止传递依赖出现意外更新而破坏构建。 ### 更新依赖和 lockfile 在 `gradle/libs.versions.toml` 中添加或更新依赖时,务必同时更新相应的 lockfile。lockfile 捕获所有直接和传递依赖的精确版本。 要从项目根目录更新 lockfile,请运行以下命令: ```bash ./gradlew alldependencies --write-locks ``` 此命令解析所有依赖并更新每个模块中的 `gradle.lockfile`。 :::info 如果 version catalog 已更新但 lockfile 未更新,CI 流水线将会失败。 ::: ## 使用 Renovate 自动更新依赖 为简化依赖管理,我们已将[Renovate](https://docs.renovatebot.com/)集成到仓库中。Renovate 会自动创建 pull request 来更新依赖和 lockfile。 ### Renovate 工作原理 * **自动更新**:Renovate 扫描项目中过时的依赖并创建 pull request 来更新它们。 * **Lockfile 更新**:Renovate 确保 lockfile 与依赖一起更新。 * **自定义配置**:Renovate 被配置为遵守项目的版本策略和更新策略。 :::note Renovate 被配置为在库的新版本发布 3 天后再打开 pull request。这一延迟允许早期采用者识别并报告任何明显的问题。 ::: ### 使用 Renovate 的好处 * **节省时间**:自动完成检查并更新依赖的繁琐过程。 * **降低风险**:确保更新通过 CI 流水线一致应用并经过测试。 * **提升安全性**:保持依赖为最新,降低漏洞风险。 ## 使用非稳定版本 虽然我们力求跟上所用库的最新版本,但我们优先考虑稳定性。因此,我们避免使用 `alpha`、`beta`、`rc` 或其他非稳定版本。 :::note 在极少数特定情况下,我们已在 PR 中同意使用 `alpha` 版本以访问新功能。但这会带来每次更新后需解决问题的代价,因为 API 并不稳定。一个显著的例子是 `wear-compose-material` 库。 ::: --- url: /developers/android/tips/dev_playground.md --- ## 为什么需要 developer playground? 该应用严重依赖 WebView 和与服务器的活跃连接,这使得在开发过程中快速测试功能变得困难。通常,你可能需要多次重建应用来测试特定行为。虽然**Compose preview**功能可以帮助进行 UI 测试,但有时它们并不充分,需要走完整个 UX 流程,这可能会很繁琐。 为节省开发时间,我们创建了一个**developer playground**。这个 playground 仅在 debug 构建中可通过应用[快捷方式](https://developer.android.com/develop/ui/views/launch/shortcuts/creating-shortcuts#static)访问。这确保它不会干扰应用的其他部分。 :::note playground 代码位于 `app/src/debug` sourceSet 中。 ::: 你可以根据需要使用 playground,但只有在对其他开发者有价值时才提交更改。在向 playground 提交更改时,请确保遵循[编码风格](/developers/android/codestyle.md)和[最佳实践](/developers/android/best_practices.md)。不过,翻译可以省略。 ### 有价值贡献的示例 * 一种故意使应用崩溃以测试缓存文件夹中错误报告的方法。 * 一个用于显示应用中使用的全部组件和主题的工具。 --- url: /developers/android/tips/fcm_push_notification.md --- ## FCM push notifications 设置 :::note 设置 Firebase Cloud Messaging (FCM) 可能很复杂。除非你特别需要它,否则建议开发时使用 WebSocket 发送通知。 ::: 如果你想要自己的 FCM 设置来实现 push notifications,请遵循以下步骤: 1. **创建 Firebase 项目** 前往 [Firebase Console](https://console.firebase.google.com) 并创建一个新的 Firebase 项目。 2. **将 Android 应用添加到 Firebase 项目** 在 Firebase 项目中将以下 package name 添加为 Android 应用: * `io.homeassistant.companion.android` * `io.homeassistant.companion.android.debug` * `io.homeassistant.companion.android.minimal` * `io.homeassistant.companion.android.minimal.debug` 3. **部署 push notification 服务** 访问 [mobile-apps-fcm-push 仓库](https://github.com/home-assistant/mobile-apps-fcm-push) 并将服务部署到你的 Firebase 项目。 4. **设置 push notification URL** 获取已部署服务的 `androidV1` URL 后,将其添加到 `${GRADLE_USER_HOME}/gradle.properties` 文件中。例如: ```properties homeAssistantAndroidPushUrl=https://mydomain.cloudfunctions.net/androidV1 ``` 可选地,你还可以定义 rate limit 函数 URL: ```properties homeAssistantAndroidRateLimitUrl=https://mydomain.cloudfunctions.net/checkRateLimits ``` 5. **下载并放置 `google-services.json` 文件** 从 Firebase 项目下载 `google-services.json` 文件并将其放置在以下文件夹中: * `/app` * `/automotive` * `/wear` :::note `google-services.json` 文件必须包含上述所有 package name 的 client ID。否则,FCM push notifications 将无法工作(仅 WebSocket 通知功能正常)。 ::: --- url: /developers/android/tips/leak_canary.md --- ## 如何在 debug 构建中禁用 LeakCanary [LeakCanary](https://square.github.io/leakcanary/) 是一个强大的工具,用于检测 Android 应用中的内存泄漏。但在某些场景下你可能想要禁用它,例如准备用于性能测试的 debug 构建或不需要它时。 ### 通过 Gradle 命令禁用 LeakCanary 你可以在 Gradle 命令中传递 `-PnoLeakCanary` 标志来手动禁用 LeakCanary。例如: ```bash ./gradlew app:assembleFullDebug -PnoLeakCanary ``` 此标志确保 LeakCanary 被排除在构建之外。 ### 通过 properties 文件禁用 LeakCanary 或者,你也可以通过在 `gradle.properties` 文件中设置 `noLeakCanary` 属性来禁用 LeakCanary。这可以在项目级别或主目录级别完成。 ```properties noLeakCanary=true ``` ::::warning 如果禁用了 LeakCanary,你需要更新 lockfile;否则 Gradle 会抱怨依赖存在问题。 [如何更新 lockfile](/developers/android/tips/dependencies.md#updating-dependencies-and-lockfiles)。 :::: ## 使用 LeakCanary 的最佳实践 * **定期监控内存泄漏**:在开发过程中使用 LeakCanary 来及早发现并修复内存泄漏。 * **记录已知泄漏**:如果内存泄漏是由第三方库引起且无法立即修复,请记录下来以供将来参考。 * **报告泄漏**:如果 LeakCanary 报告了泄漏,请打开一个 GitHub issue。 --- url: /developers/android/tips/lollipop_emulator.md --- ## 概述 要在运行 Lollipop(Android API 21)的 Android 模拟器上测试应用,你需要更新过时的 WebView 以确保兼容性。如果不更新,WebView 将会崩溃。 ## 更新 WebView 要更新 WebView,请下载最新的 WebView APK 并遵循此 [StackOverflow 帖子](https://stackoverflow.com/a/79514205/3289338)中的说明。 如果你正在构建自己的 frontend,请在构建过程中将 `ES5` 标志设置为 `1`。这确保与旧版 WebView 的兼容性。 ```bash ES5=1 script/develop ``` --- url: /developers/android/tips/release.md --- :::warning 确保 keystore 安全存储且未包含在版本控制中。凭据同样适用此要求。 ::: ## 构建 release 要为发布构建应用,你需要对其进行签名。请遵循以下步骤: ### 步骤 1:创建或使用现有 keystore 在构建应用之前,你必须拥有一个 keystore。你可以创建一个新的或使用现有的 keystore。 #### 创建 keystore 你可以直接从 Android Studio 创建 keystore: 1. 进入 **菜单** > **Build** > **Generate Signed APK**。 2. 选择创建新 keystore 的选项。 3. **记住密码和 key alias**,以便将来使用。 #### 使用现有 keystore 如果你已有 keystore,请确保其命名为 `release_keystore.keystore` 并放置在以下文件夹中: * `app` * `wear` 或者,你可以通过设置 `KEYSTORE_PATH` 环境变量来指定自定义位置。 *** ### 步骤 2:构建应用 你可以使用 Android Studio 或命令行(CLI)来构建应用。 #### 从 Android Studio 1. 打开 Android Studio。 2. 进入 **菜单** > **Build** > **Generate Signed APK**。 3. 选择你创建的 keystore 或现有的一个。 4. 按照步骤构建应用。 #### 从 CLI 1. **设置环境变量** 定义 `app/build.gradle.kts` 中使用的以下环境变量: * `KEYSTORE_PASSWORD` * `KEYSTORE_ALIAS` * `KEYSTORE_ALIAS_PASSWORD` * `KEYSTORE_PATH`(如果 keystore 位于自定义位置) 2. **构建应用** 要构建 APK,请运行: ```bash ./gradlew assembleRelease # 构建所有应用 # 或 ./gradlew ::assembleRelease # 构建特定模块,例如 :app、:automotive 或 :wear ``` 要构建 AAB,请运行: ```bash ./gradlew bundleRelease # 构建所有应用 # 或 ./gradlew ::bundleRelease # 构建特定模块,例如 :app、:automotive 或 :wear ``` --- url: /developers/android/tips/sarif_reports.md --- ## 概述 SARIF(静态分析结果交换格式)报告用于在 GitHub Actions 中通知由 linter 或代码风格工具发现的问题。本指南说明了 SARIF 报告在我们的项目中的处理方式,以及如何将多个报告合并为一个,以兼容 GitHub Actions。 ## 为什么使用 SARIF 报告? GitHub Actions 支持 SARIF 报告进行代码扫描,使得在 Pull Request 或仓库的 Security 选项卡中直接识别和解决问题变得更加容易。了解更多 SARIF 信息,请参阅 [GitHub 文档](https://docs.github.com/en/code-security/code-scanning/integrating-with-code-scanning/sarif-support-for-code-scanning)。 ## 处理多个 SARIF 报告 ### 问题 在我们的项目中,使用了多个 Gradle 模块。运行生成 SARIF 报告的任务时,每个模块都会生成自己的报告。然而,GitHub Actions 不再支持在单个 workflow 运行中处理多个 SARIF 报告。 ### 解决方案 为解决此问题,我们使用自定义 Python 脚本将所有 SARIF 报告合并为一个文件,以确保与 GitHub Actions 的兼容性。 合并 SARIF 报告的脚本位于 `.github/scripts/merge_sarif.py`。使用方法如下: 1. **生成 SARIF 报告** 2. 运行 `python3 .github/scripts/merge_sarif.py` 仓库根目录下将生成一个新的 SARIF 文件。 --- url: /developers/android/tips/strict_mode.md --- ## debug 构建中的 StrictMode 在 Android 上以 debug 模式运行应用时,StrictMode 默认启用。StrictMode 帮助你识别在主线程上意外进行的磁盘或网络访问,以及开发过程中的其他潜在问题。更多信息请参阅 [StrictMode 文档](https://developer.android.com/reference/android/os/StrictMode)。 StrictMode 还帮助我们在开发早期通过突出显示已弃用或有问题的行为来迁移到新的 Android API 版本。 [VM policy](https://developer.android.com/reference/android/os/StrictMode.VmPolicy.Builder) 配置了 `death` penalty,[threading policy](https://developer.android.com/reference/android/os/StrictMode.ThreadPolicy.Builder) 设置为 `log`。在开发过程中仔细查看日志以发现并解决任何问题。 如果在开发过程中遇到由 StrictMode 引起的问题,你可以通过设置 `noStrictMode` Gradle 标志来临时禁用它: ```bash ./gradlew app:assembleFullDebug -PnoStrictMode ``` 如果需要禁用 StrictMode,请在 GitHub 上打开 issue 或在 Discord 上寻求帮助。这有助于确保问题被跟踪且不影响其他开发者。 --- url: /developers/android/tips/testing_pr_builds.md --- 你可以通过下载 CI 生成的 APK 制品来测试 pull request 中的更改,而无需在本地构建。 1. 前往 GitHub 上的 pull request。 2. 点击 **Checks** 选项卡。 3. 在左侧边栏中,点击 **Pull Request**。 4. 滚动到页面底部,找到 **Artifacts** 部分。 5. 下载 **APKs** 制品(包含所有 APK 变体的 ZIP 文件)。 6. 解压 ZIP 并找到 `full` 或 `minimal` APK。 7. 在设备上安装 APK: * **从手机上**:直接在手机上下载制品,并使用文件管理器应用安装。 * **使用 ADB**:在计算机上运行 `adb install path/to/app.apk`。 :::note 你必须登录到 GitHub 账户才能下载制品。CI 工作流也必须成功完成后 APK 才能供下载。 ::: :::note debug APK 与应用的生产版本并排安装,允许你同时安装两者。debug 版本有一个红色图标,以区别于生产应用。 ::: --- url: /developers/api/instance_discovery.md --- Home Assistant 会在本地网络上以 `_home-assistant._tcp.local.` mDNS/Zeroconf 服务的形式宣告自己。客户端(例如 companion apps)可以浏览该服务来发现实例,而无需向用户询问地址。 该服务在 [`frontend`](https://www.home-assistant.io/integrations/frontend/) 集成完成设置(或启动时)后注册,这样当记录发布时 HTTP 服务器已经启动并可达。 ## 服务记录 | Field | Value | | --- | --- | | Service type | `_home-assistant._tcp.local.` | | Instance name | `.`。`location_name` 中的 `.` 会被替换为空格,并截断以符合 63-byte DNS label 限制。发生名称冲突时,Zeroconf 会追加后缀(`allow_name_change`)。 | | Host (server) | `.local.`,其中 `` 为 instance ID。 | | Port | HTTP server 端口。Home Assistant OS 安装默认为 `80`,其他为 `8123`,除非通过 `SETUP_PORT` 环境变量更改。 | ## TXT 属性 | Property | Meaning | Default | | --- | --- | --- | | `location_name` | 友好 instance 名称,来自 `hass.config.location_name`。 | 未配置名称时为 `Home` | | `uuid` | instance ID(`core.uuid`);一个稳定的、不透明的 32 位十六进制标识符。同样用作 host 名(`.local.`)。 | 首次运行时生成 | | `version` | [Home Assistant Core version](/developers/versioning.md)。可选:客户端应将 optional 视为当前未知版本。这通常意味着 Core 尚未安装(例如初始设置期间显示的 landing page)。目前 landing page 以哨兵版本 `0000.0.0` 宣告。这不是有效的 Home Assistant Core 版本,仅是为绕过当前 Android 应用的限制。 | 当前 Core 版本 | | `internal_url` | 内部/LAN URL,通过 `get_url(..., allow_external=False)` 解析。 | 不可用时为 `""` | | `external_url` | 外部 URL,通过 `get_url(..., allow_internal=False)` 解析。 | 不可用时为 `""` | | `base_url` | 已弃用;为向后兼容保留。设置为 `external_url`,或无外部 URL 时为 `internal_url`。 | 两者都不可用时为 `""` | | `requires_api_password` | 遗留标志,始终宣告为 `True`。其引用的 `api_password` 认证机制已在 [0.90 中弃用](https://github.com/home-assistant/core/pull/21884),并在 [2024.7.0 中移除](https://github.com/home-assistant/core/pull/119976),因此该标志现已无意义。客户端不应再解析它。 | `True` | | `landingpage` | 仅在 Core 设置完成之前由 [landing page](https://github.com/home-assistant/landingpage) 发布的记录中存在,且设为 `True`。运行中的 Core 实例中不存在。 | 未设置 | :::note TXT property 值最多为 230 bytes(`key=value` 上限为 255)。任何超出该长度的值都会被抑制(替换为空字符串),以免破坏宣告。 ::: --- url: /developers/api/native-app-integration.md --- 本指南描述如何构建一个原生的 Home Assistant 应用,使其与 Home Assistant 通信并提供无缝集成。以下是本指南将要讨论的内容。 * 允许用户建立连接并使用自己的 Home Assistant 实例进行认证。 * 将位置和DeviceInfo 发送回 Home Assistant。 * 调用 service actions、触发 events 以及渲染 templates。 * 通过已认证的 webview 提供一个控制房屋视图。 --- url: /developers/api/native-app-integration/notifications.md --- `mobile_app` 集成内置了一个 notify platform,允许以一种通用方式向用户发送 push notifications,而无需安装外部自定义组件。Push notifications 可以通过 websocket 连接或通过云服务交付。 ## 启用 websocket push notifications 你的应用可以通过 WebSocket API 连接到 Home Assistant 来订阅 push notifications。要启用此功能,你的应用需要订阅 cloud push notifications,或者在注册时将 `push_websocket_channel: true` 添加到 `app_data` 对象中。 要创建 websocket channel,请创建 push notification 订阅: ```json { "id": 2, "type": "mobile_app/push_notification_channel", "webhook_id": "abcdefghkj", "support_confirm": true // 可选 } ``` 所有 push notifications 都会作为 websocket 连接上的 event 交付: ```json { "id": 2, "type": "event", "event": { "message": "Hello world", "hass_confirm_id": "12345" // 如果 confirm = true }, } ``` 如果启用了确认,你必须发送一个 websocket 命令来确认: ```json { "id": 3, "type": "mobile_app/push_notification_confirm", "webhook_id": "abcdefghkj", "confirm_id": "12345" } ``` 如果注册支持 cloud push notifications 且已连接以接收本地 push notifications,则 notifications 会先本地交付,如果应用未确认该 notification,则回退到 cloud。 ## 启用 cloud push notifications 要为你的应用启用 notify platform,你必须在初始注册期间或后来更新现有注册时,在 `app_data` 对象中设置两个 key。 | Key | Type | Description | | --- | ---- | ----------- | | `push_token` | string | 对用户的设备唯一的 push notification token。例如,这可以是 APNS token 或 FCM Instance ID/token。 | | `push_url` | string | 你的服务器上的 URL,push notifications 将通过 HTTP POST 发送到该 URL。 | 你应该建议用户在设置这些 key 后重启 Home Assistant,以便他们能看到 notify target。它将以 `notify.mobile_app_` 的格式出现。 ### 部署服务端组件 Notify platform 并不关心如何通知你的用户。它只是将一条 notification 转发到你的外部服务器,你应该在那里实际处理该请求。 这种方法允许你完全控制自己的 push notification 基础设施。 请参阅本文档的下一节,了解一个使用 Firebase Cloud Functions 和 Firebase Cloud Messaging 的 push notification forwarder 的示例服务器实现。 你的服务器应该接受像这样的 HTTP POST payload: ```json { "message": "Hello World", "title": "Test message sent via mobile_app.notify", "push_token": "my-secure-token", "registration_info": { "app_id": "io.home-assistant.iOS", "app_version": "1.0.0", "os_version": "12.2", "webhook_id": "webhook_id_from_registration" }, "data": { "key": "value" } } ``` :::info `webhook_id` 仅在 core-2021.11 或更高版本中提供。 ::: 假设 notification 已成功排队交付,它应该以 201 状态码响应。 ### 错误 如果发生错误,你应当以 *非* 201 或 429 的状态码返回对出错情况的描述。错误响应必须是 JSON 对象,可以包含以下 key 之一: | Key | Type | Description | | --- | ---- | ----------- | | `errorMessage` | string | 如果提供,它将附加到预设的错误消息后面。例如,如果 `errorMessage` 为"Could not communicate with Apple",它将以"Internal server error, please try again later: Could not communicate with Apple"的形式输出到日志中 | | `message` | string | 如果提供,它将以 warning 日志级别直接输出到日志中。 | 无论使用哪个 key,你都应该尽可能详细地描述出了什么问题,以及如果可能的话,用户如何修复它。 ### 速率限制 Notify platform 还支持向用户公开速率限制。Home Assistant 建议你实现保守的速率限制,以保持成本较低,同时避免用户收到过多 notifications。 仅供参考,Home Assistant Companion 每 24 小时最多可发送 150 条 notifications。速率限制会在 UTC 午夜对所有用户重置。当然,你可以自由使用任何配置来实现自己的速率限制。 如果你选择实现速率限制,你成功的服务器响应应如下所示: ```json { "rateLimits": { "successful": 1, "errors": 5, "maximum": 150, "resetsAt": "2019-04-08T00:00:00.000Z" } } ``` | Key | Type | Description | | --- | ---- | ----------- | | `successful` | integer | 用户在速率限制期间成功发送的 push notifications 数量。 | | `errors` | integer | 用户在速率限制期间发送失败的 push notifications 数量。 | | `maximum` | integer | 用户在速率限制期间最多可以发送的 push notifications 数量。 | | `resetsAt` | ISO8601 timestamp | 用户的速率限制期间过期的时间戳。必须以 UTC 时区提供。 | 每次成功发送 notification 后,速率限制都会以 warning 日志级别输出到日志中。Home Assistant 还会输出距离速率限制期间重置的剩余确切时间。 一旦用户在速率限制期间达到最多发送的 notifications 数量,你应该开始以 429 状态码响应,直到速率限制期间过期。响应对象可以选择包含 key `message`,它将输出到 Home Assistant 日志中,而不是标准的错误消息。 Notify platform 本身不实现任何速率限制保护。用户将持续向你发送 notifications,因此你应该在逻辑的尽可能早的阶段以 429 状态码拒绝他们。 ### 示例服务器实现 以下代码是一个 Firebase Cloud Function,它将 notifications 转发给 Firebase Cloud Messaging。要部署此代码,你应该创建一个名为 `rateLimits` 的 Firestore 数据库。然后,你可以部署以下代码。 此外,请确保你已经使用正确的 APNS 和 FCM 认证密钥正确配置了你的项目。 ```javascript 'use strict'; const functions = require('firebase-functions'); const admin = require('firebase-admin'); admin.initializeApp(); var db = admin.firestore(); const MAX_NOTIFICATIONS_PER_DAY = 150; exports.sendPushNotification = functions.https.onRequest(async (req, res) => { console.log('Received payload', req.body); var today = getToday(); var token = req.body.push_token; var ref = db.collection('rateLimits').doc(today).collection('tokens').doc(token); var payload = { notification: { body: req.body.message, }, token: token, }; if(req.body.title) { payload.notification.title = req.body.title; } if(req.body.data) { if(req.body.data.android) { payload.android = req.body.data.android; } if(req.body.data.apns) { payload.apns = req.body.data.apns; } if(req.body.data.data) { payload.data = req.body.data.data; } if(req.body.data.webpush) { payload.webpush = req.body.data.webpush; } } console.log('Notification payload', JSON.stringify(payload)); var docExists = false; var docData = { deliveredCount: 0, errorCount: 0, totalCount: 0, }; try { let currentDoc = await ref.get(); docExists = currentDoc.exists; if(currentDoc.exists) { docData = currentDoc.data(); } } catch(err) { console.error('Error getting document!', err); return handleError(res, 'getDoc', err); } if(docData.deliveredCount > MAX_NOTIFICATIONS_PER_DAY) { return res.status(429).send({ errorType: 'RateLimited', message: 'The given target has reached the maximum number of notifications allowed per day. Please try again later.', target: token, rateLimits: getRateLimitsObject(docData), }); } docData.totalCount = docData.totalCount + 1; var messageId; try { messageId = await admin.messaging().send(payload); docData.deliveredCount = docData.deliveredCount + 1; } catch(err) { docData.errorCount = docData.errorCount + 1; await setRateLimitDoc(ref, docExists, docData, res); return handleError(res, 'sendNotification', err); } console.log('Successfully sent message:', messageId); await setRateLimitDoc(ref, docExists, docData, res); return res.status(201).send({ messageId: messageId, sentPayload: payload, target: token, rateLimits: getRateLimitsObject(docData), }); }); async function setRateLimitDoc(ref, docExists, docData, res) { try { if(docExists) { console.log('Updating existing doc!'); await ref.update(docData); } else { console.log('Creating new doc!'); await ref.set(docData); } } catch(err) { if(docExists) { console.error('Error updating document!', err); } else { console.error('Error creating document!', err); } return handleError(res, 'setDocument', err); } return true; } function handleError(res, step, incomingError) { if (!incomingError) return null; console.error('InternalError during', step, incomingError); return res.status(500).send({ errorType: 'InternalError', errorStep: step, message: incomingError.message, }); } function getToday() { var today = new Date(); var dd = String(today.getDate()).padStart(2, '0'); var mm = String(today.getMonth() + 1).padStart(2, '0'); var yyyy = today.getFullYear(); return yyyy + mm + dd; } function getRateLimitsObject(doc) { var d = new Date(); return { successful: (doc.deliveredCount || 0), errors: (doc.errorCount || 0), total: (doc.totalCount || 0), maximum: MAX_NOTIFICATIONS_PER_DAY, remaining: (MAX_NOTIFICATIONS_PER_DAY - doc.deliveredCount), resetsAt: new Date(d.getFullYear(), d.getMonth(), d.getDate()+1) }; } ``` --- url: /developers/api/native-app-integration/sending-data.md --- 一旦你将应用注册到 mobile app 组件,你就可以开始通过提供的 webhook 信息与 Home Assistant 进行交互。 ## 通过 Rest API 发送 webhook 数据 第一步是将返回的 webhook ID 转换为完整的 URL:`/api/webhook/`。这将是我们所有交互所需要的唯一 url。webhook 端点不需要经过认证的请求。 如果在注册期间提供了 Cloudhook URL,你应默认使用该 URL,仅在该请求失败时才回退到上述构造的 URL。 如果在注册期间提供了 remote UI URL,你应在构造 URL 时将其用作 `instance_url`,仅在该 URL 失败时才回退到用户提供的 URL。 总结一下,请求应按如下方式进行: 1. 如果你有 Cloudhook URL,使用它直到某个请求失败。当请求失败时,进入步骤 2。 2. 如果你有 remote UI URL,用它构造 webhook URL:`/api/webhook/`。当请求失败时,进入步骤 3。 3. 使用设置期间提供的 instance URL 构造 webhook URL:`/api/webhook/`。 ## 通过 WebSocket API 发送 webhook 数据 Webhooks 也可以通过 WebSocket API 发送 `webhook/handle` 命令来交付: ```json { "type": "webhook/handle", "id": 5, "method": "GET", // 以下字段为可选 "body": "{\"hello\": \"world\"}", "headers": { "Content-Type": "application/json" }, "query": "a=1&b=2", } ``` 响应将如下所示: ```json { "type": "result", "id": 5, "result": { "body": "{\"ok": true}", "status": 200, "headers": {"Content-Type": response.content_type}, } } ``` ## 关于 instance URLs 的简短说明 一些用户已配置 Home Assistant,使其通过动态 DNS 服务可在家庭网络外部访问。有些路由器不支持 hairpinning / NAT loopback:设备从路由器网络内部,通过外部配置的 DNS 服务,向同样位于本地网络内部的 Home Assistant 发送数据。 为解决此问题,应用应记录用户家庭网络的 WiFi SSID,并在连接到家庭 WiFi 网络时使用直接连接。 ## 交互基础 ### 请求 所有交互都通过向 webhook url 发送 HTTP POST 请求来完成。这些请求不需要包含认证信息。 payload 格式取决于交互类型,但它们都共享一个共同的基底: ```json { "type": "<消息类型>", "data": {} } ``` 如果你在注册时收到 `secret`,你**必须**加密你的消息,并将其放入 payload 中,如下所示: ```json { "type": "encrypted", "encrypted": true, "encrypted_data": "<加密消息>" } ``` ### 响应 作为一般规则,期望所有请求都收到 200 响应。但有几种情况你会收到其他代码: * 如果你的 JSON 无效,你将收到 400 状态码。但如果加密的 JSON 无效,你将不会收到此错误。 * 在创建 sensor 时,你将收到 201。 * 如果你收到 404,则很可能是 `mobile_app` 组件未加载。 * 收到 410 表示该集成已被删除。你应该通知用户,并且很可能需要重新注册。 ## 实现加密 `mobile_app` 支持通过 [Sodium](https://libsodium.gitbook.io/doc/) 进行双向加密通信。 :::info Sodium 是一个现代、易于使用的软件库,用于加密、解密、签名、密码哈希等。 ::: ### 选择库 针对大多数现代编程语言和平台,都有封装 Sodium 的库。Sodium 本身用 C 编写。 以下是我们建议使用的一些库,尽管你可以自由使用任何对你来说效果良好的库。 * Swift/Objective-C: [swift-sodium](https://github.com/jedisct1/swift-sodium)(由 Sodium 开发者维护的官方库)。 对于其他语言,请参阅[Bindings for other languages](https://doc.libsodium.org/bindings_for_other_languages)列表。如果有多个选择,我们推荐使用最近更新且经过最多同行评审(一个简便的检查方法是查看项目有多少 GitHub stars)的选择。 ### 配置 我们使用 Sodium 的[secret-key cryptography](https://doc.libsodium.org/secret-key_cryptography)功能来加密和解密 payload。所有 payload 都以 Base64 编码的 JSON。对于 Base64 类型,使用 `sodium_base64_VARIANT_ORIGINAL`(即"original",无 padding,非 URL safe)。如果 payload 在未加密时不包含 `data` key(例如 [get\_config](https://developers.home-assistant.io/docs/api/native-app-integration/sending-data#get-config) 请求),则应改为加密一个空的 JSON 对象(`{}`)。 ### 信令加密支持 有两种方式启用加密支持: * **在初始注册期间**将 `supports_encryption` 设置为 `true`。 * **在初始注册之后**调用 `enable_encryption` webhook 操作。 Home Assistant 实例必须能够安装 `libsodium` 才能启用加密。通过初始注册或启用加密响应中是否存在 key `secret` 来确认你应该使所有未来的 webhook 请求加密。 你必须永远存储此 secret。无法通过 Home Assistant UI 恢复它,并且你**不应当**要求用户调查隐藏的存储文件以重新输入加密密钥。如果加密失败,你应当创建一个新的注册并提醒用户。 某个注册可能最初不支持加密,原因是 Home Assistant Core 一侧缺少 Sodium/NaCL。如果可能,你应始终努力加密通信。因此,我们礼貌地请求你时不时尝试自动启用加密,或允许用户通过应用中的按钮手动启用加密。这样,他们可以首先尝试修复导致 Sodium/NaCL 无法安装的任何错误,然后再拥有一个加密的注册。如果 Sodium/NaCL 无法安装,Home Assistant Core 会记录确切细节。 ## 更新设备位置 此消息将通知 Home Assistant 新的位置信息。 ```json { "type": "update_location", "data": { "gps": [12.34, 56.78], "gps_accuracy": 120, "battery": 45 } } ``` | Key | Type | Description | | --- | ---- | ----------- | | `location_name` | string | 设备所在的 zone 名称。 | | `gps` | latlong | 当前位置的纬度和经度。 | | `gps_accuracy` | int | GPS 精度(米)。必须大于 0。 | | `battery` | int | 设备剩余电池百分比。必须大于 0。 | | `speed` | int | 设备速度(米/秒)。必须大于 0。 | | `altitude` | int | 设备海拔(米)。必须大于 0。 | | `course` | int | 设备行进方向,以度为单位测量,相对于正北。必须大于 0。 | | `vertical_accuracy` | int | 海拔值的精度,以米为单位。必须大于 0。 | ## 调用 service action 在 Home Assistant 中调用 service action。 ```json { "type": "call_service", "data": { "domain": "light", "service": "turn_on", "service_data": { "entity_id": "light.kitchen" } } } ``` | Key | Type | Description | | --- | ---- | ----------- | | `domain` | string | service action 的 domain | | `service` | string | service action 名称 | | `service_data` | dict | 要发送给 service action 的数据 | ## 触发 event 在 Home Assistant 中触发 event。请注意 [Data Science portal](https://data.home-assistant.io/docs/events/#database-table) 上记录的数据结构。 ```json { "type": "fire_event", "data": { "event_type": "my_custom_event", "event_data": { "something": 50 } } } ``` | Key | Type | Description | | --- | ---- | ----------- | | `event_type` | string | 要触发的 event 类型 | | `event_data` | string | 要触发的 event 数据 | ## 渲染 templates 渲染一个或多个 templates 并返回结果。 ```json { "type": "render_template", "data": { "my_tpl": { "template": "Hello {{ name }}, you are {{ states('person.paulus') }}.", "variables": { "name": "Paulus" } } } } ``` `data` 必须包含一个 `key`: `dictionary` 的映射。结果将以 `{"my_tpl": "Hello Paulus, you are home"}` 的形式返回。这允许在单次调用中渲染多个 template。 | Key | Type | Description | | --- | ---- | ----------- | | `template` | string | 要渲染的 template | | `variables` | Dict | 要包含的额外 template 变量。 | ## 更新注册 更新你的应用注册。如果 app 版本或其他值发生变化,请使用此功能。 ```json { "type": "update_registration", "data": { "app_data": { "push_token": "abcd", "push_url": "https://push.mycool.app/push" }, "app_version": "2.0.0", "device_name": "Robbies iPhone", "manufacturer": "Apple, Inc.", "model": "iPhone XR", "os_version": "23.02" } } ``` 所有 key 均为可选。 | Key | Type | Description | | --- | --- | --- | | `app_data` | Dict | 如果应用有支持组件来扩展 mobile\_app 功能或希望启用 notification platform,则可使用应用数据。 | | `app_version` | string | 移动应用的版本。 | | `device_name` | string | 运行该应用的设备的名称。 | | `manufacturer` | string | 运行该应用的设备的制造商。 | | `model` | string | 运行该应用的设备的型号。 | | `os_version` | string | 运行该应用的设备的 OS 版本。 | ## 获取 zones 获取所有启用的 zones。 ```json { "type": "get_zones" } ``` ## 获取 config 返回一个版本的 `/api/config`,其中包含有助于配置应用的值。 ```json { "type": "get_config" } ``` ## 启用加密 *这需要 Home Assistant 0.106 或更高版本。* 为现有注册启用加密支持。 ```json { "type": "enable_encryption" } ``` 你可能收到两种错误: * `encryption_already_enabled` - 此注册已经启用了加密 * `encryption_not_available` - 无法安装 Sodium/NaCL。停止所有未来启用加密的尝试。 ## 流式传输 camera *这需要 Home Assistant 0.112 或更高版本。* 获取有关如何流式传输 Camera 的路径信息。 ```json { "type": "stream_camera", "data": { "camera_entity_id": "camera.name_here" } } ``` | Key | Type | Description | | --- | ---- | ----------- | | `camera_entity_id` | string | 要获取流式信息的 camera entity | 响应将包含通过 HLS 或通过 MJPEG image 预览流式传输的路径。 ```json { "hls_path": "/api/hls/…/playlist.m3u8", "mjpeg_path": "/api/camera_proxy_stream/…" } ``` 如果 HLS 流式传输不可用,`hls_path` 将为 `null`。有关如何构造完整 URL,请参见上面关于 instance URL 的说明。 ## 处理 conversation *这需要 Home Assistant 2023.2.0 或更高版本。* 使用 conversation 集成处理一个句子。 ```json { "type": "conversation_process", "data": { "text": "Turn on the lights", "language": "en", "conversation_id": "ABCD", } } ``` 有关可用的 key 和响应,请参阅[conversation API 文档](/developers/intent_conversation_api.md)。 --- url: /developers/api/native-app-integration/sensors.md --- `mobile_app` 集成支持暴露自定义 sensors,这些 sensors 可以通过你的应用完全管理。 ## 注册 sensor 所有 sensors 在获得更新之前都必须先注册。与更新 sensors 不同,你一次只能注册一个 sensor。 要注册 sensor,请像这样向 webhook 发送请求: ```json { "data": { "attributes": { "foo": "bar" }, "device_class": "battery", "icon": "mdi:battery", "name": "Battery State", "state": "12345", "type": "sensor", "unique_id": "battery_state", "unit_of_measurement": "%", "state_class": "measurement", "entity_category": "diagnostic", "disabled": true }, "type": "register_sensor" } ``` 有效的 key 如下: | Key | Type | Required | Description | |-----|------|----------|-------------| | attributes | object | No | 附加到 sensor 的 attributes | | device\_class | string | No | 有效的 device classes 之一。[Binary Sensor Classes](https://www.home-assistant.io/integrations/binary_sensor/#device-class), [Sensor Classes](https://www.home-assistant.io/integrations/sensor/#device-class) | | icon | Material Design Icon (string) | No | 必须以 `mdi:` 为前缀。如果未提供,默认值为 `mdi:cellphone` | | name | string | Yes | sensor 的名称 | | state | bool, float, int, string | Yes | sensor 的 state | | type | string | Yes | sensor 的类型。必须是 `binary_sensor` 或 `sensor` 之一 | | unique\_id | string | Yes | 对该应用的此安装唯一的标识符。你稍后会用到它。通常最好使用 sensor 名称的安全版本 | | unit\_of\_measurement | string | No | sensor 的测量单位 | | state\_class | string | No | entity 的[state class](/developers/core/entity/sensor.md#available-state-classes)(仅适用于 sensors) | | entity\_category | string | No | entity 的 category | | disabled | boolean | No | 该 entity 是否应启用或禁用。 | Sensors 在注册后就会立即出现。 ## 更新 sensor 一旦 sensor 已注册,你需要更新它。这与注册它非常相似,但你可以同时更新所有的 sensors。 例如,要更新上述注册的 sensor,你需要发送以下内容: ```json { "data": [ { "attributes": { "hello": "world" }, "icon": "mdi:battery", "state": 123, "type": "sensor", "unique_id": "battery_state" } ], "type": "update_sensor_states" } ``` 更新期间仅允许部分 key: | Key | Type | Required | Description | |-----|------|----------|-------------| | attributes | object | No | 附加到 sensor 的 attributes | | icon | Material Design Icon (string) | No | 必须以 `mdi:` 为前缀 | | state | bool, float, int, string | Yes | sensor 的 state | | type | string | Yes | sensor 的类型。必须是 `binary_sensor` 或 `sensor` 之一 | | unique\_id | string | Yes | 对该应用的此安装唯一的标识符。你稍后会用到它。通常最好使用 sensor 名称的安全版本 | 更新 sensor 的响应是一个以 unique\_id => 更新结果为映射的字典。 如果 entity 在 Home Assistant 内部被禁用,成功的更新将添加 key `is_disabled`。这意味着应用可以停止向该 sensor 发送更新。 如果更新不成功,将返回错误。 ```json { "battery_state": { "success": true }, "battery_level": { "success": true, "is_disabled": true }, "battery_charging": { "success": false, "error": { "code": "not_registered", "message": "Entity is not registered", } }, "battery_charging_state": { "success": false, "error": { "code": "invalid_format", "message": "Unexpected value for type", } } ``` ## 保持 sensors 与 Home Assistant 同步 用户可以在 Home Assistant 中启用和禁用 entities。禁用的 entity 不会被添加到 Home Assistant,即使集成提供了它。这意味着手机继续向未在 Home Assistant 中启用的 entities 发送数据是没有意义的。 **当 sensor 在应用中启用/禁用时**,应用应为此 sensor 发送 `register_sensor` webhook,并将 `disabled` 设置为 `true` 或 `false`。 **当 mobile app 发送 `update_sensor_states` webhook 以更新被禁用的 entity 的数据时**,更新结果将包含 key `is_disabled`,其值为 `true`。这是 mobile app 需要将 Home Assistant 中的启用状态同步到 mobile app 的指示器。 ```json { "battery_level": { "success": true, }, "battery_charging": { "success": true, "is_disabled": true } } ``` **当用户在 Home Assistant 中启用/禁用 entity 时,需要将其同步到 mobile app。** `get_config` webhook 响应包含 key `entities`。这是一个将 `unique_id` 映射到 `{"disabled": boolean}` 的字典。mobile app 应采用这些启用设置。 ```json { // ... "entities": { "battery_level": { "disabled": false }, "battery_charging": { "disabled": true }, } } ``` --- url: /developers/api/native-app-integration/setup.md --- 当用户首次打开应用时,他们需要连接到本地实例以进行认证并注册设备。 ## 用户认证 如果 Home Assistant 已配置 [zeroconf integration],则可通过搜索 `_home-assistant._tcp.local.` 来发现本地实例。如果未配置,则需要向用户询问其实例的本地地址。 当实例地址已知时,应用会要求用户通过 [OAuth2 with Home Assistant] 进行认证。Home Assistant 使用 IndieAuth,这意味着要能重定向到触发你应用的 url,你需要采取一些额外步骤。务必仔细阅读 "Clients" 部分的最后一段。 [zeroconf integration]: https://www.home-assistant.io/integrations/zeroconf [OAuth2 with Home Assistant]: auth_api.md ## 注册设备 *这需要 Home Assistant 0.90 或更高版本。* Home Assistant 有一个 `mobile_app` 组件,允许应用注册自身并与实例交互。这是一个通用的组件,用于处理大多数常见的移动应用任务。如果你的应用需要比该组件提供的更多类型的交互,可以通过自定义交互来扩展此组件。 一旦你获得了用于认证用户的 tokens,就到了在 Home Assistant 中将应用注册到 mobile app 集成的时候了。 ### 准备工作 首先,你必须确保 `mobile_app` 集成已加载。有两种方式可以做到这一点: * 你可以发布一条 Zeroconf/Bonjour 记录 `_hass-mobile-app._tcp.local.` 来触发 `mobile_app` 集成的自动加载。你应在发布记录后至少等待 60 秒再继续。 * 你可以要求用户在他们的 configuration.yaml 中添加 `mobile_app` 并重启 Home Assistant。如果用户的配置中已经有 `default_config`,那么 `mobile_app` 应该已经加载了。 你可以通过检查 [`/api/config` REST API 调用](/developers/api/rest.md#get-api-config) 的 `components` 数组来确认 `mobile_app` 组件已加载。如果你继续设备注册并收到 404 状态码,那么它很可能尚未加载。 ### 注册设备 要注册设备,请向 `/api/mobile_app/registrations` 发送一个经过认证的 POST 请求。[有关如何发起经过认证的请求的更多信息。](/developers/auth_api.md#making-authenticated-requests) 发送到注册端点的示例 payload: ```json { "device_id": "ABCDEFGH", "app_id": "awesome_home", "app_name": "Awesome Home", "app_version": "1.2.0", "device_name": "Robbies iPhone", "manufacturer": "Apple, Inc.", "model": "iPhone X", "os_name": "iOS", "os_version": "iOS 10.12", "supports_encryption": true, "app_data": { "push_notification_key": "abcdef" } } ``` | Key | Required | Type | Description | | --- | -------- | ---- | ----------- | | `device_id` | V | string | 该设备的唯一标识符。Home Assistant 0.104 中新增。 | | `app_id` | V | string | 该应用的唯一标识符。 | | `app_name` | V | string | 移动应用的名称。 | | `app_version` | V | string | 移动应用的版本。 | | `device_name` | V | string | 运行该应用的设备的名称。 | | `manufacturer` | V | string | 运行该应用的设备的制造商。 | | `model` | V | string | 运行该应用的设备的型号。 | | `os_name` | V | string | 运行该应用的 OS 名称。 | | `os_version` | V | string | 运行该应用的设备的 OS 版本。 | | `supports_encryption` | V | bool | 应用是否支持加密。另见[加密部分](/developers/api/native-app-integration/sending-data.md#implementing-encryption)。 | | `app_data` | | Dict | 如果应用有支持组件来扩展 `mobile_app` 功能,则可使用应用数据。 | 当你收到 200 响应时,移动应用已注册到 Home Assistant。响应是一个 JSON 文档,将包含如何与 Home Assistant 实例交互的 URLs。你应该永久存储此信息。 ```json { "cloudhook_url": "https://hooks.nabu.casa/randomlongstring123", "remote_ui_url": "https://randomlongstring123.ui.nabu.casa", "secret": "qwerty", "webhook_id": "abcdefgh" } ``` | Key | Type | Description | | --- | ---- | ----------- | | `cloudhook_url` | string | 由 Home Assistant Cloud 提供的 cloudhook URL。仅当用户积极订阅 Nabu Casa 时才会提供。 | | `remote_ui_url` | string | 由 Home Assistant Cloud 提供的 remote UI URL。仅当用户积极订阅 Nabu Casa 时才会提供。 | | `secret` | string | 用于加密通信的密钥。仅当应用和 Home Assistant 实例都支持加密时才会包含。[更多信息](/developers/api/native-app-integration/sending-data.md#implementing-encryption)。 | | `webhook_id` | string | 可用于发送数据的 webhook ID。 | --- url: /developers/api/native-app-integration/webview.md --- 你的应用程序已经要求用户进行了认证。这意味着当用户打开 Home Assistant UI 时,你的应用不应该再次要求用户认证。 为了实现这一点,Home Assistant UI 支持[外部认证](frontend/external-authentication.md)。这允许你的应用提供 hooks,使前端向你的应用请求 access tokens。 Home Assistant 还支持前端与应用之间的进一步集成,通过[外部总线](frontend/external-bus.md)实现。 注意,此功能需要直接连接到实例。 --- url: /developers/api/rest.md --- import ApiEndpoint from '@site/static/js/api\_endpoint.jsx' Home Assistant 在与 web frontend 相同的端口上提供了一个 RESTful API。Home Assistant OS 安装上默认为 80,否则为 8123,除非通过 `SETUP_PORT` 环境变量更改了端口。 如果你的配置中没有使用 [`frontend`](https://www.home-assistant.io/integrations/frontend/),则需要在 `configuration.yaml` 文件中添加 [`api` 集成](https://www.home-assistant.io/integrations/api/)。 * `http://IP_ADDRESS:8123/` 是用于控制 Home Assistant 的接口。 * `http://IP_ADDRESS:8123/api/` 是一个 RESTful API。 API 只接受和返回 JSON 编码的对象。 所有 API 调用都必须附带 header `Authorization: Bearer TOKEN`,其中 `TOKEN` 应替换为你的唯一 access token。你可以使用 Web 浏览器登录 frontend,然后转到[你的 profile](https://www.home-assistant.io/docs/authentication/#your-account-profile) `http://IP_ADDRESS:8123/profile` 来获取一个 token("Long-Lived Access Token")。注意复制完整的 key。 有多种方式可以消费 Home Assistant Rest API。其中一种是使用 `curl`: ```shell curl \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ http://IP_ADDRESS:8123/ENDPOINT ``` 另一种选择是使用 Python 和 [Requests](https://requests.readthedocs.io/en/latest/) 模块。 ```python from requests import get url = "http://localhost:8123/ENDPOINT" headers = { "Authorization": "Bearer TOKEN", "content-type": "application/json", } response = get(url, headers=headers) print(response.text) ``` 另一种选择是在 Home Assistant 自动化或脚本中使用 [RESTful Command 集成](https://www.home-assistant.io/integrations/rest_command/)。 ```yaml turn_light_on: url: http://localhost:8123/api/states/light.study_light method: POST headers: authorization: 'Bearer TOKEN' content-type: 'application/json' payload: '{"state":"on"}' ``` 成功的调用将返回状态码 200 或 201。还可能返回的其他状态码有: * 400 (Bad Request) * 401 (Unauthorized) * 404 (Not Found) * 405 (Method Not Allowed) ### 操作 API 支持以下 actions: 如果 API 正在运行,则返回一条消息。 ```json { "message": "API running." } ``` 示例 `curl` 命令: ```shell curl \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" http://localhost:8123/api/ ``` 注意:请确保包含末尾的 `/`,完整路径是 `/api/`,而不是 `/api` 以 JSON 形式返回当前的 configuration。 ```json { "components":[ "sensor.cpuspeed", "frontend", "config.core", "http", "map", "api", "sun", "config", "discovery", "conversation", "recorder", "group", "sensor", "websocket_api", "automation", "config.automation", "config.customize" ], "config_dir":"/home/ha/.homeassistant", "elevation":510, "latitude":45.8781529, "location_name":"Home", "longitude":8.458853651, "time_zone":"Europe/Zurich", "unit_system":{ "length":"km", "mass":"g", "temperature":"\u00b0C", "volume":"L" }, "version":"0.56.2", "whitelist_external_dirs":[ "/home/ha/.homeassistant/www", "/home/ha/.homeassistant/" ] } ``` 示例 `curl` 命令: ```shell curl \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" http://localhost:8123/api/config ``` 返回当前已加载的 components 列表。 ``` [ "currentcost.sensor", "tapo.switch", "tuya_ble.sensor", "backup", "ble_monitor.binary_sensor", "localtuya.remote", "logger", "http", "hacs", "cast", "device_tracker", "upnp.binary_sensor", "notify", "person", ... ] ``` 示例 `curl` 命令: ```shell curl \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" http://localhost:8123/api/components ``` 返回一个 event 对象数组。每个 event 对象包含 event 名称和 listener 计数。 ```json [ { "event": "state_changed", "listener_count": 5 }, { "event": "time_changed", "listener_count": 2 } ] ``` 示例 `curl` 命令: ```shell curl \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" http://localhost:8123/api/events ``` 返回一个 service 对象数组。每个对象包含 domain 以及它所包含的 services。 ```json [ { "domain": "browser", "services": [ "browse_url" ] }, { "domain": "keyboard", "services": [ "volume_up", "volume_down" ] } ] ``` 示例 `curl` 命令: ```shell curl \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" http://localhost:8123/api/services ``` 返回过去状态变化的数组。每个对象包含实体的更多详细信息。 ``(`YYYY-MM-DDThh:mm:ssTZD`)是可选的,默认为请求时间前 1 天。它决定了该期间的开始。 以下参数是**必需的**: * `filter_entity_id=` 按一个或多个 entities 过滤,以逗号分隔。 你可以传递以下可选 GET 参数: * `end_time=` 以 URL 编码格式选择期间的结束时间(默认为 1 天)。 * `minimal_response` 仅对第一个和最后一个 state 以外的 states 返回 `last_changed` 和 `state`(快得多)。 * `no_attributes` 跳过从数据库返回 attributes(快得多)。 * `significant_changes_only` 仅返回重要的 state 变化。 不带 `minimal_response` 的示例 ```json [ [ { "attributes": { "friendly_name": "Weather Temperature", "unit_of_measurement": "\u00b0C" }, "entity_id": "sensor.weather_temperature", "last_changed": "2016-02-06T22:15:00+00:00", "last_updated": "2016-02-06T22:15:00+00:00", "state": "-3.9" }, { "attributes": { "friendly_name": "Weather Temperature", "unit_of_measurement": "\u00b0C" }, "entity_id": "sensor.weather_temperature", "last_changed": "2016-02-06T22:15:00+00:00", "last_updated": "2016-02-06T22:15:00+00:00", "state": "-1.9" }, ] ] ``` 带 `minimal_response` 的示例 ```json [ [ { "attributes": { "friendly_name": "Weather Temperature", "unit_of_measurement": "\u00b0C" }, "entity_id": "sensor.weather_temperature", "last_changed": "2016-02-06T22:15:00+00:00", "last_updated": "2016-02-06T22:15:00+00:00", "state": "-3.9" }, { "last_changed": "2016-02-06T22:20:00+00:00", "state": "-2.9" }, { "last_changed": "2016-02-06T22:22:00+00:00", "state": "-2.2" }, { "attributes": { "friendly_name": "Weather Temperature", "unit_of_measurement": "\u00b0C" }, "entity_id": "sensor.weather_temperature", "last_changed": "2016-02-06T22:25:00+00:00", "last_updated": "2016-02-06T22:25:00+00:00", "state": "-1.9" }, ] ] ``` 示例 `curl` 命令: ```shell # 过去一天的实体 'sensor.temperature' 的历史(默认) curl \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ "http://localhost:8123/api/history/period?filter_entity_id=sensor.temperature" ``` ```shell # 过去一天中实体 'sensor.temperature' 和 'sensor.kitchen_temperature' 的最小历史,起始日期手动设置为 2023-09-04 curl \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ "http://localhost:8123/api/history/period/2023-09-04T00:00:00+02:00?filter_entity_id=sensor.temperature,sensor.kitchen_temperature&minimal_response" ``` ```shell # 实体 'sensor.temperature' 在 2021-09-04 到 2023-09-04 期间的历史 # 使用 URL 编码的 timestamps curl \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ "http://localhost:8123/api/history/period/2021-09-04T00%3A00%3A00%2B02%3A00?end_time=2023-09-04T00%3A00%3A00%2B02%3A00&filter_entity_id=sensor.temperature" ``` 返回一个 logbook 条目数组。 ``(`YYYY-MM-DDThh:mm:ssTZD`)是可选的,默认为请求时间前 1 天。它决定了该期间的开始。 你可以传递以下可选 GET 参数: * `entity=` 按单个 entity 过滤。 * `end_time=` 以 URL 编码格式选择从 `` 开始的期间结束时间。 示例 ```json [ { "context_user_id": null, "domain": "alarm_control_panel", "entity_id": "alarm_control_panel.area_001", "message": "changed to disarmed", "name": "Security", "when": "2020-06-20T16:44:26.127295+00:00" }, { "context_user_id": null, "domain": "homekit", "entity_id": "alarm_control_panel.area_001", "message": "send command alarm_arm_night for Security", "name": "HomeKit", "when": "2020-06-21T02:59:05.759645+00:00" }, { "context_user_id": null, "domain": "alarm_control_panel", "entity_id": "alarm_control_panel.area_001", "message": "changed to armed_night", "name": "Security", "when": "2020-06-21T02:59:06.015463+00:00" } ] ``` 示例 `curl` 命令: ```shell curl \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ http://localhost:8123/api/logbook/2016-12-29T00:00:00+02:00 ``` ```shell curl \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ "http://localhost:8123/api/logbook/2016-12-29T00:00:00+02:00?end_time=2099-12-31T00%3A00%3A00%2B02%3A00&entity=sensor.temperature" ``` ```shell curl \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ "http://localhost:8123/api/logbook/2016-12-29T00:00:00+02:00?end_time=2099-12-31T00%3A00%3A00%2B02%3A00" ``` 返回一个 state 对象数组。每个 state 具有以下 attributes:`entity_id`、`state`、`last_changed` 和 `attributes`。 ```json [ { "attributes": {}, "entity_id": "sun.sun", "last_changed": "2016-05-30T21:43:32.418320+00:00", "state": "below_horizon" }, { "attributes": {}, "entity_id": "process.Dropbox", "last_changed": "22016-05-30T21:43:32.418320+00:00", "state": "on" } ] ``` 示例 `curl` 命令: ```shell curl \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" http://localhost:8123/api/states ``` 返回指定 `entity_id` 的 state 对象。如果未找到则返回 404。 ```json { "attributes":{ "azimuth":336.34, "elevation":-17.67, "friendly_name":"Sun", "next_rising":"2016-05-31T03:39:14+00:00", "next_setting":"2016-05-31T19:16:42+00:00" }, "entity_id":"sun.sun", "last_changed":"2016-05-30T21:43:29.204838+00:00", "last_updated":"2016-05-30T21:50:30.529465+00:00", "state":"below_horizon" } ``` 示例 `curl` 命令: ```shell curl \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ http://localhost:8123/api/states/sensor.kitchen_temperature ``` 作为纯文本响应检索 Home Assistant 当前会话期间记录的所有错误。 ```text 15-12-20 11:02:50 homeassistant.components.recorder: Found unfinished sessions 15-12-20 11:03:03 netdisco.ssdp: Error fetching description at http://192.168.1.1:8200/rootDesc.xml 15-12-20 11:04:36 homeassistant.components.alexa: Received unknown intent HelpIntent ``` 示例 `curl` 命令: ```shell curl \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ http://localhost:8123/api/error_log ``` 返回指定 camera `entity_id` 的数据(image)。 示例 `curl` 命令: ```shell curl \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ -o image.jpg \ "http://localhost:8123/api/camera_proxy/camera.my_sample_camera?time=1462653861261" ``` 返回 calendar entities 列表。 ```json [ { "entity_id": "calendar.holidays", "name": "National Holidays", }, { "entity_id": "calendar.personal", "name": "Personal Calendar", } ] ``` 示例 `curl` 命令: ```shell curl \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ http://localhost:8123/api/calendars ``` 返回指定 calendar `entity_id` 在 `start` 和 `end` 时间(不含)之间的[calendar events](/developers/core/entity/calendar.md#calendarevent)列表。 响应中的 events 包含 `start` 和 `end`,全天事件的值为 `date`,其他事件为 `dateTime`。 ```json [ { "summary": "Cinco de Mayo", "start": { "date": "2022-05-05" }, "end": { "date": "2022-05-06" }, }, { "summary": "Birthday Party", "start": { "dateTime": "2022-05-06T20:00:00-07:00" }, "end": { "dateTime": "2022-05-06T23:00:00-07:00" }, "description": "Don't forget to bring balloons", "location": "Brian's House" } ] ``` 示例 `curl` 命令: ```shell curl \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ "http://localhost:8123/api/calendars/calendar.holidays?start=2022-05-01T07:00:00.000Z&end=2022-06-12T07:00:00.000Z" ``` 更新或创建一个 state。你可以创建任何你想要的 state,它不需要由 Home Assistant 中的 entity 支持。 :::info 此 endpoint 设置设备在 Home Assistant 内部的表示,不会与实际设备通信。要与设备通信,请使用 [POST /api/services/\/\](#post-api-services-domain-service) endpoint。 ::: 期望一个 JSON 对象,至少包含一个 state 属性: ```json { "state": "below_horizon", "attributes": { "next_rising":"2016-05-31T03:39:14+00:00", "next_setting":"2016-05-31T19:16:42+00:00" } } ``` 如果 entity 已存在,返回码为 200;如果是新 entity 的 state 被设置,返回码为 201。将返回一个包含新资源 URL 的 location header。响应体将包含一个 JSON 编码的 State 对象。 ```json { "attributes": { "next_rising":"2016-05-31T03:39:14+00:00", "next_setting":"2016-05-31T19:16:42+00:00" }, "entity_id": "sun.sun", "last_changed": "2016-05-30T21:43:29.204838+00:00", "last_updated": "2016-05-30T21:47:30.533530+00:00", "state": "below_horizon" } ``` 示例 `curl` 命令: ```shell curl \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ -d '{"state": "25", "attributes": {"unit_of_measurement": "°C"}}' \ http://localhost:8123/api/states/sensor.kitchen_temperature ``` 使用 [Requests](https://requests.readthedocs.io/en/master/) 模块的示例 `python` 命令: ```shell from requests import post url = "http://localhost:8123/api/states/sensor.kitchen_temperature" headers = {"Authorization": "Bearer TOKEN", "content-type": "application/json"} data = {"state": "25", "attributes": {"unit_of_measurement": "°C"}} response = post(url, headers=headers, json=data) print(response.text) ``` 以 `event_type` 触发一个 event。请注意 [Data Science portal](https://data.home-assistant.io/docs/events/#database-table) 上记录的数据结构。 你可以传递一个可选的 JSON 对象作为 `event_data`。 ```json { "next_rising":"2016-05-31T03:39:14+00:00", } ``` 如果成功,则返回一条消息。 ```json { "message": "Event download_file fired." } ``` 在特定 domain 内调用一个 service。将在 service 执行完毕后返回。 你可以传递一个可选的 JSON 对象作为 `service_data`。 ```json { "entity_id": "light.Ceiling" } ``` 返回 service 执行期间发生变化的 states 列表,以及(如果 service 支持)可选的 response data。 ```json [ { "attributes": {}, "entity_id": "sun.sun", "last_changed": "2016-05-30T21:43:32.418320+00:00", "state": "below_horizon" }, { "attributes": {}, "entity_id": "process.Dropbox", "last_changed": "22016-05-30T21:43:32.418320+00:00", "state": "on" } ] ``` :::tip 结果将包括 service 执行期间发生的所有 state 变化,即使这些变化是由系统中其他事件引起的。 ::: 如果你调用的 service 支持返回 response data,你可以通过在 URL 中添加 `?return_response` 来获取它。你的响应随后将同时包含已变化 entities 列表和 service response data。 ```json { "changed_states": [ { "attributes": {}, "entity_id": "sun.sun", "last_changed": "2024-04-22T20:45:54.418320-04:00", "state": "below_horizon" }, { "attributes": {}, "entity_id": "binary_sensor.dropbox", "last_changed": "2024-04-22T20:45:54.418320-04:00", "state": "on" } ], "service_response": { "weather.new_york_forecast": { "forecast": [ { "condition": "clear-night", "datetime": "2024-04-22T20:45:55.173725-04:00", "precipitation_probability": 0, "temperature": null, "templow": 6.0 }, { "condition": "rainy", "datetime": "2024-04-23T20:45:55.173756-04:00", "precipitation_probability": 60, "temperature": 16.0, "templow": 4.0 } ] } } } ``` :::note 一些 services 不返回数据,一些可选择性地返回 response data,还有一些总是返回 response data。 如果你调用一个必须返回数据的 service 但没有使用 `return_response`,API 将返回 400。同样,如果你调用一个不返回任何数据的 service 但使用了 `return_response`,也会收到 400。 ::: 示例 `curl` 命令: 打开灯: ```shell curl \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ -d '{"entity_id": "switch.christmas_lights"}' \ http://localhost:8123/api/services/switch/turn_on ``` 使用 [Requests](https://requests.readthedocs.io/en/master/) 模块的示例 `python` 命令: 打开灯: ```shell from requests import post url = "http://localhost:8123/api/services/light/turn_on" headers = {"Authorization": "Bearer TOKEN"} data = {"entity_id": "light.study_light"} response = post(url, headers=headers, json=data) print(response.text) ``` 发送 MQTT 消息: ```shell curl \ -H "Content-Type: application/json" \ -H "Authorization: Bearer TOKEN" \ -d '{"payload": "OFF", "topic": "home/fridge", "retain": "True"}' \ http://localhost:8123/api/services/mqtt/publish ``` 获取每日天气预报信息: ```shell curl \ -H "Content-Type: application/json" \ -H "Authorization: Bearer TOKEN" \ -d '{"entity_id": "weather.forecast_home", "type": "daily"}' \ http://localhost:8123/api/services/weather/get_forecasts?return_response ``` 渲染一个 Home Assistant template。[更多信息请参阅 template 文档。](https://www.home-assistant.io/docs/configuration/templating) ```json { "template": "Paulus is at {{ states('device_tracker.paulus') }}!" } ``` 以纯文本形式返回渲染后的 template。 ```text Paulus is at work! ``` 示例 `curl` 命令: ```shell curl \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ -d '{"template": "It is {{ now() }}!"}' http://localhost:8123/api/template ``` 触发对 `configuration.yaml` 的检查。此请求无需传递额外数据。需要启用 config 集成。 如果检查成功,将返回以下内容: ```json { "errors": null, "result": "valid" } ``` 如果检查失败,对象中的 errors 属性将列出导致检查失败的原因。例如: ```json { "errors": "Integration not found: frontend:", "result": "invalid" } ``` 处理一个 intent。 你必须在 `configuration.yaml` 中添加 `intent:` 才能启用此 endpoint。 示例 `curl` 命令: ```shell curl \ -H "Authorization: Bearer TOKEN" \ -H 'Content-Type: application/json' \ -d '{ "name": "SetTimer", "data": { "seconds": "30" } }' \ http://localhost:8123/api/intent/handle ``` 删除具有指定 `entity_id` 的 entity。 示例 `curl` 命令: ```shell curl \ -X DELETE \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ http://localhost:8123/api/states/sensor.kitchen_temperature ``` --- url: /developers/api/supervisor/endpoints.md --- import ApiEndpoint from '@site/static/js/api\_endpoint.jsx' 对于标记有 :lock: 的 API endpoints,你需要使用带有 `Bearer` token 的 authorization header。 该 token 对 apps(原称 add-ons)和 Home Assistant 可通过 `SUPERVISOR_TOKEN` 环境变量获取。 要查看每个 endpoint 的更多细节,点击展开即可。 ### 应用 返回已安装 app 的概述信息。 **Payload:** | key | type | description | |-----|------|-------------| | addons | list | [Addon models](api/supervisor/models.md#app-formerly-known-as-an-add-on) 列表 | **Example response:** ```json { "addons": [ { "name": "Awesome app", "slug": "awesome_addon", "description": "My awesome app", "advanced": false, "stage": "stable", "repository": "core", "version": null, "version_latest": "1.0.1", "update_available": false, "installed": false, "detached": true, "available": true, "build": false, "url": null, "icon": false, "logo": false, "system_managed": false } ] } ``` 重新加载关于 app 的存储信息。 获取 app 的 changelog。 获取 app 的 documentation。 通过 Systemd journal 后端获取 app 的 logs。 该 endpoint 接受与 `/host/logs` 相同的 headers 并提供相同的功能。 与 `/addons//logs` 相同,区别在于它会持续返回新的 log entries。 返回该 app 容器最近一次启动的所有 logs。 `Range` header 被忽略,但可以使用 `lines` query 参数。 获取与特定 boot 相关的 app logs。 `bootid` 参数的解释方式与 `/host/logs/boots/` 中相同,该 endpoint 否则提供与 `/host/logs` 相同的功能。 与 `/addons//logs/boots/` 相同,区别在于它会持续返回新的 log entries。 获取 app icon 获取关于 app 的详细信息 **Returned data:** | key | type | description | |-----|------|-------------| | advanced | boolean | 已弃用且被忽略;自 Supervisor 2026.03.0 起始终为 `false` | | apparmor | string | disabled、default 或 profile 名称 | | arch | list | app 支持的架构列表 | | audio | boolean | 已启用 audio 时为 `true` | | audio\_input | float or null | 设备索引 | | audio\_output | float or null | 设备索引 | | auth\_api | boolean | 已授予 auth api 访问权限时为 `true` | | auto\_uart | boolean | 已授予 auto\_uart 访问权限时为 `true` | | auto\_update | boolean | 已启用 auto update 时为 `true` | | available | boolean | app 可用时为 `true` | | boot | string | "auto" 或 "manual" | | boot\_config | string | addon 的默认 boot 模式,或无法自动 boot 时为 "manual\_only" | | build | boolean | 本地 app 时为 `true` | | changelog | boolean | changelog 可用时为 `true` | | description | string | app 描述 | | detached | boolean | app 以 detached 方式运行时为 `true` | | devices | list | 附加的设备列表 | | devicetree | boolean | 已授予 devicetree 访问权限时为 `true` | | discovery | list | discovery 服务列表 | | dns | list | app 使用的 DNS server 列表 | | docker\_api | boolean | 已授予 docker\_api 访问权限时为 `true` | | documentation | boolean | documentation 可用时为 `true` | | full\_access | boolean | 已授予完全访问权限时为 `true` | | gpio | boolean | 已授予 gpio 访问权限时为 `true` | | hassio\_api | boolean | 已授予 hassio api 访问权限时为 `true` | | hassio\_role | string | hassio role(default, homeassistant, manager, admin) | | homeassistant | string or null | 最低的 Home Assistant Core 版本 | | homeassistant\_api | boolean | 已授予 homeassistant api 访问权限时为 `true` | | host\_dbus | boolean | 已授予 host dbus 访问权限时为 `true` | | host\_ipc | boolean | 已授予 host ipc 访问权限时为 `true` | | host\_network | boolean | 已授予 host network 访问权限时为 `true` | | host\_pid | boolean | 已授予 host pid 访问权限时为 `true` | | host\_uts | boolean | 已启用 host UTS 命名空间访问时为 `true`。 | | hostname | string | app 的 host 名 | | icon | boolean | icon 可用时为 `true` | | ingress | boolean | 已启用 ingress 时为 `true` | | ingress\_entry | string or null | ingress 入口点 | | ingress\_panel | boolean or null | 已启用 ingress\_panel 时为 `true` | | ingress\_port | int or null | ingress 端口 | | ingress\_url | string or null | ingress URL | | ip\_address | string | app 的 IP 地址 | | kernel\_modules | boolean | 已授予 kernel module 访问权限时为 `true` | | logo | boolean | logo 可用时为 `true` | | long\_description | string | app 的长描述 | | machine | list | app 支持的 machine 类型列表 | | name | string | app 名称 | | network | dictionary or null | app 的网络配置 | | network\_description | dictionary or null | 网络配置的描述 | | options | dictionary | app 配置。已脱敏(空字典),除非调用者是 Home Assistant Core、查询自身信息的 app,或具有 `manager` 或 `admin` role 的 app,因为 options 可能包含密码或 API keys 等 secrets | | privileged | list | app 可访问的硬件/系统 attributes 列表 | | protected | boolean | 已启用 protection mode 时为 `true` | | rating | int | addon rating | | repository | string | 指向 app repository 的 URL | | schema | dictionary or null | app 配置的 schema | | services\_role | list | services 及 app 在该 service 中 role 的列表 | | slug | string | app 的 slug | | stage | string | app 的 stage(stable, experimental, deprecated) | | startup | string | app 启动的 stage(initialize, system, services, application, once) | | state | string or null | app 的 state(started, stopped) | | stdin | boolean | app 接受 stdin 命令时为 `true` | | system\_managed | boolean | 指示该 app 是否由 Home Assistant 管理 | | system\_managed\_config\_entry | string | 如果 app 由 Home Assistant 管理,则提供 configuration entry ID | | translations | dictionary | 包含 app 翻译文件内容的字典 | | udev | boolean | 已授予 udev 访问权限时为 `true` | | update\_available | boolean | 有更新可用时为 `true` | | url | string or null | 指向该 app 更多信息的 URL | | usb | list | 附加的 USB 设备列表 | | version | string | app 已安装的版本 | | version\_latest | string | app 的最新版本 | | video | boolean | 已启用 video 时为 `true` | | watchdog | boolean | 已启用 watchdog 时为 `true` | | webui | string or null | 指向 app web UI 的 URL | | signed | boolean | 镜像已签名且受信任时为 True | **Example response:** ```json { "advanced": false, "apparmor": "default", "arch": ["armhf", "aarch64", "i386", "amd64"], "audio_input": null, "audio_output": null, "audio": false, "auth_api": false, "auto_uart": false, "auto_update": false, "available": false, "boot": "auto", "boot_config": "auto", "build": false, "changelog": false, "description": "description", "detached": false, "devices": ["/dev/xy"], "devicetree": false, "discovery": ["service"], "dns": [], "docker_api": false, "documentation": false, "full_access": false, "gpio": false, "hassio_api": false, "hassio_role": "default", "homeassistant_api": false, "homeassistant": null, "host_dbus": false, "host_ipc": false, "host_network": false, "host_pid": false, "host_uts": false, "hostname": "awesome-addon", "icon": false, "ingress_entry": null, "ingress_panel": true, "ingress_port": 1337, "ingress_url": null, "ingress": false, "ip_address": "172.0.0.21", "kernel_modules": false, "logo": false, "long_description": "Long description", "machine": ["raspberrypi2", "tinker"], "name": "Awesome app", "network_description": "{}|null", "network": {}, "options": {}, "privileged": ["NET_ADMIN", "SYS_ADMIN"], "protected": false, "rating": "1-6", "repository": "12345678", "schema": {}, "services_role": ["service:access"], "slug": "awesome_addon", "stage": "stable", "startup": "application", "state": "started", "stdin": false, "system_managed": true, "system_managed_config_entry": "abc123", "translations": { "en": { "configuration": { "lorem": "ipsum" } } }, "udev": false, "update_available": false, "url": null, "usb": ["/dev/usb1"], "version_latest": "1.0.2", "version": "1.0.0", "video": false, "watchdog": true, "webui": "http://[HOST]:1337/xy/zx", "signed": false } ``` 安装一个 app **已弃用!** 请使用 [`/store/addons//install`](#store) 代替。 获取 app logo 设置 app 的 options。 :::tip 要重置自定义的 network/audio/options,将其设为 `null`。 ::: **Payload:** | key | type | description | |-----|------|-------------| | boot | string | (auto, manual) | | auto\_update | boolean | app 应自动更新时为 `true` | | network | dictionary | network configuration 的映射。 | | options | dictionary | app 配置 | | audio\_output | float or null | 音频输出设备的索引 | | audio\_input | float or null | 音频输入设备的索引 | | ingress\_panel | boolean | 已启用 ingress\_panel 时为 `true` | | watchdog | boolean | 已启用 watchdog 时为 `true` | **你需要在 payload 中至少提供一个 key。** **Example payload:** ```json { "boot": "manual", "auto_update": false, "network": { "CONTAINER": "1337" }, "options": { "awesome": true }, "watchdog": true } ``` 更改 system managed addons 特有的 options。 此 endpoint 只能由 Home Assistant 调用,不能由其他任何客户端调用。 **Payload** | key | type | description | |-----|------|-------------| | system\_managed | boolean | 由 Home Assistant 管理时为 `true` | | system\_managed\_config\_entry | boolean | 管理 addon 的 config entry ID | **你需要在 payload 中至少提供一个 key。** **Example payload:** ```json { "system_managed": true, "system_managed_config_entry": "abc123" } ``` 针对当前存储的 app 配置或 payload 运行 configuration 验证。 **Payload:** 可选地提供原始的 app options。 **Returned data:** | key | type | description | |-----|------|-------------| | message | string | 包含错误消息 | | valid | boolean | 配置是否有效 | | pwned | boolean | None | True 或 false,指示是否包含被盗 secrets。出错时为 None | 获取其自身渲染后 configuration 的 Data endpoint。 重建 app,仅支持 local build apps。 **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | force | boolean | True | 即使提供了预构建镜像,也强制重建 app | 重启一个 app 设置 app 的 protection mode。 此函数不能由自身调用,你不能在此处使用 `self` 作为 slug。 **Payload:** | key | type | description | |-----|------|-------------| | protected | boolean | 已开启 protection mode 时为 `true` | 启动一个 app 为该 app 返回一个 [Stats model](api/supervisor/models.md#stats)。 **Example response:** ```json { "cpu_percent": 14.0, "memory_usage": 288888, "memory_limit": 322222, "memory_percent": 32.4, "network_tx": 110, "network_rx": 902, "blk_read": 12, "blk_write": 27 } ``` 向 app 的 stdin 写入数据。 你想传入 addon 的 payload 应作为请求的 body 提供给该 endpoint。 停止一个 app 卸载一个 app **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | remove\_config | boolean | True | 删除 addon 的 config 文件夹(如果使用了) | 更新一个 app **已弃用!** 请使用 [`/store/addons//update`](#store) 代替。 ### 音频 将一个 profile 设为默认输入 profile **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | name | string | False | profile 的名称 | 将一个 profile 设为默认输出 profile **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | name | string | False | profile 的名称 | 返回关于 audio 插件的信息。 **Returned data:** | key | type | description | |-----|------|-------------| | host | string | 插件的 IP 地址 | | version | string | 已安装的 observer 版本 | | version\_latest | string | 最新发布的版本 | | update\_available | boolean | 有更新可用时为 `true` | | audio | dictionary | 一个 [Audio model](api/supervisor/models.md#audio) | **Example response:** ```json { "host": "172.0.0.19", "version": "1", "latest_version": "2", "update_available": true, "audio": { "card": [ { "name": "Awesome card", "index": 1, "driver": "Awesome driver", "profiles": [ { "name": "Awesome profile", "description": "My awesome profile", "active": false } ] } ], "input": [ { "name": "Awesome device", "index": 0, "description": "My awesome device", "volume": 0.3, "mute": false, "default": false, "card": null, "applications": [ { "name": "Awesome application", "index": 0, "stream_index": 0, "stream_type": "INPUT", "volume": 0.3, "mute": false, "addon": "awesome_addon" } ] } ], "output": [ { "name": "Awesome device", "index": 0, "description": "My awesome device", "volume": 0.3, "mute": false, "default": false, "card": 1, "applications": [ { "name": "Awesome application", "index": 0, "stream_index": 0, "stream_type": "INPUT", "volume": 0.3, "mute": false, "addon": "awesome_addon" } ] } ], "application": [ { "name": "Awesome application", "index": 0, "stream_index": 0, "stream_type": "OUTPUT", "volume": 0.3, "mute": false, "addon": "awesome_addon" } ] } } ``` 通过 Systemd journal 后端获取 audio 插件容器的 logs。 该 endpoint 接受与 `/host/logs` 相同的 headers 并提供相同的功能。 与 `/audio/logs` 相同,区别在于它会持续返回新的 log entries。 返回 audio 插件容器最近一次启动的所有 logs。 `Range` header 被忽略,但可以使用 `lines` query 参数。 获取与特定 boot 相关的 audio 插件容器 logs。 `bootid` 参数的解释方式与 `/host/logs/boots/` 中相同,该 endpoint 否则提供与 `/host/logs` 相同的功能。 与 `/audio/logs/boots/` 相同,区别在于它会持续返回新的 log entries。 静音输入设备 **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | index | string | False | 设备的索引 | | active | boolean | False | 已静音时为 `true` | 对特定 application 静音输入 **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | index | string | False | 设备的索引 | | active | boolean | False | 已静音时为 `true` | 静音输出设备 **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | index | string | False | 设备的索引 | | active | boolean | False | 已静音时为 `true` | 对特定 application 静音输出 **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | index | string | False | 设备的索引 | | active | boolean | False | 已静音时为 `true` | 创建一个 audio profile **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | card | string | False | audio 设备的名称 | | name | string | False | profile 的名称 | 重新加载 audio 信息 重启 audio 插件 为该 audio 插件返回一个 [Stats model](api/supervisor/models.md#stats)。 **Example response:** ```json { "cpu_percent": 14.0, "memory_usage": 288888, "memory_limit": 322222, "memory_percent": 32.4, "network_tx": 110, "network_rx": 902, "blk_read": 12, "blk_write": 27 } ``` 更新 audio 插件 **Payload:** | key | type | description | |-----|------|-------------| | version | string | 要安装的版本,默认为最新版本 | 设置输入音量 **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | index | string | False | 设备的索引 | | volume | float | False | 音量(介于 `0.0` 和 `1.0` 之间) | 为特定 application 设置输入音量 **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | index | string | False | 设备的索引 | | volume | float | False | 音量(介于 `0.0` 和 `1.0` 之间) | 设置输出音量 **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | index | string | False | 设备的索引 | | volume | float | False | 音量(介于 `0.0` 和 `1.0` 之间) | 为特定 application 设置输出音量 **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | index | string | False | 设备的索引 | | volume | float | False | 音量(介于 `0.0` 和 `1.0` 之间) | ### 认证 你可以使用 Basic Authentication 对 Home Assistant Core 进行认证。 使用 `X-Supervisor-Token` header 提供 Supervisor authentication token。 请参阅对应的 POST 方法以提供 JSON 或 urlencoded 凭据。 你可以对 Home Assistant Core 进行认证。 你可以以 JSON、urlencoded(使用 `application/x-www-form-urlencoded` header)或使用 basic authentication 的方式 POST 数据。 使用 Basic authentication 时,你可以使用 `X-Supervisor-Token` 作为 Supervisor authentication token。 **Payload:** | key | type | description | |-----|------|-------------| | username | string | 用户的 username | | password | string | 用户的 password | 为 Home Assistant Core 用户设置新密码。 **Payload:** | key | type | description | |-----|------|-------------| | username | string | 用户的 username | | password | string | 用户的新 password | 重置内部 authentication cache,如果你在更改用户密码后需要清除内部 cache,这将非常有用。 列出 Home Assistant 中的所有用户,以帮助凭据恢复。需要一个 admin 级别的 authentication token。 **Payload:** | key | type | description | |-----|------|-------------| | users | list | Home Assistant [users](api/supervisor/models.md#user) 列表。 | ### 备份 返回一个 [Backups](api/supervisor/models.md#backup) 列表 **Example response:** ```json { "backups": [ { "slug": "skuwe823", "date": "2020-09-30T20:25:34.273Z", "name": "Awesome backup", "type": "partial", "size": 44, "protected": true, "location": "MountedBackups", "compressed": true, "content": { "homeassistant": true, "addons": ["awesome_addon"], "folders": ["ssl", "media"] } } ] } ``` 返回关于 backup manager 的信息。 **Returned data:** | key | type | description | |-----|------|-------------| | backups | list | [Backups](api/supervisor/models.md#backup) 列表 | | days\_until\_stale | int | 距 backup 被视为 stale 的天数 | **Example response:** ```json { "backups": [ { "slug": "skuwe823", "date": "2020-09-30T20:25:34.273Z", "name": "Awesome backup", "type": "partial", "size": 44, "protected": true, "compressed": true, "location": null, "content": { "homeassistant": true, "addons": ["awesome_addon"], "folders": ["ssl", "media"] } } ], "days_until_stale": 30 } ``` 创建一个 full backup。 **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | name | string | True | 你想赋予 backup 的名称 | | password | string | True | 你想赋予 backup 的密码 | | compressed | boolean | True | `false` 以创建未压缩的 backups | | location | string or null | True | backup mount 名称,或 `null` 表示 /backup | | homeassistant\_exclude\_database | boolean | True | 从 backup 中排除 Home Assistant 数据库文件 | | background | boolean | True | 立即返回 `job_id`,不等待 backup 完成。客户端必须检查 job 以获取 status 和 slug。 | **Example response:** ```json { "slug": "skuwe823" } ``` 上传一个 backup。 **Example response:** ```json { "slug": "skuwe823", "job_id": "abc123" } ``` :::note 如果单独的消息无法准确描述发生了什么,此 API 的错误响应也可能包含 `job_id`。 调用者应引导用户查看 job 或 supervisor logs,以了解发生了什么。 ::: 创建一个 partial backup。 **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | name | string | True | 你想赋予 backup 的名称 | | password | string | True | 你想赋予 backup 的密码 | | homeassistant | boolean | True | 将 home assistant core 设置添加到 backup 中 | | addons | list | True | 表示 app slugs 的字符串列表 | | folders | list | True | 表示目录的字符串列表 | | compressed | boolean | True | `false` 以创建未压缩的 backups | | location | string or null | True | backup mount 名称,或 `null` 表示 /backup | | homeassistant\_exclude\_database | boolean | True | 从 backup 中排除 Home Assistant 数据库文件 | | background | boolean | True | 立即返回 `job_id`,不等待 backup 完成。客户端必须检查 job 以获取 status 和 slug。 | **你需要在 payload 中至少提供一个 key。** **Example response:** ```json { "slug": "skuwe823", "job_id": "abc123" } ``` :::note 如果单独的消息无法准确描述发生了什么,此 API 的错误响应也可能包含 `job_id`。 调用者应引导用户查看 job 或 supervisor logs,以了解发生了什么。 ::: 更新 backup manager 的 options,你需要在 API 调用中至少提供一个 payload key。 **Payload:** | key | type | description | |-----|------|-------------| | days\_until\_stale | int | 设置距 backup 被视为 stale 的天数 | **你需要在 payload 中至少提供一个 key。** 从存储中重新加载 backup。 将 Supervisor 置于 freeze 状态,并为外部 backup 准备 Home Assistant 和 addons。 :::note 此操作不会执行 backup。它只是为 Home Assistant 和 addons 准备 backup,但预期是用户使用外部工具来执行 backup。例如 KVM 或 Proxmox 的 snapshot 功能。调用者应在完成后调用 `/backups/thaw`。 ::: **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | timeout | int | True | freeze 超时并自动开始 thaw 之前的秒数(默认:600)。 | 结束由 `/backups/freeze` 发起的 freeze,并恢复 Home Assistant 和 addons 的正常行为。 以下载给定 slug 的 backup 文件。 为该 app 返回一个 [Backup details model](api/supervisor/models.md#backup-details)。 移除给定 slug 的 backup 文件。 对给定 slug 的 backup 执行 full restore。 **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | password | string | True | backup 的密码(如果有) | | background | boolean | True | 立即返回 `job_id`,不等待 restore 完成。客户端必须检查 job 以获取 status。 | **Example response:** ```json { "job_id": "abc123" } ``` :::note 如果单独的消息无法准确描述发生了什么,此 API 的错误响应也可能包含 `job_id`。 调用者应引导用户查看 job 或 supervisor logs,以了解发生了什么。 ::: 对给定 slug 的 backup 执行 partial restore。 **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | homeassistant | boolean | True | 应恢复 Home Assistant 时为 `true` | | addons | list | True | 应恢复的 app slugs 列表 | | folders | list | True | 应恢复的目录列表 | | password | string | True | backup 的密码(如果有) | | background | boolean | True | 立即返回 `job_id`,不等待 restore 完成。客户端必须检查 job 以获取 status。 | **你需要在 payload 中至少提供一个 key。** **Example response:** ```json { "job_id": "abc123" } ``` :::note 如果单独的消息无法准确描述发生了什么,此 API 的错误响应也可能包含 `job_id`。 调用者应引导用户查看 job 或 supervisor logs,以了解发生了什么。 ::: ### CLI 返回关于 CLI 插件的信息 **Returned data:** | key | type | description | |-----|------|-------------| | version | string | 已安装的 cli 版本 | | version\_latest | string | 最新发布的版本 | | update\_available | boolean | 有更新可用时为 `true` | **Example response:** ```json { "version": "1", "version_latest": "2", "update_available": true } ``` 为 CLI 插件返回一个 [Stats model](api/supervisor/models.md#stats)。 **Example response:** ```json { "cpu_percent": 14.0, "memory_usage": 288888, "memory_limit": 322222, "memory_percent": 32.4, "network_tx": 110, "network_rx": 902, "blk_read": 12, "blk_write": 27 } ``` 更新 CLI 插件 **Payload:** | key | type | description | |-----|------|-------------| | version | string | 要安装的版本,默认为最新版本 | ### 核心 将 GET API 调用代理到 Home Assistant API 将 POST API 调用代理到 Home Assistant API 运行 configuration 检查 返回关于 Home Assistant core 的信息 **Returned data:** | key | type | description | |-----|------|-------------| | version | string | 已安装的 core 版本 | | version\_latest | string | 活动 channel 中最新发布的版本 | | update\_available | boolean | 有更新可用时为 `true` | | arch | string | host 的架构(armhf, aarch64, i386, amd64) | | machine | string | 运行 host 的 machine 类型 | | ip\_address | string | 指向 supervisor 的内部 docker IP 地址 | | image | string | 运行 core 的容器镜像 | | boot | boolean | 应在 boot 时启动时为 `true` | | port | int | Home Assistant 运行的端口 | | ssl | boolean | Home Assistant 使用 SSL 时为 `true` | | watchdog | boolean | 已启用 watchdog 时为 `true` | | wait\_boot | int | boot 期间等待的最大时间 | | audio\_input | string or null | audio 输入设备的描述 | | audio\_output | string or null | audio 输出设备的描述 | | backups\_exclude\_database | boolean | 默认在 backups 中排除 Home Assistant 数据库文件 | | duplicate\_log\_file | boolean | Home Assistant 将 logs 复制到一个文件中 | **Example response:** ```json { "version": "0.117.0", "version_latest": "0.117.0", "update_available": true, "arch": "arch", "machine": "amd64", "ip_address": "172.0.0.15", "image": "homeassistant/home-assistant", "boot": true, "port": 80, "ssl": false, "watchdog": true, "wait_boot": 800, "audio_input": "AMCP32", "audio_output": "AMCP32" } ``` 通过 Systemd journal 后端获取 Home Assistant Core 容器的 logs。 该 endpoint 接受与 `/host/logs` 相同的 headers 并提供相同的功能。 与 `/core/logs` 相同,区别在于它会持续返回新的 log entries。 返回 Home Assistant Core 容器最近一次启动的所有 logs。 `Range` header 被忽略,但可以使用 `lines` query 参数。 获取与特定 boot 相关的 Home Assistant Core 容器 logs。 `bootid` 参数的解释方式与 `/host/logs/boots/` 中相同,该 endpoint 否则提供与 `/host/logs` 相同的功能。 与 `/core/logs/boots/` 相同,区别在于它会持续返回新的 log entries。 更新 Home Assistant 的 options,你需要在 API 调用中至少提供一个 payload key。 更新 options 后,你需要调用 `/core/restart`。 :::tip 传递 `image`、`refresh_token`、`audio_input` 或 `audio_output` 且值为 `null` 可重置该 option。 ::: **Payload:** | key | type | description | |-----|------|-------------| | boot | boolean | 在 boot 时启动 Core | | image | string or null | 自定义镜像的名称 | | port | int | Home Assistant 运行的端口 | | ssl | boolean | 启用 SSL 时为 `true` | | watchdog | boolean | 启用 watchdog 时为 `true` | | wait\_boot | int | 等待 Core 启动的时间 | | refresh\_token | string or null | 用于与 Core 认证的 token | | audio\_input | string or null | audio 输入的 profile 名称 | | audio\_output | string or null | audio 输出的 profile 名称 | | backups\_exclude\_database | boolean | 从 backups 中排除 Home Assistant 数据库文件时为 `true` | | duplicate\_log\_file | boolean | 将 Home Assistant logs 复制到一个文件中时为 `true` | **你需要在 payload 中至少提供一个 key。** 重建 Home Assistant core 容器 **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | safe\_mode | boolean | True | 以 safe mode 重建 Core | | force | boolean | True | 在 Home Assistant offline db migration 期间强制重建 | 重启 Home Assistant core 容器 **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | safe\_mode | boolean | True | 以 safe mode 重启 Core | | force | boolean | True | 在 Home Assistant offline db migration 期间强制重启 | 启动 Home Assistant core 容器 为 Home Assistant core 返回一个 [Stats model](api/supervisor/models.md#stats)。 **Example response:** ```json { "cpu_percent": 14.0, "memory_usage": 288888, "memory_limit": 322222, "memory_percent": 32.4, "network_tx": 110, "network_rx": 902, "blk_read": 12, "blk_write": 27 } ``` 停止 Home Assistant core 容器 **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | force | boolean | True | 在 Home Assistant offline db migration 期间强制停止 | 更新 Home Assistant core **Payload:** | key | type | description | |-----|------|-------------| | version | string | 要安装的版本,默认为最新版本 | | backup | boolean | 在更新前创建 core 和 core configuration 的 partial backup,默认为 false | 代理到 Home Assistant Core websocket。 ### 发现 返回关于已启用 discoveries 的信息。 **Returned data:** | key | type | description | |-----|------|-------------| | discovery | list | [Discovery models](api/supervisor/models.md#discovery) 列表 | | services | dictionary | services 的字典,包含拥有该 service 的 apps 列表。 | **Example response:** ```json { "discovery": [ { "addon": "awesome_addon", "service": "awesome.service", "uuid": "fh874r-fj9o37yr3-fehsf7o3-fd798", "config": {} } ], "services": { "awesome": ["awesome_addon"] } } ``` 创建一个 discovery service **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | service | string | False | service 的名称 | | config | dictionary | False | service 的 configuration | **Example response:** ```json { "uuid": "uuid" } ``` 获取一个 UUID 的 [discovery model](api/supervisor/models.md#discovery)。 删除一个特定的 service。 ### DNS 返回关于 DNS 插件的信息。 **Returned data:** | key | type | description | |-----|------|-------------| | fallback | bool | 失败时尝试 fallback DNS | | host | string | 插件的 IP 地址 | | llmnr | bool | 能解析 LLMNR hostnames | | locals | list | DNS servers 列表 | | mdns | bool | 能解析 MulticastDNS hostnames | | servers | list | DNS servers 列表 | | update\_available | boolean | 有更新可用时为 `true` | | version | string | 已安装的 observer 版本 | | version\_latest | string | 最新发布的版本 | **Example response:** ```json { "host": "127.0.0.18", "version": "1", "version_latest": "2", "update_available": true, "servers": ["dns://8.8.8.8"], "locals": ["dns://127.0.0.18"], "mdns": true, "llmnr": false, "fallback": true } ``` 通过 Systemd journal 后端获取 DNS 插件容器的 logs。 该 endpoint 接受与 `/host/logs` 相同的 headers 并提供相同的功能。 与 `/dns/logs` 相同,区别在于它会持续返回新的 log entries。 返回 DNS 插件容器最近一次启动的所有 logs。 `Range` header 被忽略,但可以使用 `lines` query 参数。 获取与特定 boot 相关的 DNS 插件容器 logs。 `bootid` 参数的解释方式与 `/host/logs/boots/` 中相同,该 endpoint 否则提供与 `/host/logs` 相同的功能。 与 `/dns/logs/boots/` 相同,区别在于它会持续返回新的 log entries。 设置 DNS options **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | fallback | bool | True | 启用/禁用 fallback DNS | | servers | list | True | DNS servers 列表 | **你需要在 payload 中至少提供一个 key。** 重置 DNS configuration。 重启 DNS 插件 为 DNS 插件返回一个 [Stats model](api/supervisor/models.md#stats)。 **Example response:** ```json { "cpu_percent": 14.0, "memory_usage": 288888, "memory_limit": 322222, "memory_percent": 32.4, "network_tx": 110, "network_rx": 902, "blk_read": 12, "blk_write": 27 } ``` 更新 DNS 插件 **Payload:** | key | type | description | |-----|------|-------------| | version | string | 要安装的版本,默认为最新版本 | ### Docker 返回关于 docker 实例的信息。 **Returned data:** | key | type | description | |-----|------|-------------| | version | string | docker engine 的版本 | | enable\_ipv6 | bool | 为 containers 启用/禁用 IPv6 | | storage | string | 存储类型 | | logging | string | 日志类型 | | registries | dictionary | 包含 `username` 和 `password` keys 的字典集合,用于 registries。 | **Example response:** ```json { "version": "1.0.1", "enable_ipv6": true, "storage": "overlay2", "logging": "journald", "registries": {} } ``` 设置 docker options **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | enable\_ipv6 | bool | True | 为 containers 启用/禁用 IPv6 | **你需要在 payload 中至少提供一个 key。** 获取所有已配置的 container registries,返回一个 dict,以 registry hostname 作为 key,包含为对应 registry 配置的 username 字典。 **Example response:** ```json { "registry.example.com": { "username": "AwesomeUser" } } ``` 添加一个新的 container registry。 **Payload:** | key | type | description | |-----|------|-------------| | hostname | dictionary | 包含为 registry 的 `username` 和 `password` keys 的字典。 | **Example payload:** ```json { "registry.example.com": { "username": "AwesomeUser", "password": "MySuperStrongPassword!" } } ``` :::note 要登录到默认的 container registry(Docker Hub),请使用 `hub.docker.com` 作为 registry。 ::: 从已配置的 container registries 中删除一个 registry。 安排 Docker storage driver 迁移。该迁移将在下次系统重启时应用。 此 endpoint 允许迁移到以下任一: * `overlayfs`: Containerd overlayfs driver * `overlay2`: Docker graph overlay2 driver :::note 此 endpoint 需要 Home Assistant OS 17.0 或更新版本。在较旧版本或非 HAOS 安装中将返回 `404` 错误。 ::: **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | storage\_driver | string | False | 目标 storage driver(`overlayfs` 或 `overlay2`) | **Example payload:** ```json { "storage_driver": "overlayfs" } ``` 调用此 endpoint 后,需要重启才能应用迁移。响应会在 resolution center 中创建一个 `reboot_required` issue。 ### 硬件 获取 hardware 信息。 **Example response:** ```json { "devices": [ { "name": "ttyACM0", "sysfs": "/sys/devices/usb/00:01", "dev_path": "/dev/ttyACM0", "by_id": "/dev/serial/by-id/usb-Silicon_Labs-RFUSB_9017F723B061A7C01410CFCF-if00-port1", "subsystem": "tty", "parent": null, "attributes": { "MINOR": "5" }, "children": [ "/sys/devices/soc/platform/00ef" ] } ], "drives": [ { "vendor": "Generic", "model": "Flash Disk", "revision": "8.07", "serial": "AABBCCDD", "id": "Generic-Flash-Disk-AABBCCDD", "size": 8054112256, "time_detected": "2023-02-15T21:44:22.504878+00:00", "connection_bus": "usb", "seat": "seat0", "removable": true, "ejectable": true, "filesystems": [ { "device": "/dev/sda1", "id": "by-uuid-1122-1ABA", "size": 67108864, "name": "", "system": false, "mount_points": [] } ] } ] } ``` **Returned data:** | key | description | |-----|-------------| | devices | [Device models](api/supervisor/models.md#device) 列表 | | drives | [Drive models](api/supervisor/models.md#drive) 列表 | 获取 audio 设备 **Example response:** ```json { "audio": { "input": { "0,0": "Mic" }, "output": { "1,0": "Jack", "1,1": "HDMI" } } } ``` ### 主机 返回关于 host 的信息。 **Returned data** | key | type | description | |-----|------|-------------| | agent\_version | string or null | host 上运行的 agent 版本 | | apparmor\_version | string or null | host 的 AppArmor 版本 | | boot\_timestamp | int | 最后一次 boot 的时间戳(微秒) | | broadcast\_llmnr | bool or null | host 正在广播其 LLMNR hostname | | broadcast\_mdns | bool or null | host 正在广播其 MulticastDNS hostname | | chassis | string or null | chassis 类型 | | virtualization | string or null | 正在使用的虚拟化 hypervisor(如果有) | | cpe | string or null | 本地 CPE | | deployment | string or null | OS 的部署 stage(如果有) | | disk\_total | float | 磁盘总空间(GB) | | disk\_used | float | 已使用的磁盘空间(GB) | | disk\_free | float | 可用的磁盘空间(GB) | | features | list | host 可用 features 列表 | | hostname | string or null | host 的 hostname | | kernel | string or null | host 的 kernel 版本 | | llmnr\_hostname | string or null | 当前通过网络通过 LLMNR 暴露的 hostname | | operating\_system | string | host 的 operating system | | startup\_time | float | 最后一次 boot 所用的时间(秒) | | disk\_life\_time | float or null | 估计的磁盘生命周期使用百分比(0–100)。并非所有磁盘都提供此信息,不可用时返回 `null`。 | | timezone | string | host 的当前 timezone。 | | dt\_utc | string | host 的当前 UTC 日期/时间(ISO 8601 格式)。 | | dt\_synchronized | bool | host 已与 NTP service 同步时为 `true`。 | | use\_ntp | bool | host 使用 NTP service 进行时间同步时为 `true`。 | **Example response:** ```json { "agent_version": "1.2.0", "apparmor_version": "2.13.2", "chassis": "specific", "cpe": "xy", "deployment": "stable", "disk_total": 32.0, "disk_used": 30.0, "disk_free": 2.0, "features": ["shutdown", "reboot", "hostname", "services", "haos"], "hostname": "Awesome host", "llmnr_hostname": "Awesome host", "kernel": "4.15.7", "operating_system": "Home Assistant OS", "boot_timestamp": 1234567788, "startup_time": 12.345, "broadcast_llmnr": true, "broadcast_mdns": false, "virtualization": "", "disk_life_time": 10.0, "timezone": "Europe/Brussels", "dt_utc": "2025-09-08T12:00:00.000000+00:00", "dt_synchronized": true, "use_ntp": true } ``` 从 host 获取 systemd Journal logs。以纯文本形式返回 log entries,每行一条 log record。 **HTTP Request Headers** | Header | optional | description | |--------|----------|-------------| | Accept | true | 数据类型(text/plain 或 text/x-log) | | Range | true | log entries 的范围。格式为 `entries=cursor[[:num_skip]:num_entries]` | **HTTP Query Parameters** 这些是上述 headers 的便捷替代方案,因为 query 参数在开发中和与 Home Assistant proxy 一起使用时更易于使用。你应该只提供其中一种。 | Query | type | description | |-------|------|-------------| | verbose | N/A | 如果包含,使用 `text/x-log` 作为 log 输出类型(`Accept` header 的替代方案) | | lines | int | 要返回的输出行数(`Range` header 的替代方案) | | no\_colors | N/A | 如果包含,ANSI 转义码用于终端着色将从输出中剥离 | 示例 query string: ```text ?verbose&lines=100&no_colors ``` :::tip 要获取最后的 log entries,Range 请求 header 支持负值 作为 `num_skip`。例如,`Range: entries=:-9:` 返回最后的 10 条 entries。或者 `Range: entries=:-200:100` 查看从 200 条之前的 100 条 entries。 ::: API 默认返回最后的 100 行。提供一个 `Range` 值以查看更早的 logs。 `Accept` header 可以设为 `text/x-log` 以获取带有附加信息的 logs,例如时间戳和 Systemd unit 名称。如果未指定标识符(即对于 host logs 包含多个 标识符/units 的 logs),此选项将被忽略——这些 logs 始终被标注。 与 `/host/logs` 相同,区别在于它会持续返回新的 log entries。 返回一个来自 systemd journal 的 syslog identifiers 列表,你可以用它们配合 `/host/logs/identifiers/` 和 `/host/logs/boots//identifiers/` 使用。 从 host 获取与特定 log identifier 相关的 systemd Journal logs。这里有用的一些 identifiers 示例包括 * `audit` - 如果在开发 apparmor profile 时遇到权限问题 * `NetworkManager` - 遇到网络问题时显示 NetworkManager logs * `bluetoothd` - 遇到蓝牙问题时显示 bluetoothd logs 调用 `GET /host/logs/identifiers` 将显示 `identifier` 可能值的全部列表。 否则它提供与 `/host/logs` 相同的功能。 与 `/host/logs/identifiers/` 相同,区别在于它会持续返回新的 log entries。 返回一个该系统的 boot IDs 字典,你可以用它们配合 `/host/logs/boots/` 和 `/host/logs/boots//identifiers/` 使用。 字典中每项的 key 是 boot 偏移量。0 是当前 boot, 负数表示距当前 boot 往前的 boot 次数。 从 host 获取与特定 boot 相关的 systemd Journal logs。 调用 `GET /host/info/boots` 查看 boot IDs。或者你也可以提供一个 boot 偏移量: * 0 - 当前 boot * 负数 - 从当前 boot 往前计数(-1 是前一次 boot) * 正数 - 从已知的最后一次 boot 往后计数(1 是已知的最后一次 boot) 否则它提供与 `/host/logs` 相同的功能。 与 `/host/logs/boots/` 相同,区别在于它会持续返回新的 log entries。 获取特定 log identifier 和特定 boot 的 systemd Journal logs entries。 它是 `/host/logs/boots/` 和 `/host/logs/identifiers/` 的组合。 与 `/host/logs/boots//identifiers/` 相同,区别在于它会持续返回新的 log entries。 设置 host options **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | hostname | string | True | 将用作新 hostname 的字符串 | **你需要在 payload 中至少提供一个 key。** 重启 host **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | force | boolean | True | 在 Home Assistant offline db migration 期间强制重启 | 重新加载 host 信息 在 host 上启动一个 service。 在 host 上停止一个 service。 在 host 上重新加载一个 service。 获取关于 host services 的信息。 **Returned data:** | key | description | |-----|-------------| | services | [Host service models](api/supervisor/models.md#host-service) 字典 | **Example response:** ```json { "services": [ { "name": "awesome.service", "description": "Just an awesome service", "state": "active" } ] } ``` 关闭 host **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | force | boolean | True | 在 Home Assistant offline db migration 期间强制关闭 | 获取以字节为单位的详细磁盘使用情况信息。 `disk` 选择要测量的对象。使用 `default` 表示数据磁盘,或使用 mount 名称来测量该 mount。`default` 始终指向数据磁盘,因此同名 mount 无法通过此 endpoint 访问。 支持可选的 `max_depth` query 参数,用于控制细分的深度。数据磁盘默认为 1,mount 默认为 0。 数据磁盘将其已知的一级路径报告为 children,`max_depth` 控制在其中内部继续细分的深度。 Mount 没有这种固定层级,因此它通过遍历目录来测量,并且只有剩余深度超过一级时目录才会列出。因此 `max_depth` 为 0 或 1 仅返回总计,第一级目录在 2 时出现,再往下的每一级都需要多加一级。 当 mount 列出 children 时,一个 `other` child 携带遍历未归因到目录的所有内容:直接位于 mount 根部的文件、保留空间以及无法读取的条目。当该余数为正时,节点 children 之和恰好等于其自身的 `used_bytes`。如果在遍历期间文件系统发生变化,目录总计可能与 `used_bytes` 不一致;在这种情况下,细分将完全被省略,仅报告总计,因此 children 之和永远不会超过其父节点。 请求不存在的 mount 的使用情况将返回 `404`。对于不 active 的 mount、unit 仍报告 active 但已实际未挂载的 mount、无法读取的 mount 或 usage probe 在 60 秒内未完成的 mount,将返回 `400`。该 probe 在超时后仍会继续运行,因此重试请求将加入已在进行的 probe,而不是启动一个新的。 **Example response:** ```json { "id": "root", "label": "Root", "total_bytes": 503312781312, "used_bytes": 430245011456, "children": [ { "id": "system", "label": "System", "used_bytes": 75660903137 }, { "id": "addons_data", "label": "Addons data", "used_bytes": 42349200762 }, { "id": "addons_config", "label": "Addons configuration", "used_bytes": 5283318814 }, { "id": "media", "label": "Media", "used_bytes": 476680019 }, { "id": "share", "label": "Share", "used_bytes": 37477206419 }, { "id": "backup", "label": "Backup", "used_bytes": 268350699520 }, { "id": "ssl", "label": "SSL", "used_bytes": 202912633 }, { "id": "homeassistant", "label": "Home assistant", "used_bytes": 444090152 } ] } ``` **Example response for a mount**,使用 `max_depth=2` 请求: ```json { "id": "media_nas", "label": "media_nas", "total_bytes": 2000398934016, "used_bytes": 1240247081779, "children": [ { "id": "music", "label": "music", "used_bytes": 402653184000 }, { "id": "movies", "label": "movies", "used_bytes": 800000000000 }, { "id": "other", "label": "Other", "used_bytes": 37593897779 } ] } ``` ### Ingress **Returned data:** | key | type | description | |-----|------|-------------| | panels | dictionary | [Panel models](api/supervisor/models.md#panel) 字典 | **Example response:** ```json { "panels": { "addon_slug": { "enable": true, "icon": "mdi:awesome-icon", "title": "Awesome app", "admin": true } } } ``` 创建一个用于访问 ingress service 的新 session。 **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | user\_id | string | True | 新 session 认证用户的 ID | **Returned data:** | key | type | optional | description | |-----|------|----------|-------------| | session | string | False | ingress session 的 token | 验证一个 ingress session,并延长其有效期。 **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | session | string | False | ingress session 的 token | ### 任务 返回关于被忽略的 job 条件和当前运行或已完成的 jobs 的信息 **Returned data:** | key | type | description | |-----|------|-------------| | ignore\_conditions | list | 被忽略的 job 条件列表 | | jobs | list | 运行中或已完成的 [Jobs](api/supervisor/models.md#job) 列表 | **Example response:** ```json { "ignore_conditions": [], "jobs": [{ "name": "backup_manager_full_backup", "reference": "a01bc3", "uuid": "123456789", "progress": 0, "stage": "addons", "done": false, "child_jobs": [], "extra": null }] } ``` 设置 job manager 的 options **Payload:** | key | type | description | |-----|------|-------------| | ignore\_conditions | list | 要忽略的 job 条件列表(替换现有列表) | 返回关于当前运行或已完成 job 的信息 **Returned data:** 参见 [Job](api/supervisor/models.md#job) model **Example response:** ```json { "name": "backup_manager_full_backup", "reference": "a01bc3", "uuid": "123456789", "progress": 0, "stage": "addons", "done": false, "child_jobs": [], "extra": null } ``` 如果客户端不再关心该已完成的 job,则将其从 Supervisor cache 中移除 将 job manager 重置为默认值(停止忽略任何被忽略的 job 条件) ### 根 返回关于可用更新的信息 **Example response:** ```json { "available_updates": [ { "panel_path": "/update-available/core", "update_type": "core", "version_latest": "321", }, { "panel_path": "/update-available/os", "update_type": "os", "version_latest": "321", }, { "panel_path": "/update-available/supervisor", "update_type": "supervisor", "version_latest": "321", }, { "name": "Awesome addon", "icon": "/addons/awesome_addon/icon", "panel_path": "/update-available/awesome_addon", "update_type": "addon", "version_latest": "321", } ] } ``` **Returned data:** | key | type | description | |-----|------|-------------| | update\_type | string | `addon`、`os`、`core` 或 `supervisor` | | name | string | 返回名称(仅当 `update_type` 为 `addon` 时) | | icon | string | 返回 icon 的路径(如果有)(仅当 `update_type` 为 `addon` 时) | | version\_latest | string | 返回可用版本 | | panel\_path | string | 返回 UI 可以加载的路径 | 这将重新加载关于主要组件(OS、Supervisor、Core 和 Plug-ins)的信息。 这将重新加载关于 app repositories 的信息并获取新的 version files。 此 endpoint 目前不推荐使用。请使用 `/reload_updates` 或 `/store/reload` 代替。 返回一个包含来自其他 `/*/info` endpoints 的部分 key 的 dict。 **Returned data:** | key | type | description | |-----|------|-------------| | supervisor | string | 已安装的 supervisor 版本 | | homeassistant | string | 已安装的 Home Assistant 版本 | | hassos | string or null | Home Assistant OS 版本或 null | | docker | string | host 上的 docker 版本 | | hostname | string | host 上的 hostname | | operating\_system | string | host 的 operating system | | features | list | host 上的可用 features 列表 | | machine | string | machine 类型 | | machine\_id | string or null | 底层 operating system 的 machine ID | | arch | string | host 的架构 | | supported\_arch | list | 受支持的 host 架构列表 | | supported | boolean | 环境受支持时为 `true` | | channel | string | 活动 channel(stable, beta, dev) | | logging | string | 活动 log 级别(debug, info, warning, error, critical) | | state | string | Supervisor 的 core state。 | | timezone | string | 当前 timezone | **Example response:** ```json { "supervisor": "300", "homeassistant": "0.117.0", "hassos": "5.0", "docker": "24.17.2", "hostname": "Awesome Hostname", "operating_system": "Home Assistant OS", "features": ["shutdown", "reboot", "hostname", "services", "hassos"], "machine": "ova", "arch": "amd64", "supported_arch": ["amd64"], "supported": true, "channel": "stable", "logging": "info", "state": "running", "timezone": "Europe/Brussels" } ``` ### 挂载点 返回关于 Supervisor 中配置的 mounts 的信息 **Returned data:** | key | type | description | |-----|------|-------------| | mounts | list | [Mounts](api/supervisor/models.md#mount) 列表 | | default\_backup\_mount | string or null | backup mount 名称或 `null` 表示 /backup | **Example response:** ```json { "default_backup_mount": "my_share", "mounts": [ { "name": "my_share", "usage": "media", "type": "cifs", "server": "server.local", "share": "media", "state": "active", "read_only": false } ] } ``` 设置 mount manager options **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | default\_backup\_mount | string or null | True | backup mount 名称或 `null` 表示 /backup | **你需要在 payload 中至少提供一个 key。** 在 Supervisor 中添加一个新 mount 并挂载它 **Payload:** 接受一个 [Mount](api/supervisor/models.md#mount) `name` 中的值必须是唯一的,且只能由字母、数字和下划线组成。 **Example payload:** ```json { "name": "my_share", "usage": "media", "type": "cifs", "server": "server.local", "share": "media", "username": "admin", "password": "password", "read_only": false } ``` 更新 Supervisor 中现有的 mount 并重新挂载它 **Payload:** 接受一个 [Mount](api/supervisor/models.md#mount)。 应省略 `name` 字段。如果包含,其值必须与现有名称匹配,不能更改。删除并重新添加 mount 以更改名称。 **Example payload:** ```json { "usage": "media", "type": "nfs", "server": "server.local", "path": "/media/camera", "read_only": true } ``` 卸载并从 Supervisor 中删除现有的 mount。 卸载并使用相同的配置重新挂载 Supervisor 中现有的 mount。 ### Multicast 返回关于 multicast 插件的信息 **Returned data:** | key | type | description | |-----|------|-------------| | version | string | 已安装的 multicast 版本 | | version\_latest | string | 最新发布的版本 | | update\_available | boolean | 有更新可用时为 `true` | **Example response:** ```json { "version": "1", "version_latest": "2", "update_available": true } ``` 通过 Systemd journal 后端获取 multicast 插件的 logs。 该 endpoint 接受与 `/host/logs` 相同的 headers 并提供相同的功能。 与 `/multicast/logs` 相同,区别在于它会持续返回新的 log entries。 返回 multicast 插件容器最近一次启动的所有 logs。 `Range` header 被忽略,但可以使用 `lines` query 参数。 获取与特定 boot 相关的 multicast 插件 logs。 `bootid` 参数的解释方式与 `/host/logs/boots/` 中相同,该 endpoint 否则提供与 `/host/logs` 相同的功能。 与 `/multicast/logs/boots/` 相同,区别在于它会持续返回新的 log entries。 重启 multicast 插件。 为 multicast 插件返回一个 [Stats model](api/supervisor/models.md#stats)。 **Example response:** ```json { "cpu_percent": 14.0, "memory_usage": 288888, "memory_limit": 322222, "memory_percent": 32.4, "network_tx": 110, "network_rx": 902, "blk_read": 12, "blk_write": 27 } ``` 更新 multicast 插件 **Payload:** | key | type | description | |-----|------|-------------| | version | string | 要安装的版本,默认为最新版本 | ### 网络 获取 network 信息。 **Returned data:** | key | description | |-----|-------------| | interfaces | [Network interface models](api/supervisor/models.md#network-interface) 列表 | | docker | 关于内部 docker network 的信息 | | host\_internet | 指示 host 是否可以访问 internet 的 Boolean。 | | supervisor\_internet | 指示 Supervisor 是否可以访问 internet 的 Boolean。 | **Example response:** ```json { "interfaces": [ { "interface": "eth0", "type": "ethernet", "primary": true, "enabled": true, "connected": true, "ipv4": { "method": "static", "ip_address": "192.168.1.100/24", "gateway": "192.168.1.1", "nameservers": ["192.168.1.1"], }, "ipv6": null, "wifi": null, "vlan": null, } ], "docker": { "interface": "hassio", "address": "172.30.32.0/23", "gateway": "172.30.32.1", "dns": "172.30.32.3" }, "host_internet": true, "supervisor_internet": true } ``` 返回特定 network interface 的 [Network interface model](api/supervisor/models.md#network-interface)。 更新所有 Network interface 数据。 更新 network interface 的设置。 **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | enabled | bool | True | 启用/禁用 ethernet interface / 禁用时 VLAN 被移除 | | ipv6 | dict | True | 包含 ipv6 interface 设置的 struct | | ipv4 | dict | True | 包含 ipv4 interface 设置的 struct | | wifi | dict | True | 包含 Wireless 连接设置的 struct | **ipv6:** | key | type | optional | description | |-----|------|----------|-------------| | method | string | True | 设置 IP 配置方法,`auto` 表示 DHCP 或 Router Advertisements,`static` 或 `disabled` | | addr\_gen\_mode | string | True | Address generation mode 可以是 `eui64`、`stable-privacy`、`default-or-eui64` 或 `default` | | ip6\_privacy | string | True | Privacy extensions 选项有 `disabled`、`enabled-prefer-public`、`enabled` 或 `default` | | address | list | True | 接口的新 IP 地址,以 ::/XX 格式作为列表 | | nameservers | list | True | 要使用的 DNS servers 列表 | | gateway | string | True | 接口应使用的 gateway | | route\_metric | int | True | Route metric。值越低优先级越高。内核接受零(0)但会将其强制转换为 1024(用户默认值) | **ipv4:** | key | type | optional | description | |-----|------|----------|-------------| | method | string | True | 设置 IP 配置方法,`auto` 表示 DHCP,`static` 或 `disabled` | | address | list | True | 接口的新 IP 地址,以 X.X.X.X/XX 格式作为列表 | | nameservers | list | True | 要使用的 DNS servers 列表 | | gateway | string | True | 接口应使用的 gateway | | route\_metric | int | True | Route metric。值越低优先级越高 | **wifi:** | key | type | optional | description | |-----|------|----------|-------------| | mode | string | True | 设置模式 `infrastructure`(默认)、`mesh`、`adhoc` 或 `ap` | | auth | string | True | 设置 auth 模式:`open`(默认)、`web`、`wpa-psk` | | ssid | string | True | 设置要连接到的 SSID | | psk | string | True | 与 `web` 或 `wpa-psk` 一起使用的共享密钥 | 返回此 Wireless interface 上可用的 [Access Points](api/supervisor/models.md#access-points) 列表。 **此功能仅适用于 Wireless interfaces!** **Returned data:** | key | description | |-----|-------------| | accesspoints | [Access Points](api/supervisor/models.md#access-points) 列表 | **Example response:** ```json { "accesspoints": [ { "mode": "infrastructure", "ssid": "MY_TestWifi", "mac": "00:00:00:00", "frequency": 24675, "signal": 90 } ] } ``` 在此 network interface 上创建一个新的 VLAN *id*。 **此功能仅适用于 ethernet interfaces!** **Payload:** | key | type | optional | description | |-----|------|----------|-------------| | ipv6 | dict | True | 包含 ipv6 interface 设置的 struct | | ipv4 | dict | True | 包含 ipv4 interface 设置的 struct | ### 观察者 返回关于 observer 插件的信息 **Returned data:** | key | type | description | |-----|------|-------------| | host | string | 插件的 IP 地址 | | version | string | 已安装的 observer 版本 | | version\_latest | string | 最新发布的版本 | | update\_available | boolean | 有更新可用时为 `true` | **Example response:** ```json { "host": "172.0.0.17", "version": "1", "version_latest": "2", "update_available": true } ``` 为 observer 插件返回一个 [Stats model](api/supervisor/models.md#stats)。 **Example response:** ```json { "cpu_percent": 14.0, "memory_usage": 288888, "memory_limit": 322222, "memory_percent": 32.4, "network_tx": 110, "network_rx": 902, "blk_read": 12, "blk_write": 27 } ``` 更新 observer 插件 **Payload:** | key | type | description | |-----|------|-------------| | version | string | 要安装的版本,默认为最新版本 | ### OS 从 USB 闪存驱动器加载 host configurations。 返回关于 OS 的信息。 **Returned data:** | key | type | description | |-----|------|-------------| | version | string | OS 当前版本 | | version\_latest | string | 活动 channel 中 OS 最新发布的版本 | | update\_available | boolean | 有更新可用时为 `true` | | board | string | board 名称 | | boot | string | 正在使用的 slot | | data\_disk | string | 用于持久存储 OS 数据的设备 | | boot\_slots | dict | 以名称为 key 的 [boot slots](api/supervisor/models.md#boot-slot) 字典 | **Example response:** ```json { "version": "4.3", "version_latest": "5.0", "update_available": true, "board": "ova", "boot": "slot1", "data_disk": "BJTD4R-0x123456789", "boot_slots": { "A": { "state": "inactive", "status": "good", "version": "10.1" }, "B": { "state": "active", "status": "good", "version": "10.2" } } } ``` 更新 Home Assistant OS 完成此操作后需要重启才能完成更新。可以通过后续调用 `/host/reboot` 完成,或者让用户按计划使用 repair 完成。 **Payload:** | key | type | description | |-----|------|-------------| | version | string | 要安装的版本,默认为最新版本 | 更改 active boot slot,**这也会重启设备!** **Payload:** | key | type | description | |-----|------|-------------| | boot\_slot | string | 要更改到的 boot slot。查看 `/os/info` API 中 `boot_slots` 的选项。 | 获取当前 HAOS swap configuration。在 Supervised 上不可用。 **Returned data:** | key | type | description | |-----|------|-------------| | swap\_size | string | 当前 swap 大小。 | | swappiness | int | 当前 kernel swappiness 值。 | **Example response:** ```json { "swap_size": "2G", "swappiness": 1 } ``` 设置 HAOS swap configuration。在 Supervised 上不可用。 **Payload:** | key | type | description | |-----|------|-------------| | swap\_size | string | 新的 swap 大小,带可选单位的数字(K/M/G)。低于 40K 的值将禁用 swap。 | | swappiness | int | 新的 swappiness 值(0-100)。 | 返回新的 data partition 可能的目标。 **Returned data:** | key | type | description | |-----|------|-------------| | devices | list | 可能的 data disk 目标 ID 列表 | | disks | list | 可能作为 data disk 目标的 [disks](api/supervisor/models.md#disk) 列表 | **Example response:** ```json { "devices": [ "Generic-Flash-Disk-123ABC456", "SSK-SSK-Storage-ABC123DEF" ], "disks": [ { "name": "Generic Flash Disk (123ABC456)", "vendor": "Generic", "model": "Flash Disk", "serial": "123ABC456", "size": 8054112256, "id": "Generic-Flash-Disk-123ABC456", "dev_path": "/dev/sda" }, { "name": "SSK SSK Storage (ABC123DEF)", "vendor": "SSK", "model": "SSK Storage", "serial": "ABC123DEF", "size": 250059350016, "id": "SSK-SSK-Storage-ABC123DEF", "dev_path": "/dev/sdb" } ] } ``` 将 datadisk 移动到新位置,**这也会重启设备!** **Payload:** | key | type | description | |-----|------|-------------| | device | string | 用作 data 迁移目标的 disk 设备 ID | 擦除 datadisk 包括所有用户数据和设置,**这也会重启设备!** 此 API 需要 admin token 此 API 将擦除 addons、Home Assistant 和 Operating System 的所有 config/settings,以及 config、backups、media 等中本地存储的任何数据。机器将在此过程中重启。 重启完成后将下载最新稳定版本的 Home Assistant 和 Supervisor。处理完成后用户将看到 onboarding,就像初始设置时一样。 此擦除还包括 network 设置。因此重启后用户可能需要重新配置这些设置才能再次访问 Home Assistant。 Operating system 版本及其 boot configuration 将被保留。 如果 board 有可以从 Home Assistant 修改的 features 或 settings,则返回关于它的信息。`board` 的值是 `/os/info` 返回的 `board` 字段中的值。 具有以下选项的 boards 记录如下。 如果在 yellow board 上运行,返回其 settings 的当前值。 **Returned data:** | key | type | description | |-----|------|-------------| | disk\_led | boolean | disk LED 是否启用 | | heartbeat\_led | boolean | heartbeat LED 是否启用 | | power\_led | boolean | power LED 是否启用 | **Example response:** ```json { "disk_led": true, "heartbeat_led": true, "power_led": false } ``` 如果在 yellow board 上运行,更改其一个或多个 settings。 **Payload:** | key | type | description | |-----|------|-------------| | disk\_led | boolean | 启用/禁用 disk LED | | heartbeat\_led | boolean | 启用/禁用 heartbeat LED | | power\_led | boolean | 启用/禁用 power LED | 如果在 green board 上运行,返回其 settings 的当前值。 **Returned data:** | key | type | description | |-----|------|-------------| | activity\_led | boolean | green activity LED 是否启用 | | power\_led | boolean | white power LED 是否启用 | | system\_health\_led | boolean | yellow system health LED 是否启用 | **Example response:** ```json { "activity_led": true, "power_led": true, "system_health_led": false } ``` 如果在 green board 上运行,更改其一个或多个 settings。 **Payload:** | key | type | description | |-----|------|-------------| | activity\_led | boolean | 启用/禁用 green activity LED | | power\_led | boolean | 启用/禁用 white power LED | | system\_health\_led | boolean | 启用/禁用 yellow system health LED | 返回 Raspberry Pi firmware 信息。在 Raspberry Pi 4 / 5 和 OS Agent 版本至少为 1.9.0 的 Home Assistant Yellow 上可用。报告的版本涵盖捆绑的 firmware payload(bootloader EEPROM 和 VL805 USB controller(如果存在))。如果 OS Agent 版本早于 1.9.0 则返回 `404`,如果运行中的 board 没有 Raspberry Pi firmware 接口则返回 `400`。 **Returned data:** | key | type | description | |-----|------|-------------| | current\_version | string | 当前安装的 firmware 版本 | | latest\_version | string | OS 中捆绑的最新 firmware 版本 | | update\_available | boolean | `latest_version` 比 `current_version` 新时为 `true` | | update\_blocked | boolean | 当前 boot 设备或 board configuration 阻止捆绑的 updater 应用时为 `true` | | update\_pending | boolean | 已应用 firmware 更新但系统尚未重启时为 `true` | | blocked\_reason | string or null | 当 `update_blocked` 为 `true` 时的阻止原因;否则为 `null`。参见下面注释。 | 每当 `update_blocked` 为 `true` 时,`blocked_reason` 始终为 `unsupported_boot_device`。根本原因各不相同(例如 USB/NVMe boot 设备,或禁用了 self-update 的 board)。未来可能会引入更具体的值。 **Example response:** ```json { "current_version": "1765222194", "latest_version": "1778498402", "update_available": true, "update_blocked": false, "update_pending": false, "blocked_reason": null } ``` 应用捆绑的 Raspberry Pi firmware 更新(bootloader EEPROM 和 VL805(如果存在))。成功后,Supervisor 会提出 `reboot_required` issue;需要重启才能开始运行新 firmware。如果 OS Agent 版本早于 1.9.0 则返回 `404`,如果运行中的 board 没有 Raspberry Pi firmware 接口或该 board / boot 设备阻止了更新,则返回 `400`。 ### 分辨率 **Returned data:** | key | type | description | |-----|------|-------------| | unsupported | list | 安装被标记为 unsupported 的原因列表(container, dbus, docker\_configuration, docker\_version, lxc, network\_manager, os, privileged, systemd) | | unhealthy | list | 安装被标记为 unhealthy 的原因列表(docker, supervisor, privileged, setup) | | issues | list | [Issue models](api/supervisor/models.md#issue) 列表 | | suggestions | list | [Suggestion models](api/supervisor/models.md#suggestion) actions 列表 | | checks | list | [Check models](api/supervisor/models.md#check) 列表 | **Example response:** ```json { "unsupported": ["os"], "unhealthy": ["docker"], "issues": [ { "uuid": "A89924620F9A11EBBDC3C403FC2CA371", "type": "free_space", "context": "system", "reference": null, "reference_extra": null } ], "suggestions": [ { "uuid": "B9923620C9A11EBBDC3C403FC2CA371", "type": "clear_backups", "context": "system", "reference": null, "reference_extra": null, "auto": false } ], "checks": [ { "slug": "free_space", "enabled": true } ] } ``` 应用一个建议的 action 忽略一个建议的 action 获取如果应用可以解决该 issue 的建议。 **Returned data:** | key | type | description | |-----|------|-------------| | suggestions | list | [Suggestion models](api/supervisor/models.md#suggestion) actions 列表 | **Example response:** ```json { "suggestions": [ { "uuid": "B9923620C9A11EBBDC3C403FC2CA371", "type": "clear_backups", "context": "system", "reference": null, "reference_extra": null, "auto": false } ] } ``` 忽略一个 issue 执行 healthcheck 并自动修复和通知。 设置此 check 的 options。 **Payload:** | key | type | description | |-----|------|-------------| | enabled | bool | check 应启用还是禁用 | 立即执行特定 check。 ### 服务 **Returned data:** | key | type | description | |-----|------|-------------| | services | dictionary | [Service models](api/supervisor/models.md#service) 字典 | **Example response:** ```json { "services": [ { "slug": "name", "available": true, "providers": ["awesome_addon"] } ] } ``` **Returned data:** | key | type | description | |-----|------|-------------| | addon | string | app 的 slug | | host | string | 运行该 service 的 addon 的 IP | | port | string | service 运行的端口 | | ssl | boolean | 使用 SSL 时为 `true` | | username | string | service 的 username | | password | string | service 的 password | | protocol | string | MQTT protocol | **Example response:** ```json { "addon": "awesome_mqtt", "host": "172.0.0.17", "port": "8883", "ssl": true, "username": "awesome_user", "password": "strong_password", "protocol": "3.1.1" } ``` 创建一个 service definition **Payload:** | key | type | description | |-----|------|-------------| | host | string | 运行该 service 的 addon 的 IP | | port | string | service 运行的端口 | | ssl | boolean | 使用 SSL 时为 `true` | | username | string | service 的 username | | password | string | service 的 password | | protocol | string | MQTT protocol | 删除 service definitions **Returned data:** | key | type | description | |-----|------|-------------| | addon | string | app 的 slug | | host | string | 运行该 service 的 addon 的 IP | | port | string | service 运行的端口 | | ssl | boolean | 使用 SSL 时为 `true` | | username | string | service 的 username | | password | string | service 的 password | | protocol | string | MQTT protocol | **Example response:** ```json { "addon": "awesome_mysql", "host": "172.0.0.17", "port": "8883", "username": "awesome_user", "password": "strong_password" } ``` 创建一个 service definition **Payload:** | key | type | description | |-----|------|-------------| | host | string | 运行该 service 的 addon 的 IP | | port | string | service 运行的端口 | | username | string | service 的 username | | password | string | service 的 password | 删除 service definitions ### 存储 返回 app store 信息。 **Example response:** ```json { "addons": [ { "name": "Awesome app", "slug": "7kshd7_awesome", "description": "Awesome description", "repository": "https://example.com/addons", "version": "1.0.0", "installed": "1.0.0", "icon": false, "logo": true, "state": "started" } ], "repositories": [ { "slug": "awesom_repository", "name": "Awesome Repository", "source": "https://example.com/addons", "url": "https://example.com/addons", "maintainer": "Awesome Maintainer" } ] } ``` 返回 store apps 列表 **Example response:** ```json [ { "name": "Awesome app", "slug": "7kshd7_awesome", "description": "Awesome description", "repository": "https://example.com/addons", "version": "1.0.0", "installed": "1.0.0", "icon": false, "logo": true, "state": "started" } ] ``` 返回关于 store app 的信息 **Example response:** ```json { "advanced": false, "apparmor": "default", "arch": ["armhf", "aarch64", "i386", "amd64"], "auth_api": true, "available": true, "build": false, "description": "Awesome description", "detached": false, "docker_api": false, "documentation": true, "full_access": true, "hassio_api": false, "hassio_role": "manager", "homeassistant_api": true, "homeassistant": "2021.2.0b0", "host_network": false, "host_pid": false, "icon": false, "ingress": true, "installed": false, "logo": true, "long_description": "lorem ipsum", "name": "Awesome app", "rating": 5, "repository": "core", "signed": false, "slug": "7kshd7_awesome", "stage": "stable", "update_available": false, "url": "https://example.com/addons/tree/main/awesome_addon", "version_latest": "1.0.0", "version": "1.0.0" } ``` 从 store 安装一个 app。 **Payload:** | key | type | description | |-----|------|-------------| | background | boolean | 立即返回 `job_id`,不等待安装完成。客户端必须检查 job 以获取 status | 从 store 更新一个 app。 **Payload:** | key | type | description | |-----|------|-------------| | backup | boolean | 创建 app 的 partial backup,默认为 false | | background | boolean | 立即返回 `job_id`,不等待更新完成。客户端必须检查 job 以获取 status | 获取 app 的 changelog。 获取 app 的 documentation。 获取 app icon 获取 app logo 如果 app 的最新版本能够安装到当前系统上,则返回 200 成功状态。如果无法安装,则返回 400 错误状态,并附带说明原因的消息。 重新加载关于 app 的存储信息。 返回 store repositories 列表 **Example response:** ```json [ { "slug": "awesom_repository", "name": "Awesome Repository", "source": "https://example.com/addons", "url": "https://example.com/addons", "maintainer": "Awesome Maintainer" } ] ``` 向 store 添加一个 addon repository **Payload:** | key | type | description | |-----|------|-------------| | repository | string | 要添加到 store 的 addon repository URL。 | **Example payload:** ```json { "repository": "https://example.com/addons" } ``` 返回关于 store repository 的信息 **Example response:** ```json { "slug": "awesom_repository", "name": "Awesome Repository", "source": "https://example.com/addons", "url": "https://example.com/addons", "maintainer": "Awesome Maintainer" } ``` 从 store 移除一个未使用的 addon repository。 修复/重置 store 中缺失或显示不正确信息的 addon repository。 ### 安全 返回关于 security features 的信息 **Returned data:** | key | type | description | |-----|------|-------------| | pwned | bool | pwned 检查在 backend 上启用还是禁用 | | force\_security | bool | force-security 在 backend 上启用还是禁用 | **Example response:** ```json { "pwned": true, "force_security": false, } ``` **Payload:** | key | type | description | |-----|------|-------------| | pwned | bool | 禁用/启用 pwned | | force\_security | bool | 禁用/启用 force-security | ### Supervisor 返回关于 supervisor 的信息 **Returned data:** | key | type | description | |-----|------|-------------| | version | string | 已安装的 supervisor 版本 | | version\_latest | string | 活动 channel 中最新发布的版本 | | update\_available | boolean | 有更新可用时为 `true` | | arch | string | host 的架构(armhf, aarch64, i386, amd64) | | channel | string | 活动 channel(stable, beta, dev) | | timezone | string | 当前 timezone | | healthy | bool | supervisor 处于健康状态 | | supported | bool | 环境受支持 | | logging | string | 当前 log 级别(debug, info, warning, error, critical) | | ip\_address | string | 指向 supervisor 的内部 docker IP 地址 | | wait\_boot | int | boot 期间等待的最大时间 | | debug | bool | Debug 已激活 | | debug\_block | bool | 已启用 debug block 时为 `true` | | diagnostics | bool or null | 已启用发送 diagnostics | | addons\_repositories | list | app repository URL 字符串列表 | | auto\_update | bool | 是否已为 supervisor 启用 auto update | | detect\_blocking\_io | bool | Supervisor 针对事件循环中的 blocking I/O 抛出异常 | | feature\_flags | dict | 开发 feature flag 名称与其启用状态的映射 | **Example response:** ```json { "version": "246", "version_latest": "version_latest", "update_available": true, "arch": "amd64", "channel": "dev", "timezone": "TIMEZONE", "healthy": true, "supported": false, "logging": "debug", "ip_address": "172.0.0.2", "wait_boot": 800, "debug": false, "debug_block": false, "diagnostics": null, "addons_repositories": ["https://example.com/addons"], "auto_update": true, "detect_blocking_io": false, "feature_flags": { "supervisor_v2_api": false } } ``` 通过 Systemd journal 后端获取 Supervisor 容器的 logs。如果 Systemd journal gateway 无法提供 logs,则以原始 Docker container logs 作为回退返回。 该 endpoint 接受与 `/host/logs` 相同的 headers 并提供相同的功能。 与 `/supervisor/logs` 相同,区别在于它会持续返回新的 log entries。 返回 Supervisor 容器最近一次启动的所有 logs。 `Range` header 被忽略,但可以使用 `lines` query 参数。 获取与特定 boot 相关的 Supervisor 容器 logs。 `bootid` 参数的解释方式与 `/host/logs/boots/` 中相同,该 endpoint 否则提供与 `/host/logs` 相同的功能。 与 `/supervisor/logs/boots/` 相同,区别在于它会持续返回新的 log entries。 更新 supervisor 的 options,你需要在 API 调用中至少提供一个 payload key。 更新 options 后,你需要调用 `/supervisor/reload`。 **Payload:** | key | type | description | |-----|------|-------------| | channel | string | 设置活动 channel(stable, beta, dev) | | timezone | string | 设置 timezone | | wait\_boot | int | 设置等待 boot 的时间 | | debug | bool | 启用 debug | | debug\_block | bool | 启用 debug block | | logging | string | 设置 logging 级别 | | addons\_repositories | list | 设置 app repositories 的 URL 字符串列表 | | auto\_update | bool | 为 supervisor 启用/禁用 auto update | | detect\_blocking\_io | string | 启用事件循环中的 blocking I/O 检测。有效值为 `on`、`off` 和 `on_at_startup`。 | | feature\_flags | dict | 部分更新开发 feature flags。Keys 为 feature flag 名称(例如 `supervisor_v2_api`),values 为布尔值。省略的 keys 保持不变。 | 向 supervisor 发送 Ping 以检查它是否能返回响应。 重新加载 supervisor 的部分内容,这将启用新的 options 并检查更新。 重启 supervisor,有助于让 supervisor 恢复健康状态。 修复 docker overlay 问题和丢失的镜像。 为 supervisor 返回一个 [Stats model](api/supervisor/models.md#stats)。 **Example response:** ```json { "cpu_percent": 14.0, "memory_usage": 288888, "memory_limit": 322222, "memory_percent": 32.4, "network_tx": 110, "network_rx": 902, "blk_read": 12, "blk_write": 27 } ``` 更新 supervisor **Payload:** | key | type | description | |-----|------|-------------| | version | string | 要安装的版本。默认为最新版本。仅限开发:仅在 Supervisor 开发环境中有效。 | ### 占位符 一些 endpoints 在 endpoint URL 中使用以 `<...>` 表示的占位符。 | placeholder | description | |-------------|-------------| | addon | addon 的 slug。要获取 slug,可以调用 `/addons`。要为调用 endpoint 的 app 调用 endpoints,可以使用 `self` 作为 slug。 | | application | application 名称。调用 `/audio/info` 获取正确的名称 | | backup | 有效的 backup slug,例如 `skuwe823`。要获取 slug,可以调用 `/backups` | | bootid | 特定 boot 的 id 或偏移量,用于筛选 logs。调用 `/host/logs/boots` 获取 boot ids 列表,或查看 `/host/logs/boots/` 以了解 boot 偏移量 | | check | Supervisor resolution manager 中 system check 的 slug。调用 `/resolution/info` 从 `checks` 字段获取选项列表 | | disk | 附加到 host 的 disk 标识符或 `default`。查看 `/host/disks//usage` 获取更多细节 | | id | 特定 interface 上 vlan 的数值 id。查看 `/network/interface//vlan/` 获取细节 | | identifier | 用于筛选 logs 的 syslog identifier。调用 `/host/logs/identifiers` 获取选项列表。查看 `/host/logs/identifiers/` 了解一些常见示例 | | interface | 有效的 interface 名称,例如 `eth0`。要获取 interface 名称,可以调用 `/network/info`。可以使用 `default` 获取 primary interface | | issue | Supervisor 识别的系统 issue 的 UUID。调用 `/resolution/info` 从 `issues` 字段获取选项列表 | | job\_id | 当前运行或已完成的 Supervisor job 的 UUID | | name | 添加到 Supervisor 的 mount 名称。调用 `/mounts` 从 `mounts` 字段获取选项列表 | | registry | 在 container registry configuration 中定义的 registry hostname。要获取 hostname,可以调用 `/docker/registries` | | repository | 添加到 Supervisor 的 addon repository 的 slug。调用 `/store` 从 `repositories` 字段获取选项列表 | | service | host 上 service 的 service name。 | | suggestion | Supervisor 识别的系统 issue 的 suggestion 的 UUID。调用 `/resolution/info` 从 `suggestions` 字段获取选项列表 | | uuid | discovery service 的 UUID。要获取 UUID,可以调用 `/discovery` | --- url: /developers/api/supervisor/examples.md --- 如何与 supervisor API 对接的示例。 ## 使用 cURL 获取网络信息 ```bash curl -sSL -H "Authorization: Bearer $SUPERVISOR_TOKEN" http://supervisor/network/info ``` **response:** ```json { "result": "ok", "data": { "interfaces": { "eth0": { "ip_address": "192.168.1.100/24", "gateway": "192.168.1.1", "id": "Wired connection 1", "type": "802-3-ethernet", "nameservers": ["192.168.1.1"], "method": "static", "primary": true } } } } ``` ## 向 supervisor 发送 Ping ```bash curl -sSL http://supervisor/supervisor/ping ``` **response:** ```json { "result": "ok", "data": {} } ``` --- url: /developers/api/supervisor/models.md --- 这些模型描述了从 supervisor API 返回的对象。 ## 应用(原称 add-on) | key | type | description | |-----|------|-------------| | name | string | app 的名称 | | slug | string | app 的 slug | | advanced | boolean | 已弃用且被忽略;自 Supervisor 2026.03.0 起始终为 `false` | | description | string | app 的描述 | | repository | string | app 来自的 repository | | version | string or null | app 已安装的版本 | | version\_latest | string | app 最新发布版本 | | update\_available | boolean | 有更新可用时为 `true` | | installed | string | 已安装时为 `true` | | available | boolean | 无法安装时为 `false` | | icon | bool | app 拥有 icon 文件 | | logo | bool | app 拥有 logo 文件 | | state | string | app 的 state(started, stopped) | | system\_managed | bool | 指示该 app 是否由 Home Assistant 管理 | ## 应用 | key | type | description | |-----|------|-------------| | name | string | application 名称 | | index | int | TODO: What is this? | | stream\_index | int | TODO: What is this? | | stream\_type | string | stream 的类型(INPUT, OUTPUT) | | volume | float | 当前音量 | | mute | boolean | 该 application 被静音时为 `true` | | addon | string | app 的 slug | ## 音频 | key | type | description | |-----|------|-------------| | card | list | [Card models](#card) 列表 | | input | list | [Audio device models](#audio-device) 列表 | | output | list | [Output device models](#audio-device) 列表 | | application | list | [Application models](#application) 列表 | ## 音频设备 | key | type | description | |-----|------|-------------| | name | string | 设备名称 | | index | int | TODO: What is this? | | description | string | 设备描述 | | volume | float | 当前音量 | | mute | string | 设备被静音时为 `true` | | default | string | 设备为默认时为 `true` | | card | int or null | TODO: What is this? | | applications | string | [Application models](#application) 列表 | ## 音频配置文件 | key | type | description | |-----|------|-------------| | name | string | profile 名称 | | description | string | profile 描述 | | active | boolean | 该 profile 处于活动状态时为 `true` | ## 卡片 | key | type | description | |-----|------|-------------| | name | string | card 名称 | | index | int | TODO: What is this? | | driver | string | card driver 名称 | | profiles | list | [Audio profile models](#audio-profile) 列表 | ## 发现 | key | type | description | |-----|------|-------------| | addon | string | app 的 slug | | service | string | 服务名称 | | uuid | string | discovery 的 UUID | | config | dict | 配置 | ## 主机服务 | key | type | description | |-----|------|-------------| | name | string | 服务名称 | | description | string | 服务描述 | | state | string | 服务 state | ## 网络接口 | key | type | description | |-----|------|-------------| | interface | string | 接口名称,例如 eth0。 | | type | string | 接口类型:`ethernet`、`wireless` 或 `vlan`。 | | enabled | boolean | 接口已启用时返回 True。 | | connected | boolean | 接口已连接到网络时返回 True。 | | primary | boolean | 为主网络接口时为 `true`。 | | ipv6 | struct or null | 包含 IPv6 连接详情的 [IPv6 configuration](#ipv6-configuration) struct。 | | ipv4 | struct or null | 包含 IPv4 连接详情的 [IPv4 configuration](#ipv4-configuration) struct。 | | wifi | struct or null | 包含无线连接详情的 [Wifi configuration](#wifi-configuration) struct。 | | vlan | struct or null | 包含 vlan 详情的 [VLAN configuration](#vlan-configuration) struct。 | ### IPv6 configuration | key | type | description | |-----|------|-------------| | method | string | 设置 IP 的方法可以是 `static`、`auto` 或 `disabled`。 | | addr\_gen\_mode | string | Address generation mode 可以是 `eui64` 或 `stable-privacy`、`default-or-eui64` 或 `default` | | ip6\_privacy | string | Privacy extensions 选项有 `disabled`、`enabled-prefer-public`、`enabled` 或 `default` | | address | list | 包含 IP 地址和 netmask 的列表,格式为 ::/XXX。 | | gateway | string | 网关的 IP 地址。 | | nameservers | list | 包含配置的 nameservers IP 地址的字符串列表。 | | route\_metric | int | Route metric。值越低优先级越高。内核接受零(0)但会将其强制转换为 1024(用户默认值)。 | ### IPv4 configuration | key | type | description | |-----|------|-------------| | method | string | 设置 IP 的方法可以是 `static`、`auto` 或 `disabled`。 | | address | list | 包含 IP 地址和 netmask 的列表,格式为 X.X.X.X/XX。 | | gateway | string | 网关的 IP 地址。 | | nameservers | list | 包含配置的 nameservers IP 地址的字符串列表。 | | route\_metric | int | Route metric。值越低优先级越高。 | ### Wi-Fi 配置 | key | type | description | |-----|------|-------------| | mode | string | 设置模式 `infrastructure`、`mesh`、`adhoc` 或 `ap`。 | | auth | string | 设置 auth 模式:`open`、`web` 或 `wpa-psk`。 | | ssid | string | 为 Wireless 设置 SSID。 | | signal | integer | 信号强度百分比。 | ### VLAN configuration | key | type | description | |-----|------|-------------| | id | integer | VLAN ID。 | | parent | string | VLAN 附加到的父接口。 | ## 接入点 | key | type | description | |-----|------|-------------| | mode | string | 之一:`infrastructure`、`mesh` 或 `adhoc`。 | | ssid | string | Wireless 网络 ID。 | | frequency | integer | 此 Access Point 的工作频率。 | | signal | integer | 信号强度百分比。 | | mac | string | Access Point 的 MAC Address。 | ## 面板 | key | type | description | |-----|------|-------------| | enable | boolean | 已启用时为 `true` | | icon | string | sidebar icon | | title | string | sidebar title | | admin | boolean | 仅供 admin 账户使用时为 `true` | ## 仓库 | key | type | description | |-----|------|-------------| | slug | string | repository slug | | name | string | repository 名称 | | source | string | 指向 repository 的 URL | | url | string or null | repository website 的 URL | | maintainer | string | repository 维护者名称 | ## 服务 | key | type | description | |-----|------|-------------| | slug | string | service slug | | available | boolean | 服务可用时为 `true` | | providers | list | 该服务的 providers 列表 | ## 备份 | key | type | description | |-----|------|-------------| | slug | string | 为 backup 生成的 slug | | date | string | backup 创建日期的 ISO 日期字符串表示 | | name | string | 赋予 backup 的名称 | | type | string | backup 的类型(full, partial) | | protected | boolean | backup 受密码保护时为 `true` | | content | dictionary | backup content 详情。参见 [Backup -> content](#backup---content) | | compressed | boolean | backup 以压缩归档保存时为 `true` | ### 备份到内容 Backup 对象的 `content` key 包含以下 key: | key | type | description | |-----|------|-------------| | homeassistant | boolean | backup 包含 homeassistant 时为 `true` | | addons | list | backup 中包含的 app slugs 列表 | | folders | list | backup 中包含的文件夹名称列表 | ## 备份 details | key | type | description | |-----|------|-------------| | slug | string | 为 backup 生成的 slug | | type | string | backup 的类型(full, partial) | | name | string | 赋予 backup 的名称 | | date | string | backup 创建日期的 ISO 日期字符串表示 | | size | string | backup 大小(MB) | | protected | boolean | backup 受密码保护时为 `true` | | location | string or null | backup 存储所在的 backup mount 名称。本地存储时为 `null`。 | | homeassistant | string | 当时使用的 Home Assistant 版本 | | addons | list | backup 中的 apps 列表。Apps 以字典形式表示,包含这些 key:\[`slug`,`name`,`version`,`size`] | | repositories | list | app repository URL 字符串列表 | | folders | list | 表示目录的字符串列表 | | homeassistant\_exclude\_database | boolean | Home Assistant 数据库文件被从此 backup 中排除时为 `true` | ## 统计 | key | type | description | |-----|------|-------------| | cpu\_percent | float | 已使用的 CPU 百分比 | | memory\_usage | int | 当前内存使用量(字节) | | memory\_limit | int | 允许的最大内存使用量(字节) | | memory\_percent | float | 已使用的内存百分比 | | network\_tx | int | 网络发送使用量 | | network\_rx | int | 网络接收使用量 | | blk\_read | int | 文件系统读取使用量 | | blk\_write | int | 文件系统写入使用量 | ## 问题 | key | type | description | |-----|------|-------------| | uuid | str | 作为 issue ID 的生成 uuid | | type | str | issue 类型 | | context | str | issue 发生的上下文 | | reference | str or null | 取决于上下文;对另一个 model 的引用(例如 app slug) | | reference\_extra | dict or null | 关于该 issue 的额外上下文特定元数据(例如哪个端口存在冲突) | ## 建议 | key | type | description | |-----|------|-------------| | uuid | str | 作为 suggestion ID 的生成 uuid | | type | str | suggestion 类型 | | context | str | suggestion 发生的上下文 | | reference | str or null | 取决于上下文;对另一个 model 的引用(例如 app slug) | | reference\_extra | dict or null | 关于该 suggestion 的额外上下文特定元数据(例如要清除哪个端口) | | auto | bool | 建议的修复将自动应用时为 True | ## 检查 | key | type | description | |-----|------|-------------| | slug | str | 为 check 生成的 slug | | enable | bool | check 的启用状态 | ## 设备 | key | type | description | |-----|------|-------------| | name | string | 设备对象名称 | | sysfs | string | 指向 sysfs 设备对象的路径 | | dev\_path | string | 指向 devfs 的路径 | | subsystem | string or null | 设备的 subsystem 类型(tty, input, sound, block, misc) | | parent | string or null | 指向父 sysfs 设备对象的路径 | | by\_id | string or null | Udev by ID 链接 | | attributes | dict | 包含用于调试和理解的纯 udev 设备 attributes 的 dict | | children | list | 指向子 sysfs 设备的路径列表 | ## 磁盘 | key | type | description | |-----|------|-------------| | name | string | 磁盘设备名称 | | vendor | string | 磁盘设备厂商 | | model | string | 磁盘设备型号 | | serial | string | 磁盘设备的序列号 | | size | int | 磁盘大小(字节) | | id | string | 磁盘设备的唯一 ID(UDisks2 drive ID 或设备路径) | | dev\_path | string | 磁盘设备的设备路径 | ## 挂载 | key | type | description | request/response | |-----|------|-------------|------------------| | name | string | mount 名称 | both | | type | string | mount 类型(cifs 或 nfs) | both | | usage | string | mount 用途(backup, media, 或 share) | both | | server | string | 网络共享服务器的 IP 地址或主机名 | both | | port | int | 要使用的端口(如果不使用该 mount 类型的标准端口) | both | | read\_only | bool | mount 为只读(不适用于 backup mounts) | both | | path | string | (仅 nfs mounts) 从网络共享挂载的路径 | both | | share | string | (仅 cifs mounts) 从网络共享挂载的 share | both | | username | string | (仅 cifs mounts) 用于认证的 username | request only | | password | string | (仅 cifs mounts) 用于认证的 password | request only | | state | string | mount 的当前 state(active, failed 等) | response only | Request only 字段可以包含在 requests 中,但永远不会出现在 responses 中。 Response only 字段会出现在 responses 中,但不能包含在 requests 中。 ## 任务 | key | type | description | |-----|------|-------------| | name | string | job 名称 | | reference | string | job 所作用的实例的唯一 ID(如果适用) | | uuid | string | job 的唯一 ID | | progress | int | job 的进度(如果可以获得准确的进度) | | stage | string | job 所处 stage 的名称(如果适用) | | done | boolean | job 是否完成 | | created | string | job 创建的日期和时间(ISO 格式) | | child\_jobs | list | 由该 job 启动的子[jobs](#job)列表 | | errors | list | 执行期间发生的[errors](#job-error)列表 | | extra | dictionary or null | 与该 job 或 stage 相关的额外元数据(如果适用) | ## 任务错误 | key | type | description | |-----|------|-------------| | type | string | 发生的错误类型 | | message | string | 出错情况的人类可读描述 | | stage | string | 错误发生时 job 所处 stage 的名称(如果适用) | ## 启动槽位 | key | type | description | |-----|------|-------------| | state | string | Active 或 inactive(active slot 正在使用中) | | status | string | 从该 slot 最后一次启动的状态(good 或 bad) | | version | string | 已安装 OS 的版本 | ## 用户 | key | type | description | |-----|------|-------------| | username | string | 用于登录的 Username | | name | string | 用户名称 | | is\_owner | boolean | 该用户是否为 owner | | is\_active | boolean | 该用户是否 active | | local\_only | boolean | 用户能否从网络登录(例如通过 http) | | group\_ids | list | 用户拥有的 role(s)(admin 等) | ## 驱动器 | key | type | description | |-----|------|-------------| | vendor | string | Drive vendor | | model | string | Drive 型号 | | serial | string | Drive 序列号 | | id | string | Drive 的唯一且持久 id | | size | int | Drive 大小(字节) | | time\_detected | datetime | Drive 被系统检测到的时间 | | connection\_bus | string | Drive 的物理连接总线(USB 等) | | seat | string | Drive 所插入的 seat 标识符 | | removable | boolean | Drive 是否可由用户移除? | | ejectable | boolean | Drive 是否可由系统弹出? | | filesystems | list | Drive 上的[filesystem partitions](#filesystem)列表 | ## 文件系统 | key | type | description | |-----|------|-------------| | device | string | filesystem 的特殊设备文件(例如 `/dev/sda1`) | | id | string | filesystem 的唯一且持久 id | | size | int | filesystem 大小(字节) | | name | string | filesystem 名称(如果已知) | | system | boolean | filesystem 被视为 system/internal 设备时为 `true` | | mount\_points | list | filesystem 挂载的路径列表。 | --- url: /developers/api/websocket.md --- Home Assistant 在 `/api/websocket` 托管一个 WebSocket API。此 API 可用于将 Home Assistant 实例的信息流式传输到任何实现了 WebSockets 的客户端。我们维护一个 [JavaScript library](https://github.com/home-assistant/home-assistant-js-websocket),在我们的 frontend 中使用它。 ## 服务器 states 1. 客户端连接。 2. 开始认证阶段。 * 服务器发送 `auth_required` 消息。 * 客户端发送 `auth` 消息。 * 如果 `auth` 消息正确:进入第 3 步。 * 服务器发送 `auth_invalid`。进入第 6 步。 3. 发送 `auth_ok` 消息 4. 认证阶段结束。 5. 开始命令阶段。 1. 客户端可以发送命令。 2. 服务器可以发送之前命令的结果。 6. 客户端或服务器断开会话。 在命令阶段,客户端会给每条消息附加一个唯一的标识符。服务器会将此标识符添加到每条消息中,以便客户端可以将每条消息与其来源关联起来。 ## 消息格式 每个 API 消息都是一个 JSON 序列化的对象,包含一个 `type` key。在认证阶段之后,消息还必须包含一个 `id`,一个调用者可以用来将消息与响应关联的整数。 auth 消息示例: ```json { "type": "auth", "access_token": "ABCDEFGHIJKLMNOPQ" } ``` ```json { "id": 5, "type":"event", "event":{ "data":{}, "event_type":"test_event", "time_fired":"2016-11-26T01:37:24.265429+00:00", "origin":"LOCAL" } } ``` ## 认证阶段 当客户端连接到服务器时,服务器会发出 `auth_required`。 ```json { "type": "auth_required", "ha_version": "2021.5.3" } ``` 客户端的第一条消息应该是一个 auth 消息。你可以使用 access token 进行授权。 ```json { "type": "auth", "access_token": "ABCDEFGH" } ``` 如果客户端提供了有效的认证,服务器通过发送 `auth_ok` 消息来完成认证阶段: ```json { "type": "auth_ok", "ha_version": "2021.5.3" } ``` 如果数据不正确,服务器将以 `auth_invalid` 消息回复并断开会话。 ```json { "type": "auth_invalid", "message": "Invalid password" } ``` ## 功能启用阶段 支持需要启用的 features 的客户端,应作为第一条消息(`"id": 1`)发送以下形式的消息: ``` { "id": 1, "type": "supported_features", "features": { coalesce_messages: 1 } } ``` 目前唯一支持的 feature 是 'coalesce\_messages',其结果是消息以批量方式合并发送,而不是逐个发送。 ## 命令阶段 在此阶段,客户端可以向服务器发送命令。服务器将对每个命令回复一个 `result` 消息,指示命令何时完成以及是否成功,并附带命令的 context。 ```json { "id": 6, "type": "result", "success": true, "result": { "context": { "id": "326ef27d19415c60c492fe330945f954", "parent_id": null, "user_id": "31ddb597e03147118cf8d2f8fbea5553" } } } ``` ## 订阅 events 命令 `subscribe_events` 将使你的客户端订阅 event bus。你可以监听所有 events 或特定 event 类型。如果你想监听多个 event 类型,你将需要发送多个 `subscribe_events` 命令。 ```json { "id": 18, "type": "subscribe_events", // 可选 "event_type": "state_changed" } ``` 服务器将以 result 消息回复,以指示订阅已激活。 ```json { "id": 18, "type": "result", "success": true, "result": null } ``` 对于每个匹配的 event,服务器将发送一条类型为 `event` 的消息。消息中的 `id` 将指向 `listen_event` 命令的原始 `id`。 ```json { "id": 18, "type":"event", "event":{ "data":{ "entity_id":"light.bed_light", "new_state":{ "entity_id":"light.bed_light", "last_changed":"2016-11-26T01:37:24.265390+00:00", "state":"on", "attributes":{ "rgb_color":[ 254, 208, 0 ], "color_temp":380, "supported_features":147, "xy_color":[ 0.5, 0.5 ], "brightness":180, "white_value":200, "friendly_name":"Bed Light" }, "last_updated":"2016-11-26T01:37:24.265390+00:00", "context": { "id": "326ef27d19415c60c492fe330945f954", "parent_id": null, "user_id": "31ddb597e03147118cf8d2f8fbea5553" } }, "old_state":{ "entity_id":"light.bed_light", "last_changed":"2016-11-26T01:37:10.466994+00:00", "state":"off", "attributes":{ "supported_features":147, "friendly_name":"Bed Light" }, "last_updated":"2016-11-26T01:37:10.466994+00:00", "context": { "id": "e4af5b117137425e97658041a0538441", "parent_id": null, "user_id": "31ddb597e03147118cf8d2f8fbea5553" } } }, "event_type":"state_changed", "time_fired":"2016-11-26T01:37:24.265429+00:00", "origin":"LOCAL", "context": { "id": "326ef27d19415c60c492fe330945f954", "parent_id": null, "user_id": "31ddb597e03147118cf8d2f8fbea5553" } } } ``` ## 订阅 trigger 你也可以使用 `subscribe_trigger` 订阅一个或多个 triggers。这些与[自动化 triggers](https://www.home-assistant.io/docs/automation/trigger/)所使用的语法相同。你可以定义一个或一组 triggers。 ```json { "id": 2, "type": "subscribe_trigger", "trigger": { "platform": "state", "entity_id": "binary_sensor.motion_occupancy", "from": "off", "to":"on" } } ``` 作为响应,你将收到: ```json { "id": 2, "type": "result", "success": true, "result": null } ``` 对于每个匹配的 trigger,服务器将发送一条类型为 `trigger` 的消息。消息中的 `id` 将指向 `subscribe_trigger` 命令的原始 `id`。注意,你的 variables 将根据所使用的 trigger 而不同。 ```json { "id": 2, "type": "event", "event": { "variables": { "trigger": { "id": "0", "idx": "0", "platform": "state", "entity_id": "binary_sensor.motion_occupancy", "from_state": { "entity_id": "binary_sensor.motion_occupancy", "state": "off", "attributes": { "device_class": "motion", "friendly_name": "motion occupancy" }, "last_changed": "2022-01-09T10:30:37.585143+00:00", "last_updated": "2022-01-09T10:33:04.388104+00:00", "context": { "id": "90e30ad8e6d0c218840478d3c21dd754", "parent_id": null, "user_id": null } }, "to_state": { "entity_id": "binary_sensor.motion_occupancy", "state": "on", "attributes": { "device_class": "motion", "friendly_name": "motion occupancy" }, "last_changed": "2022-01-09T10:33:04.391956+00:00", "last_updated": "2022-01-09T10:33:04.391956+00:00", "context": { "id": "9b263f9e4e899819a0515a97f6ddfb47", "parent_id": null, "user_id": null } }, "for": null, "attribute": null, "description": "state of binary_sensor.motion_occupancy" } }, "context": { "id": "9b263f9e4e899819a0515a97f6ddfb47", "parent_id": null, "user_id": null } } } ``` ### 取消订阅 events 你可以取消之前创建的订阅。将原始订阅命令的 id 作为值传递给 subscription 字段。 ```json { "id": 19, "type": "unsubscribe_events", "subscription": 18 } ``` 服务器将以 result 消息回复,以指示取消订阅成功。 ```json { "id": 19, "type": "result", "success": true, "result": null } ``` ## 触发 event 这将在 Home Assistant event bus 上触发一个 event。 ```json { "id": 24, "type": "fire_event", "event_type": "mydomain_event", // 可选 "event_data": { "device_id": "my-device-id", "type": "motion_detected" } } ``` 服务器将以 result 消息回复,以指示 event 触发成功。 ```json { "id": 24, "type": "result", "success": true, "result": { "context": { "id": "326ef27d19415c60c492fe330945f954", "parent_id": null, "user_id": "31ddb597e03147118cf8d2f8fbea5553" } } } ``` ## 调用 service action 这将在 Home Assistant 中调用一个 service action。目前没有任何返回值。如果客户端对由于调用而产生的已变化 entities 感兴趣,可以监听 `state_changed` events。 ```json { "id": 24, "type": "call_service", "domain": "light", "service": "turn_on", // 可选 "service_data": { "color_name": "beige", "brightness": "101" } // 可选 "target": { "entity_id": "light.kitchen" } // 对于返回 response data 的 service actions 必须包含 "return_response": true } ``` 服务器将通过一条消息指示 action 已完成执行。 ```json { "id": 24, "type": "result", "success": true, "result": { "context": { "id": "326ef27d19415c60c492fe330945f954", "parent_id": null, "user_id": "31ddb597e03147118cf8d2f8fbea5553" }, "response": null } } ``` 调用的 `result` 将始终包含一个 `response`,以应对支持响应的 service actions。当调用不支持响应的 action 时,`response` 的值将为 `null`。 ## 获取 states 这将获取 Home Assistant 中所有当前 states 的 dump。 ```json { "id": 19, "type": "get_states" } ``` 服务器将以包含 states 的 result 消息回复。 ```json { "id": 19, "type": "result", "success": true, "result": [ ... ] } ``` ## 获取 config 这将获取 Home Assistant 中当前 config 的 dump。 ```json { "id": 19, "type": "get_config" } ``` 服务器将以包含 config 的 result 消息回复。 ```json { "id": 19, "type": "result", "success": true, "result": { ... } } ``` ## 获取 service actions 这将获取 Home Assistant 中当前 service actions 的 dump。 ```json { "id": 19, "type": "get_services" } ``` 服务器将以包含 service actions 的 result 消息回复。 ```json { "id": 19, "type": "result", "success": true, "result": { ... } } ``` ## 获取 panels 这将获取 Home Assistant 中当前已注册 panels 的 dump。 ```json { "id": 19, "type": "get_panels" } ``` 服务器将以包含当前已注册 panels 的 result 消息回复。 ```json { "id": 19, "type": "result", "success": true, "result": [ ... ] } ``` ## Ping 和 pong API 支持接收来自客户端的 ping 并返回 pong。这作为心跳,以确保连接仍然存活: ```json { "id": 19, "type": "ping" } ``` 如果连接仍然 active,服务器应尽快发送 pong 作为回应: ```json { "id": 19, "type": "pong" } ``` ## 验证 config 此命令允许你验证 triggers、conditions 和 action configurations。`trigger`、`condition` 和 `action` keys 将被作为自动化的一部分进行验证(因此 triggers/conditions/actions 的列表也是允许的)。所有字段都是可选的,结果将只包含传入的 keys。 ```json { "id": 19, "type": "validate_config", "trigger": ..., "condition": ..., "action": ... } ``` 服务器将以验证结果回复。只有命令消息中同时包含的字段才会出现在响应中。 ```json { "id": 19, "type": "result", "success": true, "result": { "trigger": {"valid": true, "error": null}, "condition": {"valid": false, "error": "Invalid condition specified for data[0]"}, "action": {"valid": true, "error": null} } } ``` ## 从 target 提取 此命令允许你从一个或多个 targets 中提取 entities、devices 和 areas。 ```json { "id": 19, "type": "extract_from_target", "target": { "entity_id": ["group.kitchen"], "device_id": ["device_abc123"], "area_id": ["kitchen"], "label_id": ["smart_lights"] }, // 可选:将 group entities 展开为成员(默认:false) "expand_group": true } ``` target 参数的结构与服务调用 targets 相同。 服务器将以从 target 中提取的信息回复: ```json { "id": 19, "type": "result", "success": true, "result": { "referenced_entities": ["light.kitchen", "switch.kitchen", "light.living_room", "switch.bedroom"], "referenced_devices": ["device_abc123", "device_def456"], "referenced_areas": ["kitchen", "living_room"], "missing_devices": [], "missing_areas": [], "missing_floors": [], "missing_labels": [] } } ``` 响应包括: * `referenced_entities`: 将被目标的所有 entity IDs(包括来自 devices/areas/labels 的 entities) * `referenced_devices`: 被引用的所有 device IDs * `referenced_areas`: 被引用的所有 area IDs * `missing_devices`: 不存在的 device IDs * `missing_areas`: 不存在的 area IDs * `missing_floors`: 不存在的 floor IDs * `missing_labels`: 不存在的 label IDs 当 `expand_group` 设为 `true` 时,group entities 将被展开以包含其 member entities,而不是 group entity 本身。 ## 获取 target 的 triggers/conditions/services `get_triggers_for_target`、`get_conditions_for_target` 和 `get_services_for_target` 命令允许你获取 target 中 entities 的所有适用 triggers、conditions 和 services。这三个命令共享相同的输入和输出格式。 ```json { "id": 20, "type": "get_triggers_for_target", "target": { "entity_id": ["light.kitchen", "light.living_room"], "device_id": ["device_abc123"], "area_id": ["bedroom"], "label_id": ["smart_lights"] }, // 可选:将 group entities 展开为成员(默认:true) "expand_group": true } ``` target 参数的结构与服务调用 targets 相同。 服务器将以适用于 target 中任何 entity 的一组 trigger/condition/service 标识符回复,格式为 `domain.trigger_name`: ```json { "id": 20, "type": "result", "success": true, "result": [ "homeassistant.event", "homeassistant.state", "light.turned_on", "light.turned_off", "light.toggle" ] } ``` 当 `expand_group` 设为 `true`(默认)时,group entities 将被展开以包含其 member entities,适用于任何 member 的 triggers 将包含在结果中。否则,仅包含适用于 group entities 本身的 triggers。 ## 获取用于显示的 Entity Registry entries `config/entity_registry/list_for_display` 返回一个轻量级、经过优化的 entity registry entries 列表,适合在 UI 中显示。仅包含已启用(非禁用)的 entities。 响应以紧凑格式包含 entity data,使用简写属性 key 以最小化带宽并提高性能。 ### 使用场景 此 endpoint 设计用于: * 在 UI 中显示 entities 列表 * 仪表板和 UI 组件的实时 entity 更新 * 面向移动客户端的带宽高效数据传输 * 在 device management 界面中渲染 entity 信息 ### 请求 ```json { "id": 1, "type": "config/entity_registry/list_for_display" } ``` ### 响应 ```json { "id": 1, "type": "result", "success": true, "result": { "entity_categories": { 0: "config", 1: "diagnostic" }, "entities": [ { "ei": "light.living_room", "pl": "hue", "ai": "living_room", "di": "abc123def456", "en": "Living Room", "hn": true }, { "ei": "switch.setting", "pl": "esphome", "di": "cde83923", "en": "Setting for something", "hn": true, "ec": 0 } ] } } ``` ### 响应属性 #### 根对象 | Name | Type | Description | |------|------|-------------| | `id` | int | 请求 ID 的 echo | | `type` | string | 始终为 `"result"` | | `success` | boolean | 成功响应时始终为 `true` | | `result` | object | 包含 `entity_categories` 和 `entities` 的实际 response data | #### Entity 类别映射 | Name | Type | Description | |------|------|-------------| | `entity_categories` | object\[number, string] | 将数值索引映射到 entity category 字符串,用于解码 entities 中的 `ec` 属性。允许 UI 将 category 索引解释回人类可读的名称。 | ### 实体 #### 过滤与行为 * **排除禁用的 entities**:仅包含 `disabled_by = null` 的 entities。禁用的 entities(由 user、integration、device、config entry 或 system 禁用)会被过滤掉。 * **属性简写**:属性 key 被简写,以最小化 JSON payload 大小,从而提高性能。 * **类型转换**:Sets(如 `labels`)被转换为列表以进行 JSON 序列化。 * **Category 编码**:Entity categories 以数值索引形式发送,而不是字符串,以减小数据量。使用 `entity_categories` 映射在 UI 上解码它们。 * **条件属性**:可选属性仅在具有有意义的值(非 null、非空或 true)时才包含在响应中。 #### Entity 属性 `entities` 数组中的每个 entity 对象使用简写的属性名称以提高性能: | Name | Type | Required | Description | Source | |------|------|----------|-------------|--------| | `ei` | string | Yes | Entity ID - entity 的唯一标识符(例如 `"light.living_room"`) | `RegistryEntry.entity_id` | | `pl` | string | Yes | Platform - 创建该 entity 的集成(例如 `"hue"`、`"mqtt"`) | `RegistryEntry.platform` | | `ai` | string | No | Area ID - 该 entity 分配的 area | `RegistryEntry.area_id`(仅当非 `null` 时) | | `lb` | array\[string] | No | Labels - 分配给该 entity 的 label IDs 列表,用于组织 | `RegistryEntry.labels`(转换为列表,仅当非空时) | | `di` | string | No | Device ID - 该 entity 所属的 device | `RegistryEntry.device_id`(仅当非 `null` 时) | | `ic` | string | No | Icon - 用户设置的自定义 icon(覆盖 state icon,因此如果设置了此项,不要使用 state 中的 attribute 值),icons 格式为 `"prefix:icon-name"`,例如:`"mdi:lightbulb-on"` | `RegistryEntry.icon`(仅当非 `null` 时) | | `tk` | string | No | Translation Key - 用于从集成翻译 entity 名称的 key | `RegistryEntry.translation_key`(仅当非 `null` 时) | | `ec` | integer | No | Entity Category(index)- 在 `entity_categories` 映射中的数值索引 | `RegistryEntry.entity_category`(仅当非 `null` 时) | | `hb` | boolean | No | Hidden By - 如果 entity 被 user 或 integration 隐藏则存在(true) | `RegistryEntry.hidden_by`(仅当非 `null` 时以 true 出现) | | `hn` | boolean | No | Has Entity Name - 如果 entity 使用集成提供的名称则存在(true) | `RegistryEntry.has_entity_name`(仅当为 `true` 时以 true 出现) | | `en` | string | No | Entity Name - entity 的显示名称(优先用户自定义) | 用户设置的 `RegistryEntry.name` 或回退到 `RegistryEntry.original_name`(仅当任一被设置时) | | `dp` | integer | No | Display Precision - 显示值的 sensor 特定精度。用户配置的 `display_precision` 优先;回退到集成提供的 `suggested_display_precision` | `RegistryEntry.options["sensor"]["display_precision"]`(首选)或 `RegistryEntry.options["sensor"]["suggested_display_precision"]`(仅 sensor domain,仅当设置时) | ## 管理已暴露的 entities 这些命令管理哪些 entities 暴露给 voice assistants(Assist 对应 `conversation`,Alexa 对应 `cloud.alexa`,Google Assistant 对应 `cloud.google_assistant`)。 ### 列出已暴露的 entities 返回所有 assistants 中所有 entities 的暴露状态。 ```json { "id": 18, "type": "homeassistant/expose_entity/list" } ``` 服务器将以 entity IDs 到各 assistant 的暴露状态映射回复: ```json { "id": 18, "type": "result", "success": true, "result": { "exposed_entities": { "light.living_room": { "conversation": true, "cloud.alexa": false, "cloud.google_assistant": false }, "sensor.temperature": { "conversation": true } } } } ``` 只有被明确暴露或未暴露的 entities 才会出现在结果中。响应中未出现的 entities 尚未配置,并使用默认的暴露设置。 ### 暴露或未暴露 entities 将一个或多个 entities 暴露或未暴露给一个或多个 voice assistants。更改立即生效,无需重启 Home Assistant。 ```json { "id": 19, "type": "homeassistant/expose_entity", "assistants": ["conversation"], "entity_ids": ["light.living_room", "sensor.temperature"], "should_expose": true } ``` | Field | Type | Description | |-------|------|-------------| | `assistants` | array\[string] | assistant 标识符列表:`"conversation"`、`"cloud.alexa"`、`"cloud.google_assistant"` | | `entity_ids` | array\[string] | 要暴露或未暴露的 entity IDs 列表 | | `should_expose` | boolean | 暴露为 `true`,未暴露为 `false` | 服务器将以 result 消息回复: ```json { "id": 19, "type": "result", "success": true, "result": null } ``` ## 错误处理 如果发生错误,`result` 消息中的 `success` key 将被设为 `false`。它将包含一个 `error` key,其中包含一个带有两个 key 的对象:`code` 和 `message`。 ```json { "id": 12, "type":"result", "success": false, "error": { "code": "invalid_format", "message": "Message incorrectly formatted: expected str for dictionary value @ data['event_type']. Got 100" } } ``` ### 在调用 service actions 和翻译期间的错误处理 下面的 JSON 展示了一个错误响应的示例。如果处理了 `HomeAssistantError` 错误(或 `HomeAssistantError` 的子类),如果设置了翻译信息,将被添加到响应中。 在处理 `ServiceValidationError`(`service_validation_error`)时,仅在 debug 级别向日志打印堆栈跟踪。 ```json { "id": 24, "type":"result", "success": false, "error": { "code": "service_validation_error", "message": "Option 'custom' is not a supported mode.", "translation_key": "unsupported_mode", "translation_domain": "kitchen_sink", "translation_placeholders": { "mode": "custom" } } } ``` [阅读更多](/developers/core/platform/raising_exceptions.md) 关于抛出 exceptions 或 [exceptions 的本地化](/developers/internationalization/core.md#exceptions)。 --- url: /developers/api_lib_auth.md --- 本页面向旨在集成第三方 API 的第三方库的一般 API 开发。有关与 Home Assistant API 交互的信息,请参见[Home Assistant REST API 文档](/developers/api/rest.md)。 库的 Authentication 部分负责获取认证信息以及发起经过认证的请求。它不应该知道请求中包含了什么内容。 认证有许多种形式,但归根结底通常就是每个请求都附带一个 `authorization` header,其中包含一个 access token。access token 通常是一串随机数字和字母的字符串。 你的库应该能够获取认证令牌、在必要时更新它们,并使用认证信息发起请求。它不应提供存储认证数据的功能。 由于认证信息将由开发者存储,因此重要的是你要以可以 JSON 序列化的格式将认证信息返回给开发者。建议使用包含基本类型(`str`、`float`、`int`)的 `dict`。 如果你的 API 可以从多个位置提供,你的认证类应该允许开发者传入 API 的位置。 ## 异步示例 Python 允许开发者编写同步或异步(通过 `asyncio`)的代码。Home Assistant 使用 async 编写,但也能够与同步库配合使用。我们更倾向于使用 async 库。 如果你在编写 async 库,我们建议使用 `aiohttp`。它是一个现代且成熟的 HTTP 库,易于使用。 ```python from aiohttp import ClientSession, ClientResponse class Auth: """Class to make authenticated requests.""" def __init__(self, websession: ClientSession, host: str, access_token: str): """Initialize the auth.""" self.websession = websession self.host = host self.access_token = access_token async def request(self, method: str, path: str, **kwargs) -> ClientResponse: """Make a request.""" if headers := kwargs.pop("headers", {}): headers = dict(headers) headers["authorization"] = self.access_token return await self.websession.request( method, f"{self.host}/{path}", **kwargs, headers=headers, ) ``` 要使用此类,你需要创建一个 aiohttp `ClientSession` 并将其与 API 信息一起传递给构造函数。 ```python import asyncio import aiohttp from my_package import Auth async def main(): async with aiohttp.ClientSession() as session: auth = Auth(session, "http://example.com/api", "secret_access_token") # This will fetch data from http://example.com/api/lights resp = await auth.request("get", "lights") print("HTTP response status code", resp.status) print("HTTP response JSON content", await resp.json()) asyncio.run(main()) ``` ## 同步示例 ```python import requests class Auth: """Class to make authenticated requests.""" def __init__(self, host: str, access_token: str): """Initialize the auth.""" self.host = host self.access_token = access_token def request(self, method: str, path: str, **kwargs) -> requests.Response: """Make a request.""" if headers := kwargs.pop("headers", {}): headers = dict(headers) headers["authorization"] = self.access_token return requests.request( method, f"{self.host}/{path}", **kwargs, headers=headers, ) ``` 要使用此类,请用 API 信息构造该类。 ```python from my_package import Auth auth = Auth("http://example.com/api", "secret_access_token") # This will fetch data from http://example.com/api/lights resp = auth.request("get", "lights") print("HTTP response status code", resp.status_code) print("HTTP response JSON content", resp.json()) ``` ## OAuth2 OAuth2 是一种利用 refresh token 和 access token 的[标准化](https://tools.ietf.org/html/rfc6749)认证方案。access token 在颁发后短时间内即过期。refresh token 可用于获取新的 access token。 刷新 access token 依赖于 client ID 和 secret,它们可能由外部服务持有。我们需要设计认证类的结构,使其能够允许开发者实现自己的 token refresh 逻辑。 Home Assistant 附带了 Home Assistant Cloud Account Linking 服务,这是一个免费的云服务,允许用户通过 OAuth2 快速连接账户。Home Assistant 内置了易于使用的工具,允许用户配置基于 OAuth2 的 integrations。更多信息,请[点击此处](/developers/core/integration/config_flow.md#configuration-via-oauth2)。如果你的库按照下面的示例方式实现,这些内置工具将发挥最佳效果。 ### 异步示例 ```python from abc import ABC, abstractmethod class AbstractAuth(ABC): """Abstract class to make authenticated requests.""" def __init__(self, websession: ClientSession, host: str): """Initialize the auth.""" self.websession = websession self.host = host @abstractmethod async def async_get_access_token(self) -> str: """Return a valid access token.""" async def request(self, method, url, **kwargs) -> ClientResponse: """Make a request.""" if headers := kwargs.pop("headers", {}): headers = dict(headers) access_token = await self.async_get_access_token() headers["authorization"] = f"Bearer {access_token}" return await self.websession.request( method, f"{self.host}/{url}", **kwargs, headers=headers, ) ``` 现在,使用你的库的开发者必须实现获取 access token 的 abstract method。假设开发者拥有自己的 token manager 类。 ```python from my_package import AbstractAuth class Auth(AbstractAuth): def __init__(self, websession: ClientSession, host: str, token_manager): """Initialize the auth.""" super().__init__(websession, host) self.token_manager = token_manager async def async_get_access_token(self) -> str: """Return a valid access token.""" if self.token_manager.is_token_valid(): return self.token_manager.access_token await self.token_manager.fetch_access_token() await self.token_manager.save_access_token() return self.token_manager.access_token ``` ### 同步示例 如果你使用 `requests`,我们建议使用 `requests_oauthlib` 包。下面是一个示例,它可以使用本地的 client ID 和 secret,同时也允许将 token 获取工作委托给 Home Assistant。 ```python from typing import Optional, Union, Callable, Dict from requests import Response from requests_oauthlib import OAuth2Session from oauthlib.oauth2 import TokenExpiredError class Auth: def __init__( self, host: str, token: Optional[Dict[str, str]] = None, client_id: str = None, client_secret: str = None, token_updater: Optional[Callable[[str], None]] = None, ): self.host = host self.client_id = client_id self.client_secret = client_secret self.token_updater = token_updater extra = {"client_id": self.client_id, "client_secret": self.client_secret} self._oauth = OAuth2Session( auto_refresh_kwargs=extra, client_id=client_id, token=token, token_updater=token_updater, ) def refresh_tokens(self) -> Dict[str, Union[str, int]]: """Refresh and return new tokens.""" token = self._oauth.refresh_token(f"{self.host}/auth/token") if self.token_updater is not None: self.token_updater(token) return token def request(self, method: str, path: str, **kwargs) -> Response: """Make a request. We don't use the built-in token refresh mechanism of OAuth2 session because we want to allow overriding the token refresh logic. """ url = f"{self.host}/{path}" try: return getattr(self._oauth, method)(url, **kwargs) except TokenExpiredError: self._oauth.token = self.refresh_tokens() return getattr(self._oauth, method)(url, **kwargs) ``` 现在开发者可以覆盖 refresh token 函数,将其路由到自己的外部服务。 ```python from my_package import AbstractAuth class Auth(AbstractAuth): def refresh_tokens(self) -> Dict[str, Union[str, int]]: """Refresh and return new tokens.""" self.token_manager.fetch_access_token() self.token_manager.save_access_token() return self.token_manager.access_token ``` --- url: /developers/api_lib_data_models.md --- 既然认证已经就绪,我们就可以开始发起经过认证的请求并获取数据了! 在建模数据时,重要的是我们要以 API 所提供的相同结构来暴露数据。某些 API 设计可能不太合理,或者包含拼写错误。我们仍然需要在对象中如实表示它们。这使得使用你的库的开发者可以轻松参考 API 文档,并了解它在你的库中如何工作。 API 库应尽量做到最少。因此,将数据结构表示为类是可以的,但你不应该将一个值转换为另一个值。例如,你不应该实现 Celsius 和 Fahrenheit 温度之间的转换。这涉及到对结果精度的决策,因此应该交由使用库的开发者来处理。 在这个示例中,我们将为名为 ExampleHub 的 Rest API 构建一个 async 库,它有两个 endpoints: * get `/light/`:查询单个 light 的信息。 ```json { "id": 1234, "name": "Example Light", "is_on": true } ``` * post `/light/`:控制 light。发送的示例 JSON:`{ "is_on": false }`。返回 light 的新状态。 * get `/lights`:返回所有 lights 的列表 ```json [ { "id": 1234, "name": "Example Light", "is_on": true }, { "id": 5678, "name": "Example Light 2", "is_on": false } ] ``` 由于此 API 表示 lights,我们首先要创建一个类来表示 light。 ```python from .auth import Auth class Light: """Class that represents a Light object in the ExampleHub API.""" def __init__(self, raw_data: dict, auth: Auth): """Initialize a light object.""" self.raw_data = raw_data self.auth = auth # Note: each property name maps the name in the returned data @property def id(self) -> int: """Return the ID of the light.""" return self.raw_data["id"] @property def name(self) -> str: """Return the name of the light.""" return self.raw_data["name"] @property def is_on(self) -> bool: """Return if the light is on.""" return self.raw_data["id"] async def async_control(self, is_on: bool): """Control the light.""" resp = await self.auth.request( "post", f"light/{self.id}", json={"is_on": is_on} ) resp.raise_for_status() self.raw_data = await resp.json() async def async_update(self): """Update the light data.""" resp = await self.auth.request("get", f"light/{self.id}") resp.raise_for_status() self.raw_data = await resp.json() ``` 现在我们有了 light 类,可以建模 API 的根部分,它提供了数据的入口点。 ```python from typing import List from .auth import Auth from .light import Light class ExampleHubAPI: """Class to communicate with the ExampleHub API.""" def __init__(self, auth: Auth): """Initialize the API and store the auth so we can make requests.""" self.auth = auth async def async_get_lights(self) -> List[Light]: """Return the lights.""" resp = await self.auth.request("get", "lights") resp.raise_for_status() return [Light(light_data, self.auth) for light_data in await resp.json()] async def async_get_light(self, light_id) -> Light: """Return the lights.""" resp = await self.auth.request("get", f"light/{light_id}") resp.raise_for_status() return Light(await resp.json(), self.auth) ``` 有了这两个文件,我们现在可以这样控制 lights: ```python import asyncio import aiohttp from my_package import Auth, ExampleHubAPI async def main(): async with aiohttp.ClientSession() as session: auth = Auth(session, "http://example.com/api", "secret_access_token") api = ExampleHubAPI(auth) lights = await api.async_get_lights() # Print light states for light in lights: print(f"The light {light.name} is {light.is_on}") # Control a light. light = lights[0] await light.async_control(not light.is_on) asyncio.run(main()) ``` --- url: /developers/api_lib_index.md --- Home Assistant 的基础规则之一是,我们不包含任何特定协议的代码。相反,这类代码应该放入一个独立的 Python 库并发布到 PyPI。本指南将介绍如何开始! ## Basic library requirements * 库必须提供 source distribution packages,不允许依赖仅具有 binary distribution packages 的包。 * 发布在 PyPi 上的库版本应与公开在线仓库中标记的 releases 相对应。 * PyPi 上的发布必须是自动化的。 * 与外部设备或服务通信的外部 Python 库必须启用 issue trackers。 * 如果库主要用于 Home Assistant,并且你是该 integration 的 code owner,建议使用带有指向 [Home Assistant Core Issues](https://github.com/home-assistant/core/issues) 链接的 issue template picker。例如:[zwave-js-server-python - New Issue](https://github.com/home-assistant-libs/zwave-js-server-python/issues/new/choose) * 库及其可能的子依赖必须使用 [OSI-approved license](https://opensource.org/license) 许可。这应在库的 metadata 中反映出来。 在本指南中,我们将假设我们正在为可通过 HTTP 访问并返回 JSON 对象结构化数据的 Rest API 构建库。这是我们最常见的 API 类型。这些 API 可以在设备本身访问,也可以在云端访问。 本指南并不完美适用于所有 API。你可能需要对示例进行调整。 :::info 如果你是正在为产品设计新 API 的制造商,[请阅读此处关于为产品添加最佳 API 类型的建议](https://www.home-assistant.io/blog/2016/02/12/classifying-the-internet-of-things/#local-device-pushing-new-state)。 ::: HTTP API 请求由四个不同的部分组成: * URL。这是我们要从中获取数据的路径。对于 Rest API,URL 将唯一标识资源。URL 的示例有 `http://example.com/api/lights` 和 `http://example.com/api/light/1234`。 * HTTP method。它定义了我们希望从 API 获得什么。最常见的有: * `GET` 用于获取信息,例如 light 的状态 * `POST` 用于执行操作(例如打开 light) * Body。这是我们要发送到服务器的数据,用于标识需要执行的操作。对于 `POST` 请求,这就是我们发送命令的方式。 * Headers。它包含描述请求的 metadata。它将用于将 authorization 附加到请求中。 ## 构建库的结构 我们的库将包含两个不同的部分: * **Authentication:** 负责向 API endpoint 发起经过认证的 HTTP 请求并返回结果。这是唯一实际与 API 交互的代码部分。 * **Data models:** 表示数据并提供与数据交互的命令。 ## 在 Home Assistant 中试用你的库 如果你想将库发布到 PyPI 之前在 Home Assistant 中试用它,需要运行可编辑版本的库。 进入你的 Home Assistant 开发环境,激活虚拟环境并输入: ```shell pip3 install -e ../my_lib_folder ``` 现在运行 Home Assistant 时跳过从 PyPI 安装依赖,以避免覆盖你的包。 ```shell hass --skip-pip-packages my_lib_module_name ``` --- url: /developers/apple/architecture.md --- Home Assistant iOS 是一个多目标 Apple 平台项目。它最初是一个围绕 web 体验的 companion app,现已发展为一个混合代码库,具备原生 onboarding、传感器、widgets、Apple Watch 支持、CarPlay、App Intents 以及由通知驱动的功能。 该仓库将特定应用的代码、共享平台代码、extension 和一个小的 Swift server 组件组合在单个 workspace 中。 ## 核心原则 ### 多目标设计 该仓库的组织方式尽可能在各目标间共享逻辑,同时允许在需要时使用平台特定实现。数据库访问、网络、设计系统组件、通知、widgets 和共享模型等跨领域关注点都放在 common 模块中,以便多个目标可以复用它们。请参阅[目标指南](/developers/apple/targets.md),了解每个 surface 的概述。 ### 混合 UI 栈 该项目同时使用 **SwiftUI** 和 **UIKit**。更新的工作流和组件越来越多地使用 SwiftUI,而遗留和平台特定的集成仍直接依赖 UIKit 和其他 Apple 框架。 ## 仓库结构 ### `Sources/App` 这里包含 iOS 应用特定的功能,例如 onboarding、设置、场景、摄像头、通知、web/frontend 集成、kiosk 功能和工具。 ### `Sources/Shared` 这是共享代码库的核心。它包括: * API 和网络支持 * 围绕 GRDB 构建的数据库代码 * 共享模型和 domain 逻辑 * 设计系统工具 * Widget 和通知支持 * 位置、Assist 和服务集成 ### `Sources/Extensions` 该区域包含 extension 和系统集成的代码,包括: * Widgets * App Intents * Share extension * 通知服务和内容 extension * Matter 支持 * Push provider 支持 ### 其他重要目录 * `Sources/CarPlay`: CarPlay 模板和功能逻辑 * `Sources/Watch` 和 `Sources/WatchApp`: Apple Watch 通信和 watch app 代码 * `Sources/Thread`: Thread 凭据管理和共享流程 * `Sources/MacBridge`: Mac 构建使用的 macOS 特定 bridge 代码 * `Sources/PushServer` 和 `Sources/SharedPush`: 基于 Swift 包的 server 和共享 push 逻辑 * `Tests`: 应用、共享、UI 和 widget 测试 * `fastlane`: Linting、测试、版本控制和构建自动化 ## 关键技术 当前代码库大量使用: * [**Swift**](https://www.swift.org/) * **Xcode workspace 和 scheme** * [**CocoaPods**](https://cocoapods.org/) * [**Fastlane**](https://fastlane.tools/) * 用于 frontend 集成的 [**WKWebView**](https://developer.apple.com/documentation/webkit/wkwebview) * [**SwiftUI**](https://developer.apple.com/xcode/swiftui/) 和 [**UIKit**](https://developer.apple.com/documentation/uikit) * [**App Intents**](https://developer.apple.com/documentation/appintents) 和 [**WidgetKit**](https://developer.apple.com/documentation/widgetkit) ## 值得注意的第三方依赖 除了 Apple 框架之外,应用还依赖几个开源库。完整列表位于 [`Podfile`](https://github.com/home-assistant/iOS/blob/main/Podfile) 中,但以下是被频繁触碰的: * [**HAKit**](https://github.com/home-assistant/HAKit) — Home Assistant API client(WebSocket 和 REST) * [**GRDB.swift**](https://github.com/groue/GRDB.swift) — SQLite 数据库访问 * [**Alamofire**](https://github.com/Alamofire/Alamofire) — HTTP 网络 * [**PromiseKit**](https://github.com/mxcl/PromiseKit) — 基于 promise 的异步流程 * [**Starscream**](https://github.com/daltoniam/Starscream) — HAKit 使用的 WebSocket 传输层(我们跟踪一个带有特定修复的 fork) * [**SFSafeSymbols**](https://github.com/SFSafeSymbols/SFSafeSymbols) — 类型安全地访问 SF Symbols * [**KeychainAccess**](https://github.com/kishikawakatsumi/KeychainAccess) — keychain 存储辅助 * [**Eureka**](https://github.com/xmartlabs/Eureka) — 遗留 screen 中的表单式 UI * [**ObjectMapper**](https://github.com/tristanhimmelman/ObjectMapper) — 遗留模型中的 JSON 映射 * [**XCGLogger**](https://github.com/DaveWoodCom/XCGLogger) — 日志记录 * [**Improv-iOS**](https://github.com/home-assistant/Improv-iOS) — Improv Bluetooth onboarding ## 实践中应用的架构模式 ### 共享环境访问 项目在许多地方使用共享的 `Current` 环境模式(参见 [How to control the world](https://www.pointfree.co/blog/posts/21-how-to-control-the-world))来访问依赖和服务。实际上,这意味着单个 `Current` 值将应用所需的依赖分组在一起,这使得它们很容易从任何地方读取,也很容易在测试中替换。代码库对此处理得很谨慎,以至于 SwiftLint 有一条自定义规则来防止随意的重新赋值。 ### Extension 是一等公民 我们鼓励你从一开始就把 widgets、通知、CarPlay、watchOS 支持和 App Intents 考虑在内。应用需要良好地在所有这些 surface 上工作,同时保持代码质量,因此变更往往需要考虑 extension-safe 代码、共享存储和跨目标复用。 ### App 加平台 surface 一个功能可能会触及主应用之外的部分。例如,一个实体操作可能会出现在应用 UI、widgets、Apple Watch、App Intents 或 CarPlay 中。在开始编码之前,值得检查一下变更是否应该放在 `Sources/App`、`Sources/Shared` 或某个 extension 目标中。 ## 如何浏览代码库 下图显示了顶部的实际 Xcode 发布产品,以及为每个产品提供输入的 `Sources/*` 目录。可以双向阅读: * **从产品开始**(例如,Apple Watch 应用):沿着箭头向外看,可以看到包含在其中的每个 source 目录。 * **从 source 目录开始**(例如,`Shared`):沿着入箭头看,可以看到消费它的每个产品。 有一些组件位于主 workspace 之外: * [`Sources/PushServer`](https://github.com/home-assistant/iOS/tree/main/Sources/PushServer) 是一个独立的 Swift 包,用于 server 侧的 push relay。 * [`Sources/SharedTesting`](https://github.com/home-assistant/iOS/tree/main/Sources/SharedTesting) 是一个仅用于测试的 framework,由测试目标使用。 如果你是仓库的新手,一个很好的定位方法是: 1. 从 `Sources/App` 开始,了解主 iPhone 和 iPad 应用的组织方式。大多数功能都源自这里。 2. 将多个目标需要的逻辑放在 `Sources/Shared` 中,以便 extension、watch 和 CarPlay 可以复用。 3. 对于特定目标的功能(例如仅 watch 或仅 widget 的变更),在 `Sources/Extensions`、`Sources/CarPlay` 或 `Sources/Watch` 中查找匹配的 surface。 4. 在添加新代码之前,在 `Tests/App` 和 `Tests/Shared` 中查看示例。 --- url: /developers/apple/ci.md --- Home Assistant iOS 仓库使用 **GitHub Actions** 配合 **Fastlane** 进行 linting、测试、构建、本地化更新和分发。 ## 主 CI 工作流 CI 在 pull request 和推送到 `main` 时运行。 ## Linting 任务 每次 pull request,CI 运行 [编码风格指南](/developers/apple/codestyle.md) 中描述的相同 linter: * 使用 SwiftFormat 检查 Swift 格式 * 使用 SwiftLint lint Swift 代码,包括仓库的自定义规则 * 使用 RuboCop lint Ruby(Fastlane)代码 * Lint YAML 文件(工作流和配置) 这些在容器中的 Linux 上运行,这保持了风格检查的快速,并独立于 macOS 构建环境。 ## Pull request 安全检查 仓库有额外的仅针对 pull request 的检查: ### SwiftLint disable 检测 如果 PR 添加了新的 `// swiftlint:disable` 行,CI 会在 pull request 上评论,以便维护者审查该抑制是否必要。 ### 未使用本地化检测 CI 运行 `Tools/detect_unused_strings.py`,并在发现未使用的本地化字符串时在 pull request 上评论。 ## 测试 job `test` job 在 macOS 上运行,并使用: * 当前 CI Xcode 版本 * 用于 Ruby 依赖的 Bundler * 用于 Apple 平台依赖的 CocoaPods * `bundle exec fastlane test` 默认的 Fastlane test lane 在 CI 配置的模拟器上运行 `HomeAssistant.xcworkspace` 中的 `Tests-Unit` scheme。有关确切的 Xcode 和模拟器版本,请参阅 [`ci.yml`](https://github.com/home-assistant/iOS/blob/main/.github/workflows/ci.yml)。 CI 还会上传: * 来自 `Tests-Unit.xcresult` bundle 的代码覆盖率 * 测试日志和崩溃诊断 * 用于快速验证和仅 frontend 测试的模拟器 `.app` artifact ## 分发工作流 `distribute.yml` 工作流在推送到 `main` 时运行,也可以由拥有仓库写权限的维护者手动触发。它构建: * iOS App Store artifact * macOS artifact,包括 Developer ID 和 App Store 打包 这些构建使用 Fastlane lane 进行签名、归档、导出、公证和上传到 Apple 服务。 ## 其他工作流 ### 本地化更新 `download_localized_strings.yml` 按计划运行,也可以由拥有仓库写权限的维护者手动触发。它与 Lokalise 同步本地化字符串,并在有更新时打开 pull request。 ### Push server 测试 `push_ci.yml` 对 `Sources/PushServer/**` 下的更改运行 `swift test`。 ### 版本递增 `set_version.yml` 通过 Fastlane 更新 `Configuration/Version.xcconfig`,并打开一个包含版本变更的 pull request。 ## 这对你意味着什么 CI 验证的不仅仅是编译:风格、字符串和 artifact 也是审查循环的一部分。有关 linting,请参阅[编码风格指南](/developers/apple/codestyle.md);有关在推送之前在本地运行测试,请参阅[入门指南](/developers/apple/get_started.md)。 --- url: /developers/apple/codestyle.md --- ## 为什么强制代码风格很重要 一致的格式化和 linting 可以减少 review 噪音,使维护者更容易关注行为、架构和边界情况,而不是风格问题。 ## 仓库中使用的工具 iOS 项目使用几种自动化检查: * **SwiftFormat** 用于 Swift 格式化 * **SwiftLint** 用于 Swift linting 和项目特定规则 * **RuboCop** 用于 Fastlane 和 Ruby 代码 * **Yamllint** 用于 workflow 和其他 YAML 文件 这些检查在 [pull request](/developers/apple/ci.md) 中运行,你应该在打开或更新 PR 之前在本地运行它们。 ## 在本地运行检查 运行所有默认 linting 检查: ```bash bundle exec fastlane lint ``` 应用支持的自动修复: ```bash bundle exec fastlane autocorrect ``` ## 仓库特定的 linting 细节 ### SwiftFormat SwiftFormat 通过 `.swiftformat` 进行配置。仓库目前目标为 Swift 5.8 格式化规则,并排除生成的或外部内容,如 `Pods`、`vendor`、resources 和 `fastlane`。 ### SwiftLint SwiftLint 通过 `.swiftlint.yml` 进行配置,并使用有效规则的 allowlist,而不是启用所有默认规则。 配置还包括自定义规则,例如: * 防止在批准的位置之外直接赋值给 `Current.*` * 优先使用 `SFSafeSymbols` 辅助方法而非原始系统 symbol 字符串 ### `swiftlint:disable` 请谨慎使用 `swiftlint:disable`。CI 包含一个 pull request 检查,当添加新的 disable 指令时会发出评论,因此每次抑制都应该是有意且合理的。 ## 一般指导 * 优先使用小型、命名良好的类型和函数。 * 将共享代码放在共享模块中,而不是在各个 target 之间重复逻辑。 * 避免将 target 特定的假设引入 extension-safe 或共享代码中。 * 使更改易于隔离测试。 ## Dependencies 和生成的代码 * 不要编辑 `Pods` 下的文件。此目录由仓库根目录中的 `Podfile` 生成,并通过 `bundle exec pod install` 刷新。 * 注意生成的或与 localization 相关的文件;有些由脚本和 workflow 维护。生成的文件通常会在文件顶部的注释中说明(例如,`// This file is auto-generated`),localization 文件与 `.strings` 和 `.xcstrings` 资源共存。 * 更改 Ruby 或 workflow 自动化时,确保相关的 lint 检查仍然通过。 --- url: /developers/apple/get_started.md --- 本指南将带你走完克隆仓库、安装依赖、配置本地签名和运行应用的最快路径。 ## 要求 你需要: * [Xcode 26.2 或更高版本](https://developer.apple.com/xcode/) * 通过 [Homebrew](https://formulae.brew.sh/formula/ruby)、[`rbenv`](https://github.com/rbenv/rbenv) 或 [`mise`](https://mise.jdx.dev/) 安装的 Ruby 3.1(有关示例,请参见下方的[安装依赖](#install-dependencies)) Ruby 为 **Bundler**(用于 Ruby 工具链)和 **[CocoaPods](https://cocoapods.org/)**(用于 Apple 平台依赖)提供动力,这两者都是作为依赖安装步骤的一部分进行安装的。 ## Fork、clone 并创建分支 ### Fork 仓库 1. 打开 [Home Assistant iOS 仓库](https://github.com/home-assistant/iOS)。 2. 点击 **Fork** 创建你自己的副本。 ### Clone 你的 fork ```bash git clone https://github.com//iOS.git cd iOS ``` ### 创建分支 在进行更改之前创建分支: ```bash git checkout -b feature/my-change ``` ## 安装依赖 选择一个适合你的 Ruby 设置,然后安装 gems 和 pods。 ### 使用 Homebrew Ruby 的示例 ```bash brew install ruby@3.1 cocoapods $(brew --prefix)/opt/ruby@3.1/bin/bundle install $(brew --prefix)/opt/ruby@3.1/bin/bundle exec pod install --repo-update ``` ### 使用 `mise` 的示例 ```bash brew install mise mise install bundle install bundle exec pod install --repo-update ``` 如果你已经有一个可用的 Ruby 环境,`bundle install` 后跟 `bundle exec pod install --repo-update` 就足够了。 ## 配置本地代码签名 Debug 构建使用自动配置,但由于应用使用了多个 entitlement,你仍然需要本地覆盖。 创建 `Configuration/HomeAssistant.overrides.xcconfig` 并添加: ```text DEVELOPMENT_TEAM = YourTeamID BUNDLE_ID_PREFIX = some.bundle.prefix ``` * `DEVELOPMENT_TEAM` 是你的 Apple 开发者团队标识符。 * `BUNDLE_ID_PREFIX` 应该是你控制的 prefix,以便 Xcode 可以创建本地 provisioning profile。 该文件被 Git 忽略,应保持在本地。 ## 打开并运行应用 依赖安装完成后: 1. 在 Xcode 中,打开 **HomeAssistant.xcworkspace**。 2. 在 scheme 选择器中,选择 **App-Debug**。 3. 在 destination 选择器中,选择一个 iOS 模拟器或开发设备。 4. 在 Xcode 中构建并运行。 **App-Debug** 是本地开发的常规入口点。 ## 有用的本地命令 运行仓库质量检查: ```bash bundle exec fastlane lint ``` 对支持的问题运行自动修正: ```bash bundle exec fastlane autocorrect ``` 运行默认的自动化测试套件: ```bash bundle exec fastlane test ``` ## 测试 Home Assistant frontend 更改 如果你正在 [Home Assistant frontend](https://github.com/home-assistant/frontend)(在应用的 WebView 内渲染的 web UI)上工作,并且只需要验证这些更改,你可以跳过自己构建应用: 1. 下载 CI 在最近一次 `main` 构建中生成的模拟器应用 artifact。 2. 将其安装到 iOS 模拟器中。 3. 使用 Safari Web Inspector 调试嵌入的 WebView。 ## 下一步是什么? * 阅读[架构指南](/developers/apple/architecture.md)了解代码库布局。 * 浏览[目标概述](/developers/apple/targets.md)查看每个 surface(iPhone、Watch、CarPlay、widgets 等)。 * 在打开 pull request 之前,审阅[编码风格指南](/developers/apple/codestyle.md)。 * 在[持续集成指南](/developers/apple/ci.md)中了解 CI 如何工作。 * [加入我们的 Discord 社区](https://www.home-assistant.io/join-chat),确保选择开发者角色,并前往 **[iOS](https://discord.com/channels/330944238910963714/1481713628553019392)** 项目线程,与其他贡献者联系。 --- url: /developers/apple/index.md --- **Home Assistant Apple 平台 apps** 帮助用户在 Apple 平台上控制并自动化他们的家庭。该项目是开源的、积极维护的,涵盖了主要的 iPhone 和 iPad 应用、Apple Watch、widgets、CarPlay、app extensions 以及支撑服务。 **[查看 GitHub 仓库](https://github.com/home-assistant/iOS)** 以了解当前的代码库和待办工作。 *** ## 为什么要贡献? * **产生影响**:改进将落地到一个被 Home Assistant 用户每天使用的应用中。 * **跨 Apple 平台工作**:在一个仓库中为 iOS、watchOS、widgets、CarPlay、App Intents 和 macOS 打包做出贡献。 * **在实战中学习**:该项目使用包含 Xcode、CocoaPods、Fastlane、GitHub Actions 和自动化测试的真实生产工作流。 * **帮助社区**:更好的文档、更好的 review、更好的 bug 修复都很重要。 *** ## 你如何提供帮助 * **代码贡献**:修复 bug、添加功能,或改进平台集成。 * **测试**:在本地验证更改,并帮助捕获各 target 之间的回归。 * **代码 review**:Review pull requests,帮助保持变更小而可维护。 * **文档**:在行为发生变更时,改进贡献者文档和用户可见的配套文档。 * **翻译**:加入[iOS 翻译团队](https://app.lokalise.com/public/834452985a05254348aee2.46389241/)。 *** ## 准备好开始了吗? 1. **[查看入门指南](/developers/apple/get_started.md)** 了解本地设置、签名覆盖以及你的第一次构建。 2. **[阅读架构指南](/developers/apple/architecture.md)** 以了解仓库的组织方式。 3. **[加入我们的 Discord 社区](https://www.home-assistant.io/join-chat)**,确保选择开发者角色,然后前往 **[iOS](https://discord.com/channels/330944238910963714/1481713628553019392)** 项目线程,与其他贡献者交流。 --- url: /developers/apple/submit.md --- 感谢你的贡献。一旦你的更改准备就绪,请向 [home-assistant/iOS](https://github.com/home-assistant/iOS) 的 `main` 分支打开一个 pull request。 ## 提交 PR 的清单 在请求 review 之前,请确保你已经完成了基本工作: * **Description**:解释更改了什么以及为什么。 * **Tests**:当行为变更时添加或更新测试。 * **Linting**:运行 `bundle exec fastlane lint`。 * **Buildability**:确保相关的 scheme 仍能在本地构建。 * **UI changes**:界面变更时附上截图或录屏。 * **Documentation**:当更改影响贡献者工作流或用户可见的行为时,更新开发者文档或用户文档。 * **Cross-target impact**:检查你的更改是否也影响 widgets、watchOS、CarPlay、app extensions 或 macOS packaging。请参见每个表面的 [targets overview](/developers/apple/targets.md)。 ## 保持 pull request 小而精 较小的 pull request 更容易 review,也更易于理解。如果更改超过一个思路,请尽可能将其拆分为后续的 PR。 ## 打开 draft PR Draft pull requests 是在一切就绪之前获得关于方向、架构或 CI 密集型更改的早期反馈的好方法。 ## Review 期望 维护者和 reviewer 通常关注: * correctness * 各 target 间的回归 * test coverage * maintainability * 共享代码是否属于正确的模块 CI 是 review 过程的一部分,而不是替代品。 ## 更新你的分支 你不需要在每次 push 到 `main` 时都 rebase。在有必要的原因时更新你的分支——例如,与 `main` 存在冲突、由最近更改引起的 CI 失败,或 `main` 上的修复影响了你的工作。如果你的分支尚未 review,rebase 通常是可行的。开始 review 后,请优先选择对 PR 上已有的讨论最不打扰的更新策略。 ## Localization 和生成的文件 * Translations 通过 [Lokalise](https://app.lokalise.com/public/834452985a05254348aee2.46389241/) 管理 * 如果你触及 localized strings 或生成的输出,请确保相关的 workflow 和生成的文件保持一致。 * 如果 CI 报告未使用的 strings,请在请求重新 review 之前清理它们。 ## 收到反馈后 * 用有针对性的后续提交处理评论。 * 当反馈影响行为时,重新运行本地 lint 和测试。 * 分支变绿后,请求再次 review。 --- url: /developers/apple/targets.md --- ## Apple 平台目标 Home Assistant iOS 仓库是一个 multi-target workspace。单个更改可能影响的范围不止主 app,因此了解项目中的主要 surface 很有帮助。 ## 主应用 主 application target 是 iPhone 和 iPad app。对于本地开发,通常的入口点是 `App-Debug` scheme。仓库还包含面向发布的 `App-Beta` 和 `App-Release` scheme。 ## Widgets 和 App Intents 项目在 `Sources/Extensions/Widgets` 和 `Sources/Extensions/AppIntents` 下包含 widget 和 App Intent targets。 这些 target 为 Home Screen widgets、交互式控件以及在主 app 之外展示 Home Assistant actions 的系统集成提供动力。 ## Apple Watch Watch 相关代码位于 `Sources/Watch`、`Sources/WatchApp` 以及 `Sources/Extensions/Watch` 下的 watch 相关 extension 代码中。 涉及 actions、notifications、complications 或共享配置的更改通常需要 watch 特定的验证。 ## CarPlay CarPlay 功能位于 `Sources/CarPlay` 下。这包括模板、列表项、过滤以及受支持实体的 action 执行行为。 ## 通知扩展 仓库包含用于丰富 push 处理的专用 notification targets: * Notification service extension * Notification content extension * Push provider support 在处理 notifications、attachments 或 command handling 时,这些 target 很重要。 ## Share 和其他 extensions 项目还包含其他 extensions,如: * Share extension * Matter extension 如果你的功能与传入内容、home platform setup 或 extension-safe 共享代码交互,也请检查这些 target。 ## macOS support 仓库还在 CI 中构建 macOS 工件。`Sources/MacBridge` 包含这些构建使用的 macOS 特定 bridge 代码。 即使你在处理 iOS 功能,共享代码也可能同时编译到 Mac 构建中。 ## 支持包 仓库包含支持 app 生态系统的独立 Swift packages: * `Sources/PushServer` * `Sources/SharedPush` 当它们的代码发生变更时,会在主 Xcode workspace 之外单独测试。 --- url: /developers/apple/testing.md --- ## 为什么测试很重要 Home Assistant iOS 应用涵盖多个 target 和平台。测试有助于在贡献者更改共享逻辑、onboarding、widgets、notifications、watch 功能和与 Home Assistant 的集成时,确保行为的稳定性。 ## 默认测试命令 在本地环境中运行默认测试,执行: ```bash bundle exec fastlane test ``` 这将在本地 Fastlane test lane 配置的模拟器上运行 `HomeAssistant.xcworkspace` 中的 `Tests-Unit` scheme。 ## 测试布局 仓库包含多个测试区域: * `Tests/App`:应用特定行为 * `Tests/Shared`:共享逻辑、模型、数据库、传感器、通知和工具 * `Tests/UI`:UI 自动化测试 * `Tests/Widgets`:widget 相关的快照式测试 ## 仓库中的测试类型 ### 单元测试和功能测试 大多数贡献者更改应附带在 `Tests/App` 或 `Tests/Shared` 中的针对性测试。这些测试由默认 CI test lane 运行。 ### UI 测试 UI 测试位于 `Tests/UI` 下。当行为最好通过用户交互验证而非隔离逻辑验证时,使用它们。 ### 快照和 widget 测试 仓库包含 widget 和快照测试,包括存储在 `Tests/Widgets/__Snapshots__` 下的快照。如果你有意更改 widget 或视觉输出,请仔细检查快照更新。 ### Push server 测试 `Sources/PushServer` 下的更改还应使用以下命令验证: ```bash cd Sources/PushServer swift test ``` ## 良好的测试习惯 * 保持测试聚焦于单一行为 * 优先使用确定性测试而非依赖时序的测试 * 在可能出现回归的地方添加覆盖率,尤其是在共享代码中 * 更改跨 target 行为时,不要只考虑主应用,尽量在接近共享逻辑的地方添加测试 ## 从 Xcode 运行测试 在 Xcode 中,从 **HomeAssistant.xcworkspace** 运行相关测试 scheme: * **Tests-Unit**:主要自动化测试套件 * **Tests-UI**:UI 自动化覆盖率 使用与 CI 相同的 workspace 和 scheme,可减少后续意外。 --- url: /developers/apps.md --- Home Assistant 的 app(以前称为 add-ons)允许用户扩展 Home Assistant 周边的功能。这可以是运行 Home Assistant 可以集成的应用程序(如 MQTT broker),或者通过 Samba 共享配置以便于从其他计算机编辑。app 可以通过 Home Assistant 中的 Supervisor 面板进行配置。 在底层,app 是发布到容器 registry(如 [GitHub container registry](https://github.com/features/packages) 和 [Docker Hub](https://hub.docker.com/))的容器镜像。开发者可以创建 [GitHub](https://github.com) 仓库,其中包含多个 app,以便于与社区分享。 * [教程:制作你的第一个 app](/developers/apps/tutorial.md) * [配置](/developers/apps/configuration.md) * [通信](/developers/apps/communication.md) * [本地测试](/developers/apps/testing.md) * [发布](/developers/apps/publishing.md) * [展示](/developers/apps/presentation.md) * [仓库](/developers/apps/repository.md) * [安全](/developers/apps/security.md) 有用链接: * [示例 app 仓库](https://github.com/home-assistant/addons-example) * [Home Assistant Supervisor](https://github.com/home-assistant/supervisor) * [Home Assistant Core app](https://github.com/home-assistant/addons) * [Home Assistant Docker 基础镜像](https://github.com/home-assistant/docker-base) * [Home Assistant Builder actions](https://github.com/home-assistant/builder) * [Home Assistant 社区 app](https://github.com/hassio-addons) * [Home Assistant 操作系统](https://github.com/home-assistant/operating-system) * [Home Assistant Docker 镜像](https://github.com/home-assistant/docker) --- url: /developers/apps/communication.md --- 在 Home Assistant 中,app(以前称为 add-on)之间有多种不同的通信方式。 ## 网络 我们使用一个内部网络,该网络允许通过名称或别名与每个 app(包括与 Home Assistant 之间)进行通信。仅在主机网络上运行的 app 受到的限制是,它们可以通过名称与所有内部 app 通信,但所有其他 app 无法通过名称寻址这些 app。然而,使用别名对两者都有效! 名称/别名用于 Home Assistant 内部的通信。 名称的生成格式为:`{REPO}_{SLUG}`,例如 `local_xy` 或 `3283fh_myaddon`。在这个示例中,`{SLUG}` 定义在 app 的 `config.yaml` 文件中。你也可以将此名称用作 DNS 名称,但你需要将任何 `_` 替换为 `-` 才能成为有效的 hostname。如果 app 在本地安装,`{REPO}` 将是 `local`。如果 app 从 GitHub 仓库安装,`{REPO}` 是从 GitHub 仓库 URL 生成的哈希标识符(例如:`https://github.com/xy/my_hassio_addons`)。请参见[此处](https://github.com/home-assistant/supervisor/blob/4ac7f7dcf08abb6ae5a018536e57d078ace046c8/supervisor/store/utils.py#L17)了解此标识符的生成方式。请注意,在使用 [Supervisor app API][supervisor-addon-api] 的某些操作中需要此标识符。你可以通过向 Supervisor API `addons` endpoint 发送 GET 请求来查看所有当前已安装 app 的仓库标识符。 使用 `supervisor` 与内部 API 通信。 ## Home Assistant 核心 app(以前称为 add-on)可以通过内部代理与 [Home Assistant Core API][core-api] 通信。这样你无需知道密码、端口或关于 Home Assistant 实例的任何其他信息,就能轻松地与 API 通信。使用此 URL:`http://supervisor/core/api/` 可以确保内部通信被重定向到正确的地方。下一步是在 `config.yaml` 文件中添加 `homeassistant_api: true` 并读取环境变量 `SUPERVISOR_TOKEN`。在发起请求时将其作为 Home Assistant Core [bearer token](/developers/auth_api.md#making-authenticated-requests) 使用。 例如 `curl -X GET -H "Authorization: Bearer ${SUPERVISOR_TOKEN}" -H "Content-Type: application/json" http://supervisor/core/api/config` 还有一个用于 [Home Assistant Websocket API][core-websocket] 的代理,它的工作原理与上面的 API 代理相同,需要 `SUPERVISOR_TOKEN` 作为密码。使用此 URL:`ws://supervisor/core/websocket`。 你也可以在内部网络上直接与名为 `homeassistant` 的 Home Assistant 实例通信。然而,你需要知道正在运行的实例所使用的配置。 我们在 Home Assistant 中有几个 action 可以运行任务。通过 STDIN 向 app 发送数据以使用 `hassio.addon_stdin` action。 ## Supervisor API 要启用对 [Supervisor API][supervisor-api] 的调用,请在 `config.yaml` 文件中添加 `hassio_api: true` 并读取环境变量 `SUPERVISOR_TOKEN`。现在你可以在 URL `http://supervisor/` 上使用 API。使用 `Authorization: Bearer` 头携带 `SUPERVISOR_TOKEN`。你还需要将 Supervisor API 角色更改为 `hassio_role: default`。 app 可以在无需设置 `hassio_api: true` 的情况下调用某些 API 命令: * `/core/api` * `/core/api/stream` * `/core/websocket` * `/addons/self/*` * `/services*` * `/discovery*` * `/info` ***注意:*** 有关 Home Assistant API 访问要求,请参见上文。 ## Services API 我们有一个内部 services API,可以在无需用户添加任何配置的情况下将服务公开给其他 app。app 可以获取服务的全部配置来使用并连接到它。app 需要在 app [配置](/developers/apps/configuration.md) 中标记服务的使用,才能访问服务。所有受支持的服务,包括其可用选项,都记录在 [API 文档][supervisor-services-api] 中。 支持的服务有: * mqtt * mysql 你可以使用 Bashio 在 app 初始化时为 app 获取这些信息:`bashio::services ` 例如: ```bash MQTT_HOST=$(bashio::services mqtt "host") MQTT_USER=$(bashio::services mqtt "username") MQTT_PASSWORD=$(bashio::services mqtt "password") ``` [core-api]: /api/rest.md [core-websocket]: /api/websocket.md [supervisor-api]: /api/supervisor/endpoints.md [supervisor-addon-api]: /api/supervisor/endpoints.md#apps [supervisor-services-api]: /api/supervisor/endpoints.md#service --- url: /developers/apps/configuration.md --- 每个 app(以前称为 add-on)都存储在一个文件夹中。文件结构如下: ```text addon_name/ translations/ en.yaml apparmor.txt CHANGELOG.md config.yaml DOCS.md Dockerfile icon.png logo.png README.md run.sh ``` :::note Translation files 和 `config` 支持 `.json`、`.yml` 和 `.yaml` 作为文件类型。 为简单起见,所有示例都使用 `.yaml`。 ::: ## App 脚本 与每个 Docker 容器一样,你需要一个脚本在容器启动时运行。用户可能会运行许多 app,因此如果你做的是简单的事情,建议使用 Bash 脚本。 我们所有的镜像还安装了 [bashio][bashio]。它包含一组常用操作,可以在 app 中使用以减少 app 之间的代码重复,从而使 app 更容易开发和维护。 在开发你的脚本时: * `/data` 是用于持久化存储的 volume。 * `/data/options.json` 包含用户配置。你可以使用 Bashio 来解析这些数据。 ```shell CONFIG_PATH=/data/options.json TARGET="$(bashio::config 'target')" ``` 因此如果你的 `options` 包含 ```json { "target": "beer" } ``` 那么在 bash 文件的环境中将会有一个包含 `beer` 的变量 `TARGET`。 [bashio]: https://github.com/hassio-addons/bashio ## App Dockerfile 大多数 app(以前称为 add-on)都基于最新的 Alpine Linux 镜像。如果需要运行在不同的时区,请添加 `tzdata`。`tzdata` 已经添加到我们的 base 镜像中。 ```dockerfile FROM ghcr.io/home-assistant/base:latest # Install requirements for app RUN \ apk add --no-cache \ example_alpine_package # Copy data for app COPY run.sh / RUN chmod a+x /run.sh CMD [ "/run.sh" ] ``` :::note 当 Supervisor 构建没有 `build.yaml` 的 app 时,它之前会自动传递 `BUILD_FROM=ghcr.io/home-assistant/base:latest`。自 Supervisor 2026.04.0 起,该 fallback 不再适用,请确保你的 Dockerfile 不依赖于通过默认 `BUILD_FROM` 参数提供的外部 base 镜像。 ::: 如果你没有使用 Home Assistant GitHub builder actions(请参见 [Publishing your app](/developers/apps/publishing.md)),请确保 Dockerfile 也包含一组 labels,其中包括: ```dockerfile LABEL \ io.hass.version="VERSION" \ io.hass.type="app" \ io.hass.arch="aarch64|amd64" ``` ### 构建参数 我们默认支持以下构建参数: | ARG | Description | |-----|-------------| | `BUILD_VERSION` | App 版本(从 `config.yaml` 读取)。 | | `BUILD_ARCH` | 保存当前构建的 arch。 | :::note 自 Supervisor 2026.04.0 起,`BUILD_FROM` 参数默认不再提供。请在你的 Dockerfile 中显式使用 `FROM ghcr.io/home-assistant/base:latest`,以获得与之前相同的构建结果。建议使用固定版本的 base 镜像以获得更好的构建稳定性。 ::: ## App 配置 app(以前称为 add-on)的配置存储在 `config.yaml` 中。 ```yaml name: "Hello world" version: "1.1.0" slug: folder description: >- "Long description" arch: - amd64 url: "website with more information about the app (e.g., a forum thread for support)" ports: 123/tcp: 123 map: - type: share read_only: False - type: ssl - type: homeassistant_config read_only: False path: /custom/config/path image: ghcr.io/my-org/my-app ``` :::note 避免在 app 中使用 `config.yaml` 作为文件名来存放 app 配置以外的任何东西。Supervisor 会在 app 仓库中递归搜索 `config.yaml`。 ::: ### 必填配置选项 | Key | Type | Description | | --- | ---- | ----------- | | `name` | string | app 的名称。 | | `version` | string | app 的版本。如果你使用带有 `image` 选项的 docker 镜像,这必须与将要使用的镜像的 tag 相匹配。 | | `slug` | string | app 的 slug。这必须在 app 发布的 [repository](/developers/apps/repository.md) 范围内是唯一的,并且要 URI friendly。 | | `description` | string | app 的描述。 | | `arch` | list | 支持的架构列表:`aarch64`、`amd64`。 | ### 可选配置选项 | Key | Type | Default | Description | | --- | ---- | -------- | ----------- | | `machine` | list | | 默认支持所有 machine 类型。你可以配置 app 仅在特定机器上运行。你可以在 machine 类型前使用 `!` 来取反。 | | `url` | url | | app 的主页。你可以在这里解释 app 和选项。 | | `startup` | string | `application` | `initialize` 会在 Home Assistant 设置时启动 app。`system` 用于数据库之类的东西,且不依赖于其他东西。`services` 会在 Home Assistant 之前启动,而 `application` 则在之后启动。最后 `once` 适用于不作为 daemon 运行的应用程序。 | | `webui` | string | | app web 界面的 URL。如 `http://[HOST]:[PORT:2839]/dashboard`,端口需要使用内部端口,它将被替换为有效的端口。还可以将协议部分绑定到配置选项:`[PROTO:option_name]://[HOST]:[PORT:2839]/dashboard`,并在其为 `true` 且指向 `https` 时进行查找。 | | `boot` | string | `auto` | `auto` 启动由系统控制,`manual` 配置 app 仅手动启动。如果 app 不应在启动时自动启动,请使用 `manual_only` 来防止用户更改。 | | `ports` | dict | | 从容器暴露的网络端口。格式为 `"container-port/type": host-port`。如果主机端口为 `null`,则映射被禁用。 | | `ports_description` | dict | | 网络端口描述映射。格式为 `"container-port/type": "description of this port"`。或者使用 [Port description translations](#port-description-translations)。 | | `host_network` | bool | `false` | 如果为 `true`,app 在主机网络上运行。 | | `host_ipc` | bool | `false` | 允许 IPC namespace 与其他共享。 | | `host_dbus` | bool | `false` | 将主机 D-Bus 服务映射到 app。 | | `host_pid` | bool | `false` | 允许容器在主机 PID namespace 上运行。仅适用于未受保护的 app。**警告:** 与 S6 Overlay 不兼容。如果必须将其设为 `true` 且你使用普通的 app base 镜像,你需要通过覆盖 `/init` 来禁用 S6。或者使用替代的 base 镜像。 | | `host_uts` | bool | `false` | 使用主机的 UTS namespace。 | | `devices` | list | | 要映射到 app 的设备列表。格式为:``。例如,`/dev/ttyAMA0` | | `homeassistant` | string | | 固定 app 所需的最小 Home Assistant Core 版本。值是一个版本字符串,如 `2022.10.5`。 | | `hassio_role` | str | `default` | 基于角色的 Supervisor API 访问。可用:`default`、`homeassistant`、`backup`、`manager` 或 `admin` | | `hassio_api` | bool | `false` | 此 app 可以访问 Supervisor 的 REST API。使用 `http://supervisor`。 | | `homeassistant_api` | bool | `false` | 此 app 可以访问 Home Assistant REST API proxy。使用 `http://supervisor/core/api`。 | | `docker_api` | bool | `false` | 允许 app 只读访问 Docker API。仅适用于未受保护的 app。 | | `privileged` | list | | 访问硬件/系统的权限。可用访问:`BPF`、`CHECKPOINT_RESTORE`、`DAC_READ_SEARCH`、`IPC_LOCK`、`NET_ADMIN`、`NET_RAW`、`PERFMON`、`SYS_ADMIN`、`SYS_MODULE`、`SYS_NICE`、`SYS_PTRACE`、`SYS_RAWIO`、`SYS_RESOURCE` 或 `SYS_TIME`。 | | `full_access` | bool | `false` | 像 Docker 的 privileged 模式一样授予对硬件的完全访问权限。仅适用于未受保护的 app。考虑使用其他 app 选项而不是此选项,如 `devices`。如果你启用了此选项,请不要添加 `devices`、`uart`、`usb` 或 `gpio`,因为这是不必要的。 | | `apparmor` | bool/string | `true` | 启用或禁用 AppArmor 支持。如果已启用,你还可以使用 profile 的名称作为自定义 profile。 | | `map` | list | | 要绑定挂载到你的容器中的 Home Assistant 目录类型列表。可能的值:`homeassistant_config`、`addon_config`、`ssl`、`addons`、`backup`、`share`、`media`、`all_addon_configs` 和 `data`。默认为只读,你可以通过添加属性 `read_only: false` 来更改。默认情况下,所有路径都映射到 app 容器中的 `/`,但也可以提供可选的 `path` 属性来配置路径(示例:`path: /custom/config/path`)。如果使用,路径不能为空,必须与为该 app 定义的任何其他路径不同,并且不能是根路径。注意,`data` 目录始终映射且可写,但可以使用相同的约定设置 `path` 属性。 | | `environment` | dict | | 运行 app 所需的环境变量字典。 | | `audio` | bool | `false` | 标记此 app 使用内部音频系统。我们将一个可用的 PulseAudio 设置映射到容器中。如果你的应用程序不支持 PulseAudio,你可能需要安装:Alpine Linux `alsa-plugins-pulse` 或 Debian/Ubuntu `libasound2-plugins`。 | | `video` | bool | `false` | 标记此 app 使用内部视频系统。所有可用设备都将映射到 app 中。 | | `gpio` | bool | `false` | 如果设置为 `true`,`/sys/class/gpio` 将映射到 app 中以访问内核的 GPIO 接口。某些库还需要 `/dev/mem` 和 `SYS_RAWIO` 才能对此设备进行读写访问。在启用 AppArmor 的系统上,你需要禁用 AppArmor 或为该 app 提供你自己的 profile,后者对安全性更好。 | | `usb` | bool | `false` | 如果设置为 `true`,它会将原始 USB 访问权限 `/dev/bus/usb` 映射到 app 中,并支持即插即用。 | | `uart` | bool | `false` | 默认 `false`。自动将主机的所有 UART/串口设备映射到 app 中。 | | `udev` | bool | `false` | 默认 `false`。将其设置为 `true` 会将主机的 udev 数据库以只读方式挂载到 app 中。 | | `devicetree` | bool | `false` | 如果设置为 `true`,`/device-tree` 将映射到 app 中。 | | `kernel_modules` | bool | `false` | 将主机内核模块和配置映射到 app 中(只读),并授予你 `SYS_MODULE` 权限。 | | `stdin` | bool | `false` | 如果启用,你可以将 STDIN 与 Home Assistant API 一起使用。 | | `legacy` | bool | `false` | 如果 Docker 镜像没有 `hass.io` labels,你可以启用 legacy 模式来使用 config 数据。 | | `options` | dict | | app 的默认 options 值。 | | `schema` | dict | | app 的 options 值的 schema。它可以是 `false` 以禁用 schema 验证和 options。 | | `image` | string | | 与容器注册表一起使用。将其设置为通用(多架构)镜像名称,例如 `ghcr.io/my-org/my-app`。`{arch}` 占位符仍作为按架构镜像名称的兼容 fallback 受支持(例如,`ghcr.io/my-org/{arch}-my-app`)。如果使用此选项,请使用 `version` 选项设置活动 Docker tag。 | | `timeout` | integer | 10 | 默认 10(秒)。等待 Docker daemon 完成或将被杀死的超时时间。 | | `tmpfs` | bool | `false` | 如果设置为 `true`,容器的 `/tmp` 将使用 tmpfs(内存文件系统)。 | | `discovery` | list | | 此 app 为 Home Assistant 提供的服务列表。 | | `services` | list | | 将通过此 app 提供或消费的服务列表。格式为 `service`:`function`,函数包括:`provide`(此 app 可以提供此服务)、`want`(此 app 可以使用此服务)或 `need`(此 app 需要此服务才能正常工作)。 | | `auth_api` | bool | `false` | 允许访问 Home Assistant 用户后端。 | | `ingress` | bool | `false` | 为 app 启用 Ingress 功能。 | | `ingress_port` | integer | `8099` | 对于在主机网络上运行的 app,你可以使用 `0` 并在之后通过 API 读取端口。 | | `ingress_entry` | string | `/` | 修改 URL 入口点。 | | `ingress_stream` | bool | `false` | 启用后,对 app 的请求将被流式处理 | | `panel_icon` | string | `mdi:puzzle` | 菜单 panel 集成的 [MDI icon](https://materialdesignicons.com/)。 | | `panel_title` | string | | 默认为 app 名称,但可以使用此选项修改。 | | `panel_admin` | bool | `true` | 使菜单项仅对 admin 组中的用户可用。 | | `backup` | string | `hot` | `hot` 或 `cold`。如果为 `cold`,supervisor 会在备份前关闭 app(使用 `cold` 时忽略 `pre/post` 选项)。 | | `backup_pre` | string | | 在备份前在 app 上下文中执行的命令。 | | `backup_post` | string | | 在备份后在 app 上下文中执行的命令。 | | `backup_exclude` | list | | 从备份中排除的文件/路径列表(支持 glob)。 | | `stage` | string | `stable` | 用以下属性之一标记 app,让用户了解其在开发生命周期中的位置:`stable`、`experimental` 或 `deprecated`。 | | `init` | bool | `true` | 设置为 `false` 以禁用 Docker 默认系统 init。如果镜像有自己的 init 系统(如 [s6-overlay](https://github.com/just-containers/s6-overlay)),请使用此选项。*注意:从 S6 V3 开始,将其设置为 `false` 是必需的,否则 app 将无法启动,详情请参见[此处](https://developers.home-assistant.io/blog/2022/05/12/s6-overlay-base-images)。* | | `watchdog` | string | | 用于监控 app 健康状况的 URL。如 `http://[HOST]:[PORT:2839]/dashboard`,端口需要使用内部端口,它将被替换为有效的端口。还可以将协议部分绑定到配置选项:`[PROTO:option_name]://[HOST]:[PORT:2839]/dashboard`,并在其为 `true` 且指向 `https` 时进行查找。对于简单的 TCP 端口监控,你可以使用 `tcp://[HOST]:[PORT:80]`。它适用于主机或内部网络上的 app。 | | `realtime` | bool | `false` | 授予 app 对主机调度的访问权限,包括 `SYS_NICE` 用于更改执行时间/优先级。 | | `journald` | bool | `false` | 如果设置为 `true`,主机的系统 journal 将以只读方式映射到 app 中。大多数情况下 journal 位于 `/var/log/journal`,但在某些主机上你将在 `/run/log/journal` 中找到它。依赖此功能的 app 应检查目录 `/var/log/journal` 是否已填充,如果没有则回退到 `/run/log/journal`。 | | `breaking_versions` | list | | app 破坏性版本的列表。如果更新到破坏性版本或会跨越破坏性版本,即使用户已为 app 启用自动更新,也需要手动更新。 | | `ulimits` | dict | | app 容器资源限制(ulimit)设置的字典。每个限制可以是一个简单的整数值,或一个包含 `soft` 和 `hard` 键的字典,每个键取一个简单整数以实现精细控制。单个值不得大于主机的硬限制(可通过 `ulimit -Ha` 检查;例如,在 Home Assistant Operating System 中 `nofile` 限制为 524288)。 | ### 选项 / Schema `options` 字典包含所有可用选项及其默认值。将默认值设置为 `null` 或在 `schema` 字典中定义数据类型,即可使某个选项成为必填项。这样,在 app(以前称为 add-on)启动之前需要用户提供该选项。支持嵌套数组和字典,最大深度为二。 要使某个选项真正可选(没有默认值),需要使用 `schema` 字典。在数据类型末尾加一个 `?`,并且*不要*在 `options` 字典中定义任何默认值。如果给出了任何默认值,该选项就变成必填值。 ```yaml message: "custom things" logins: - username: beer password: "123456" - username: cheep password: "654321" random: - haha - hihi link: "http://example.com/" size: 15 count: 1.2 ``` :::note 如果你从已经部署给用户的 app 中移除配置选项,建议删除该选项,以避免出现 `Option '' does not exist in the schema for ()` 之类的警告。 要移除一个选项,可以使用 Supervisor addons API。使用 bashio 时,这简化为 `bashio::addon.option ''`(不带额外参数以删除此 option key)。要检查该选项是否仍然设置,可以像这样检查 options 字典的内容: ```sh options=$(bashio::addon.options) old_key='test' if bashio::jq.exists "${options}" ".${old_key}"; then bashio::log.info "Removing ${old_key}" bashio::addon.option "${old_key}" fi ``` ::: `schema` 看起来像 `options`,但描述了我们如何验证用户输入。例如: ```yaml message: str logins: - username: str password: str random: - "match(^\\w*$)" ssh: private_key: str public_key: str link: url size: "int(5,20)" count: float not_need: "str?" ``` 我们支持: * `str` / `str(min,)` / `str(,max)` / `str(min,max)` * `bool` * `int` / `int(min,)` / `int(,max)` / `int(min,max)` * `float` / `float(min,)` / `float(,max)` / `float(min,max)` * `email` * `url` * `password` * `port` * `match(REGEX)` * `list(val1|val2|...)` * `device` / `device(filter)`:设备过滤器可以使用以下格式:`subsystem=TYPE`,即 `subsystem=tty` 用于串口设备。 :::note 以前,额外的构建选项(如 `build_from`、`args` 和 `labels`)是在单独的 `build.yaml` 文件中配置的,由旧版 builder 读取。该文件已不再使用。base 镜像应在你的 `Dockerfile` 中直接使用 `FROM` 语句设置,labels 使用 `LABEL` 语句设置,自定义构建参数使用 `ARG` 定义。有关详细的迁移说明,请参见 [builder migration blog post](/developers/blog/2026-04-02-builder-migration.md)。 ::: ## App 翻译 app(以前称为 add-on)可以为 UI 中使用的配置选项提供翻译文件。 翻译文件的路径示例:`addon/translations/{language_code}.yaml` `{language_code}` 使用有效的语言代码,如 `en`,[完整列表请参见此处](https://github.com/home-assistant/frontend/blob/dev/src/translations/translationMetadata.json),`en.yaml` 将是一个有效的文件名。 此文件支持 2 个主要 key:`configuration` 和 `network`。 ### 配置翻译 ```yaml configuration: ssl: name: Enable SSL description: Enable usage of SSL on the webserver inside the app ssh: name: SSH Options description: Configure SSH authentication options fields: public_key: name: Public Key description: Client Public Key private_key: name: Private Key description: Client Private Key ``` *此处在 `configuration` 下的 key(此例中为 `ssl`)需要与你的 `schema` 配置中的一个 key 相匹配(在 [`config.yaml`](#app-configuration) 中)。* ### 端口描述翻译 ```yaml network: 80/TCP: The webserver port (Not used for Ingress) ``` *此处在 `network` 下的 key(此例中为 `80/TCP`)需要与你的 `ports` 配置中的一个 key 相匹配(在 [`config.yaml`](#app-configuration) 中)。* ## App 高级选项 有时 app 开发者可能希望允许用户配置提供自己的文件,这些文件随后将直接提供给内部服务作为其配置的一部分。一些示例包括: 1. 内部服务需要配置项的列表,且每项的 schema 很复杂,但服务没有提供 UI 进行设置,更简单的做法是将用户指向其文档并请求一个符合该 schema 的文件。 2. 内部服务需要一个二进制文件或作为其配置一部分的外部配置文件。 3. 内部服务支持配置变更时的实时重新加载,你希望为其部分或全部配置支持此功能,方法是要求用户提供一个符合其 schema 的文件进行实时重新加载。 在这些情况下,你应该在你的 app 配置文件的 `map` 中添加 `addon_config`。然后你应该指导用户将该文件放入 `/addon_configs/{REPO}_` 文件夹中。如果 app 在本地安装,`{REPO}` 将为 `local`。如果 app 从 GitHub 仓库安装,`{REPO}` 是从 GitHub 仓库 URL 生成的哈希标识符(例如:`https://github.com/xy/my_hassio_addons`)。 此文件夹在 app 的 docker 容器运行时将挂载在 `/config` 下。你应该在 app 的 schema 中提供一个选项来收集从该文件夹开始的相对文件路径,或者依赖固定的文件名并将其包含在文档中。 `addon_config` 的另一种用途可能是你的 app 想要提供基于文件的输出,或让用户访问内部文件以进行调试。一些示例包括: 1. 内部服务将日志记录到文件,你希望允许用户访问该日志文件 2. 内部服务使用数据库,你希望允许用户访问该数据库以进行调试 3. 内部服务生成一些文件,这些文件打算在其自身配置中使用,你希望允许用户访问它们 在这些情况下,你应该在 `map` 中添加 `addon_config:rw`,这样你的 app 就可以向该文件夹写入以及从中读取。然后你应该在 app 运行时将这些文件写出到 `/config`,以便用户可以看到和访问它们。 --- url: /developers/apps/presentation.md --- 如果你选择将你的 app(以前称为 add-on)向公众开放,提供清晰的信息、图形和安全保障将有助于吸引用户。下面的建议是展示 app 的参考指南。 ## 添加介绍 介绍会显示在 app 商店中,向用户提供关于 app 功能的简短描述。 包含介绍的这个文件通常被称为"README",一般以 `README.md` 文件发布。 ## 添加文档 良好的文档有助于 app 的使用者理解其用法,解释配置选项,在用户有疑问或问题时为他们指明正确的方向,并包含 app 发布时所用的许可证。 包含文档的这个文件通常被称为"DOCS",一般以 `DOCS.md` 文件发布。 ## App 图标与标志 一图胜千言。因此,为你的 app 添加合适的图片图标和标志可以改进 app 的表现。这些图片在 Home Assistant Supervisor 面板中展示你的 app 时会使用到,并能显著提升 app 的视觉效果。 对 app 标志的要求: * 标志必须是便携式网络图形格式(`.png`)。 * 文件名必须是 `logo.png`。 * 建议将标志尺寸保持在 250x100px 左右。你可以根据 app 的实际情况选择其他尺寸或宽高比。 对 app 图标的要求: * 图标必须是便携式网络图形格式(`.png`)。 * 文件名必须是 `icon.png`。 * 图标的宽高比必须为 1x1(正方形)。 * 建议使用 128x128px 的图标尺寸。 ## 维护更新日志 将来你很可能会发布 app 的更新版本。如果发生这种情况,app 的用户会看到升级通知,并希望了解最新版本中做了哪些更改。 更新日志是一个文件,其中包含按版本整理的、按时间顺序排列的重要更改列表,一般以 `CHANGELOG.md` 文件发布。 关于维护更新日志的建议,我们推荐 [keep a changelog](http://keepachangelog.com) 网站。他们制定了一项被世界各地许多开源项目使用的标准。 ## 提供稳定版和 canary 版本 你可以考虑同时提供稳定版和"next"或"canary"分支。这些可以通过不同的分支来提供。在 Home Assistant 中添加 app 时,用户可以通过在仓库地址后附加 #分支名来选择所需的分支。 ```text https://github.com/home-assistant/hassio-addons-example#next ``` 你应该将此信息添加到文档中。此外,你应该考虑在每个分支中为仓库设置不同的[名称](/developers/apps/repository.md#repository-configuration),例如"Super app (stable)"和"Super app (beta)"。 ## AppArmor 当 API 调用返回了作为开发者的你没有预料到的内容时,过多资源的访问权限可能成为用户的隐患。作为 app 开发者,确保你的 app 不会损坏用户的设备或执行你从未期望的操作是你的责任。AppArmor 在此发挥作用。 虽然这里不会评判你在输入验证、处理敏感数据及其他防御性编程技巧方面的能力,但 AppArmor 是你的 app 防范恶意 API 调用、错误设置或其他系统劫持形式时的第二道防线。 默认情况下,AppArmor 通过限制一些被认为不适合 Docker 容器的一般操作来提供一定程度的安全性。你可以在 [Docker Security page](https://docs.docker.com/engine/security/apparmor/) 上阅读更多关于 Docker 的 AppArmor 实现。 关于 Home Assistant 的实现,你可以将 `apparmor.txt` 文件放入你的 app 文件夹来启用自定义的 AppArmor profile。添加你自己的 `apparmor.txt` 后,该文件将被作为主要 AppArmor profile 加载,而不是默认的实现。除了让你的 app 以更受限且有效的方式运行之外,编写自定义的 `apparmor.txt` 文件还能在你的 app 安装后为其赢得一个安全积分,从而提升用户对你 app 的信心和认知。 `apparmor.txt` 放在与你的 `config.yaml` 文件相同的文件夹中。下面是一个示例 `apparmor.txt`。将 `ADDON_SLUG` 替换为你 app 配置中定义的 slug。 apparmor.txt ```txt #include profile ADDON_SLUG flags=(attach_disconnected,mediate_deleted) { #include # Capabilities file, signal (send) set=(kill,term,int,hup,cont), # S6-Overlay /init ix, /bin/** ix, /usr/bin/** ix, /run/{s6,s6-rc*,service}/** ix, /package/** ix, /command/** ix, /etc/services.d/** rwix, /etc/cont-init.d/** rwix, /etc/cont-finish.d/** rwix, /run/{,**} rwk, /dev/tty rw, # Bashio /usr/lib/bashio/** ix, /tmp/** rwk, # Access to options.json and other files within your addon /data/** rw, # Start new profile for service /usr/bin/myprogram cx -> myprogram, profile myprogram flags=(attach_disconnected,mediate_deleted) { #include # Receive signals from S6-Overlay signal (receive) peer=*_ADDON_SLUG, # Access to options.json and other files within your addon /data/** rw, # Access to mapped volumes specified in config.json /share/** rw, # Access required for service functionality /usr/bin/myprogram r, /bin/bash rix, /bin/echo ix, /etc/passwd r, /dev/tty rw, } } ``` 在为你的 app 做这项工作时,以下提示应能帮助你入门: 1. 其中 S6 部分相当标准化。你可能需要添加一些内容来适应你的 setup 脚本,但通常不要移除任何内容。 2. 如果运行的某个服务提供了 AppArmor profile,则对该服务应用此 profile。始终优先使用开发者编写的 profile。 3. 如果某个服务没有现成的 profile 而你想要创建一个,请执行以下操作: a. 添加你了解的最低必要权限。即你确定该服务需要的东西 b. 在 profile 中添加 `complain` 作为 flag c. 运行 app 并使用 `journalctl _TRANSPORT="audit" -g 'apparmor="ALLOWED"'` 查看 audit 日志 d. 按需添加权限,直到使用 app 不再产生任何 audit 警告 e. 移除 `complain` flag,使未授权的访问被 DENIED 而非 ALLOWED 4. 在更新服务时重复第 3 步,因为可能需要新的权限 ## Ingress Ingress 允许用户通过 Home Assistant UI 访问 app 的 web 界面。认证由 Home Assistant 处理,因此用户和 app 开发者都无需关心安全性或端口转发。用户非常喜欢这个功能!它直接将用户连接到 app,能在 Home Assistant 中提供无缝的 UX,并为你的 app 提供 2 个安全积分。 以下是 Ingress 的要求: * 必须启用 Ingress。在 [`config.yaml`](/developers/apps/configuration.md#optional-configuration-options) 中设置 `ingress: true`。 * 你的服务器可以运行在 8099 端口。如果它不运行在 8099 端口上,必须在 [`config.yaml`](/developers/apps/configuration.md#app-configuration) 中设置 `ingress_port: PORT_NUMBER` 以匹配你的配置。 * 仅允许来自 `172.30.32.2` 的连接。你应在 app 服务器中拒绝所有其他 IP 地址的访问。 * 用户已经通过 Home Assistant 进行了认证。无需再次认证。 :::tip 路径和端口信息可以通过 [apps info API endpoint](/developers/api/supervisor/endpoints.md#apps) 查询。如果你的 app 需要 Home Assistant URL,Ingress 会添加一个请求头 `X-Ingress-Path`,你可以通过过滤它来获取 base URL。 ::: Ingress API gateway 支持以下功能: * HTTP/1.x * 流式内容 * Websockets ## 使用 Nginx 的基础 Ingress 示例 以下是一个使用 Nginx 服务器的基础 Ingress 实现。它包含一个示例 `Dockerfile`、`config.yaml` 和 `ingress.conf` 配置。 `ingress.conf` 配置为仅接受来自 IP 地址 `172.30.32.2` 的连接,因为我们只为 Ingress 目的预期来自该 IP 地址的连接。任何其他 IP 地址都将被拒绝。使用 Ingress 端口 8099 可以减少配置工作量。如果你希望配置其他 Ingress 端口,也可以,但必须定义 `config.yaml` 选项 `ingress_port` 以匹配。 ingress.conf ```nginx server { listen 8099; allow 172.30.32.2; deny all; } ``` 我们的示例 `Dockerfile` 配置为仅支持我们的 Nginx 服务器,不像大多数 app 那样支持 `run.sh`。你可以用你自己的命令替换 `CMD`,以便在启动 app 时提供更多配置选项。此 Dockerfile 会 `RUN` 安装我们的 Nginx 依赖,`COPY` 上面示例 `ingress.conf` 到 app 容器,然后 `CMD` 启动 Nginx。 Dockerfile ```dockerfile FROM ghcr.io/home-assistant/base:latest #Add nginx and create the run folder for nginx. RUN \ apk --no-cache add \ nginx \ \ && mkdir -p /run/nginx #Copy our conf into the nginx http.d folder. COPY ingress.conf /etc/nginx/http.d/ #Launch nginx with debug options. CMD [ "nginx","-g","daemon off;error_log /dev/stdout debug;" ] ``` 为了启用 Ingress,我们的 `config.yaml` 文件必须包含 `ingress: true`,并可以指定 `ingress_port`,以及其它所需信息。 config.yaml ```yaml name: "Ingress Example" version: "1.0.0" slug: "nginx-ingress-example" description: "Ingress testing" arch: - aarch64 - amd64 ingress: true ``` app 启动后,你应能在 app 信息页面中点击"OPEN WEB UI"来查看你的 Ingress 服务器。 ## 安全 App 安全应该是一件引以为傲的事。你应该努力达到你能达到的最高安全级别。如果你的 app 安全评级较低,用户就更不太可能信任它。 每个 app 的基础评级为 5,范围从 1 到 6。根据开发过程中所做的决定,你会基于某些操作获得评分。有些操作还有额外的后果。这些额外后果显示在下面的备注栏中。 | Action | Change | Notes | |---|---|---| | 在 [`config.yaml`](/developers/apps/configuration.md#optional-configuration-options) 中使用 `ingress: true` | +2 | 覆盖 `auth_api` 评级 | | 在 [`config.yaml`](/developers/apps/configuration.md#optional-configuration-options) 中使用 `auth_api: true` | +1 | 被 `ingress` 覆盖 | | 使用自定义 [`apparmor.txt`](/developers/apps/presentation.md#apparmor)| +1| 评级在安装后应用 | | 在 [`config.yaml`](/developers/apps/configuration.md#optional-configuration-options) 中设置 `apparmor: false` | -1 | | | 在 [`config.yaml`](/developers/apps/configuration.md#optional-configuration-options) 中使用 `privileged: NET_ADMIN`、`SYS_ADMIN`、`SYS_RAWIO`、`SYS_PTRACE`、`SYS_MODULE` 或 `DAC_READ_SEARCH`,或使用 `kernel_modules:` | -1 | 如果使用了多个,评级仅应用一次。 | | 在 [`config.yaml`](/developers/apps/configuration.md#optional-configuration-options) 中使用 `hassio_role: manager` | -1 | | | 在 [`config.yaml`](/developers/apps/configuration.md#optional-configuration-options) 中使用 `host_network: true` | -1 | | | 在 [`config.yaml`](/developers/apps/configuration.md#optional-configuration-options) 中使用 `hassio_role: admin` | -2 | | | 在 [`config.yaml`](/developers/apps/configuration.md#optional-configuration-options) 中使用 `host_pid: true` | -2 | | | 在 [`config.yaml`](/developers/apps/configuration.md#optional-configuration-options) 中使用 `host_uts: true` 和 `privileged: SYS_ADMIN` | -1 | | | 在 [`config.yaml`](/developers/apps/configuration.md#optional-configuration-options) 中使用 `full_access: true` | Security 设为 1 | 覆盖所有其他调整 | | 在 [`config.yaml`](/developers/apps/configuration.md#optional-configuration-options) 中使用 `docker_api: true` | Security 设为 1 | 覆盖所有其他调整 | --- url: /developers/apps/publishing.md --- 发布 app(以前称为 add-on)有两种不同的方式。一种是将预构建的容器发布到容器注册表,另一种方式是让用户在自己的 Home Assistant 实例上本地构建容器。 ## 预构建容器 使用预构建容器时,开发者负责为每种架构构建镜像并将结果推送到容器注册表。这对用户有很多好处:用户只需下载最终的容器,下载完成后即可运行。这使得安装过程快速且几乎不会失败,因此是首选方法。 我们已通过 GitHub Actions 自动化了构建和发布 app 的过程。详见下面的说明。 ## 本地构建容器 使用 Supervisor,可以分发将在用户机器上构建的 app。它的优点是,对于开发者来说,测试一个想法并看看是否有人对你的 app 感兴趣很容易。这种方法包括安装和潜在的代码编译。这意味着安装这样的 app 速度较慢,并且比上述预构建方案更容易磨损用户的 SD 卡/硬盘。如果容器的某个依赖项已更改或不再可用,它的失败几率也更高。 在玩 app 并看看是否有人对你的工作感兴趣时,请使用此选项。一旦你的仓库已建立,请迁移到将构建推送到容器注册表,因为这能大大改善用户体验。将来我们会在 app 商店中标记本地构建的 app,以提醒用户。 ## 使用 GitHub Actions 将 app 发布到容器注册表 构建和发布多架构 app 镜像的推荐方式是通过 GitHub Actions,使用 Home Assistant 项目维护的 builder composite actions。这些 action 可以用于 app 仓库中的构建矩阵。有关构建多个 app 的复杂示例,请参见示例 app 仓库中的 [builder workflow](https://github.com/home-assistant/apps-example/blob/main/.github/workflows/builder.yaml),或者 builder 仓库中针对单个 app 构建的 [example workflow](https://github.com/home-assistant/builder?tab=readme-ov-file#example-workflow)。builder action 设计灵活,可以根据需要用于更复杂的工作流中。 ### 镜像命名 在 app 的 `config.yaml` 中,将 `image` 字段设置为发布在容器注册表中的镜像名称: ```yaml image: "ghcr.io/my-org/my-app" ``` `{arch}` 占位符仍受支持,用于向后兼容按架构发布的镜像。当有可用的多架构 manifest 时,通用名称是首选的公共引用: ```yaml # Preferred — resolves via the multi-arch manifest image: "ghcr.io/my-org/my-app" # Compatibility fallback — still works if only arch-prefixed images exist image: "ghcr.io/my-org/{arch}-my-app" ``` ### 已发布的镜像 成功运行后,可获得两种类型的镜像引用: * **Per-architecture images**(例如,`ghcr.io/my-org/aarch64-my-app:1.0.0`)— 由 `build-image` action 推送。 * **Generic manifest image**(例如,`ghcr.io/my-org/my-app:1.0.0`)— 由 `publish-multi-arch-manifest` action 推送;这是在 `config.yaml` 中使用以及向用户共享的首选引用。 ### 示例 app 仓库 请参见 [Home Assistant example app repository](https://github.com/home-assistant/apps-example),这是一个完整的、最新的可运行示例。 --- url: /developers/apps/repository.md --- app 仓库可以包含一个或多个 app(以前称为 add-on)。每个 app 存储在各自独立的文件夹中。要被识别为仓库,该仓库必须包含一个配置文件。 请查看 [Example app repository](https://github.com/home-assistant/addons-example) 以获取更多详细信息。 ## 安装仓库 用户可以通过进入 Home Assistant 的 Supervisor 面板,点击右上角的商店图标,将你的仓库 URL 复制/粘贴到仓库文本区域,然后点击 **Save** 来添加一个仓库。 :::tip 你可以在 readme 文件中生成一个 [my.home-assistant.io](https://my.home-assistant.io/create-link/) 链接,让用户一键完成此操作。 ::: ## 仓库配置 每个仓库都要求在 git 仓库的根目录中包含 `repository.yaml`。 ```yaml name: Name of repository url: http://www.example/addons maintainer: HomeAssistant Team ``` | Key | Required | Description | | --- | -------- | ----------- | | `name` | yes | 仓库的名称 | | `url` | no | 仓库的主页。你可以在这里介绍各种 app。 | | `maintainer` | no | 维护者的联系信息。 | --- url: /developers/apps/security.md --- Home Assistant 根据 app(以前称为 add-on)所需权限对其进行评级。评级为 6 的 app 非常安全。如果 app 的评级为 1,除非你 100% 确定可以信任该来源,否则不应运行此 app。 ## API 角色 要访问 Supervisor API,你需要定义一个角色或以默认模式运行。这仅对 Supervisor API 是必需的,对 Home Assistant proxy 不要求。所有角色都已可以访问默认的 API 调用,不需要任何额外的设置。 ### 可用的角色 | Role | Description | |------|-------------| | `default` | 可以访问所有 `info` 调用 | | `homeassistant` | 可以访问所有 Home Assistant API endpoints | | `backup` | 可以访问所有 backup API endpoints | | `manager` | 适用于运行 CLI 且需要扩展权限的 Apps | | `admin` | 可以访问所有 API 调用。这是唯一可以禁用/启用 App protection mode 的角色 | ## 保护 默认情况下,所有 app 都在启用 protection 的模式下运行。此模式防止 app 在系统上获得任何权限。如果 app 需要更多权限,你可以通过该 app 的 API app options 禁用此 protection。但要小心,禁用了 protection 的 app 可能会破坏你的系统! ## 制作安全的 app 作为开发者,请遵循以下最佳实践来确保 app 安全: * 不要在主机网络上运行 * 创建 AppArmor profile * 如果不需要写入访问权限,则以只读方式映射文件夹 * 如果需要任何 API 访问权限,请确保不授予不必要的权限 * 签署已发布的镜像(支持的 [publishing workflow](/developers/apps/publishing.md) 可以使用 Cosign 签署镜像) ## 使用 Home Assistant 用户后端 与其允许用户以明文配置设置新的登录凭据,不如使用 Home Assistant [Auth backend](/developers/api/supervisor/endpoints.md#auth)。你可以通过 `auth_api: true` 启用对 API 的访问。现在你可以将登录凭据发送到 auth backend,并在 Home Assistant 中进行验证。 ## 使用 Ingress 时验证用户 当 app 通过 supervisor 的 Ingress 访问时,授权用户可以通过其 session token 来识别。supervisor 会为每个请求添加一些标识用户的 header: | Header name | Description | | -------------------------- | ------------------------------------------- | | X-Remote-User-Id | 已认证的 Home Assistant 用户 ID | | X-Remote-User-Name | 已认证用户的用户名 | | X-Remote-User-Display-Name | 已认证用户的显示名称 | --- url: /developers/apps/testing.md --- 开发 app(以前称为 add-on)的最快且推荐的方法是使用本地 Visual Studio Code devcontainer。我们为此维护了一个 [devcontainer](https://github.com/home-assistant/devcontainer),它被用于我们所有的 app 仓库。这个面向 VS Code 的 devcontainer 设置会运行 Supervisor 和 Home Assistant,并将所有 app 映射为内部本地 app,使得在 Windows、Mac 和 Linux 桌面操作系统上的 app 开发者可以轻松开发。 * 按照说明下载并安装 [Remote Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) VS Code 扩展。 * 将 [`devcontainer.json`](https://github.com/home-assistant/devcontainer/raw/main/apps/devcontainer.json) 文件复制到仓库中的 `.devcontainer/devcontainer.json`。 * 将 [`tasks.json`](https://github.com/home-assistant/devcontainer/raw/main/apps/tasks.json) 文件复制到仓库中的 `.vscode/tasks.json`。 * 在 VS Code 中打开根文件夹,当提示时在容器中重新打开窗口(或者,从 Command Palette 中选择"Rebuild and Reopen in Container")。 * 当 VS Code 在容器中打开你的文件夹时(首次运行可能需要一些时间),你需要运行任务(Terminal -> Run Task)"Start Home Assistant",这将启动 Supervisor 和 Home Assistant。 * 然后你将能通过 `http://localhost:7123/` 上的 Home Assistant 实例访问正常的 onboarding 流程。 * 你的根文件夹中的 app 将自动出现在 Local Apps 仓库中。 ## 远程开发 如果你需要访问物理硬件或其他无法在本地模拟的资源(例如串口),开发 app 的下一个最佳选项是将它们添加到运行 Home Assistant 的真实设备上的本地 app 仓库中。要访问远程设备上的本地 app 仓库,请安装 [Samba](https://my.home-assistant.io/redirect/supervisor_addon/?addon=core_samba) 或 [SSH](https://my.home-assistant.io/redirect/supervisor_addon/?addon=core_ssh) 这两个 app,并将 app 文件复制到 `/addons` 的子目录中。 目前 app 可以使用存储在 Docker Hub 上的镜像(通过 app 配置中的 `image`)。为确保 app 在本地构建而非从上游仓库获取,请确保 `config.yaml` 文件中的 `image` 键被注释掉(你可以在它前面加上 `#`,例如 `#image: xxx`)。 ## 本地构建 如果你不想使用 devcontainer 环境,可以使用独立 Docker 在本地构建 app。这对于在当前工作的主机上快速进行单一架构检查很有用。 在包含 app 文件的目录中使用 `docker` 来构建测试 app: ```shell docker build \ -t local/my-test-app \ . ``` 对于多平台构建或交叉编译,你可以使用 `--platform` flag 和相应的目标平台(例如,`--platform linux/arm64` 在 AMD64 主机上使用 QEMU 构建 `aarch64` 镜像)。有关更多详细信息,请参见 Docker 官方文档中的 [multi-platform builds](https://docs.docker.com/build/building/multi-platform/)。 :::note `--platform` 选项中使用的架构与 Home Assistant 中使用的架构不同。Home Assistant 中的 `amd64` 对应 `--platform linux/amd64`,Home Assistant 中的 `aarch64` 对应 Docker 中的 `--platform linux/arm64`。 ::: ## 本地运行 如果你不想使用 devcontainer 环境,仍然可以使用 Docker 在本地运行 app。 为此可以使用以下命令: ```shell docker run \ --rm \ -v /tmp/my_test_data:/data \ -p PORT_STUFF_IF_NEEDED \ local/my-test-app ``` ## 日志 所有 `stdout` 和 `stderr` 输出都会被重定向到 Docker 日志。可以在 Home Assistant 的 Supervisor 面板中的 app 页面获取日志。 --- url: /developers/apps/tutorial.md --- 好,你的 Home Assistant 已经运行起来了,内置的 app 让你乐在其中,但你现在缺了某一个应用。是时候自己做一个 app 了! 要开始开发 app,我们首先需要访问 Home Assistant 查找本地 app 的位置。为此你可以使用 [Samba](https://my.home-assistant.io/redirect/supervisor_addon/?addon=core_samba) 或 [SSH](https://my.home-assistant.io/redirect/supervisor_addon/?addon=core_ssh) 这两个 app。 对于 Samba,启用并启动它之后,你的 Home Assistant 实例会出现在本地网络选项中,并共享一个名为"addons"的文件夹。这就是存放自定义 app 的文件夹。 :::tip 如果你使用的是 macOS 且文件夹没有自动显示,请到 Finder 中按 CMD+K,然后输入 `smb://homeassistant.local` ::: 对于 SSH,你需要先安装它。在启动之前,你必须有一对私钥/公钥,并将公钥存储在 app 配置中([更多信息请参见文档](https://github.com/home-assistant/addons/blob/master/ssh/DOCS.md#configuration))。启动后,你可以 SSH 到 Home Assistant,并将自定义 app 存储在 `/addons` 目录中。 一旦你找到了 app 目录,就可以开始了! ## 第 1 步:基础 * 创建一个名为 `hello_world` 的新目录 * 在该目录中创建三个文件: * `Dockerfile` * `config.yaml` * `run.sh` ### `Dockerfile` 文件 这是用于构建你 app 的镜像。 ```dockerfile FROM ghcr.io/home-assistant/base:latest # Copy data for app COPY run.sh / RUN chmod a+x /run.sh CMD [ "/run.sh" ] ``` ### `config.yaml` 文件 这是你的 app 配置,它告诉 Supervisor 该做什么以及如何展示你的 app。 有关所有有效 app 配置选项的概述,请参见 [App configuration options](/developers/apps/configuration.md#app-configuration)。 ```yaml name: "Hello world" description: "My first real app!" version: "1.0.0" slug: "hello_world" init: false arch: - aarch64 - amd64 ``` ### `run.sh` 文件 这是你的 app 启动时运行的脚本。 ```shell #!/usr/bin/with-contenv bashio echo "Hello world!" ``` :::note 请确保你的编辑器使用类 UNIX 换行符(LF),而不是 DOS/Windows(CRLF)。 ::: ## 第 2 步:安装和测试你的 app 现在到了有趣的部分,打开 Home Assistant UI 并安装、运行你的 app。 * 打开 Home Assistant 前端 * 进入"Settings" * 点击"Apps" * 点击右下角的"App store"。 [![Open your Home Assistant instance and show the Supervisor app store.](https://my.home-assistant.io/badges/supervisor_store.svg)](https://my.home-assistant.io/redirect/supervisor_store/) * 在右上角的三点菜单中,点击"Check for updates"按钮 * 根据需要刷新网页 * 你现在应该能在商店顶部看到一个名为"Local apps"的新版块,其中列出了你的 app! ![Screenshot of the local repository card](/img/en/hass.io/screenshots/local_repository.png) * 点击你的 app 进入 app 详情页面 * 安装你的 app * 启动你的 app * 点击"Logs"标签页,并刷新你的 app 日志,你现在应该在日志中看到"Hello world!" ![Screenshot of the app logs](/img/en/hass.io/tutorial/addon_hello_world_logs.png) ### 我看不见我的 app?! 糟糕!你在商店中点击了"Check for updates",但你的 app 没有显示。或者也许你只是更新了一个选项,点击刷新后看到你的 app 消失了。 发生这种情况时,请先尝试按下 Ctrl + F5(Windows/Linux)或 Cmd + Shift + R(macOS)来刷新浏览器的缓存。如果这没有帮助,那就说明你的 `config.yaml` 无效。它要么是[无效的 YAML](http://www.yamllint.com/),要么是指定的某个选项不正确。要查看出了什么问题,请转到["Settings" → "System" → "Logs",并在右上角的下拉菜单中选择"Supervisor"](https://my.home-assistant.io/redirect/logs/?provider=supervisor)。这会带你进入一个包含 supervisor 日志的页面。滚动到底部,你应该能找到验证错误。 修复错误后,回到 app 商店,再次点击"Check for updates"。 ## 第 3 步:托管服务器 到目前为止我们只做了一些基本的事情,但这还不是很实用。所以让我们再进一步,托管一个我们在端口上公开的服务器。为此,我们将使用 Python 3 自带的内置 HTTP 服务器。 要做到这一点,我们需要按以下方式更新文件: * `Dockerfile`:安装 Python 3 * `config.yaml`:将容器中的端口在主机上公开 * `run.sh`:运行 Python 3 命令启动 HTTP 服务器 更新你的 `Dockerfile`: ```dockerfile FROM ghcr.io/home-assistant/base:latest # Install requirements for app RUN \ apk add --no-cache \ python3 # Python 3 HTTP Server serves the current working dir # So let's set it to our app persistent data directory. WORKDIR /data # Copy data for app COPY run.sh / RUN chmod a+x /run.sh CMD [ "/run.sh" ] ``` 在 `config.yaml` 中添加"ports"。这将使容器内 8000 端口的 TCP 在主机上以 8000 端口可用。 ```yaml name: "Hello world" description: "My first real app!" version: "1.1.0" slug: "hello_world" init: false arch: - aarch64 - amd64 startup: services ports: 8000/tcp: 8000 ``` 更新 `run.sh` 以启动 Python 3 服务器: ```shell #!/usr/bin/with-contenv bashio echo "Hello world!" python3 -m http.server 8000 ``` ## 第 4 步:安装更新 由于我们在 `config.yaml` 中更新了版本号,Home Assistant 在查看 app 详情时会显示一个更新按钮。你可能需要刷新浏览器,或在 app 商店中点击"Check for updates"按钮才能看到它。如果你没有更新版本号,你也可以卸载并重新安装 app。重新安装 app 后,请确保启动它。 现在导航到 查看我们的服务器运行效果! ![Screenshot of the file index served by the app](/img/en/hass.io/tutorial/python3-http-server.png) ## 奖励:使用 app 选项 在上面的截图中,你可能注意到我们的服务器只提供了一个文件:`options.json`。这个文件包含此 app 的用户配置。因为我们在 `config.yaml` 中为 `options` 和 `schema` 键指定了两个空对象,所以生成的文件当前是空的。 让我们看看能否向该文件中写入一些数据! 为此,我们需要指定默认选项和一个让用户修改选项的 schema。用以下内容更改 `config.yaml` 中的 options 和 schema 条目: ```yaml ... options: beer: true wine: true liquor: false name: "world" year: 2017 schema: beer: bool wine: bool liquor: bool name: str year: int ... ``` 重新加载 app 商店并重新安装你的 app。你现在会在 app 配置屏幕中看到可用的选项。当你回到我们的 Python 3 服务器并下载 `options.json` 时,你会看到你设置的选项。[options.json 在 `run.sh` 中使用的示例](https://github.com/home-assistant/apps-example/blob/main/example/rootfs/etc/services.d/example/run#L12-L17) ## 奖励:模板 app 仓库 我们维护了一个完整的模板示例仓库,你可以用它来开始构建 app。你可以在 [`home-assistant/addons-example` 仓库](https://github.com/home-assistant/addons-example) 中找到它。 --- url: /developers/architecture/core.md --- Home Assistant Core 由四个主要部分组成。在此之上,它还包含许多用于处理常见场景的辅助类,例如提供实体(entity)或处理位置信息。 * **事件总线(Event Bus)**:实现事件的触发与监听——Home Assistant 的核心所在。 * **状态机(State Machine)**:跟踪各类对象的状态,并在状态发生变化时触发 `state_changed` 事件。 * **服务注册表(Service Registry)**:监听事件总线上的 `call_service` 事件,并允许其他代码注册 service actions。 * **定时器(Timer)**:每秒在事件总线上发送一次 `time_changed` 事件。 Home Assistant 核心架构概览 --- url: /developers/architecture/devices-and-services.md --- 集成可以在 Home Assistant 中表示设备与服务。数据点以实体(entities)的形式表示。实体由 `light`、`switch` 等其他集成进行标准化。标准化实体附带用于控制的 actions,但集成也可以提供自己的 service actions,以应对尚未标准化的功能。 实体封装了 Home Assistant 的内部工作机制。作为集成开发者,你无需关心 service actions 或状态机是如何工作的。你只需扩展一个实体类,并为所集成的设备类型实现必要的属性和方法。 集成设备与服务 配置由用户通过 [Config Entry](/developers/config_entries_index.md) 提供,或在特殊/遗留场景下通过 [configuration.yaml](/developers/core/integration/yaml_configuration.md) 提供。 设备集成(即 `hue`)将使用此配置与设备/服务建立连接。它会将 config entry 转发(遗留方式使用 discovery helper)以在各自的集成(light、switch)中设置实体。设备集成还可以为尚未标准化的功能注册自己的 service actions。这些 actions 发布在集成的 domain 下,例如 `hue.activate_scene`。 实体集成(即 `light`)负责定义抽象实体类以及用于控制实体的 services。 Entity Component 辅助类负责将配置分发到各平台,转发 discovery 并收集实体以执行 service calls。 Entity Platform 辅助类管理该平台的所有实体,并在必要时对其进行轮询以获取更新。在添加实体时,Entity Platform 负责将实体注册到设备和实体注册表中。 集成平台(即 `hue.light`)使用配置来查询外部设备/服务并创建待添加的实体。集成平台还可以注册 entity services。这些 services 将作用于设备集成中该实体集成下的所有实体(即所有 Hue 灯的实体)。这些 services 发布在设备集成的 domain 下。 ## 实体与 Home Assistant Core 的交互 继承自实体基类的集成实体类负责获取数据和处理 service calls。如果禁用了轮询,它还负责在数据可用时通知 Home Assistant。 实体与核心交互 实体基类(由实体集成定义)负责格式化数据并将其写入状态机。 对于当前没有实体对象支持的任何已注册实体,实体注册表将写入 `unavailable` 状态。 ## 实体数据层级 \实体层级 删除、禁用或重新启用任何对象,其下方的所有对象都将相应调整。 --- url: /developers/architecture_components.md --- Home Assistant Core 可以通过**集成**进行扩展。每个集成负责 Home Assistant 中的一个特定域。集成可以监听或触发事件,提供 action,并维护状态。集成由一个 component(基础逻辑)和 platforms(与其他集成集成的部分)组成。集成使用 Python 编写,可以利用 Python 提供的所有优势。开箱即用,Home Assistant 提供了大量[内置集成](https://www.home-assistant.io/integrations/)。 图表展示集成与 Home Assistant 核心之间的交互。 Home Assistant 区分以下集成类型: ## 定义物联网域 这些集成在 Home Assistant 中定义特定的物联网设备类别,比如 light。由 `light` 集成来定义在 Home Assistant 中有哪些可用数据以及以什么格式。它还提供了控制灯的 action。 有关已定义域的列表,请参见 [entities](/developers/core/entity.md)。 如需建议一个新域,请在 [架构仓库](https://github.com/home-assistant/architecture/discussions) 中发起讨论。务必展示你提议的 entity 将包含哪些数据,以及它如何被控制。包含多个品牌的示例。 ## 与外部设备和服务交互 这些集成与外部设备和服务交互,并通过定义 IoT 域(如 `light`)的集成使其在 Home Assistant 中可用。此类集成的一个示例是 Philips Hue。Philips Hue 灯在 Home Assistant 中作为 light entity 提供。 与外部设备和服务交互的集成通常不允许消耗来自其他集成的 entity 状态,例外情况是具有位置的来自其他集成的 entity,例如 zone 和 device\_tracker entity 的状态。 更多信息请参见 [entity 架构](/developers/architecture/devices-and-services.md)。 ## 表示虚拟/计算数据点 这些集成基于虚拟数据来表示 entity,例如 [`input_boolean` 集成](https://www.home-assistant.io/integrations/input_boolean/),一个虚拟开关。或者它们基于 Home Assistant 中其他可用数据来派生自己的数据,例如 [`template` 集成](https://www.home-assistant.io/integrations/template/) 或 [`utility_meter` 集成](https://www.home-assistant.io/integrations/utility_meter/)。 ## 用户可触发或响应事件的 action 这些集成提供小的家庭自动化逻辑片段,在房屋内执行常见任务。最受欢迎的是 [`automation` 集成](https://www.home-assistant.io/integrations/automation/),允许用户通过配置格式创建自动化。 它也可以更具体,例如 [`flux` 集成](https://www.home-assistant.io/integrations/flux/),根据太阳位置控制灯光。 --- url: /developers/architecture_index.md --- Home Assistant 提供了一个家庭控制与家庭自动化平台。Home Assistant 不仅仅是一个应用程序:它是一个嵌入式系统,提供类似于其他消费级产品的体验:引导设置、配置和更新都通过易于使用的界面完成。 * [操作系统](/developers/operating-system.md) 提供了运行 Supervisor 和 Core 所需的最小 Linux 环境。 * [Supervisor](/developers/supervisor.md) 管理系统。 * [Core](/developers/architecture/core.md) 与用户、supervisor 和 IoT 设备及服务交互。 Home Assistant 全貌 ## 运行部分堆栈 用户对家庭自动化平台有不同的需求。因此,可以只运行 Home Assistant 堆栈的一部分。更多信息请参见[安装说明](https://www.home-assistant.io/installation/)。 --- url: /developers/area_registry_index.md --- 区域注册表(area registry)是 Home Assistant 跟踪区域的注册表。区域代表 Home Assistant 中的一个物理位置。它可以用来将设备放置在不同的区域。 | 属性 | 描述 | | --------- | ----------- | | id | 区域的唯一 ID(由 Home Assistant 生成) | name | 此区域的名称 | aliases | 区域的备用名称/别名 | floor\_id | 区域所属楼层的 ID | humidity\_entity\_id | 提供区域湿度的 entity ID | icon | 此区域的图标 | labels | 分配给区域的 label ID 集合 | picture | 此区域的图片 | temperature\_entity\_id | 提供区域温度的 entity ID | created\_at | 区域创建时的时间戳 | modified\_at | 区域最后修改时的时间戳 --- url: /developers/asyncio_101.md --- 如果你还不熟悉 asyncio,请观看下面的视频。这是 [Robert Smallshire][rob] 对 asyncio 如何以及为何以这种方式工作的一次很好的介绍。
[rob]: https://github.com/rob-smallshire --- url: /developers/asyncio_blocking_operations.md --- 在编写 asyncio 代码时,确保所有阻塞操作都在单独的线程中完成至关重要。如果阻塞操作发生在 event loop 中,在操作完成之前,其他什么都无法运行。因此,没有任何阻塞操作会发生在 event loop 中,因为整个系统将在阻塞操作的持续时间内停滞。 下面讨论了一些可能阻塞的操作的详细示例,例如网络 I/O 或重度计算。 :::tip 开发期间务必启用 [`asyncio` debug mode](https://docs.python.org/3/library/asyncio-dev.html#debug-mode) 和 [Home Assistant 内置的 debug mode](https://www.home-assistant.io/integrations/homeassistant/#debug),因为许多阻塞 I/O 错误可以自动检测。 ::: ## 解决 event loop 中的阻塞 I/O 你可能到达此页面是因为 Home Assistant 检测到并报告了 event loop 中的阻塞调用。从版本 2024.7.0 开始,Home Assistant 可以检测 event loop 中更多的阻塞操作,以防止系统不稳定。在 Home Assistant 能够检测这些错误之前,它们可能导致系统无响应或行为未定义。以下是纠正 event loop 中阻塞操作的一些提示。 ## 在 executor 中运行阻塞调用 在 Home Assistant 中,这通常通过调用 `await hass.async_add_executor_job` 来实现。在库代码中,通常使用 `await loop.run_in_executor(None, ...)`。请查阅 Python 关于[运行阻塞代码](https://docs.python.org/3/library/asyncio-dev.html#running-blocking-code)的文档,以获取避免陷阱的提示。某些特定调用可能需要不同的方法。 ```python from functools import partial def blocking_code(some_arg: str): ... def blocking_code_with_kwargs(kwarg: bool = False): ... # 在 Home Assistant 内部调用阻塞函数时 result = await hass.async_add_executor_job(blocking_code, "something") result = await hass.async_add_executor_job(partial(blocking_code_with_kwargs, kwarg=True)) # 在库代码中调用阻塞函数时 loop = asyncio.get_running_loop() result = await loop.run_in_executor(None, blocking_code, "something") result = await loop.run_in_executor(None, partial(blocking_code_with_kwargs, kwarg=True)) ``` ### 特定函数调用 根据检测到的阻塞调用类型,解决方案可能更为复杂。 #### open `open` 执行阻塞磁盘 I/O,应使用上述标准方法在 executor 中运行。 :::warning 当修复在 event loop 中运行的 `open` 调用时,所有的阻塞读取和写入操作也必须修复为在 executor 中发生。Home Assistant 只能检测 `open` 调用,无法检测阻塞的读取和写入,这意味着如果阻塞的读取和写入调用没有在修复 `open` 调用的同时一并修复,它们可能会在很长时间内困扰集成用户,因为它们将非常难以发现。 ::: #### import\_module 参见 [使用 asyncio 导入代码](/developers/asyncio_imports.md) #### sleep 阻塞式的 sleep 应替换为 `await asyncio.sleep`。在 event loop 中报告最常见的阻塞 `sleep` 是 `pyserial-asyncio`,可以替换为 [`pyserial-asyncio-fast`](https://github.com/home-assistant-libs/pyserial-asyncio-fast),它没有这个问题。 #### putrequest urllib 执行阻塞 I/O,应使用上述标准方法在 executor 中运行。考虑将集成转换为使用 `aiohttp` 或 `httpx`。 #### glob `glob.glob` 执行阻塞磁盘 I/O,应使用上述标准方法在 executor 中运行。 #### iglob `glob.iglob` 执行阻塞磁盘 I/O,应使用上述标准方法在 executor 中运行。 #### walk `os.walk` 执行阻塞磁盘 I/O,应使用上述标准方法在 executor 中运行。 #### listdir `os.listdir` 执行阻塞磁盘 I/O,应使用上述标准方法在 executor 中运行。 #### scandir `os.scandir` 执行阻塞磁盘 I/O,应使用上述标准方法在 executor 中运行。 #### stat `os.stat` 执行阻塞磁盘 I/O,应使用上述标准方法在 executor 中运行。 #### write\_bytes `pathlib.Path.write_bytes` 执行阻塞磁盘 I/O,应使用上述标准方法在 executor 中运行。 #### write\_text `pathlib.Path.write_text` 执行阻塞磁盘 I/O,应使用上述标准方法在 executor 中运行。 #### read\_bytes `pathlib.Path.read_bytes` 执行阻塞磁盘 I/O,应使用上述标准方法在 executor 中运行。 #### read\_text `pathlib.Path.read_text` 执行阻塞磁盘 I/O,应使用上述标准方法在 executor 中运行。 #### load\_default\_certs `SSLContext.load_default_certs` 执行阻塞磁盘 I/O 以从磁盘加载证书。 以下辅助方法确保阻塞 I/O 将在 executor 中发生: * `aiohttp`:使用 `homeassistant.helpers.aiohttp_client.async_get_clientsession` 创建 `aiohttp.ClientSession`。 * `httpx`:使用 `homeassistant.helpers.httpx_client.get_async_client` 创建 `httpx.AsyncClient`。 * 通用 SSL:`homeassistant.util.ssl` #### load\_verify\_locations 参见 [SSLContext.load\_default\_certs](#load_default_certs) #### load\_cert\_chain 参见 [SSLContext.load\_default\_certs](#load_default_certs) #### set\_default\_verify\_paths 参见 [SSLContext.load\_default\_certs](#load_default_certs) --- url: /developers/asyncio_categorizing_functions.md --- Home Assistant 中的一项工作由将被调用的函数表示。它将在我们的 event loop 或我们的 thread pool 中运行,具体取决于它是否是 async safe。 Home Assistant 使用一种约定:所有必须在 event loop 内运行的函数都以 `async_` 为前缀。 ## 协程函数(Coroutine function) 协程是基于 Python 生成器语法的特殊函数,允许它们在等待结果时挂起执行。 调用协程函数将返回一个 Generator 对象,但实际上不会开始执行。当该对象被 await(从另一个协程中)或被调度到 event loop 上时,它将执行该任务。 要将函数声明为协程,在函数定义的 `def` 之前添加 `async`。 ```python async def async_look_my_coroutine(target): result = await entity.async_turn_on() if result: print(f"hello {target}") hass.loop.create_task(async_look_my_coroutine("world")) ``` 在这个示例中,我们通过调用 `hass.loop.create_task` 来调度协程。这会将协程添加到待执行任务队列中。当 event loop 运行 `async_look_my_coroutine` 时,在调用 `await entity.async_turn_on()` 时会挂起该任务。此时会调度一个新任务来执行 `entity.async_turn_on()`。当该任务执行完毕后,`async_look_my_coroutine` 将恢复。 ## 回调函数(Callback function) 这是一种被认为在 event loop 内运行安全的普通函数。回调函数无法挂起自身,因此不能执行任何 I/O 或调用协程。回调函数可以调度新任务,但无法等待结果。 要将函数声明为回调,从 core 包中导入 callback 注解并注解你的函数。 在 Home Assistant 中,回调的一个常见用例是作为 event 或 service action 调用的监听器。它可以处理传入的信息,然后调度需要进行的正确调用。以下是来自自动化引擎的示例。 ```python from homeassistant.core import callback @callback def async_trigger_service_handler(service_call): """处理自动化触发器 service action 调用。""" vars = service_call.data.get(ATTR_VARIABLES) for entity in component.async_extract_from_service(service_call): hass.loop.create_task(entity.async_trigger(vars, True)) ``` 在这个示例中,`entity.async_trigger` 是一个协程函数。调用协程函数将返回一个协程任务。传入的参数将在任务执行时使用。 要执行任务,我们需要将其调度到 event loop 上执行。这是通过调用 `hass.loop.create_task` 完成的。 ### 为什么还要有回调? 你可能想知道,如果协程能做回调能做的所有事情,为什么还要有回调。原因是性能和 core API 对象更好的状态一致性。 当协程 A 等待协程 B 时,它会挂起自身并调度一个新任务来运行 B。这意味着 event loop 现在运行 A、B,然后再运行 A。如果 B 是回调函数,A 永远不需要挂起自身,因此 event loop 只需运行 A。一致性方面的影响是,其他排队在 event loop 上运行的事件将继续等待直到回调完成,但在让出给另一个协程时将被交错。 ## Event loop 和线程安全 这些函数在 thread 和 event loop 内运行都是安全的。这些函数通常执行计算或在内存中转换数据。任何执行 I/O 的操作都不属于此类别。许多标准库函数都属于此类别。例如使用 sum 生成一组数字的总和或合并两个字典。 没有特殊的注解来标记函数属于此类别,在从 event loop 内使用这些函数时应谨慎。如有疑问,请查看它们的实现。 ## 其他函数 这些都是不符合前面任何类别的函数。这些函数要么是线程安全的,要么被认为在 event loop 内运行不安全。这些是使用 sleep 或执行 I/O 的函数。 被归入此类别不需要特殊注解。 --- url: /developers/asyncio_imports.md --- 在使用 asyncio 时,确定何时可以安全地导入代码可能很棘手,因为需要考虑两个约束: * 导入代码可能会执行阻塞 I/O 来从磁盘加载文件 * 在 [cpython 中导入代码不是线程安全的](https://github.com/python/cpython/issues/83065) ## 模块级导入 如果你的导入在**模块级**(也称为**顶层导入**),并且所有必要的模块都在 `__init__.py` 中导入,Home Assistant 将在 **event loop 启动之前** 或在后台线程中使用 **import executor** 加载你的集成。 在这种情况下,你的导入通常会被安全地处理,所以你**不需要担心**它们是否是 event-loop safe。 ## 模块级之外的导入 如果你的导入不是在模块级进行的,你必须仔细考虑每个导入,因为导入机制需要从磁盘读取模块,这会执行阻塞 I/O。如果可能的话,通常最好改为模块级导入,因为它避免了大量复杂性和出错风险。导入模块既消耗 CPU,又涉及阻塞 I/O,因此确保这些操作在 executor 中执行至关重要。 如果你能确定模块已经被导入,那么使用裸 [`import`](https://docs.python.org/3/reference/simple_stmts.html#import) 语句是安全的,因为 Python 不会再次加载模块。 如果集成将始终使用该模块,通常最好在 `__init__.py` 中包含模块级导入,以确保模块被加载。然而,如果这导致循环导入,则需要改用下面解决方案之一。 如果模块仅在条件性使用时才会导入,并且只会在一个地方导入,则可以使用标准的 executor 调用: * 对于 Home Assistant 内部的导入:`hass.async_add_executor_job(_function_that_does_late_import)` * 对于 Home Assistant 外部的导入:[`loop.run_in_executor(None, _function_that_does_late_import)`](https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.run_in_executor) 如果同一个模块可能在应用程序的不同部分并发导入,请使用线程安全的 `homeassistant.helpers.importlib.import_module` 辅助函数。 如果模块可能从多个不同路径导入,请使用 `async_import_module`: 示例: ```python from homeassistant.helpers.importlib import async_import_module platform = await async_import_module(hass, f"homeassistant.components.homeassistant.triggers.{platform_name}") ``` ## 确定模块是否已加载 如果你不确定模块是否已经加载,可以检查模块是否已经在 [`sys.modules`](https://docs.python.org/3/library/sys.html#sys.modules) 中。你应该知道,模块一旦开始加载就会出现在 `sys.modules` 中,并且 [cpython 的导入不是线程安全的](https://github.com/python/cpython/issues/83065)。因此,当代码可能从多个路径导入时,考虑竞态条件非常重要。 ## 避免仅用于类型检查的导入 如果导入的模块仅用于类型检查,建议用 `if TYPE_CHECKING:` 块对其进行保护,以避免在运行时导入。 ```python from typing import TYPE_CHECKING if TYPE_CHECKING: from some_module import SomeClass # 仅用于类型检查时导入 def some_function() -> SomeClass: # 函数实现 pass ``` ## 避免导入很少使用的代码 导入模块既可能消耗 CPU 也可能消耗 I/O,因此避免导入很少使用的代码非常重要。虽然在模块级之外导入代码确实会增加一些运行时开销,但当代码仅在偶尔需要时才需要时,这种方法通常更高效。通过延迟导入,确保资源仅在必要时使用,减少不必要的处理并提高整体性能。 --- url: /developers/asyncio_index.md --- 2016 年 9 月 29 日,我们在双周发布计划中发布了 [Home Assistant 0.29][0.29]。该版本引入了由 [Ben Bangert][ben] 主导的 core 全面改造。 旧的 core 像传统的线程应用一样设置。每个非线程安全的资源(例如 entity 的状态)都会受到锁的保护。这导致了大量等待和潜在的不一致性,因为一个任务可能在执行一半时等待,直到某个资源被释放。 我们的新 core 基于 Python 内置的 **asyncio** 模块。不再让所有线程都能访问 core API 对象,现在访问仅限于一个称为 *event loop* 的特殊线程。所有组件现在都会将自己调度为一个由 event loop 执行的任务。这保证了同时只有一个任务在执行,意味着我们不再需要任何锁。 将所有内容放在 event loop 内运行的唯一问题是,当任务执行阻塞 I/O 时;大多数第三方 Python 库都会这样做。例如,在向设备请求新信息时,core 将停止运行,直到我们收到设备的响应。为了处理这个问题,任务可以挂起自身,直到响应可用,然后将其排入 event loop 以处理结果。 为了使任务能够挂起自身,它所调用的所有代码都必须支持此功能。实际上,这意味着每个设备集成都需要对提供该集成的库进行完整重写!由于这是永远无法实现的事情,因此添加了一个 100% 向后兼容的 API,这样就没有平台需要更新。 向后兼容的 API 会在不同的线程中调度任务,并阻塞该线程,直到 event loop 处理完该任务。 [0.29]: https://www.home-assistant.io/blog/2016/09/29/async-sleepiq-emoncms-stocks/ [ben]: https://github.com/bbangert/ --- url: /developers/asyncio_thread_safety.md --- 使用 asyncio 开发需要仔细关注线程安全,因为几乎所有 asyncio 对象都不是线程安全的。如果你刚刚开始使用 asyncio,请查阅 Python 关于 [使用 asyncio 开发](https://docs.python.org/3/library/asyncio-dev.html) 的文档,以获取避免陷阱的提示。 Home Assistant 有一些在同一个代码库中处理 async 和非 async 代码的约定。主要要点如下: * 从 helper 调用函数时如何运行取决于它是否使用了 `@callback` 修饰,以表明它不会阻塞且在 event loop 中运行是安全的;更多详情请参见 [处理 Async](/developers/asyncio_working_with_async.md)。 * 大多数 API 在从线程调用函数时都有同步和异步版本。async API 以 `async_` 为前缀。例如,在从 event loop 之外的线程触发 event 时,使用 `hass.bus.fire` 而不是 `hass.bus.async_fire`。 :::tip 开发期间务必启用 [`asyncio` debug mode](https://docs.python.org/3/library/asyncio-dev.html#debug-mode) 和 [Home Assistant 内置的 debug mode](https://www.home-assistant.io/integrations/homeassistant/#debug),因为许多线程安全错误可以自动检测。 ::: ## 解决线程安全错误 你可能到达此页面是因为 Home Assistant 检测到并报告了线程安全错误。从版本 2024.5.0 开始,Home Assistant 可以检测、报告并阻止一些非线程安全操作,以防止系统不稳定。在 Home Assistant 能够检测这些错误之前,它们可能导致意外重启或未定义行为,因为它们会破坏内部 asyncio 状态。以下是纠正非线程操作的一些提示。 ## 确保代码在正确的线程中运行 ### 接受 callback 的内置 helper 使用 Home Assistant 的内置 helper(如 `event.async_track_state_change_event` 或 `event.track_state_change_event`)时,重要的是根据代码运行在哪个线程来调用正确的 API。如果代码运行在 event loop 之外的线程中,请使用非 `async` 版本。 在下面的示例中,所有内容都将在 event loop 线程中运行,当 `async_track_state_change_event` 触发时,`async_update_event_state_callback` 也将在 event loop 线程中运行,因为它使用了 `@callback` 修饰。如果缺少 `@callback` 修饰器,`async_update_event_state_callback` 将在 executor 中运行,从而对 `async_write_ha_state` 进行非线程安全调用。 ```python async def async_added_to_hass(self) -> None: """Entity 已被添加到 hass。""" self.async_on_remove( async_track_state_change_event( self.hass, ["light.other"], self.async_update_event_state_callback, ) ) @callback def async_update_event_state_callback(self, event: Event[EventStateChangedData]) -> None: """Entity 状态更改时调用。""" new_state = event.data["new_state"] if new_state is None or new_state.state in (STATE_UNAVAILABLE, STATE_UNKNOWN): return self.async_write_ha_state() ``` ### 特定 API 调用 你可能会发现需要从 event loop 线程之外的线程调用其中一个 async API 调用。在大多数情况下,`hass.add_job` 可以安全地从其他线程调用 async API。一些 helper 有特定的同步 API 用于从其他线程调用。下面是常用的 async API 及其从其他线程调用的方法的列表。 #### hass.async\_create\_task 在从 event loop 线程之外的线程创建任务时,请改用 `hass.create_task` #### hass.bus.async\_fire 在从 event loop 线程之外的线程触发 event 时,请改用 `hass.bus.fire` #### hass.services.async\_register 在从 event loop 线程之外的线程注册 service action 时,请改用 `hass.services.register` #### hass.services.async\_remove 在从 event loop 线程之外的线程移除 service action 时,请改用 `hass.services.remove` #### async\_write\_ha\_state 在从 event loop 线程之外的线程写入 entity 状态时,请改用 `self.schedule_update_ha_state` #### hass.config\_entries.async\_update\_entry 更新 config entry 必须在 event loop 线程中完成。没有同步的 API 来更新 config entry。如果调用函数在另一个线程中运行不是错误,请使用 `hass.add_job` 在 event loop 中调度一个调用 `hass.config_entries.async_update_entry` 的函数。 #### async\_dispatcher\_send 在从 event loop 线程之外的线程调用 dispatcher 时,请改用 `dispatcher_send`。 #### async\_render\_to\_info 模板必须在 event loop 线程中渲染。没有同步的 API 来渲染模板。使用 `hass.add_job` 在 event loop 中调度一个调用 `async_render_to_info` 的函数。 #### area\_registry.async\_create 区域注册表必须在 event loop 线程中修改。区域注册表没有同步的 API。使用 `hass.add_job` 在 event loop 中调度一个调用 `area_registry.async_create` 的函数。 #### area\_registry.async\_delete 区域注册表必须在 event loop 线程中修改。区域注册表没有同步的 API。使用 `hass.add_job` 在 event loop 中调度一个调用 `area_registry.async_delete` 的函数。 #### area\_registry.async\_update 区域注册表必须在 event loop 线程中修改。区域注册表没有同步的 API。使用 `hass.add_job` 在 event loop 中调度一个调用 `area_registry.async_update` 的函数。 #### category\_registry.async\_create 分类注册表必须在 event loop 线程中修改。分类注册表没有同步的 API。使用 `hass.add_job` 在 event loop 中调度一个调用 `category_registry.async_create` 的函数。 #### category\_registry.async\_delete 分类注册表必须在 event loop 线程中修改。分类注册表没有同步的 API。使用 `hass.add_job` 在 event loop 中调度一个调用 `category_registry.async_delete` 的函数。 #### category\_registry.async\_update 分类注册表必须在 event loop 线程中修改。分类注册表没有同步的 API。使用 `hass.add_job` 在 event loop 中调度一个调用 `category_registry.async_update` 的函数。 #### device\_registry.async\_update\_device 设备注册表必须在 event loop 线程中修改。设备注册表没有同步的 API。使用 `hass.add_job` 在 event loop 中调度一个调用 `device_registry.async_update_device` 的函数。 #### device\_registry.async\_remove\_device 设备注册表必须在 event loop 线程中修改。设备注册表没有同步的 API。使用 `hass.add_job` 在 event loop 中调度一个调用 `device_registry.async_remove_device` 的函数。 #### entity\_registry.async\_get\_or\_create Entity 注册表必须在 event loop 线程中修改。Entity 注册表没有同步的 API。使用 `hass.add_job` 在 event loop 中调度一个调用 `entity_registry.async_get_or_create` 的函数。 #### entity\_registry.async\_remove Entity 注册表必须在 event loop 线程中修改。Entity 注册表没有同步的 API。使用 `hass.add_job` 在 event loop 中调度一个调用 `entity_registry.async_remove` 的函数。 #### entity\_registry.async\_update\_entity Entity 注册表必须在 event loop 线程中修改。Entity 注册表没有同步的 API。使用 `hass.add_job` 在 event loop 中调度一个调用 `entity_registry.async_update_entity` 的函数。 #### floor\_registry.async\_create 楼层注册表必须在 event loop 线程中修改。楼层注册表没有同步的 API。使用 `hass.add_job` 在 event loop 中调度一个调用 `floor_registry.async_create` 的函数。 #### floor\_registry.async\_delete 楼层注册表必须在 event loop 线程中修改。楼层注册表没有同步的 API。使用 `hass.add_job` 在 event loop 中调度一个调用 `floor_registry.async_delete` 的函数。 #### floor\_registry.async\_update 楼层注册表必须在 event loop 线程中修改。楼层注册表没有同步的 API。使用 `hass.add_job` 在 event loop 中调度一个调用 `floor_registry.async_update` 的函数。 #### issue\_registry.async\_get\_or\_create 问题注册表必须在 event loop 线程中修改。请改用 `issue_registry.create_issue`。 #### issue\_registry.async\_delete 问题注册表必须在 event loop 线程中修改。请改用 `issue_registry.delete_issue`。 #### issue\_registry.async\_ignore 问题注册表必须在 event loop 线程中修改。问题注册表没有同步的 API 来忽略 issue。使用 `hass.add_job` 在 event loop 中调度一个调用 `issue_registry.async_ignore_issue` 的函数。 #### label\_registry.async\_create 标签注册表必须在 event loop 线程中修改。标签注册表没有同步的 API。使用 `hass.add_job` 在 event loop 中调度一个调用 `label_registry.async_create` 的函数。 #### label\_registry.async\_delete 标签注册表必须在 event loop 线程中修改。标签注册表没有同步的 API。使用 `hass.add_job` 在 event loop 中调度一个调用 `label_registry.async_delete` 的函数。 #### label\_registry.async\_update 标签注册表必须在 event loop 线程中修改。标签注册表没有同步的 API。使用 `hass.add_job` 在 event loop 中调度一个调用 `label_registry.async_update` 的函数。 --- url: /developers/asyncio_working_with_async.md --- 虽然我们有向后兼容的 API,但直接使用 async core 会快得多。大多数核心组件已经改写为利用 async core。这包括 EntityComponent 助手(light、switch 等的基础)、scripts、groups 和 automation。 ## 与 core 交互 Home Assistant core 中的所有方法都有两种实现:异步版本和从其他线程调用的版本。其他版本只是以线程安全的方式调用 async 版本的包装器。 因此,如果你从回调或协程内部对 core(即 hass 对象)进行调用,请使用以 async\_ 开头的方法。如果你需要调用作为协程的 async\_ 函数,你的 task 也必须是协程。 ## 实现异步 component 要使 component 变为异步,实现 async\_setup 即可。 ```python def setup(hass, config): """Set up component.""" # Code for setting up your component outside of the event loop. ``` 变成: ```python async def async_setup(hass, config): """Set up component.""" # Code for setting up your component inside of the event loop. ``` ## 实现异步 platform 对于 platforms,我们支持异步 setup。将 `setup_platform` 改为协程 `async_setup_platform`。 ```python def setup_platform(hass, config, add_entities, discovery_info=None): """Set up platform.""" # Code for setting up your platform outside of the event loop. ``` 变成: ```python async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): """Set up platform.""" # Code for setting up your platform inside of the event loop. ``` 与原参数的唯一区别是,`add_entities` 函数被替换为异步友好的回调 `async_add_entities`。 ## 实现异步 entity 通过将 update 方法转换为异步,可以使你的 entity 支持异步。这要求你的 entity 的依赖项也必须支持异步! ```python class MyEntity(Entity): def update(self): """Retrieve latest state.""" self._state = fetch_state() ``` 变成: ```python class MyEntity(Entity): async def async_update(self): """Retrieve latest state.""" self._state = await async_fetch_state() ``` 确保你的 entity 上定义的所有 properties 不会导致执行 I/O。所有数据必须在 update 方法内部获取并缓存在 entity 上。这是因为这些 properties 在 event loop 内部被读取,执行 I/O 会导致 Home Assistant core 等待你的 I/O 完成。 ## 从线程中调用异步函数 有时你可能在某个线程中,需要调用一个仅提供异步版本的函数。Home Assistant 包含一些异步辅助工具来帮助处理这种情况。 在以下示例中,`say_hello` 将调度 `async_say_hello` 并阻塞直到函数运行并获取结果。 ```python import asyncio def say_hello(hass, target): return asyncio.run_coroutine_threadsafe( async_say_hello(hass, target), hass.loop ).result() async def async_say_hello(hass, target): return f"Hello {target}!" ``` **警告:** 请小心!如果 async 函数使用了 executor jobs,可能导致死锁。 ## 从异步上下文中调用同步函数 如果你在异步上下文中运行,有时可能需要调用同步函数。方法如下: ```python # hub.update() 是同步函数。 result = await hass.async_add_executor_job(hub.update) ``` ## 从异步上下文中启动独立 task 如果你希望生成一个不会阻塞当前异步上下文的 task,可以将其作为 event loop 上的 task 创建。它将与当前执行并行运行。 ```python hass.async_create_task(async_say_hello(hass, target)) ``` --- url: /developers/auth_api.md --- 本页将描述你的应用程序对 Home Assistant 实例进行授权和集成所需的步骤。[查看演示](https://hass-auth-demo.glitch.me),由我们的 helper lib [home-assistant-js-websocket](https://github.com/home-assistant/home-assistant-js-websocket) 提供支持。 每个用户都有自己的 Home Assistant 实例,这使每个用户能够控制自己的数据。然而,我们也希望使第三方开发者能够轻松创建允许用户与 Home Assistant 集成的应用程序。为此,我们采用了 [OAuth 2 规范][oauth2-spec],并结合 [OAuth 2 IndieAuth 扩展][indieauth-spec] 来生成客户端。 ## 客户端(Clients) 在你请求用户将其实例与你的应用程序授权之前,你需要一个客户端。在传统的 OAuth2 中,服务器需要在用户授权之前生成客户端。然而,由于每个服务器都属于一个用户,我们采用了与 [IndieAuth][indieauth-clients] 略有不同的方法。 你需要使用的 client ID 是你应用程序的网站。redirect URI 必须与 client ID 使用相同的主机和端口。例如: * client ID:`https://www.my-application.io` * redirect URI:`https://www.my-application.io/hass/auth_callback` 如果你需要不同的 redirect URI(例如在构建原生应用时),你可以在你的应用程序网站(即 client ID)的内容中添加一个 HTML 标签,包含已批准的 redirect URI。例如,将此添加到你的站点以允许 redirect URI `hass://auth`: ```html ``` Home Assistant 将扫描网站的前 10kB 以查找 link 标签。 ## 授权(Authorize) 各部分之间如何交互的概览 :::info 此处所有示例 URL 为显示目的添加了额外的空格和换行。 ::: Authorize URL 应包含 `client_id` 和 `redirect_uri` 作为查询参数。 ```txt http://your-instance.com/auth/authorize? client_id=https%3A%2F%2Fhass-auth-demo.glitch.me& redirect_uri=https%3A%2F%2Fhass-auth-demo.glitch.me%2F%3Fauth_callback%3D1 ``` 你还可以选择包含一个 `state` 参数,它将被添加到 redirect URI 中。state 非常适合存储你正在认证的实例 URL。示例: ```txt http://your-instance.com/auth/authorize? client_id=https%3A%2F%2Fhass-auth-demo.glitch.me& redirect_uri=https%3A%2F%2Fhass-auth-demo.glitch.me%2Fauth_callback& state=http%3A%2F%2Fhomeassistant.local ``` 用户将导航到该链接,并看到登录并授权你的应用程序的说明。一旦授权,用户将被重定向回传入的 redirect URI,其中包含 authorization code 和 state 作为查询参数的一部分。示例: ```txt https://hass-auth-demo.glitch.me/auth_callback? code=12345& state=http%3A%2F%2Fhomeassistant.local ``` 这个 authorization code 可以通过将其发送到 token 端点来交换为 tokens(见下一节)。 ## Token Token 端点在给定有效 grant 时返回 tokens。该 grant 是从 authorize 端点获取的 authorization code 或 refresh token。在 refresh token 的情况下,token 端点还能够撤销 token。 与该端点的所有交互都需要向 `http://your-instance.com/auth/token` 发送 HTTP POST 请求,并使用 `application/x-www-form-urlencoded` 编码请求体。 ### Authorization code :::tip 所有对 token 端点的请求必须包含与将用户重定向到 authorize 端点时使用的完全相同的 client ID。 ::: 在用户成功完成 authorize 步骤后,使用 grant type `authorization_code` 获取 tokens。请求体为: ```txt grant_type=authorization_code& code=12345& client_id=https%3A%2F%2Fhass-auth-demo.glitch.me ``` 返回的响应将是一个 access token 和 refresh token: ```json { "access_token": "ABCDEFGH", "expires_in": 1800, "refresh_token": "IJKLMNOPQRST", "token_type": "Bearer" } ``` Access token 是一个短期有效的 token,可用于访问 API。Refresh token 可用于获取新的 access token。`expires_in` 值是 access token 有效的秒数。 如果发出了无效请求,将返回 HTTP 状态码 400。如果为非活动用户请求 token,HTTP 状态码将为 403。 ```json { "error": "invalid_request", "error_description": "Invalid client id", } ``` ### Refresh token 一旦通过 grant type `authorization_code` 获取了 refresh token,你就可以使用它来获取新的 access token。请求体为: ```txt grant_type=refresh_token& refresh_token=IJKLMNOPQRST& client_id=https%3A%2F%2Fhass-auth-demo.glitch.me ``` 返回的响应将是一个 access token: ```json { "access_token": "ABCDEFGH", "expires_in": 1800, "token_type": "Bearer" } ``` 如果发出了无效请求,将返回 HTTP 状态码 400。 ```json { "error": "invalid_request", "error_description": "Invalid client id", } ``` ### 撤销 refresh token :::tip 撤销 refresh token 不需要 `client_id` ::: 要撤销 refresh token,请向 `http://your-instance.com/auth/revoke` 发送 HTTP POST 请求,并使用 `application/x-www-form-urlencoded` 编码请求体。撤销 refresh token 将立即撤销该 refresh token 以及它曾经授予的所有 access token。请求体为: ```txt token=IJKLMNOPQRST ``` 请求将始终返回空响应体和 HTTP 状态 200,无论请求是否成功。 以前,撤销是通过向 token 端点(`/auth/token`)发送 `action=revoke` 来完成的。此形式已弃用,但为了向后兼容仍然有效: ```txt token=IJKLMNOPQRST& action=revoke ``` ## 长期 access token 长期 access token 的有效期为 10 年。它们适用于与第三方 API 和 webhook 风格的集成。长期 access token 可以在用户 Home Assistant 个人资料页面底部的 **"Long-Lived Access Tokens"** 部分中创建。 你还可以使用 WebSocket 命令 `auth/long_lived_access_token` 生成长期 access token,它将为当前用户创建一个长期 access token。Access token 字符串不会保存在 Home Assistant 中;你必须将其记录在安全的地方。 ```json { "id": 11, "type": "auth/long_lived_access_token", "client_name": "GPS Logger", "lifespan": 365 } ``` 响应包含一个长期 access token: ```json { "id": 11, "type": "result", "success": true, "result": "ABCDEFGH" } ``` ## 发起经过认证的请求 一旦你有了 access token,你就可以向 Home Assistant API 发起经过认证的请求。 对于 WebSocket 连接,在 [authentication message](/developers/api/websocket.md#authentication-phase) 中传递 access token。 对于 HTTP 请求,将 token type 和 access token 作为 authorization header 传递: ```http Authorization: Bearer ABCDEFGH ``` ### 示例:cURL ```shell curl -X GET \ https://your.awesome.home/api/error/all \ -H 'Authorization: Bearer ABCDEFGH' ``` ### 示例:Python ```python import requests url = "https://your.awesome.home/api/error/all" headers = { "Authorization": "Bearer ABCDEFGH", } response = requests.request("GET", url, headers=headers) print(response.text) ``` ### 示例:NodeJS ```javascript fetch('https://your.awesome.home/api/error/all', { headers: { Authorization: 'Bearer ABCDEFGH' } }).then(function (response) { if (!response.ok) { return Promise.reject(response); } return response.text(); }).then(function (body ) { console.log(body); }); ``` 如果 access token 不再有效,你将收到 HTTP 状态码 401 unauthorized 的响应。这意味着你需要刷新 token。如果 refresh token 不起作用,说明 token 已不再有效,用户已登出。你应该清除用户数据并请求用户重新授权。 [oauth2-spec]: https://tools.ietf.org/html/rfc6749 [indieauth-spec]: https://indieauth.spec.indieweb.org/ [indieauth-clients]: https://indieauth.spec.indieweb.org/#client-identifier ## 签名路径(Signed paths) 有时你希望用户向 Home Assistant 发起 GET 请求以下载数据。在这种情况下,普通的认证系统无法满足要求,因为我们无法将用户与带有认证头的 API 关联起来。在这种情况下,签名路径可以帮助。 签名路径是我们服务器上的一个普通路径,如 `/api/states`,但附加了安全认证签名。用户可以导航到该路径,并将作为创建签名路径的 access token 进行授权。签名路径可以通过 WebSocket 连接创建,并且设计为短期有效。默认过期时间为 30 秒。 有两种方式获取签名路径。 如果你正在创建集成,请从 `homeassistant.components.http.auth` 导入 `async_sign_path`。该方法在从 HTTP 请求或 WebSocket 连接的上下文中调用时,会自动采用 refresh token。如果两者都不可用(例如,因为它在一个自动化内部),它将使用一个特殊的 "Home Assistant Content" 用户。 如果你正在处理前端,你可以使用以下 WebSocket 命令创建签名路径: ```js { "type": "auth/sign_path", "path": "/api/states", // 可选,过期时间以秒为单位。默认为 30 秒 "expires": 20 } ``` 响应将包含签名路径: ```js { "path": "/api/states?authSig=ABCDEFGH" } ``` 关于签名路径的注意事项: * 如果 refresh token 被删除,签名 URL 将不再有效。 * 如果用户被删除,签名 URL 将不再有效(因为 refresh token 将被删除)。 * 如果 Home Assistant 重启,签名 URL 将不再有效。 * 访问仅在收到请求时验证。如果响应耗时超过过期时间(例如下载大文件),下载将在过期时间过去后继续进行。 --- url: /developers/auth_auth_module.md --- 多因素认证模块与[认证提供程序](/developers/auth_auth_provider.md)结合使用,以提供完全可配置的认证框架。每个 MFA 模块可以提供一种多因素认证功能。用户可以启用多个 mfa 模块,但在登录过程中只能选择一个模块。 ## 定义 mfa auth module :::info 我们目前仅支持内置的 mfa auth module。对自定义 auth module 的支持将来可能会推出。 ::: 多因素 Auth 模块定义在 `homeassistant/auth/mfa_modules/<模块名称>.py` 中。Auth 模块需要提供 `MultiFactorAuthModule` 类的实现。 有关完全实现的 auth module 示例,请参见 [insecure\_example.py](https://github.com/home-assistant/core/blob/dev/homeassistant/auth/mfa_modules/insecure_example.py)。 多因素 Auth 模块应扩展 `MultiFactorAuthModule` 类的以下方法。 | 方法 | 必填 | 描述 | ------ | -------- | ----------- | `@property def input_schema(self)` | 是 | 返回定义用户输入表单的 schema。 | `async def async_setup_flow(self, user_id)` | 是 | 返回一个 SetupFlow 来处理设置流程。 | `async def async_setup_user(self, user_id, setup_data)` | 是 | 为用户设置此 auth module。 | `async def async_depose_user(self, user_id)` | 是 | 从此 auth module 中移除用户信息。 | `async def async_is_user_setup(self, user_id)` | 是 | 返回用户是否已设置。 | `async def async_validate(self, user_id, user_input)` | 是 | 给定 user\_id 和用户输入,返回验证结果。 | `async def async_initialize_login_mfa_step(self, user_id)` | 否 | 将在显示登录流程的 mfa 步骤之前调用一次。这不是 MFA 模块的初始化,而是登录流程中 mfa 步骤的初始化。 ## 设置流程(Setup flow) 在用户使用多因素 auth module 之前,必须启用或设置它。所有可用模块将列在用户个人资料页面中,用户可以启用他/她想使用的模块。设置数据录入流程将引导用户完成必要的步骤。 每个 MFA 模块都需要实现一个从 `mfa_modules.SetupFlow` 扩展的设置流程处理器(如果只需要一个简单设置步骤,可以直接使用 `SetupFlow`)。例如对于 Google Authenticator(TOTP,基于时间的一次性密码)模块,流程需要是: * 生成一个密钥并将其存储在设置流程实例上 * 通过 `async_show_form` 返回一个描述中包含二维码的表单(通过 `description_placeholders` 以 base64 注入) * 用户扫描二维码并输入代码以验证扫描正确且时钟已同步 * TOTP 模块保存密钥和用户\_id,模块为用户启用 ## 工作流程(Workflow) 多因素认证工作流程 ## 配置示例 ```yaml # configuration.xml homeassistant: auth_providers: - type: homeassistant - type: legacy_api_password auth_mfa_modules: - type: totp - type: insecure_example users: [{'user_id': 'a_32_bytes_length_user_id', 'pin': '123456'}] ``` 在这个示例中,用户将首先从 `homeassistant` 或 `legacy_api_password` auth provider 中选择。对于 `homeassistant` auth provider,用户将首先输入用户名/密码,如果该用户同时启用了 `totp` 和 `insecure_example`,则用户需要选择一个 auth module,然后根据选择输入 Google Authenticator 代码或输入 pin 代码。 :::tip `insecure_example` 仅用于演示目的,请勿在生产环境中使用。 ::: ## 验证会话(Validation session) 与 auth provider 不同,auth module 使用 session 来管理验证。在 auth provider 验证之后,mfa module 将创建一个验证会话,包含过期时间和来自 auth provider 验证结果的 user\_id。多因素 auth module 不仅验证用户输入,还验证 session 是否未过期。验证会话数据存储在你的配置目录中。 --- url: /developers/auth_auth_provider.md --- 认证提供程序确认用户的身份。用户通过 auth provider 的登录流程来证明其身份。Auth provider 定义登录流程,并要求用户提供所需的所有信息。这通常是用户名和密码,但也可以包括 2FA token 或其他挑战。 一旦认证提供程序确认了用户的身份,它将以 Credentials 对象的形式将其传递给 Home Assistant。 ## 定义 auth provider :::info 我们目前仅支持内置的 auth provider。对自定义 auth provider 的支持将来可能会推出。 ::: Auth 提供程序定义在 `homeassistant/auth/providers/<提供程序名称>.py` 中。Auth 提供程序模块需要提供 `AuthProvider` 类和 `LoginFlow` 类的实现,它根据 `data_entry_flow` 向用户询问信息并对其进行验证。 有关完全实现的 auth provider 示例,请参见 [insecure\_example.py](https://github.com/home-assistant/core/blob/dev/homeassistant/auth/providers/insecure_example.py)。 Auth 提供程序应扩展 `AuthProvider` 类的以下方法。 | 方法 | 必填 | 描述 | ------ | -------- | ----------- | async def async\_login\_flow(self, context: AuthFlowContext | None) | 是 | 返回一个登录流程实例,供用户进行身份识别。 | async def async\_get\_or\_create\_credentials(self, flow\_result) | 是 | 给定登录流程的结果,返回一个 credentials 对象。它可以是现有的或新的。 | async def async\_user\_meta\_for\_credentials(credentials) | 否 | 回调,当 Home Assistant 将从 Credentials 对象创建用户时调用。可用于为用户填充额外字段。 Auth 提供程序应扩展 `LoginFlow` 类的以下方法。 | 方法 | 必填 | 描述 | ------ | -------- | ----------- | async def async\_step\_init(self, user\_input=None) | 是 | 处理登录表单,更多详细信息见下文。 ## LoginFlow 的 async\_step\_init :::info 我们可能在未来不久更改此接口。 ::: `LoginFlow` 继承自 `data_entry_flow.FlowHandler`。数据录入流程的第一步硬编码为 `init`,因此每个流程都必须实现 `async_step_init` 方法。`async_step_init` 的模式类似于以下伪代码: ```python async def async_step_init(self, user_input=None): if user_input is None: return self.async_show_form( step_id="init", data_schema="some schema to construct ui form" ) if is_invalid(user_input): return self.async_show_form(step_id="init", errors=errors) return await self.async_finish(user_input) ``` --- url: /developers/auth_index.md --- Home Assistant 拥有一个内置的身份验证系统,允许不同的用户与 Home Assistant 进行交互。身份验证系统由各个部分组成。 概述各部分如何交互 ## 身份验证提供方 身份验证提供方用于让用户进行身份认证。采用何种认证方式以及使用哪个后端,由身份验证提供方自行决定。默认情况下,我们启用了内置的 Home Assistant 身份验证提供方,它会将用户安全地存储在你的配置目录中。 Home Assistant 将使用哪些身份验证提供方,是在 `configuration.yaml` 中指定的。可以同时启用多个同一身份验证提供方实例。在这种情况下,每个实例会通过一个唯一的标识符来识别。相同类型的身份验证提供方之间不会共享凭证。 ## 凭证 凭证用于存储用户在特定身份验证提供方处的认证信息。它在用户成功认证时产生。它会允许系统在系统中找到该用户。如果用户不存在,则会创建一个新的用户。该用户不会被激活,而需要管理员(owner)的批准。 一个用户可以关联多个凭证。但是,对于每个特定的身份验证提供方,它只能拥有一个凭证。 ## 用户 每个人都是系统中的用户。要以特定用户登录,可以通过与该用户关联的任意一个身份验证提供方进行认证。用户登录时,会获得一个刷新令牌(refresh token)和一个访问令牌(access token),用于向 Home Assistant 发起请求。 ### Owner 在引导(onboarding)过程中创建的用户会被标记为"owner"。owner 可以管理其他用户,并且始终拥有所有权限的访问权。 ## 群组 用户属于一个或多个群组。群组身份是用户被授予权限的方式。 ## 权限策略 这是描述某个群组可以访问哪些资源的权限策略。有关权限和策略的更多信息,请参阅 [权限](/developers/auth_permissions.md)。 ## 访问令牌和刷新令牌 希望访问 Home Assistant 的应用程序会要求用户启动一个授权流程。当用户成功通过 Home Assistant 授权该应用程序时,该流程会产生一个授权码。此代码可用于获取访问令牌和刷新令牌。访问令牌的有效期有限,而刷新令牌会保持有效,直到用户删除它为止。 访问令牌用于访问 Home Assistant API。刷新令牌用于获取新的有效访问令牌。 ### 刷新令牌类型 刷新令牌有三种不同的类型: * *Normal*:这些令牌在用户授权应用程序时生成。应用程序会代表用户持有这些令牌。 * *Long-lived Access Token*:这些是支持长期访问令牌的刷新令牌。它们是在内部创建的,永远不会暴露给用户。 * *System*:这些令牌仅限于系统用户(如 Home Assistant OS 和 Supervisor)生成和使用。它们永远不会暴露给用户。 --- url: /developers/auth_permissions.md --- Permissions 限制用户可以访问或控制的内容。Permissions 附加到 groups 上,用户可以成为其成员。用户所属的所有 groups 的 permissions 合并后,决定用户可以查看或控制什么。 Permissions 不适用于被标记为 "owner" 的用户。该用户将始终拥有对一切的访问权限。 ## 通用权限结构 Policies 是字典,在根级别由不同类别的 permissions 组成。在当前的实现中,这仅限于 entities。 ```python { "entities": { # … } } ``` 每个 category 可以进一步拆分为描述该 category 各部分的 subcategories。 ```python { "entities": { "domains": { # … }, "entity_ids": { # … }, } } ``` 如果某个 category 被省略,用户将没有该 category 的权限。 在定义 policy 时,任何位置的任何字典值都可以用 `True` 或 `None` 替换。`True` 表示授予权限,`None` 表示使用默认值,即拒绝访问。 ## 实体 Entity permissions 可以通过 `entity_ids`、`device_ids`、`area_ids` 和 `domains` 这些 subcategories 在按 entity 和按 domain 的基础上进行设置。你可以通过将值设为 `True` 来授予所有访问权限,也可以使用 "read"、"control"、"edit" permissions 逐个指定每个 entity。 系统将按照 `entity_ids`、`device_ids`、`area_ids`、`domains`、`all` 的顺序返回第一个匹配的结果。 ```json { "entities": { "domains": { "switch": true }, "entity_ids": { "light.kitchen": { "read": true, "control": true } } } } ``` ## 合并策略 如果用户是多个 groups 的成员,这些 groups 的 permission policies 将在运行时合并为一个单一的 policy。在合并 policies 时,我们将检查字典的每一层,并使用以下方法对每个来源的值进行比较: 1. 如果任何值为 `True`,则合并后的值为 `True`。 2. 如果任何值为字典,则合并后的值成为一个通过递归使用此方法检查每个值而创建的字典。 3. 如果所有值都是 `None`,则合并后的值为 `None`。 来看一个示例: ```python { "entities": { "entity_ids": { "light.kitchen": True } } } ``` ```python { "entities": { "entity_ids": True } } ``` 合并后变为 ```python { "entities": { "entity_ids": True } } ``` ## 检查权限 我们目前有两种不同的 permission checks:用户能否对 entity 执行 read/control/edit 操作,以及用户是否为 admin 从而被允许更改此 configuration setting。 某些 APIs 对所有用户始终可访问,但可能根据 permissions 提供有限的范围,例如渲染 template。 ### 检查权限 要检查 permission,你需要能够访问 user object。一旦有了 user object,检查 permission 就很容易了。 ```python from homeassistant.exceptions import Unauthorized from homeassistant.auth.permissions.const import POLICY_READ, POLICY_CONTROL, POLICY_EDIT # Raise error if user is not an admin if not user.is_admin: raise Unauthorized() # Raise error if user does not have access to control an entity # Available policies: POLICY_READ, POLICY_CONTROL, POLICY_EDIT if not user.permissions.check_entity(entity_id, POLICY_CONTROL): raise Unauthorized() ``` ### context 对象 Home Assistant 中的所有 service actions、fired events 和 states 都有一个 context object。该对象允许我们将更改归因于 events 和 actions。这些 context objects 还包含一个 user id,用于检查 permissions。 对于 permission checking 来说,至关重要的是,代表用户执行的操作必须使用包含用户 ID 的 context 来完成。如果你在 service action handler 中,应该重用传入的 context `call.context`。如果你在 WebSocket API 或 Rest API endpoint 中,应该使用正确的用户创建 context: ```python from homeassistant.core import Context await hass.services.async_call( "homeassistant", "stop", context=Context(user_id=user.id), blocking=True ) ``` ### 权限检查失败时 当你检测到 unauthorized action 时,应该抛出 `homeassistant.exceptions.Unauthorized` 异常。此异常将取消当前操作并通知用户其操作未被授权。 `Unauthorized` 异常有多个参数,用于标识失败的 permission check。所有字段都是可选的。 | Parameter | Description | --------- | ----------- | context | The context of the current call. | user\_id | The user ID that we tried to operate on. | entity\_id | The entity ID that we tried to operate on. | config\_entry\_id | The config entry ID that we tried to operate on. | perm\_category | The permission category that we tested. Only necessary if we don't have an object ID that the user tried to operate on (like when we create a config entry). | permission | The permission that we tested, ie `POLICY_READ`. ### 保护 service action handler Actions 允许用户控制 entities 或与整个 integration 进行交互。Service action 使用附加的 context 来查看哪个用户触发了命令。由于使用了 context,重要的是你还要将 call context 传递给所有 service actions。 所有通过 entity component(`component.async_register_entity_service()`)注册的 service actions 将自动进行权限检查。 #### 检查实体权限 你的 service action handler 需要检查它将操作的每个 entity 的 permissions。 ```python from homeassistant.exceptions import Unauthorized, UnknownUser from homeassistant.auth.permissions.const import POLICY_CONTROL async def handle_entity_service(call: ServiceCall) -> None: """Handle a service action call.""" entity_ids = call.data["entity_id"] for entity_id in entity_ids: if call.context.user_id: user = await hass.auth.async_get_user(call.context.user_id) if user is None: raise UnknownUser( context=call.context, entity_id=entity_id, permission=POLICY_CONTROL, ) if not user.permissions.check_entity(entity_id, POLICY_CONTROL): raise Unauthorized( context=call.context, entity_id=entity_id, permission=POLICY_CONTROL, ) # Do action on entity async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: hass.services.async_register(DOMAIN, "my_service", handle_entity_service) return True ``` #### 检查管理员权限 有一个特殊的 helper 用于保护需要 admin 访问权限的 service actions。 ```python from homeassistant.helpers.service import async_register_admin_service async def handle_admin_service(call: ServiceCall) -> None: """Handle a service action call.""" # Do admin action async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: async_register_admin_service( hass, DOMAIN, "my_service", handle_admin_service, vol.Schema({}) ) return True ``` ### 保护 REST API endpoint ```python from homeassistant.core import Context from homeassistant.components.http.view import HomeAssistantView from homeassistant.exceptions import Unauthorized class MyView(HomeAssistantView): """View to handle Status requests.""" url = "/api/my-component/my-api" name = "api:my-component:my-api" async def post(self, request): """Notify that the API is running.""" hass = request.app["hass"] user = request["hass_user"] if not user.is_admin: raise Unauthorized() hass.bus.async_fire( "my-component-api-running", context=Context(user_id=user.id) ) return self.json_message("Done.") ``` ### 保护 Websocket API endpoint 在 Websocket API endpoint 中验证 permissions 可以通过访问 `connection.user` 来获取用户。如果需要检查 admin 访问权限,可以使用内置的 `@require_admin` decorator。 ```python from homeassistant.components import websocket_api async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: websocket_api.async_register_command(hass, websocket_create) return True @websocket_api.require_admin @websocket_api.async_response @websocket_api.websocket_command( {vol.Required("type"): "my-component/my-action",} ) async def websocket_create( hass: HomeAssistant, connection: ActiveConnection, msg: dict, ) -> None: """Create a user.""" # Do action ``` --- url: /developers/automation_action.md --- :::warning 我们目前正在探索设备自动化的替代方案。现有的设备自动化将继续工作,但不会接受新的设备自动化。 ::: 设备动作允许用户让设备执行某个操作。例如,打开灯光或打开门。 设备动作用字典定义。这些字典由你的集成创建,并传递给你的集成以创建一个执行该动作的函数。 设备动作可以由提供该设备的集成(例如 ZHA、deCONZ)提供,也可以由该设备所属的实体集成提供(例如 light、switch)。前者的示例可以是重启设备,而后者的示例可以是打开灯光。 如果动作需要静态的 `ACTION_SCHEMA` 无法提供的动态验证,可以实现一个 `async_validate_action_config` 函数。 ```py async def async_validate_action_config(hass: HomeAssistant, config: ConfigType) -> ConfigType: """Validate config.""" ``` Home Assistant 包含一个模板,供你开始编写设备动作。要开始使用,请在开发环境中运行 `python3 -m script.scaffold device_action`。 该模板会在你的集成文件夹中创建一个新的文件 `device_action.py` 以及一个对应的测试文件。该文件包含以下函数和常量: #### `ACTION_SCHEMA` 这是动作的 schema。基础 schema 应扩展自 `homeassistant.helpers.config_validation.DEVICE_ACTION_BASE_SCHEMA`。不要手动应用 schema。如果动作 schema 被定义为集成 `device_action.py` 模块中的一个常量,核心会自动应用该 schema。 #### `async_get_actions` ```py async def async_get_actions(hass: HomeAssistant, device_id: str) -> list[dict]: """List device actions for devices.""" ``` 返回该设备支持的动作列表。 #### `async_call_action_from_config` ```py async def async_call_action_from_config( hass: HomeAssistant, config: dict, variables: dict, context: Context | None ) -> None: """Execute a device action.""" ``` 执行传入的动作。 --- url: /developers/automation_init.md --- :::warning 我们目前正在探索设备自动化的替代方案。现有的设备自动化将继续工作,但不会接受新的设备自动化。 ::: 设备自动化(Device Automations)在 Home Assistant 的核心概念之上,为用户提供了一层以设备为中心的抽象。在创建自动化时,用户不再需要处理诸如状态(states)和事件(events)等核心概念。相反,他们将能够选择一个设备,然后从预定义的触发器(triggers)、条件(conditions)和动作(actions)列表中进行选择。 集成可以通过暴露函数来生成预定义的触发器、条件、动作,并拥有能够监听触发器、检查条件以及执行动作的函数,来接入该系统。 设备自动化并没有暴露额外的功能,而是让用户无需学习新概念的一种方式。设备自动化在底层使用了事件、状态和服务动作(service action)辅助工具。 ### 次要设备自动化 某些设备可能会暴露大量的设备自动化。为了避免给用户造成困扰,可以将某个设备自动化标记为次要(secondary)。被标记为次要的设备自动化仍然会向用户显示,但可能会在其他设备自动化之后显示,或者可能需要用户选择"显示更多"(show more)选项或类似选项。 如果设备自动化通过 `entity_id` 键引用了某个实体,则当被引用的实体被隐藏,或被引用实体的 entity category 不是 `None` 时,次要标志会自动设置为 `True`。下面的示例展示了如何将设备自动化标记为次要。 ```python from homeassistant.const import ( CONF_DEVICE_ID, CONF_DOMAIN, CONF_PLATFORM, CONF_TYPE, ) from homeassistant.helpers import device_registry as dr async def async_get_triggers(hass, device_id): """Return a list of triggers.""" device_registry = dr.async_get(hass) device = device_registry.async_get(device_id) triggers = [] # Determine which triggers are supported by this device_id ... triggers.append({ # Required fields of TRIGGER_BASE_SCHEMA CONF_PLATFORM: "device", CONF_DOMAIN: "mydomain", CONF_DEVICE_ID: device_id, # Required fields of TRIGGER_SCHEMA CONF_TYPE: "less_important_trigger", # Mark the trigger as secondary "metadata": {"secondary": True}, }) return triggers ``` --- url: /developers/automation_trigger.md --- :::warning 我们目前正在探索设备自动化的替代方案。现有的设备自动化将继续工作,但不会接受新的设备自动化。 ::: 设备触发器是与特定设备和某个事件或状态变更绑定的自动化触发器。例如"灯光被打开"或"检测到水"。 设备触发器可以由提供该设备的集成(例如 ZHA、deCONZ)提供,也可以由该设备所属的实体集成提供(例如 light、switch)。前者的示例是不与某个实体绑定事件,例如遥控器上的按键或触摸面板上的触摸事件;后者的示例则是灯光被打开。 要添加对设备触发器的支持,集成需要有一个 `device_trigger.py` 文件,并且需要: * *定义一个 `TRIGGER_SCHEMA`*:一个代表触发器的字典,例如某个设备和一个事件类型 * *创建触发器*:创建包含设备或实体以及由 schema 定义的支持事件或状态变更的字典。 * *挂载触发器*:将一个触发器配置与某个事件或状态变更关联,例如事件总线(event bus)上发出的消息。 * *添加文本和翻译*:为每个触发器赋予一个人类可读的名称。 不要手动应用静态 schema。如果触发器 schema 被定义为集成 `device_trigger.py` 模块中的一个常量,核心会自动应用该 schema。 如果触发器需要静态的 `TRIGGER_SCHEMA` 无法提供的动态验证,可以实现一个 `async_validate_trigger_config` 函数。 ```py async def async_validate_trigger_config(hass: HomeAssistant, config: ConfigType) -> ConfigType: """Validate config.""" ``` Home Assistant 包含一个模板,供你开始编写设备触发器。要开始使用,请在开发环境中运行 `python3 -m script.scaffold device_trigger`。 该模板会在你的集成文件夹中创建一个新的文件 `device_trigger.py` 以及一个对应的测试文件。该文件包含以下函数和常量: #### 定义一个 `TRIGGER_SCHEMA` 设备触发器被定义为字典。这些字典由你的集成创建,并被你的集成消费,用于挂载触发器。 这是一个 voluptuous schema,用于验证某个特定的触发器字典是否代表你的集成可以处理的配置。它应该扩展自 `device_automation/__init__.py` 中的 TRIGGER\_BASE\_SCHEMA。 ```python from homeassistant.const import ( CONF_ENTITY_ID, CONF_TYPE, ) TRIGGER_TYPES = {"water_detected", "noise_detected"} TRIGGER_SCHEMA = TRIGGER_BASE_SCHEMA.extend( { vol.Required(CONF_TYPE): vol.In(TRIGGER_TYPES), } ) ``` 此示例只有一个 `type` 字段,表示所支持的事件类型。 #### 创建触发器 `async_get_triggers` 方法返回由设备或任何关联实体支持的触发器列表。这些是向用户暴露的、用于创建自动化的触发器。 ```python from homeassistant.const import ( CONF_DEVICE_ID, CONF_DOMAIN, CONF_PLATFORM, CONF_TYPE, ) from homeassistant.helpers import device_registry as dr async def async_get_triggers(hass, device_id): """Return a list of triggers.""" device_registry = dr.async_get(hass) device = device_registry.async_get(device_id) triggers = [] # Determine which triggers are supported by this device_id ... triggers.append({ # Required fields of TRIGGER_BASE_SCHEMA CONF_PLATFORM: "device", CONF_DOMAIN: "mydomain", CONF_DEVICE_ID: device_id, # Required fields of TRIGGER_SCHEMA CONF_TYPE: "water_detected", }) return triggers ``` #### 挂载触发器 要将其连接起来:给定一个 `TRIGGER_SCHEMA` 配置,确保当触发器被触发时,会调用 `action`。 例如,你可以将触发器和动作挂载到你的集成在事件总线上发出的[事件](/developers/integration_events.md)上。 ```python async def async_attach_trigger(hass, config, action, trigger_info): """Attach a trigger.""" event_config = event_trigger.TRIGGER_SCHEMA( { event_trigger.CONF_PLATFORM: "event", event_trigger.CONF_EVENT_TYPE: "mydomain_event", event_trigger.CONF_EVENT_DATA: { CONF_DEVICE_ID: config[CONF_DEVICE_ID], CONF_TYPE: config[CONF_TYPE], }, } ) return await event_trigger.async_attach_trigger( hass, event_config, action, trigger_info, platform_type="device" ) ``` 返回值是一个用于解除触发器挂载的函数。 #### 添加文本和翻译 自动化用户界面会在设备自动化中,显示一个映射到事件类型的人类可读字符串。用你支持的触发器类型和子类型更新 `strings.json`: ```json { "device_automation": { "trigger_type": { "water_detected": "Water detected", "noise_detected": "Noise detected" } } ``` 要在开发过程中测试你的翻译,请运行 `python3 -m script.translations develop`。 --- url: /developers/automations.md --- :::warning 此页面的功能仍在非常积极地开发中,集成目前不应使用。API 可能会在没有弃用通知的情况下发生变化。 ::: ## 触发器 Triggers 基于事件、状态更改或条件启动 automations。通过创建并注册 trigger 类,在你的集成 `trigger` platform(`trigger.py`)中实现它们。 ### 触发器类 每个 trigger 必须继承自 `homeassistant.helpers.trigger.Trigger`,并实现 `async_validate_config` 和 `async_attach_runner`。 `async_validate_config` 验证 trigger 的 configuration dict,而 `async_attach_runner` 设置 trigger,以便在每次 trigger 触发时调用所提供的 action runner `run_action`。 需要等待 action 完成的 integrations 可以 `await` 由 `run_action` 返回的 `Task`:`await run_action(...)`。 ```python from typing import TYPE_CHECKING, cast import voluptuous as vol from homeassistant.const import CONF_TARGET from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback from homeassistant.helpers import config_validation as cv from homeassistant.helpers.trigger import Trigger, TriggerActionRunner, TriggerConfig from homeassistant.helpers.typing import ConfigType _CONFIG_SCHEMA = vol.Schema( { vol.Required(CONF_TARGET): cv.TARGET_FIELDS, } ) class OccupancyClearedTrigger(Trigger): """Trigger when occupancy is cleared.""" @classmethod async def async_validate_config( cls, hass: HomeAssistant, config: ConfigType ) -> ConfigType: """Validate trigger-specific config.""" return cast(ConfigType, _CONFIG_SCHEMA(config)) def __init__(self, hass: HomeAssistant, config: TriggerConfig) -> None: """Initialize trigger.""" super().__init__(hass, config) if TYPE_CHECKING: assert config.target is not None self._target = config.target async def async_attach_runner( self, run_action: TriggerActionRunner ) -> CALLBACK_TYPE: """Attach the trigger.""" @callback def async_remove() -> None: """Remove trigger.""" # 你的代码以注销 trigger @callback def async_on_cleared(entity_id: str) -> None: """Handle occupancy cleared.""" payload = {"entity_id": entity_id} description = f"Occupancy cleared for {entity_id}" run_action(payload, description) # 一个虚示例方法,用于为目标 entity 注册你的 listener register_for_occupancy_cleared(self._target, async_on_cleared) return async_remove ``` ### 注册触发器 在 `trigger` platform 中实现 `async_get_triggers` 以注册该集成的所有 triggers。 每个 trigger 由一个唯一字符串标识(例如上面示例中的 `"occupancy_cleared"`)。 ```python async def async_get_triggers(hass: HomeAssistant) -> dict[str, type[Trigger]]: """Return triggers provided by this integration.""" return { "occupancy_cleared": OccupancyClearedTrigger, } ``` ### 触发器描述 Triggers 的描述应放在 `triggers.yaml` 文件中。该描述指定了 trigger 的结构,并被前端等使用。 以下片段显示一个接受具有特定 device class 的目标 binary sensor 的 trigger。 ```yaml occupancy_cleared: target: entity: domain: binary_sensor device_class: presence ``` ### 命名触发器 一致地为 triggers 命名有助于用户预测每个集成的行为。一个学会了一种集成如何命名其 triggers 的用户,应该能够猜出另一种集成是如何做的。 核心原则是:trigger 命名一个刚刚发生的事件。它以 entity type 开头,读起来像一个陈述。 在整个集成的 triggers、conditions 和 actions 中,使用单一且一致的 entity type。这是面向人类描述设备种类的名称,例如 "light"、"fan"、"cover"、"lock"、"alarm"、"media player"、"vacuum cleaner"、"climate-control device" 或 "lawn mower"。不要混用诸如 "vacuum" 和 "vacuum cleaner" 的变体,并且始终包含 entity type,即使是 sensor 风格或 zone 风格的条目。 #### 标题 以 entity type 开头,然后描述事件,遵循模式 `[Entity type] [event]`。选择适合事件类型的子模式,而不要将所有事件都强行套用一般过去时。 * **瞬时转换** — 一般过去时,用于瞬时状态变化:"Light turned on"、"Door opened"、"Lock locked"、"Alarm armed"、"Button pressed"。 * **正在进行活动的开始或结束** — `started` / `stopped` / `paused` 加上现在分词,用于设备随时间执行的活动。一般过去时会被错误地暗示活动已结束("Vacuum cleaned" 听起来是已完成,而 "Vacuum cleaner started cleaning" 则不然):"Climate-control device started cooling"、"Lawn mower started mowing"、"Vacuum cleaner paused cleaning"、"Battery started charging"。 * **测量值变化或阈值** — `[measurement] changed` 或 `[measurement] crossed threshold`:"Temperature changed"、"Battery level crossed threshold"、"Light brightness changed"。 * **检测(binary sensors)** — `[phenomenon] detected` 或 `[phenomenon] cleared`:"Motion detected"、"Smoke cleared"。 * **状态阈值** — `[Entity type] became [status]` 或 `[Entity type] no longer [status]`,用于设备进入或离开一个没有自然过去时动词的状态。不要将其留作裸形容词(如 "Battery low"),因为它读起来像状态而不是事件:"Battery became low"、"Battery no longer low"、"Update became available"、"Satellite became idle"。 即使是 sensor 和 zone triggers,也应以 entity type 开头。比起 "Selection changed",更偏向 "Dropdown selection changed";比起 "Entered zone",更偏向 "Zone entered"。 #### 描述 遵循模式 `Triggers when one or more [entity type plural] [present tense verb phrase].` * "Triggers when one or more lights turn on." * "Triggers when one or more lawn mowers start mowing." * "Triggers when one or more locks lock." 规则: * 以 "Triggers when" 开头。trigger 在事件发生的瞬间触发,所以 "when" 比 "after" 更自然、更准确。 * 使用 "one or more \[plural]",而不是 "a" 或单数名词。 * 使用现在时动词("turn on"、"ring"、"return"),即使标题是过去时。 * 以句号结尾。 #### 键名 Keys 为小写 snake\_case,且 key 应与其 title 的含义相匹配。 * **瞬时转换**:`turned_on`、`turned_off`、`opened`、`closed`、`locked`、`armed`、`pressed`。 * **活动开始或结束**:`started_cooling`、`started_mowing`、`paused_cleaning`、`started_charging`、`stopped_charging`。 * **测量值**:`level_changed`、`level_crossed_threshold`、`target_temperature_changed`、`target_temperature_crossed_threshold`。 * **检测**:`detected`、`cleared`。 * **状态阈值**:`became_low`、`no_longer_low`、`became_available`。不要使用裸 `low` 或 `not_low`;应匹配标题中 "became" 的措辞。 * **Subtypes** 将前缀放在名词前:`awning_opened`、`blind_closed`、`co2_changed`。 不要在 key 中重复 domain。在 update domain 中使用 `became_available`,而不是 `update_became_available`。不要使用如 `_` 这样的占位符 key。 ## 条件 当 automation 被触发时,它可能有一些必须满足的条件才能执行 action。 Conditions 通过在你的集成 `condition` platform(`condition.py`)中创建并注册 condition 类来定义。 ### 条件类 Conditions 继承自 `homeassistant.helpers.condition.Condition`,并且必须实现 `async_validate_config` 和 `_async_check`。 与 [trigger class](#trigger-class) 一样,`async_validate_config` 用于验证 condition configuration。 `_async_check` 在需要检查 condition 时被调用,应返回 condition 是否满足。 在下面的片段中,我们创建一个 condition,可以配置为仅当 `binary_sensor.front_door` 具有所配置的期望状态时才通过。 ```python from typing import TYPE_CHECKING, Any, override import voluptuous as vol from homeassistant.const import ( CONF_OPTIONS, CONF_STATE, STATE_OFF, STATE_ON, ) from homeassistant.core import HomeAssistant from homeassistant.helpers.condition import Condition, ConditionConfig from homeassistant.helpers.typing import ConfigType, TemplateVarsType STATE_CONDITION_SCHEMA = vol.Schema( { vol.Required(CONF_OPTIONS, default={}): { vol.Required(CONF_STATE): vol.In([STATE_ON, STATE_OFF]), }, } ) class DoorStateCondition(Condition): """State condition.""" @classmethod @override async def async_validate_config( cls, hass: HomeAssistant, config: ConfigType ) -> ConfigType: """Validate config.""" return STATE_CONDITION_SCHEMA(config) def __init__(self, hass: HomeAssistant, config: ConditionConfig) -> None: """Initialize condition.""" super().__init__(hass, config) if TYPE_CHECKING: assert config.options self._state = config.options[CONF_STATE] @override def _async_check( self, variables: TemplateVarsType = None, **kwargs: Any ) -> bool: """Check the condition.""" # 在此执行你的 condition 检查 return get_example_state() == self._state ``` ### 注册条件 要在该集成的 `condition` platform 中注册 conditions,应实现 `async_get_conditions`。 每个 condition 由一个唯一字符串标识(例如下面示例中的 `"door_state"`)。 ```python async def async_get_conditions(hass: HomeAssistant) -> dict[str, type[Condition]]: """Return the door state conditions.""" return { "door_state": DoorStateCondition, } ``` ### 条件模式 Home Assistant 使用 `conditions.yaml` 文件来了解 condition 的结构。 该文件类似于 `triggers.yaml` 和 `services.yaml`。 例如,下面的片段展示了前面示例中描述的 `door_state` condition。 ```yaml door_state: fields: state: required: true selector: select: options: - "on" - "off" ``` ### 命名条件 Conditions 遵循与 [triggers](#naming-triggers) 相同的 consistency 原则,重用集成的单一、一致的 entity type。不同之处在于,condition 测试的是当前状态,而不是命名一个事件。它以 entity type 开头,读起来像一个陈述。 #### 标题 遵循模式 `[Entity type] is [state]`: * "Light is on" * "Climate-control device is cooling" * "Lock is locked" 对于否定,使用 `[Entity type] is not [state]`,例如 "Media player is not playing"。 对于基于值的 condition,使用变体 `[Entity type] [property]`,例如 "Climate-control device target temperature" 或 "Media player volume"。即使是值 condition 也应包含 entity type,并避免裸 property 名称(如 "Volume")。 #### 描述 遵循模式 `Tests if one or more [entity type plural] are [state].` * "Tests if one or more lights are on." * "Tests if one or more locks are locked." 对于基于值的变体,使用 `Tests the [property] of one or more [entity type plural].`,例如 "Tests the temperature of one or more entities." #### 键名 对所有 condition 使用 `is_` 前缀。这使得 condition 在视觉上与 triggers 和 actions 有所区分。 * **Boolean**:`is_on`、`is_off`、`is_locked`、`is_cooling`、`is_detected`。 * **Negation**:`is_not_`,例如 `is_not_playing`、`is_not_low`、`is_not_detected`。 * **Mode 或特定值**:`is_hvac_mode`、`is_operation_mode`、`is_option_selected`。 * **基于值**:`is_`,例如 `is_target_temperature`、`is_brightness`、`is_value`。这里也要保留 `is_` 前缀。 * **Subtypes**:`[subtype]_is_[state]`,例如 `awning_is_closed`、`blind_is_open`。 --- url: /developers/blog/2018-05-22-custom-ui-panels-api.md --- 随着 Home Assistant 0.70 的发布,我们将前端构建流程从基于 HTML imports 迁移到了 ES module imports(稍后会详细介绍)。带来的影响之一是,我们不再使用 `window` 对象来与其他代码共享类、数据和工具函数。 如果你依赖其中的某些内容,这可能会影响到你。例如 Polymer(`window.Polymer`),或我们以前作为 `window.hassUtil`、`window.HAWS` 或 `window.hassMixins` 提供的工具函数。 为了给开发者留出迁移时间,我们添加了一个临时的 legacy support layer,会在 `window` 对象上重新暴露部分内部内容。我们已经添加了 `window.Polymer`、`window.Polymer.Element` 和 `window.Polymer.html`。如果你还使用了 window 对象上的其他特定内容,[请告诉我们](https://github.com/home-assistant/frontend/issues/1157)。 该 legacy support layer 将在 2018 年 7 月之后的版本中不再包含。 --- url: /developers/blog/2018-06-01-071-custom-panels.md --- 现代化和本地化前端的努力正在全速推进。这篇博文将介绍 Home Assistant 0.71 即将推出的功能,该版本预计今天会进入 beta 通道,并计划一周后正式发布。 ## 改进的 Custom Panel 支持 Custom panels 允许开发者构建可以嵌入到 Home Assistant 用户界面的面板,具备与我们其他面板(如 history、map 等)相同的扩展能力。Home Assistant 前端将负责管理认证和后端 state 的订阅,面板只需负责显示数据,并可为用户提供控制选项(调用 service 等)。 这项支持已经存在一段时间了,但上周我们花了一些时间 [打磨](https://github.com/home-assistant/core/pull/14708) 我们的支持,并增加了三个新特性: 第一个新特性是,我们现在支持从 JavaScript URL 导入 panel。这将是未来分发 panel 的首选方式。这也意味着你可以引用托管在外部服务器的 panel。外部 panel 在加载前需要用户批准。用户仍然可以将 panel 本地托管(无需批准),只需将其复制到 `/www/your-panel.js` 并使用 `/local/your-panel.js` 作为 url。 第二个新特性是,我们现在可以将你的 panel 嵌入到 iFrame 中。这让 panel 开发者无需担心重复的 web components,并且可以使用 React 开发 panel。过去,React 面板无法工作,因为 React 在 Shadow DOM 中无法很好地工作([更多信息](https://github.com/facebook/react/pull/12163))。 第三个新特性是,我们现在提供了一个 [starter kit](https://github.com/home-assistant/custom-panel-starter-kit-react),用于开始开发 React 面板!该工具包包含开发 React 面板所需的一切,并与社区分享。告诉我们你在构建什么吧! ## Custom UI:`` 和 `` 如果你正在构建 custom UI,那么你很可能在使用 `` 和 ``。虽然它们并未被官方支持为对外 API,但我们仍然想提前通知,以后需要传入 `hass` 对象。 这变得必要,是因为 `` 现在可以实现本地化了,感谢 c727 在 [#1241](https://github.com/home-assistant/frontend/pull/1241)。 --- url: /developers/blog/2018-07-02-trying-new-auth.md --- 在 Home Assistant 0.69 中,我们引入了新的 [authentication API](/developers/auth_index.md) 的基础设施。我们将从单一的硬编码 API 密码切换到基于 refresh/access token 的认证系统(由 OAuth2 驱动)。 对于 Home Assistant 0.73,我与 [@awarecan] 一起冲刺,确保 auth 系统已达到最低可用产品的水平: * 用户可以通过内置命令行脚本管理。 * 前端会要求输入用户名和密码进行登录。 * 如果你选择了新系统,API 密码将不再可用。 * 为了不强制与 Home Assistant 生态发生硬性断裂,我们添加了一个临时的 legacy mode,可以重新启用 API 密码支持。该功能未来会被移除。 **该系统尚未准备好供主流用户使用**,我们仍然需要添加 Hass.io 支持以及用户界面,来帮助用户创建第一个用户账户和管理用户。你可以关注(并加入!)待完成的工作[在这里](https://github.com/home-assistant/core/issues?q=is%3Aissue+is%3Aopen+label%3Aauth)。 如果你有兴趣试用,请继续阅读。 ## 试用 这要求你运行 Home Assistant 0.73 beta 或更高版本。 第一步是配置 auth provider。我们将配置内置的 `homeassistant` auth provider。该 provider 将是默认的,并将用户安全地存储在 config 目录中。 ```yaml # Example configuration.yaml entry homeassistant: auth_providers: - type: homeassistant # Uncomment next line if you want to enable legacy API password support # - type: legacy_api_password # Enable the auth component auth: ``` :::info 在 Home Assistant 0.74 或更高版本中,以下说明已不再必要。 ::: 下一步是创建用户。打开终端并导航到 Home Assistant 安装目录。管理用户的脚本内置于 Home Assistant 中,可以使用 `hass --script auth --config /path/to/config` 来调用。 ![显示 auth 脚本帮助输出的截图](/img/en/blog/2018-07-experimental-auth/cli.png) 如果你重启 Home Assistant 并访问前端,你将看到一个全新的登录界面。如果你启用了两个 auth provider,你将首先选择使用哪个 auth provider 进行认证。 登录后,前端将存储 access token 和 refresh token。access token 每 30 分钟过期,并且在每次 Home Assistant 重启时也会过期。前端会自动使用存储的 refresh token 获取新的 access token。我们使用 OAuth2 标准来实现这一点。[更多信息请参阅文档](/developers/auth_api.md)。 [@awarecan]: https://github.com/awarecan --- url: /developers/blog/2018-08-13-deprecating-remote-package.md --- 随着 Home Assistant 0.76 的发布,`homeassistant.remote` 包中的函数将被弃用,并将在 0.77 中移除。该包包含以非 async 方式调用 Home Assistant REST API 的函数。 移除的原因有两点:首先,这些代码在 Home Assistant 内部并未使用,因此不应属于 Home Assistant。其次,它与新的 auth 系统不兼容,我们也不想花费时间去使其兼容。 如果你想继续使用 `homeassistant.remote` 中的方法,欢迎将[这些代码](https://github.com/home-assistant/core/blob/0.75.0/homeassistant/remote.py)复制到你自己的项目中。 --- url: /developers/blog/2019-02-19-the-great-migration.md --- Home Assistant 建立在 components 之上。其中一类 component 为某类设备(如 lights、switches 或 media players)提供 entity 抽象。从历史上看,要与这些抽象集成,你需要为该 component 创建一个 platform。如果 light component 是 `light/`,那么集成就会创建自己的 platform,如 `light/hue.py`。这样,所有与 lights 相关的逻辑就被集中在了一起。 随着 Home Assistant 的发展,我们集成的设备/服务的能力和规模也随之增长。现在,一个集成不再仅仅是某个 entity component 的 platform,而是五个 platform + 一个用于管理连接的 component。当集成变得如此庞大时,将文件分散在 `light/zwave.py`、`switch/zwave.py`、`cover/zwave.py` 等位置就变成了维护的噩梦。这也使得 custom components 的分发更加困难,因为现在用户需要在不同文件夹下创建文件。 因此,从 Home Assistant 0.87 开始,我们启动了迁移。我们不再像 `light/hue.py` 那样查找 entity component 的 platform,而是改为 `hue/light.py` 的形式。文件内容保持完全一致。通过将文件移出 entity component 文件夹,我们还能够将大型 entity component 拆分成多个文件,以提升可维护性。 这一变更在很大程度上是向后兼容的,但对 custom components 有一个小的 breaking change:如果你要覆盖一个内置 platform,现在必须使用新的 `hue/light.py` 文件名格式。 随着集成文件整合到单个文件夹中,我们还要强制实施一项新规则:所有 platform 都将从与 component 相同的来源加载。这意味着,如果你想要用自己的版本覆盖一个内置 component/platform,你需要复制所有的 component 和 platform 文件,而不仅仅是要加载的那一个。这样做可以防止 custom platforms 或 components 在 Home Assistant 升级移动内部文件/值时出现问题。 ## 对 custom component 开发者的说明 * Components 创建在 `/custom_components//`。务必在该文件夹中至少创建一个空的 `__init__.py` 文件。 * 如果你为某个 entity component 编写 platform,将其放在以 integration 命名的文件夹中:`/light.py` * 如果你想分享修改过的 Home Assistant integration 版本,请复制 ALL 文件。为用户着想,使用相对导入以避免升级时组件出现问题的发生。相对导入的示例:`from . import DATA_BRIDGE`。 ## 资源 相关的架构议题: * [Embedded platforms and the road to packaged components](https://github.com/home-assistant/architecture/issues/124) * [Disable partial custom component overlays](https://github.com/home-assistant/architecture/issues/141) * [Config structure for embedded platforms](https://github.com/home-assistant/architecture/issues/142) --- url: /developers/blog/2019-03-11-user-permissions.md --- Home Assistant 从 0.82 版本(2018 年 11 月发布)开始就拥有用户权限系统。权限附加到 groups 上,一个用户可以属于多个 group,用户权限基于合并其所有 group 的权限策略。更详细的信息可以在[我们的文档](/developers/auth_permissions.md)中找到。用户可以创建自己的 group,但也有三个系统 group:"admin"、"users"(0.90 新增)和 "read-only"。三者都可以访问所有 entity,但 read-only 无法控制其中任何一个。只有属于 admin group 的用户才能访问管理用户和 integrations 等管理选项。 在 Home Assistant 0.90 之前,我们没有使用其中任何功能。相反,所有用户都属于 admin group,因为该 group 提供了与权限出现之前相同的访问权限。从 0.90 开始,我们将允许在系统 group "admin" 和 "users" 之间切换用户 group。当用户属于 "users" group 时,他们将无法管理 Home Assistant。UI 将隐藏用于打开配置面板或 developer tools 的菜单项。 ![显示 users group 中用户的截图](/img/en/blog/2019-03-user-permissions/screenshot.png) 然而,此功能尚未完成。我们需要审查 Home Assistant 代码,确保所有 API 和 service 调用都检查了用户权限。因此,虽然用户将无法通过 UI 进行更改,但可能仍然存在无需权限即可访问的 API。而且我们不仅需要检查 Home Assistant 代码,注册了 services 或 APIs 的 custom components 也需要进行更新。 所以这里就是你可以帮助的地方!如果你正在维护某个 integration(无论是 custom 还是内置的),请阅读[如何检查权限的文档](/developers/auth_permissions.md#checking-permissions)。然后检查你的 integration 是否正确检查了权限。检查完自己的之后,帮助别人检查他们的,并帮助我们审查 Home Assistant 中的所有 services 和 API 调用。 ## 那 custom groups 呢? 虽然我们支持创建 custom groups,但暂时不要期望它会公开提供。原因是这需要大量工作来处理与 custom policies 交互的 API。最困难的部分是,custom policy 可能只允许读取几个 entity 的权限,并且只允许对其中一部分进行控制访问。我们需要逐一检查每个 API 以确保它们支持这一点。Lovelace 也需要进行更新,以支持用户拥有自己的配置视图。 话虽如此,如果你确实想试用它,这是可能的。 :::danger 这是有风险的。请做好备份等。 ::: 关闭 Home Assistant,并打开 `/.storage/auth`。找到键 `"groups"`,并添加一个新 group: ```json { "id": "my-custom-group", "name": "My Custom Group", "policy": { "entities": { "entity_ids": { "light.kitchen": true, "switch.ac": { "read": true } } } } } ``` 现在在文件中向下滚动到 `"users"` 键,找到你想要应用 custom group 的用户。对于该用户,将其 `"group_ids"` 值更新为你的 custom group。注意,你不应更新 `"owner": true` 的用户,因为他们将始终拥有所有权限。 ```json "group_ids": [ "my-custom-group" ], ``` 现在启动 Home Assistant 并使用更新后的用户登录。如果一切顺利,你应该只能看到厨房灯和空调开关。控制空调将失败。 一个用户可以属于任意多个 group。只有 `system-admin` group 的成员才能管理系统。要了解有关 policy 格式的更多信息,请查看[文档](/developers/auth_permissions.md)。 --- url: /developers/blog/2019-04-12-new-integration-structure.md --- 我们已经完成了[伟大的迁移](/developers/blog/2019-02-19-the-great-migration.md)。结果将作为 Home Assistant 0.92 的一部分发布。由于我们有大量的问题需要修复,发布时间略有延迟!随着迁移的完成,我们现在将共享相同名称的 components 和 platforms 视为同一个 integration。每个 integration 要么是一个单一的 Python 文件,要么是一个包含 `__init__.py` 文件的文件夹。我们已更新文档,并引入了一个新的[ integrations 章节](/developers/creating_integration_file_structure.md)。 Home Assistant 0.92 为 integrations 引入了一个新的 [`manifest.json`](/developers/creating_integration_manifest.md)。此文件对 custom components 是可选的,用于指定元数据:名称、文档链接、dependencies、requirements 和 code owners。我们正在探索利用 `manifest.json` 实现更多未来功能,如跟踪 breaking changes,或允许 custom components 提供 config flows 并被 discovered。 随着所有这些变更,我们必须移除一些已弃用的内容并更改一些行为: * Platforms 不再可以放在 entity component 的目录中,如 `light/my_platform.py`。相反,在你的 custom\_components 中创建一个新的 `my_platform` 文件夹,创建一个空的 `__init__.py` 文件,并将 `light/my_platform.py` 移动到 `my_platform/light.py`。 * Platforms 不再能够拥有 dependencies 或 requirements。相反,在 `my_platform` 文件夹中创建一个 [`manifest.json`](/developers/creating_integration_manifest.md) 来指定它们,或者在 `__init__.py` 文件中添加 `REQUIREMENTS` 或 `DEPENDENCIES` 常量。 * Platform 现在总是要求在可用时先设置好 component。 * 不再能够为包含在单个 Python 文件中的 component 提供 translations。将它们转换为[目录形式](/developers/creating_integration_file_structure.md)的 integration。 * 如果你想覆盖一个内置 integration,你需要为你的 custom integration 指定一个 `manifest.json`。请注意,我们强烈不鼓励覆盖内置 integration。相反,如果你想运行带有自定义更改的 integration,请更改 integration 名称。例如,如果你想运行一个 MQTT integration 的自定义版本(在 Home Assistant 中名为 `mqtt`): * 将 [Home Assistant 仓库](https://github.com/home-assistant/core/tree/dev/homeassistant/components/mqtt) 中 `mqtt` 文件夹的内容复制到新文件夹 `/custom_components/mqtt_custom/` * 打开 `mqtt_custom/manifest.json`,将 `domain` 的值从 `mqtt` 改为 `mqtt_custom` * 打开 `mqtt_custom/__init__.py`,将 `DOMAIN` 的值从 `mqtt` 改为 `mqtt_custom` * 在配置中所有引用 `mqtt` 的地方,改为引用 `mqtt_custom`。例如,使用 `mqtt_custom:` 来指定 host,在指定 platform 时使用 `platform: mqtt_custom`。 --- url: /developers/blog/2019-05-22-internet-of-things-and-the-modern-web.md --- import DiscussionBox from '../static/js/discourse\_discussion.jsx' [Home Assistant](https://www.home-assistant.io) 是全球最大的开源家庭自动化平台。它[支持](https://www.home-assistant.io/components/)超过 1000 种设备和服务,并被广泛使用:家庭、[船只](https://hasspodcast.io/ha048/) 和 [博物馆](https://twitter.com/sjvanterpool/status/1124035433212649475)。 今天我想谈谈我们的 UI、我们要解决的问题以及我们如何解决问题。在深入探讨原因、内容和方式之前,让我们先看看我们的用户界面。这是我们的演示的嵌入式版本,完全可交互。

嵌入式演示已隐藏,因为屏幕太小。在新屏幕中打开演示。

# 使用场景 在构建物联网平台时,有许多使用场景需要用户界面。请注意,为了这篇博文,我们专注于尺寸相当于手机或更大的设备上的图形用户界面。 **安全。** 当用户不在家时,想要快速查看房屋情况。他们想快速检查车库门是否关闭,或者收到后院意外运动或水槽下方漏水的通知需要查看。这些用户会希望看到包含最近安全相关事件的 logbook、当前摄像头流以及门、窗、水位和运动传感器的当前 state。 **控制一切。** 用户希望有一个单一的地方来控制所有设备。他们的目标是快速概览房屋的各个部分,并控制 lights、switches、thermostats 和音乐。 **控制单个房间。** 用户正在为每个房间中的设备构建界面。这些设备需要暴露单个房间的所有控制,以及可选的关于整个房屋的额外信息和控制房屋其他部分的选项。 **监控。** 用户希望构建自己的 dashboards,以可视化 Home Assistant 和其他数据库(如 InfluxDB)中的所有当前和历史数据。他们想跟踪能源消耗、互联网速度或当前通勤时间。 **管理和自动化。** 用户希望拥有包含管理 Home Assistant 控件的 dashboards。其中包含 automations、scripts 和各种输入控件,用于配置 automations 和 scripts 的参数。 如果你正在使用 Home Assistant,那么你的 UI 很可能是上述几个使用场景的混合体。今天的博文将讨论我们使用了哪些技术来构建一个 UI,让用户能够构建适合所有这些使用场景的 UI。 # 需求 去年当我们开始重新架构界面的一部分时,我们根据使用场景、构建前一个界面的经验以及遇到的问题,提出了一份需求清单。 * **它需要零运行时 magic。** 每个用户想要的东西都不同,因此如果在运行时做决定,人们会要求配置选项来影响这个决定。我们的 UI 需要基于配置做出所有决定,只有在不提供配置时才进行智能干预。我们仍然可以向用户建议配置,但一旦用户编辑了它,他们就拥有了它,并且是唯一更新它的人。 * **它需要可自定义。** 用户希望能够更改一切。我们允许用户指定配置选项来更改样式、名称或图标等,这非常重要。 * **它需要 mobile first。** Home Assistant 不附带单独的 mobile 应用。我们的 UI 将在移动设备、笔记本电脑和介于两者之间的设备上使用。需要仅用一部手机就能安装、使用和配置 Home Assistant。 * **它需要适应新兴市场。** Home Assistant 希望让智能家居对所有人触手可及。因为我们是免费和开源的,所以全球各地广泛的人群都可以使用我们。大多数人使用的是低端手机,并且网络不稳定。我们的用户界面仍然需要可用,并且能够在许多不同的手机上运行。 * **它需要可扩展。** 由于要涵盖许多使用场景,因此 UI 的可扩展性很重要。可扩展性允许开发者进行实验,并允许我们支持所有内容,而不必在 Home Assistant core 中满足所有边缘情况/独特功能,因为一旦放入,就必须永远维护。 * **它需要易于开发。** 在工具中迷失方向很容易。尤其是在尝试维护对所有不同设备的支持的同时,还要提供简单的 theming 和配置。应该让任何人都可以轻松地从现在用户转变为开发者,而无需花费 2 天时间准备开发环境。 # 现代 Web 是我们的平台之选 相当长一份需求清单。Home Assistant 是一个开源项目,得益于用户的慷慨支持,有 2 名全职开发者,加上遍布全球的志愿者开发者大军。在这样的配置下,我们必须做出决策来实现我们的目标。而只有一个平台完全符合我们的要求,一个允许我们提供 theming、默认配置选项,还允许用户导入外部组件来渲染页面部分,并允许我们以简单的方式组织代码以便用户从任何设备轻松访问它的平台:现代 Web。 请注意我说的是现代。近年来,浏览器、Web 框架和工具在提供解决我们挑战的方法方面取得了长足的进步。我们看到了 CSS properties、custom elements 的引入,以及所有主要 Web 工具开箱即用地支持 code splitting。 所有这些现代 Web 优势都广泛可用:桌面浏览器已变得 evergreen,意味着它们无需用户干预即可自动更新。Android 用户可以通过 Play Store 获取浏览器更新,而 Apple 倾向于为其手机提供 5 年的更新,每次更新都包含更新的浏览器。 # 实现 我们所做的事情大多基于或受他人启发。虽然我没有一份列出所有启发我们选择或方法的人的完整名单,但它确实受到了 [Alex Russel](https://twitter.com/slightlylate)、[Rich Harris](https://twitter.com/Rich_Harris)、[Justin Fagnani](https://twitter.com/justinfagnani)、[Malte Ubl](https://twitter.com/cramforce) 的推文和演讲,以及 Polymer 团队的信条 "Do less and be lazy" 的启发。这些人帮助我们塑造了如何构建优秀 UI 的心态。 如果你好奇一个开源项目是如何拥有我们做的这么多酷炫功能的,其实正是因为我们是一个开源项目。对于参与其中的志愿者来说,这是乐趣所在。我们热爱跟进最新的前端发展并实现它们,而无需担心有人抱怨我们的时间应该花在别的地方。 * **[TypeScript](https://www.typescriptlang.org/) 是我们的首选语言。** Home Assistant 支持许多不同类型的设备,包含大量 API,并在前端支持许多不同的 widgets。指望人们记住这一切是不可能的,通过利用 TypeScript,没有人需要记住。TypeScript 是 JavaScript 的带类型版本,提供编译时类型检查和出色的自动补全。当我们发布时,TypeScript 会被转换为 JavaScript,因此浏览器中不需要特殊的运行时。 * **[Lit Element](https://lit-element.polymer-project.org/) 是我们的首选 Web 框架,为我们的用户界面提供动力。** Lit Element 是一个允许声明式模板的 Web 框架,gzip 后仅 6KB,速度极快,并具有出色的 TypeScript 支持。Lit Element 不需要任何构建工具,因此它也成为了我们开发者创建 UI 扩展的首选框架。 * **使用 [Custom Elements](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements) 作为可扩展性的首选技术。** Web 不断变化,我们希望吸引广泛的开发者。所以我们不想选择一个框架并强制用户使用它。因此,我们选择了浏览器内置的兼容层:custom elements。Custom elements 是一个浏览器规范,允许开发者指定自己的 HTML 标签,这些标签添加到 DOM 后,会与你的 JavaScript 代码交互以更新页面。 Custom elements 非常灵活。可以在实际 JavaScript 加载之前将标签添加到页面中。一旦加载,它将接管并渲染正确的 UI。这使得无需预先加载所有内容即可快速构建页面成为可能。浏览器还允许我们监听 custom element 何时被定义,从而随着内容的加载重建 UI 的部分。 * **使用 Shadow DOM 隔离我们的 components。** 虽然我们想让用户在我们的页面上运行代码,但我们不希望他们不小心弄乱我们的内置 components,甚至更糟——破坏整个页面。为了保护我们的 components,我们使用 Shadow DOM。这使我们能够封装 components 的 DOM 和样式。 * **使用 CSS properties 实现 theming。** 用户想要自定义内置 components,还想要自定义他们导入的第三方 components。无论开发者使用什么 Web 框架来构建他们的 widgets,这都必须有效。我们使用 CSS properties 解决了这个问题。CSS properties 是用户可以在整个 UI 上、每个 tab 上,有时是每个 card 上设置以自定义外观的 CSS 值。 * **依赖静态 DOM。** 当页面首次加载时,我们将根据用户的配置构建页面。之后,我们不会再触碰它。相反,当 state 改变时,我们会将 state 传递给所有相关 components,lit-html 将高效地更改需要更新的部分。 * **交付现代 JavaScript。** 我们构建两个前端版本。一个版本面向现代浏览器,作为 module 导入,可以利用 lambdas、classes 和 async/await 等现代功能。现代版本生成的代码更少,浏览器中的 JavaScript 引擎可以更好地理解代码意图,从而执行更快。 我们以前使用浏览器 user agent 检测来决定交付哪个版本,但最近通过利用 `type=module`、`nomodule` 以及一个特定的检查,以确保 Safari 10.1 不会同时加载两者,转而采用前端功能检测。 * **使用 Service Workers 激进地预缓存。** Home Assistant 附带一个 service worker。Service worker 是一个在网站后台运行的独立 JavaScript 脚本,我们将其设置为提前下载显示我们 UI 所需的所有代码。这意味着一旦 service worker 启动并运行,对服务器的唯一请求就是数据请求!我们在你登录的同时就已经注册了 service worker,这样当你完成登录时,前端就已经下载好了。我们使用 [Workbox](https://developers.google.com/web/tools/workbox/) 在构建时生成我们的 service worker。 * **解耦获取数据的代码和渲染 UI 的代码。** 我们在页面上加载的第一样东西是一个 5KB 的 JS 文件,它将启动与服务器的连接并开始请求必要的数据。与此同时,浏览器正在解析渲染初始页面所需的其他 JavaScript。我们使用 `link rel=preload` 来确保该 JavaScript 文件在页面加载后立即成为第一个被下载的内容。 * **简单的 state management。** 为了能够将 state 与任何 component(无论是内部还是外部)共享,我们决定自己实现 state management。它是一个简单的对象,包含房屋当前的 state,并沿着我们的 component 树向下传递。每当 state 改变时,我们复制一份并更新更改的部分,然后再次将其传递给所有 components。Components 随后重新渲染并显示最新的 state。所有 state 更新都由 Home Assistant JS Websocket 管理,并且全部在服务器上生成。它们通过 web sockets 推送到前端,使所有打开的 UI 保持同步,因为它们都能在第一时间收到最新更改。 [Home Assistant JS Websocket](https://github.com/home-assistant/home-assistant-js-websocket/) 是我们 4KB 的 WebSocket + Auth 库,可以添加到任何网站中,将其与 Home Assistant 实例集成。关于一个使用 50 行 JavaScript 构建的独立 Home Assistant UI,请参见[这个 glitch](https://hass-auth-demo.glitch.me/)。 * **使用 modules 和 unpkg 轻松进行扩展开发。** 开发者无需运行任何工具即可开发自己的 card。你只需要创建一个 JavaScript 文件,在配置的 resource 部分引用它,就可以开始使用了([文档中的示例](/developers/frontend/custom-ui/custom-card.md#example-using-js-modules))。我们默认将资源作为 type=module 导入,这样开发者可以在开发过程中直接从 http://unpkg.com 导入他们的依赖。 * **使 bundle 中的 bloat 易于发现。** 如果我们使发现不必要打包的内容变得更容易,开发者就更有可能发现它并花时间去除 bloat。为此,我们在仓库中包含脚本,允许任何人快速使用 [webpack-bundle-analyzer](https://github.com/webpack-contrib/webpack-bundle-analyzer) 运行 bundle 分析,并查看哪些包增加了我们的 bundle 大小。这些分析看起来[是这样的](https://s3.amazonaws.com/home-assistant-demos/bundle-analysis/report-20190522.html)。 * **拆分翻译的 code。** 我们使用 [lokalise.com](https://lokalise.com/) 管理我们的 translations。我们代码库中的所有翻译字符串会自动上传到 lokalise.co,志愿者在那里翻译可用的字符串。我们构建了构建工具,根据 UI 中不同的 panel 拆分我们的 translations。这使我们能够仅按需动态加载所需的 translations。 * **去中心化路由。** 应用的顶层只知道如何路由 url 的第一部分。它知道要加载哪些代码以及实例化哪个 web component。它会将 url 的其余部分传递给 panel,进一步的路由可以从那里完成。这将避免初始 bundle 随着更多部分被拆分而不断增长。我们还为 web components 创建了一个简单易用的 router,支持 code splitting 和加载屏幕,使我们的开发者很容易做正确的事。 * **避免在解析 source 或初始化 classes 时执行操作。** 这属于 "Do less and be lazy" 类别。尽快达到初始渲染很重要。因此,避免任何不必要的操作非常重要。Lit Element 通过提供在 update 完成后运行的生命周期的 hooks 来帮助我们。没有 "组件更新前运行" 的生命周期。 在 Polymer 中,这个信条的一个很好的例子是 debounce。它的 debounce 不会生成一个防抖函数,而是你只需在想要调用函数时调用它。然后它可能会调用函数,并返回一段 state,你需要在下次调用时传回。这样你就不需要在需要之前生成防抖函数。 # 挑战 / 未来改进 我们做了很多酷炫的事情,但工作永远不会结束。以下是一些我们面临的挑战和可能探索的未来改进。在编写这份列表时,我有一个有趣的观察:我们的一些问题并非由于糟糕的设计,而是因为超出了设计的范围。当 UI 较小时,这些设计是正确的,但现在我们成长了,需要适应。 * **处理重复的 custom element 名称。** Custom element 只能定义一次。这意味着如果一个 component 导入了不同的版本,这将会出问题。Home Assistant 拥有自己的专用操作系统 [Hass.io](https://www.home-assistant.io/hassio/),它随自身发布周期附带自己的 control panel。我们无法对版本兼容性做任何保证,在我们弄坏用户 UI 太多次之后,我们坐下来解决了它:我们在 iframe 中运行 Hass.io control panel,以便 custom elements 与父页面隔离。 我们还为此功能提供了开发者扩展点。通过 [custom panel integration](https://www.home-assistant.io/components/panel_custom/),他们可以构建自己的 panel,可选地支持 iframe 隔离。我们为 iframe 隔离发现的另一个使用场景是 React。这个 Web 框架很流行,但无法在 ShadowDOM 中工作。通过在 iframe 中隔离它,我们也解决了这个问题([示例代码](https://github.com/home-assistant/custom-panel-starter-kit-react))。 * **不再尝试将所有内容放入 Webpack。** 当项目从 HTML imports 迁移到 JS imports 时,我们切换到 WebPack 作为我们的 bundler。我们有点过于兴奋,在 WebPack 中做了所有事情,包括生成 HTML。由于我们有前端两个构建版本,实际上我们有两个 WebPack 构建。通过将所有内容放入 WebPack,我们无法创建能够引用现代和 ES5 版本构建的哈希文件名的文件。我们的目标是将 WebPack 的职责最小化到转换 TypeScript、打包文件和压缩。通过减少职责,将更容易尝试其他 bundler。我很期待尝试 [Rollup](https://rollupjs.org/) + [Closure Compiler plugin](https://github.com/ampproject/rollup-plugin-closure-compiler)。 * **在现代 JavaScript 构建中使用 [dynamic imports](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#Dynamic_imports)。** WebPack 只有捆绑构建的单一输出模式,它在运行时使用自己的依赖注入系统。如果我们能切换到 Rollup,我们应该能够利用 dynamic imports,这是浏览器内置的。 * **从主 bundle 中移除 Polymer。** UI 的第一版本是使用 Polymer Web 框架和 [Paper elements](https://www.webcomponents.org/collection/polymerelements/paper-elements)(一组使用 Polymer 构建的 material design components)构建的。我们仍然有一些依赖 Polymer 的核心 UI 代码,这意味着它仍然是初始 UI bundle 的一部分。这意味着目前 Polymer 和 Lit Element 都是我们初始 bundle 的一部分,使该 bundle 不必要地臃肿。 * **翻译所有字符串。** 我们仍然交付尚未翻译的文本。Home Assistant 被各种人群在家庭中使用。让用户使用他们能理解的语言使用 UI 很重要。此外,我们最近在 RTL 支持方面取得了很大进展,大部分已覆盖,但仍有可以改进的地方。 * **去中心化一切。** 我从 Malte Ubl 关于[设计大型 JavaScript 应用](https://medium.com/@cramforce/designing-very-large-javascript-applications-6e013a3291a3)的文章中获得的关键要点之一是避免集中配置。集中配置会随着应用的成长而不断增长,如果它是主 bundle 的一部分,你将交付不必要的内容。这目前在我们的代码中体现在两个地方: * 我们交付一个在发布时构建的 iconset,包含整个 UI 中引用的所有图标。随着 UI 的增长,这个 iconset 也在增长。它现在包含大量初始加载不再需要的图标,但仍然被加载。一个可探索的选项是用支持包含 SVG 图标的 lit-html 模板的组件替换我们当前的图标渲染组件。然后我们可以通过正常的 JS import 开始加载图标。这将允许我们的 JS bundler 仅包含 bundle 中代码引用的图标。我们应该确保可以标记这些文件为允许重复,否则 JS bundler 会生成大量只包含单个图标的小 bundle。 * 我们目前按语言和 UI panel 分别拆分翻译文件,然后单独指纹验证每个文件。这个 manifest 文件包含在我们的初始构建中,随着我们的 app 在 panel 数量上的增长以及支持更多语言,我们的 manifest 文件现在成了初始 UI bundle 的一大块。我们的第一步应该是为每种语言生成单个 hash,使我们只能包含每种语言的一行。 * **分析当前的 code splitting 算法。** 目前 WebPack 会确保每个 JavaScript 文件只加载一次(按照规范)。然而,这意味着我们最终以某些文件完全不被打包结束,因为有太多 code splitted 的代码片段引用该文件,导致它成为自己的 chunk。目前我们前端构建包含 126 个 code splitted chunks,其中 85 个小于 5KB!我们需要运行 traces 来查看这是否是个问题,或者 service worker 隐藏了大部分。 * **停止使用 local storage。** 我们使用 local storage 存储 auth tokens、语言偏好以及是否显示侧边栏。由于 local storage 是同步访问的,浏览器会在等待从磁盘读取 local storage 时停止执行页面上的任何操作。浏览器厂商正在开发像 [kv-storage](https://github.com/WICG/kv-storage) 这样的替代方案,它是异步的,可能会成为一个可行的替代方案。 * **将 Paper elements 替换为 [Material Web Components](https://github.com/material-components/material-components-web-components)。** Paper elements 不再维护,Material Web Components 将是继承者,但仍在开发中。MWC components 底层使用 Lit Element,并依赖 material.io 的 Material design VanillaJS 实现。这意味着它们将比当前的 Paper elements 轻得多,并且实际上会得到维护。 ## 评论
--- url: /developers/blog/2019-07-03-climate-cleanup.md --- import DiscussionBox from '../static/js/discourse\_discussion.jsx' *本文介绍 Home Assistant climate integration 即将发生的变更。这些变更目前正在实施中,不再接受讨论。如果你希望看到变更,请考虑提出[架构议题](https://github.com/home-assistant/architecture/issues)。* 从 Home Assistant 0.96 开始,我们将交付 climate integrations 的大型架构清理。这项努力由 Pascal Vizeli 领导。 多年来,climate integration 从一个简单的恒温器位置,发展为容纳空调、热泵和通风系统。在此期间,出现了失误,导致设计混乱且难以使用。清理工作正在进行中,我们将在 Home Assistant 0.96 中交付。 我们犯的最大错误是将 operating mode 和 operation mode 混淆了。Operation mode 是你希望恒温器做的事,例如将房屋加热到 19 °C。Operating mode 是恒温器\_当前\_在做什么。是因为房屋太冷而在加热?还是已经达到了目标温度,当前处于 idle? 此外,我们发现许多 integrations 通过大量选项过度重载了 operation mode,如 "eco"、"comfort"、"boost" 或 "sleep"。在仔细分析了各种气候系统后,我们得出结论,这些替代 operation modes 是现有 operation modes(heat、cool、heat-cool)的变体,但可能有不同的目标温度范围,或者尝试以更慢的速度加热/冷却以节省能源。 为了尽可能支持多种恒温器,我们决定允许 climate devices 指定它们正在运行的新 "preset" mode。它涵盖 hold mode、away mode,或恒温器包含的任何自定义 operation mode。 你可能想知道,为什么要使用 preset 而不是允许重载 operation mode?乍一看,一个 integration 列出可能的选项和当前选择的选项似乎是可行的,很容易构建 UI。然而,这不是 Home Assistant 被使用的唯一方式。我们还作为单一地点为外部系统(如 Google Assistant 或 Amazon Alexa)控制任何恒温器。它们有一套有限的期望的 operation modes。 变更要点: * `operation_mode` 已重命名为 `hvac_mode`,以强调该 mode 的用途。 * 我们将 HVAC mode `auto` 拆分为 `auto` 和 `heat_cool`。如果是 `heat_cool`,用户设定了设备必须使用加热和冷却来保持在内的温度范围。Auto mode 现在仅限于运行在 schedule 或 AI 上的设备。 * Climate entity 的 state 现在总是等于 HVAC mode。 * `hvac_action` 引入用于知道当前 action(heating、cooling、idle)的 integrations。 * `set_away_mode` 和 `set_hold_mode` 已合并为 `set_preset_mode`。因此,不再是 `turn_away_mode_on()`,现在我们将调用 `set_preset_mode("away")`。 * `is_on` 属性已移除。如果设备能够关闭,它应包含 hvac mode `HVAC_MODE_OFF`。 * 属性名已对齐,所有以 "\_list" 结尾的现在命名为 "\_modes"。 如果你是拥有 climate platform 的 integration 的维护者,或维护拥有 climate platform 的 custom component,请确保你[跟进该 pull request](https://github.com/home-assistant/core/pull/23899),并在 beta 期间测试你的 integration,确保它按预期工作。 ## 评论
--- url: /developers/blog/2019-07-19-building-all-the-things.md --- import DiscussionBox from '../static/js/discourse\_discussion.jsx' *Home Assistant 如何使用 Azure Pipelines 自动化一切。* 在 Home Assistant,我们热爱自动化!不仅是在我们的家中,也在开发工作中。我们每三周发布一次版本,包含来自 80 多个不同人员的代码。所有这些都由两名全职人员管理(感谢 [Nabu Casa](https://www.nabucasa.com)!)。 我们将 Home Assistant 作为 Python 包分发,并作为我们名为 Hass.io 的一体化系统的一部分。Hass.io 有自己的操作系统、一个 supervisor Docker 容器和 Home Assistant docker 容器。除此之外,Hass.io 还支持 add-ons,我们有一套官方 add-ons 也进行维护。对于 Hass.io 所做的每一件事,我们都要做五次,每次针对我们支持的一种架构:amd64、i386、armv6、armv7、aarch64。 为了保持快速推进,我们花了很多时间自动化构建任务。在试用了 [TravisCI](https://travis-ci.org/) 和 [CircleCI](https://circleci.com/) 之后,我们最终选择了 [Azure Pipelines](https://azure.microsoft.com/en-us/services/devops/pipelines/)。 我们最初从 Travis 开始,但意识到可以通过利用包含 4 个 worker、测试分布和构建 artifact 缓存的 CircleCI 开源计划来显著加速构建。我们尝试从 CircleCI 获取更多 worker,但根据他们的新定价计划添加 worker 太贵了。 [Pascal Vizeli](https://www.github.com/pvizeli) 在以前的工作中有 Azure 经验,他能够在几天内迁移并构建所有基于 YAML 的 pipelines。他得到了 [Kees Schollaart](https://twitter.com/keesschollaart) 的支持,后者是 Azure 的 DevRel,但在我们的社区中因创建 [Home Assistant Companion extension for VS Code](https://marketplace.visualstudio.com/items?itemName=keesschollaart.vscode-home-assistant) 而闻名。每当我们卡住时,他都给予了很多帮助。 Azure 的开源计划附带 10 个免费 agents,在我们联系 Microsoft 后,他们额外提供了 20 个 agents 来帮助我们自动化一切! 有兴趣看看我们用这些 Azure 能力做了什么吗? ## 持续集成 对 Home Assistant 的所有更改都经过我们的 CI pipeline。当有 pull request 提交到 Home Assistant 仓库时,它将触发按 [`azure-pipelines-ci.yml`](https://github.com/home-assistant/home-assistant/blob/dev/azure-pipelines-ci.yml) 配置的 pipeline。 Home Assistant 的贡献会经过我们的测试套件、代码风格和类型检查,以确保贡献不会破坏东西。我们将测试套件拆分为 3 个不同的 stages。通过使用 stages,我们可以运行快速的验证 stage,如果不正确就快速失败。 这一策略使我们在已知基础 linting 无法通过时,不会浪费任何 worker 时间运行完整的测试套件。 下面是我们 Home Assistant CI pipeline 的截图。由于所有工作分布在多个 worker 上,总运行时间是第一列中最长的任务,加上第二列中最长的任务。
![Home Assistant CI pipeline 的截图。](/img/en/blog/2019-07-building-all-the-things/test-stages.png)
为了在 Azure 上改善我们的 CI 时间,我们使用了 [pipeline artifact caching](https://marketplace.visualstudio.com/items?itemName=1ESLighthouseEng.PipelineArtifactCaching) 的预览版本。这允许我们构建一次依赖,将其作为包存储在测试 runner 附近,并在 jobs 和 pipeline runs 之间重用。 另一个我们进行的优化是使用自己的 base images 作为测试 runner。这些镜像已经安装了正确的 Python 和其他基础工具。我们将它们添加到 [resources](https://github.com/home-assistant/core/blob/de3d28d9d5bd5dd69cf9f84d021d683da2c322d6/azure-pipelines-ci.yml#L12-L18),然后在 [strategy](https://github.com/home-assistant/core/blob/de3d28d9d5bd5dd69cf9f84d021d683da2c322d6/azure-pipelines-ci.yml#L72-L80) 部分引用它们。 CircleCI 有一个不错的功能,它可以通过跟踪每个测试的持续时间将测试分布在多个 worker 上。这将 PyTest 套件的持续时间减少到约 10 分钟。但这使用了更多 agents,我们会很快耗尽 agents,产生大量积压。后续 stages 只有在 "Overview" stage 完成后才会排队,导致它们排在其他贡献后面。 使用 Azure,我们获得更多 runner,它们更强大、更快,但没有 parallelization。这意味着单个构建将花费更长时间,但随着许多构建涌入,单个构建时间大致保持不变,因为我们没有遇到积压。
![Home Assistant CI pipeline 的截图。](/img/en/blog/2019-07-building-all-the-things/test-results.png)
[测试结果](https://dev.azure.com/home-assistant/Home%20Assistant/_build/results?buildId=3976&view=ms.vss-test-web.build-test-results-tab)的截图。
## 构建 HassOS HassOS 是我们自己的嵌入式 Linux 发行版。它专为在 Docker 容器中运行 Home Assistant 所需的最基本功能而定制。BuildRoot 驱动构建,我们针对五种不同的处理器架构。 Azure Pipelines agents 使用 amd64 CPU 架构。可以使用称为 cross-compiling 的方法为不同架构编译。我们尝试了,但意识到它比使用与我们目标相同的 native CPU 进行编译要慢得多。 我们使用 Azure Pipelines 上称为 [self-hosted agents](https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/agents?view=azure-devops#install) 的功能,在具有正确架构的自有硬件上托管 build agents。Azure Pipelines 管理 pipeline 定义和编排,但执行在我们的自有硬件上飞速运行。
![Home Assistant CI pipeline 的截图。](/img/en/blog/2019-07-building-all-the-things/build-cabinet.jpg)
我们的 build cabinet。
## 构建 Python Wheels Home Assistant 作为独立的 Python 包分发,并捆绑在 Docker 容器中。我们的 Docker 容器包含不同 integrations 的所有 Python 包预装。因此,创建 Docker 容器需要很长时间,因为我们必须为每种架构安装和构建每个 Python 包。Home Assistant + 所有 integrations 依赖于超过 1000 个不同的 Python 包。 为了加速这个过程,我们利用 Python Wheels。Wheels 是一种二进制格式,包含特定操作系统和 CPU 架构的预构建 Python 包。我们有一个 Azure pipeline 帮助在所有支持的 CPU 架构上为所有不同包构建 wheels。总计 5000 个 wheels! 有一种特殊的 wheels 格式,可以通过单次构建针对多个平台。我们无法使用它,因为它与 musl libc 不兼容,而 Alpine 使用 musl。 该 pipeline 在贡献被接受并合并到开发中且更改了任何 requirements 时自动触发([pipeline 定义](https://github.com/home-assistant/core/blob/de3d28d9d5bd5dd69cf9f84d021d683da2c322d6/azure-pipelines-wheels.yml#L3-L10))。我们还每天运行它以确保捕获所有更改。 由于使用 wheel 安装要快得多,我们还允许 custom integrations [注册自己](https://github.com/home-assistant/custom-components-wheels)。我们将每天扫描每个 custom integration 一次,以确保我们有它们使用的 Python 包的 wheels。 通过利用 wheels,我们将 Home Assistant containers 的构建时间从 1 小时减少到 10 分钟(来自 amd64 构建的测量)。 *(旁注。Python 是以 Monty Python 命名的,包索引则因他们著名的一个段子被叫做 "the Cheese Shop"。因此 Wheel 格式是以一块轮状奶酪命名的,而不是汽车的轮子。5000 块轮状奶酪是很多的奶酪。)* ## 构建 Home Assistant 发布版本 Home Assistant 每三周发布一次稳定版本。在这个稳定版本之前,我们通常有大约 6 个 beta 版本。稳定版本发布后,我们通常有 2 到 3 个 patch 版本。 每个版本都需要构建为独立的 Python 包,以及针对五种支持的 CPU 架构之一的 Docker 容器。 该 pipeline 在[新 release 打 tag](https://github.com/home-assistant/core/blob/dev/azure-pipelines-release.yml#L3-L7)时触发。我们首先验证 tag 名是否匹配代码中的版本,并且 release 是由我们白名单中的 release 管理员之一创建的。然后我们将自动构建所有 releases 并发布。 ## 构建 Hass.io add-ons Hass.io 的功能之一是 add-ons。Add-ons 允许开发者重用 Home Assistant 在 Hass.io 中运行所使用的相同基础设施,但用于你想在网络上运行的任何其他程序。这些 add-ons 可以与 Home Assistant 紧密集成。例如,可以从 [Community Add-ons](https://github.com/hassio-addons/repository) 一键安装 AdGuard,并使其数据可以在 Home Assistant 中访问。 Hass.io 包含几个核心 add-ons。这些 add-ons 的每个版本也需要为所有五种架构构建。我们将所有 add-ons 保存在一个仓库中,但每个 add-on 有自己的 pipeline 定义,仅在该 add-on 更改时触发([示例](https://github.com/home-assistant/hassio-addons/blob/master/mosquitto/azure-pipelines.yml))。 ## 结论 构建广泛的自动化系统确实帮助 Home Assistant 以最少的资源进行了扩展。我们对从 Azure 及其员工那里得到的所有帮助感到非常高兴。干杯! ## 链接 * [Home Assistant on Azure Pipelines](https://dev.azure.com/home-assistant/Home%20Assistant/_build) * [Hass.io on Azure Pipelines](https://dev.azure.com/home-assistant/Hass.io/_build) ## 评论
--- url: /developers/blog/2019-07-31-black.md --- 今天我们正式采用了 Python 代码格式化工具 [Black](https://black.readthedocs.io)。所有代码都已用 Black 格式化,所有未来的贡献都将被检查以确保已使用 Black 格式化。 作为采用 Black 的一部分,flake8 和 pylint 中的所有 style 检查已被禁用。 为了确保在提交更改时所有文件都使用 Black 格式,我们使用 [`pre-commit`](https://pre-commit.com/)。该 hook 会自动为新开发环境安装(作为 `script/setup` 的一部分)。 如果你有现有的开发者安装,请在你的 virtual environment 中运行: ``` pip install pre-commit pre-commit install ``` `pre-commit` 不会更改你的文件,而只是确认更改的文件已由 Black 格式化。我们建议你设置编辑器,在保存时自动使用 Black 格式化文件。各种编辑器的说明可以在[这里](https://black.readthedocs.io/en/stable/integrations/editors.html)找到。 --- url: /developers/blog/2019-09-27-hacktoberfest.md --- import DiscussionBox from '../static/js/discourse\_discussion.jsx' 今年我们再次参与 [Hacktoberfest](https://hacktoberfest.digitalocean.com)。Hacktoberfest 是一项庆祝开源的全球活动。如果你在 10 月提交 4 个 pull request,你将获得一件免费的 Hacktoberfest t-shirt。 Home Assistant 目前正在向我们神奇的 1.0 版本冲刺。Home Assistant 1.0 注重用户友好性。作为其中的一部分,我们最近引入了 device automations,并扩展了 scenes 在 Home Assistant 中的工作方式。 Home Assistant 支持广泛的产品,因此并非我们构建的每个功能都支持每种产品类型。在本次 Hacktoberfest 中,我们准备了 issues,帮助 integrations 使用最新的 Home Assistant 功能。 为了更容易入门,我们引入了一个新的 scaffolding 脚本。该脚本能够创建向现有 entity integrations 添加新功能所需的所有样板代码,包括 tests!你只需专注于与特定 integration 配合工作的代码。每个链接的 issue 中都有使用说明。 如果你想查看所有可用 issues,而不是下面的精选列表,[请点击这里](https://github.com/issues?page=1\&q=is%3Aopen+is%3Aissue+org%3Ahome-assistant+archived%3Afalse+label%3AHacktoberfest\&utf8=%E2%9C%93)(需要登录 GitHub)。 **9 月 30 日更新:** 添加了文档部分,更新了 Almond 部分的链接,添加了指向所有 Home Assistant Hacktoberfest issues 的链接。 **10 月 1 日更新:** 添加了 Frontend 部分。 ## 场景 Scenes 允许用户定义灯光应该看起来的样子(即,它应该是开启的,颜色应该是蓝色的)。当 scene 被激活时,由 Home Assistant 决定调用哪些 services 来实现。 Scenes 是强大的工具,用户易于理解。因此,改进我们的 scene 支持很重要。我们准备了以下 issues: * [添加 `scene.create` service 用于即时创建 scenes。](https://github.com/home-assistant/core/issues/27023) * \~~[添加 `scene.apply` service 用于应用定义为 service data 的 scene。](https://github.com/home-assistant/core/issues/26813)~~ * \~~[在 script 语法中添加 activate scene](https://github.com/home-assistant/core/issues/27026)~~ * [为 entity integrations 添加 reproduce state 支持。](https://github.com/home-assistant/core/issues?utf8=%E2%9C%93\&q=label%3AHacktoberfest+reproduce_state+is%3Aopen+)(多个 issues) ## 设备自动化 Device Automations 是一种面向设备的方式,让用户创建 automations。在定义 automation 的 trigger、condition 或 action 部分时,用户将从选择一个设备开始,查看该设备的可能选项列表。简单! Device automations 依赖 integrations 为每个设备定义可能的选项。由于这是一项新技术,我们仍在寻求帮助,使所有 entity integrations(light、switch 等)支持它。我们准备了以下 issues: * [为 entity integrations 添加 device trigger 支持](https://github.com/home-assistant/core/issues?utf8=%E2%9C%93\&q=label%3AHacktoberfest+device_trigger+is%3Aopen+)(多个 issues) * [为 entity integrations 添加 device condition 支持](https://github.com/home-assistant/core/issues?utf8=%E2%9C%93\&q=label%3AHacktoberfest+device_condition+is%3Aopen+)(多个 issues) * [为 entity integrations 添加 device action 支持](https://github.com/home-assistant/core/issues?utf8=%E2%9C%93\&q=label%3AHacktoberfest+device_action+is%3Aopen+)(多个 issues) ## Home Assistant 文档 猜猜什么永远做不完?文档。 * [为 integrations 填充缺失的文档](https://github.com/home-assistant/home-assistant.io/issues?q=is%3Aissue+is%3Aopen+label%3AHacktoberfest) * [为 hass.io add-ons 填充缺失的文档](https://github.com/home-assistant/hassio-addons/issues?q=is%3Aissue+is%3Aopen+label%3AHacktoberfest) ## 前端 我们还需要在 Home Assistant 的 Frontend 上做些工作。 因此我们也准备了一些 issues 帮你入门: * [使所有文本可翻译](https://github.com/home-assistant/frontend/issues?utf8=%E2%9C%93\&q=label%3AHacktoberfest+label%3Alocalization+is%3Aopen+)(多个 issues) * [帮助使 Home Assistant 更易访问](https://github.com/home-assistant/frontend/issues?q=is%3Aopen+label%3AHacktoberfest+label%3Aaccessibility)(多个 issues) * [以及大量其他小 UX issues](https://github.com/home-assistant/frontend/labels/Hacktoberfest?page=2\&q=is%3Aopen+label%3AHacktoberfest) ## 奖励:Almond - 虚拟助手 [Almond](https://almond.stanford.edu/) 是斯坦福大学的一个开放、保护隐私的虚拟助手。我们一直在[合作](https://github.com/stanford-oval/thingpedia-common-devices/pull/80)使其与 Home Assistant 配合工作。目前它仅限于控制 Home Assistant 中的 lights。 在本次 Hacktoberfest 中,让我们看看能否扩展支持类型的数量!要开始,请查看以下链接: * [关于如何贡献 Home Assistant 特定类型的文档](https://almond.stanford.edu/doc/home-assistant-integration.md) * [关于如何运行 tests 的文档](https://almond.stanford.edu/doc/thingpedia-testing.md) * 在[家中](https://github.com/stanford-oval/almond-server)、[Android 版本](https://play.google.com/store/apps/details?id=edu.stanford.thingengine.engine\&hl=en_US)或 [Gnome 版本](https://flathub.org/apps/details/edu.stanford.Almond) 运行 Almond ## 评论
--- url: /developers/blog/2019-10-05-simple-mode.md --- import DiscussionBox from '../static/js/discourse\_discussion.jsx' :::info 本博文引用了 simple 和 advanced mode。后来已重命名为 standard mode 和 advanced mode。 ::: Home Assistant UI 有两种不同的模式。一种是 simple mode,另一种是 advanced mode。Simple mode 最近已在 [Home Assistant 0.96](https://www.home-assistant.io/blog/2019/07/17/release-96/#advanced-mode) 中引入。在本文中,我想概述我对 Home Assistant 1.0 中 simple mode 的愿景。 **在 simple mode 中,我们专注于核心 Home Assistant 体验。我们正在努力回答这个问题:我们希望任何人都能做什么。我们能否使其足够直观,让人们(无论老少)都能安装 Home Assistant 并使用它。** ## 核心概念 Simple mode 是非高级用户的简化界面。这是默认 UI。Simple mode 提供 Home Assistant 的直观子集:易于理解且易于使用。 在 simple mode 中,我们将按照用户对房屋的理解来组织配置: * Inputs:devices 和 persons * Outputs:scenes、scripts、automations
![Configuration concepts. Inputs are users, integrations, zones, persons, devices. Outputs are scenes, scripts and automations.](/img/en/blog/2019-10-simple-mode/config-concepts.png)
还有其他 inputs,但它们用于支持 devices 和 persons: * Integrations 允许你与设备交互 * Users 允许 persons 登录并访问 Home Assistant * Areas 允许将 devices 分组 * Zones 在地图上标记位置,以跟踪携带 GPS 发射设备的人员 作为 simple mode 中的用户,你将不会被暴露于 events、entity IDs、YAML 或 services。 ## 集成要求 Integrations 需要能够为 simple mode 中的用户提供 inputs。这意味着在 integration 被纳入 simple mode 之前,必须满足一些要求。 * Integration 的所有 entities 都需要有唯一的 ID * Integration 的所有 entities 都需要提供 device info Integrations 应通过 discovery 或 account linking 进行设置。在极少数情况下,我们可以允许通过 IP 地址配置 integration。 ## 扩展发现 在 onboarding 期间以及用户访问 integrations 页面时,我们将触发 extended discovery。默认情况下,Home Assistant 使用 SSDP 和 zeroconf discovery 协议扫描网络。在 extended discovery 中,我们将为流行的 integrations(如 Plex 或 Unifi)运行自定义 discovery 协议。 ## 无 YAML Simple mode 将完全通过 UI 控制。不应暴露需要用户打开文本编辑器的功能。例如,需要用户在 configuration.yaml 中添加 client\_id/secret 的 config flow 不应属于 simple mode。 ## 无 add-ons 的 Hass.io 在 simple mode 中,Hass.io 将是用户管理硬件设置和更新的地方。 Simple mode 的初始版本不会显示安装 Hass.io add-ons 的功能。这是为了控制 Home Assistant 1.0 的范围。未来我们将重新审视这一点,并决定哪些 add-ons 适合我们的 simple mode。 ## 场景 用户将使用 scenes 而不是 services,从 scripts 和 automations 控制设备。通过 scenes,你可以对设备的当前 state 进行快照,并在将来某个时刻恢复。易于解释,也易于使用。我们管理 scenes 的 UI 将围绕 devices 和 areas 构建。 ## 自动化与脚本 Automations 和 scripts 将使用当前编辑器,但 triggers、conditions 和 actions 的类型将限制为与我们 inputs 匹配的那些。 * Trigger 类型将限制为 time、sun、zone 和 device triggers。 * Condition 类型将限制为 time、zone、sun 和 device conditions。 * Action 类型将限制为 activate scene 和 device actions。 ## 我是 power user,为什么要在乎? 通过集中精力在 simple mode 上,我们正在使 Home Assistant 对所有用户(无论是初学者还是 power users)都更容易使用。 一个最近受 simple mode 驱动但对每个人都有益的功能的绝佳例子是 device automations。使用 device automations,配置 Zigbee 遥控器变得轻而易举。你可以直接从列表中选择应该触发你的 automation 的按钮。与此相比,以前的方式是:你需要在 event dev tool 中监听 `zha_event`,然后按下按钮以学习事件数据,用于 event trigger 的匹配。 另一个将使所有人受益的正在进行的工作是,我们在 Hacktoberfest 中重点关注将 scenes 变为[一等公民](https://github.com/home-assistant/core/issues/25681)。 ## 评论
--- url: /developers/blog/2020-02-04-new-zwave.md --- import DiscussionBox from '../static/js/discourse\_discussion.jsx' 在 State of the Union 上,我们[介绍了我们正在开发新的 Z-Wave integration](https://youtu.be/tc17q1Zn0Xs?t=4482)。它基于 Open Z-Wave 项目的一个新项目 [OZWDaemon](https://github.com/OpenZWave/qt-openzwave),我们将通过 MQTT 与它通信。 这种新方法使我们能够直接与 Open Z-Wave 的核心集成,而无需依赖通过其他语言的 bindings。这使得我们能够轻松保持与最新 Open Z-Wave 版本的同步。 得益于 [@cgarwood] 和 [@marcelveldt] 的努力,integration 取得了很大进展,你可以从今天开始作为 [custom component](https://github.com/cgarwood/homeassistant-zwave_mqtt) 测试它。目前还处于早期阶段,并非所有设备类型都已支持。目前它支持 lights、switches、sensors 和 binary sensors。该 custom component 由新的 [`python-openzwave-mqtt`](https://github.com/cgarwood/python-openzwave-mqtt) 包提供动力。 [请试用。](https://github.com/cgarwood/homeassistant-zwave_mqtt#requirements) 如果你发现任何 bugs,请[创建 issue](https://github.com/cgarwood/homeassistant-zwave_mqtt/issues/new)。如果你使用 Home Assistant 0.105,请使用 topic `openzwave/#` 上的新 `mqtt.dump` service 对 Open Z-Wave 实例进行 dump,并将其附加到你的 issue 中。Dump 将被写入 config 文件夹中的 `mqtt_dump.txt`。 一旦 integration 足够成熟,它将成为 Home Assistant Core 的一部分。 [@cgarwood]: https://github.com/cgarwood [@marcelveldt]: https://github.com/marcelveldt ## 评论
--- url: /developers/blog/2020-02-18-106-custom-card-changes.md --- 我们在 Home Assistant Core 0.106 中进行了一些可能会影响 custom Lovelace cards 的变更,如果你是 custom card 开发者,请阅读以下内容。 ### 冻结配置 我们过去会给每张 card 一个配置的副本,因为有些 cards 会修改 Lovelace 传递给它们的配置。在 0.105 中我们停止了这种做法,因为为每张 card 创建深拷贝对性能不好。 这导致了一些问题,因为 cards 仍然在修改配置。在 0.106 中我们 freeze 了配置。这意味着 custom card 不能修改配置。如果它仍然尝试修改,将会抛出异常或静默失败,具体取决于是否在 strict mode 下运行。 请检查你的 custom card 在 0.106 中是否仍然正常工作,并进行调整以避免修改配置。如果你需要,可以自己创建配置的副本。 ### 辅助函数 :::info 我们决定将此变更推迟到 0.107。 ::: 所做的另一个变更是,我们不再默认加载所有 element types。我们在需要时加载它们。这也将有助于性能,但可能会破坏你的 custom card。 我们引入了一组 helpers,你可以使用它们来创建 Lovelace element,这些是 Home Assistant 内部使用的相同函数,并始终与用户使用的版本保持最新。 你可以按如下方式使用它们: ```js const helpers = await loadCardHelpers(); const element = helpers.createRowElement(config); element.hass = this.hass; ``` 更多信息请参见 https://github.com/home-assistant/frontend/pull/4853 --- url: /developers/blog/2020-04-10-translation-handling.md --- 我们已经将 Home Assistant Core 仓库中的翻译脚本迁移到单个命名空间下。现在都可以通过 `python3 -m script.translations` 调用。 | 旧命令 | 新命令 | | ------------------------------ | ----------------------------------------- | | `script/translations_develop` | `python3 -m script.translations develop` | | `script/translations_upload` | `python3 -m script.translations upload` | | `script/translations_download` | `python3 -m script.translations download` | | `script/translations_clean` | `python3 -m script.translations clean` | 这将帮助我们为 [Translations 2.0 effort](https://github.com/home-assistant/architecture/blob/master/adr/0009-translations-2.0.md) 做准备,它将清理 translations 并使其更好地扩展。 --- url: /developers/blog/2020-04-12-s6-overlay.md --- Home Assistant 使用许多不同的 Docker 容器用于各种目的。不仅是可作为 Docker 容器提供的 Home Assistant Core,我们的 Supervisor 和所有 add-ons 也都在利用 Docker。 在许多情况下,我们需要在容器中运行多个进程,并且都需要被管理。我们过去使用简单的 Bash 脚本来完成这件事,但很快意识到我们需要一个真正的进程管理器来处理这件事。 我们决定使用 [S6 Overlay init system][s6-overlay],它基于出色的 [S6][s6] 工具集,提供进程监督和管 理、日志记录以及系统初始化。 S6 Overlay 已添加到我们的 [Docker base images][base-imags] 中,每个 Home Assistant 发布的 Docker 镜像都使用它。 所有容器都已更新,更改由 Home Assistant Supervisor 自动处理;对于 Home Assistant 用户来说,没有明显的 影响。 对于在 Docker 上使用 Home Assistant Core 容器的用户,这可能会影响你运行或启动容器的方式。如果你以覆写 Docker entry point 或 command 的方式运行 Home Assistant Core 容器,你需要调整这些设置。例如,一些容器 管理系统(如 Portainer 和 Synology)会自动为你覆写这些,因此你会受到影响。 在这些情况下: * Entry point 已更改为:`/init` * Command (CMD) 已更改为:` ` *(空/未设置)* 如果你覆写 command endpoint 以启动 Home Assistant,entry point 中的 init system 仍将在后台处于活动状态, 并第二次启动 Home Assistant。这可能导致意外行为。 [base-imags]: https://github.com/home-assistant/docker-base [s6-overlay]: https://github.com/just-containers/s6-overlay [s6]: http://skarnet.org/software/s6/ --- url: /developers/blog/2020-04-16-hassfest.md --- Hassfest 是我们在 Home Assistant 中使用的内部工具,用于确保所有 integrations 拥有有效数据。我们现在已使 Hassfest 能够验证任何 integration,包括 custom integrations。为了让你轻松开始使用它,[@ludeeus](https://www.github.com/ludeeus) 创建了一个 GitHub Action,让你不到一分钟就能开始使用。 要安装它,请按照以下步骤操作: 1. 在 GitHub 上打开你的 custom component 仓库 2. 点击 "Create new file" 3. 对于文件名,粘贴 `.github/workflows/hassfest.yaml` 4. 粘贴以下内容: ```yaml name: Validate with hassfest on: push: pull_request: schedule: - cron: "0 0 * * *" jobs: validate: runs-on: "ubuntu-latest" steps: - uses: "actions/checkout@v3" - uses: home-assistant/actions/hassfest@master ``` GitHub 现在将使用 hassfest lint 所有传入的 PR 和 commits,并且每天晚上运行一次以检查最新的 requirements。 Hassfest action 将跟踪 beta release channel。这样你就可以在 integration 与较新版本的 Home Assistant 不兼容时收到通知。 --- url: /developers/blog/2020-04-23-frontend-translations.md --- 如果你是 custom Lovelace card 的作者,并且使用了 translations,请注意,state translation keys 已更改。 在 0.109 之前,state translations 位于 `state..` 或 `state...`(针对 binary sensors)。从 0.109 版本开始,这些 translations 现在是 backend 的一部分,因此它们具有 backend translations 的 key 格式。我们将 state 格式标准化为始终包含 device class。Device class `_` 保留为没有 device class 的 entities 的 fallback。 | 旧 | 新 | | --------------------------------------- | ------------------------------------------------- | | `state..` | `component..state._.` | | `state...` | `component..state..` | 在未来的版本中,我们计划将 state attribute translations 也迁移到 backend。发生时我们将在此博客上发布。 --- url: /developers/blog/2020-05-08-instance-url-helper.md --- 如果你是 integration 开发者,并遇到了获取用户的 Home Assistant instance URL 的问题,你可能知道,这过去并不总是容易的。 主要问题是 Home Assistant instance 通常安装在家庭中。这意味着内部地址和外部地址可能不同,甚至这些地址本身也可能有变体(例如,如果用户拥有 Home Assistant Cloud 订阅)。 如果 integration 对 URL 有特定要求,情况会变得更糟;例如,它必须可从外部访问并且需要 SSL。 从 Home Assistant Core 0.110 开始,引入了一个新的 instance URL helper 来简化这一点。我们从以下流程图开始解决此问题: [![获取 Home Assistant instance URL 的流程图](/img/en/blog/2020-05-instance-url-helper/flowchart.png)](/img/en/blog/2020-05-instance-url-helper/flowchart.png) 因此,之前可用的 `base_url` 现在被两个新的用户 core 配置设置替换:internal URL 和 external URL。 从开发的角度来看,使用 `hass.config.api.base_url` 现在已被弃用,改用新的 `get_url` helper 方法。 有关使用和实现此新 URL helper 方法的更多信息,请参阅我们的[文档](/developers/instance_url.md)。 --- url: /developers/blog/2020-05-08-logos-custom-integrations.md --- 最近,Home Assistant 开始支持为 integrations 显示 images 和 icons,以在前端中显示。它们看起来很棒,并为 Home Assistant 的 UI 增添了一些色彩。 最近我们收到了很多问题,关于 custom integrations(也称为 custom components)如何添加它们的 images。从今天起,这是可能的! ![HACS icon 在 Home Assistant 前端中的显示](/img/en/blog/2020-05-logos-custom-integrations/customlogo.png) 创建了 custom integration?想让你的 integration 的 logo 和 icon 显示在 Home Assistant 前端中?如果是这样,请访问我们的 [GitHub brands 仓库](https://github.com/home-assistant/brands) 添加你的! *PS:你知道你也可以将你的 custom integration 添加到我们的 [Python wheels 仓库](https://github.com/home-assistant/wheels-custom-integrations) 吗?这将使你的 custom integration 在 Home Assistant 中的安装变得超快!* --- url: /developers/blog/2020-05-09-custom-iconsets.md --- 如果你是 custom icon set 的维护者,你可能需要更新它。 在 Home Assistant core 版本 0.110 中,我们将更改 icons 的加载方式。我们不再一次性加载所有 `mdi` icons,它们也不会成为 DOM elements。 这将为我们节省近 5000 个 DOM elements,并将减少加载时间。 这也意味着我们不再使用或加载 ``,如果你的 icon set 依赖于这个 element,你将不得不更改你的 icon set。 我们引入了一个新 API,你可以通过一个 async 函数注册你的 custom icon set,我们将使用 icon name 作为参数调用它。 我们期望返回一个包含所请求 icon 的 object 的 promise。你的 icon set 可以决定加载和缓存的策略。 API 的格式为: ```ts window.customIconsets: { [iconset_name: string]: (icon_name: string) => Promise< { path: string; viewBox?: string } > }; ``` `path` 是 `svg` 的 path。这是 `` 元素的 `d` 属性中的字符串。 `viewBox` 是可选的,默认为 `0 0 24 24`。 以下是 icon `custom:icon` 的一个非常简单示例: ```js async function getIcon(name) { return { path: "M13,14H11V10H13M13,18H11V16H13M1,21H23L12,2L1,21Z", }; } window.customIconsets = window.customIconsets || {}; window.customIconsets["custom"] = getIcon; ``` 当设置了 icon `custom:icon` 时,Home Assistant 将调用函数 `getIcon("icon")`。 --- url: /developers/blog/2020-05-14-entity-class-names.md --- 你是否在为自己的 entity integrations 实现 entities 时,曾经疑惑过为什么必须扩展 `BinarySensorDevice` 而不是 `BinarySensorEntity`?不用再疑惑了,因为我们在 Home Assistant 0.110 中通过重命名所有名称中错误包含 Device 的类解决了这个问题。旧类仍然存在,但使用时将记录警告。 Home Assistant 中的所有 integrations 都已升级。Custom component 作者需要自己进行迁移。你可以使用以下代码片段在保持向后兼容的同时进行迁移: ```python try: from homeassistant.components.binary_sensor import BinarySensorEntity except ImportError: from homeassistant.components.binary_sensor import BinarySensorDevice as BinarySensorEntity ``` 以下类已被重命名: | 旧类名 | 新类名 | | -------------------- | -------------------- | | `BinarySensorDevice` | `BinarySensorEntity` | | `MediaPlayerDevice` | `MediaPlayerEntity` | | `LockDevice` | `LockEntity` | | `ClimateDevice` | `ClimateEntity` | | `CoverDevice` | `CoverEntity` | | `VacuumDevice` | `VacuumEntity` | | `RemoteDevice` | `RemoteEntity` | | `Light` | `LightEntity` | | `SwitchDevice` | `SwitchEntity` | | `WaterHeaterDevice` | `WaterHeaterEntity` | --- url: /developers/blog/2020-06-01-getCardSize.md --- 自从我们在 Lovelace 中引入 lazy loading cards 以来,获取 lazy loaded card 的 card size 一直很难。 我们过去会在 element 加载之前发送一个 error element,它会带有一个 `getCardSize` 函数。但那个尺寸是错误的。 当 element 被定义时,我们会触发并重建事件,以便重新创建正确的 card。 在 0.110 中我们停止了这种做法,我们会返回正确的 element,但 element constructor 还没有加载,因此它没有 `getCardSize`。 当 constructor 加载时,element 将被升级并设置 config。从那一刻起,我们可以调用 `getCardSize`。 在这个版本中,我们更改了 `getCardSize` 的逻辑,使其会等待这一点。这意味着一些 cards(如 stacks)将返回一个 promise,因为它们必须等待其 children 被定义。 如果你是 custom card 开发者,并且你的 custom card 使用 `getCardSize` 获取其他 cards 的尺寸,你必须调整它以处理这些 promises。 我们获取 card size 的函数(你可以复制),现在看起来像这样: ```ts export const computeCardSize = ( card: LovelaceCard | LovelaceHeaderFooter ): number | Promise => { if (typeof card.getCardSize === "function") { return card.getCardSize(); } if (customElements.get(card.localName)) { return 1; } return customElements .whenDefined(card.localName) .then(() => computeCardSize(card)); }; ``` 我们首先进行和以前相同的检查,如果 element 有 `getCardSize` 函数,我们将返回该值,这应该是一个 `number` 或解析为 `number` 的 `Promise`。 如果该函数不存在,我们将检查 element 的 constructor 是否已注册,如果已注册,这意味着该 element 没有 `getCardSize`,我们将像以前一样返回 `1`。 如果 element 尚未注册,我们将等待它被注册,然后再次调用相同函数获取现在已定义的 card 的尺寸。 --- url: /developers/blog/2020-07-13-alpine-python.md --- 我们的大多数 Containers 使用 Alpine。它是容器的完美发行版,因为它体积小(基于 BusyBox)、支持许多 CPU 架构,并且包系统精简。Alpine 使用 musl 作为其 C 库,而不是更常用的 glibc。 Alpine 与 musl 相比其同类产品相对年轻(分别有 15 年和 9 年的历史),但发展速度显著。由于进展如此之快,基于已不再真实的情况,对两者存在许多误解。本文的目标是解决其中几个问题,以及我们如何解决它们。 本博文无意成为 musl vs. glibc 的争吵。每种用例都不同,有自己的权衡。例如,我们在操作系统中使用 glibc。 对于测试,我使用了 [Docker Python library](https://github.com/docker-library/python) 的镜像,结果发布到我们的 [base images](https://github.com/home-assistant/docker-base)。我使用 pyperformance 进行实验室测试,并使用 Home Assistant 内部 benchmark 工具进行更真实的对比。测试环境运行在与 Docker host 相同的容器内。 ## C/POSIX 标准库 我经常读到:Python 在使用 musl 作为默认 C 库时速度较慢。这个事实并不 100% 正确。如果 Python 运行时使用相同的 GCC 和 `-O3` 编译,glibc 版本在实验室基准测试中稍快,但在实际世界中,差异微不足道。Alpine 使用 `-Os` 编译,而大多数其他发行版使用 `-O2` 编译。这导致了 Python 运行时解释器之间常被提及的差异。但使用相同的编译器优化时,基于 musl 的 Python 运行时没有负面副作用。 但有一个变革者,使得基于 musl 的运行时相比基于 glibc 的运行时更实用。它是内存分配器 [jemalloc](http://jemalloc.net/),一个注重减少碎片和可扩展并发支持的通用 malloc 实现。我在一些关于 Rust 的博文上发现了一个有趣的效果。一些开发者发现 musl 在使用 jemalloc 时比 glibc 快得多,而 glibc 在使用 jemalloc 时反而变慢。可以肯定的是,glibc 和 jemalloc 的好处不在于速度(因为它们优化的是内存管理),但 musl 同时获得两者的好处。虽然纯 musl 和 glibc 之间的差异可以忽略不计,但 musl + jemalloc 与 glibc 之间的差异是实质性的(禁用 GCC 内置内存分配器优化时)。是的,现在的 jemalloc 与 musl 兼容(曾经有一段时间不兼容)。 ## 编译器 如何编译 Python 也很重要。Fedora 或 Redhat 曾有关于禁用 `semantic-interposition` 以获得高性能提升的声明。我在 GCC 9.3.0 上无法重现这一点,但也未看到任何不良副作用。我建议禁用语义(如内置分配器优化)并在构建时链接 jemalloc。我也建议使用 `-O3` 优化。我们从未在目标平台上看到这些激进优化引发任何问题。需要说明的是,与发行版的 Python 运行时解释器不同,我们不需要在所有地方运行。因此,我们可以不加任何覆盖地使用 `--enable-optimizations` 并添加更多 flags。我可以肯定地说,PGO/LTO/O3 使 Python 更快,并且在我们的目标 CPU 上有效。 ## Python 包 Alpine 使用 musl 确实没有 manylinux 兼容性。如果你不缓存构建,安装需要 C extensions 的包时,需要编译它们。这个过程需要时间,就像使用 Qemu 为不同 CPU 架构 cross-build 一样。你无法从 PyPi 获取预编译的二进制文件。这对我们不是问题,因为 PyPI 上提供的二进制文件大多不为我们的目标系统优化。 为了解决 Python 包的安装时间问题,我们创建了自己的 [wheel index](https://wheels.home-assistant.io/) 和 [backend](https://github.com/home-assistant/wheels),用于编译所有需要的 wheels,并通过 CI agents 保持最新。我们为每种 CPU 架构预构建了超过 1k 个包,Docker 文件的构建时间已不再重要。 ## Alpine Linux Alpine 是容器的优秀基础系统,使我们能够为用户提供最佳体验。非常感谢 Alpine Linux、musl 和 jemalloc,使这一切成为可能。 下表显示了 Alpine Linux 的 Python 运行时与我们优化(GCC 9.3.0/musl)的结果对比。所有测试均使用 Python 3.8.3 进行。 | Benchmark | Alpine | Optimized | | ----------------------- | -------- | ----------------------------- | | 2to3 | 924 ms | 699 ms: 1.32x faster (-24%) | | chameleon | 37.9 ms | 25.6 ms: 1.48x faster (-33%) | | chaos | 393 ms | 273 ms: 1.44x faster (-31%) | | crypto\_pyaes | 373 ms | 245 ms: 1.52x faster (-34%) | | deltablue | 22.8 ms | 16.4 ms: 1.39x faster (-28%) | | django\_template | 184 ms | 145 ms: 1.27x faster (-21%) | | dulwich\_log | 157 ms | 122 ms: 1.29x faster (-22%) | | fannkuch | 1.81 sec | 1.32 sec: 1.38x faster (-27%) | | float | 363 ms | 263 ms: 1.38x faster (-28%) | | genshi\_text | 113 ms | 83.9 ms: 1.34x faster (-26%) | | genshi\_xml | 226 ms | 171 ms: 1.32x faster (-24%) | | go | 816 ms | 598 ms: 1.36x faster (-27%) | | hexiom | 36.8 ms | 24.2 ms: 1.52x faster (-34%) | | json\_dumps | 34.8 ms | 25.6 ms: 1.36x faster (-26%) | | json\_loads | 61.2 us | 47.4 us: 1.29x faster (-23%) | | logging\_format | 30.0 us | 23.5 us: 1.28x faster (-22%) | | logging\_silent | 673 ns | 486 ns: 1.39x faster (-28%) | | logging\_simple | 27.2 us | 21.3 us: 1.27x faster (-22%) | | mako | 54.5 ms | 35.6 ms: 1.53x faster (-35%) | | meteor\_contest | 344 ms | 219 ms: 1.57x faster (-36%) | | nbody | 526 ms | 305 ms: 1.73x faster (-42%) | | nqueens | 368 ms | 246 ms: 1.49x faster (-33%) | | pathlib | 64.4 ms | 45.2 ms: 1.42x faster (-30%) | | pickle | 20.3 us | 17.1 us: 1.19x faster (-16%) | | pickle\_dict | 40.2 us | 33.6 us: 1.20x faster (-16%) | | pickle\_list | 6.77 us | 5.88 us: 1.15x faster (-13%) | | pickle\_pure\_python | 1.85 ms | 1.27 ms: 1.45x faster (-31%) | | pidigits | 274 ms | 222 ms: 1.24x faster (-19%) | | pyflate | 2.53 sec | 1.74 sec: 1.45x faster (-31%) | | python\_startup | 14.9 ms | 12.1 ms: 1.23x faster (-19%) | | python\_startup\_no\_site | 9.84 ms | 8.24 ms: 1.19x faster (-16%) | | raytrace | 1.61 sec | 1.23 sec: 1.30x faster (-23%) | | regex\_compile | 547 ms | 398 ms: 1.38x faster (-27%) | | regex\_dna | 445 ms | 484 ms: 1.09x slower (+9%) | | regex\_effbot | 10.3 ms | 9.96 ms: 1.03x faster (-3%) | | regex\_v8 | 81.8 ms | 71.6 ms: 1.14x faster (-12%) | | richards | 265 ms | 182 ms: 1.46x faster (-31%) | | scimark\_fft | 1.31 sec | 851 ms: 1.54x faster (-35%) | | scimark\_lu | 616 ms | 384 ms: 1.61x faster (-38%) | | scimark\_monte\_carlo | 390 ms | 248 ms: 1.57x faster (-36%) | | scimark\_sor | 838 ms | 571 ms: 1.47x faster (-32%) | | scimark\_sparse\_mat\_mult | 19.0 ms | 13.2 ms: 1.43x faster (-30%) | | spectral\_norm | 567 ms | 388 ms: 1.46x faster (-32%) | | sqlalchemy\_declarative | 364 ms | 286 ms: 1.27x faster (-21%) | | sqlalchemy\_imperative | 60.3 ms | 46.8 ms: 1.29x faster (-22%) | | sqlite\_synth | 6.88 us | 5.09 us: 1.35x faster (-26%) | | sympy\_expand | 1.39 sec | 1.05 sec: 1.32x faster (-24%) | | sympy\_integrate | 67.3 ms | 49.5 ms: 1.36x faster (-26%) | | sympy\_sum | 505 ms | 389 ms: 1.30x faster (-23%) | | sympy\_str | 945 ms | 656 ms: 1.44x faster (-31%) | | telco | 17.9 ms | 12.5 ms: 1.44x faster (-31%) | | tornado\_http | 347 ms | 273 ms: 1.27x faster (-21%) | | unpack\_sequence | 232 ns | 212 ns: 1.09x faster (-9%) | | unpickle | 41.6 us | 30.7 us: 1.36x faster (-26%) | | unpickle\_list | 10.5 us | 9.24 us: 1.14x faster (-12%) | | unpickle\_pure\_python | 1.28 ms | 945 us: 1.36x faster (-26%) | | xml\_etree\_parse | 335 ms | 292 ms: 1.15x faster (-13%) | | xml\_etree\_iterparse | 281 ms | 226 ms: 1.24x faster (-20%) | | xml\_etree\_generate | 330 ms | 219 ms: 1.51x faster (-34%) | | xml\_etree\_process | 263 ms | 181 ms: 1.45x faster (-31%) | --- url: /developers/blog/2020-09-30-customViewChanges.md --- Custom Element 开发者现在可以创建用户可以加载和使用的 Custom View Layouts! 在 0.116 中,我们将更改在 Lovelace 中创建 Views 的方式。过去,我们有两种 views:default view 和 panel view。在讨论为 Lovelace 添加 Drag and Drop 时,我们决定可以做得更好,并开始允许自定义 view types。 Custom 开发者现在将能够创建一个接收以下 properties 的 view: ```ts interface LovelaceViewElement { hass?: HomeAssistant; lovelace?: Lovelace; index?: number; cards?: Array; badges?: LovelaceBadge[]; setConfig(config: LovelaceViewConfig): void; } ``` Cards 和 Badges 将由 core code 创建和维护,并传递给 custom view。Custom views 旨于加载 cards 和 badges,并以自定义布局显示它们。 以下是示例:(注意:此示例没有包含所有 properties,但包含显示示例所必需的内容) ```js class MyNewView extends LitElement { setConfig(_config) {} static get properties() { return { cards: {type: Array, attribute: false} }; } render() { if(!this.cards) { return html``; } return html`${this.cards.map((card) => html`
${card}
`)}`; } } ``` 你可以像在 Custom Element Registry 中定义 Custom Card 一样定义这个 element: ```js customElements.define("my-new-view", MyNewView); ``` 你可以在我们的 default view:`Masonry View` 中找到示例,位置在此:[frontend/src/panels/lovelace/views/hui-masonry-view.ts](https://github.com/home-assistant/frontend/blob/master/src/panels/lovelace/views/hui-masonry-view.ts) 下载并安装你的新 Custom View 的用户,可以通过编辑其 view 的 YAML 配置来使用它: ```yaml - title: Home View type: custom:my-new-view badges: [...] cards: [...] ``` Custom 开发者可以为每个 card 添加一个 `layout` property,用于存储 key、位置信息、宽度、高度等: ```yaml - type: weather-card layout: key: 1234 width: 54px entity: weather.my_weather ``` ### 破坏性变更 对于像这样使用以下代码的 Custom Card 开发者: ```js const LitElement = Object.getPrototypeOf(customElements.get("hui-view")); ``` 你将不再能够使用 `hui-view` element 来获取 LitElement,因为它已被更改为 `updatingElement`。相反,你可以使用: ```js const LitElement = Object.getPrototypeOf(customElements.get("hui-masonry-view")); ``` 但请注意!HA 不支持这种做法。未来,这可能无法再用来导入 LitElement。 --- url: /developers/blog/2020-10-02-lazyMoreInfo.md --- 在 0.115 中,我们将 more info controls 转换为 lazy-loaded。这样做是因为 more info dialog 总是在页面加载的早期阶段加载。每个 domain 都可以有自己的 controls,而且它们可能很重。我们不需要在页面加载时拥有所有这些 elements,因此我们决定仅在需要时加载它们。 我们收到 Lovelace custom card 开发者的反馈,称这破坏了他们的 cards,因为并非所有 elements 都可用了。虽然我们不支持在 custom cards 中使用内部 elements(原因见下文),但我们决定在 0.115 中撤销此变更。 在 0.116 中,我们将重新添加 more info dialog controls 的 lazy loading。为了帮助 Lovelace custom card 开发者,我们使我们用于 lazy-load more info controls 的函数可供 custom card 开发者使用。 这意味着如果你的 card 需要某个 domain 的 controls,你可以加载它。 :::info 请注意,我们以任何方式都不支持此功能。我们不保证未来更新中会保留相同的 elements,依赖我们的 elements 时将发生 breaking changes。 ::: 一个加载 `light` domain 的 more info controls 的示例: ```js const helpers = await loadCardHelpers(); helpers.importMoreInfoControl("light"); ``` ## 我们为什么要这样做? 我们总是尝试使前端尽可能快。不仅是在拥有光纤网络的速度极快的台式机上,还是在只有 3G 的低端手机上。 我们尝试优化的一件事是加载代码。加载的代码越少,加载速度越快,我们就可以越早开始渲染页面。如果我们不加载所有内容,也会使用更少的内存。 然而存在权衡,如果我们总是只想加载需要的部分,就必须能够单独加载每个 element。这将意味着大量小型网络请求,由于网络请求的开销,最终比加载稍多但请求次数更少要慢。 因此,这总是在 chunk 大小和所需 chunk 数量之间寻找合适的平衡。我们的代码拆分为 chunks 是通过 bundler 完成的。目前,我们使用 Webpack 来完成这一点。 一些 custom Lovelace 开发者问我们,为什么不能将所有内部使用的 elements 暴露给 custom cards。这仅仅是因为你需要的 element 可能尚未加载,因为它之前并不需要。 使这变得格外困难的是,我们使用 custom elements。Custom elements 只能定义一次,如果你尝试再次定义它,将会报错。这意味着我们无法同时拥有较大的 chunks 和单独的 elements,因为第二次加载时会报错。 如果我们希望实现这一点,要么必须在首次加载时加载每个 component(这将使首次加载非常慢),要么必须将每个 component 拆分为自己的 chunk(这将导致大量小型网络请求,从而降低体验)。 此外,我们内部使用的 elements 本就不打算由外部开发者使用,其 API 未记录也不受支持,随时可能破坏。我们可以在任何 release 中决定替换某个 element,因为有更好的 element 或新的使用场景。或者更改 API,就像我们最近对 `chart` element 所做的那样。如果我们必须支持所有内部使用的 elements,就无法保持目前的速度。我们开发的是一个应用,elements 只是我们的构建模块。 ## 那外部 elements 呢? 我们在前端中使用外部 custom elements,如 Google 的 [Material Web Components](https://github.com/material-components/material-components-web-components)。虽然我们很希望你使用相同的 elements 以提供统一的体验,但我们不能建议这样做。 就像我们自己的 elements 一样,外部 elements 也是我们 code splitted chunks 的一部分,并且很可能被 lazy-loaded。这意味着它们不会一直可用,可能会在稍后加载。 这意味着如果 custom card 在需要时因为 `mwc` element 不可用而加载并定义了它,而我们之后在 lazy-loaded 时尝试这样做,Home Assistant 前端就会遇到错误。 遗憾的是,目前对此没有技术解决方案。有一些解决方案,如来自 open-wc 的 [scoped elements](https://open-wc.org/docs/development/scoped-elements/),但它们在大多数情况下不起作用,因为导入的 element 要么自行注册,要么定义了无法被 scoping 的 sub-elements。 关于 [Scoped Custom Element Definitions](https://github.com/w3c/webcomponents/issues/716) 的提案讨论,可能会解决这个问题,但在提案被接受(如果能被接受的话)之前,可能需要很长时间才能在所有我们支持的浏览器中可用。 ## 有解决方案吗? 有没有解决所有这些问题的方案?使 custom cards 能够提供相同的统一用户体验,而无需担心每次 release 都有 breaking changes 的风险? 我们看到的最佳解决方案是一套由 custom card 社区创建的 elements。这套 elements 将拥有自己的 namespace,不会与 Home Assistant 使用的 elements 的 namespace 冲突。所有 custom cards 都可以使用这些 elements,而无需担心 breaking changes 的风险。 --- url: /developers/blog/2020-10-29-supervisor-update.md --- :::note 本文描述的 builder action(`home-assistant/builder@master`)是遗留工作流。它已被专门的 composite actions 取代。请参见 [builder migration 博文](/developers/blog/2026-04-02-builder-migration.md) 了解当前推荐的方法。 ::: ## GitHub Action 你现在可以将我们的 [builder][marketplace] 作为 [GitHub action][github_action] 使用!:tada: 这已经在我们的 [hassio-addons 仓库][addons] 中使用,你可以[在这里][builder-action]查看我们如何实现它的示例。 它可以用来确保 add-on 在仓库做出更改后仍能构建,并将镜像作为 release workflow 的一部分发布。如何使用该 action 已在 [builder 仓库][builder-action] 中记录。 以下是使用它的示例: ```yaml jobs: build: name: Test build runs-on: ubuntu-latest steps: - name: Checkout the repository uses: actions/checkout@v2 - name: Test build uses: home-assistant/builder@master with: args: | --test \ --all \ --target /data ``` 此示例将在 add-on 的所有支持架构上运行测试构建。 :::tip 你的仓库被映射到 action 中的 `/data`,因此如果你的 add-on 文件在子目录中,你需要提供 `--target /data/{directoryname}` 作为 builder action 的参数。 ::: ## 文档 我们的 [API 文档][api_docs] 已移至 developer documentation 站点。在此过程中,它还进行了样式更新,以便更易于导航。一些 endpoints 仍然缺少内容。如果你还没有达到 [Hacktoberfest] 的配额,也许你想为我们的 API 描述贡献更多细节? ## API 变更 * 使用 `/homeassistant/*` endpoints 已弃用,将于今年晚些时候移除。你需要改用 `/core/*`。 * 使用 `http://hassio/` 已弃用,将于今年晚些时候移除。你需要改用 `http://supervisor/`。 * 使用 `HASSIO_TOKEN` 已弃用,将于今年晚些时候移除。你需要改用 `SUPERVISOR_TOKEN`。 * 使用 `POST` 调用 `/supervisor/snapshots//remove` 删除 snapshots 已弃用,将于今年晚些时候移除。你需要改用 `DELETE` 方法调用 `/supervisor/snapshots/`。 * 使用 `X-Hassio-Key` 头作为认证方法已弃用,将于今年晚些时候移除。你需要改用带有 `Bearer` token 的 authorization 头。 [API 文档][api_docs] 已更新以反映这些变更。 ## Add-on 选项 `/data/options.json` 文件的权限从 `644` 更改为 `600`。如果你的 add-on 以非 root 身份运行并读取此文件,现在将出现权限问题。 你可以在 add-on 中采取以下几个步骤来继续使用这些信息: * 如果你在 add-on 中使用 [S6-overlay],可以使用 [`/etc/fix-attrs.d`][S6-overlay-permissions] 确保运行 add-on 的用户有权访问该文件。 * 你可以将 add-on 更改为以 `root`(默认)身份运行。 ## 发布版本 到目前为止,Supervisor、我们的 plugins 和 add-ons 一直使用 build number 和 [Semantic Versioning (SemVer)][semver] 的混合作为版本系统。我们决定为这些仓库替换它,改为采用 [Calendar Versioning (CalVer)][calver] 作为我们的版本系统。 我们正在将 Supervisor 从基于 release 的开发迁移到 continuous development。这与我们现有的基于 channel 的更新策略(stable、beta 和 dev)完美契合。我们现在利用自动化的 pipelines 将新的 Supervisor 版本构建并发布到正确的 channel。采用这种结构后不再需要双分支设置,因此我们的 `dev` 和 `master` 分支现在已被新的 `main` 分支替换。Supervisor 的 plugins(DNS、Multicast、Observer、CLI)也将遵循这一 continuous development 原则。 我们做出这一更改是为了通过自动测试系统提供更高的软件质量。现在每个 commit 都会触发一个新的 dev release,由我们的测试实例进行测试。问题会立即报告给 sentry。这使我们有时间在创建 release 之前测试所有更改。创建 release 时,更改将在 beta channel 中可用。一旦宣布为 stable,我们就可以将 release 推广到 stable channel。 我们使用 [builder action][marketplace] 配合 [GitHub actions][github_action] 来构建和发布 Supervisor、我们的 plugins 和 Docker 容器的 base images。如果你有兴趣了解我们如何做到这一点,可以查看[此处的 Supervisor builder action][builder_action],以及[此处的 action helpers][action_helpers]。 [action_helpers]: https://github.com/home-assistant/actions/tree/master/helpers [addons]: https://github.com/home-assistant/hassio-addons [api_docs]: /docs/api/supervisor/endpoints [builder_action]: https://github.com/home-assistant/supervisor/blob/main/.github/workflows/builder.yml [builder-action]: https://github.com/home-assistant/builder#github-action [calver]: https://calver.org/ [github_action]: https://github.com/features/actions [Hacktoberfest]: https://hacktoberfest.digitalocean.com/ [marketplace]: https://github.com/marketplace/actions/home-assistant-builder [S6-overlay-permissions]: https://github.com/just-containers/s6-overlay#fixing-ownership--permissions [S6-overlay]: https://github.com/just-containers/s6-overlay [semver]: https://semver.org/ --- url: /developers/blog/2020-11-09-system-health-and-templates.md --- 在 Home Assistant 0.118 中,将有可能会影响你的 custom integration 的两项变更。 ## 移除已弃用的 `helpers.template.extract_entities` 之前已弃用的来自 Template helper 的 `extract_entities` 方法已被移除([PR 42601](https://github.com/home-assistant/core/pull/42601))。不要提取 entities 然后手动监听 state 变化,请改用 Event helper 中的新 `async_track_template_result`。它将动态确保每个接触到的 entity 都被正确跟踪。 ```python from homeassistant.helpers.event import async_track_template_result, TrackTemplate template = "{{ light.kitchen.state == 'on' }}" async_track_template_result( hass, [TrackTemplate(template, None)], lambda event, updates: print(event, updates), ) ``` ## 改进的 System Health 从 Home Assistant 0.118 开始,我们正在弃用为 integration 提供 system health 信息的旧方式。相反,请在你的 integration 中创建一个 `system_health.py` 文件([PR 42785](https://github.com/home-assistant/core/pull/42785))。 从这个版本开始,你还可以包含需要较长时间才能解析的健康检查([PR 42831](https://github.com/home-assistant/core/pull/42831)),例如检查服务是否在线。结果将在准备好时传递给前端。 ```python """Provide info to system health.""" from homeassistant.components import system_health from homeassistant.core import HomeAssistant, callback from .const import DOMAIN @callback def async_register( hass: HomeAssistant, register: system_health.RegisterSystemHealth ) -> None: """Register system health callbacks.""" register.async_register_info(system_health_info) async def system_health_info(hass): """Get info for the info page.""" client = hass.data[DOMAIN] return { "server_version": client.server_version, "can_reach_server": system_health.async_check_can_reach_url( hass, client.server_url ) } ``` --- url: /developers/blog/2021-01-29-custom-integration-changes.md --- 大家新年好!2021 年终于到来了 🎉 你可能已经知道,最近我们意识到几个流行的 custom integrations 中存在安全问题。你可以在此处阅读更多: * https://www.home-assistant.io/blog/2021/01/14/security-bulletin/ * https://www.home-assistant.io/blog/2021/01/22/security-disclosure/ * https://www.home-assistant.io/blog/2021/01/23/security-disclosure2/ 鉴于这些事件。从刚刚发布的 Home Assistant 2021.2.0 beta 开始,我们正在更改两件会影响 custom integrations 的事情。 ## 已弃用的 utilities 位于 `homeassistant.utils` 包中的 `sanitize_filename` 和 `sanitize_path` helper 已被弃用,并等待移除。这将在计划于今年 4 月第一周发布的 Home Assistant 2021.4.0 中发生。 我们添加了 `raise_if_invalid_filename` 和 `raise_if_invalid_path` 作为替代品。它们位于同一个 `homeassistant.utils` 包中。这些新函数将抛出 `ValueError`,而不是依赖开发者比较函数输出与输入是否不同。这将防止滥用。 ## 版本 第二个变更非常酷!版本! [`manifest.json` 文件][manifest] 现在增加了对 `version` key 的支持。Version 应该是包含 major、minor 和 patch 版本的字符串。例如,`"1.0.0"`。 这个 version 将帮助用户向你传达他们遇到问题的 version。并且如果你发现 custom integration 中存在安全问题,Home Assistant 将能够阻止使用不安全的版本。 **从 Home Assistant 2021.6 版本开始,`version` key 是必需的** ## Hassfest 已更新 `hassfest` 是我们在 Home Assistant 中用于验证所有 integrations 的内部工具。今年 4 月,我们将其作为一个 GitHub Action 提供,帮助你发现 custom integration 中的问题。该 action 可用于任何托管在 GitHub 上的 custom integration。如果你还没有将它添加到仓库中,现在正是时候![在此处阅读更多][hassfest]。 如果你正在使用 `hassfest` GitHub action,现在当你缺少 [`manifest.json` 文件][manifest] 中的 `version` key 时,它运行时将开始显示警告。当 `version` key 完全成为 custom integrations 的必需项时,此警告将成为错误。 ## 提供文件 使用户能够访问资源是 custom integrations 的常见用例,无论是 images、panels,还是用户可以在 Lovelace 中使用的增强功能。从路径提供静态文件的唯一方式应使用 `hass.http.async_register_static_paths`。请使用此方法,避免使用自己的方法,因为这可能导致严重的 bug 或安全问题。 ```python from pathlib import Path from homeassisant.components.http import StaticPathConfig should_cache = False files_path = Path(__file__).parent / "static" files2_path = Path(__file__).parent / "static2" await hass.http.async_register_static_paths([ StaticPathConfig("/api/my_integration/static", str(files_path), should_cache), StaticPathConfig("/api/my_integration/static2", str(files2_path), should_cache) ]) ``` 关于 custom integrations 的更新就这些。继续做很棒的事情!下次见 👋 [AwesomeVersion]: https://github.com/ludeeus/awesomeversion [CalVer]: https://calver.org/ [SemVer]: https://semver.org/ [hassfest]: /blog/2020/04/16/hassfest [manifest]: /docs/creating_integration_manifest --- url: /developers/blog/2021-04-09-astral-2.2.md --- 我们最近合并了一个 [pull request](https://github.com/home-assistant/core/pull/48573),将 Home Assistant Core 中使用的 astral 库版本升级到 2.2。这将随 Home Assistant 2021.5 发布。这是 Astral 的一个 major 版本 bump,包含一些 breaking changes,这导致我们更新了依赖 astral 的内置 helpers 和 integrations。这导致我们的 sun helpers 出现了一些 breaking changes。 维护直接使用 sun helpers 或 astral 库的 integrations 的 custom integration 作者,应审查 breaking changes,并在需要时更新他们的 custom integrations。 Sun helper 已更改 `get_astral_location` 和 `get_location_astral_event_next` 的签名,以包含一个 `elevation` 参数。此外,`get_astral_location` 的返回值已更改为包含 elevation 的 tuple。 ```py @callback @bind_hass def get_astral_location( hass: HomeAssistant, ) -> tuple[astral.location.Location, astral.Elevation]: """Get an astral location for the current Home Assistant configuration.""" @callback def get_location_astral_event_next( location: astral.Location, location: astral.location.Location, elevation: astral.Elevation, event: str, utc_point_in_time: datetime.datetime | None = None, offset: datetime.timedelta | None = None, ) -> datetime.datetime: """Calculate the next specified solar event.""" ``` 详情请查看 [`astral` 的 changelog](https://github.com/sffjunkie/astral/blob/master/ChangeLog.md#22---2020-05-20)。 --- url: /developers/blog/2021-05-07-switch-pytz-to-python-dateutil.md --- 三年前,Paul Ganssle 写了一篇[对比文章](https://blog.ganssle.io/articles/2018/03/pytz-fastest-footgun.html),比较了 `pytz` 和 `python-dateutil` 之间的时区处理方式。在这篇文章中,他展示了 `pytz` 很容易以几乎正确但难以发现错误的方式来使用: ```python import pytz from datetime import datetime, timedelta NYC = pytz.timezone('America/New_York') dt = datetime(2018, 2, 14, 12, tzinfo=NYC) print(dt) # 2018-02-14 12:00:00-04:56 ``` *[(链接到文章解释为什么是 -4:56 的部分)](https://blog.ganssle.io/articles/2018/03/pytz-fastest-footgun.html#pytz-s-time-zone-model)* 在 Home Assistant 2021.6 中,我们将切换到 `python-dateutil`。如果你的 custom integration 依赖于非官方接口 `my_time_zone.localize(my_dt)`,你需要进行升级。请改用 Python 的官方方法 `my_dt.astimezone(my_time_zone)`。 属性 `hass.config.time_zone` 也将变为字符串,而不是时区对象。 感谢 [@bdraco] 帮助重启这项努力并推动此变更[完成](https://github.com/home-assistant/core/pull/49643)。我们实际上在迁移过程中发现了一些 bugs!也感谢 Paul Ganssle 维护 `python-dateutil` 以及出色的文章。 [@bdraco]: https://github.com/bdraco ## 5 月 10 日更新 哇,时间过得真快!Paul,`python-dateutil` 的作者,也是启发我们的博文作者,提醒我们 Python 3.9 包含了升级后的时区处理,我们应该改用它。在 Nick 和 Paul 的帮助下,`python-dateutil` 已被移除,改为使用 `zoneinfo`([PR](https://github.com/home-assistant/core/pull/50387))。 --- url: /developers/blog/2021-05-19-lit-2.0.md --- 我们将前端升级到使用 Lit 2.0,这是 `LitElement`(3.0)和 `lit-html`(2.0)的 major bump,今后将一起在 [Lit](https://lit.dev) 名称下发展。 这次升级带来了许多出色的[改进](https://lit.dev/blog/2021-04-21-lit-2.0-meet-lit-all-over-again/),但也包含一些 breaking changes。 如果你开发了 custom card 或 view,并从我们的 components 中使用了 `LitElement` 和 `lit-html`,你的 component 将在下一个版本(2021.6)中使用 Lit 2.0。如果你不确定是否从我们的 components 中使用了 `LitElement`,你的代码看起来可能像这样: ```ts const LitElement = Object.getPrototypeOf(customElements.get("ha-panel-lovelace")); const html = LitElement.prototype.html; const css = LitElement.prototype.css; ``` 这不是推荐的做法,我们建议你打包 Lit 到你的 component 中,或从 `unpkg.com` 或其他来源导入,如这个[示例](https://developers.home-assistant.io/docs/frontend/custom-ui/custom-card#example-using-js-modules)。这样你的 card 就不依赖于 Home Assistant 随附的 Lit 版本。 其中一项变更是,`shadowRoot` 的创建不再在 constructor 中进行,而是在第一次 update 之前进行。这意味着如果你直接与 DOM 交互(如使用 query selector),你不能假设 `shadowRoot` 总是可用的。 所有变更请查看 Lit 文档中的[升级指南](https://lit.dev/docs/releases/upgrade/)。 我们预计大多数 cards 都能无问题地与 Lit 2.0 配合工作,但请 custom card 开发者确保兼容性。你可以使用当前 dev 版本的 Home Assistant 或 nightly 版本的 Home Assistant 来完成这一点,两者目前都使用 Lit 2.0。 --- url: /developers/blog/2021-05-25-sensor_attributes.md --- Sensor entity 模型已更新,增加了两个新 properties:`state_class` 和 `last_reset`。引入这两个新 properties 的驱动力是启用自动生成长期统计。 ### state\_class 诸如 `DEVICE_CLASS_TEMPERATURE` 等 sensor device classes 用于表示差异巨大的数据类型,例如: * 定期更新的温度测量 * 历史或统计数据,例如每日平均温度 * 未来数据,例如明天的预测 区分代表测量的 sensors 和不代表测量的 sensors 是必要的,以便自动合理地选择要包含在长期统计中的 sensors。 [`state_class`](https://developers.home-assistant.io/docs/core/entity/sensor#properties) property 对 state 的类型进行分类:state 可能是来自温度传感器或电能表的\_当前时间测量值\_,*历史值*(如过去 24 小时的平均温度或上个月使用的能量),或\_预测值\_(如天气预报或下一次垃圾收集时间表)。如果 `state_class="measurement"`,state 表示当前值,而不是历史聚合或未来预测。否则,`state_class=None`。有一个[架构讨论](https://github.com/home-assistant/architecture/discussions/557),包含一些额外的背景信息。 请注意,上面提到的\_当前时间测量值\_并不意味着 state 必须以特定频率更新,也不意味着 sensor 不允许进行间接测量(如集成功率来计算能量)。换句话说,如果 sensor 表示最新观察值或时间序列中的最新数据点,它就符合 `state_class="measurement"`。 ### last\_reset 累积型 sensor(如电表、燃气表、水表等)初始化的时间。如果初始化时间未知且表永远不会重置,设置为 UNIX epoch 0:`homeassistant.util.dt.utc_from_timestamp(0)`。请注意,`last_reset` property 返回的 `datetime.datetime` 在更新 entity 的 state attributes 时将被转换为 ISO 8601 格式的字符串。更改 `last_reset` 时,`state` 必须是有效数字。 --- url: /developers/blog/2021-08-12-sensor_temperature_conversion.md --- 温度单位转换正从 `Entity` base class 移至 `SensorEntity` base class。仅当 sensor 的 `device_class` 属性设置为 `DEVICE_CLASS_TEMPERATURE` 时,才会进行单位转换。如果 `device_class` 未设置或未设置为 `DEVICE_CLASS_TEMPERATURE`,温度转换将在过渡期间进行,并记录警告。 为此,sensor entity 模型已更新,增加了两个新 properties:`native_value` 和 `native_unit_of_measurement`。这使我们在未来可以添加额外的单位转换,而无需依赖 integrations 自行处理。 Sensor 实现不应再实现 `state()` property 函数或设置 `_attr_state` 属性。Sensor 实现也不应实现 `unit_of_measurement` property 函数,设置 `_attr_unit_of_measurement` 属性,或设置 `EntityDescription` 中的 `unit_of_measurement` 成员。 ### native\_value sensor 报告的值。 写入 state machine 的实际 state 可能会因单位转换而被 `SensorEntity` 修改。 ### native\_unit\_of\_measurement sensor 的测量单位(如果有)。 写入 state machine 的 `unit_of_measurement` 可能会因单位转换而被 `SensorEntity` 修改。 --- url: /developers/blog/2021-08-16-state_class_total.md --- 新增了一个新的 state class:`total_increasing`。此外,`last_reset` 属性已从 `SensorEntity` 中移除。推动这些变更的驱动力是使其更容易与设备(如公用事业表)集成。 ### 状态类别 有 2 个定义的 state classes: * `measurement`,state 表示当前时间的测量值,例如温度、电功率、股票投资组合的价值等。对于受支持的 sensors,每小时更新每小时 min、max 和平均 sensor 读数的统计,或自首次添加以来 sensor 值的累计增长或下降统计。 * `total_increasing`,单调递增的总计值,例如消耗的燃气、水或能量量。支持时,每小时更新自首次添加以来 sensor 值的累计增长。 #### `STATE_CLASS_TOTAL_INCREASING` 对于 state\_class 为 `STATE_CLASS_TOTAL_INCREASING` 的 sensors,递减的值被解释为新表计周期的开始或表的更换。重要的是,integration 必须确保在从存在测量噪声的 sensor 计算值时,值不会错误地递减。此 state class 适用于燃气表、电表、水表等。 sensor 首次添加到 Home Assistant 时的 state 用作初始零点。检测到新表计周期时,零点将被设置为 0。请参考下表了解这对统计的影响。 `STATE_CLASS_TOTAL_INCREASING` 带有新表计周期的示例: | t | state | sum | | :--------------------- | -----: | ---: | | 2021-08-01T13:00:00 | 1000 | 0 | | 2021-08-01T14:00:00 | 1010 | 10 | | 2021-08-01T15:00:00 | 0 | 10 | | 2021-08-01T16:00:00 | 5 | 15 | `STATE_CLASS_TOTAL_INCREASING` 在新表计周期开始时初始 state 不为 0,但使用 0 作为零点的示例: | t | state | sum | | :--------------------- | -----: | ---: | | 2021-08-01T13:00:00 | 1000 | 0 | | 2021-08-01T14:00:00 | 1010 | 10 | | 2021-08-01T15:00:00 | 5 | 15 | | 2021-08-01T16:00:00 | 10 | 20 | 此 state class 以前由 state class `measurement` 与 `last_reset` 值组合表示。这种方法已被弃用,将被解释为具有自动 last reset 的 `total_increasing` state class。 --- url: /developers/blog/2021-08-24-supervisor_update.md --- 距离我们上次发布关于 Supervisor 的变更已经有一段时间了。以下是过去一年的一些亮点以及未来的计划。这些信息主要针对 add-on 开发者,但这里也有一些适合所有人的内容。如果你还没有看到,我们在[主站发布了一篇博客][main_blog],建议你阅读。 ## Snapshot 到 Backup 首先,正如[主站上的博客][main_blog]中提到的,我们已经开始从"snapshot"这一名称(自 Supervisor 诞生之初就一直使用)向更容易被识别的"backup"过渡。 这些变更现已在 Supervisor 的 `dev` 频道上线,你可以开始测试和调整你的工具/add-ons,确保在用户使用时它们仍然能正常工作。 ### API 变更 随着从"snapshot"到"backup"的过渡,Supervisor API 中增加了一个新的基础部分 [`/backups`][supervisor_api_backups],它的运作方式与 [`/snapshots`][supervisor_api_snapshots] 相同,拥有旧部分的所有相同 endpoints,但有两个关键区别: * 如果你访问 `/backups`,返回的数据现在将是 `{"backups": []}` 而不是 `{"snapshots": []}` * 要删除 snapshot,你现在必须使用 `DELETE` HTTP 方法配合 `/backups` endpoint,此前同时支持 `POST` 和 `DELETE`。 旧的 [`/snapshots`][supervisor_api_snapshots] endpoints 现已弃用,计划于今年第四季度移除。 ### Backup 结构变更 为了保持一致性,我们还更改了 backup tar 中 meta 文件的名称,从 `snapshot.json` 改为 `backup.json`。如果你的工具使用了该文件,你应该查找这两种文件,这样你的工具就可以同时适用于现有和新备份。 ## 流式 ingress 一些 add-ons 需要接收用户传来的大量数据,例如上传。此前,运行在 ingress 后面的 add-ons 每个请求的限制为 16 MB,这仍然是默认值。如果你需要接收更大的负载,可以通过在 add-on 配置中将 `ingress_stream` 设置为 `True` 来启用此功能。这样做时,请求将从客户端流式传输到你的 add-on,且请求没有大小限制,几乎没有任何开销。 请注意,并非所有 webservers 默认都能处理此功能,因此你可能需要对其进行调整。 ## 弃用的 API endpoints 在过去几年中,我们重组了部分 API endpoints,但同时也保留了旧 endpoints 的可用性。如果你的工具/add-ons 使用了任何弃用的 endpoints,你应该立即迁移到新 endpoints。所有弃用的 endpoints 计划于今年第四季度移除。 以下是弃用的 endpoints 及其替代项列表: 弃用的 endpoints | 替代为 \-- | -- `/homeassistant/*` | `/core/*` `/snapshots/*` | `/backups/*` 此外,以下内容也已弃用,并计划于今年第四季度移除。 * 环境变量 `HASSIO_TOKEN` 已被 `SUPERVISOR_TOKEN` 替代。 * 使用 `X-Hassio-Key` header 已被[使用带 Bearer token 的 `Authorization`][api_example]替代。 * 使用 `http://hassio/` 与 Supervisor 通信已被 `http://supervisor/` 替代。 ## Supervised 安装 目前维护[supervised installation][supervised_installation]的体验并不理想。大多数用户用来安装的[脚本][supervised_script]落后于 Supervisor 对主机的要求。由于没有真正的升级路径,使用它的用户需要手动调整安装。 最近我们创建了 [OS Agent][os_agent],如[主站上的博客][main_blog]中所述。这改善了主机操作系统与 Supervisor 之间的通信,并引入了更多功能。为了利用这些功能,当前 supervised 安装的用户必须手动安装 OS Agent。 作为替代方案,可以将 supervised installation 打包并分发为 deb 包,以便在主机上使用 `apt` 安装和升级。为了使这可行,我们正在寻找一个人(或一群人)来创建和维护这种类型的部署,使 supervised installation 方法与我们的 OS 保持同等水平,更重要的是让用户在主机上进行必要的更新更容易。 如果你对这些变更有疑问,欢迎在[我们的 Discord 服务器][discord]上的 `#devs_supervisor` 频道中咨询。 下次再见 👋 [discord]: https://discord.gg/c5DvZ4e [main_blog]: https://www.home-assistant.io/blog/2021/08/24/supervisor-update/ [supervisor_api_backups]: /docs/api/supervisor/endpoints#backup [supervisor_api_snapshots]: /docs/api/supervisor/endpoints#backup [supervised_installation]: https://github.com/home-assistant/architecture/blob/master/adr/0014-home-assistant-supervised.md [supervised_script]: https://github.com/home-assistant/supervised-installer [os_agent]: https://github.com/home-assistant/os-agent [api_example]: /docs/api/supervisor/examples#get-network-information-with-curl --- url: /developers/blog/2021-09-20-state_class_total.md --- 注意:本文于 2021-10-21 进行了编辑,移除了对 total accumulated increases 和 decreases 的引用,这些内容已被移除且从未包含在 Home Assistant 2021.10 版本中。 新增了一个 state class `total`,并且 `last_reset` 属性已重新添加到 `SensorEntity` 中,不再被弃用。此次变更的目的是支持那些使用 `total_increasing`(在 Home Assistant 2021.9 中引入)过于受限无法覆盖的情况。注意,为 state class `measurement` 的 sensor 设置 `last_reset` 仍然被弃用。 ### 状态类别 共有 3 个已定义的 state class: * `measurement`,state 表示当前时间的测量值,例如温度、电功率等。对于受支持的 sensor,会定期更新最小值、最大值和平均值统计。 * `total`,state 表示一个既可增加又可减少的总量,例如净能量电表。当受支持时,会定期更新 sensor 自首次添加以来值的累积增长或下降。 * `total_increasing`,单调递增的总量,例如消耗的气体、水或能量的数量。当受支持时,会定期更新 sensor 自首次添加以来值的累积增长。 #### 状态类别 `total` 对于 state class 为 `total` 的 sensor,`last_reset` 属性可选择性地设置,以获取对 meter cycle 的手动控制。 Sensor 首次添加到 Home Assistant 时的 state 被用作初始零点。当 `last_reset` 发生变化时,零点将被设置为 0。 如果未设置 last\_reset,则在计算 `sum` 统计时使用 sensor 首次添加时的值作为零点。 不设置 last\_reset 的 state class `total` 示例: | t | state | sum | | :--------------------- | -----: | -----: | | 2021-08-01T13:00:00 | 1000 | 0 | | 2021-08-01T14:00:00 | 1010 | 10 | | 2021-08-01T15:00:00 | 0 | -1000 | | 2021-08-01T16:00:00 | 5 | -995 | 设置 last\_reset 的 state class `total` 示例: | t | state | last\_reset | sum | | :--------------------- | -----: | ------------------- | -----: | | 2021-08-01T13:00:00 | 1000 | 2021-08-01T13:00:00 | 0 | | 2021-08-01T14:00:00 | 1010 | 2021-08-01T13:00:00 | 10 | | 2021-08-01T15:00:00 | 1005 | 2021-08-01T13:00:00 | 5 | | 2021-08-01T16:00:00 | 0 | 2021-09-01T16:00:00 | 5 | | 2021-08-01T17:00:00 | 5 | 2021-09-01T16:00:00 | 10 | 新 meter cycle 开始时初始 state 不是 0,但使用 0 作为零点的 state class `total` 示例: | t | state | last\_reset | sum | | :--------------------- | -----: | ------------------- | -----: | | 2021-08-01T13:00:00 | 1000 | 2021-08-01T13:00:00 | 0 | | 2021-08-01T14:00:00 | 1010 | 2021-08-01T13:00:00 | 10 | | 2021-08-01T15:00:00 | 1005 | 2021-08-01T13:00:00 | 5 | | 2021-08-01T16:00:00 | 5 | 2021-09-01T16:00:00 | 10 | | 2021-08-01T17:00:00 | 10 | 2021-09-01T16:00:00 | 15 | #### 状态类别 `total_increasing` 对于 state\_class 为 `total_increasing` 的 sensor,减少的值被解释为新 meter cycle 的开始或 meter 的更换。集成必须确保当从含有 measurement noise 的 sensor 计算值时,值不会因误操作而减少。此 state class 适用于 gas meter、electricity meter、water meter 等。 Sensor 首次添加到 Home Assistant 时的 state 被用作初始零点。当检测到新的 meter cycle 时,零点将被设置为 0。 请参阅下方表格了解这对统计的影响。 具有新 meter cycle 的 state class `total_increasing` 示例: | t | state | sum | | :--------------------- | -----: | ---: | | 2021-08-01T13:00:00 | 1000 | 0 | | 2021-08-01T14:00:00 | 1010 | 10 | | 2021-08-01T15:00:00 | 0 | 10 | | 2021-08-01T16:00:00 | 5 | 15 | 新 meter cycle 开始时初始 state 不是 0,但使用 0 作为零点的 state class `total_increasing` 示例: | t | state | sum | | :--------------------- | -----: | ---: | | 2021-08-01T13:00:00 | 1000 | 0 | | 2021-08-01T14:00:00 | 1010 | 10 | | 2021-08-01T15:00:00 | 5 | 15 | | 2021-08-01T16:00:00 | 10 | 20 | --- url: /developers/blog/2021-10-26-config-entity.md --- Home Assistant Core 2021.11 引入了两个新概念,使设备管理更加容易: device configuration URL 和 entity categories。 ### 设备配置 URL 现在可以提供一个 configuration\_url 作为 device registry 信息的一部分。 configuration\_url 在 device card 中使用,允许用户访问设备 以进行在 Home Assistant 中不可用的配置或诊断。 注意,链接到的 URL 不由 Home Assistant 代理,因此在远程连接到 Home Assistant 时通常无法使用。 [![显示访问设备的截图](/img/en/blog/2021-10-26-config-entity/configuration_url.png)](/img/en/blog/2021-10-26-config-entity/configuration_url.png) ### 实体类别 实体现在有一个可选属性 `entity_category`,用于分类非 primary 实体。对于允许更改设备配置的实体,设置为 `config`, 例如,一个可以开关设备背景照明的 switching entity。对于暴露设备的某些配置参数 或诊断信息但不允许更改它的实体,设置为 `diagnostic`,例如,显示 RSSI 或 MAC 地址(含允许值)的 sensor。 设置了 `entity_category` 的实体: * 不包含在针对整个设备或 area 的 service call 中。 * 默认不暴露给 Google Assistant 或 Alexa。 * 显示在设备配置页面的独立 card 上。 * 不出现在自动生成的 Lovelace Dashboards 上。 [![显示 entity categories 分离的截图](/img/en/blog/2021-10-26-config-entity/entity_categories.png)](/img/en/blog/2021-10-26-config-entity/entity_categories.png) --- url: /developers/blog/2022-02-18-paper-elements.md --- 在 Home Assistant Core 2022.3 版本中,我们正在 Frontend Repository 中移除所有 `paper-dropdown-menu` 和 `paper-input` elements。这意味着任何之前在卡片或卡片编辑器中使用这些 elements 的 custom card 将无法正确渲染,需要更新其代码库。 使用 Home Assistant Frontend 中 elements 的 Custom Cards 从未被支持。 ## 为什么这么做? 我们正在将代码库从已弃用的 `paper` elements 转换为 Google 的新 [Material Web Components](https://github.com/material-components/material-components-web-components)。这是为了使我们的前端保持与最新组件和功能同步。 ## Custom cards 应该怎么做? 我们的建议是使用 [Scoped Custom Element Registry](https://github.com/lit/lit/tree/main/packages/labs/scoped-registry-mixin) 在你的 custom card 中打包 Material Web Components。从 Home Assistant 2022.3 版本开始,Home Assistant Frontend 加载了为此所需的[polyfill](https://github.com/webcomponents/polyfills/tree/master/packages/scoped-custom-element-registry)。 这将允许任何 custom card 利用 Lovelace Editors 中使用的相同 MWC elements。你可以在 [Boilerplate Card](https://github.com/custom-cards/boilerplate-card) 中看到这种用法的示例。其他 HA elements(如图标选择器 ``)不支持以同样的方式使用。 更多信息请参见[这篇旧博客文章](https://developers.home-assistant.io/blog/2020/10/02/lazyMoreInfo#what-about-external-elements)。 --- url: /developers/blog/2022-02-28-opt-in-remove-device.md --- 在 Home Assistant Core 2022.3 版本中,[Erik Montnemery](https://github.com/emontnemery) 添加了[支持](https://github.com/home-assistant/core/pull/66188),允许任何集成选择(opt in)在 Home Assistant 界面的设备页面上显示"删除设备"按钮。 请参阅我们的[开发者文档](/developers/device_registry_index.md#removing-devices)了解如何在集成中实现此功能。 到目前为止,已有五个集成选择加入了此功能: * [Google Cast](https://github.com/home-assistant/core/pull/66808) * [MQTT](https://github.com/home-assistant/core/pull/66766) * [MySensors](https://github.com/home-assistant/core/pull/67128) * [RFXCOM RFXtrx](https://github.com/home-assistant/core/pull/58252) * [Tasmota](https://github.com/home-assistant/core/pull/66811) ## 为什么需要这个功能? 在此功能添加之前,建议集成自动清理 config entry 中的过时设备。但并非所有集成都能自动确定设备是否应被移除,因此在某些情况下仍需要一种让用户自行选择的手动选项。 为满足此需求,一些集成实现了一个集成特定的 websocket command 并附带前端支持,以允许手动移除设备。有了这个新功能,集成不再需要添加任何 websocket 或前端代码,只需实现后端回调函数即可支持手动设备移除。 Happy days! --- url: /developers/blog/2022-03-20-update-entity.md --- Home Assistant 2022.4 将提供一个全新的 entity platform: `update` entity。 `update` entity 可由集成提供,用于向 Home Assistant 用户指示设备或服务有可用的更新。它允许你提供关于更新的附加信息,例如可用最新版本、发布说明摘要以及在线完整发布公告的链接。 此外,可以实现 `install` 方法,使用户能够直接从 Home Assistant 中安装更新。 向你的集成添加 `update` platform 相对简单,因为它只需要几个属性和(如果集成支持的话)一个 `install` 方法。大多数其他细节由 Home Assistant 自动处理。 在 Home Assistant Core [2021.12](https://www.home-assistant.io/blog/2021/12/11/release-202112/#brand-new-configuration-panel) 中,我们将由 Supervisor 提供的更新移到了 Configuration 面板。通过使用这个新 platform,我们将能够在不久的将来通过新 entities 提供的信息对其进行扩展。 请参阅我们的[开发者文档](/developers/core/entity/update.md)了解如何在集成中实现此功能。 如果你的集成此前提供了一个带有 `update` device class 的 `binary_sensor` 或 `button` entity,请考虑用 `update` entity 替换它们。 --- url: /developers/blog/2022-03-30-2022.4-new-dev-features.md --- 2022.4 中有一些面向开发者的新功能: * [Integration Type]:集成现在可以标记自己为 helper。 * [Backup platform]:集成现在可以通过实现新的 backup platform 在备份期间暂停工作。 * entity registry 中的 hidden\_by:实体现在可以通过 entity registry 隐藏。当向 voice assistants 等外部 UI 暴露实体时,这些实体应默认为不包含。 * \[新的和更新的 selectors]:我们添加了一堆新的 selectors,可用于 blueprints、services.yaml 和 config flows。 * \[backend flows 中的 selectors]:现在可以在 config flows 中使用 `selector` helper。它的配置和渲染方式与 services.yaml/blueprints 中的 selectors 完全相同。 * [ha-form context]:Context 是一种允许 selectors 根据其他字段的值进行动态配置的新方式。目前仅适用于 attribute selector。 * \[config flow fields 的 helper text]:Config flow fields 现在可以有一个 description。 * [Schema Config Flow helper]:基于 config schema 创建 config flows 的新 helper。[示例实现](https://github.com/home-assistant/core/blob/dev/homeassistant/components/switch_as_x/config_flow.py) * [Show Menu step]:数据录入流程中的这个新步骤会向用户显示一个菜单。 * [Fan speed]:我们引入了一个新格式,此过渡现已完成。 * [Device State Attributes]:此属性的向后兼容支持在自 Home Assistant 2021.4 弃用后已被移除。请改用 `extra_state_attributes`。 * \[不带 width/height 的 Cameras]:已移除不带 width/height 的 cameras 的兼容层。 * [Calendar offset]:`calculate_offset` 和 `is_offset_reached` 的 Calendar 方法签名已更改,为 Calendar 的 typing 改进做准备,并可能进一步简化 offsets。 [ha-form context]: https://github.com/home-assistant/frontend/pull/12062 [Integration Type]: /docs/creating_integration_manifest [Backup platform]: /docs/core/platform/backup [New and updated selectors]: https://next.home-assistant.io/docs/blueprint/selectors/ [Selectors in backend flows]: /docs/data_entry_flow_index#show-form [config flow helper text for fields]: /docs/data_entry_flow_index#show-form [Schema Config Flow helper]: https://github.com/home-assistant/core/blob/dev/homeassistant/helpers/schema_config_entry_flow.py [Show Menu step]: /docs/data_entry_flow_index#show-menu [Fan speed]: https://github.com/home-assistant/core/pull/67743 [Device State Attributes]: https://github.com/home-assistant/core/pull/67837 [Cameras without width/height]: https://github.com/home-assistant/core/pull/68039 [Calendar offset]: https://github.com/home-assistant/core/pull/68724 --- url: /developers/blog/2022-04-02-support-constants-deprecation.md --- 从 Home Assistant Core 2022.5 开始,所有 `SUPPORT_*` 常量已被弃用, 每个 entity platform 都提供了一个 `EntityFeature` enum 来替代它们。 这适用于以下 platform: * **Alarm Control Panel** 已弃用的 supported feature 常量: * `SUPPORT_ALARM_ARM_AWAY` * `SUPPORT_ALARM_ARM_CUSTOM_BYPASS` * `SUPPORT_ALARM_ARM_HOME` * `SUPPORT_ALARM_ARM_NIGHT` * `SUPPORT_ALARM_ARM_VACATION` * `SUPPORT_ALARM_TRIGGER` 请改用新的 [`AlarmControlPanelEntityFeature`](/developers/core/entity/alarm-control-panel.md#supported-features) enum。 * **Camera** 已弃用的 supported feature 常量: * `SUPPORT_ON_OFF` * `SUPPORT_STREAM` 请改用新的 [`CameraEntityFeature`](/developers/core/entity/camera.md#supported-features) enum。 * **Cover** 已弃用的 supported feature 常量: * `SUPPORT_OPEN` * `SUPPORT_CLOSE` * `SUPPORT_SET_POSITION` * `SUPPORT_STOP` * `SUPPORT_OPEN_TILT` * `SUPPORT_CLOSE_TILT` * `SUPPORT_STOP_TILT` * `SUPPORT_SET_TILT_POSITION` 请改用新的 [`CoverEntityFeature`](/developers/core/entity/cover.md#supported-features) enum。 * **Climate** 已弃用的 supported feature 常量: * `SUPPORT_TARGET_TEMPERATURE` * `SUPPORT_TARGET_TEMPERATURE_RANGE` * `SUPPORT_TARGET_HUMIDITY` * `SUPPORT_FAN_MODE` * `SUPPORT_PRESET_MODE` * `SUPPORT_SWING_MODE` * `SUPPORT_AUX_HEAT` 请改用新的 [`ClimateEntityFeature`](/developers/core/entity/climate.md#supported-features) enum。 * **Humidifier** 已弃用的 supported feature 常量: * `SUPPORT_MODES` 请改用新的 [`HumidifierEntityFeature`](/developers/core/entity/humidifier.md#supported-features) enum。 * **Fan** 已弃用的 supported feature 常量: * `SUPPORT_SET_SPEED` * `SUPPORT_OSCILLATE` * `SUPPORT_DIRECTION` * `SUPPORT_PRESET_MODE` 请改用新的 [`FanEntityFeature`](/developers/core/entity/fan.md#supported-features) enum。 * **Light** 已弃用的 supported feature 常量: * `SUPPORT_EFFECT` * `SUPPORT_FLASH` * `SUPPORT_TRANSITION` 请改用新的 [`LightEntityFeature`](/developers/core/entity/light.md#supported-features) enum。 注意,以下 light 常量此前已被弃用, 因此 `LightEntityFeature` 没有为它们提供替代项。 * `SUPPORT_BRIGHTNESS` * `SUPPORT_COLOR_TEMP` * `SUPPORT_COLOR` * `SUPPORT_WHITE_VALUE` 这些情况应迁移到[新的 color modes](/developers/core/entity/light.md#color-modes)。 * **Lock** 已弃用的 supported feature 常量: * `SUPPORT_OPEN` 请改用新的 [`LockEntityFeature`](/developers/core/entity/lock.md#supported-features) enum。 * **Media Player** 已弃用的 supported feature 常量: * `SUPPORT_PAUSE` * `SUPPORT_SEEK` * `SUPPORT_VOLUME_SET` * `SUPPORT_VOLUME_MUTE` * `SUPPORT_PREVIOUS_TRACK` * `SUPPORT_NEXT_TRACK` * `SUPPORT_TURN_ON` * `SUPPORT_TURN_OFF` * `SUPPORT_PLAY_MEDIA` * `SUPPORT_VOLUME_STEP` * `SUPPORT_SELECT_SOURCE` * `SUPPORT_STOP` * `SUPPORT_CLEAR_PLAYLIST` * `SUPPORT_PLAY` * `SUPPORT_SHUFFLE_SET` * `SUPPORT_SELECT_SOUND_MODE` * `SUPPORT_BROWSE_MEDIA` * `SUPPORT_REPEAT_SET` * `SUPPORT_GROUPING` 请改用新的 [`MediaPlayerEntityFeature`](/developers/core/entity/media-player.md#supported-features) enum。 * **Remote** 已弃用的 supported feature 常量: * `SUPPORT_LEARN_COMMAND` * `SUPPORT_DELETE_COMMAND` * `SUPPORT_ACTIVITY` 请改用新的 [`RemoteEntityFeature`](/developers/core/entity/remote.md#supported-features) enum。 * **Siren** 已弃用的 supported feature 常量: * `SUPPORT_DURATION` * `SUPPORT_TONES` * `SUPPORT_TURN_OFF` * `SUPPORT_TURN_ON` * `SUPPORT_VOLUME_SET` 请改用新的 [`SirenEntityFeature`](/developers/core/entity/siren.md#supported-features) enum。 * **Vacuum** 已弃用的 supported feature 常量: * `SUPPORT_TURN_ON` * `SUPPORT_TURN_OFF` * `SUPPORT_PAUSE` * `SUPPORT_STOP` * `SUPPORT_RETURN_HOME` * `SUPPORT_FAN_SPEED` * `SUPPORT_BATTERY` * `SUPPORT_STATUS` * `SUPPORT_SEND_COMMAND` * `SUPPORT_LOCATE` * `SUPPORT_CLEAN_SPOT` * `SUPPORT_MAP` * `SUPPORT_STATE` * `SUPPORT_START` 请改用新的 [`VacuumEntityFeature`](/developers/core/entity/vacuum.md#supported-features) enum。 * **Water Heater** 已弃用的 supported feature 常量: * `SUPPORT_TARGET_TEMPERATURE` * `SUPPORT_OPERATION_MODE` * `SUPPORT_AWAY_MODE` 请改用新的 [`WaterHeaterEntityFeature`](/developers/core/entity/water-heater.md#supported-features) enum。 --- url: /developers/blog/2022-04-16-local-oauth2.md --- 从 Home Assistant Core 2022.5 开始,注册了 `config_entry_oauth2_flow.LocalOAuth2Implementation` 的集成必须对 `auth` component 有[manifest dependency](https://developers.home-assistant.io/docs/creating_integration_manifest?_highlight=manifest#dependencies)。 这是由改善 OAuth [Application Credentials](https://github.com/home-assistant/architecture/discussions/692#discussioncomment-2121633) 处理的更广泛努力所驱动的,该努力需要更改 OAuth callback 的 HTTP endpoint 注册方式。 --- url: /developers/blog/2022-04-18-calendar-data-model.md --- 从 Home Assistant Core 2022.5 开始,`CalendarDeviceEntity` 已被弃用,并由 `CalendarEntity` 取代。新 entity 拥有更明确的数据模型和简化的 websocket API。`CalendarDeviceEntity` 将在未来的 Home Assistant 版本中移除,custom components 需要迁移到新的 API。详情请参见新的 [Calendar Entity](https://developers.home-assistant.io/docs/core/entity/calendar) 开发者文档。 --- url: /developers/blog/2022-04-20-saying-goodbye-to-event_time_changed.md --- 从 Home Assistant Core 0.113 开始,我们开始迁移到使用 asyncio event loop 来调度事件。 在 2022.5 版本中,我们很高兴地宣布此过程现已完成。传统的 `time_changed` 事件(也称为 `EVENT_TIME_CHANGED`)不再每秒触发一次。监听所有事件的集成不再需要过滤掉 `EVENT_TIME_CHANGED`。在单独线程中运行的集成可能会看到轻微的性能提升,因为它们不再每秒被唤醒。 在之前的实现中,消费者会订阅 `time_changed` 事件,并在每次触发时检查时间,看是否匹配。这种模式导致大量回调,其中大部分回调会拒绝事件并继续接收回调,直到达到预期时间。 如果你的 custom integration 仍然依赖监听 `time_changed` 事件,则需要迁移到使用内置的 event helpers 之一,在大多数情况下,它们可以直接替换(只需一行)。更多信息请参阅[集成文档中的事件监听说明](https://developers.home-assistant.io/docs/integration_listen_events#tracking-time-changes)。 --- url: /developers/blog/2022-04-26-tts-say-media-source.md --- 从 Home Assistant 2022.5 开始,TTS say service 将把 media content ID 设置为 media source URI。这些需要在 media player 内部通过 media source integration 来解析。 此前,TTS integration 会将 media content ID 设置为指向 Home Assistant 的 URL,media players 无需额外操作。 Media players 需要支持 media source integration,详见[此处文档](/developers/core/entity/media-player.md#browse-media)。 --- url: /developers/blog/2022-05-03-constants-deprecations.md --- 对于 Home Assistant Core 2022.5,我们弃用了许多常量并用 enums 替换它们。 所有 `SUPPORT_*` 常量已被弃用,并在[之前发布的博文](/developers/blog/2022-04-02-support-constants-deprecation.md)中进行了总结。 此外,以下常量已被弃用: * **Alarm Control Panel** 已弃用的常量: * `FORMAT_TEXT` * `FORMAT_NUMBER` 请改用新的 [`CodeFormat`](/developers/core/entity/alarm-control-panel.md#code-formats) enum。 * **Camera** 已弃用的常量: * `STREAM_TYPE_HLS` * `STREAM_TYPE_WEB_RTC` 请改用新的 [`StreamType`](/developers/core/entity/camera.md#properties) enum。 * **Climate** 已弃用的常量: * `CURRENT_HVAC_COOL` * `CURRENT_HVAC_DRY` * `CURRENT_HVAC_FAN` * `CURRENT_HVAC_HEAT` * `CURRENT_HVAC_IDLE` * `CURRENT_HVAC_OFF` * `HVAC_MODE_AUTO` * `HVAC_MODE_COOL` * `HVAC_MODE_DRY` * `HVAC_MODE_FAN_ONLY` * `HVAC_MODE_HEAT_COOL` * `HVAC_MODE_HEAT` * `HVAC_MODE_OFF` 请改用新的 [`HVACAction`](/developers/core/entity/climate.md#hvac-action) 和 [`HVACMode`](/developers/core/entity/climate.md#hvac-modes) enums。 * **Light** 已弃用的常量: * `COLOR_MODE_UNKNOWN` * `COLOR_MODE_ONOFF` * `COLOR_MODE_BRIGHTNESS` * `COLOR_MODE_COLOR_TEMP` * `COLOR_MODE_HS` * `COLOR_MODE_XY` * `COLOR_MODE_RGB` * `COLOR_MODE_RGBW` * `COLOR_MODE_RGBWW` * `COLOR_MODE_WHITE` 请改用新的 [`ColorMode`](/developers/core/entity/light.md#color-modes) enum。 --- url: /developers/blog/2022-05-03-serviceinfo-model-improvements.md --- 从 Home Assistant Core 2022.6 开始,通过此前已弃用的 dictionary 方法访问 discovery 信息的能力已被移除。 这适用于 `DhcpServiceInfo`、`MqttServiceInfo`、`SsdpServiceInfo`、`UsbServiceInfo` 和 `ZeroconfServiceInfo` 实例。 Custom integrations 需要迁移到使用新的 dataclass properties。 --- url: /developers/blog/2022-05-12-s6-overlay-base-images.md --- 我们开始更新 base images 以使用新的 s6-Overlay v3。[迁移文章](https://github.com/just-containers/s6-overlay/blob/master/MOVING-TO-V3.md)也解释了围绕此变更的新可能性。这篇博客文章说明了使用我们的新 base images 所需的最小变更。 我们已经更新了我们的[示例 add-on](https://github.com/home-assistant/addons-example)以包含新的行为。 ## 最低要求 如果你的 add-on 的 `config.yaml` 中还没有,请添加 `init: false`。在 V3 中,S6 强制要求正确使用其 init。如果使用 Docker 默认系统 init,启动 add-on 时会看到以下错误: ``` s6-overlay-suexec: fatal: can only run as pid 1 ``` 确保你的 git repository rootfs 文件夹中的所有可执行/脚本文件已设置执行权限。你可以使用以下命令更新权限: ```sh $ git update-index --chmod=+x rootfs/etc/service.d/my-service/run ``` 如果你在 S6-overlay services 中使用 `finish` 脚本(例如,在出错时停止容器),你需要将 `s6-svscanctl -t /var/run/s6/services` 替换为 `/run/s6/basedir/bin/halt`。 ## AppArmor 你需要调整你的 [AppArmor profile](/developers/apps/presentation.md#apparmor) 使其与新 s6-Overlay 配合工作。我们更新了文档中的默认 profile。需要进行以下更改: ```txt # S6-Overlay /init ix, /bin/** ix, /usr/bin/** ix, /run/{s6,s6-rc*,service}/** ix, /package/** ix, /command/** ix, /etc/services.d/** rwix, /etc/cont-init.d/** rwix, /etc/cont-finish.d/** rwix, /run/{,**} rwk, /dev/tty rw, ``` ## `host_pid` 选项 未启用 protection mode 的 addons 可以在配置中设置 `host_pid: true`。如[文档](https://developers.home-assistant.io/docs/apps/configuration#optional-configuration-options)中所述: > 允许容器在 host PID namespace 上运行。仅适用于未受保护的 add-ons。 这存在问题,因为 S6 期望自己是 PID 1(这在其[标语](https://github.com/just-containers/s6-overlay#s6-overlay-)中明确说明),而在使用 host PID namespace 时这是不可能的。 在 V2 中,S6 实际上并没有检查自己是否作为 PID 1 运行。这就是为什么过去在此模式下它"能工作"的原因(尽管它需要一些[变通方法](https://github.com/hassio-addons/addon-glances/blob/8575d7903ef4c0a7c49e9ab32e0536bd2eb12dd6/glances/rootfs/bin/s6-nuke)来防止 s6 以此方式运行时破坏系统)。在 V3 中,S6 检查自己是否确实是 PID 1,否则拒绝启动。 要解决此问题,不要在你的 addon 中使用 s6 overlay,因为它不是为此用例设计的。你可以通过用 no-op 脚本覆盖 `/init` 然后使用正常的 docker init 系统来继续使用 addon base images。或者你可以切换到其他 base image(如 stock alpine 或 debian)并添加所需的内容。 --- url: /developers/blog/2022-05-24-entity_matches_only_removed_logbook_card.md --- 在 2022.6 之前,`entity_matches_only` 标志阻止 logbook 提供 context data,以换取在查询特定实体时的性能提升。采用新的 logbook 设计后,为特定实体选择 context data 不再是一个密集过程。无需立即采取行动,因为该标志将被忽略,你可以在方便时从任何活动代码路径中移除该标志。 --- url: /developers/blog/2022-05-31-media-player-updates.md --- 从 Home Assistant 2022.6 开始,media player integration 对 `media_player.play_media` service 进行了两项更新。`enqueue` 属性在 [PR #72406](https://github.com/home-assistant/core/pull/72406) 中已更改为 string,并在 [PR #72566](https://github.com/home-assistant/core/pull/72566) 中添加了新的 `announce` boolean 属性。 更多信息请参见更新的 [media player play\_media 文档](/developers/core/entity/media-player.md#play-media)。 --- url: /developers/blog/2022-06-02-update_coordinator-context.md --- 从 Home Assistant 2022.7 开始,update coordinator 支持跟踪每个监听 entity 的 context。这可用于基于启用的 entities 限制对 API 的请求。 对于依赖 update coordinators 并检查内部变量 `self._listeners` 和/或重载方法 `async_remove_listener()` 以检测监听器何时耗尽的 custom components,这可能会是一个 breaking change。改用 `async_update_listeners()` 触发对所有监听器的更新,并重载 `_unschedule_refresh()` 以检测监听器耗尽的情况。 更多信息请参见更新的[集成数据获取文档](/developers/integration_fetching_data.md#polling-api-endpoints)。 --- url: /developers/blog/2022-06-07-dataflow-constants-deprecation.md --- 从 Home Assistant Core 2022.7 开始,所有用于 data entry flow result types 的 `RESULT_TYPE_*` 常量已被弃用: * `RESULT_TYPE_FORM` * `RESULT_TYPE_CREATE_ENTRY` * `RESULT_TYPE_ABORT` * `RESULT_TYPE_EXTERNAL_STEP` * `RESULT_TYPE_EXTERNAL_STEP_DONE` * `RESULT_TYPE_SHOW_PROGRESS` * `RESULT_TYPE_SHOW_PROGRESS_DONE` * `RESULT_TYPE_MENU` 请改用新的 `FlowResultType` enum。 --- url: /developers/blog/2022-06-13-unsafe_reloads_during_entry_setup.md --- 在 2022.7 之前,可以在 config entry 仍在设置过程中触发其重新加载。在 config entry 设置期间重新加载通常会导致意外的失败模式,需要重启 Home Assistant 才能使 config entry 恢复到正常状态。现在在设置期间尝试重新加载会抛出 `OperationNotAllowed` 异常。 --- url: /developers/blog/2022-06-14-number_entity_refactoring.md --- `NumberEntity` 现在支持温度单位转换,采用的模式与 `SensorEntity` 支持的单位转换类似。 对于 device class 设置为 `temperature` 的 number entities,温度转换将根据用户配置的温度单位自动进行。 为此,custom component 集成应更新为覆写属性 `native_max_value`、`native_min_value`、`native_step`、`native_unit_of_measurement`、`native_value`,而不是 `max_value`、`min_value`、`step`、`unit_of_measurement`、`value`,并覆写方法 `async_set_native_value` 和 `set_native_value`,而不是 `async_set_value` 和 `set_value`。 同样的重命名也已应用于 `_attr_*` 属性和 `NumberEntityDescription` 的成员。 在 Home Assistant Core 2023.1 中,覆写 `async_set_value`、`max_value`、`min_value`、`set_value`、`step`、`unit_of_measurement`、`value`,设置 `_attr_max_value`、`_attr_min_value`、`_attr_unit_of_measurement`、`_attr_step`、`_attr_value` 以及在 `NumberEntityDescription` 实例上设置 `max_value`、`min_value`、`unit_of_measurement`、`step` 将不再受支持。 --- url: /developers/blog/2022-06-27-weather_entity_refactoring.md --- `WeatherEntity` 现在支持温度单位转换,采用的模式与 `NumberEntity` 和 `SensorEntity` 支持的单位转换类似。 降水、气压、温度、能见度和风速会根据用户配置的单位系统自动转换。此外,用户可以为特定的 weather entities 覆盖单位。 为此,custom component 集成应更新为覆写属性 `native_precipitation_unit`、`native_pressure`、`native_pressure_unit`、`native_temperature`、`native_temperature_unit`、`native_visibility`、`native_visibility_unit`、`native_wind_speed` 和 `native_wind_speed_unit`,而不是 `precipitation_unit`、`pressure`、`pressure_unit`、`temperature`、`temperature_unit`、`visibility`、`visibility_unit`、`wind_speed` 和 `wind_speed_unit`。 相同的重命名也已应用于相应的 `_attr_*` 属性以及 `Forecast` typed dict 的成员。 在 Home Assistant Core 2023.1 中,覆写 `precipitation_unit`、`pressure`、`pressure_unit`、`temperature`、`temperature_unit`、`visibility`、`visibility_unit`、`wind_speed`、`wind_speed_unit`,设置 `_attr_precipitation_unit`、`_attr_pressure`、`_attr_pressure_unit`、`_attr_temperature`、`_attr_temperature_unit`、`_attr_visibility`、`_attr_visibility_unit`、`_attr_wind_speed`、`_attr_wind_speed_unit` 以及在 `Forecast` 实例上设置 `precipitation`、`pressure`、`temperature`、`templow`、`wind_speed` 将不再受支持。 --- url: /developers/blog/2022-07-08-config_entry_forwards.md --- 在 2022.8 之前,如果 config entry 加载的 platforms 中有一个尚未加载,那么 `await` config entry platforms forwards 就会导致死锁。 集成需要重构,用等待 `hass.config_entries.async_forward_entry_setups` 替换对 `hass.config_entries.async_setup_platforms` 的调用,以确保 Home Assistant 不会在 entities 和 platforms 仍在设置时意外重新加载集成。 `hass.config_entries.async_setup_platforms` 计划在 2022.12 中移除。 --- url: /developers/blog/2022-07-08-generic-store.md --- 从 Home Assistant Core 2022.8 开始,Store(来自 `homeassistant/helpers/storage.py`)被定义为 Generic `Store(Generic[_T])`。建议在 Store 定义中指定要存储的数据类型。它应该是 JSON 可序列化的(dict 或 list),例如: * 使用 dict 的标准定义:`self._store = Store[dict[str, int]](hass, STORAGE_VERSION, STORAGE_KEY)` * 使用 TypedDict:`self._store = Store[EnergyPreferences](hass, STORAGE_VERSION, STORAGE_KEY)` * 访问现有 Store:`store: Store[dict[str, Any]] = hass.data[DOMAIN][DATA_STORE]` * 继承 Store:`class MyCustomStorage(Store[list[int]]):` 有关 generics 的更多信息,请参阅 [PEP 483](https://peps.python.org/pep-0483/#generic-types)。 --- url: /developers/blog/2022-07-10-entity_naming.md --- 我们正在改进和标准化实体命名。这将允许我们在未来的 UI 中以正确的上下文展示实体,同时从代码库中移除一些容易出错的实体名称魔法处理。 简要说明如下: * 设备保持现有的名称,例如 "Dishwasher"。 * 实体将拥有自己的名称(不含 device、area)。或者,它们可以选择将名称设置为 `None`(在这种情况下它们继承设备名称)。 * 设备、Area 和实体名称都以大写字母开头,其余单词为小写(除非是品牌名称/专有名词/缩写)。 * 每个已迁移以遵循这些规则的实体应将 [`has_entity_name`](https://developers.home-assistant.io/docs/core/entity#entity-naming) 属性设置为 `True`。 在迁移期间,我们使用 `has_entity_name` 属性来创建"向后兼容"的 friendly names。未来,我们可以为未设置此属性的实体显示 deprecation warnings,之后完全移除它。 前端也将为此进行调整。它将能够以多种方式展示实体/设备,选择最适合上下文的方式。 ### 示例 以下示例说明了设备和实体应如何按照新建议命名(类型:实体名称 / state 对象的 `friendly_name` / `entity_id`)。 开发者只需设置设备名称和实体名称,`friendly_name` 和 `entity_id` 会自动生成。 * 设备: Dishwasher * 开关: `None` / Dishwasher / `switch.dishwasher` * 传感器: Power usage / Dishwasher Power usage / `sensor.dishwasher_power_usage` * 设备: Laundry machine * 开关: `None` / Laundry machine / `switch.laundry_machine` * 传感器: Power usage / Laundry machine Power usage / `sensor.laundry_machine_power_usage` ## 背景 Home Assistant 将用户的家庭建模为三个层次: * Area(例如 Living Room) * Device(例如 Switch) * Entity(例如 Power usage) Home Assistant 中的 entities 是设备提供的数据点,可以表示特定的控制(设备的开关、设备的灯光)。 由于 Home Assistant 在其存在的头几年中只有 entities,因此 Home Assistant 中的许多功能都是围绕 entities 构建的,最主要的就是 UI。 假设你有 2 个名为 Dishwasher 和 Laundry Machine 的 Shelly 开关,它们都报告 power usage。两个设备都有一个 switch entity 和一个 power sensor。之前的设备和实体看起来是这样的(类型:实体名称 / state 对象 `friendly_name` / `entity_id`): * 设备: Dishwasher * 开关: Dishwasher Switch / Dishwasher Switch / `switch.dishwasher_switch` * 传感器: Dishwasher Power usage / Dishwasher Power usage / `sensor.dishwasher_power_usage` * 设备: Laundry machine * 开关: Laundry machine Switch / Laundry machine Switch / `switch.laundry_machine_switch` * 传感器: Laundry machine Power usage / Laundry machine Power usage / `sensor.laundry_machine_power_usage` ### 为什么这是个问题? 设备名称没有单一的事实来源,因为实体名称中包含了设备名称。 因为我们将设备名称包含在实体名称中"解决"了 UI 和 `entity_id` 的问题,我们现在将这个解决方案应用到了所有使用实体的地方,不得不围绕这个解决方案进行变通处理。 这种命名方案使得将 UI 从长实体列表迁移到 area->device->entity 的分层视图变得不必要地困难。 --- url: /developers/blog/2022-07-29-device-tracker_source-type-deprecation.md --- 对于 Home Assistant Core 2022.9,我们弃用了 `device_tracker` 的 `SOURCE_TYPE_*` 常量。 请改用新的 [`SourceType`](/developers/core/entity/device-tracker.md) enum。 已弃用的常量: * `SOURCE_TYPE_GPS` * `SOURCE_TYPE_ROUTER` * `SOURCE_TYPE_BLUETOOTH` * `SOURCE_TYPE_BLUETOOTH_LE` --- url: /developers/blog/2022-08-08-bluetooth-api-changes.md --- 对于 Home Assistant Core 2022.9,我们修改了 `PassiveBluetoothProcessorCoordinator` 和 `PassiveBluetoothDataProcessor` bluetooth API,使 `PassiveBluetoothProcessorCoordinator` 负责解析。然后 coordinator 将解析后的数据推送给 `PassiveBluetoothDataProcessor` 实例。 PassiveBluetoothProcessorCoordinator 现在接收一个必填的 update\_method 回调,该回调接收 bluetooth advertisements(形式为 BluetoothServiceInfoBleak),并返回应移交给任何订阅的 PassiveBluetoothDataProcessor 的数据: ```python def my_parser(service_info: BluetoothServiceInfoBleak) -> MyDataClass: ... return MyDataClass( a=some_parsed_data, b=some_other_parsed_data, ) coordinator = PassiveBluetoothProcessorCoordinator( hass, _LOGGER, address=address, mode=BluetoothScanningMode.PASSIVE, update_method=my_parser, ) ``` PassiveBluetoothDataProcessor 仍然接收一个 update\_method,但它现在接收的不是 BluetoothServiceInfoBleak,而是来自 PassiveBluetoothProcessorCoordinator 的 update\_method 返回的数据。它仍然应该像以前一样返回一个 `PassiveBluetoothDataUpdate`: ```python def sensor_update_to_bluetooth_data_update( sensor_update: MyDataClass, ) -> PassiveBluetoothDataUpdate: """Convert a sensor update to a bluetooth data update.""" ... return PassiveBluetoothDataUpdate( ... ) processor = PassiveBluetoothDataProcessor(sensor_update_to_bluetooth_data_update) ``` 所有内置集成都已完成转换,因此可以查看它们以获取更多示例。 此变更将有助于那些在加载 platform 之前就需要开始解析数据的集成(例如,要加载的 platform 列表取决于 advertisements 中的数据),或者单一 advertisement 驱动多个 platforms 的情况(你不必解析广播两次)。 --- url: /developers/blog/2022-08-15-automation-action-type-deprecation.md --- 对于 Home Assistant Core 2022.9,我们弃用了来自 `homeassistant/components/automation/__init__.py` 的 `AutomationActionType`、`AutomationTriggerInfo` 和 `AutomationTriggerData`。 它们被来自 `homeassistant/helpers/trigger.py` 的 `TriggerActionType`、`TriggerInfo` 和 `TriggerData` 替代。 | 旧 | 新 | | --- | --- | | `AutomationActionType` | `TriggerActionType` | | `AutomationTriggerInfo` | `TriggerInfo` | | `AutomationTriggerData` | `TriggerData` | 此外,我们建议将 `async_attach_trigger` 函数的 `automation_info` 参数名更新为 `trigger_info`。 --- url: /developers/blog/2022-08-18-light_white_value_removed.md --- `LightEntity` 不再支持 `white_value`,它已被[color mode](/developers/core/entity/light.md#color-modes) `white` 替代。 ### 背景 Light 的 `white_value` 在 Home Assistant Core 2021.4 中通过 [PR #47720](https://github.com/home-assistant/core/pull/47720)被弃用, 并在 Home Assistant Core 2021.7 中通过 [PR #51411](https://github.com/home-assistant/core/pull/51411)被 color mode `white` 替代。 --- url: /developers/blog/2022-08-24-globally_accessible_hass.md --- 现在可以通过调用 `core.async_get_hass()` 获取 `HomeAssistant` 实例的引用。 虽然这意味着不再严格要求传递 `hass`,但建议仍然只在传递 `hass` 非常困难或根本无法传递的地方使用 `core.async_get_hass`。 一个可以使用它的示例是 voluptuous validators,它们之前无法访问 `hass`,因为 voluptuous 没有办法将用户数据传递给 validators。 ```python @callback def async_get_hass() -> HomeAssistant: """Return the HomeAssistant instance. Raises LookupError if no HomeAssistant instance is available. This should be used where it's very cumbersome or downright impossible to pass hass to the code which needs it. """ ``` --- url: /developers/blog/2022-08-25-issue_registry_moved_to_helpers.md --- Issue registry 已从 `homeassistant.components.repairs` 移至 `homeassistant.helpers`,现在在 bootstrapping 过程中与其他 registries 一起非常早地加载,早于任何 integrations 的设置。 这允许在配置验证期间创建 issues。 --- url: /developers/blog/2022-09-06-media-player-repeat-mode-deprecation.md --- 从 Home Assistant Core 2022.10 开始,以下 media player 常量已被弃用: * `MEDIA_CLASS_ALBUM` * `MEDIA_CLASS_APP` * `MEDIA_CLASS_ARTIST` * `MEDIA_CLASS_CHANNEL` * `MEDIA_CLASS_COMPOSER` * `MEDIA_CLASS_CONTRIBUTING_ARTIST` * `MEDIA_CLASS_DIRECTORY` * `MEDIA_CLASS_EPISODE` * `MEDIA_CLASS_GAME` * `MEDIA_CLASS_GENRE` * `MEDIA_CLASS_IMAGE` * `MEDIA_CLASS_MOVIE` * `MEDIA_CLASS_MUSIC` * `MEDIA_CLASS_PLAYLIST` * `MEDIA_CLASS_PODCAST` * `MEDIA_CLASS_SEASON` * `MEDIA_CLASS_TRACK` * `MEDIA_CLASS_TV_SHOW` * `MEDIA_CLASS_URL` * `MEDIA_CLASS_VIDEO` * `MEDIA_TYPE_ALBUM` * `MEDIA_TYPE_APP` * `MEDIA_TYPE_APPS` * `MEDIA_TYPE_ARTIST` * `MEDIA_TYPE_CHANNEL` * `MEDIA_TYPE_CHANNELS` * `MEDIA_TYPE_COMPOSER` * `MEDIA_TYPE_CONTRIBUTING_ARTIST` * `MEDIA_TYPE_EPISODE` * `MEDIA_TYPE_GAME` * `MEDIA_TYPE_GENRE` * `MEDIA_TYPE_IMAGE` * `MEDIA_TYPE_MOVIE` * `MEDIA_TYPE_MUSIC` * `MEDIA_TYPE_PLAYLIST` * `MEDIA_TYPE_PODCAST` * `MEDIA_TYPE_SEASON` * `MEDIA_TYPE_TRACK` * `MEDIA_TYPE_TVSHOW` * `MEDIA_TYPE_URL` * `MEDIA_TYPE_VIDEO` * `REPEAT_MODE_ALL` * `REPEAT_MODE_OFF` * `REPEAT_MODE_ONE` * `REPEAT_MODES` 请改用新的 `MediaClass`、`MediaType` 和 `RepeatMode` enums。 使用 `STATE_*` 常量来反映 media player state 的做法也被弃用。请改用新的 `MediaPlayerState` enum。 --- url: /developers/blog/2022-09-16-bluetooth-unavailable-api-changes.md --- 对于 Home Assistant Core 2022.10,我们修改了 `async_track_unavailable` bluetooth API,使其向回调发送最后一个 `BluetoothServiceInfoBleak`,而不是 `address`。 以下是一个使用示例: ```python from homeassistant.components import bluetooth def _unavailable_callback(info: bluetooth.BluetoothServiceInfoBleak) -> None: _LOGGER.debug("%s is no longer seen", info.address) cancel = bluetooth.async_track_unavailable(hass, _unavailable_callback, "44:44:33:11:23:42", connectable=True) ``` --- url: /developers/blog/2022-09-28-deprecate-conversion-utilities.md --- 从 Home Assistant Core 2022.10 开始,以下工具已被弃用: * `homeassistant/util/distance` * `homeassistant/util/pressure` * `homeassistant/util/speed` * `homeassistant/util/temperature` * `homeassistant/util/volume` 请改用 `homeassistant/util/unit_conversion` 中相应的静态类: * `DistanceConverter` * `PressureConverter` * `SpeedConverter` * `TemperatureConverter` * `VolumeConverter` --- url: /developers/blog/2022-09-28-new_sensor_device_classes.md --- 已添加多个新的 sensor device classes: * `distance`,以 `cm`、`ft`、`in`、`km`、`m`、`mi`、`mm`、`yd` 之一测量的距离 * `speed`,以 `ft/s`、`in/d`、`in/h`、`km/h`、`kn`、`m/s`、`mm/d`、`mph` 之一测量的速度 * `volume`,以 `fl. oz.`、`ft³`、`gal`、`L`、`mL`、`m³` 之一测量的体积 * `weight`,以 `g`、`kg`、`lb`、`mg`、`oz`、`µg` 之一测量的质量 与 `pressure` 和 `temperature` sensors 类似,用户可以在 UI 中自由地为使用任何新 device class 的 sensors 选择显示单位。 ### 长期统计 长期统计将 `distance` 存储为 `m`,`speed` 存储为 `m/s`,`volume` 存储为 `m³`,`weight` 存储为 `g`。 对于修改为其中一种新 device class 的现有 sensors,统计将继续以 sensor 的 `state_unit` 记录,但用户将获得选项,可以将现有统计转换为标准化单位。 --- url: /developers/blog/2022-09-29-statistics_refactoring.md --- 长期统计现在允许以与存储时不同的单位显示统计。例如,可以将以 `kWh` 存储的统计显示为 `Wh`、`kWh` 或 `MWh`。 这些变更通过一系列 PR 实现: * https://github.com/home-assistant/core/pull/78031 * https://github.com/home-assistant/core/pull/78578 * https://github.com/home-assistant/core/pull/79370 背景是我们允许覆盖多个 sensor device class 的单位,此覆盖在查看长期统计时也应反映出来。 这会影响调用以下 WS API 的代码作者: * `recorder/adjust_sum_statistics` - 新增了一个必填参数 `adjustment_unit_of_measurement`,它定义了 `adjustment` 参数使用的单位。 * `recorder/statistics_during_period` - 对于从 sensor entities 生成的统计,返回统计的单位将转换为 sensor 的 `unit_of_measurement`。此行为可以通过传递可选的 `units` 参数来控制。 --- url: /developers/blog/2022-10-10-add-options-to-SelectEntityDescription.md --- 从 Home Assistant Core 2022.11 开始,`options` 作为 `SelectEntityDescription` 的标准属性可用。 如果自定义集成之前实现了自定义的 `options` 属性,可能会导致问题。 请通过删除或重命名自定义 `options` 属性来调整自定义集成。 --- url: /developers/blog/2022-10-14-deprecate-unit-system.md --- 从 Home Assistant Core 2022.11 开始,`IMPERIAL_SYSTEM` 已弃用,由 `US_CUSTOMARY_SYSTEM` 替代。 单位系统的 `is_metric` 和 `name` 属性同样已弃用,不应再使用。 引用该单位系统或这些属性的自定义集成需要进行调整,改为使用实例检查。 正确做法: ```python if hass.config.units is METRIC_SYSTEM: pass if hass.config.units is US_CUSTOMARY_SYSTEM: pass ``` 为避免与未来的单位系统混淆,常量 `CONF_UNIT_SYSTEM_IMPERIAL` 和 `CONF_UNIT_SYSTEM_METRIC` 也已弃用,不应再引用: * 如果它们曾被用于与单位系统的 `name` 进行比较, 则现在已不再需要。 * 如果它们曾被用于其他目的,则应改为创建本地常量。 --- url: /developers/blog/2022-10-21-code-owner-commands.md --- Home Assistant [服务中枢](https://github.com/home-assistant/service-hub/) 已被 [Ludeeus](https://github.com/ludeeus) 扩展了一个新功能:代码所有者的 GitHub 命令。 此功能允许任何代码所有者对其集成标记的 issue 进行分诊。从今天起,可以使用以下命令: * `@home-assistant close`
关闭该 issue。仅当只有一个集成被标记时可用 * `@home-assistant rename New Title`
更改 issue 的标题。仅当只有一个集成被标记时可用 * `@home-assistant unassign `
移除集成标签及相关的 assignee。 当 bot 发布评论以通知代码所有者有新的 issue 或 pull request 时,将包含这些命令([示例](https://github.com/home-assistant/core/issues/80731#issuecomment-1287084569))。 --- url: /developers/blog/2022-10-24-hubs-devices-services-virtual-integrations.md --- 在 2022.11 版本中,我们调整了集成清单, 以更好地区分 hub、device 和 service。此外, 我们还引入了一种新类型的集成:虚拟集成。 ## 区分 hub、device 和 service 一个容易混淆的方面是:config entry 可以集成单个设备(ESPHome), 也可以通过 hub 集成一系列设备(Hue),或者集成一个 service(AdGuard)。 我们希望近期在 UI 中开始区分这些类型, 但目前无法做到,因为集成并没有暴露此信息。 我们已经有 [`integration_type`](/developers/creating_integration_manifest.md#integration-type) 清单属性,现在已扩展以支持这些新类型: * `device`:集成一次集成一个设备。 * `hub`:集成多个设备。 * `service`:集成一个服务。 `hub` 与 `service` 或 `device` 的区别由 集成本身的性质决定。`hub` 提供对多个其他 设备或服务的网关。`service` 和 `device` 是每个 config entry 提供 单个设备或服务的集成。 :::caution 当 [`integration_type`](/developers/creating_integration_manifest.md#integration-type) 未设置时,我们将其自动默认为 `hub`。这是一个临时降级方案。 未来我们将要求显式设置 [`integration_type`](/developers/creating_integration_manifest.md#integration-type)。 请将您现有的(自定义)集成更新为在集成清单中设置正确的 `integration_type`。 ::: ## 虚拟集成 有些产品由不以产品名称命名的集成支持。 例如,Roborock 吸尘器通过 Xiaomi Miio 集成进行集成。 也有一些产品线仅支持标准 IoT 协议 如 Zigbee 或 Z-Wave。例如,U-tec ultraloq 通过 Z-Wave 工作, 并且没有专门的集成。 对于终端用户来说,找到如何将这些产品 与 Home Assistant 集成可能会令人困惑。为解决上述情况,我们引入: [虚拟集成](/developers/creating_integration_manifest.md#virtual-integration)。 虚拟集成不是真正的集成,而是用于帮助用户 找到适合其设备的正确集成。它们只有一个 manifest 文件,没有任何附加代码。 虚拟集成有两种类型:由另一个集成支持的虚拟集成,以及使用现有 IoT 标准的虚拟集成。 [在开发者文档中了解更多信息。](/developers/creating_integration_manifest.md#virtual-integration) ## 移除支持的 brands 功能 虚拟集成取代了之前的"supported brands"功能。该 功能仅被 Home Assistant Core 集成使用,所有这些集成都已 迁移为使用虚拟集成。 因此已无使用该功能的情况,支持的 brands 功能已 在未经弃用期的情况下被移除。 --- url: /developers/blog/2022-10-25-new-precipitation-intensity-units.md --- 从 Home Assistant Core 2022.11 开始,以下常量(用于 volumetric flux,如降水强度)已弃用,由 `UnitOfVolumetricFlux` 枚举替代: * `PRECIPITATION_INCHES_PER_HOUR` 由 `UnitOfVolumetricFlux.INCHES_PER_HOUR` 替代 * `PRECIPITATION_MILLIMETERS_PER_HOUR` 由 `UnitOfVolumetricFlux.MILLIMETERS_PER_HOUR` 替代 * `SPEED_INCHES_PER_DAY` 由 `UnitOfVolumetricFlux.INCHES_PER_DAY` 替代 * `SPEED_INCHES_PER_HOUR` 由 `UnitOfVolumetricFlux.INCHES_PER_HOUR` 替代 * `SPEED_MILLIMETERS_PER_DAY` 由 `UnitOfVolumetricFlux.MILLIMETERS_PER_DAY` 替代 --- url: /developers/blog/2022-10-26-new-unit-enumerators.md --- 从 Home Assistant Core 2022.11 开始,以下单位常量已弃用,并由相应的 enum 替代: * `UnitOfEnergy` 枚举器替代 `ENERGY_***` 常量 * `UnitOfLength` 枚举器替代 `LENGTH_***` 常量 * `UnitOfMass` 枚举器替代 `MASS_***` 常量 * `UnitOfPower` 枚举器替代 `POWER_***` 常量 * `UnitOfPressure` 枚举器替代 `PRESSURE_***` 常量 * `UnitOfSpeed` 枚举器替代 `SPEED_***` 常量 * `UnitOfTemperature` 枚举器替代 `TEMP_***` 常量 * `UnitOfVolume` 枚举器替代 `VOLUME_***` 常量 --- url: /developers/blog/2022-11-16-statistics_refactoring.md --- 对长期统计相关 API 做了一些更改,以减少响应大小和数据库负载。 这些更改在[此 PR](https://github.com/home-assistant/core/pull/82131)中实现。 这会影响调用以下 WS API 的代码作者: * `recorder/statistics_during_period` * 新增了一个可选参数 `types`,允许提供要包含在响应中的统计特征列表。可能的值有:`"last_reset"`、`"max"`、`"mean"`、`"min"`、`"state"`、`"sum"` * 时间戳 `start`、`end` 和 `last_reset` 现在是自 UNIX epoch 以来的毫秒整数,而不是 ISO 格式字符串。新格式意味着时间戳可以直接传递给 js `Date()` 构造函数。 * `statistic_id` 不再在返回的 map 中为每个列表项重复。由于返回类型是以 `statistic_id` 为键的 map,因此此前并未使用该字段。 这会影响调用以下 Python API 的代码作者: * `homeassistant.recorder.statistics.get_last_short_term_statistics` * 新增了一个参数 `types`,允许提供要包含在响应中的统计特征集合。可能的值有:`"last_reset"`、`"max"`、`"mean"`、`"min"`、`"state"`、`"sum"` * 时间戳 `start`、`end` 和 `last_reset` 现在是 `datetime` 对象,而不是 ISO 格式字符串。 * `statistic_id` 不再在返回的 map 中为每个列表项重复。由于返回类型是以 `statistic_id` 为键的 map,因此此前并未使用该字段。 * `homeassistant.recorder.statistics.get_latest_short_term_statistics` * 新增了一个参数 `types`,允许提供要包含在响应中的统计特征集合。可能的值有:`"last_reset"`、`"max"`、`"mean"`、`"min"`、`"state"`、`"sum"` * 时间戳 `start`、`end` 和 `last_reset` 现在是 `datetime` 对象,而不是 ISO 格式字符串。 * `statistic_id` 不再在返回的 map 中为每个列表项重复。由于返回类型是以 `statistic_id` 为键的 map,因此此前并未使用该字段。 * `homeassistant.recorder.statistics.statistics_during_period` * 新增了一个参数 `types`,允许提供要包含在响应中的统计特征集合。可能的值有:`"last_reset"`、`"max"`、`"mean"`、`"min"`、`"state"`、`"sum"` * 时间戳 `start`、`end` 和 `last_reset` 现在是 `datetime` 对象,而不是 ISO 格式字符串。 * `statistic_id` 不再在返回的 map 中为每个列表项重复。由于返回类型是以 `statistic_id` 为键的 map,因此此前并未使用该字段。 --- url: /developers/blog/2022-11-28-more-unit-enumerators.md --- 从 Home Assistant Core 2022.12 开始,以下单位常量已弃用,并由相应的 enum 替代: * `UnitOfPrecipitationDepth` 枚举器替代 `PRECIPITATION_***` 常量 --- url: /developers/blog/2022-12-01-entity_translations.md --- 集成为其 entity(例如传感器的)state 提供翻译的方法已经改变。 集成不应再将自定义 device class 与 `strings..json` 文件一起使用。相反,entity 应在自身上设置 `translation_key` 属性,并在集成的 `strings.json` 中包含该 `translation_key`。 :::warning 通过 `translation_key` 属性指向翻译目前仅支持具有 `unique_id` 的 entity。 ::: 以下 `strings.json` 示例适用于 `translation_key` 属性设置为 `phase` 的 Moon 域 `sensor` entity: ```json { "entity": { "sensor": { "phase": { "state": { "new_moon": "New moon", "first_quarter": "First quarter", "full_moon": "Full moon", "last_quarter": "Last quarter" } } } } } ``` 更多详情请参见 [`translation`](/developers/internationalization/core.md#state-of-entities) 和 [`entity`](/developers/core/entity.md#generic-properties) 文档。 --- url: /developers/blog/2022-12-05-more-unit-enumerators.md --- 从 Home Assistant Core 2023.1 开始,以下单位常量已弃用,并由相应的 enum 替代: * `UnitOfApparentPower` 枚举器替代 `POWER_VOLT_AMPERE` 常量 * `UnitOfDataRate` 枚举器替代 `DATA_RATE_***` 常量 * `UnitOfElectricCurrent` 枚举器替代 `ELECTRIC_CURRENT_***` 常量 * `UnitOfElectricPotential` 枚举器替代 `ELECTRIC_POTENTIAL_***` 常量 * `UnitOfFrequency` 枚举器替代 `FREQUENCY_***` 常量 * `UnitOfInformation` 枚举器替代 `DATA_***` 常量 * `UnitOfIrradiance` 枚举器替代 `IRRADIATION_***` 常量 * `UnitOfSoundPressure` 枚举器替代 `SOUND_PRESSURE_***` 常量 * `UnitOfTime` 枚举器替代 `TIME_***` 常量 * `UnitOfVolumeFlowRate` 枚举器替代 `VOLUME_FLOW_RATE_***` 常量 --- url: /developers/blog/2022-12-07-entity-color-changes.md --- 从 Home Assistant Core 2022.12 版本开始,当 entity 处于 active 状态时,我们按 domain 使用不同的颜色。以下 CSS 变量不再使用: * `--paper-item-icon-active-color` * `--state-icon-active-color` 这意味着任何之前覆盖过这些 CSS 变量的 theme 将使用内置的 active state 颜色。所有新颜色也都以 CSS 变量的形式提供。 :::caution 由于我们仅正式支持 theme 的 `primary-color` 和 `accent-color` 属性,某些颜色可能会在版本之间增加或删除。 ::: 有关 theme 配置的更多详情请参见 [Home Assistant 文档](https://www.home-assistant.io/integrations/frontend/#defining-themes)。 --- url: /developers/blog/2022-12-07-unit_system_changes.md --- 过去几个月,受支持的单位系统以及数值传感器受其影响的方式发生了许多变化。本博客文章旨在总结这些变更。 * 对于 device class 为 `distance`、`gas`、`precipitation`、`precipitation_intensity`、`speed`、`volume`、`water`、`weight` 或 `wind_speed` 的传感器,其 state 使用的单位受单位系统影响并会自动转换。 * 集成可以通过设置 entity 属性 `suggested_unit_of_measurement` 来覆盖单位系统规则。 * 为避免 breaking change,传感器的单位仅在该传感器首次添加到 Home Assistant 时,根据单位系统规则自动转换。这意味着用户系统中已有的传感器不会受到新的单位转换规则的影响。 * 如果用户在偏好设置中更改单位系统,用户系统中已有的传感器的单位不会受到单位系统变更的影响。 * 在大多数情况下,集成不再需要进行任何单位转换,因为现在会自动处理。 * 在大多数情况下,现有实现单位转换的集成特定代码可以被移除,因为在移除自定义代码后,传感器的 state 会自动转换。有关此机制的详细信息,请参见 [core PR #83228](https://github.com/home-assistant/core/pull/83228)。注意:这仅适用于具有 `unique_id` 的传感器。 * 允许用户为集成选择传感器单位的自定义 option flow 在大多数情况下也可以被移除。用户可以改为通过 frontend 的 entity settings 覆盖传感器的单位,如果根据所选单位系统的自动转换不符合用户喜好。注意:这仅适用于具有 `unique_id` 的传感器。 * 温度传感器的行为基本保持不变;温度传感器的 state 单位始终反映单位系统,除非: * 用户已通过 frontend 的 entity settings 覆盖了单位。 * 温度传感器具有非 None 的 `suggested_unit_of_measurement` 属性。 * `IMPERIAL_SYSTEM` 单位系统已弃用,并由 `US_CUSTOMARY_SYSTEM` 替代。此外,单位系统的 `is_metric` 和 `name` 属性也已弃用,不应再使用。有关这些变更的更多详情请参见[此博客文章](/developers/blog/2022-10-14-deprecate-unit-system.md)。 * 单位转换工具已经过重构和移动,unit converter 现在作为 `homeassistant/util/unit_conversion` 中的静态类提供。有关这些变更的更多详情请参见[此博客文章](/developers/blog/2022-09-28-deprecate-conversion-utilities.md)。 --- url: /developers/blog/2022-12-08-multi-pan-rollback.md --- **更新:** multi-pan 已修复,从 Home Assistant 2023.2 开始,用户可以重新选择加入实验版本。 在 [Home Assistant 2022.12](https://www.home-assistant.io/blog/2022/12/07/release-202212/) 中,我们软发布了实验性的 multi-pan 功能:允许使用 Home Assistant Yellow 和 Home Assistant SkyConnect 中的单个 radio 同时运行 Zigbee 和 Thread。用户需要在硬件菜单中找到它,确认实验说明并选择加入。 我们刚刚在固件中发现了一个严重的 bug,需要修复。这就是我们决定从 Home Assistant 2022.12.1 开始暂时禁止用户选择加入 multi-pan 的原因。 该 bug 是 Zigbee end-device 无法通过 coordinator 重新加入网络:coordinator 会将其踢出并要求重新加入,反复如此。普通的 EmberZNet 固件不会出现这种行为。它仅影响直接加入 coordinator 的 end device,而不是通过中间 router 加入的设备,并且仅影响那些尝试重新加入网络的设备。 我们正在与 Silicon Labs 合作,尽快解决此问题。一旦解决,我们将重新启用 multi-pan。 启用 multi-pan 会在您的 radio 上安装特殊固件。要禁用 multi-pan,需要重新安装原始的 Zigbee 固件。目前这还无法从 Home Assistant 自动完成。我们将尽快通过浏览器方式更新此帖子的操作说明。 --- url: /developers/blog/2023-01-02-db-schema-v32.md --- 对于 Home Assistant Core 2023.2,数据库 schema 已更改。 此变更影响那些不通过 `recorder` 的 [`history`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/recorder/history.py) API,而是直接访问 `last_updated`、`last_changed` 或 `time_fired` 列的自定义集成。 [`events`](https://data.home-assistant.io/docs/events) 和 [`states`](https://data.home-assistant.io/docs/events/) 的文档已更新,可在 [Data Science Portal](https://data.home-assistant.io/) 上查阅。 --- url: /developers/blog/2023-01-12-bluetooth-adapters.md --- 需要使用 Bluetooth 适配器的集成应在 [`manifest.json`](/developers/creating_integration_manifest.md) 的 [`dependencies`](/developers/creating_integration_manifest.md#dependencies) 中添加 `bluetooth_adapters`。[`manifest.json`](/developers/creating_integration_manifest.md) 条目确保在集成尝试使用所有受支持的远程适配器之前,它们已连接。这取代了在 [`dependencies`](/developers/creating_integration_manifest.md#dependencies) 中添加 `bluetooth` 的需求。 提供 Bluetooth 适配器的集成应在 [`manifest.json`](/developers/creating_integration_manifest.md) 的 [`dependencies`](/developers/creating_integration_manifest.md#dependencies) 中添加 `bluetooth`,并添加到 `bluetooth_adapters` 集成的 [`after_dependencies`](/developers/creating_integration_manifest.md#after-dependencies) 中。 在构建新的 Bluetooth 集成时,请务必查阅 [集成作者的 Best Practices](/developers/bluetooth.md#best-practices-for-integration-authors)。 --- url: /developers/blog/2023-01-20-cover-intent-deprecated.md --- 从 Home Assistant 2023.02 开始,`HassCoverOpen` 和 `HassCoverClose` intents 已弃用。请改用 `HassTurnOn` 和 `HassTurnOff` intents。这样做的原因是某些语言不区分 Open/On 和 Close/Off。 --- url: /developers/blog/2023-01-24-conversation-updates.md --- Home Assistant 2023.2 版本包含 [PR 86592](https://github.com/home-assistant/core/pull/86592) 和 [PR 86484](https://github.com/home-assistant/core/pull/86484),其中包含对 [conversation agent](/developers/core/entity/conversation.md) API 的 breaking changes,以做未来兼容设计。 * 设置 agent 现在需要 config entry:\`conversation.async\_set\_agent(hass, config\_entry, agent). * 取消设置 agent 现在通过新端点:\`conversation.async\_unset\_agent(hass, config\_entry) * `AbstractConversationAgent` API 已更改: * 移除了所有 onboarding 逻辑 * `async_process` 现在接收新的 `ConversationInput` 参数,参数相同。Language 现在始终被设置。 * `async_process` 现在应始终返回 `ConversationResult`。不再允许返回 `None` 或期望为你进行错误处理。 --- url: /developers/blog/2023-01-25-sensor_rounding.md --- 注意: 此处描述的变更已被回退,并替换为 presentation rounding,更多详情请参见[此博客文章](/developers/blog/2023-02-08-sensor_presentation_rounding.md)。 `SensorEntity` 现在可以在将数值型 `native_value` 转换为 sensor state 时进行 rounding。这是 [core PR #86074](https://github.com/home-assistant/core/pull/86074) 的一部分。rounding 由集成通过设置 `native_precision` 属性来 opt-in。建议集成设置此属性,因为它可确保即使经过单位转换后,小数位数仍然合理。 以下是 PR 描述中变更的摘要: * 默认情况下不进行任何 rounding * 集成可以通过设置新属性 `native_precision` 来影响 state precision * state precision 受单位转换影响 * 从小单位转换到大单位会增加 display precision * 从大单位转换到小单位会减小 display precision(前提是集成已设置 `native_precision`) * 从大单位转换到小单位时的最小 precision 为 0,即不会 round 到十位、百位等 * 用户可以从 frontend 覆盖 display precision * 没有最小 precision,即通过设置负 precision 可以 round 到十位、百位等 * 鼓励集成取消 display rounding,改为设置 `native_precision` 属性 * 在以下情况下,会在 sensor state 的字符串表示中补充尾随零以匹配 precision: * precision 由用户设置 * `native_precision` 属性不为 `None` * 进行了单位转换 --- url: /developers/blog/2023-02-03-responses.md --- 为 [Assist](https://www.home-assistant.io/docs/assist) 提供支持的 [intents 仓库](https://github.com/home-assistant/intents/) 有两个重要变更。 首先,intents YAML 中的 data block 现在可以有一个 `response` key。例如: ```yaml language: en intents: HassTurnOn: data: - sentences: - "open {name}" response: cover ``` 必须在 `responses//.yaml` 中定义具有匹配 key 的 response: ```yaml language: en responses: intents: HassTurnOn: cover: "Opened {{ slots.name }}" ``` Response 模板采用 [Jinja2 格式](https://www.home-assistant.io/docs/configuration/templating/),可以访问匹配 intent 的 `slots` 以及受影响 entity 的 `state`。 第二个变更来自 [hassil](https://github.com/home-assistant/hassil),它是我们的 [intent template 语法](/developers/voice/intent-recognition/template-sentence-syntax.md)的解析器。除了解析速度提升 8-10 倍之外,模板中的 whitespace 将被按字面处理。 以前,像 `light(s | ing)` 这样的模板会同时匹配 "lights" 和 "lighting"。现在,由于 `|` 周围的额外空格,将匹配 "light s" 和 "light ing"。正确的模板应为 `light(s|ing)` --- url: /developers/blog/2023-02-06-translations-files-removed-from-core.md --- 我们已从 Home Assistant Core 仓库中移除了所有翻译文件, 并放置了一个 helper script,用于从 翻译字符串文件(`strings.json`)编译英文翻译, 以供开发使用。 以前,所有翻译文件(包括所有语言)都是 Home Assistant Core 仓库的一部分。每天晚上我们都会通过 从 Lokalise 下载翻译并将它们提交到 Core 仓库来更新翻译。 现在,我们将此流程移至构建时。我们每次发布 新版本(包括 beta 和 nightly builds)时,会从 Lokalise 下载最新的 翻译。 这种方法带来了一些好处: * 我们不再需要将翻译文件提交到 Core 仓库。 这意味着作为开发者,这也不再是一种令人困惑的负担。 * 人们将不再(错误地)尝试通过 GitHub 贡献语言翻译。 * 每个版本,包括 patch、beta 和 nightly 版本, 现在也将拥有最新的翻译。 ## 本地开发 对于本地开发,我们有翻译开发 helper script。此 脚本一直存在,但现在它可以一次性为所有集成编译英文 翻译。 ```bash python3 -m script.translations develop --all ``` 当设置开发环境时,以及每次在 VSCode 中运行 Home Assistant 时(作为 pre-launch task),此脚本会自动运行。 --- url: /developers/blog/2023-02-07-introducing-PR-drafting-in-reviews.md --- Home Assistant 收到了大量贡献,这真是太棒了!但是 当有大量 PR 时,就很难追踪它们的状态。 为此,我们在 review 流程中引入了一项新流程, 当 PR 需要更多工作才能再次 review(或合并)时, 会自动将其标记为 draft。 我们已调整 bot,如果 review 请求了更改,则自动将 PR 标记为 draft。一旦更改完成,PR 的作者可以 点击 "Ready for review" 按钮将 PR 从 draft 中取消,使其准备好 再次接受 review。 ![The ready for review button in the bottom of a PR in draft mode](/img/en/blog/2023-02-07-introducing-PR-drafting-in-reviews/ready-for-review.png) 在点击 "Ready for review" 按钮之前,请确保已处理 所有请求的更改,且所有 CI jobs 和 checks 均成功通过。 ## 什么是 draft PR? Draft PR 是指尚未准备好接受 review 的 PR。它是一种让其他人 知道您正在处理某事的方式,但它尚未准备好接受 review 和 合并。 Draft PR 在 PR 右上角有 "Draft" 标签,并且在 GitHub UI 各处 都以灰色合并图标显示。 ![This is what a PR in draft looks like](/img/en/blog/2023-02-07-introducing-PR-drafting-in-reviews/pr-in-draft.png) 这并不意味着您应该打开 PR 来开始处理某事;请 仅在您认为已准备好接受 review 和合并时才打开 PR。然而, 在打开 PR 后,可能出于某种原因需要将其重新设置为 draft 状态。 例如,打开 PR 会自动触发我们的 CI jobs 和 checks。这些 checks 可能会发现您代码中需要调整的问题, 或者确实进行了 review 并请求了更改。 您可以随时通过将 PR 右上角的 "Convert to draft" 链接点击, 将任何 PR 重新设置为 draft。 ![Putting a PR in draft is something you can do too](/img/en/blog/2023-02-07-introducing-PR-drafting-in-reviews/convert-to-draft.png) ## 我们为什么要这样做? 作为 reviewer,您会面对大量 PR。有些已准备好接受 review,有些则没有。通常,唯一的方法就是打开 PR 并查看,结果发现它仍在进行中。 这不仅浪费时间,也浪费精力。尤其是 考虑到这种情况会发生在多个 reviewer 身上,且每天在同一个 PR 上发生多次。 PR 的 draft 状态在 GitHub 的所有地方都是可见的。在通知、 搜索以及 PR 的概览中。最重要的是,它易于筛选。 这让 reviewer 能够更好地专注于当前真正需要他们关注的内容。 更多背景信息可以在 [此 Google Document](https://docs.google.com/document/d/11_x2YUmAD07JN7JMM4YIIAWVGTJsOB0UptN8hlmWFWg/edit?usp=sharing) 中找到。 或者,[在此页面阅读有关我们 review 流程的所有内容](/developers/review-process.md)。 --- url: /developers/blog/2023-02-08-sensor_presentation_rounding.md --- 显示 sensor state 时展示的小数位数现在可由用户配置。集成可以通过设置 `suggested_display_precision` 属性来建议 小数位数。鼓励集成移除 display rounding,改为设置 `suggested_display_precision` 属性。 Presentation rounding 由 frontend 完成,同时也由 [core PR #87619](https://github.com/home-assistant/core/pull/87619) 中引入的新 template 函数完成。 显示的小数位数受单位转换影响: * 从小单位转换到大单位会增加 display precision * 从大单位转换到小单位会减小 display precision(前提是集成已设置 `suggested_display_precision`) * 从大单位转换到小单位时的最小 precision 为 0,即不会 round 到十位、百位等 如果用户自行设置了 display precision,则显示的小数位数不受单位转换影响。 注意: 类似的概念(即对 sensor state 进行 rounding)已在[较早的博客文章](/developers/blog/2023-01-25-sensor_rounding.md)中详细介绍,但该变更已被回退。 --- url: /developers/blog/2023-02-09-hassgetstate.md --- 我们新增了一个[内置 intent](/developers/intent_builtin.md):`HassGetState` 一旦我们在 [intents 仓库](https://github.com/home-assistant/intents/) 中添加翻译,此 intent 将使用户能够向 [Assist](https://www.home-assistant.io/docs/assist) 提问。 您可以通过添加 [自定义句法](https://www.home-assistant.io/docs/assist/custom_sentences) 来试用: ```yaml # Example /custom_sentences/en/get_state.yaml language: en intents: HassGetState: data: - sentences: - what is [in ] - is {state} [in ] responses: intents: HassGetState: default: "{{ slots.name }} is {{ state.state_with_unit }}" lists: state: values: - "on" - "off" - open - closed - locked - unlocked - wet - dry ``` 通过这些句法,您现在可以向 Assist 提问 "what is the outside temperature?"、"is the front door locked?" 或 "is the floor in the basement wet?" 等问题。 当然,这依赖于 entity 名称(或别名)设置正确。例如,一个名为 "outside temperature" 的传感器,以及一个名为 "floor" 的二进制湿度传感器位于 "basement" 区域。 随着我们添加更多翻译,将支持更多类型的问题,如 "which lights are in the living room?" 和 "are any doors unlocked?" --- url: /developers/blog/2023-02-15-json.md --- 从 Home Assistant Core 2023.3 开始,部分常量和函数在 `homeassistant.helpers.json` 和 `homeassistant.util.json` 之间进行了移动: * `save_json` 和 `find_paths_unserializable_data` 函数现在应 从 `homeassistant.helpers.json` 导入 * `json_loads` 函数现在应从 `homeassistant.util.json` 导入 * `JSON_ENCODE_EXCEPTIONS` 和 `JSON_DECODE_EXCEPTIONS` 常量现在应 从 `homeassistant.util.json` 导入 --- url: /developers/blog/2023-02-20-snapshot-testing.md --- Home Assistant [现已支持 snapshot testing](https://github.com/home-assistant/core/pull/88323) 用于 Python 代码库。 Snapshot testing(也称为 approval tests)是将值与 存储的参考值(snapshot)进行断言的测试, 确保代码的输出随时间保持一致。 Snapshot 测试不同于常规的(功能)测试,不能替代 功能测试,但对于测试较大的输出非常有用。 在 Home Assistant 中,例如可用于测试 entity states、device 或 entity registry 条目,或诊断 dump 的输出。 以下是一个诊断测试示例,它使用 snapshot 来断言 诊断 dump 的输出: ```python # tests/components/example/test_diagnostics.py async def test_diagnostics( hass: HomeAssistant, hass_client: ClientSessionGenerator, init_integration: MockConfigEntry, snapshot: SnapshotAssertion, ) -> None: """Test diagnostics.""" assert ( await get_diagnostics_for_config_entry(hass, hass_client, init_integration) == snapshot ) ``` 首次运行此测试时将会失败,因为不存在 snapshot。 要创建(或更新)snapshot,请运行带 `--snapshot-update` 标志的 pytest, 这将在该组件的 `snapshots` 目录中创建 snapshot 文件。 Snapshot 文件以测试文件命名,在本例中为: `tests/components/example/snapshots/test_diagnostics.ambr`。Snapshot 文件 是人类可读的,必须提交到仓库中。 随后的测试运行会将结果与 snapshot 进行比较。如果结果不同,测试将失败。 Snapshot 是一种确保代码输出随时间保持不变的简便方法, 可以大幅减少所需的测试代码量(同时提供) 对完整输出的完整断言。 Home Assistant 中的 snapshot testing 基于 [Syrupy](https://github.com/tophat/syrupy) 构建, 并进行了扩展以处理 Home Assistant 特定的数据结构。 有关测试集成的更多信息, 请参见[我们的文档](/developers/development_testing.md)。 --- url: /developers/blog/2023-02-21-deprecated-callback-removed.md --- Home Assistant 的 MQTT 集成[不再支持](https://github.com/home-assistant/core/pull/88543) 用于 MQTT subscribe 的弃用 callback 签名。 如果自定义集成仍在使用弃用的 callback 签名进行 MQTT subscribe 的 callback 函数,则会因未更新而中断。如果检测到不支持的 callback 类型,将抛出异常。 以下是不再工作的弃用 callback 函数示例: ```python async def async_deprecated_callback1(topic: str, payload: ReceivePayloadType, qos: int) -> None: """Deprecated async callback example 1.""" ... @callback def async_deprecated_callback2(topic: str, payload: ReceivePayloadType, qos: int) -> None: """Deprecated async callback example 2.""" ... ``` 以下是一个正确的 callback 签名示例: ```python @callback def async_correct_callback(msg: ReceiveMessage) -> None: """Callback example 1.""" ... ``` --- url: /developers/blog/2023-02-28-custom-tile-features.md --- 在 Home Assistant Core 2022.3 版本中,我们为 [tile card](https://www.home-assistant.io/dashboards/tile/) 添加了自定义 features。如果您是自定义 card 的开发者,现在可以为 tile card 构建自己的 feature,而无需构建整个 card。 ![Screenshot showing example of custom tile feature](/img/en/blog/2023-02-28-custom-tile-features/example.png) ```yaml type: tile entity: button.push features: - type: custom:button-press-tile-feature ``` 自定义 tile features 甚至可以使用与自定义 cards 类似的语法添加到 tile card editor 中,就像任何内置 tile feature 一样。 ```js window.customTileFeatures = window.customTileFeatures || []; window.customTileFeatures.push({ type: "button-press-tile-feature", name: "Button press", }); ``` 更多详情请参见 [custom tile features](/developers/frontend/custom-ui/custom-card-feature.md) 文档。 --- url: /developers/blog/2023-03-27-entity_name_translations.md --- 现在可以翻译 entity 的 name,且这优于在 Python 实现中硬编码自然语言名称。此外,entity components 提供共享翻译,例如用于 binary sensor device class 的翻译,应使用这些翻译以避免重复翻译相同内容。 此外,frontend 现已完全支持翻译 entity state attributes 的 name 和值。 :::warning 通过 `translation_key` 属性指向翻译目前仅支持具有 `unique_id` 的 entity。 此外,翻译 entity name 要求 `has_entity_name` 属性设置为 `True`。 ::: ## 翻译 entity name 以下 `strings.json` 示例适用于 `translation_key` 属性设置为 `thermostat_mode` 的 `sensor` entity: ```json { "entity": { "sensor": { "thermostat_mode": { "name": "Thermostat mode" } } } } ``` 以下 `strings.json` 示例适用于 `translation_key` 属性设置为 `temperature_sensor` 的 `sensor` entity,其中使用了 `sensor` 集成提供的共享翻译: ```json { "entity": { "sensor": { "temperature_sensor": { "name": "[%key:component::sensor::entity_component::temperature::name%]" } } } } ``` ## 翻译 entity attributes 以下 `strings.json` 示例适用于 `translation_key` 属性设置为 `ubercool` 的 `demo` 域 `climate` entity,它包含自定义的 `fan_mode` 和 `swing_mode` 设置: ```json { "entity": { "climate": { "ubercool": { "state_attributes": { "fan_mode": { "state": { "auto_high": "Auto High", "auto_low": "Auto Low", "on_high": "On High", "on_low": "On Low" } }, "swing_mode": { "state": { "1": "1", "2": "2", "3": "3", "auto": "Auto", "off": "Off" } } } } } } } ``` 更多详情请参见 [`entity name translation`](/developers/internationalization/core.md#name-of-entities)、[`entity attribute translation`](/developers/internationalization/core.md#entity-state-attributes) 和 [`entity`](/developers/core/entity.md#generic-properties) 文档。 --- url: /developers/blog/2023-03-28-calendar_best_practices.md --- Home Assistant 改进了 Calendar entity 的 best practices,以确保 在所有情况下 calendar triggers/automations 和 UI 均能正常工作。 特别地,现在有更多文档化的期望和不变量强制,包括: * `CalendarEvent` 属性 `end` 是 exclusive 的。例如,持续一天的全日事件,其 end date 应为 start date 之后的 1 天。 * `CalendarEvent` 可以接受任何时区的 `datetime`。不允许无时区的 floating dates。 * 创建 `CalendarEvent` 时现在会强制验证不变量。 * 由 `async_get_events` 返回的事件应按顺序返回。 * 由 `async_get_events` 返回的全日事件必须在 Home Assistant 本地时区中评估。即,全日事件应按其在本地时间午夜开始的顺序排列。 [Calendar Entity 开发者文档](/developers/core/entity/calendar.md) 已更新,包含更多详细信息。 --- url: /developers/blog/2023-04-04-deprecating_polymer.md --- Home Assistant frontend 过去使用 [Polymer Library](https://polymer-library.polymer-project.org/3.0/docs/about_30) 来处理 web components。Polymer 此后已被弃用,并由 [Lit](https://lit.dev) 取代。 在过去几年中,我们将大部分 frontend 迁移到了 Lit,只有少数地方和依赖仍在使用 Polymer。 这是好消息,因为 Lit 比 Polymer 快得多也轻量得多。 在 Home Assistant 2023.4 中,我们终于从 Home Assistant 的入口点移除了最后一块 Polymer,这意味着它在应用启动时不会加载,只有在组件需要它时才会加载。 对于自定义 cards 和 panels,我们在 window 对象上提供了 Polymer,以便于访问和使用。但现在几乎不再使用了,而且由于 Home Assistant 不再使用它,它主要是一大段未使用的代码,拖慢了 Home Assistant 的加载速度。 因此我们决定将其移除。 在 Home Assistant 2023.5 中,Home Assistant 将不再提供 Polymer。如果您现在使用 Polymer,我们建议您切换到 Lit。如果您想继续使用 Polymer,则需要自行加载 Polymer。 在 Home Assistant 2023.4 中,每次访问 Polymer 时我们都会记录一条警告。如果您收到日志消息,请找到使用 Polymer 的自定义 card、panel 或 more info,并通知作者此弃用信息。 --- url: /developers/blog/2023-04-13-new_limits_for_add_ons.md --- 随着 Home Assistant OS 10,我们更新到最新的 Docker 发布版本 23.0。在 新的 Docker 版本中,add-on 的最大打开文件描述符数量 更改为无限(接近无限)。 如果您是 add-on 开发者,并且在 Home Assistant OS 10 上遇到内存不足问题,您可以在 启动服务之前使用 `ulimit -n 1048576` 来应用旧的限制。 背景:在 Home Assistant OS release candidate 阶段,较高的限制对 几个 add-on 来说有问题(Node-RED、Network UPS Tools 和 EMQX MQTT broker,参见 [Home Assistant OS issue #2438](https://github.com/home-assistant/operating-system/issues/2438))。 在所有情况下,问题都表现为内存不足错误, 而在上一版 Home Assistant OS 发布的相同硬件上则工作正常。并且 在所有三种情况下,内存都是根据允许的 打开文件描述符数量动态分配的(可通过 `prlimit64` 系统调用确定, 返回的限制为 1073741816)。 我们考虑过恢复旧限制;然而,根据 Docker(moby)仓库中的变更, 使用无限作为限制的开销更少。 因此我们决定保留新的默认值。 --- url: /developers/blog/2023-04-30-statistics_impossible_values.md --- 此变更影响 WebSocket API:`recorder/statistic_during_period` 和 `recorder/statistics_during_period`。Home Assistant 项目目前不记录这些 API,因为它们可能会变更。 对于 Home Assistant Core 2023.6,statistics WebSocket API 将不再返回已确定将为空的列。调用方应将缺少值视为与 null 值相同。 为减少数据库开销,如果 statistics backend 提前知道某列的所有行都将为空值,则不再返回该列。 --- url: /developers/blog/2023-05-07-job-home-assistant-core.md --- Nabu Casa 正在寻找一位有热情且经验丰富的 Python 开发者,全职加入 Home Assistant core 团队担任 Software Engineer。作为我们团队的一员,您将负责 review 贡献并开发与我们的 roadmap 一致的新功能。 [在 Nabu Casa 了解更多](https://nabucasa.com/jobs/home-assistant-core-developer/) --- url: /developers/blog/2023-05-21-retained-mqtt-messages-filtered.md --- Home Assistant 的 MQTT 集成处理 MQTT 消息的方式,以及 subscribe 和 unsubscribe 的执行方式已发生变更。 ### MQTT subscribe 和 unsubscribe 的执行方式已更新 Subscribe 和 unsubscribe 不再立即发送到 broker。新增了 debouncer 代码,会在 debounce 时间内延迟向 broker 发送 subscribe 并进行合并。在实际执行(un)subscribe 时,(un)subscribe 会被合并为对 broker 的一次调用。这些变更将加快 MQTT 集成以及注册了大量 MQTT entity 的集成的启动速度,尤其是在 subscribe 共享 topic(例如发布 availability)时。在 MQTT debug 日志中,`mid` 编号显示哪些(un)subscribe 调用已合并为对 MQTT broker 的一次调用。 ### retained messages 的处理方式已变更 具有 `retain` 标志的 MQTT 消息的处理方式已发生变更,使得现有 subscriber 不再收到因新的 subscriber 订阅同一 topic 而由 broker 重新发送的 retained messages。相反,broker 重新发送的 retained messages 仅传递给新的 subscriber。 新行为避免了相同 retained message 反复向 subscriber 洪泛,并且更好地符合 MQTT 规范,参见 OASIS MQTT Version 3.1.1 规范([关于 RETAIN 标志的使用方式](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc385349265))和规范性声明编号 [MQTT-3.3.1-9](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718134)。 --- url: /developers/blog/2023-06-14-service-calls.md --- 此变更影响 Service Call API:`hass.services.async_call` 和 `hass.services.call`。 对于 Home Assistant Core 2023.7,service calls 的部分输入参数和返回值已 变更,以准备更好地支持 [Service return values](https://github.com/home-assistant/architecture/discussions/777#discussioncomment-6127898)。 之前,成功时返回 `True`,发生超时返回 `False`。用于设置超时的 `limit` 参数已被移除,布尔返回值也已移除。 如果调用方需要超时,现在应使用 asyncio 自行设置。 --- url: /developers/blog/2023-06-28-entity-name-changes.md --- Entity 命名发生了以下变更: * 将 entity 标记为 device 的单一主要功能现在需要通过显式将 entity 的 `name` 属性设置为 `None` 来完成,通过不设置 `name` 属性来隐式将 entity 标记为 device 的单一主要功能已不再支持。 * 某些平台的未命名 entity 现在会根据其 device class 获得默认名称,这包括 `binary_sensor`、`button`、`number` 和 `sensor` entity。 更多详情请参见 [entity 命名文档](/developers/core/entity.md#entity-naming)。 --- url: /developers/blog/2023-06-28-service-description-filters.md --- 服务调用描述已更改以支持过滤。 可以为服务调用添加过滤器,以不显示不支持该服务调用的 entity;也可以为服务调用字段添加过滤器,以不向用户显示被选中 entity 不支持的字段。 例如: * 仅当 light 支持亮度时,`light.turn_on` 的 `brightness` 服务调用参数才会显示。 * `climate.set_aux_heat` 服务调用仅允许选择支持辅助加热的 climate entity。 此功能在 core [PR #86162](https://github.com/home-assistant/core/pull/86162) 中引入,文档见[此处](/developers/dev_101_services.md#filtering-service-action-fields)。 --- url: /developers/blog/2023-07-07-action-event-custom-cards.md --- 在 Home Assistant Core 2023.7 版本中,我们为自定义卡片引入了 `hass-action`。 如果您是自定义卡片开发者,现在可以通过新的 `hass-action` 在自定义卡片中使用任意[卡片 action](https://www.home-assistant.io/dashboards/actions/)。 示例: ```js // Define the action config const actionConfig = { entity: "sensor.temperature", tap_action: { action: "more-info", }, hold_action: { action: "assist", start_listening: true, }, }; // Open more info on tap action const event = new Event("hass-action", { bubbles: true, composed: true, }); event.detail = { config: actionConfig, action: "tap", }; this.dispatchEvent(event); // Open assist dialog on hold action const event = new Event("hass-action", { bubbles: true, composed: true, }); event.detail = { config: actionConfig, action: "hold", }; this.dispatchEvent(event); ``` --- url: /developers/blog/2023-07-10-vacuum-updates.md --- Vacuum entity 最近发生了一些变更: * `VacuumEntity` 基类已被 `StateVacuumEntity` 取代(由 [PR 15573](https://github.com/home-assistant/core/pull/15573) 实现,于 2018 年 8 月合并),现计划在 Home Assistant Core 2024.2.0 中移除。所有 core 集成均已更新,但自定义组件的集成作者需要更新自己的集成。[PR 95920](https://github.com/home-assistant/core/pull/95920) 是最近一个从 `VacuumEntity` 迁移到 `StateVacuumEntity` 的示例。 * `VacuumEntity` 与 `StateVacuumEntity` 所支持的服务有所不同,但文档此前表述有些模糊,导致部分集成实现了来自错误基类的服务。现在 [PR 95833](https://github.com/home-assistant/core/pull/95833) 已对此进行了限制。所有 core 集成均已更新,但自定义组件的集成作者需要更新自己的集成。 * `battery_icon` 与 `battery_level` state 属性已被弃用。集成可以通过在同一 device 上添加一个 device class 为 `battery` 的 `sensor` 来报告电池状态,详情请见架构讨论 [938](https://github.com/home-assistant/architecture/discussions/938)。 * `map` state 属性已被弃用。集成可以通过在同一 device 上添加一个 `image` entity 来提供地图图片,详情请见架构讨论 [939](https://github.com/home-assistant/architecture/discussions/939)。 更多详情,请参阅[`vacuum` 文档](/developers/core/entity/vacuum.md)。 --- url: /developers/blog/2023-07-11-translating-services.md --- Home Assistant 现在支持翻译 services。此前,service 及其 service 字段的名称和描述被硬编码在每个集成的 `services.yaml` 文件中。 现在,我们已添加使用翻译系统翻译这些名称和描述的支持。这意味着 service 及其 service 字段的名称和描述现在可以被翻译成任何语言。 为实现这一点,每个 service 和 service 字段的 `name` 与 `description` 键从硬编码的 `services.yaml` 文件中移动到每个集成的翻译文件中。 `services.yaml` service 描述更新的示例可在[我们的文档中](/developers/dev_101_services.md#service-action-descriptions)找到。[后端本地化](/developers/internationalization/core.md#service-actions)也已扩展,包含一个已翻译 service 的示例,与 service 描述中的示例相匹配。 service 翻译自 Home Assistant 2023.8 起可用。我们希望这能让 Home Assistant 对非英语用户更加友好。 --- url: /developers/blog/2023-07-21-change-naming-mqtt-entities.md --- MQTT entities 的命名方式,以及发现的 entity 之间如何共享 device 配置,已发生改变。 ### 共享 device 配置 发现的 MQTT entities 可以共享 device 配置,即一个 entity 可以包含完整的 device 配置,其他 entity 仅通过设置必填字段即可链接到该 device。此前必填字段至少包含 `connection` 和 `identifiers` 中的一个,现已扩展为至少包含 `connection` 和 `identifiers` 中的一个,以及 `name`。 ### MQTT entities 的命名 MQTT entities 的命名已更改,以符合[entity 命名指南](https://developers.home-assistant.io/docs/core/entity/#entity-naming): * 所有 MQTT entities 的 `has_entity_name` 将被设置为 `True` * 未命名的 `binary_sensor`、`button`、`number` 与 `sensor` entities 现在将以其 device class 命名,而不再命名为 `MQTT binary sensor` 等 * 现在允许将 MQTT entity 的 name 设置为 `None`,以标记其为 device 的主要功能 --- url: /developers/blog/2023-07-27-avoiding-unnecessary-callbacks-with-dataupdatecoordinator.md --- `DataUpdateCoordinator` 现在可以在 API 数据可比较时减少不必要的更新。 使用 `DataUpdateCoordinator` 时,轮询的数据通常预期大部分时间保持不变。例如,如果你轮询一个每周仅开启一次的灯,该数据几乎在所有时间都是相同的。默认行为是在数据更新时始终回调监听器,即使数据并未改变。如果 API 返回的数据可以通过 Python 的 `__eq__` 方法进行比较,则在创建 `DataUpdateCoordinator` 时设置 `always_update=False`,以避免不必要的回调和对 state machine 的写入。 --- url: /developers/blog/2023-08-07-weather_entity_forecast_types.md --- `WeatherEntity` 现在允许单个 weather entity 支持不同的预报类型,这意味着不再需要为同一地点创建多个 entity,例如一个提供每日预报的 entity 和另一个提供每小时预报的 entity。 提供 `weather` entities 的集成应进行更新,以实现一个或多个新的 async 方法 `async_forecast_daily`、`async_forecast_hourly` 和 `async_forecast_twice_daily`。 对于即将到来的 Home Assistant Core 2024.3 版本,集成应移除已弃用的 `forecast` 属性,并移除为提供多种预报而添加的任何重复 weather entities。 请参阅[`weather` 开发者文档](/developers/core/entity/weather.md#weather-forecasts),了解如何实现新的预报方法。 "Weather Forecast Card" 已更新,如果集成使用了新方法,将为用户提供选择要显示的偏好预报的选项。 --- url: /developers/blog/2023-08-23-sensor-updates.md --- 数值型 sensor 不再允许将 state 设置为[非数字 (Not a Number)](https://en.wikipedia.org/wiki/NaN) 或正无穷/负无穷。 此变更在 [core PR#98110](https://github.com/home-assistant/core/pull/98110) 中引入。 更多详情,请参阅[`sensor` 文档](/developers/core/entity/sensor.md)。 --- url: /developers/blog/2023-08-29-hass-format-state.md --- 在 Home Assistant Core 2023.9 版本中,我们在 `hass` 对象中引入了 3 个新方法,以允许自定义卡片对 entity state 进行带本地化支持格式化: * `hass.formatEntityState` * `hass.formatEntityAttributeValue` * `hass.formatEntityAttributeName` 示例: ```js hass.formatEntityState(hass.states["cover.living_room_shutter"]); // 如果用户语言是英语,将返回 "Open"。 // 如果用户语言是法语,将返回 "Ouvert"。 ``` 更多详情,请参阅[entity state 格式化文档](/developers/frontend/data.md#entity-state-formatting)。 --- url: /developers/blog/2023-08-29-homeassistant-changed-signature.md --- `HomeAssistant.__init__` 的签名已从无需参数更改为要求以字符串形式传递配置目录。Home Assistant core 仓库之外的脚本、测试等如果创建了 `HomeAssistant` 对象,都需要进行更新。 此变更在 [core PR#98442](https://github.com/home-assistant/core/pull/98442) 中引入。 如果需要保持向后兼容,可以通过以下方式实现: ```python try: hass = HomeAssistant() # pylint: disable=no-value-for-parameter except TypeError: hass = HomeAssistant(config_dir) # pylint: disable=too-many-function-args ``` --- url: /developers/blog/2023-09-12-ws-entity-source-simplified.md --- websocket 命令 `entity/source` 已大大简化: * 不再能够获取单个 entity 的信息 * 响应中仅包含 entities 的 domain,`custom_component`、`config_entry` 和 `source` 不再存在。 ### 新响应示例 ```json { "light.entity_1": { "domain": "template", }, "switch.entity_2": { "domain": "shelly", }, } ``` ### 旧响应示例 ```json { "light.entity_1": { "custom_component": false, "domain": "template", "source": "platform_config", }, "switch.entity_2": { "custom_component": false, "config_entry": "", "domain": "shelly", "source": "config_entry", }, } ``` 此变更在 [core PR#99439](https://github.com/home-assistant/core/pull/99439) 中引入。 --- url: /developers/blog/2023-09-20-excluding-state-attributes-from-recording.md --- 排除 state 属性不参与 recording 的方式已发生改变。 recorder platform 已被两个新属性所取代,可在从 `Entity` 派生的类中设置: * `_entity_component_unrecorded_attributes: frozenset[str]` - 应由 base component entity 类(例如 `LightEntity`)设置 * `_unrecorded_attributes: frozenset[str]` - 应由派生 platform 类(例如 `HueLight`)设置,以排除额外的、集成特有的属性不参与 recording 更多详情可在[entity 文档](/developers/core/entity.md#excluding-state-attributes-from-recorder-history)中找到。 变更的背景在[架构讨论 #964](https://github.com/home-assistant/architecture/discussions/964)中。 --- url: /developers/blog/2023-10-01-hacktoberfest-2023.md --- 📢 对 Hacktoberfest 2023 参与者来说的好消息!我们要参与了!🎉 这不仅是我们的[10 周年](https://www.home-assistant.io/blog/2023/09/17/10-years-home-assistant/),也是 Hacktoberfest 的第 10 年!恭喜!🎂 Hacktoberfest 是全球性的、为期一个月的开源庆祝活动,一个向所有人开放的活动。无论你是开发者、学习编程的学生、文档编写者还是设计师,你都可以推动 Home Assistant 这类开源项目的增长。欢迎所有背景和技能水平的参与者完成 Hacktoberfest 挑战。当然,我们也乐意帮助你提交 pull requests。 与往年一样,Home Assistant 参与 Hacktoberfest。我们所有的仓库都已加入,无论你想修改[前端](https://github.com/home-assistant/frontend)、[core](https://github.com/home-assistant/core),还是我们的[文档](https://github.com/home-assistant/home-assistant.io)。这些仓库的 issue tracker 都能很好地概览可以贡献的内容。 ## 但,我不是开发者?! 如果你不是开发者,对 git、GitHub 或开源还不太熟悉,那么参与文档工作是很好的入门方式。一个相对简单的贡献方式是审查你使用或熟悉的集成的文档,检查内容是否仍然最新且无拼写/语法错误。 我们网站上每一页文档底部都有一个"Edit"按钮。使用该按钮,你可以修改页面上的文本并提出改进建议。 在我们的 Community 论坛上,有一份详细的分步指南说明了操作方式:[Editing the Documentation and Creating a Pull Request on GitHub](https://community.home-assistant.io/t/editing-the-documentation-and-creating-a-pull-request-on-github/9573)。 那么,你还在等什么?在 [Hacktoberfest](https://hacktoberfest.com/) 网站上注册,开始 hack 吧!如果有任何问题,请前往我们的[Discord 聊天服务器](https://www.home-assistant.io/join-chat)。我们有专门的开发者频道,很乐意为你提供帮助。 Happy Hacktoberfest 🎉 --- url: /developers/blog/2023-10-03-conversion-functions-cleanup.md --- 以下工具在 [Home Assistant 2022.10 中被弃用](/developers/blog/2022-09-28-deprecate-conversion-utilities.md)),现在自 2023.11 起已被移除: * `homeassistant/util/distance` * `homeassistant/util/pressure` * `homeassistant/util/speed` * `homeassistant/util/temperature` * `homeassistant/util/volume` 请使用 `homeassistant/util/unit_conversion` 中对应的静态类: * `DistanceConverter` * `PressureConverter` * `SpeedConverter` * `TemperatureConverter` * `VolumeConverter` 这些已弃用的函数在内置 Home Assistant 集成中已不再使用,使用它们的社区集成在过去 12 个月中应该已经看到过警告。现在尝试导入原始工具将导致错误。 --- url: /developers/blog/2023-10-12-country_selector.md --- [Selectors](https://www.home-assistant.io/docs/blueprint/selectors/) 已扩展,现在也包含了 `CountrySelector`。 在[config flows](/developers/data_entry_flow_index.md#show-form)中使用它可以让 frontend 自动将国家代码翻译成正确的国家名称。 示例: ```python vol.Schema( { vol.Optional(CONF_COUNTRY): CountrySelector( CountrySelectorConfig( countries=["DE", "US"], ) ), } ) ``` --- url: /developers/blog/2023-11-06-public-addon-config.md --- Add-on 现在可以有一个用于配置文件或数据文件的公共文件夹,用户可以看到并修改它,但它仍然会与 add-on 一起被备份。 许多 add-on 会要求用户在 add-on 配置中提供文件。或者生成一些文件,希望用户能够查看并可能修改它们。它们通常通过映射文件夹列表中包含 `config` 和/或 `share` 来处理。 但这样做有两个问题: 1. `config` 或 `share` 中的内容都不会与 add-on 一起备份。因此,在恢复后,该 add-on 的备份不包含运行它所需的所有文件。 2. 映射 `config` 的 add-on 拥有的访问权限远多于其应有的权限,因为 `config` 包含了你在 Home Assistant 集成中使用的所有 secrets 和 credentials。 现在为 add-on 开发者提供了一种更好的解决方案。Add-on 可以在映射文件夹列表中包含 `addon_config`。然后,supervisor 将为该 add-on 在 `/addon_configs/` 处创建一个文件夹,并将其映射到 add-on container 内的 `/config`。如果你的 add-on 除了收集用户文件之外,还需要能够在此文件夹中创建和修改文件,则使用 `addon_config:rw`。 要了解更多关于此功能及其用例的信息,请参阅[Add-on advanced options](/developers/apps/configuration.md#app-advanced-options)。 ## 与 `/config` 的向后兼容 你可能会注意到新的公共 config 文件夹被映射到 `/config`。此前如果你将 `config` 添加到 `map` 字段中,Home Assistant 的 config 文件夹就会被映射到此处。 此选项旨在取代 add-on 将 Home Assistant 的 config 映射到其 container 的需求。因此,add-on 不能在 `map` 字段中同时包含 `config` 和 `addon_config`。 今后,如果你确实需要将 Home Assistant 的 config 提供给你的 add-on,你应该在 `map` 字段中将 `homeassistant_config` 列为文件夹。然后 Home Assistant 的 config 文件夹将被映射到 container 内的 `/homeassistant`。 ## 新的 `addon_configs` 文件夹 一些 add-on 需要访问所有这些 add-on 专用的 config 文件夹。例如: 1. Samba 2. SSH 3. Studio Code Server 本质上,这些 add-on 提供了编辑 Home Assistant 及其 add-on 配置文件的其他手段。类似这些 add-on 应将 `all_addon_configs:rw` 添加到 map 字段中的文件夹列表。这将把整个 add-on config 文件夹映射到 container 内的 `/addon_configs`。 --- url: /developers/blog/2023-11-27-config-validation-and-error-handling.md --- ## Component config 处理与错误处理的变更 Component YAML 配置的处理方式已发生改变。现在可以在发生错误时抛出异常。如果某些自定义集成使用了 `config.async_process_component_config`,它们可能会中断。现在它们可以改用 `config.async_process_component_and_handle_errors`。这个新方法支持在 config 处理过程中发生错误时抛出异常。 从现在起,失败将不再作为持久消息发出通知,因此集成需要实现错误处理,以便在发生失败时通知用户。在 setup 期间如果存在 config 问题,仍然会添加通知。 ```python async def async_process_component_and_handle_errors( hass: HomeAssistant, config: ConfigType, integration: Integration, raise_on_failure: bool = False, ) -> ConfigType | None: ... ``` 在 reload 期间,集成可以使用 `helpers.reload.async_integration_yaml_config`。该 helper 现在在发生失败时也具备抛出异常的能力。 ```python async def async_integration_yaml_config( hass: HomeAssistant, integration_name: str, *, raise_on_failure: bool = False ) -> ConfigType | None: ... ``` ## Config 验证异常(Exceptions)的翻译支持 引入了一种新的 `ConfigValidationError` 异常类。当 config 错误处理过程中发生错误且 `raise_on_failure` 设置为 `True` 时,将抛出此异常。如果该错误是在执行服务调用期间抛出的且不需要 stack trace,它可以被重新抛出为 `ServiceValidationError`。添加了翻译键以允许对错误消息进行本地化。 ### 背景 * 背景[讨论](https://github.com/home-assistant/architecture/discussions/992)。 * 实现 [Core PR #102410](https://github.com/home-assistant/core/pull/102410)。 --- url: /developers/blog/2023-11-30-service-exceptions-and-translations.md --- ## 服务调用期间的异常处理 迄今为止,抛出异常的 service 调用会记录 stack trace。由于错误用法(例如无效输入)导致失败的 service 调用不需要 stack trace,如果能向用户提供其本语言的有帮助的错误消息会更好。 为了在这些情况下抑制 stack trace,引入了派生自 `HomeAssistantError` 的新异常类型 `ServiceValidationError`。当 service 因被错误使用而失败时,现在应抛出 `ServiceValidationError` 而不是 `ValueError`。 如果 service 被正确使用但仍然失败,仍然应抛出 `HomeAssistantError`,或者是除 `ServiceValidationError` 之外的 `HomeAssistantError` 子类。 当 service 抛出 `ServiceValidationError` 时,错误消息将显示在 UI 和日志中,但 stack trace 将以 debug 级别记录。对于从 service 调用抛出的其他异常(包括 `HomeAssistantError`),一切不变,仍然以异常严重级别打印完整的 stack trace。 集成应进行更新:当 service 因错误用法而失败时,抛出 `ServiceValidationError` 而不是 `ValueError`;当它因其他预期错误(例如网络错误)而失败时,抛出 `HomeAssistantError`。[了解更多](/developers/core/platform/raising_exceptions.md)。 ## 异常的翻译支持 `HomeAssistantError` 异常及其子类(包括 `ServiceValidationError`)现在接受 translation key 以允许本地化。[了解更多](/developers/internationalization/core.md#exceptions)。当 frontend 收到关于异常的信息时,将使用 translation key。如果未作为参数将自定义错误消息传递给异常,translation 缓存中的英文错误消息也将用于在控制台记录消息。 ### 背景 * 背景[讨论](https://github.com/home-assistant/architecture/discussions/992)。 * 实现 [Core PR #102592](https://github.com/home-assistant/core/pull/102592)。 --- url: /developers/blog/2023-12-05-scaling-utils.md --- ## 用于缩放亮度的新工具 多个集成实现各自自己的 scaling 算法来缩放亮度。现在在 `homeassistant.util.color` 中引入了新的工具,以简化亮度 scaling 的实现: ```python def brightness_to_value(low_high_range: tuple[float, float], brightness: int) -> float: """Given a brightness_scale convert a brightness to a single value. Do not include 0 if the light is off for value 0. Given a brightness low_high_range of (1,100) this function will return: 255: 100.0 127: ~49.8039 10: ~3.9216 """ ... ``` 如果你更倾向于将亮度缩放到一个整数范围,也可以使用 `scale_ranged_value_to_int_range`,详情见[此处](#background)。 ```python def value_to_brightness(low_high_range: tuple[float, float], value: float) -> int: """Given a brightness_scale convert a single value to a brightness. Do not include 0 if the light is off for value 0. Given a brightness low_high_range of (1,100) this function will return: 100: 255 50: 127 4: 10 The value will be clamped between 1..255 to ensure valid value. """ ... ``` 这也确保了返回有效的亮度值。 ### 背景 为了缩放 fan speed 百分比,我们已经有一些工具在 `homeassistant.utils.percentage` 中: ```python def ranged_value_to_percentage( low_high_range: tuple[float, float], value: float ) -> int: ... ``` 以及 ```python def percentage_to_ranged_value( low_high_range: tuple[float, float], percentage: int ) -> float: ... ``` 这些百分比工具现在将在 `homeassistant.utils.scaling` 中使用新的通用 scaling 工具: `scale_ranged_value_to_int_range` 和 `scale_to_ranged_value` ```python def scale_ranged_value_to_int_range( source_low_high_range: tuple[float, float], target_low_high_range: tuple[float, float], value: float, ) -> int: """Given a range of low and high values convert a single value to another range. Given a source low value of 1 and a high value of 255 and a target range from 1 to 100 this function will return: (1,255), 255: 100 (1,255), 127: 50 (1,255), 10: 4 """ ... ``` 以及 ```python def scale_to_ranged_value( source_low_high_range: tuple[float, float], target_low_high_range: tuple[float, float], value: int, ) -> float: """Given a range of low and high values convert a single value to another range. Do not include 0 in a range if 0 means off, e.g. for brightness or fan speed. Given a source low value of 1 and a high value of 255 and a target range from 1 to 100 this function will return: (1,255), 255: 100 (1,255), 127: ~49.8039 (1,255), 10: ~3.9216 """ ... ``` ## 工具 `int_states_in_range` 和 `states_in_range` 已迁移 这些工具现在位于 `homeassistant.util.scaling` 下。如果它们在自定义集成中被使用,请确保更新 import 到新模块。 --- url: /developers/blog/2023-12-11-entity-description-changes.md --- `EntityDescription` 类已发生变更;派生的 `dataclasses` 现在应设置 `frozen=True` 和 `kw_only=True`。 将 `frozen` 设置为 `True` 使 `EntityDescription` 实例不可变,这意味着它们在创建后不会被意外更新。 将 `kw_only` 设置为 `True` 确保 base 类中字段的顺序可以更改,而不会破坏用户代码。 在一段以 HA Core 2025.1 结束的弃用期内,仍然可以派生未设置 `frozen=True` 或 `kw_only=True` 的 `dataclasses`,但会被记录日志,并要求用户为自定义集成创建 issue。 一旦 HA Core 2025.1 发布,将不再可能派生未设置 `frozen=True` 或 `kw_only=True` 的 `dataclasses`。 更多详情可在[core PR #105211](https://github.com/home-assistant/core/pull/105211)中找到。 --- url: /developers/blog/2023-12-18-config-entry-minor-version.md --- Config entry 现在支持 minor 版本。 如果 minor 版本不同但 major 版本相同,即使集成未实现 `async_migrate_entry`,集成 setup 也会被允许继续。这意味着 minor 版本提升是向后兼容的,这与 major 版本提升不同,后者会在用户降级 HA Core 且未从备份恢复配置时导致集成 setup 失败。 ### 背景 由于 config entry 数据的版本化会破坏降级到旧版 Home Assistant Core 的过程,此前我们对版本化的态度非常保守。这意味着在大多数情况下,我们不做版本化,集成反而进行一种软升级,例如,对初始版本中不存在的 config entry 数据执行 `dict.get`,在 setup 期间转换数据等。 通过引入类似 storage helper 已提供的 minor 版本,此模式不再被推荐。每当新增或更改的数据不会破坏旧版版本时,应改为提升 minor 版本。 更多详情可在[config entry 迁移文档](/developers/core/integration/config_flow.md#config-entry-migration)和 [core PR #105749](https://github.com/home-assistant/core/pull/105479) 中找到。 --- url: /developers/blog/2023-12-19-constant-deprecation.md --- 近年来,许多常量通过添加指向其替代项的代码注释,被 Enum 或其他值所取代。 现在使用已弃用的常量将生成一条警告日志条目,其中包含使用的集成、替代项以及该常量将从 core 中移除的版本。 将有一年的弃用期,以确保所有自定义集成作者有时间进行调整。 大多数常量应该已经被替换了,因为过去我们发布了多篇关于其弃用的博客文章。部分列于下方: * [Deprecating all SUPPORT\_\* constants](/developers/blog/2022-04-02-support-constants-deprecation.md) * [Constant deprecations for 2022.5](/developers/blog/2022-05-03-constants-deprecations.md) * [AutomationActionType deprecation for 2022.9](/developers/blog/2022-08-15-automation-action-type-deprecation.md) * [Device tracker deprecations for 2022.9](/developers/blog/2022-07-29-device-tracker_source-type-deprecation.md) * [Deprecating media player constants](/developers/blog/2022-09-06-media-player-repeat-mode-deprecation.md) * [Add new precipitation intensity units](/developers/blog/2022-10-25-new-precipitation-intensity-units.md) * [Introducing new unit enumerators](/developers/blog/2022-10-26-new-unit-enumerators.md) * [Add more unit enumerators](/developers/blog/2022-11-28-more-unit-enumerators.md) * [Add more unit enumerators](/developers/blog/2022-12-05-more-unit-enumerators.md) 更多详情可在 [core PR #105736](https://github.com/home-assistant/core/pull/105736) 中找到,或者通过查看弃用 helper 中 [`check_if_deprecated_constant`](https://github.com/home-assistant/core/blob/dev/homeassistant/helpers/deprecation.py#L240) 函数的使用情况。 --- url: /developers/blog/2023-12-28-support-feature-magic-numbers-deprecation.md --- 自 Home Assistant Core 2024.1 起,所有用于 supported features 的 magic numbers 用法均已被弃用,并且每个 entity platform 都提供了一个 `EntityFeature` enum 来替代它们。 将有一年的弃用期,magic numbers 将在 2025.1 中停止工作,以确保所有自定义集成作者有时间进行调整。 这适用于以下 platform: * **Alarm Control Panel** 请改用新的 [`AlarmControlPanelEntityFeature`](/developers/core/entity/alarm-control-panel.md#supported-features) enum。 * **Camera** 请改用新的 [`CameraEntityFeature`](/developers/core/entity/camera.md#supported-features) enum。 * **Cover** 请改用新的 [`CoverEntityFeature`](/developers/core/entity/cover.md#supported-features) enum。 * **Climate** 请改用新的 [`ClimateEntityFeature`](/developers/core/entity/climate.md#supported-features) enum。 * **Humidifier** 请改用新的 [`HumidifierEntityFeature`](/developers/core/entity/humidifier.md#supported-features) enum。 * **Fan** 请改用新的 [`FanEntityFeature`](/developers/core/entity/fan.md#supported-features) enum。 * **Light** 请改用新的 [`LightEntityFeature`](/developers/core/entity/light.md#supported-features) enum。 * **Lock** 请改用新的 [`LockEntityFeature`](/developers/core/entity/lock.md#supported-features) enum。 * **Media Player** 请改用新的 [`MediaPlayerEntityFeature`](/developers/core/entity/media-player.md#supported-features) enum。 * **Remote** 请改用新的 [`RemoteEntityFeature`](/developers/core/entity/remote.md#supported-features) enum。 * **Siren** 请改用新的 [`SirenEntityFeature`](/developers/core/entity/siren.md#supported-features) enum。 * **Vacuum** 请改用新的 [`VacuumEntityFeature`](/developers/core/entity/vacuum.md#supported-features) enum。 * **Water Heater** 请改用新的 [`WaterHeaterEntityFeature`](/developers/core/entity/water-heater.md#supported-features) enum。 --- url: /developers/blog/2024-01-11-async-show-progress-changes.md --- `FlowHandler.async_show_progress` 已更新: * 添加了一个新参数 `progress_task`,它在 Home Assistant core 发布版 2024.8 中将成为必填项 如果传递了 `progress_task`,`FlowManager` 将: * 在任务完成后向 frontend 发送一个事件 * 如果用户在任务完成前关闭了 config flow 对话框,则取消 `progress_task` 这意味着派生类不再负责 progress task 状态与 UI 之间的交互。 `FlowHandler.async_show_progress` 在未传入 `progress_task` 的情况下被调用时会记录警告。在 Home Assistant core 发布版 2024.8 中,该调用将失败。 更多详情可在[文档](/developers/data_entry_flow_index.md#show-progress--show-progress-done)、[core PR #107668](https://github.com/home-assistant/core/pull/107668) 和 [#107802](https://github.com/home-assistant/core/pull/107802) 中找到。 --- url: /developers/blog/2024-01-17-deprecate-invalid-sensor-uom-state-class-use.md --- 自 Home Assistant Core 2022.12 起,如果具有 device class 的 sensor entity 错误地使用了 unit of measurement 和 state class(会考虑其 device class),则会在日志中发出警告。 无效的用法示例:具有 `SensorDeviceClass.TEMPERATURE` device class 的 sensor entity,但使用了 unit of measurement `%` 而不是 `°C` 或 `°F`;或者使用了 state class `SensorStateClass.TOTAL` 而不是 `SensorStateClass.MEASUREMENT`。 将有一个六个月的弃用期,以确保所有自定义集成作者有时间进行调整。自 Home Assistant Core 2024.8 起,该警告将被异常所取代。 --- url: /developers/blog/2024-01-19-entity-translations-placeholders.md --- 现在可以使用 placeholders 为 entity translation 提供静态值。 你可以通过 entity 的 `translation_placeholders` 属性传递 placeholders。 一个 sensor 示例: ```python class TestEntity(SensorEntity): """Example entity.""" _attr_has_entity_name = True _attr_translation_key = "temperature" def __init__(self) -> None: """Initialize example entity.""" self._attr_translation_placeholders = {"channel_id": "2"} self._attr_device_info = DeviceInfo( name="Example device" ) ``` `strings.json` 文件将如下所示: ```json { "entity": { "sensor": { "temperature": { "name": "Temperature channel {channel_id}" } } } } ``` 最终生成的 entity 将被称为 `Example device Temperature channel 2`。 当预期存在 translation placeholder 但 entity 未提供时,会记录一次警告。 在不是稳定版本的系统上(dev、nightly 或 beta),发生此情况时会抛出错误,以便能够迅速捕获问题。 请记住对你的翻译人员友善,因为他们需要理解 placeholder 名称中传入的是什么类型的名称或值 ❤️。 --- url: /developers/blog/2024-01-19-icon-translations.md --- 在 Home Assistant 2024.2 中,我们将引入一种为集成提供 icons 的新方式:Icon 翻译。 Icon 翻译的工作方式类似于我们用于 entities 的常规翻译,后者可以将 entity 的 state 或 entity 属性 state 翻译成任何语言。Icon 翻译的工作方式类似,但并不是将 state 翻译成最终用户语言,而是将 state 翻译为一个 icon。 每个集成现在都可以提供一个 `icons.json` 文件,其中包含从 states 到 icons 的映射。以下是一个 Moon `sensor` entity 的示例,它为每个 state 提供不同的 icon: ```json { "entity": { "sensor": { "phase": { "default": "mdi:moon", "state": { "new_moon": "mdi:moon-new", "first_quarter": "mdi:moon-first-quarter", "full_moon": "mdi:moon-full", "last_quarter": "mdi:moon-last-quarter" } } } } } ``` Icon 翻译也支持翻译 entity 属性 states。 [在我们的文档中了解更多关于 icon 翻译的内容](/developers/core/entity.md#icons)。 ## Service 图标 此变更是向后兼容的。entity 现有的 `icon` 属性将继续像以前一样工作。不过,我们建议使用 icon 翻译来替代 `icon` 属性。 此外,集成提供的 services 现在也支持 icons,并可以在相同的 icon 翻译文件中提供。这些 icons 在 Home Assistant UI 中显示 service 时使用,比如在 automation 和 script 编辑器中。以下示例展示了如何为 `light.turn_on` 和 `light.turn_off` services 提供 icons: ```json { "services": { "turn_on": "mdi:lightbulb-on", "turn_off": "mdi:lightbulb-off" } } ``` [在我们的文档中了解更多关于 service icons 的内容](/developers/dev_101_services.md#icons)。 --- url: /developers/blog/2024-01-22-async_services_for_domain.md --- 在 Home Assistant 2024.2 中,我们将引入 `hass.services.async_services_for_domain()`,这是一种按 domain 枚举 services 的新方式,允许集成检查哪些 services 可用,而无需获取系统中的所有 services。我们发现大多数集成只关心它们自己提供的 services,而在集成只关心自己的 services 时,枚举系统中的所有 services 成本很高。 调用 `hass.services.async_services()[DOMAIN]` 以获取特定 domain 的 services 的集成,应将调用替换为 `hass.services.async_services_for_domain(DOMAIN)`。 --- url: /developers/blog/2024-01-23-light-color-mode-changes.md --- ## 背景 引入 light color modes 的主要原因是 light 的 state 不应含糊不清。例如,一个同时支持 color 和可调节 color temperature 的白色光的 light,必须处于 color mode `hs`(举例)或 `color_temp` 中。 然而,effects 使情况变得复杂,因为当同一盏 light 正在渲染 effect 时,`hs_color`、`color_temp` 或 `brightness` state 属性可能都没有意义。 ## 变更 ### light 渲染 effect 时,对 `color_mode` 的要求不那么严格 当 effect 激活时,允许使用比 light 通常支持的限制性更高的 color modes: * 支持 colors 的 light 在被 effect 控制时,允许指示 color modes `on_off` 和 `brightness` * 支持 brightness 的 light 在被 effect 控制时,允许指示 color mode `on_off` 例如,一个 supported\_color\_modes 设置为 `{"hs", "color_temp"}` 的 light,在渲染无法调节的 effect 时允许将其 `color_mode` 设置为 `on_off`,在渲染允许控制 brightness 的 effect 时允许设置为 `brightness`。 ### 新增了一个表示无 effect / 关闭 effect 的特殊 effect `EFFECT_OFF` 此前,支持 effects 的 light 没有标准方式来表示当前没有 effect 激活。 现在通过添加预定义 effect `EFFECT_OFF` 来解决此问题,用于指示没有 effect 激活。 更多详情可在[文档](/developers/core/entity/light.md#color-modes)和[架构讨论 #960](https://github.com/home-assistant/architecture/discussions/960)中找到。 --- url: /developers/blog/2024-01-24-climate-climateentityfeatures-expanded.md --- 自 Home Assistant Core 2024.2 起,我们在 `ClimateEntityFeature` 中添加了两个新标志:`TURN_ON`、`TURN_OFF`。 实现 `turn_on` service 调用的集成需要设置 `TURN_ON` feature flag。 实现 `turn_off` service 调用的集成需要设置 `TURN_OFF` feature flag。 将有一个 10 个月的弃用期(2025.1),在此期间 `ClimateEntity` 将代实现相应方法的集成设置这些标志;自 2025.1 起,如果 entity features 未相应设置,集成将无法使用相应方法。 在未设置相应 feature flag 的情况下实现方法将生成一条警告日志条目,引导用户为集成创建 issue。 集成一旦迁移到使用或不使用新的 feature flags,应在 `ClimateEntity` 子类实例中将属性 `_enable_turn_on_off_backwards_compatibility` 设置为 `False`。 这将在弃用期间停止自动设置新的 feature flags,并可在弃用结束后移除。 --- url: /developers/blog/2024-01-30-ha-state-icon-properties-changes.md --- 在 Home Assistant 2024.2 中,集成有了提供 icons 的新方式。为了支持这一新功能,`ha-state-icon` 组件的 properties 已发生变更。 [在我们的文档中了解更多关于 icon 翻译的内容](/developers/core/entity.md#icons)。 如果你是使用此组件的自定义卡片开发者,你必须调整传递给组件的 properties,以避免在自定义卡片中显示错误的 icons。 ### 2024.2 之前 ```html ``` ### 2024.2 之后 ```html ``` ### 向后兼容 如果你想同时支持 Home Assistant 的旧版和新版,可以传递所有 properties。 ```html ``` --- url: /developers/blog/2024-02-12-async_update_entry.md --- 自 Home Assistant 2024.3 起,对 `ConfigEntry` 的修改应使用 `hass.config_entries.async_update_entry`。 直接在 `ConfigEntry` 对象上设置属性已被弃用,并将在 2024.9 及更高版本中开始失败。 直接在 `ConfigEntry` 上设置 `unique_id` 没有弃用期,因为这样做会破坏内部状态,并且会立即开始失败。 以下属性现在必须通过 `hass.config_entries.async_update_entry` 设置: * data * minor\_version * options * pref\_disable\_new\_entities * pref\_disable\_polling * title * unique\_id * version 测试必须确保在调用 `hass.config_entries.async_update_entry` 之前,通过 `entry.add_to_hass(hass)` 将 `MockConfigEntry` 对象添加到 Home Assistant 中。 --- url: /developers/blog/2024-02-12-light-color-mode-mandatory.md --- ## 变更 Light entities 现在必须设置 `supported_color_modes` 和 `color_mode` 属性,如果没有这样做,将记录警告并提示用户报告 issue。 此外,如果 light 报告了无效的 `supported_color_modes` 组合,或报告了 `ColorMode.UNKNOWN` 以外的、未包含在 light 的 `supported_color_modes` 中的 `color_mode`,也将记录警告。 在 Home Assistant 2025.3 版本中,警告将被移除,仍未升级到 color mode 或违反 color mode 规则的 lights 将不再工作。 更多详情可在[文档](/developers/core/entity/light.md#color-modes)中找到。 --- url: /developers/blog/2024-02-25-Climate-toggle-service.md --- 自 Home Assistant Core 2024.3 起,我们在 `ClimateEntity` 中添加了一个新的 `toggle` 方法,用户现在可以在 service 调用中调用 `climate.toggle`。 支持 `turn_on` 和 `turn_off` 的集成隐式也支持 `toggle` 方法。 [在我们的文档中了解更多关于 toggle 方法的内容](/developers/core/entity/climate.md#toggle) 示例(默认实现): ```python async def async_toggle(self) -> None: """Toggle the entity.""" if self.hvac_mode == HVACMode.OFF: await self.async_turn_on() else: await self.async_turn_off() ``` --- url: /developers/blog/2024-02-26-single-instance-only-manifest-option.md --- 在 Home Assistant 2024.3 中,我们为 integration manifest 文件引入了一个新的 `single_config_entry` 选项。 此选项允许你设置你的集成仅支持一个 config entry。 Home Assistant 将处理并阻止在已经存在该集成的 config entry 时初始化 config flow。 这样你就不必在 config flow 中实现任何检查。 未在 manifest 中设置此选项并在 config flow 中进行检查的集成,应使用新选项替换该检查。 --- url: /developers/blog/2024-02-27-deprecate-bind-hass-and-hass-components.md --- 自 Home Assistant 2024.3 起,我们弃用 `@bind_hass` decorator 的使用,因此也弃用 `hass.components` 的使用。 使用 `hass.components` 会在日志中发出警告。 建议自定义集成的作者在 Home Assistant 2024.9 之前更新代码,以避免任何问题。 自 Home Assistant 2024.9 起,`@bind_hass` decorator 和 `hass.components` 将被移除,并将不再可用。 ## 使用 `@bind_hass` decorator 使用 `@bind_hass` decorator 的集成应进行更新,移除该 decorator,并将 `hass` 对象作为第一个参数传递给函数: ### 新示例 ```python from homeassistant.core import HomeAssistant from homeassistant.components.persistent_notification import async_create def create_notification(hass: HomeAssistant, message: str): """Create a notification.""" async_create( hass, message, title='Important notification' ) async def async_setup(hass: HomeAssistant, config): """Set up the component.""" create_notification(hass, "You're already using the latest version!") ``` ### 旧示例 ```python from homeassistant.core import HomeAssistant from homeassistant.loader import bind_hass from homeassistant.components.persistent_notification import async_create @bind_hass def create_notification(hass: HomeAssistant, message: str): """Create a notification.""" async_create( hass, message, title='Important notification' ) async def async_setup(hass: HomeAssistant, config): """Set up the component.""" create_notification("You're already using the latest version!") ``` ## 使用 `hass.components` 使用 `hass.components` 的集成应进行更新,从 integration 包中直接 import 函数和类,并将 `hass` 对象作为第一个参数传递。 请记住在 `manifest.json` 的 `dependencies` 下包含所 import 的组件。 ### 新示例 ```python from homeassistant.core import HomeAssistant from homeassistant.components.persistent_notification import async_create async def async_setup(hass: HomeAssistant, config): """Set up the component.""" async_create( hass, "You're already using the latest version!", title='Important notification' ) ``` ### 旧示例 ```python from homeassistant.core import HomeAssistant async def async_setup(hass: HomeAssistant, config): """Set up the component.""" hass.components.persistent_notification.async_create( "You're already using the latest version!", title='Important notification' ) ``` --- url: /developers/blog/2024-02-28-device-name-translations.md --- 现在可以为 device name 提供翻译了,包括支持使用静态值作为占位符。 一个带有已翻译 device name 的 sensor 示例: ```python class TestEntity(SensorEntity): """示例 entity。""" _attr_has_entity_name = True def __init__(self) -> None: """初始化示例 entity。""" self._attr_device_info = DeviceInfo( translation_key="n_ch_power_strip", translation_placeholders={"number_of_sockets": "2"}, ) ``` `strings.json` 文件如下所示: ```json { "device": { "n_ch_power_strip": { "name": "带有 {number_of_sockets} 个插座的电源排插" } } } ``` 生成的 device 将被称为 `Power strip with 2 sockets`。 当 device 缺少预期提供的翻译占位符时,会记录一条警告。 当这种情况发生在非稳定版本(dev、nightly 或 beta)的系统上时,会抛出错误,以便能够快速捕获错误。 请记得对您的翻译者保持友善,因为他们需要理解将从占位符名称中传入什么样的名称或值 ❤️。 --- url: /developers/blog/2024-03-05-platform_entity_translations_deprecation.md --- 集成在其 entity 处于其他集成下时为状态提供翻译的方法,例如翻译某个集成的 sensors,在 2022 年 11 月发生了变化,对旧方法的支持将在 Home Assistant Core 2024.5.0 中移除。 一旦 Home Assistant Core 2024.5.0 发布,集成将不能再使用自定义 device class 配合 `strings..json` 文件。取而代之的是,entity 必须设置 `translation_key` 属性,并将该 `translation_key` 包含在集成的 `strings.json` 中。 以下示例 `strings.json` 是针对一个 `translation_key` 属性设置为 `phase` 的 Moon domain `sensor` entity: ```json { "entity": { "sensor": { "phase": { "state": { "new_moon": "New moon", "first_quarter": "First quarter", "full_moon": "Full moon", "last_quarter": "Last quarter" } } } } } ``` 更多详情请参阅 [`translation`](/developers/internationalization/core.md#state-of-entities) 和 [`entity`](/developers/core/entity.md#generic-properties) 文档。 --- url: /developers/blog/2024-03-09-import_executor_default.md --- 从 Home Assistant 2024.4 开始,所有集成都在 executor 中导入,以避免在代码被导入和执行期间阻塞 event loop。 在极少数情况下,如果集成在导入时创建了与 loop 绑定的对象,这可能会失败,因为在 executor 中没有正在运行的 loop。 自定义集成如果需要更多时间来调整代码以避免创建此类对象,可以选择退出,继续让代码在 event loop 中导入,但需了解系统稳定性将受到影响。 要退出在 executor 中导入,集成可以在其 [`manifest.json`](/developers/creating_integration_manifest.md) 中添加: `"import_executor": false` --- url: /developers/blog/2024-03-10-climate-aux-heater-deprecated.md --- 从 Home Assistant Core 2024.4 起,`ClimateEntity` 中的辅助加热器功能已被弃用。 当前实现了 `is_aux_heat` 属性以及 `turn_aux_heat_on`/`turn_aux_heat_off` 方法的集成需要移除这些方法和属性,并转而实现其他 entity(例如 `SwitchEntity`)来提供必要的功能;如果是只读属性,则可使用 `BinarySensorEntity`。 您可以在[这里](https://github.com/home-assistant/architecture/discussions/932)阅读有关此决定的更多信息。 --- url: /developers/blog/2024-03-13-deprecate_add_run_job.md --- `async_run_job` 和 `async_add_job` 已被弃用,并将在 Home Assistant 2025.4 中移除。此弃用不适用于 sync API `add_job` 方法,该方法计划保留不移除。 转而使用其他 job 方法更高效,因为不需要去判断 job 的调用方式: 如果 callable 是从 config entry 运行的 coroutine 函数: `entry.async_create_background_task`、`entry.async_create_task` 如果 callable 是从其他位置运行的 coroutine 函数: `hass.async_create_background_task`、`hass.async_create_task` 如果 callable 应该在 executor 中运行: `hass.async_add_executor_job` --- url: /developers/blog/2024-03-15-exception-translations.md --- ### 记录支持翻译的 exception 翻译支持适用于 `HomeAssistantError` 及其子类,如 `ServiceValidationError`。当设置了 `translation_domain` 和 `translation_key`,并且错误消息已添加到 `strings.json` 中时,不再需要为本地 logging 添加错误消息字符串。Home Assistant 会自动从翻译缓存中获取英文错误消息。 在抛出带有翻译支持的 `HomeAssistantError` 或其子类时,我们应该从参数列表中移除 log message,以便从翻译缓存中获取它。 例如: ```python async def async_select_index(hass: HomeAssistant, index: int) -> None: """Setup the config entry for my device.""" try: check_index(index) except ValueError as exc: raise ServiceValidationError( translation_domain=DOMAIN, translation_key="invalid_index", translation_placeholders={ "index": index, "expected": expected, }, ) from exc ``` 错误消息放置在 `strings.json` 中: ```json { ... "exceptions": { "invalid_index": { "message": "选择了无效的索引,期望值:{expected},实际值:{index}" } } } ``` --- url: /developers/blog/2024-03-20-state_reported_timestamp.md --- 现在,当集成设置 entity 的 state 时,`State` 对象总是会被更新,并且总是会触发一个事件,无论 state 或 state attribute 是否发生了变化。这是通过添加一个新的时间戳 `State.last_reported` 和一个新的事件 `state_reported` 来实现的。 `state_reported` 事件的触发量很大,使用时必须小心,以避免对系统负载产生不利影响: * 当触发 `state_reported` 时,不会调用订阅所有事件的 event listener。 * 不允许监听所有 entity 的 `state_reported` 事件。 * 当监听 `state_reported` 时,必须使用 `event_filter` 来过滤掉其他 entity 的事件。 * 当监听 `state_reported` 时,必须设置 `run_immediately` 标志。 ### 背景 Home Assistant 以前会丢弃那些 state 和 state attribute 均未发生变化的 state 写入,除非集成设置了 `force_update` 标志。这种行为使得集成很难正确地分析数值型 sensor state 的时间序列。这也意味着用户不知道某个集成是否在更新 sensor。 新的时间戳和相关事件在 architecture discussion [#1062](https://github.com/home-assistant/architecture/discussions/1062) 中进行了讨论。 ### 对自定义集成的影响 以下 API 存在 breaking changes: * `hass.bus.async_fire` 的 `time_fired` 参数现在接受 `float` 时间戳,而不是 `datetime` 对象。 * 可以传递给 `hass.bus.async_listen` 的 event filter 签名已更改。 * `Event()` 的 `time_fired: datetime | None` 参数已被替换为 `time_fired_timestamp: float | None`。 * `State()` 的参数字段列表中间新增了一个参数 `last_reported: datetime`。 更多详情请参阅 [`core PR #113511`](https://github.com/home-assistant/core/pull/113511) 和 [`core PR #113798`](https://github.com/home-assistant/core/pull/113798)。 --- url: /developers/blog/2024-03-21-config-entry-reconfigure-step.md --- 从 Home Assistant Core 2024.4 起,config entry 现在可以通过在其 config flow 中添加 `reconfigure` 步骤来进行重新配置。 这并非为了替代可选配置(`OptionsFlow`),而是允许用户在创建 config entry 之后更改设置配置。 ### Reconfiguration 与 Reauthentication `reconfigure` 步骤并不会替代 `reauth` 步骤,它们有不同的目的。 Reauthentication 应该在登录/token/等无效的情况下由集成自动启动,以便用户有机会调整这些设置。 Reconfiguration 由用户从 config entry 的选项菜单启动,应实现用于更新集成正常工作所必需的、非可选的 config entry 数据。认证问题通过 re-authentication flow 处理。([查看 reauthentication](/developers/core/integration/config_flow.md#reauthentication))。 ### 示例 示例包括:在搬家或拥有移动房屋时更改 `WeatherEntity` 的纬度和经度、更改本地设备的通信端口等。 要实现 `reconfigure` 步骤,请在您的 config flow 中将其包含如下: ```python import voluptuous as vol class ExampleConfigFlow(ConfigFlow, domain=DOMAIN): """Example 集成的 config flow。""" async def async_step_reconfigure(self, user_input: dict[str, Any] | None = None): """添加 reconfigure 步骤以允许重新配置 config entry。""" if user_input is not None: pass # TODO: 处理用户输入 return self.async_show_form( step_id="reconfigure", data_schema=vol.Schema({vol.Required("password"): str}), ) ``` --- url: /developers/blog/2024-03-30-deprecate-hass-helpers.md --- 从 Home Assistant 2024.5 起,我们弃用 `hass.helpers` 的使用。 使用 `hass.helpers` 将在日志中发出警告。 建议自定义集成的作者在 Home Assistant 2024.11 之前更新代码,以防止出现问题。 从 Home Assistant 2024.11 起,`hass.helpers` 将被移除,并且不再可用。 使用 `hass.helpers` 的集成应更新为直接从集成包中导入函数和类,并将 `hass` 对象作为第一个参数传入。 ### 新示例 ```python from homeassistant.core import HomeAssistant from homeassistant.helpers.aiohttp_client import async_get_clientsession async def async_setup(hass: HomeAssistant, config): """设置组件。""" client = async_get_clientsession(hass) ``` ### 旧示例 ```python from homeassistant.core import HomeAssistant async def async_setup(hass: HomeAssistant, config): """设置组件。""" client = hass.helpers.aiohttp_client.async_get_clientsession() ``` --- url: /developers/blog/2024-04-03-build-images-with-uv.md --- 在我们的生产镜像中用 `uv` 替换 `pip` 后,我们的构建流水线(因此发布新版本)快了很多。 `Uv` 是一个由 Rust 编写的极其快速的 Python 包安装器和解析器。它由 [Astral](https://astral.sh/) 开发,并且是开源的。可以在 [GitHub](https://github.com/astral-sh/uv) 上查看它。 在下表中,您可以看到每次构建可以节省大约 5 小时的执行时间。 | Arch | Pip | UV | Savings | |-----------|--------------|----------|----------| | aarch64 | 1h 24m 53s | 5m 18s | ~1h 20m | | armhf | 1h 52m 20s | 6m 2s | ~1h 46m | | armv7 | 1h 26m 43s | 5m 28s | ~1h 21m | | amd64 | 22m 10s | 3m 20s | ~19m | | i386 | 17m 37s | 3m 11s | ~14m | 平均而言,我们运行构建流水线 43 次,因为我们要创建: * 31 个 nightly(每天一个 nightly) * 7 个 beta 版本 * 5 个 stable 版本(包括 patch 版本) 总共,我们每月节省约 215 小时。 有了这一巨大的改进,我们现在可以更快速地发布热修复,因为发布新版本的流水线现在大约需要 20 分钟,而不是 2.5 小时。 每月节省的 215 个执行小时可供其他任务使用,使所有开发者和我们社区的 CI 体验更好。 通过将 `pip` 替换为 `uv`,我们通过使用更少的资源来构建镜像,提高了我们的可持续性。 **非常感谢 Astral 开发了这款出色的工具。** 请查看他们的[网站](https://astral.sh/)和提供的产品,例如他们还提供了一个"闪电"般快速的 Python linter/formatter。 --- url: /developers/blog/2024-04-07-deprecate_add_hass_job.md --- 作为提高性能并简化核心 job API 工作的一部分,`async_add_hass_job` 已被弃用,并将在 Home Assistant 2025.5 中移除。 调用应改用 `async_run_hass_job` 替代。 --- url: /developers/blog/2024-04-08-deprecated-backports-and-typing-aliases.md --- 在过去,我们从上游 CPython backport 了一些功能,以便提前使用并改善用户和开发者的体验。Home Assistant 仅支持 Python 3.12,因此这些功能可以直接从 Python 中使用。这些 backports 现在已被弃用,并将于未来移除。 | Deprecated | Replacement | Python version | | ---------- | ----------- | -------------- | | `homeassistant.backports.enum.StrEnum` | `enum.StrEnum` | >= 3.11 | | `homeassistant.backports.functools.cached_property` | `functools.cached_property` | >= 3.8, >= 3.12 (performance improvement) | 此外,一些 typing alias 现在也被弃用了。 | Deprecated | Replacement | | ---------- | ----------- | | `homeassistant.helpers.typing.ContextType` | `homeassistant.core.Context` | | `homeassistant.helpers.typing.EventType` | `homeassistant.core.Event` | | `homeassistant.helpers.typing.HomeAssistantType` | `homeassistant.core.HomeAssistant` | | `homeassistant.helpers.typing.ServiceCallType` | `homeassistant.core.ServiceCall` | --- url: /developers/blog/2024-04-10-new-notify-entity-platform.md --- ### 新的 notify entity platform notify platform 现在可以作为 [entity platform](https://developers.home-assistant.io/docs/core/entity/notify/) 使用。新的 `notify` platform 的 MVP [实现](https://github.com/home-assistant/core/pull/110950)了方法和 service `send_message`。它接受 `message` 作为必需属性。 与传统的 `notify.notify` service 不同,我们没有将 targets 作为参数,因为它是 entity,我们在调用 `send_message` 时可以针对多个 `notify` entity。 [architecture discussion](https://github.com/home-assistant/architecture/discussions/1041) 仍在进行中,讨论的主题包括要实现的 device class 以及通过[联系人注册表实现 recipient 支持](https://github.com/home-assistant/architecture/discussions/1041#discussioncomment-8947842)。 实现传统 `notify` service 的现有集成将分阶段迁移。第一步是迁移那些仅使用 `message` 作为参数的集成。 确定要迁移的集成如下: * circuit * clickatell * clicksend * command\_line * demo * ecobee * flock * free\_mobile * knx * mastodon 一旦我们有了 `title` 和/或 `recipient` 支持,就可以迁移更多集成来使用新的 platform。 当集成完成迁移后,用户将需要使用新的 `notify.send_message` service,因此在弃用期结束后,迁移变更将导致自动化失效。 --- url: /developers/blog/2024-04-13-deprecate_async_track_state_change.md --- `async_track_state_change` 已被弃用,并将在 Home Assistant 2025.5 中移除。应改用 `async_track_state_change_event`。 `async_track_state_change` 总是为 `EVENT_STATE_CHANGED` 创建一个顶层 listener,这会拒绝所有与所需 entity 不匹配的 state changes。当有多个集成使用 `async_track_state_change` 时,这种设计会带来性能问题。自从引入 `async_track_state_change_event` 以来,`async_track_state_change` 在 `core` 中已被逐步淘汰,最后一个实例在 2024.5 中被移除。 使用 `async_track_state_change` 的示例: ```python from homeassistant.core import State, callback from homeassistant.helpers.event import async_track_state_change @callback def _async_on_change(entity_id: str, old_state: State | None, new_state: State | None) -> None: ... unsub = async_track_state_change(hass, "sensor.one", _async_on_change) unsub() ``` 使用 `async_track_state_change_event` 替换的示例: ```python from homeassistant.core import Event, EventStateChangedData, callback from homeassistant.helpers.event import async_track_state_change_event @callback def _async_on_change(event: Event[EventStateChangedData]) -> None: entity_id = event.data["entity_id"] old_state = event.data["old_state"] new_state = event.data["new_state"] ... unsub = async_track_state_change_event(hass, "sensor.one", _async_on_change) unsub() ``` --- url: /developers/blog/2024-04-25-always-reload-after-successful-reauth-flow.md --- ## 在成功的 reauthentication 之后始终 reload 为了在成功的 reauthentication flow 之后更新并 reload entry,可以使用 helper `async_update_reload_and_abort`。该 helper 的默认行为已经更改。默认情况下,调用该 helper 时 entry 将始终 reload。如果 entry 需要 reauthentication,并不总是需要更新 entry,例如当账户被临时禁用或 API-key 被临时禁止时。 对于在 entry 未更改的情况下不希望 reload 的场景,可以向 helper 传入 `reload_even_if_entry_is_unchanged=False` 参数。 更多有关此 helper 的信息可以在[这里](/developers/core/integration/config_flow.md#reauthentication)找到。 ### 示例 ```python class OAuth2FlowHandler( config_entry_oauth2_flow.AbstractOAuth2FlowHandler, domain=DOMAIN ): """Config flow to handle OAuth2 authentication.""" reauth_entry: ConfigEntry | None = None async def async_step_reauth(self, user_input=None): """在 API 认证错误时执行 reauth。""" self.reauth_entry = self.hass.config_entries.async_get_entry( self.context["entry_id"] ) return await self.async_step_reauth_confirm() async def async_step_reauth_confirm(self, user_input=None): """通知用户需要 reauth 的对话框。""" if user_input is None: return self.async_show_form( step_id="reauth_confirm", data_schema=vol.Schema({}), ) return await self.async_step_user() async def async_oauth_create_entry(self, data: dict) -> dict: """为 reauth 创建 oauth config entry 或更新现有 entry。""" if self.reauth_entry: # 仅当 entry 被更新时才 reload return self.async_update_reload_and_abort( self.reauth_entry, data=data, reload_even_if_entry_is_unchanged=False, ) return await super().async_oauth_create_entry(data) ``` --- url: /developers/blog/2024-04-30-store-runtime-data-inside-config-entry.md --- 集成通常需要设置和跟踪自定义数据,例如 coordinators、API 连接或代码对象。以前,这些都存储在 `hass.data` 中,这使得跟踪它们变得困难。 随着最近的更改,现在可以使用 `entry.runtime_data` 来存储这些数据。在设置 platform 时,config entry 已经可用,并且会自动清理。卸载后无需再从 `hass.data` 中删除 key。 它还更好地支持了 type-checking。`ConfigEntry` 现在是泛型的,因此可以传递数据类型。为此,请使用 `dataclass` 等类型化的数据结构。为简化注释,建议为其定义一个 type alias。 示例可能如下所示: ```py # /__init__.py # type alias 需要以 'ConfigEntry' 作为后缀 type MyConfigEntry = ConfigEntry[MyData] @dataclass class MyData: client: MyClient other_data: dict[str, Any] async def async_setup_entry( hass: HomeAssistant, entry: MyConfigEntry, # 使用 type alias 替代 ConfigEntry ) -> bool: client = MyClient(...) # 赋值 runtime_data entry.runtime_data = MyData(client, {...}) ``` ```py # /switch.py from . import MyConfigEntry async def async_setup_entry( hass: HomeAssistant, entry: MyConfigEntry, # 使用 type alias 替代 ConfigEntry async_add_entities: AddEntitiesCallback, ) -> None: # 从 config entry 访问 runtime data data = entry.runtime_data async_add_entities([MySwitch(data.client)]) ``` --- url: /developers/blog/2024-05-01-improved-hass-data-typing.md --- 在过去,`hass.data` 面临的挑战之一是正确分配类型信息。由于它的类型为 `dict[str, Any]`,唯一的选择是 annotation assignments 或类似 `cast` 的方式: ```py data: MyData = hass.data[SOME_KEY] ``` 这有几个缺点。不仅需要为每个赋值添加注释,而且 type checker 基本上还会假定该注释总是正确的。特别是在重构过程中,很容易遗漏某个实例,虽然 type-checking 仍然通过,但实际代码却已经损坏。 为了解决这个问题,现在可以使用两个新的 key 类型 `HassKey` 和 `HassEntryKey`。借助一点"魔法",type checker 现在能够推断类型并确保其正确性。甚至在存储数据时也是如此。 示例可能如下所示: ```py # /__init__.py from homeassistant.util.hass_dict import HassKey MY_KEY: HassKey["MyData"] = HassKey(DOMAIN) @dataclass class MyData: client: MyClient other_data: dict[str, Any] async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: client = MyClient(...) hass.data[MY_KEY] = MyData(client, {...}) hass.data[MY_KEY] = 1 # mypy error ``` ```py # /switch.py from . import MY_KEY async def async_setup_platform( hass: HomeAssistant, config: ConfigType, async_add_entities: AddEntitiesCallback, discovery_info: DiscoveryInfoType | None = None, ) -> None: data = hass.data[MY_KEY] reveal_type(data) # MyData async_add_entities([MySwitch(data.client)]) ``` 按 `entry.entry_id` 将数据存储在 dict 中?通常直接将数据存储到 `ConfigEntry` 中会更好。请参见关于此的近期[博客文章](/developers/blog/2024-04-30-store-runtime-data-inside-config-entry.md)。如果这不是一个选项,请使用 `HassEntryKey`。 ```py # /__init__.py from homeassistant.util.hass_dict import HassEntryKey MY_KEY: HassEntryKey["MyData"] = HassEntryKey(DOMAIN) async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, ) -> bool: client = MyClient(...) hass.data.setdefault(MY_KEY, {})[entry.entry_id] = MyData(client, {...}) ``` --- url: /developers/blog/2024-05-03-notify-title.md --- ### send\_message service notify entity platform 的 Title 选项 最近我们添加了 notify [entity platform](https://developers.home-assistant.io/docs/core/entity/notify/)。新的 `notify` platform 方法实现了 service `send_message`。该 service 现在还将可选的 `title` 作为参数接受。这使得一些新的集成现在可以迁移到使用新的 entity platform: * cisco\_webex\_teams * file * sendgrid * syslog * tibber [architecture discussion](https://github.com/home-assistant/architecture/discussions/1041) 仍在进行中。 当集成完成迁移后,用户将需要使用新的 `notify.send_message` service,因此在弃用期结束后,迁移变更将导致自动化失效。 --- url: /developers/blog/2024-05-09-improving-ci-test-execution.md --- 在 [UV 每月为我们找回 215 个计算小时](/developers/blog/2024-04-03-build-images-with-uv.md) 之后,我们对速度有了更高的追求。 我们的 CI workflow 在每次 commit 时触发,由于贡献量巨大,它在 2024 年 3 月被触发了 6647 次。 完整的运行(即执行整个测试套件)耗时很长。 结果发现,我们用来将测试分成 10 个组的插件效率很低。每个 pytest job 都需要发现所有测试,即使该 job 打算只执行其中一部分。 现在我们有一个单独的 job 来发现所有测试并将它们分成 10 个组。10 个 pytest job 只需要执行所有测试的一个子集。不在每个 test runner 中进行完整的发现,每次完整运行可节省我们 3 小时! ```mermaid flowchart LR A[Full run] --> R{Distribute work} R -->|One| D[Discover tests to run] R -->|Two| E[Discover tests to run] R -->|Three| F[Discover tests to run] D --> D2[Run tests] E --> E2[Run tests] F --> F2[Run tests] AN[Full run] --> RW[Discover tests to run] RW --> RN{Distribute work} RN -->|One| D2N[Run tests] RN -->|Two| E2N[Run tests] RN -->|Three| F2N[Run tests] ``` 对 2024 年 3 月的 6647 个 CI workflow 的简要分析揭示了以下统计: * 2406 个在终止前被取消 * 1771 个应为 full runs * 1085 个失败 * 732 个为失败的 full runs * 3007 个成功终止 * 1629 个 partial runs(仅执行了给定集成的测试) * 1378 个 full runs 考虑到 1378 个成功的 full runs,如果有了 [#114381](https://github.com/home-assistant/core/pull/114381),我们在 2024 年 3 月将节省约 **4042 小时 ~ 168 天** 的执行时间。如果我还分析了失败/取消的 runs,节省的时间会更多。 每月节省的超过 168 天的执行时间可供其他任务使用,使所有开发者和我们社区的 CI 体验更好。 我们通过使用更少的资源来运行测试套件,提高了可持续性。 **非常感谢 GitHub 为 Home Assistant 提供额外的 CI runner。** --- url: /developers/blog/2024-05-10-group-integration.md --- ## 使用 group integration 设置 entity platform 的变更 默认情况下,`group` 集成允许将 entity 分组。如果 entity 的默认 `ON`/`OFF` state 分别为 `on` 和 `off`,则默认支持 `grouping`。但是,对于可以分组但具有替代状态的 Entity platform(例如 `cover`(`open`/`closed`)或 `person`(`home`/`not_home`)),或者意图排除的 platform(如 `sensor`),设置方式有所不同。这些 entity platform 必须在 `group.py` 模块中实现 `async_describe_on_off_states`。 在 `async_describe_on_off_states` 中,`domain` 需要是传递给 `registry` 方法 `on_off_states` 和 `exclude_domain` 的第一个参数。在使用 `registry.on_off_state` 注册替代 `ON`/`OFF` state 时,除了 `ON` states 之外,还需要传递默认的 `ON` state。 ### 注册替代状态的示例 `registry.on_off_states` 的新签名: ```python @callback def on_off_states( self, domain: str, on_states: set[str], default_on_state:str, off_state: str ) -> None: """为当前 domain 注册 on 和 off states。""" ... ``` `vacuum` entity platform 的 `group.py` 示例,注册替代的 `ON`/`OFF` state。请注意,第一个 `ON` state 现在被视为默认的 `ON` state。 ```python """描述 group states。""" from typing import TYPE_CHECKING from homeassistant.const import STATE_OFF, STATE_ON from homeassistant.core import HomeAssistant, callback if TYPE_CHECKING: from homeassistant.components.group import GroupIntegrationRegistry from .const import DOMAIN, STATE_CLEANING, STATE_ERROR, STATE_RETURNING @callback def async_describe_on_off_states( hass: HomeAssistant, registry: "GroupIntegrationRegistry" ) -> None: """描述 group on off states。""" registry.on_off_states( DOMAIN, # domain # 包含所有 group ON states 的 set { STATE_ON, STATE_CLEANING, STATE_RETURNING, STATE_ERROR, }, STATE_ON, # 默认 group ON state STATE_OFF, # Group OFF state ) ``` ### 从 group entity 中排除 entity platform 的示例 `registry.exclude_domain` 的新签名: ```python @callback def exclude_domain(self, domain: str) -> None: """排除当前 domain。""" ... ``` `sensor` entity platform 的 `group.py` 示例,从 `group` entity 中排除 sensor entity。 ```python """描述 group states。""" from typing import TYPE_CHECKING from homeassistant.core import HomeAssistant, callback if TYPE_CHECKING: from homeassistant.components.group import GroupIntegrationRegistry from .const import DOMAIN @callback def async_describe_on_off_states( hass: HomeAssistant, registry: "GroupIntegrationRegistry" ) -> None: """描述 group on off states。""" registry.exclude_domain(DOMAIN) ``` --- url: /developers/blog/2024-05-10-lock-supports-open-state.md --- 最近我们为 `LockEntity` 添加了 `open` 和 `opening` state。 如果您拥有能够区分 `unlocked`(未锁定但已闩锁)state 和 `open`(未锁定且闩锁已拉开)state 的锁,这将非常有用。 `LockEntity` 通过实现 feature flag `LockEntityFeature.OPEN` 已经支持 [`open` 方法](/developers/core/entity/lock.md#open)。 示例(默认实现): ```python class MyLock(LockEntity): @property def is_opening(self) -> bool: """如果锁已打开则返回 true。""" return self._state == STATE_OPENING @property def is_open(self) -> bool: """如果锁已打开则返回 true。""" return self._state == STATE_OPEN async def async_open(self, **kwargs: Any) -> None: """打开门的闩锁。""" self._state = STATE_OPEN self.async_write_ha_state() ``` --- url: /developers/blog/2024-05-19-fix_zoneinfo_blocking_io.md --- 如果传递的 timezone 不在缓存中,构造 `ZoneInfo` 对象可能会进行阻塞 I/O 以从磁盘加载 zone info。 现在可以使用 `dt_util.async_get_time_zone` 来替换 `dt_util.get_time_zone`,以便在 event loop 中异步安全地获取 timezone,它不会在 event loop 中执行阻塞 I/O。 `hass.config.set_time_zone` 已被弃用,并由 `hass.config.async_set_time_zone` 替代。`hass.config.set_time_zone` 将在 2025.6 中移除。设置 timezone 仅影响测试,因为任何集成都不应在生产环境中调用此函数。 直接检查 `dt_util.DEFAULT_TIME_ZONE` 已被弃用,应改用 `dt_util.get_default_time_zone()`。 如果您的集成需要在 event loop 中构造 `ZoneInfo` 对象,建议使用 [`aiozoneinfo` 库](https://pypi.org/project/aiozoneinfo/)。 --- url: /developers/blog/2024-05-20-llm-api.md --- 自从作为"语音之年"(Year of the Voice)的一部分在 Home Assistant 中引入 LLMs 以来,我们收到了允许 LLMs 与 Home Assistant 交互的请求。现在,通过将 Home Assistant API 暴露给 LLMs,这已成为可能。 Home Assistant 将附带一个内置的 Assist API,该 API 遵循内置的 conversation agent 也可访问的能力和已暴露的 entity。 与 LLMs 交互的集成应更新其集成以支持 LLM API。 自定义集成的作者可以创建自己的 LLM API,为 LLMs 提供更高级的 Home Assistant 访问权限。 更多信息请参阅 [LLM API 文档](/developers/core/llm.md),以及[此示例 pull request](https://github.com/home-assistant/core/pull/117644)了解如何在您的集成中集成 LLM API。 --- url: /developers/blog/2024-05-22-alarm_control_panel_validation.md --- `AlarmControlPanelEntity` 现在强制要求对 alarm control panel entity 的 code 进行验证,这些 entity 将 `code_arm_required` 设置为 `True`(默认行为)。当需要 code 但未提供 code 时,service calls 将失败。 以前这完全是可选的,用户无论集成是否需要,都可以跳过 code 输入(因此每个集成需要实现自己的检查)。 由于默认行为是需要 code,因此不需要 code 输入的自定义集成需要将 `code_arm_required` 设置为 `False`,否则用户将始终需要输入 code,无论 service calls 是否需要它。 --- url: /developers/blog/2024-06-12-async_forward_entry_setups.md --- 调用 `hass.config_entries.async_forward_entry_setup` 已被弃用,并将在 Home Assistant 2025.6 中移除。相反,请 await `hass.config_entries.async_forward_entry_setups`,因为它可以一次性加载多个 platform,并且效率更高,因为它不需要为每个 platform 单独使用一个 import executor job。 如果在 config entry 正在设置时调用 `hass.config_entries.async_forward_entry_setups`,必须始终 await 它,以确保它在 config entry 设置完成之前结束。更多详情请参阅[此博客文章](https://developers.home-assistant.io/blog/2022/07/08/config_entry_forwards)。 --- url: /developers/blog/2024-06-18-async_register_static_paths.md --- `hass.http.register_static_path` 已被弃用,因为它在 event loop 中执行阻塞 I/O,请改用 `await hass.http.async_register_static_paths([StaticPathConfig(url_path, path, cache_headers)])`。 `async_register_static_paths` 的参数与 `register_static_path` 相同,只是它们被包装在 `StaticPathConfig` `dataclass` 中,并接受它们的 `Iterable` 以便一次性注册多个 path,从而避免多个 executor job。 例如,如果您的集成调用了 `hass.http.register_static_path("/integrations/photos", "/config/photos", True)`,现在应改为调用 `await hass.http.async_register_static_paths([StaticPathConfig("/integrations/photos", "/config/photos", True)])`。 `StaticPathConfig` `dataclass` 应从 `homeassistant.components.http` 导入。 `hass.http.register_static_path` 将在 2025.7 中移除。 ## 示例 ```python from pathlib import Path from homeassistant.components.http import StaticPathConfig should_cache = False files_path = Path(__file__).parent / "static" files2_path = Path(__file__).parent / "static2" await hass.http.async_register_static_paths([ StaticPathConfig("/api/my_integration/static", str(files_path), should_cache), StaticPathConfig("/api/my_integration/static2", str(files2_path), should_cache) ]) ``` --- url: /developers/blog/2024-06-22-excluding-state-attributes-from-recording-match-all.md --- 从 recording 中排除 state attribute 的方式在 2023 年 9 月之前已经更改过。 之前的实现存在局限性,因为没有方法可以处理动态 attribute,也没有简单的方法来简单地排除所有 attribute,而不是逐一列出它们。 现在可以在集成中使用 `MATCH_ALL` 常量来告诉 recording 不要记录任何 attribute,这将自动从 recording 中移除所有 attribute,但 `device_class`、`state_class`、`unit_of_measurement` 和 `friendly_name` 除外。 ```python from homeassistant.const import MATCH_ALL class ExampleEntity(Entity): """一个 entity 的实现。""" _unrecorded_attributes = frozenset({MATCH_ALL}) ``` 更多详情请参阅 [entity 文档](/developers/core/entity.md#excluding-state-attributes-from-recorder-history)。 原始更改的背景在 [architecture discussion #964](https://github.com/home-assistant/architecture/discussions/964) 中。 --- url: /developers/blog/2024-07-07-climate-hvacaction-defrosting.md --- `ClimateEntity` 有一个 `hvac_action` 属性,它描述了 climate entity 当前正在做什么(这与它的 mode 不同)。 我们添加了 `DEFROSTING` 作为 `HVACAction` 的一种可能值,用于表示 entity 当前正在除霜。 除霜是指系统反向运行一段时间以融化积聚的冰块。它通常发生在较冷的环境中,不应与例如通过加热车窗来除霜的汽车混淆。 ```python from homeassistant.components.climate.const import HVACAction class MyClimateEntity(ClimateEntity): """我的 climate entity 的实现。""" def hvac_action(self) -> HVACAction | None: """如果支持,返回当前正在运行的 hvac 操作。""" return HVACAction.DEFROSTING ``` 更多详情请参阅 [climate entity 文档](/developers/core/entity/climate.md#hvac-action)。 原始更改的背景在 [architecture discussion #1090](https://github.com/home-assistant/architecture/discussions/1090) 中。 --- url: /developers/blog/2024-07-16-device-info-model-id.md --- 从 2024.8 开始,您现在可以在 `DeviceInfo` 类中添加一个 model 标识符。该标识符可用于在集成和 frontend 中识别 device model。 例如,Philips Hue ambiance spot 以前被列为"Hue ambiance spot (LTG002)"。现在可以将其拆分,其中 `model` 为"Hue ambiance spot",`model_id` 为"LTG002"。 --- url: /developers/blog/2024-07-16-service-actions.md --- "Services" 一词让许多用户感到困惑,因为它并不能立即明确指代什么;它可能是 web 或 STT service,但在 Home Assistant 的上下文中,它意味着完全不同的东西(service calls)。 在 Home Assistant 2024.8 中,"Services"(即 service calls)将被重命名为"Actions"。此更改是我们持续努力使 Home Assistant 更用户友好、更容易让新用户理解的一部分。该术语与我们在过去几个月一直实施的 UI 更改相符(在我们的 automations 和 script 编辑器中不再存在 call services)。实际上,用户在自己的 automations 中执行的是 actions。 此更改将反映在 Home Assistant UI、文档以及使用"Services"一词的其他地方。例如,Developer Tools 中的 **"Services"** 选项卡将重命名为 **"Actions"**。 对于开发者而言,无需担心此变更。在开发者文档中,我们将把所有对"services"的引用更新为"service actions",因为我们在后端有不同种类的 actions(例如 device actions)。底层功能将保持不变,过渡是无缝的。 这只是一个术语变更,就像面向终端用户的变更一样。 --- url: /developers/blog/2024-07-19-fan-fanentityfeatures-turn-on_off.md --- 从 Home Assistant Core 2024.8 起,我们为 `FanEntityFeature` 添加了两个新 flag:`TURN_ON`、`TURN_OFF`。 实现了 `turn_on` service call 的集成需要设置 `TURN_ON` feature flag。 实现了 `turn_off` service call 的集成需要设置 `TURN_OFF` feature flag。 将有 6 个月的弃用期(至 2025.2),在此期间 `FanEntity` 将代表实现了相应方法的集成设置这些 flag。从 2025.2 起,如果 entity feature 未相应设置,集成将无法使用相应的方法。 在不设置相应 feature flag 的情况下实现这些方法,将创建一条警告日志,引导用户为集成创建 issue。 集成应在 `FanEntity` 子类实例中将属性 `_enable_turn_on_off_backwards_compatibility` 设置为 `False`,一旦迁移到使用或不使用新的 feature flag 之后。 这将停止在弃用期间自动设置新的 feature flag,并应在弃用结束后移除。 --- url: /developers/blog/2024-07-24-climate-min-max-temperature-check.md --- 从 Home Assistant Core 2024.8 起,我们为 `ClimateEntity` 提供的温度 action call 实现了验证。 集成不再需要在其自己的设置温度方法(`async_set_temperature`/`set_temperature`)中进行此检查。 然而,集成正确指定 `min_temp` 和 `max_temp` 属性非常重要,否则如果验证失败,用户可能无法设置正确的温度。 同样,处理同时可在 `Celsius` 和 `Fahrenheit` 下运行的设备的集成需要相应地转换其 `min_temp` 和 `max_temp` 值。 ### 示例 将设备的原生 min/max 值转换为集成指定的 temperature\_unit。 ```python class MyClimateEntity(ClimateEntity): """我的 climate entity 的实现。""" @property def min_temp(self) -> float: """返回最低温度。""" return TemperatureConverter.convert( self.device.min_temp, UnitOfTemperature.CELSIUS, self.temperature_unit ) @property def max_temp(self) -> float: """返回最高温度。""" return TemperatureConverter.convert( self.device.max_temp, UnitOfTemperature.CELSIUS, self.temperature_unit ) ``` --- url: /developers/blog/2024-08-05-coordinator_async_setup.md --- 在 Home Assistant 2024.8 中,我们为 data update coordinator 引入了 `_async_setup` 方法。 此方法允许您运行异步代码来准备您的 `DataUpdateCoordinator` 实例, 或加载只需加载一次的数据。 您可以在 coordinator 中重写 `_async_setup`,它将在 `coordinator.async_config_entry_first_refresh()` 期间自动被调用。 它提供与 `_async_update_data` 相同的错误处理,并将相应地处理 `ConfigEntryError` 和 `ConfigEntryAuthFailed`。 ## 示例 ```python class MyUpdateCoordinator(DataUpdateCoordinator[MyDataType]): prereq_data: SomeData def __init__( self, hass: HomeAssistant, ) -> None: """初始化 coordinator。""" super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=SCAN_INTERVAL) self.my_api = MyApi() async def _async_setup(self) -> None: """执行初始化逻辑。""" self.prereq_data = await self.my_api.get_initial_data() async def _async_update_data(self) -> MyDataType: """执行通常的更新""" return await self.my_api.update(self.prereq_data) ``` ## 避免检查初始化状态 此更改允许您重构那些在 `_async_update_data` 方法中通过检查初始化变量来加载初始数据的代码,例如 ```python async def _async_update_data(self) -> ...: if not self.something: self.something = self.client.fetch() return self.client.fetch_data() ``` 重构为 ```python async def _async_setup(self) -> None: self.something = self.client.fetch() async def _async_update_data(self) -> ...: return self.client.fetch_data() ``` ## 更多信息 更多信息请阅读[文档](https://developers.home-assistant.io/docs/integration_fetching_data/)。 --- url: /developers/blog/2024-08-23-lawn-mower-activity-returning.md --- 从 Home Assistant Core 2024.9 起,实现了 `LawnMowerEntity` 的集成可以使用新的 `LawnMowerActivity.RETURNING` state 来指示其割草机正在返回 dock。 更多详情请参阅 [文档](/developers/core/entity/lawn-mower.md#activities)。 ## 示例 ```python async def async_dock(self) -> None: """开始 dock。""" self._attr_activity = LawnMowerActivity.RETURNING self.async_write_ha_state() ``` 或者在您的 `lawn_mower` entity 的 activity 属性中返回 `LawnMowerActivity.RETURNING`。 ```python @property def activity(self) -> LawnMowerActivity: """返回割草机的 state。""" mower = self.mower if mower.state is RETURNING: return LawnMowerActivity.RETURNING ... ``` --- url: /developers/blog/2024-08-27-changed-icon-translations-schema.md --- icon translations schema 已经调整,允许为[service 中的 sections](/developers/dev_101_services.md#grouping-of-service-action-fields)分配 icon。 service 的 icon 现在应按照更明确的 schema 提供,该 schema 允许为 sections 指定 icon。 这允许像这样指定 service icon: ```json "services": { "test_service_1": { "service": "mdi:flask", "sections": { "section_1": "mdi:test-tube" } } } ``` 旧格式在为期一年的弃用期间得到支持,以便自定义集成有时间迁移到新 schema: ```json "services": { "test_service_1": "mdi:flask" } ``` 请参阅 [core PR #124656](https://github.com/home-assistant/core/pull/124656) 以获取实现细节。 ### 对自定义卡片的影响 发送到 frontend 的 icon 数据始终遵循新格式,显示 service icon 的自定义卡片需要进行调整。 --- url: /developers/blog/2024-08-27-entity-service-schema-validation.md --- 注册 entity service action 允许集成作者传入: * 无 schema(`None`) * 一个字典,它将通过传递给 `cv.make_entity_service_schema` 转换为 voluptuous schema * 一个自定义的 voluptuous schema 对于第三种情况,当使用不满足以下至少一个条件的自定义 schema 注册 entity action 时,现在将记录一条警告: * 由 `cv.make_entity_service_schema` 返回的 validator * 由 `cv.make_entity_service_schema` 返回的 validator,包裹在 `vol.Schema` 中 * 由 `cv.make_entity_service_schema` 返回的 validator,包裹在 `vol.All` 中 在 Home Assistant Core 2025.10 中,将不再能够注册不满足此要求的自定义 schema 的 entity action。 更改的原因是,如果未使用 `cv.make_entity_service_schema`,service 将不会自动支持所有可能的 entity 定向方式。 更多详情请参阅 [开发者文档](/developers/dev_101_services.md#entity-service-actions) 以及 core PR [#124102](https://github.com/home-assistant/core/pull/124102) 和 [#125057](https://github.com/home-assistant/core/pull/125057)。 --- url: /developers/blog/2024-09-02-template-hass-required.md --- 随着 [core PR #89242](https://github.com/home-assistant/core/pull/89242) 的合并(该 PR 已合入 Home Assistant Core 2023.4),在 schema 验证期间创建的 `Template` 对象上将会设置 `Template.hass`。 在此更改之前,在渲染模板之前必须检查并设置 `Template.hass`,这在代码库的许多地方都有实现。 这类代码已从 Home Assistant Core 中移除,这将影响到自定义集成的作者: * 手动创建 `Template` 对象的自定义集成必须向构造函数传入一个有效的 `hass` 对象。在 config entries 创建模板时尤其如此。如果不传入 `hass` 对象,将触发 deprecation warning,并在 Home Assistant Core 2025.10 中失效。 * 辅助函数 `template.attach` 已不再有任何作用,core 也不再使用它。它已被标记为 deprecated,并计划在 Home Assistant Core 2025.10 中移除。 --- url: /developers/blog/2024-09-10-calories-units.md --- 从 Home Assistant 2024.10 开始,calories 已被添加到 energy [sensor class](/developers/core/entity/sensor.md#available-device-classes) 的 measurement units 中。通常,这些传感器用于测量热能、水加热、食物能量或人体能量消耗。 --- url: /developers/blog/2024-09-11-extending-deprecation-hass-components.md --- 在 2024 年 2 月 27 日,我们[宣布弃用](/developers/blog/2024-02-27-deprecate-bind-hass-and-hass-components.md)了 `@bind_hass` decorator 和 `hass.components` 属性,计划于 Home Assistant 2024.9 版本生效。 由于仍有大量自定义集成在使用它们,并且近期又发布了 HACS v2 更新,我们决定将 deprecation 期限再延长六个月。 这意味着从 Home Assistant 2025.3 开始,`@bind_hass` decorator 和 `hass.components` 将被移除。 我们鼓励所有自定义集成的开发者更新他们的代码,以避免在 Home Assistant 2025.3 发布之前出现任何问题。 --- url: /developers/blog/2024-09-23-constants-media-player-deprecation.md --- 自 Home Assistant Core 2022.5 起,`MediaPlayerEntity` 中使用的 feature flag 常量已被 deprecated,并由 `MediaPlayerEntityFeature` enum 取代。随后在 2022.10 中,repeat mode、media type 和 media class 常量也被 deprecated,并分别由 `RepeatMode`、`MediaType` 和 `MediaClass` 取代。 然而,当时并没有执行正确的 deprecation 流程,因此现在在 2024.10 中我们正式开始为期一年的 deprecation 期,这些常量将从 2025.10 起停止工作,以确保所有自定义集成作者都有时间进行调整。 --- url: /developers/blog/2024-09-23-feature-flag-constants-vacuum-deprecation.md --- 自 Home Assistant Core 2022.5 起,`StateVacuumEntity` 中使用的 feature flag 常量已被 deprecated,并由 `VacuumEntityFeature` enum 取代。 然而,当时并没有执行正确的 deprecation 流程,因此现在在 2024.10 中我们正式开始为期一年的 deprecation 期。这些常量将从 2025.10 起停止工作,以确保所有自定义集成作者都有时间进行调整。 --- url: /developers/blog/2024-09-23-state-constants-camera-deprecation.md --- 自 Home Assistant Core 2024.10 起,`Camera` 中用于返回 state 的常量已被 deprecated,并由 `CameraState` enum 取代。 设有为期一年的 deprecation 期,这些常量将从 2025.10 起停止工作,以确保所有自定义集成作者都有时间进行调整。 由于 `state` 属性本来就不应被覆盖,在大多数情况下,这一变更仅会影响其他 Entity 属性或测试。 --- url: /developers/blog/2024-09-23-state-constants-lock-deprecation.md --- 自 Home Assistant Core 2024.10 起,`LockEntity` 中用于返回 state 的常量已被 deprecated,并由 `LockState` enum 取代。 设有为期一年的 deprecation 期,这些常量将从 2025.10 起停止工作,以确保所有自定义集成作者都有时间进行调整。 由于 `state` 属性本来就不应被覆盖,在大多数情况下,这一变更仅会影响其他 Entity 属性或测试,而不是 `state` 属性本身。 --- url: /developers/blog/2024-09-24-climate-set-temp-validation.md --- 自 Home Assistant Core 2024.10 起,我们增加了对 `set_temperature` 方法参数传递的进一步校验。这意味着集成无需在自己的方法中实现这些校验。 在 2024.10 之前,当 entity 没有设置 `ClimateEntityFeature.TARGET_TEMPERATURE` 时,可以在 action 中设置 `temperature` 参数;当 entity 没有设置 `ClimateEntityFeature.TARGET_TEMPERATURE_RANGE` 时,也可以设置 `target_temp_low`/`target_temp_high` 参数。现在这将不再可行,系统会抛出 `ServiceValidationError`,告知用户在 action 调用中使用了错误的参数。 此外,在设置温度范围时,之前可以将 `target_temp_low` 设置为高于 `target_temp_high` 的值。 现在这将抛出 `ServiceValidationError`,告知用户高值必须高于低值。 --- url: /developers/blog/2024-09-24-device-tracker-entity-description.md --- device\_tracker 实体的 `source_type` 属性现在始终要求是 `SourceType` enum 值。标准字符串不再有效。 `TrackerEntity` 和 `ScannerEntity` 现在拥有专用的 `ScannerEntityDescription` 和 `TrackerEntityDescription`,当需要将 `EntityDescription` 关联到 `Entity` 时必须使用它们作为基类。 这些实体的 `source_type` 现在也默认为 `SourceType.GPS` 和 `SourceType.ROUTER`,因此可能可以移除覆盖该属性的代码。 同时新增了以下 shorthand 属性: * `BaseTrackerEntity._attr_source_type` * `TrackerEntity._attr_latitude` * `TrackerEntity._attr_location_accuracy` * `TrackerEntity._attr_location_name` * `TrackerEntity._attr_longitude` * `TrackerEntity._attr_source_type`(默认为 `SourceType.GPS`) * `ScannerEntity._attr_hostname` * `ScannerEntity._attr_ip_address` * `ScannerEntity._attr_mac_address` * `ScannerEntity._attr_source_type`(默认为 `SourceType.ROUTER`) 更多详情请参阅 [device-tracker 文档](/developers/core/entity/device-tracker.md)。 --- url: /developers/blog/2024-09-28-update-version-compare.md --- 随着 [core PR #124797](https://github.com/home-assistant/core/pull/124797) 的合并(该 PR 将合入 Home Assistant Core 2024.10),update 平台新增了一个方法:`version_is_newer()`。 在此更改之前,已安装固件版本、新可用版本与 beta 版本之间的比较逻辑是硬编码的: ```python def version_is_newer(self, latest_version: str, installed_version: str) -> bool: """Return True if latest_version is newer than installed_version.""" return AwesomeVersion(latest_version) > installed_version ``` 现在,新方法允许开发者自定义该比较逻辑,编写他们自己的方法即可。 以下是一个示例(为 Shelly gen1 设备实现): ```python def version_is_newer(self, latest_version: str, installed_version: str) -> bool: """Return True if available version is newer then installed version.""" return AwesomeVersion( latest_version, find_first_match=True, ensure_strategy=[AwesomeVersionStrategy.SEMVER], ) > AwesomeVersion( installed_version, find_first_match=True, ensure_strategy=[AwesomeVersionStrategy.SEMVER], ) ``` --- url: /developers/blog/2024-10-01-assist-satellite-entity.md --- 用户通常通过远程语音 satellite 与 [Assist](https://www.home-assistant.io/voice_control/) 进行交互,例如运行 ESPHome 的 [ESP32-S3-BOX-3](https://www.home-assistant.io/voice_control/s3_box_voice_assistant/)、运行 VoIP 的[模拟电话](https://www.home-assistant.io/voice_control/worlds-most-private-voice-assistant/)等。管理这些 satellite 的集成使用了临时的 `binary_sensor` 和 `select` 实体,以允许用户配置 satellite 的[pipeline](/developers/voice/pipelines.md)、基于 pipeline state 进行自动化等。 新的 [`AssistSatelliteEntity`](/developers/core/entity/assist-satellite.md) 提供了一个表示语音 satellite 的 entity。它的 state 会跟随底层的 Assist pipeline,从而便于自动化。此外: * 新增了一个 [announce action](https://home-assistant.io/integrations/assist_satellite#action-assist_satelliteannounce),可用于在支持的设备上进行广播。 * 还新增了几个 [websocket 命令](/developers/core/entity/assist-satellite.md#websocket-api),提供了一种统一的方式来获取和设置设备上的活动唤醒词。 `esphome` 和 `voip` 集成已经迁移到使用 `AssistSatelliteEntity`,`wyoming` 集成将紧随其后。 --- url: /developers/blog/2024-10-08-state-constants-cover-deprecation.md --- 自 Home Assistant Core 2024.11 起,`CoverEntity` 中用于返回 state 的常量已被 deprecated,并由 `CoverState` enum 取代。 设有为期一年的 deprecation 期,这些常量将从 2025.11 起停止工作,以确保所有自定义集成作者都有时间进行调整。 由于 `state` 属性本来就不应被覆盖,在大多数情况下,这一变更仅会影响其他 Entity 属性或测试,而不是 `state` 属性本身。 更多详情请参阅 [cover 文档](/developers/core/entity/cover.md#states)。 --- url: /developers/blog/2024-10-08-unit-of-conductivity-changes.md --- `UnitOfConductivity` enum 已从以下内容更改为: ```py class UnitOfConductivity(StrEnum): """Conductivity units.""" SIEMENS = "S/cm" MICROSIEMENS = "µS/cm" MILLISIEMENS = "mS/cm" ``` 更改为: ```py class UnitOfConductivity(StrEnum): """Conductivity units.""" SIEMENS_PER_CM = "S/cm" MICROSIEMENS_PER_CM = "µS/cm" MILLISIEMENS_PER_CM = "mS/cm" ``` 旧的 enum 成员可以在为期一年的 deprecation 期内继续使用,以便自定义集成有时间迁移到新的 enum 成员。 实现详情请参阅 [core PR #127919](https://github.com/home-assistant/core/pull/127919)。 --- url: /developers/blog/2024-10-09-extend-deprecation-hass-helpers.md --- 在 2024 年 3 月 30 日,我们[宣布弃用](/developers/blog/2024-03-30-deprecate-hass-helpers.md)了 `hass.helpers` 属性,计划于 Home Assistant 2024.11 版本生效。 由于仍有大量自定义集成在使用它们,并且近期又发布了 HACS v2 更新,我们决定将 deprecation 期限再延长六个月。 这意味着从 Home Assistant 2025.5 开始,`hass.helpers` 将被移除。 我们鼓励所有自定义集成的开发者更新他们的代码,以避免在 Home Assistant 2025.5 发布之前出现任何问题。 --- url: /developers/blog/2024-10-21-reauth-reconfigure-helpers.md --- ConfigFlow 中新增了一些辅助方法,以简化 reauth 和 reconfigure flows 的管理: * `self._get_reauth_entry()` 和 `self._get_reconfigure_entry()` 可以随时访问对应的 config entry * 应优先使用它们,而不是 `self.hass.config_entries.async_get_entry(self.context["entry_id"])` * config entry 应在需要时(局部变量,每步一次)请求,而不应作为 class 属性缓存 * 如果 steps 与 discovery 或 user flows 共享,在访问 entry 前应检查 `self.source` 是否为 `SOURCE_REAUTH` 或 `SOURCE_RECONFIGURE` * `self._abort_if_unique_id_mismatch` 允许你在 `unique_id` 与待重新认证或重新配置的 config entry 的 `unique_id` 不匹配时中止 * 应在调用 `self.async_set_unique_id` 之后使用 * 如果 steps 与 discovery 或 user flows 共享,应检查 `self.source` 是否为 `SOURCE_REAUTH` 或 `SOURCE_RECONFIGURE` * 其他 source 应继续使用 `self._abort_if_unique_id_configured` * `self.async_update_reload_and_abort` 已调整,可为 reconfigure flows 更新默认消息 * 新消息 `reconfigure_successful` 必须存在于 `strings.json` 中 * `self.async_update_reload_and_abort` 新增参数 `data_updates`,用于将数据更新与已有的数据合并 * 优先于使用 `data` 参数,因为它降低了在 schema 更新时数据丢失的风险 更多详情请参阅 [reconfigure](/developers/core/integration/config_flow.md#reconfigure) 和 [reauthentication](/developers/core/integration/config_flow.md#reauthentication) 文档。 --- url: /developers/blog/2024-10-22-new-alarm-state-property.md --- 自 Home Assistant Core 2024.11 起,我们在 `AlarmControlPanelEntity` 中引入了 `alarm_state` 属性。这个新属性应取代直接设置 `state` 属性。 新的 `alarm_state` 属性应使用新的 `AlarmControlPanelState` enum 返回其 state,而不是像以前那样使用 `STATE_ALARM_*` 常量设置 state。 设有为期一年的 deprecation 期,这些常量将从 2025.11 起停止工作,以确保所有自定义集成作者都有时间进行调整。 ### 示例 ```python from homeassistant.components.alarm_control_panel import AlarmControlPanelEntity, AlarmControlPanelState class MyAlarm(AlarmControlPanelEntity): """My alarm.""" @property def alarm_state(self) -> AlarmControlPanelState | None: """Return the state of the alarm.""" if self.device.is_on(): return AlarmControlPanelState.ARMED_AWAY return AlarmControlPanelState.DISARMED ``` 更多详情请参阅 [alarm control panel 文档](/developers/core/entity/alarm-control-panel.md#states)。 --- url: /developers/blog/2024-10-31-core-config-moved.md --- ### 变更摘要 Core config 类的定义——其实例可通过 [`hass.config`](https://developers.home-assistant.io/docs/dev_101_hass/#the-hass-object) 访问——已从 `homeassistant/core.py` 移至 `homeassistant/core_config.py`。迁移是为了让 core 代码更容易阅读和理解。当前从 `homeassistant.core` 导入 `Config` 的自定义集成需要更新为从 `homeassistant.core_config` 导入。 :::info 通常集成不需要使用 core `Config` 类。但有些自定义集成的类型注解有误,将传入集成 `async_setup` 的 `config` 对象标注为了 `Config` 实例: ```py from homeassistant.core import Config async def async_setup(hass: HomeAssistant, config: Config) -> bool: """Set up the integration.""" ``` 正确的类型注解应该是这样: ```py from homeassistant.helpers.typing import ConfigType async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up the integration.""" ``` ::: ### 向后兼容性 直到 Home Assistant Core 2025.11,仍可从 `homeassistant.core` 导入,但这样做会记录一条警告,提示用户在该自定义集成的 bug tracker 上提 issue。 --- url: /developers/blog/2024-10-31-update-entity-changes.md --- ### 变更摘要 `update` entity 已做出以下调整: * `in_progress` 属性及其对应的 state attribute 现在应仅为一个 `bool`,用于指示是否有更新正在进行,或者在未知时为 `None`。 * 新增了一个属性和对应的 state attribute `update_percentage`,它可以返回一个表示 0 到 100% 进度的 `int` 或 `float`,或者为 None。 * 新增了一个属性和对应的 state attribute `display_precision`,用于在 `update_percentage` 为 `float` 时控制前端显示的十进制位数。 ### 向后兼容性 直到 Home Assistant Core 2025.12,`in_progress` 属性中的数值会自动复制到 `update_percentage` state attribute。 ### 文档与 core 实现 详情请参阅 [update entity 开发者文档](https://developers.home-assistant.io/docs/core/entity/update)。 PR 列表: * 新增 [`update_percentage` state attribute](https://github.com/home-assistant/core/pull/128877) 的 PR * 新增 [`update_percentage` 属性](https://github.com/home-assistant/core/pull/128908) 的 PR * 新增 [`display_precision` state attribute 和属性](https://github.com/home-assistant/core/pull/128930) 的 PR * 一个[更新集成 update entity](https://github.com/home-assistant/core/pull/129380) 的示例 --- url: /developers/blog/2024-11-04-reauth-reconfigure-entry-id.md --- 在没有关联到 config entry 的情况下启动 reauth 或 reconfigure flow 已被 deprecated,并将在 2025.12 开始失效。 自定义集成应更新为使用 `entry.async_start_reauth(hass)` 辅助函数来触发 reauth flow。 ```python async def async_press(self) -> None: """Handle the button press.""" try: await self.device.press_button() except DevicePasswordProtected as ex: self.entry.async_start_reauth(self.hass) ``` 旧的错误代码: ```python async def async_press(self) -> None: """Handle the button press.""" try: await self.device.press_button() except DevicePasswordProtected as ex: # old incorrect code: self.hass.async_create_task( hass.config_entries.flow.async_init(DOMAIN, context={"source": SOURCE_REAUTH} ) ) ``` 自定义集成还可以在初始化阶段,或在 data update coordinator 的 update 方法内抛出 `ConfigEntryAuthFailed` 异常。 ```python async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up integration from a config entry.""" username = entry.data[CONF_USERNAME] password = entry.data[CONF_PASSWORD] if not _credentials_valid(username, password): raise ConfigEntryAuthFailed() ``` 启动 reconfigure flow 只能由前端完成,自定义集成不应需要对这些 flow 做任何更改。 更多详情请参阅 [reconfigure](/developers/core/integration/config_flow.md#reconfigure) 和 [reauthentication](/developers/core/integration/config_flow.md#reauthentication) 文档。 --- url: /developers/blog/2024-11-06-custom-card-sections-support.md --- 从 Home Assistant `2024.11` 起,"sections" view 已成为构建 dashboard 时的默认视图。该视图类型的新特性之一是调整卡片尺寸。 虽然调整尺寸功能默认支持所有卡片,但自定义卡片可以实现一个新方法,以提供最佳的默认尺寸以及最小和最大尺寸,确保卡片在任何情况下看起来都良好。 sections 使用 12 列网格。在下面的示例中,卡片默认占用 6 列 2 行,最小尺寸为 2 列 x 2 行。 ```js public getGridOptions() { return { rows: 2, columns: 6, min_rows: 2, min_columns: 3, }; } ``` 更多详情请参阅 [custom card sizing](/developers/frontend/custom-ui/custom-card.md#sizing-in-sections-view) 文档。 --- url: /developers/blog/2024-11-12-options-flow.md --- ### 变更摘要 `OptionsFlow` 中新增了几个 helper 属性: * `self._config_entry_id` 提供 config entry 的 ID * `self.config_entry` 返回 config entry ### 向后兼容性 直到 Home Assistant Core 2025.12,仍可以手动设置 `self.config_entry`,但这样做会记录一条警告,提示用户在该自定义集成的 bug tracker 上提 issue。 新代码: ```python @staticmethod @callback def async_get_options_flow( config_entry: ConfigEntry, ) -> OptionsFlowHandler: """Create the options flow.""" return OptionsFlowHandler() class OptionsFlowHandler(OptionsFlow): """Options flow handler.""" def __init__(self) -> None: """Initialize options flow.""" self._conf_app_id: str | None = None ``` 旧的带 `OptionsFlow` 属性的代码: ```python @staticmethod @callback def async_get_options_flow( config_entry: ConfigEntry, ) -> OptionsFlowHandler: """Create the options flow.""" return OptionsFlowHandler(config_entry) class OptionsFlowHandler(OptionsFlow): """Options flow handler.""" def __init__(self, config_entry: ConfigEntry) -> None: """Initialize options flow.""" self.config_entry = config_entry self._conf_app_id: str | None = None ``` ### OptionsFlowWithConfigEntry 的特殊处理 `OptionsFlowWithConfigEntry` 类的主要目的是提供 `self.config_entry` 属性,而该属性现在已由父类提供。 目前尚无移除 `OptionsFlowWithConfigEntry` 类的计划,但保留它仅为了向后兼容,新代码应避免使用。 希望移除对 `OptionsFlowWithConfigEntry` 引用的自定义集成需要考虑它们是如何引用 `self.options` 的: * 如果没有引用 `self.options`,则迁移到 `OptionsFlow` 很简单(见 [PR #129651](https://github.com/home-assistant/core/pull/129651)) * 如果你只是读取 options 值,则建议将读取改为 `self.config_entry.options`(见 [PR #129895](https://github.com/home-assistant/core/pull/129895)) * 如果在单个 step 内更新/修改 options 值,则可能需要先复制 options(`options = deepcopy(dict(self.config_entry.options))`,见 [PR #129928](https://github.com/home-assistant/core/pull/129928)) * 如果在多个 step 中更新/修改 options 值,则可能需要在类初始化时复制 options(`self.options = deepcopy(dict(config_entry.options))`,见 [PR #129890](https://github.com/home-assistant/core/pull/129890)) 更多详情请参阅 [options flow](/developers/core/integration/options_flow.md) 文档。 --- url: /developers/blog/2024-11-20-integration-quality-scale.md --- 自 2020 年最初的质量等级推出以来,Home Assistant 发生了相当多的变化。 无论是集成的开发方式还是它们能提供的功能都有变化。 然而,质量等级尚未更新以反映这些变化。 在过去的几个月里,我们一直与社区一起制定一套符合 Home Assistant 当前状态的新集成质量等级。 以下是变更概览: * 质量等级现在分为四个等级:Bronze、Silver、Gold 和 Platinum。新增的 Bronze 等级是今后新 core 集成的最低要求。这虽然暂时略微降低了新集成的门槛,但它可以明确地说明在这个时代对 core 集成有何期望。 * 新增了一个非分级的 legacy 等级,用于那些尚未可通过 UI 配置的集成。该等级会向用户表明,与可通过 UI 配置的集成相比,该集成可能无法满足其预期。 * 为了让该等级体系能够随 Home Assistant 一起发展,并避免未来再次大规模返工,我们为该等级体系设计了一份规则手册,以明确在添加新规则时需要做什么。 * 为了表明项目致力于保持该等级体系的更新,我们创建了一份架构决策记录 (ADR),描述了保持等级体系更新的目标和流程。 * 开发者文档现在有了[一个全新的章节](/developers/core/integration-quality-scale.md)专门介绍集成质量等级。它包含了每条规则及其背后的理由,并提供了示例以展示如何实现。此外,还有一份[检查清单](/developers/core/integration-quality-scale/checklist.md)可用于更改集成的等级。 * 文档现在也在集成的质量中发挥作用,因为集成的用户体验不仅仅取决于代码。 * 为了追踪集成的进度,我们在集成文件夹中新增了[一个 `quality_scale.yaml` 文件](https://github.com/home-assistant/core/blob/dev/homeassistant/components/airgradient/quality_scale.yaml)。该文件将包含集成所遵守的所有规则列表,以及可能的豁免说明及其原因。 在这一切就绪后,你可能会想知道接下来的步骤是什么。 由于这是对等级体系的一次重大返工,我们决定取消当前集成的等级。 这意味着这些集成需要提交 PR,以将其等级恢复到它们认为应有的水平。 我也希望激励社区帮忙尽可能多地将集成提升到 Bronze(或更高)等级。 我还要感谢社区在质量等级方面的贡献以及他们维护集成所付出的努力。 没有社区,Home Assistant 就不可能像今天这样出色 ❤️。 --- url: /developers/blog/2024-11-21-unit-of-measurement-translations.md --- Home Assistant 2024.12 将支持对自定义 measurement 单位的翻译。在此之前,这些单位都是在各自的集成中硬编码的。 与 entity 名称一样,集成只需在 entity 定义上设置 `translation_key`,并在 `strings.json` 文件中提供单位名称(使用新的 `unit_of_measurement` key): ```json { "entity": { "sensor": { "subscribers_count": { "unit_of_measurement": "subscribers" }, } } } ``` 详情请参阅我们的 [backend localization 文档](/developers/internationalization/core.md#unit-of-measurement-of-entities)。 --- url: /developers/blog/2024-11-26-camera-deprecations.md --- 在 Home Assistant `2024.11` 中,我们为大多数摄像头添加了 WebRTC。为了支持它,我们需要重构并改进 camera entity。 今天我们要宣布,在即将到来的 Home Assistant `2024.12` 版本中,以下方法已被 deprecated,并将在 Home Assistant `2025.6` 版本中移除: * `frontend_stream_type` 属性将被移除。从 `2024.11` 起,Home Assistant 将通过检查 camera entity 是否实现了原生 WebRTC 方法来识别前端 stream 类型([#130932](https://github.com/home-assistant/core/pull/130932))。卡片开发者可以使用新的 websocket 命令 `camera/capabilities` 来获取前端 stream 类型。 * `async_handle_web_rtc_offer` 方法将被移除。请使用 `async_handle_async_webrtc_offer` 和 async WebRTC signaling 方式([#131285](https://github.com/home-assistant/core/pull/131285))。 * `async_register_rtsp_to_web_rtc_provider` 方法已被 deprecated。请使用 `async_register_webrtc_provider`,它提供了更大的灵活性并支持 async WebRTC signaling 方式([#131462](https://github.com/home-assistant/core/pull/131462))。 更多关于替代方案的详情请参阅 [camera entity 文档](/developers/core/entity/camera.md)。 --- url: /developers/blog/2024-11-28-dt-util-utc-to-timestamp-deprecation.md --- Utility 函数 `homeassistant.util.dt.utc_to_timestamp` 已被 deprecated,并将在 Home Assistant Core 2026.1 中移除。调用该函数的自定义集成应改为调用 stdlib 方法 `datetime.datetime.timestamp()`。 弃用的原因是 stdlib 方法与 utility 函数速度一样快。 更多详情请参阅 [core PR](https://github.com/home-assistant/core/pull/131787)。 --- url: /developers/blog/2024-12-03-climate-horizontal-swing.md --- 自 Home Assistant Core 2024.12 起,我们在 `ClimateEntity` 中实现了一个独立的属性和方法,用于控制水平 swing。 支持完全独立的垂直和水平 swing 控制和 state 的集成,现在可以使用之前的 `swing_mode` 仅用于垂直 swing,并使用新的 `swing_horizontal_mode` 来提供水平 swing 的 state 和控制。 不支持独立控制的集成仍应继续使用当前的 `swing_mode` 同时处理垂直和水平支持。 ### 示例 以下是在你的 climate entity 中实现 `swing` 和 `swing_horizontal` 的示例要求。 ```python class MyClimateEntity(ClimateEntity): """Implementation of my climate entity.""" @property def supported_features(self) -> ClimateEntityFeature: """Return the list of supported features.""" return ClimateEntityFeature.SWING_MODE | ClimateEntityFeature.SWING_HORIZONTAL_MODE @property def swing_mode(self) -> str | None: """Return the swing setting. Requires ClimateEntityFeature.SWING_MODE. """ return self._attr_swing_mode @property def swing_modes(self) -> list[str] | None: """Return the list of available swing modes. Requires ClimateEntityFeature.SWING_MODE. """ return self._attr_swing_modes @property def swing_horizontal_mode(self) -> str | None: """Return the swing setting. Requires ClimateEntityFeature.SWING_HORIZONTAL_MODE. """ return self._attr_swing_horizontal_mode @property def swing_horizontal_modes(self) -> list[str] | None: """Return the list of available swing modes. Requires ClimateEntityFeature.SWING_HORIZONTAL_MODE. """ return self._attr_swing_horizontal_modes async def async_set_swing_mode(self, swing_mode: str) -> None: """Set new target swing operation.""" await self.api.set_swing_mode(swing_mode) async def async_set_swing_horizontal_mode(self, swing_horizontal_mode: str) -> None: """Set new target horizontal swing operation.""" await self.api.set_swing_horizontal_mode(swing_horizontal_mode) ``` 更多详情请参阅 [climate 文档](/developers/core/entity/climate.md#swing-modes)。 --- url: /developers/blog/2024-12-08-new-vacuum-state-property.md --- 自 Home Assistant Core 2025.1 起,`StateVacuumEntity` 中用于返回 state 的常量已被 deprecated,并由 `VacuumActivity` enum 取代。 此外,随着这一变更,集成应设置 `activity` 属性,而不是直接设置 `state` 属性。 设有为期一年的 deprecation 期,这些常量将从 2026.1 起停止工作,以确保所有自定义集成作者都有时间进行调整。 ### 示例 ```python from homeassistant.components.vacuum import VacuumActivity class MyVacuumCleaner(StateVacuumEntity): """My vacuum cleaner.""" @property def activity(self) -> VacuumActivity | None: """Return the state of the vacuum.""" if self.device.is_cleaning(): return VacuumActivity.CLEANING return VacuumActivity.DOCKED ``` 更多详情请参阅 [vacuum 文档](/developers/core/entity/vacuum.md#states)。 --- url: /developers/blog/2024-12-13-water-heater-entity-description.md --- 在 Water Heater 集成中发现了一个 entity description 的命名错误,我们现在在 2025.1 版本中将 `WaterHeaterEntityEntityDescription` 重命名为 `WaterHeaterEntityDescription`。 旧的 `WaterHeaterEntityEntityDescription` 已被 deprecated,并计划在 2026.1 中移除,建议开发者改用新的 `WaterHeaterEntityDescription`。 更多详情请参阅 core PR: [#132888](https://github.com/home-assistant/core/pull/132888)。 --- url: /developers/blog/2024-12-14-kelvin-preferred-color-temperature-unit.md --- ### 变更摘要 2022 年 10 月,Home Assistant 将首选 color temperature 单位从 mired 迁移到了 kelvin。 现在时候到了,我们需要为相应的 attributes、constants 和 properties 添加 deprecation warnings: * 弃用 state 和 capability attributes:`ATTR_COLOR_TEMP`、`ATTR_MIN_MIREDS` 和 `ATTR_MAX_MIREDS` * 弃用 `light.turn_on` service call 中的常量 `ATTR_KELVIN` 和 `ATTR_COLOR_TEMP` * 弃用 properties:`LightEntity.color_temp`、`LightEntity.min_mireds` 和 `LightEntity.max_mireds` * 弃用相应的 attributes:`LightEntity._attr_color_temp`、`LightEntity._attr_min_mired` 和 `LightEntity._attr_max_mired` ### 示例 #### 自定义最小/最大 color temperature ```python class MyLight(LightEntity): """Representation of a light.""" # 旧 # _attr_min_mireds = 200 # 5000K # _attr_max_mireds = 400 # 2500K # 新 _attr_min_color_temp_kelvin = 2500 # 400 mireds _attr_max_color_temp_kelvin = 5000 # 200 mireds ``` #### 默认最小/最大 color temperature ```python from homeassistant.components.light import DEFAULT_MAX_KELVIN, DEFAULT_MIN_KELVIN class MyLight(LightEntity): """Representation of a light.""" # 旧无需设置 _attr_min_mireds / _attr_max_mireds # 新需要显式设置默认值 _attr_min_color_temp_kelvin = DEFAULT_MIN_KELVIN _attr_max_color_temp_kelvin = DEFAULT_MAX_KELVIN ``` #### 动态最小/最大 color temperature ```python from homeassistant.util import color as color_util class MyLight(LightEntity): """Representation of a light.""" # 旧 # def min_mireds(self) -> int: # """Return the coldest color_temp that this light supports.""" # return device.coldest_temperature # # def max_mireds(self) -> int: # """Return the warmest color_temp that this light supports.""" # return device.warmest_temperature # 新 def min_color_temp_kelvin(self) -> int: """Return the warmest color_temp that this light supports.""" return color_util.color_temperature_mired_to_kelvin(device.warmest_temperature) def max_color_temp_kelvin(self) -> int: """Return the coldest color_temp that this light supports.""" return color_util.color_temperature_mired_to_kelvin(device.coldest_temperature) ``` #### Service 调用 ```python from homeassistant.components.light import ATTR_COLOR_TEMP_KELVIN from homeassistant.util import color as color_util class MyLight(LightEntity): """Representation of a light.""" def turn_on(self, **kwargs: Any) -> None: """Turn on the light.""" # 旧 # if ATTR_COLOR_TEMP in kwargs: # color_temp_mired = kwargs[ATTR_COLOR_TEMP] # color_temp_kelvin = color_util.color_temperature_mired_to_kelvin(color_temp_mired) # 旧 # if ATTR_KELVIN in kwargs: # color_temp_kelvin = kwargs[ATTR_KELVIN] # color_temp_mired = color_util.color_temperature_kelvin_to_mired(color_temp_kelvin) # 新 if ATTR_COLOR_TEMP_KELVIN in kwargs: color_temp_kelvin = kwargs[ATTR_COLOR_TEMP_KELVIN] color_temp_mired = color_util.color_temperature_kelvin_to_mired(color_temp_kelvin) ``` ### 背景信息 * [关于 Kelvin 温度的社区讨论](https://community.home-assistant.io/t/wth-is-light-temperature-not-in-kelvin/467449/6) * [Core PR #79591: 迁移到 Kelvin](https://github.com/home-assistant/core/pull/79591) * [架构讨论 #564](https://github.com/home-assistant/architecture/discussions/564) --- url: /developers/blog/2024-12-21-moving-to-pydantic-v2.md --- Pydantic 是 Python 中广泛使用的数据验证库。2023 年 6 月 30 日,Pydantic v2 发布,引入了与 Pydantic v1 不向后兼容的重大变更。 从 Home Assistant Core 2025.1 起,Pydantic v2 将取代 v1。如果你的自定义集成使用了 Pydantic,则必须更新以支持 Pydantic v2,才能在即将发布的版本中继续工作。 在过去一年中,我们的社区努力确保 Home Assistant Core 使用的库与 Pydantic v1 和 v2 都兼容。这种双重兼容性帮助我们尽可能顺畅地过渡到 Pydantic v2。 如需快速迁移,你可以使用 Pydantic v2 中内置的 Pydantic v1 shims。关于在 v1/v2 环境中使用这些 shims 的详细信息,请参阅 [Pydantic migration guide](https://docs.pydantic.dev/latest/migration/#using-pydantic-v1-features-in-a-v1v2-environment)。 --- url: /developers/blog/2024-12-26-area-squared-units.md --- ### 变更摘要 现在为 number 和 sensor entities 新增了一个 `AREA` device class,并支持基于 unit system 的自动单位转换。 同时新增了相应的 `UnitOfArea` unit enumerator 和 `AreaConverter` converter class,以支持新的 device class。 ### 向后兼容性 `AREA_SQUARE_METERS` 常量已被 deprecated,并将在 Home Assistant `2025.12` 中移除。 自定义集成应调整为使用 `UnitOfArea.SQUARE_METERS`。 更多详情请参阅 [Number 文档](/developers/core/entity/number.md#available-device-classes) 和 [Sensor 文档](/developers/core/entity/sensor.md#available-device-classes)。 --- url: /developers/blog/2025-01-15-service-info.md --- ### 变更摘要 为了减少对 optional 集成的依赖(这些集成名称本质上是作为 helpers 使用的),以下 ServiceInfo models 已被迁移: * `DhcpServiceInfo` 从 `homeassistant.components.dhcp` 迁移到 `homeassistant.helpers.service_info.dhcp` * `SsdpServiceInfo` 从 `homeassistant.components.ssdp` 迁移到 `homeassistant.helpers.service_info.ssdp` * `UsbServiceInfo` 从 `homeassistant.components.usb` 迁移到 `homeassistant.helpers.service_info.usb` * `ZeroconfServiceInfo` 从 `homeassistant.components.zeroconf` 迁移到 `homeassistant.helpers.service_info.zeroconf` 要更新你的集成: 1. 按下述示例替换 import 语句 2. 使用新的 imports 测试你的集成 旧的 import 位置已被 deprecated,并将在 Home Assistant 2026.2 中移除。 ### 示例 ```python # 旧 # from homeassistant.components.dhcp import DhcpServiceInfo # from homeassistant.components.ssdp import SsdpServiceInfo # from homeassistant.components.usb import UsbServiceInfo # from homeassistant.components.zeroconf import ZeroconfServiceInfo # 新 from homeassistant.helpers.service_info.dhcp import DhcpServiceInfo from homeassistant.helpers.service_info.ssdp import SsdpServiceInfo from homeassistant.helpers.service_info.usb import UsbServiceInfo from homeassistant.helpers.service_info.zeroconf import ZeroconfServiceInfo class MyConfigFlow(ConfigFlow, domain=DOMAIN): """Handle a config flow.""" async def async_step_dhcp(self, discovery_info: DhcpServiceInfo) -> ConfigFlowResult: """Handle dhcp discovery.""" ... async def async_step_ssdp(self, discovery_info: SsdpServiceInfo) -> ConfigFlowResult: """Handle ssdp discovery.""" ... async def async_step_usb(self, discovery_info: UsbServiceInfo) -> ConfigFlowResult: """Handle usb discovery.""" ... async def async_step_zeroconf(self, discovery_info: ZeroconfServiceInfo) -> ConfigFlowResult: """Handle zeroconf discovery.""" ... ``` --- url: /developers/blog/2025-01-31-energy-distance-units.md --- ### 变更摘要 现在为 number 和 sensor entities 新增了一个 `ENERGY_DISTANCE` device class,用于表示每单位距离消耗的能量,并支持基于 unit system 的自动单位转换。 例如,这个新的 device class 可用于显示电动汽车消耗的电能量的 entities。同时新增了相应的 `UnitOfEnergyDistance` unit enumerator 和 `EnergyDistanceConverter` converter class,以支持新的 device class。 以下单位可用: * kWh/100km * mi/kWh * km/kWh 更多详情请参阅 [Number 文档](/developers/core/entity/number.md#available-device-classes) 和 [Sensor 文档](/developers/core/entity/sensor.md#available-device-classes) ### 倒数单位 实现 `EnergyDistanceConverter` 也为 `BaseUnitConverter` 带来了倒数单位的支持。这简化了添加互为倒数的新单位(例如 kWh/100km 和 km/kWh)的工作。 --- url: /developers/blog/2025-02-16-config-subentries.md --- Config entries 现在新增了一种称为“config subentry”的数据类型。[Config subentries](/developers/config_entries_index.md#config-subentries) 由 config entry 拥有,并在 `async_setup_entry` 期间设置。Config subentries 由 [config subentry flows](/developers/core/integration/config_flow.md#subentry-flows) 创建,并通过 config subentry reconfigure flows 更新。这与我们创建/编辑 config entries 的方式类似。 这使得集成作者可以更方便地允许用户添加、修改和移除共享某些公共资源(例如 cloud 账号或 MQTT broker)的配置片段。 [架构讨论](https://github.com/home-assistant/architecture/discussions/1070) 提供了更多背景信息。 --- url: /developers/blog/2025-02-17-backup-agents.md --- 在 2025 年 1 月的版本中,我们为备份引入了一项新功能,称为 backup agents。 此前,backup platform 仅用于在创建备份之前暂停或准备集成操作,以及在备份之后执行后续操作。随着 backup agents 的引入,backup platform 现在允许集成添加一个或多个 backup agents,这些 agents 可以将备份上传到某些本地或远程位置。 第一个实现 backup agent 的集成是 Home Assistant Cloud 集成。在 2025 年 2 月的版本中,又有三个集成实现了 backup agents:Google Drive、OneDrive 和 Synology DSM。如果你是一名集成作者,并希望为你喜欢的备份位置添加支持,你可以在[开发者文档](/developers/core/platform/backup.md)中了解更多关于如何实现 backup agents 的信息。 --- url: /developers/blog/2025-02-19-new-config-entry-states.md --- 在卸载和移除 entries 时的 config entry state 转换已被修改: * 新增了一个状态 `ConfigEntryState.UNLOAD_IN_PROGRESS`,在调用集成的 `async_unload_entry` 之前设置
原因: * 使编写在最后一条 config entry 卸载之后应运行的清理代码变得更简单 * 改善与 config entries 的 reload 和 unload 相关的问题的调试 * 当集成的 `async_unload_entry` 返回 False 时,config entry state 将被设置为 `ConfigEntryState.FAILED_UNLOAD`
原因: * 如果 `async_unload_entry` 返回 `False`,我们不能假设集成仍处于已加载状态,很可能它已经部分卸载了自身,尤其是考虑到这是我们推荐的模式: ```py async def async_unload_entry(hass: HomeAssistant, entry: MyConfigEntry) -> bool: """Unload a config entry.""" # async_unload_platforms 在至少有一个 platform 未卸载时返回 False if (unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS)): entry.runtime_data.listener() # 完成与 platforms 无关的清理 return unload_ok ``` * 在调用集成的 `async_remove_entry` 之前,config entry 会从 `hass.config_entries` 中移除
原因: * 使编写在最后一条 config entry 移除之后应运行的清理代码变得更简单 自定义集成作者需要检查并在必要时更新他们的集成的 `async_unload_entry` 和 `async_remove_entry`。 最常见的需要更新的模式如下: ```python async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" loaded_entries = [ entry for entry in hass.config_entries.async_entries(DOMAIN) if entry.state is ConfigEntryState.LOADED ] if len(loaded_entries) == 1: # 最后一条 config entry 正在卸载,释放共享资源、注销 services 等。 ... ``` 如果自定义集成的最低 Home Assistant 版本设置为 2025.3.0,现在可以简化为: ```python async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" if not hass.config_entries.async_loaded_entries(DOMAIN): # 最后一条 config entry 正在卸载,释放共享资源、注销 services 等。 ... ``` 如果自定义集成需要与早期版本的 Home Assistant Core 保持向后兼容: ```python async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" other_loaded_entries = [ _entry for _entry in hass.config_entries.async_loaded_entries(DOMAIN) if _entry.entry_id != entry.entry_id ] if not other_loaded_entries: # 最后一条 config entry 正在卸载,释放共享资源、注销 services 等。 ... ``` 更多背景信息请参阅 [config entry 文档](/developers/config_entries_index.md) 以及 [home assistant core PR #138522](https://github.com/home-assistant/core/pull/138522)。 --- url: /developers/blog/2025-03-01-config-flow-unique-id.md --- ### 变更摘要 创建带有已在注册表中存在的 unique ID 的 config entry 已被弃用,现在将会记录警告。 ### 详情 当 config flow 创建一个具有冲突 unique ID 的 entry 时,旧 entry 当前会被自动移除并替换为新的 config entry。 这可能导致意外的行为,集成应调整为中止 flow。 对于手动 flow,集成应实现 options、reauth、reconfigure,以允许用户更改设置。 对于非用户可见的 flow,集成应在中止前可选择更新现有 entry。 更多详情请参阅 [config flow](/developers/core/integration/config_flow.md#unique-id-requirements) 文档。 --- url: /developers/blog/2025-03-04-backup-agent-api-changes.md --- `BackupAgent` API 已进行调整,以下方法在找不到备份时应抛出 `BackupNotFound`: * `BackupAgent.async_delete_backup` * `BackupAgent.async_download_backup` * `BackupAgent.async_get_backup` 请参阅 [backup agent 文档](/developers/core/platform/backup.md#backup-agents) 和 [home assistant core PR #139754](https://github.com/home-assistant/core/pull/139754) 以获取更多背景信息。 --- url: /developers/blog/2025-03-14-media-player-toggle-adjusted.md --- media player 基类中的 toggle action service 实现已进行调整。 media player 现在会在处于 `off` 或 `standby` 状态时开启;在其他所有状态下,将会被关闭。 在此变更之前,如果 media player 处于 `idle` 状态,也会被关闭。这与 `idle` 状态的含义不符,因为它被视为[设备已开启的状态](/developers/core/entity/media-player.md#states)。 自定义集成如果覆盖了 `async_toggle`,可能需要更新其实现。 此变更引入于 [home assistant core PR #78192](https://github.com/home-assistant/core/pull/78192)。 --- url: /developers/blog/2025-03-24-config-subentry-flow-changes.md --- `ConfigSubentryFlow._reconfigure_entry_id` 已重命名为 `ConfigSubentryFlow._entry_id`,`ConfigSubentryFlow._get_reconfigure_entry` 已重命名为 `ConfigSubentryFlow._get_entry`。 进行此项变更的原因是,sub entry user flow 和 subentry reconfigure flow 都需要访问父 config entry,例如获取 options、data 等。 调用了上述任一重命名方法的自定义集成需要更新其实现。 此变更引入于 [home assistant core PR #141017](https://github.com/home-assistant/core/pull/141017)。 --- url: /developers/blog/2025-03-25-frozen-unit-system.md --- `UnitSystem` 类已更改为冻结的 data class,所有派生自它的实例现在也是冻结的。 以下派生自 `UnitSystem` 类的 unit system 现在已冻结: * `METRIC_SYSTEM` * `US_CUSTOMARY_SYSTEM` 进行此项变更的原因是,Unit system 是不应被修改的常量。修改这些常量的集成可能会破坏 unit 转换,并导致 Home Assistant 其他组件产生不期望的输出。 使用冻结的 data class 时,尝试修改 UnitSystem 常量将会失败: ```python dataclasses.FrozenInstanceError: cannot assign to field 'temperature_unit' ``` 此项变更引入于 [home assistant core PR #140954](https://github.com/home-assistant/core/pull/140954)。 --- url: /developers/blog/2025-04-17-search-media-play.md --- media player 现在可以允许用户搜索 media,只需添加 `MediaEntityFeature.SEARCH_MEDIA` 并实现 `async_search_media`。用户可以通过搜索查询和一组 `MediaClasses` 来过滤搜索结果。更多信息请参阅[更新的文档](/developers/core/entity/media-player.md#search-media)。 --- url: /developers/blog/2025-04-24-device-tracker-accuracy.md --- `device_tracker` entity 组件的 `TrackerEntity` 类中 `location_accuracy` 属性(简写为 `_attr_location_accuracy`)的类型已从 `int` 更改为 `float`。 当源值为 `float` 时,不再需要类型转换。 ### 示例 ```python class ExampleTrackerEntity(TrackerEntity): """Test tracker entity.""" _attr_location_accuracy: float = 2.5 @cached_property def location_accuracy(self) -> float: """Return the location accuracy of the device. Value in meters. """ return self._attr_location_accuracy ``` --- url: /developers/blog/2025-05-22-range-based-icons.md --- 图标翻译现在支持基于数值范围定义图标。这意味着集成作者可以定义根据数值变化的图标,而无需在代码中实现自定义逻辑。 以前,图标翻译仅支持基于 state 的图标,即特定的 state 映射到特定的图标。虽然这对"on"/"off"等离散状态效果很好,但处理电池电量或信号强度等数值时,需要自定义代码。 基于范围的图标定义在 `icons.json` 文件中: ```json { "entity": { "sensor": { "battery_level": { "default": "mdi:battery", "range": { "0": "mdi:battery-outline", "10": "mdi:battery-10", "20": "mdi:battery-20", "30": "mdi:battery-30", "40": "mdi:battery-40", "50": "mdi:battery-50", "60": "mdi:battery-60", "70": "mdi:battery-70", "80": "mdi:battery-80", "90": "mdi:battery-90", "100": "mdi:battery" } } } } } ``` 系统会选择与小于或等于 entity 当前值的高范围值相关联的图标。例如: * 值为 15 时显示 `mdi:battery-10` 图标 * 值为 45 时显示 `mdi:battery-40` 图标 * 值为 100 时显示 `mdi:battery` 图标 关于实现细节,请参阅[图标翻译文档](/developers/core/integration-quality-scale/rules/icon-translations.md#range-based-icons)。 --- url: /developers/blog/2025-05-26-sensor-default-display-precision.md --- 如果数值型 sensor 没有由集成设置建议的显示精度,Home Assistant 现在将根据 sensor 的 device class 使用默认显示精度。 新的 device class 应添加到 `homeassistant/components/sensor/const.py` 中的 `UNITS_PRECISION`,并附带正确的 unit 和期望的默认显示精度。有关如何选择正确的 unit 和精度,请参阅该常量的 docstring。 以前在发生 unit 转换时对 sensor state 进行的舍入现在已被移除,sensor state 包含完整的原始值。 仍然建议集成在其 sensor 上设置 `suggested_display_precision`。此项变更是一个回退机制,以确保所有数值型 sensor 具有一致的体验。 更多详情请参阅实现 [pull request](https://github.com/home-assistant/core/pull/145013) 和 [Sensor entity 文档](/developers/core/entity/sensor.md)。 --- url: /developers/blog/2025-07-02-vacuum-battery-properties-deprecated.md --- 自 Home Assistant Core 2025.8 起,`StateVacuumEntity` 中的两个电池属性 `battery_level` 和 `battery_icon` 已被弃用。 `battery_level` 和 `battery_icon` 属性应替换为一个独立的 sensor,使用该 sensor 的 `battery` device class,如果不需要 battery sensor device class 的默认图标,还可选择自定义图标。如果有需要,也可考虑提供一个 `charging` device class 的 binary sensor,以指示是否正在充电。 弃用期为一年,从 2026.8 起这两个电池属性将停止工作,以确保所有自定义集成作者有足够时间进行调整。 更多详情请参阅[架构决策](https://github.com/home-assistant/architecture/discussions/938)。 --- url: /developers/blog/2025-07-14-home-assistant-os-16-open-file-limit.md --- 随着 Home Assistant OS 16 的发布,Docker 容器(以及由此扩展的所有 add-on 及其内部进程)的打开文件描述符默认限制已发生变化。Home Assistant OS 现在使用 Systemd 提供的默认值:软限制为 **1024**,硬限制为 **524288** 个打开文件。 这与之前的 OS 版本不同,之前的版本将限制设置为"无限"(实际上超过 10 亿的值)——这也是上游引入的变更——[自 Home Assistant OS 10 起](/developers/blog/2023-04-13-new_limits_for_add_ons.md)。新限制符合现代 Linux 系统上的常见做法,并遵循其他 Linux 发行版逐渐采用的变更。 有关这些限制和最佳实践的更多详情,请参阅 Lennart Poettering 对 [File Descriptor Limits](https://0pointer.net/blog/file-descriptor-limits.html) 的解释。简而言之,需要超过默认软限制 1024 个文件描述符的应用程序,应在启动时显式提高自身的限制,最高不超过系统设定的硬限制(在我们的情况下为 524288)。这种方法确保每个应用程序仅请求其所需的资源,并避免可能导致意外资源耗尽的全局高限制。 ### 这对 add-on 开发者意味着什么? * 如果您的 add-on 应用程序需要打开超过 1024 个文件(socket、pipe 等),您应自行调整限制,例如使用 `ulimit -Sn `,只要 `` 不超过硬限制(可通过 `ulimit -Hn` 检查)。 * 大多数 add-on 可能不会受此变更影响,但部分 add-on——例如处理大量网络连接或访问大量文件(如数据库或文件共享应用程序)的 add-on——可能需要调整其启动流程。 ### 如果限制太低会发生什么? 如果 add-on 或其应用程序需要的文件描述符超过默认软限制(1024),且未自行提高限制,则在达到限制后可能无法打开更多文件、socket 或网络连接。这通常会导致"Too many open files"或"No file descriptors available"(`EMFILE`)等错误、网络连接失败或服务异常。 如有任何问题或遇到故障,请参阅[此 GitHub discussion](https://github.com/home-assistant/operating-system/discussions/4166),其中还包含更多细节和背景信息。 --- url: /developers/blog/2025-07-16-media-player-standby-state-deprecated.md --- 根据 [home-assistant/architecture#799](https://github.com/home-assistant/architecture/discussions/799) 的决定,media player 的 state `MediaPlayerState.STANDBY` 已被弃用,并将在 Home Assistant Core 2026.8 中移除。 集成应改用 `MediaPlayerState.IDLE` 或 `MediaPlayerState.OFF`。 更多详情请参阅 [media player 开发文档](/developers/core/entity/media-player.md#states)。 --- url: /developers/blog/2025-07-18-updated-pattern-for-helpers-linking-to-devices.md --- helper 集成不应将其自己的 config entry 添加到源 entity 的 device 或用户选择的 device。相反,它们应仅将其 entity 链接到源 entity 的 device。 将 helper config entry 添加到其他集成的 device 已不再受支持,并将在 Home Assistant Core 2026.8 中停止工作。 ### 背景 架构提案 [home-assistant/architecture#1226](https://github.com/home-assistant/architecture/discussions/1226) 使 device 的连接和标识符在每个集成 domain 中唯一,而非全局唯一。这对大多数集成来说不是问题,但带 config flow 的 helper 集成是例外。 ### 建议的变更 #### 将 helper entity 直接链接到源集成的 device 在 helper entity 的构造函数中,将 `self.device_entry` 设置为源 device ```py class HelperEntity(Entity) def __init__(hass: HomeAssistant, source_entity_id: str, ...) -> None: self.device_entry = async_entity_id_to_device( hass, source_entity_id, ) ``` #### 不要直接将 helper config entry 添加到源 device 不要将 config entry 直接添加到源 device,这意味着以下模式不再允许 ```py device_registry.async_update_device( source_device.id, add_config_entry_id=helper_config_entry.entry_id, ) ``` #### 不要隐式地将 helper config entry 添加到源 device 不要设置 `self._attr_device_info`,也不要覆盖 `device_info` 以返回另一个集成 device 的 identifiers 和 connections,因为这会导致 helper config entry 被添加到源 device。相反,应在 helper entity 中设置 `self.device_entry`,以将 helper entity 链接到其他集成的 device,如上面的示例所示。 #### 清理 device registry 提供了一个 helper 函数 `homeassistant.helpers.helper_integration.async_remove_helper_config_entry_from_source_device` 来辅助清理。核心集成已被修改为在 config entry 迁移步骤中调用此 helper。 #### 处理已移除的 device 如何处理已移除的 device 由 helper 集成自行决定;大多数核心 helper 将 `self.device_entry` 设置为 `None`。请注意,如果传入的 `device_id` 不存在,`DeviceRegistry.async_get` 会返回 `None`。 #### 示例实现 derivative 核心集成之前将其 config entry 添加到源 entity 的 device,现已更新为仅将 helper entity 链接到源 entity 的 device,见核心 [PR #148674](https://github.com/home-assistant/core/pull/148674)。 template 核心集成之前将其 config entry 添加到用户选择的 device,现已更新为仅将 helper entity 链接到用户选择的 device,见核心 [PR #148756](https://github.com/home-assistant/core/pull/148756)。 --- url: /developers/blog/2025-07-31-result-removed-from-flowresult.md --- `homeassistant.data_entry_flow.FlowResult` typed dict 中的 result 属性已被移除,现在仅在需要时才存在,即 `homeassistant.auth.models.AuthFlowResult` 和 `homeassistant.config_entries.ConfigFlowResult`。 此项变更预计不会影响自定义集成的运行时行为,但自定义集成作者可能需要更新测试以及任何派生自 `homeassistant.data_entry_flow.FlowResult` 且使用了 `result` 属性的类,以消除类型检查器的警告。 --- url: /developers/blog/2025-08-01-suggested-area-removed-from-deviceentry.md --- `DeviceEntry.suggested_area` 属性已弃用,并将在 HA Core 2026.9 中移除。此外,当 HA Core 2026.9 发布时,`suggested_area` 将不再出现在 `EVENT_DEVICE_REGISTRY_UPDATED` 事件中。 注意: 在 `DeviceInfo` 中设置 `suggested_area`,以及将 `suggested_area` 传递给 `DeviceRegistry.async_get_or_create` 仍然受支持,并会影响创建设备的 area,尽管未来可能会改变。 在自定义集成中,请使用 `DeviceEntry.area_id` 来确定设备的 area。不要访问 `DeviceEntry.suggested_area`。 在弃用期间,访问 `DeviceEntry.suggested_area` 将会记录警告。 更多详情请参阅 [DeviceEntry 文档](/developers/device_registry_index.md#device-properties) 以及弃用了 `DeviceEntry.suggested_area` 的核心 [PR 149730](https://github.com/home-assistant/core/pull/149730)。 --- url: /developers/blog/2025-08-20-micro-sign-encoding.md --- ## 统一使用一种编码来表示测量单位中的 μ 单位前缀 μ 被用于 μV 和 μS 等测量单位常量。 然而 μ 有两种不同的 Unicode 编码: 1. [MICRO SIGN](https://www.compart.com/en/unicode/U+00B5) 2. [Greek Small Letter Mu](https://www.compart.com/en/unicode/U+03BC) Home Assistant 以前混用了这两种编码,这导致问题,因为两种编码之间的字符串比较会失败,从而导致测量单位验证失败。 我们选择了"Greek Small Letter Mu",因为"MICRO SIGN"编码是为了与旧的 8 位西欧字符集兼容而存在的,Unicode 联盟建议不要使用它。 通过 [#144853](https://github.com/home-assistant/core/pull/144853),我们通过一致地使用 Greek Small Letter Mu 版本来编码 μ,修复了 Home Assistant 核心中的这个问题。在 Python 字面量字符串中,此变体编码为 `"\u03bc"`。 开发者应检查其代码和库是否依赖有歧义的 MICRO SIGN(μ)`"\u00b5"`,并将代码迁移为使用 Greek Small Letter Mu `"\u03bc"` 以避免问题。 `sensor` 和 `number` entity 平台现在包含一个内置功能,可自动转换使用有歧义的 MICRO SIGN(μ)编码的 unit。 ## 在 Visual Studio Code 中查找实例 在 Visual Studio Code 中,在 **Search**(文件)面板中启用 **Match Case**,以仅查找所选编码。从上方复制确切的 μ 字符并粘贴到搜索框中。编辑器的页面搜索会匹配所有变体;请使用全局搜索。 ## 新的 linter 为了避免新代码或已更改代码中的问题,[#144853](https://github.com/home-assistant/core/pull/144853) 添加了一个 linter,会对使用非首选编码的 μ 的字面量赋值发出警告。 --- url: /developers/blog/2025-09-22-deprecate-hass-argument-service-helpers.md --- ### 变更摘要 向以下 service helpers 提供 `hass` 参数已被弃用: `verify_domain_control`、`extract_entity_ids`、`async_extract_entities`、`async_extract_entity_ids` 和 `async_extract_config_entry_ids`。 自版本 `2025.1` 起(通过核心 PR [#133062](https://github.com/home-assistant/core/pull/133062)), `HomeAssistant` 的引用可以作为 `ServiceCall` 对象的属性使用, 因此向上述 helper 传递 `hass` 对象变得多余。 要更新您的集成,只需移除 `hass` 参数。 对 `hass` 参数的支持将在 Home Assistant 2026.10 中移除。 ### 示例 #### ID 提取 helper ```python # 旧方式 # target_entry_ids = await async_extract_config_entry_ids(hass, service_call) # entity_ids = await async_extract_entity_ids(hass, service_call) # entities = await service.async_extract_entities(hass, platform_entities.values(), service_call) # 新方式 target_entry_ids = await async_extract_config_entry_ids(service_call) entity_ids = await async_extract_entity_ids(service_call) entities = await service.async_extract_entities(platform_entities.values(), service_call) ``` #### 装饰器 helper ```python # 旧方式 # @verify_domain_control(hass, DOMAIN) # async def do_action(call: ServiceCall) -> None: # ... # 新方式 @verify_domain_control(DOMAIN) async def do_action(call: ServiceCall) -> None: ... ``` --- url: /developers/blog/2025-09-25-entity-services-api-changes.md --- Platform entity service 应通过从集成的 `async_setup` 调用 helper [`service.async_register_platform_entity_service`](/developers/dev_101_services.md?_highlight=async_register_platform_entity_service#entity-service-actions) 来注册,而不是在 platform set up 期间调用 `platform.async_register_entity_service`。 现有集成应迁移到新 API,以确保加载 service 不依赖于 platform setup。 有关迁移示例,请参阅 [core PR 152172](https://github.com/home-assistant/core/pull/152172) 和 [core PR 152047](https://github.com/home-assistant/core/pull/152047)。 --- url: /developers/blog/2025-10-05-coordinator-retrigger.md --- 启用 debouncer 的 update coordinator 现在会在更新进行时接受更新请求。 该请求将被排队,等待当前更新完成后再执行。 考虑以下情况: ```python async def _update(): a = await get_a() # A: 用户或其他逻辑在此通过 async_schedule_update() 请求新更新 b = await get_b() return (a,b) ``` 在时间戳 `A` 请求更新的用户或代码,期望链接的 entity 都将获得从该时间点开始的新数据。然而,由于我们以前会忽略该请求,entity 获得的 `a` 值的数据来自被忽略的更新请求之前的时间点。 为避免这种情况,update coordinator 现在将在当前执行更新时收到请求的情况下,安排一次额外的更新。 此变更的一个副作用是,现在可以从 coordinator 的 update 函数内部安排更新。这在例如更新过程中连接丢失时非常有用,我们希望所有 entity 立即指示为不可用,同时希望尽快尝试重新连接,但将其放在下一个更新周期中进行。 --- url: /developers/blog/2025-10-14-device-filter-removed-from-target-selector.md --- target selector 不再支持 device filter 选项,它已从 [target selector 文档](https://www.home-assistant.io/docs/blueprint/selectors/#target-selector)中移除。 Hassfest 已更新为在 [带有 device filter 的 target 的 service 上失败](https://github.com/home-assistant/core/pull/152794)。 在 Home Assistant Core 2026.11 中,指定了 device filter 的 target selector 验证将会失败。 ### 背景 从 target 中提取 entity 的核心 helper 不支持 device filter。当用户选择 floor、area、label 或 category 时,filter 会被忽略。前端在选择 target 的 entity 时也会忽略 device filter。 对所有核心集成的审查发现,没有在 target selector 上正确使用 device filter 的情况。我们没有在 Core 和前端中实现对 device filter 的支持,而是直接从 target selector 中移除了 device filter。 ### 对自定义集成和 blueprint 的影响 请更新自定义集成和 blueprint,从 target selector 中移除 device filter。 如果您在 target selector 上使用 device filter 有合理的用例,请通过 Discord 联系我们。 --- url: /developers/blog/2025-10-16-recorder-statistics-api-changes.md --- 注入和修改 statistics 的 Python 和 WS API 已发生变更。 以下是对 WS API 所做的变更: * WS 命令 `recorder/update_statistics_metadata` 接受指向用于 unit 转换的 unit converter 的 `unit_class`。如果没有兼容的 unit converter,`unit_class` 应设置为 `null`。不指定 `unit_class` 已被弃用,并将在 Home Assistant Core 2026.11 中停止工作。 * WS 命令 `recorder/import_statistics` 中包含的 `metadata` 对象接受指向用于 unit 转换的 unit converter 的 `unit_class`。如果没有兼容的 unit converter,`unit_class` 应设置为 `null`。不指定 `unit_class` 已被弃用,并将在 Home Assistant Core 2026.11 中停止工作。 * WS 命令 `recorder/import_statistics` 中包含的 `metadata` 对象接受 `mean_type`,用于指定 mean 的类型(`0` 表示无 mean,`1` 表示算术 mean,`2` 表示圆周 mean)。`mean_type` 替换了 bool 标志 `has_mean`。不指定 `mean_type` 已被弃用,并将在 Home Assistant Core 2026.11 中停止工作。 * WS 命令 `recorder/list_statistic_ids` 和 `recorder/get_statistics_metadata` 的响应中的 items 包含 `mean_type` 和 `unit_class`。 * WS 命令 `recorder/list_statistic_ids` 和 `recorder/get_statistics_metadata` 的响应中 items 的 `has_mean` 已被弃用,并将在 Home Assistant Core 2026.11 中移除。 以下是对 Python API 所做的变更: * 函数 `async_update_statistics_metadata` 接受指向用于 unit 转换的 unit converter 的 `new_unit_class`。如果没有兼容的 unit converter,`new_unit_class` 应设置为 `None`。不指定 `new_unit_class` 已被弃用,并将在 Home Assistant Core 2025.11 中停止工作。 * 传递给函数 `async_import_statistics` 和 `async_add_external_statistics` 的 metadata 对象接受指向用于 unit 转换的 unit converter 的 `unit_class`。如果没有兼容的 unit converter,`unit_class` 应设置为 `None`。不指定 `unit_class` 已被弃用,并将在 Home Assistant Core 2025.11 中停止工作。 * 传递给函数 `async_import_statistics` 和 `async_add_external_statistics` 的 metadata 对象接受类型为 `StatisticMeanType` 的 `mean_type`,用于指定 mean 的类型(`NONE`、`ARITHMETIC` 或 `CIRCULAR`)。`mean_type` 替换了 bool 标志 `has_mean`。不指定 `mean_type` 已被弃用,并将在 Home Assistant Core 2026.11 中停止工作。 * 函数 `async_list_statistic_ids` 返回值中的 items 包含 `mean_type` 和 `unit_class`。 * 函数 `async_list_statistic_ids` 返回值中 items 的 `has_mean` 已被弃用,并将在 Home Assistant Core 2026.11 中移除。 --- url: /developers/blog/2025-10-24-service-web-api-changes.md --- 在 `strings.json` 中定义的 action translations 不再包含在 WebSocket `get_services` 命令和 REST `/api/services` 端点的响应中,因为它们不完整,且 Home Assistant 前端并未使用它们。 来自 `services.yaml` 的旧版未翻译的 action 名称和描述仍然保留在 WebSocket 和 REST 响应中。 使用 WebSocket 命令 `frontend/get_translations` 获取完整的 action translations。 更多详情请参阅 [core PR 147120](https://github.com/home-assistant/core/pull/147120)。 --- url: /developers/blog/2025-11-04-convert-interval-deprecation.md --- `TemperatureConverter` 中的方法 `convert_interval`(允许在 °F 和 °C 区间之间转换)已被弃用,建议改用 `TemperatureDeltaConverter.convert`。 新的 converter 和 device class 现在是处理温度区间的推荐方式。 更多详情请参阅 [core PR 155689](https://github.com/home-assistant/core/pull/155689) 和 [core PR 147358](https://github.com/home-assistant/core/pull/147358)。 --- url: /developers/blog/2025-11-05-config-entry-oauth2-error-handling.md --- 使用 [Application Credentials](https://developers.home-assistant.io/docs/core/platform/application_credentials/) 和 [Configuration via OAuth2](https://developers.home-assistant.io/docs/core/integration/config_flow/#configuration-via-oauth2) 的集成需要更新其错误处理,以在网络断开时正确处理配置。 目前,使用 OAuth2 配置的集成在 `__init__.py` 中的 `async_setup_entry` 里调用 `config_entry_oauth2_flow.async_get_config_entry_implementation`。以前在没有网络时,这会抛出 `ValueError: Implementation not available`,这是一个不可重试的错误,导致集成在网络恢复后需要手动重新配置(见 Issue [153956](https://github.com/home-assistant/core/issues/153956) 和 [144582](https://github.com/home-assistant/core/issues/144582))。[core PR 154579](https://github.com/home-assistant/core/pull/154579) 添加了 `config_entry_oauth2_flow.ImplementationUnavailableError`,并在因缺少网络导致 OAuth2 配置不可用时,在 `config_entry_oauth2_flow.async_get_config_entry_implementation` 中抛出该错误。集成应捕获此错误并抛出 `ConfigEntryNotReady`。 带新异常的行为变更将在 2025.12 中发布。 以下是迁移示例: ```diff - implementation = await async_get_config_entry_implementation(hass, entry) + try: + implementation = await async_get_config_entry_implementation(hass, entry) + except ImplementationUnavailableError as err: + raise ConfigEntryNotReady( + "OAuth2 implementation temporarily unavailable, will retry" + ) from err ``` 新集成将通过 `python3 -m script.scaffold config_flow_oauth2` 生成正确的 `try` / `except` 块。 --- url: /developers/blog/2025-11-10-calculated-state-capability-attributes-removed.md --- `capability_attributes` 字段已从 `CalculatedState` 中移除。Capability attributes 仍然包含在所有 attributes 中,这些 attributes 在 `CalculatedState` 中仍然可用。 `CalculatedState` 是包含 state 和 attributes 的容器,由 `Entity._async_calculate_state` 返回。 更多详情请参阅 [core PR 151672](https://github.com/home-assistant/core/pull/151672)。 --- url: /developers/blog/2025-11-17-retry-after-update-failed.md --- 使用 [Data Update Coordinator](https://developers.home-assistant.io/docs/integration_fetching_data/#coordinated-single-api-poll-for-data-for-all-entities) 的集成可以通过新参数 `retry_after` 增强 `UpdateFailed` 异常,以延迟下一次计划的刷新指定秒数,然后在 API 恢复后恢复正常节奏。 在轮询 API 因超载而返回 HTTP 429 或在响应头中提供 `Retry-After` 的情况下,集成现在可以遵守这些 backoff 信号。 集成和 API 客户端必须检测这些 backoff 信号并清理 API 期望的 backoff 时间段。`UpdateFailed` 异常接受一个 `retry_after` 参数(以秒为单位的 float),用于延迟下一次计划的刷新。一旦 API 恢复且不再抛出 `UpdateFailed`,集成将恢复其正常的 `update_interval`。 使用示例: ```python try: request = await self.client.get_information() except APIClientRateLimited as err: raise UpdateFailed( retry_after=60 # 也可以从 API 响应中获取,或提供默认值 ) from err ``` #### ConfigEntryNotReady `retry_after` 参数在 Update Coordinator 设置阶段(`async_config_entry_first_refresh`)被忽略。如果第一次刷新失败,Home Assistant 将抛出 `ConfigEntryNotReady` 异常,允许 config entry 设置使用内置的 retry 自动重试。一旦 coordinator 设置成功,`retry_after` 将应用于后续的刷新。 --- url: /developers/blog/2025-11-20-labs-preview-features.md --- 我们很高兴宣布 Home Assistant 中用于发布预览功能的新系统:**Labs**。Labs 为集成提供了一种标准化的方式,在功能成为标准之前让用户可以选择加入,从而使我们能够收集反馈并根据实际使用来完善设计。 ## 什么是 Labs 预览功能? Labs 预览功能不同于 beta 测试。虽然 beta 测试评估即将发布的 Home Assistant 版本的稳定性,但 Labs 侧重于完善用户界面和设计。Labs 功能经过全面测试且功能完整,但在我们收集实际使用和反馈的过程中,其设计和行为仍可能改变。这意味着它们可能包含 breaking changes,可能被扩展新功能,甚至如果效果不佳可能会被移除。 可以这样理解: * **Beta**:评估即将发布的 Home Assistant 版本的稳定性 * **Labs**:经过全面测试的功能,设计和用户界面在不断演进,通过实际使用和反馈进行完善 ## 工作原理 集成在其 `manifest.json` 中声明预览功能,并提供反馈、文档和 issue 报告的链接。然后用户可以在 **Settings** → **System** → **Labs** 中启用这些功能,它们会立即激活而无需重启。集成代码会检查功能是否已启用并相应地作出响应。 ## 为什么需要 Labs? 我们许多最重要的改进在成为标准之前都需要经过实际测试。Labs 提供: 1. **结构化反馈渠道**:每个功能都有专门的 URL,用于反馈、文档和 issue 报告 2. **运行时激活**:功能可以即时启用和禁用,无需配置更新或重启 3. **清晰的预期**:用户知道他们正在尝试经过全面测试的功能,其设计可能会根据反馈而改变 4. **迭代开发**:将用户反馈直接融入开发过程 ## 示例:Kitchen Sink special repair [Kitchen Sink](https://www.home-assistant.io/integrations/kitchen_sink/) 演示集成包含一个工作示例。启用时,"special repair" 功能会创建一个 repair issue,以演示 Labs 功能如何与其他 Home Assistant 集成交互。请参阅[开发文档](/developers/development/labs.md#complete-example-kitchen-sink-special-repair) 获取完整的实现。 ## 开始使用 准备向您的集成添加 Labs 预览功能吗?查看我们的[综合指南](/developers/development/labs.md),涵盖: * 何时使用 Labs(以及何时不使用) * 如何在 manifest 中定义功能 * 后端和前端功能的实现模式 * 运行时激活要求 * 测试方法 * 功能生命周期(preview → 标准或移除) ## 接下来做什么? 我们鼓励集成开发者考虑将 Labs 用于: * 重大的 UI 变更或重新设计 * 受益于实际测试的重大架构变更 * 用户反馈将塑造最终设计的功能 Labs **不适合**用于: * 永久配置选项(请改用集成 options) * 可以直接进入发布版本的小改动 * 存在关键 bug 或根本上不完整的功能 ## 亲自试一试 想看看 Labs 的实际效果?安装 Kitchen Sink 演示集成,并在 Settings → System → Labs 中启用"Special repair"功能。您将亲身体验预览功能的工作原理。 --- url: /developers/blog/2025-11-21-identify-buttons-diagnostic-category.md --- 表示设备识别机制的 button entity(使用 `IDENTIFY` device class)现要求其 entity category 设置为 `DIAGNOSTIC`。 有关 entity category 的更多详情,请参阅[文档](/developers/core/entity.md#registry-properties)。 --- url: /developers/blog/2025-11-23-mqtt-subscribe-wait.md --- ## 为 MQTT subscription 添加状态回调 使用 MQTT 的集成可能需要等待 subscription 完成后再执行操作。默认行为是 subscription 会被排队并去抖,因此调用者通常不会等待 broker 确认。某些集成必须保证 broker 已完成 subscription。 新的 `mqtt.async_on_subscribe_done` helper 可用于监控 MQTT subscription,以允许执行额外任务。 请确保使用与 MQTT subscription 相同的 QoS。 示例: ```python from homeassistant.components import mqtt async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Setup integration MQTT subscription monitoring.""" def _on_subscribe_status() -> None: """Handle subscription ready signal.""" # Do stuff # Handle subscription ready status update await mqtt.async_on_subscribe_done( hass, "myintegration/status", qos=1, on_subscribe_status=_on_subscribe_status, ) # Do stuff ``` --- url: /developers/blog/2025-11-25-storage-helper-opt-in-serialize-in-executor.md --- 来自 `homeassistant/helpers/storage.py` 的 `Store` 类接受新的构造函数参数 `serialize_in_event_loop` 如果 `serialize_in_event_loop` 为 `True`(默认值): * 传递给 `Store.async_delay_save` 的 `data_func` 从 event loop 调用 * 传递给 `Store.async_delay_save` 的 `data_func` 产生的数据在 event loop 中序列化为 JSON * 传递给 `Store.async_save` 的数据在 event loop 中序列化为 JSON 如果 `serialize_in_event_loop` 为 `False`: * 传递给 `Store.async_delay_save` 的 `data_func` 从单独的 thread 调用,这意味着它必须是 thread-safe 的,且不得访问 hass 对象 * 传递给 `Store.async_delay_save` 的 `data_func` 产生的数据在单独的 thread 中序列化为 JSON,这意味着它必须是 thread-safe 的 * 传递给 `Store.async_save` 的数据在单独的 thread 中序列化为 JSON,这意味着它必须是 thread-safe 的 此行为已发生变更;以前传递给 `Store.async_delay_save` 的 `data_func` 总是从单独的 thread 调用,其产生的数据或传递给 `Store.async_save` 的数据以前总是由单独的 thread 序列化。 进行此项变更的原因是,之前并未文档说明 `data_func` 将由 event loop 以外的 thread 调用,或 JSON 序列化将在 event loop 以外的 thread 中发生,而 `data_func` 及其产生的数据或传递给 `Store.async_save` 的数据通常并非 thread-safe 的。 更多详情请参阅 [core PR 157158](https://github.com/home-assistant/core/pull/157158) 和 [core PR 157263](https://github.com/home-assistant/core/pull/157263)。 --- url: /developers/blog/2025-11-27-service-translation-placeholders.md --- 现在可以使用 translation placeholders 来处理(自定义)service actions。 [service action 示例](/developers/core/integration-quality-scale/rules/action-setup.md?_highlight=hass.services.async_register#example-implementation) 现在展示了如何在注册 service action 时提供可用的 description placeholders。 将 URL 从 service 描述和 translation strings 中移动到 description placeholders。 --- url: /developers/blog/2026-01-05-pyserial-asyncio-fast.md --- ### 变更摘要 从 `2026.7` 起,在 Home Assistant 中安装 `pyserial-asyncio` 将被阻止。 建议库维护者和自定义集成迁移到 `pyserial-asyncio-fast`。 ### 背景 `pyserial-asyncio` 因为执行阻塞式 `sleep` 而阻塞 event loop。该库也不再维护,因此改善状况的努力尚未发布。 `pyserial-asyncio-fast` 被创建为替代方案(见[仓库](https://github.com/home-assistant-libs/pyserial-asyncio-fast)),所有核心集成现已迁移完成。 ### 迁移 `pyserial-asyncio-fast` 被设计为 `pyserial-asyncio` 的替代方案,必要的更改非常简单。 #### 依赖项 ```python # 旧方式 install_requires=[ "pyserial-asyncio" ] # 新方式 install_requires=[ "pyserial-asyncio-fast" ] ``` #### 用法 ```python # 旧方式 import serial_asyncio async def connect(): conn = await serial_asyncio.open_serial_connection(**self.serial_settings) # 新方式 import serial_asyncio_fast async def connect(): conn = await serial_asyncio_fast.open_serial_connection(**self.serial_settings) ``` 更多示例请参阅[跟踪 pull request](https://github.com/home-assistant/core/pull/116635)。 --- url: /developers/blog/2026-01-13-replace-pre-commit-with-prek.md --- 通过将 `pre-commit` 替换为 [`prek`](https://prek.j178.dev/),我们可以提升检查的性能。Prek 使用与 `pre-commit` 相同的 `.pre-commit-config.yaml`,是完整的替代方案。由于 `prek` 是用 Rust 编写的,并允许并行执行不同的 job,我们可以更快地检查代码。 新的开发环境将自动安装 `prek`,对于现有的开发环境,请通过运行 `uv pip install requirements_test.txt` 更新测试依赖。 --- url: /developers/blog/2026-02-16-labs-async-listen-deprecation.md --- `labs` 集成中的 `async_listen` helper 已被弃用,建议改用 `async_subscribe_preview_feature`。 新的 `async_subscribe_preview_feature` 函数提供了更一致的 API,其中 listener callback 会接收到一个包含更新后 feature state 的 `EventLabsUpdatedData` 参数。这消除了需要在 listener 内部分别调用 `async_is_preview_feature_enabled` 来检查当前值的需要。 ### 旧用法 ```python from homeassistant.components.labs import async_is_preview_feature_enabled, async_listen def my_listener() -> None: if async_is_preview_feature_enabled(hass, DOMAIN, "my_feature"): # feature 已启用 ... async_listen( hass, domain=DOMAIN, preview_feature="my_feature", listener=my_listener, ) ``` ### 新用法 ```python from homeassistant.components.labs import EventLabsUpdatedData, async_subscribe_preview_feature async def my_listener(event_data: EventLabsUpdatedData) -> None: if event_data["enabled"]: # feature 已启用 ... async_subscribe_preview_feature( hass, domain=DOMAIN, preview_feature="my_feature", listener=my_listener, ) ``` 请注意,新的 listener 是一个协程函数,并接收 `EventLabsUpdatedData` 作为参数。 `async_listen` 将在 Home Assistant 2027.3 中移除。 更多详情请参阅 [core PR #162648](https://github.com/home-assistant/core/pull/162648)。 --- url: /developers/blog/2026-02-18-reconfiguration-support-for-webhook-helper.md --- 使用 webhook config flow helper(`homeassistant.helpers.config_entry_flow.register_webhook_flow`)的集成现已支持 reconfiguration。这使得集成能够重新获取 webhook,或在 Home Assistant 实例 URL 更改时获取更新的 webhook。 使用 webhook config flow helper 的自定义集成必须为 reconfiguration flow 添加 translation strings。 **reconfiguration flow 的示例 translation strings:** ```json { "config": { "abort": { "reconfigure_successful": "**Reconfiguration was successful**\n\nIn Sleep as Android go to *Settings → Services → Automation → Webhooks* and update the webhook with the following URL:\n\n`{webhook_url}`" }, "step": { "reconfigure": { "description": "Are you sure you want to re-configure the Sleep as Android integration?", "title": "Reconfigure Sleep as Android" } } } } ``` 更多详情请参阅 [core PR #151729](https://github.com/home-assistant/core/pull/151729)。 --- url: /developers/blog/2026-02-19-oauth-token-request-error-handling.md --- ## 变更摘要 自 `2026.3` 起,我们正在增强 OAuth 2.0 helper 处理 token request 和 refresh token 失败的方式。此变更使错误处理更加健壮,不再依赖于 aiohttp 库,并帮助使用 [Data Update Coordinator](https://developers.home-assistant.io/docs/integration_fetching_data/#coordinated-single-api-poll-for-data-for-all-entities) 的集成自动触发正确的错误处理。 ## 有哪些变更 当 OAuth 2.0 token request 或 token refresh 失败时,Home Assistant 会允许底层的 `aiohttp.ClientResponseError` 直接传播到集成。此行为正在变更和增强。 我们引入了三个新的异常,提供 clearer 的语义: * `OAuth2TokenRequestTransientError` - 可恢复的错误,可以重试。 * `OAuth2TokenRequestReauthError` - 不可恢复的错误,需要重新认证。 * `OAuth2TokenRequestError` - 当上述两个条件都不满足时的基类异常,或允许集成捕获所有 token request 异常。 ### Data Update Coordinator 大多数使用 OAuth 2.0 helper 的集成,也使用 Data Update Coordinator。当 token request 或 refresh token 失败时,异常将在 Data Update Coordinator 中冒泡,并触发以下错误处理: 对于不可恢复的错误(400+,除 429(rate limit)外): * `OAuth2TokenRequestReauthError`:Data Update Coordinator 会在需要抛出异常时抛出 `ConfigEntryAuthFailed`,或启动重新认证 flow。 对于 transient 错误(500+ 和 429): * `OAuth2TokenRequestTransientError`:Data Update Coordinator 将其视为 `UpdateFailed`,并触发 retry 机制。 这意味着使用 OAuth 2.0 helper 结合 Data Update Coordinator 的集成不需要对这些新异常做任何特殊处理。 ### 迁移 目前使用 OAuth 2.0 helper 且明确处理 `aiohttp.ClientResponseError` 的集成应调整其错误处理,以应对新异常。为便于过渡,我们添加了一个兼容层,让新的 OAuth 异常继承自 `aiohttp.ClientResponseError`。捕获此异常类型的现有代码应该继续正常工作。但建议重构代码以使用新异常。详情请参阅代码示例。 #### 迁移代码示例 更新异常处理,然后继续判断是否为(不可)恢复错误。例如: ```python try: await auth.async_get_access_token() except OAuth2TokenRequestReauthError as err: raise ConfigEntryAuthFailed( translation_domain=DOMAIN, translation_key="reauth_required" ) from err except (OAuth2TokenRequestError, ClientError) as err: raise ConfigEntryNotReady( translation_domain=DOMAIN, translation_key="auth_server_error" ) from err ``` --- url: /developers/blog/2026-02-23-remove-deprecate-light-features.md --- ### 变更摘要 2022 年 10 月,Home Assistant 将首选色温单位从 mired 迁移到了 kelvin。 在 [2024 年 2 月](/developers/blog/2024-02-12-light-color-mode-mandatory.md),Home Assistant 要求显式提供 `supported_color_modes` 和 `color_mode` 属性(触发了对传统 fallback color mode 支持的弃用)。 在 [2024 年 12 月](/developers/blog/2024-12-14-kelvin-preferred-color-temperature-unit.md),Home Assistant 要求显式支持 Kelvin(触发了对 mired 支持的弃用)。 现在是清理遗留代码并移除相应属性、常量和属性的时候了: * 移除已弃用的 `ATTR_COLOR_TEMP`、`ATTR_MIN_MIREDS`、`ATTR_MAX_MIREDS`、`ATTR_KELVIN`、`COLOR_MODE_***` 和 `SUPPORT_***` 常量 * 移除已弃用的 state 属性 `ATTR_COLOR_TEMP`、`ATTR_MIN_MIREDS` 和 `ATTR_MAX_MIREDS` * 移除 `light.turn_on` 服务调用中对 `ATTR_KELVIN` 和 `ATTR_COLOR_TEMP` 参数的已弃用支持 * 移除 entity 中对 `LightEntity.color_temp`、`LightEntity.min_mireds` 和 `LightEntity.max_mireds` 属性的已弃用支持 * 移除 entity 中对 `LightEntity._attr_color_temp`、`LightEntity._attr_min_mireds` 和 `LightEntity._attr_max_mireds` 简写属性的已弃用支持 此外,未提供有效的 `supported_color_modes` 和 `color_mode` 属性将不再可行,并会引发错误。 ### 示例 #### 自定义最小/最大色温 ```python class MyLight(LightEntity): """Representation of a light.""" # 旧 # _attr_min_mireds = 200 # 5000K # _attr_max_mireds = 400 # 2500K # 新 _attr_min_color_temp_kelvin = 2500 # 400 mireds _attr_max_color_temp_kelvin = 5000 # 200 mireds ``` #### 默认最小/最大色温 ```python from homeassistant.components.light import DEFAULT_MAX_KELVIN, DEFAULT_MIN_KELVIN class MyLight(LightEntity): """Representation of a light.""" # 旧方式无需设置 _attr_min_mireds / _attr_max_mireds # 新方式需要显式设置默认值 _attr_min_color_temp_kelvin = DEFAULT_MIN_KELVIN _attr_max_color_temp_kelvin = DEFAULT_MAX_KELVIN ``` #### 动态最小/最大色温 ```python from homeassistant.util import color as color_util class MyLight(LightEntity): """Representation of a light.""" # 旧 # def min_mireds(self) -> int: # """Return the coldest color_temp that this light supports.""" # return device.coldest_temperature # # def max_mireds(self) -> int: # """Return the warmest color_temp that this light supports.""" # return device.warmest_temperature # 新 def min_color_temp_kelvin(self) -> int: """Return the warmest color_temp that this light supports.""" return color_util.color_temperature_mired_to_kelvin(device.warmest_temperature) def max_color_temp_kelvin(self) -> int: """Return the coldest color_temp that this light supports.""" return color_util.color_temperature_mired_to_kelvin(device.coldest_temperature) ``` #### 在服务调用中检查色温 ```python from homeassistant.components.light import ATTR_COLOR_TEMP_KELVIN from homeassistant.util import color as color_util class MyLight(LightEntity): """Representation of a light.""" def turn_on(self, **kwargs: Any) -> None: """Turn on the light.""" # 旧 # if ATTR_COLOR_TEMP in kwargs: # color_temp_mired = kwargs[ATTR_COLOR_TEMP] # color_temp_kelvin = color_util.color_temperature_mired_to_kelvin(color_temp_mired) # 旧 # if ATTR_KELVIN in kwargs: # color_temp_kelvin = kwargs[ATTR_KELVIN] # color_temp_mired = color_util.color_temperature_kelvin_to_mired(color_temp_kelvin) # 新 if ATTR_COLOR_TEMP_KELVIN in kwargs: color_temp_kelvin = kwargs[ATTR_COLOR_TEMP_KELVIN] color_temp_mired = color_util.color_temperature_kelvin_to_mired(color_temp_kelvin) ``` ### 背景信息 * [关于 Kelvin 温度的社区讨论](https://community.home-assistant.io/t/wth-is-light-temperature-not-in-kelvin/467449/6) * [Core PR #79591: 迁移到 Kelvin](https://github.com/home-assistant/core/pull/79591) * [Architecture discussion #564](https://github.com/home-assistant/architecture/discussions/564) * [Color modes 文档](/developers/core/entity/light.md#color-modes) --- url: /developers/blog/2026-02-24-brands-proxy-api.md --- 从 Home Assistant 2026.3 开始,自定义集成可以直接在集成目录中包含自己的品牌图片(图标和 logo)。无需再提交到单独的仓库——只需将图片放入 `brand/` 文件夹即可在 UI 中显示。 ## 自定义集成本地品牌图片 在你的自定义集成中添加一个 `brand/` 目录,包含你的图标和 logo 文件: ```text custom_components/my_integration/ ├── __init__.py ├── manifest.json └── brand/ ├── icon.png └── logo.png ``` 支持以下图片文件名: * `icon.png` / `dark_icon.png` * `logo.png` / `dark_logo.png` * `icon@2x.png` / `dark_icon@2x.png` * `logo@2x.png` / `dark_logo@2x.png` 本地品牌图片会自动优先于 brands CDN 中的图片。无需任何额外配置。 更多详情,请参阅 [integration file structure 文档](/developers/creating_integration_file_structure.md#brand-images---brand)。 ## 品牌图片现在通过本地 API 提供 为了使本地品牌图片成为可能,所有品牌图片现在都通过 Home Assistant 本地 API 提供,而不是由浏览器直接从 CDN 获取。 一个新的 `brands` system integration 通过两个端点代理品牌图片: * `/api/brands/integration/{domain}/{image}` — 集成的图标和 logo * `/api/brands/hardware/{category}/{image}` — 硬件图片 图片会在本地磁盘上缓存,并使用 stale-while-revalidate 策略提供,因此在网络中断期间仍然可用。 ### 对 frontend 的影响 `src/util/brands-url.ts` 中的 `brandsUrl()` 和 `hardwareBrandsUrl()` helper 现在返回本地 API 路径,而不是 CDN URL。如果你的自定义卡片或面板使用了这些 helper,则无需任何更改。 如果你是在手动构建品牌图片 URL,请进行更新: ```typescript // 旧 const url = `https://brands.home-assistant.io/_/${domain}/icon.png`; // 新 import { brandsUrl } from "../util/brands-url"; const url = brandsUrl({ domain, type: "icon" }); ``` 这些端点需要身份验证。`brandsUrl()` helper 会自动处理此问题,通过追加 access token。如果你手动构建 URL,则需通过 `brands/access_token` WebSocket 命令获取 token,并将其作为 `token` 查询参数追加。 --- url: /developers/blog/2026-03-11-backup-upload-progress.md --- `BackupAgent.async_upload_backup` 方法现在接收一个新的 `on_progress` 回调参数。Backup agents 可以在上传期间定期调用此回调,以报告到目前为止已上传的字节数: ```python class ExampleBackupAgent(BackupAgent): async def async_upload_backup( self, *, open_stream: Callable[[], Coroutine[Any, Any, AsyncIterator[bytes]]], backup: AgentBackup, on_progress: OnProgressCallback, **kwargs: Any, ) -> None: """Upload a backup.""" ... bytes_uploaded = 0 async for chunk in await open_stream(): await do_upload(chunk) bytes_uploaded += len(chunk) on_progress(bytes_uploaded=bytes_uploaded) ... ``` Backup manager 使用这些进度报告来触发 `UploadBackupEvent` 事件,使 frontend 能够向用户显示实时上传进度。 更多详情,请查看 [backup agent 文档](/developers/core/platform/backup.md#backup-agents)。 --- url: /developers/blog/2026-03-25-frontend-component-updates-2026.4.md --- :::info 我们不官方支持或鼓励自定义卡片开发者使用我们内置的 components。这些 component APIs 随时可能变更,你应该将你的卡片构建为独立组件。 ::: ## ha-input 我们持续将基于 Material Design 的 components 迁移到基于 Web Awesome。这次我们迁移了 input 组件,这导致了 API 变更,但视觉效果暂时保持不变。 * `ha-input` 是 `ha-textfield` 的继任者 * `ha-textfield` 的 API 保持不变,但组件已迁移为内部使用 `ha-input`,并将在 2026.5 中移除 * 同时替换 `ha-outlined-text-field` * `ha-input-search` 替换 `search-input` 和 `search-input-outlined` * `ha-input-multi` 替换 `ha-multi-textfield` * `ha-input-copy` 替换 `copy-textfield` 此组件还引入了新的表单背景语义化 theme 变量: ```css --ha-color-form-background: var(--ha-color-neutral-95); --ha-color-form-background-hover: var(--ha-color-neutral-90); --ha-color-form-background-disabled: var(--ha-color-neutral-80); ``` ## 日期选择器 我们终于通过用 [Cally](https://wicky.nillia.ms/cally/) 替换 date 和 date range picker 移除了 Vue 2 依赖。 --- url: /developers/blog/2026-03-25-frontend-dialogs.md --- ## 问题 由 dialog manager 管理的每个 dialog 只打开一次,并在整个应用程序生命周期内保留在 DOM 中。这会导致: * **更多内存占用**:Dialogs 即使在不可见时也会堆积在 DOM 中 * **因缺少 state 重置而导致的更多 bugs**:Dialog state 在多次打开之间持久存在,导致过期数据或意外行为 ## 解决方案:DialogMixin 我们使用 `DialogMixin` 实现了一种处理 dialogs 的新方式。这种方式具有以下特点: * **Dialogs 在打开时创建,关闭时销毁**:无需在关闭时手动重置 dialog 的 state * **关闭事件自动处理**:Dialog mixin 负责清理工作 * **Subscribe mixin 现在可以在 dialogs 中使用**:由于 dialogs 被正确销毁,subscriptions 会被自动清理 * **使用正常的 Lit lifecycle methods**:使用 `connectedCallback` 在 dialog 打开时初始化,而不是依赖 `showDialog` 方法 ## 示例 查看 `ha-dialog-date-picker` 作为参考实现。`DialogMixin` 如果可用的话,会将 dialog params 添加到 `this.params`。 --- url: /developers/blog/2026-03-25-frontend-lazy-context.md --- ## 什么是 context? 在 Home Assistant frontend 中,[Context](https://lit.dev/docs/data/context/) 是一种在 component 树中共享数据的方式,无需显式地通过每一层作为 property 传递。通过 context 提供特定的数据片段,并仅在需要的地方消费它们,而不是将 `hass` 对象层层传递到多个 component 层级。 使用 context 而非传递整个 `hass` 对象的关键优势: * **更易于使用**:Components 可以直接消费所需数据,无需父级 components 将其向下传递。这减少了 prop drilling,使 components 更加自包含且可复用。 * **减少不必要的 component re-renders**:当 component 以 property 形式接收 `hass` 时,`hass` 的任何变更都会触发该 component 及其所有子组件的 re-render——即使该 component 只关心数据的一个小子集。通过 context 仅提供 component 所需的特定数据,可以确保 components 仅在实际依赖发生变更时才 re-render,从而实现更好的性能和更响应的 UI。 ## 引入 LazyContext 我们引入了一种新的 `LazyContext` 模式,它应替换传统的基于订阅的方式以及 `SubscribeMixin` 的使用。以前,components 会订阅数据源并手动管理订阅生命周期,这往往导致样板代码,且如果订阅未正确清理,则可能导致内存泄漏。 `LazyContext` 简化了这一点: * **Lazy loading**:数据仅在 component 实际消费该 context 时才被获取 * **Automatic cleanup**:Subscriptions 被自动管理 * **Shared state**:消费同一 context 的多个 components 共享单个订阅 * **Optimized re-renders**:仅在数据变更时,消费该 context 的 components 才会 re-render 这种方式集中了 data-fetching 逻辑,使你更容易推理数据何时以及如何流经应用程序。 ## 示例 ### 定义一个 LazyContext 要定义一个 lazy context,使用 `LazyContextProvider` 并提供一个 fetch 函数: ```ts new LazyContextProvider(this, { context: labelsContext, subscribeFn: (connection, setValue) => subscribeLabelRegistry(connection, setValue), }) ``` ### 使用 lit 消费 context 要在 component 中消费 context,使用 `@consume` decorator: ```ts @state() @consume({ context: labelsContext, subscribe: true }) private _labels?: LabelRegistryEntry[]; ``` 查看更新后的 custom card 示例,以在 vanilla JS 中使用它:[Custom card example](/developers/frontend/custom-ui/custom-card.md#defining-your-card)。 ### 使用 @transform 处理派生数据 *仅在 home-assistant frontend codebase 内可用* `@transform` decorator 允许你从 context value 派生数据,确保 component 仅在转换后的值实际变更时才 re-render。 ```ts @state() @consume({ context: statesContext, subscribe: true }) @transform({ transformer: function (this: HuiButtonCard, entityStates: HassEntities) { return this._config?.entity ? entityStates?.[this._config?.entity] : undefined; }, watch: ["_config"], }) private _stateObj?: HassEntity; ``` 使用 `@transform`,即使完整的 states 对象更新,你的 component 也仅会在转换后的结果(`_stateObj`)实际变更时才 re-render。`watch` 选项允许你指定应触发 transformer 函数重新求值的附加属性——在这种情况下,当 `_config` 变更时,transformer 会再次运行以提取正确的 entity state。 --- url: /developers/blog/2026-03-30-infrared-entity-platform.md --- Home Assistant 现在有了一个 `infrared` entity platform,它将 IR 发射器硬件与它们所控制的设备解耦。每个设备集成不再直接与特定 IR 硬件通信,而是由发射器集成(如 `esphome`)暴露 `InfraredEntity` 实例,设备集成(如 `lg_infrared`)通过 helper 函数向其发送命令。 查看 [architecture discussion](https://github.com/home-assistant/architecture/discussions/1316) 了解完整背景。 ## 架构 Infrared domain 位于两类集成之间: * **发射器集成**(ESPHome、Broadlink 等)实现 `InfraredEntity` base class 以提供特定硬件的 IR 传输。 * **消费方集成**(LG、Samsung、Daikin 等)使用 helper 函数通过可用的发射器发送特定设备的 IR 命令。 用户在消费方集成的 config flow 期间选择要使用哪个发射器。 ## 实现一个发射器集成 发射器集成通过继承 `InfraredEntity` 并实现 `async_send_command` 来提供 `infrared` platform。Command 的 `get_raw_timings()` 方法返回与协议无关的 timing 数据,硬件可以据此传输: ```python from homeassistant.components.infrared import InfraredCommand, InfraredEntity class MyInfraredEntity(InfraredEntity): """My IR transmitter.""" async def async_send_command(self, command: InfraredCommand) -> None: """Send an IR command.""" timings = [ interval for timing in command.get_raw_timings() for interval in (timing.high_us, -timing.low_us) ] await self._device.transmit( carrier_frequency=command.modulation, timings=timings, ) ``` 原始与协议无关的 timings 应转换为硬件所需的具体格式。 ## 构建消费方集成 消费方集成通过向发射器 entity 发送命令来控制 IR 设备。它们不直接与 IR 硬件交互。 **1. 在 `manifest.json` 中声明依赖**: ```json { "dependencies": ["infrared"] } ``` **2. 在 config flow 中让用户选择发射器**: ```python from homeassistant.components import infrared emitters = infrared.async_get_emitters(hass) if not emitters: return self.async_abort(reason="no_emitters") ``` **3. 使用 helper 函数和 [`infrared-protocols`](https://github.com/home-assistant-libs/infrared-protocols) 库发送 IR 命令**: ```python from infrared_protocols.codes.lg.tv import LGTVCode, make_lg_tv_command from homeassistant.components import infrared await infrared.async_send_command( hass, self._infrared_entity_id, make_lg_tv_command(LGTVCode.VOLUME_UP), context=self._context, ) ``` ## IR 协议和 codes IR protocol 编码器及设备 code 集合存放在 Home Assistant 之外的 [`infrared-protocols`](https://github.com/home-assistant-libs/infrared-protocols) 库中。核心集成所使用的常见协议(NEC、Samsung 等)和知名设备 codes 应贡献到那里。对于小众或专有协议,也可以使用单独的第三方库。 更多详情,请参阅 [infrared entity 文档](/developers/core/entity/infrared.md)。 --- url: /developers/blog/2026-04-02-builder-migration.md --- 传统的 `home-assistant/builder` container 以及旧的 `home-assistant/builder` GitHub Action 已被废弃。我们建议你按照本文所述,迁移所有 app(原 add-ons)的 GitHub workflows 和 Dockerfiles。 ## 变更内容及原因 旧版 builder 在单个特权 Docker-in-Docker container 中使用 QEMU 模拟运行每种架构的 build。这速度慢、需要高权限,而且已经熟悉 Docker 的用户还需要学习如何使用自定义的 Home Assistant builder container。旧版 builder 还存在不必要的维护开销。如今,builder 所做的一切都可以完全用 Docker BuildKit 替代,GitHub Actions runners 原生支持它,并且在需要时内置了带 QEMU 模拟的多架构支持。 对于 CI 来说,替代方案是一组专注的 [composite GitHub Actions](https://github.com/home-assistant/builder),它们将构建任务委托给 runner 的原生 Docker 并使用 Docker BuildKit。在 CI 之外,迁移意味着你的 `Dockerfile` 现在成为构建 app 镜像的唯一可信来源,你可以直接使用 `docker build` 在本地构建和测试你的 app,而无需使用 builder container。 ## 迁移过程 迁移包括两部分:更新 Dockerfiles 和更新 GitHub Actions workflows。 ### 更新 Dockerfiles 新的 build workflow 不再使用 `build.yaml`。将内容移动到 `Dockerfile` 中,如下所示: * **`build_from`** — 用 `Dockerfile` 中的 `FROM` 语句替换 `build.yaml` 中的 `build_from` key: ```dockerfile FROM ghcr.io/home-assistant/base:latest ``` 由于 base images 现在作为 multi-platform manifests 发布,通常不再需要为每种架构定义 base images。`build-image` action 仍然提供 `BUILD_ARCH` 作为 build argument,如果你需要在 base image 名称模板中使用它,可以在 `Dockerfile` 中使用。 * **`labels`** — 将所有自定义 Docker labels 直接移动到 `Dockerfile` 中,使用 `LABEL` 语句: ```dockerfile LABEL \ org.opencontainers.image.title="Your awesome app" \ org.opencontainers.image.description="Description of your app." \ org.opencontainers.image.source="https://github.com/your/repo" \ org.opencontainers.image.licenses="Apache License 2.0" ``` 如果你正在创建自定义 workflow,请注意旧版 builder 会自动添加 `io.hass.type`、`io.hass.name`、`io.hass.description` 和 `io.hass.url` labels。新 action 不会推断这些值,因此通过 `build-image`(或类似)action 的 `labels` input 显式添加它们。 * **`args`** — 将自定义 build arguments 作为带默认值的 `ARG` 定义移动到 `Dockerfile` 中: ```dockerfile ARG MY_BUILD_ARG="default-value" ``` `ARG` 中的默认值替代了之前通过 `build.yaml` 的 `args` 字典提供的值。如果需要,仍然可以在 build 时使用 `--build-arg` 覆盖。 将 `build.yaml` 的内容迁移后,你可以将该文件从仓库中删除。 ### 更新 GitHub Actions workflows 移除任何使用 `home-assistant/builder@master` 的 workflow steps,并替换为新的 composite actions。查看我们示例 app 仓库中的 [example workflow](https://github.com/home-assistant/apps-example/blob/main/.github/workflows/builder.yaml) 以获得完整的可工作示例。或者,根据需要,在更自定义的 workflow 中使用 [individual actions](https://github.com/home-assistant/builder?tab=readme-ov-file#example-workflow)。 ### 镜像命名 引用已发布的 app image 的首选方式现在是**通用的(multi-arch)名称**,不带架构前缀: ```yaml # config.yaml image: "ghcr.io/my-org/my-app" ``` `{arch}` 占位符(例如 `ghcr.io/my-org/{arch}-my-app`)仍然作为兼容性后备方案受支持,但建议改用通用名称,让 manifest 处理平台解析。 ### 本地构建 更新 `Dockerfile` 后,你可以使用 `docker build` 直接构建 app 镜像——详情请参阅 [Local app testing](/developers/apps/testing.md)。 ## 由 Supervisor 在本地构建的 Apps 为了向后兼容,Supervisor 仍然会读取 `build.yaml` 文件(如果存在),并用从该文件中读取的值填充 image build arguments。这将产生警告,并会在未来的某个时候被移除,因此建议迁移到上述基于 Dockerfile 的方式。 --- url: /developers/blog/2026-04-07-entity-id-mismatched-domain-deprecated.md --- 直接在 entity 上设置 `entity_id` 的集成现在会被验证,以确保 domain 部分与 platform 的 domain 匹配。例如,`light` entity 必须使用 `light.my_light`,而不能使用 `cover.my_light`。 使用错误 domain 设置 entity ID 会记录一条 deprecation 警告,并且将在 **Home Assistant 2027.5 中停止工作**。 在大多数情况下,集成不应设置 `entity_id`——Home Assistant 会自动生成它。 --- url: /developers/blog/2026-04-15-doorbell-standard-event-type.md --- Doorbell event entities 现在有了一个标准的 `ring` event type。使用 `EventDeviceClass.DOORBELL` 的集成必须在它们的 `event_types` 列表中包含 `DoorbellEventType.RING`。 查看 [architecture discussion](https://github.com/home-assistant/architecture/discussions/1363) 了解完整背景。 ## 原因 以前,每个集成使用自己的字符串来表示"门铃被按下"事件——`ding`、`ring`、`doorbell_chime`、`single_press` 等。这种不一致性使得无法构建适用于所有集成的通用 doorbell 自动化。 新的 `DoorbellEventType.RING` 标准 event type 通过确保每个 doorbell 集成在门铃被按下时触发通用的 `ring` 事件来解决这个问题。 ## 需要做什么 从 `homeassistant.components.event` 导入 `DoorbellEventType`,并在你的 doorbell entity 的 `event_types` 中包含 `DoorbellEventType.RING`。每当门铃被按下时触发它: ```python from homeassistant.components.event import DoorbellEventType, EventDeviceClass, EventEntity class MyDoorbellEvent(EventEntity): _attr_device_class = EventDeviceClass.DOORBELL _attr_event_types = [DoorbellEventType.RING] @callback def _async_handle_event(self) -> None: """Handle the doorbell press event.""" self._trigger_event(DoorbellEventType.RING) self.async_write_ha_state() ``` 除了标准的 `ring` type 之外,仍然允许额外的自定义 event types(例如 `double_press`、`long_press`)。 不包含 `DoorbellEventType.RING` 的 doorbell entities 会记录一条 deprecation 警告,并且将在 **Home Assistant 2027.4 中停止工作**。 更多详情,请参阅 [event entity 文档](/developers/core/entity/event.md)。 --- url: /developers/blog/2026-04-20-legacy-device-tracker-deprecation.md --- ## 摘要 传统的(非 config-entry)device tracker platform API 已弃用,并将在 Home Assistant 2027.5 版本中移除。 在 12 个月的弃用期结束时,所有剩余的 legacy device tracker platforms 都将从核心仓库中移除,实现 legacy API 的自定义集成将停止工作。 集成作者需要更新集成以实现 [modern device tracker platform API](https://developers.home-assistant.io/docs/core/entity/device-tracker)。 ## 背景 Config entry device trackers 于 2019 年 5 月推出,这意味着集成作者在 2027 年 5 月支持被移除时,已有 8 年时间迁移集成。 截至今天(2026 年 4 月),大多数广泛使用的核心 device tracker 集成已经迁移。 请注意,尚未迁移的最受欢迎的集成 xiaomi\_miio 具有广泛的功能混合,包括 device tracker 以外的其他功能。 弃用 legacy device tracker API 的提案已在 [architecture proposal 1375](https://github.com/home-assistant/architecture/discussions/1375) 中获得批准。 ### 核心集成列表,按报告使用量排序 该列表生成于 2026 年 3 月的 https://analytics.home-assistant.io/ ```text Integration Installations API Type Details ---------------------------------------------------------------------------------------------------- mobile_app 415,204 modern tracker TrackerEntity mqtt 233,161 modern tracker TrackerEntity zha 126,903 modern scanner ScannerEntity ibeacon 89,099 modern unknown BaseTrackerEntity fritz 42,934 modern scanner ScannerEntity ping 33,439 modern scanner ScannerEntity unifi 33,136 modern scanner ScannerEntity xiaomi_miio 12,866 legacy scanner async_scan_devices nmap_tracker 7,397 modern scanner ScannerEntity icloud 5,772 modern tracker TrackerEntity freebox 5,312 modern scanner ScannerEntity asuswrt 4,686 modern scanner ScannerEntity tile 4,212 modern tracker TrackerEntity renault 3,646 modern tracker TrackerEntity private_ble_device 3,231 modern unknown BaseTrackerEntity keenetic_ndms2 3,080 modern scanner ScannerEntity owntracks 3,022 modern tracker TrackerEntity snmp 2,923 legacy scanner async_scan_devices devolo_home_network 2,910 modern scanner ScannerEntity tesla_fleet 2,798 modern tracker TrackerEntity netgear 2,782 modern scanner ScannerEntity mikrotik 2,761 modern scanner ScannerEntity tplink_omada 2,708 modern scanner ScannerEntity starlink 2,250 modern tracker TrackerEntity tractive 2,144 modern tracker TrackerEntity volvo 2,077 modern tracker TrackerEntity husqvarna_automower 1,924 modern tracker TrackerEntity tessie 1,562 modern tracker TrackerEntity bluetooth_le_tracker 1,011 legacy traccar_server 978 modern tracker TrackerEntity huawei_lte 827 modern scanner ScannerEntity gpslogger 813 modern tracker TrackerEntity teslemetry 720 modern tracker TrackerEntity traccar 609 modern tracker TrackerEntity luci 590 legacy scanner scan_devices subaru 502 modern tracker TrackerEntity mysensors 474 modern tracker TrackerEntity starline 460 modern tracker TrackerEntity geofency 443 modern tracker TrackerEntity google_maps 389 legacy locative 378 modern tracker TrackerEntity opnsense 355 legacy scanner scan_devices fing 266 modern scanner ScannerEntity ruckus_unleashed 232 modern scanner ScannerEntity synology_srm 193 legacy scanner scan_devices unifi_direct 190 legacy scanner scan_devices mqtt_json 182 legacy vodafone_station 166 modern scanner ScannerEntity xiaomi 143 legacy scanner scan_devices demo 141 legacy ubus 111 legacy scanner scan_devices bt_smarthub 95 legacy scanner scan_devices aprs 93 legacy nrgkick 81 modern tracker TrackerEntity ddwrt 79 legacy scanner scan_devices fressnapf_tracker 74 modern tracker TrackerEntity linksys_smart 69 legacy scanner scan_devices fortios 53 legacy scanner scan_devices swisscom 51 legacy scanner scan_devices tomato 45 legacy scanner scan_devices quantum_gateway 42 legacy scanner scan_devices aruba 24 legacy scanner scan_devices meraki 24 legacy sky_hub 22 legacy scanner async_scan_devices ituran 19 modern tracker TrackerEntity cisco_ios 10 legacy scanner scan_devices upc_connect 10 legacy scanner async_scan_devices cisco_mobility_express 6 legacy scanner scan_devices arris_tg2492lg 2 legacy scanner async_scan_devices bbox 1 legacy scanner scan_devices actiontec 0 legacy scanner scan_devices autoskope 0 modern tracker TrackerEntity bt_home_hub_5 0 legacy scanner scan_devices cppm_tracker 0 legacy scanner scan_devices fleetgo 0 legacy hitron_coda 0 legacy scanner scan_devices lojack 0 modern tracker TrackerEntity thomson 0 legacy scanner scan_devices ``` --- url: /developers/blog/2026-04-21-registering-custom-dashboard-strategies.md --- 从 Home Assistant 2026.5 开始,你现在可以注册自定义 dashboard strategies,就像你可以使用 [custom cards](/developers/frontend/custom-ui/custom-card.md) 一样,在 **Community dashboards** 部分下通过 **新的 dashboard** 对话框更容易地发现并添加它们。 以前,你必须引导用户创建一个空白 dashboard,在 YAML 模式下编辑,然后粘贴你的自定义 strategy。现在你可以注册一个友好的名称、描述和文档。 要注册你的 strategy,用包含以下 keys 的对象调用 `window.customStrategies.push()`: * `type`:不带 `custom:` 前缀的 strategy type,例如 `"my-demo"`。 * `strategyType`:设置为 `"dashboard"` 以注册 dashboard strategy。 * `name`:strategy 的友好名称。 * `description`(可选):strategy 的简短描述。 * `documentationURL`(可选):指向 strategy 文档的 URL。目前在 strategy UI 中不会显示,但将来可能会显示。 示例: ```js window.customStrategies = window.customStrategies || []; window.customStrategies.push({ type: "my-demo", strategyType: "dashboard", name: "My demo dashboard", description: "A starter dashboard generated from JavaScript.", documentationURL: "https://example.com/my-demo-dashboard", }); ``` 此元数据独立于自定义元素本身。你的 strategy 仍然需要用类似 `ll-strategy-dashboard-my-demo` 的 tag 注册,用户仍然需要在 Home Assistant 发现它之前加载该资源。你可以为此使用 HACS,因为像 custom cards 一样,其他资源也可以添加。 查看更新后的 [custom strategies](/developers/frontend/custom-ui/custom-strategy.md) 文档,其中包含示例代码和更多详情。 --- url: /developers/blog/2026-04-24-radio-frequency-entity-platform.md --- Home Assistant 现在有了一个 `radio_frequency` entity platform,它将 RF 收发器硬件与所控制的设备解耦。每个设备集成不再直接与特定 RF 硬件通信,而是由发射器集成(如 `esphome`)暴露 `RadioFrequencyTransmitterEntity` 实例,设备集成通过 helper 函数向其发送命令。 这与 [`infrared` entity platform](/developers/blog/2026-03-30-infrared-entity-platform.md) 类似,并已在 [architecture discussion #1365](https://github.com/home-assistant/architecture/discussions/1365) 中获得批准。 ## 架构 `radio_frequency` domain 位于两类集成之间: * **发射器集成**(ESPHome、Broadlink 等)实现 `RadioFrequencyTransmitterEntity` base class 以提供特定硬件的 RF 传输。 * **消费方集成**(车库门开启器、RF 遥控器、无线开关等)使用 helper 函数通过可用的发射器发送特定设备的 RF 命令。 用户在消费方集成的 config flow 期间选择要使用哪个发射器,并根据设备的工作频率进行筛选。 ## 实现一个发射器集成 发射器集成通过继承 `RadioFrequencyTransmitterEntity`、声明其 `supported_frequency_ranges` 并实现 `async_send_command` 来提供 `radio_frequency` platform: ```python from rf_protocols import RadioFrequencyCommand from homeassistant.components.radio_frequency import RadioFrequencyTransmitterEntity class MyRadioFrequencyTransmitterEntity(RadioFrequencyTransmitterEntity): """My RF transmitter.""" @property def supported_frequency_ranges(self) -> list[tuple[int, int]]: """Return the list of (min_hz, max_hz) ranges this hardware can transmit on.""" return [(300_000_000, 348_000_000), (433_050_000, 434_790_000)] async def async_send_command(self, command: RadioFrequencyCommand) -> None: """Send an RF command.""" await self._device.transmit( frequency=command.frequency, modulation=command.modulation, timings=command.get_raw_timings(), ) ``` Base class 会将最后发送命令的时间戳作为 entity state 跟踪,因此发射器集成只需处理实际传输。 ## 构建消费方集成 消费方集成通过向发射器 entity 发送命令来控制 RF 设备。它们不直接与 RF 硬件交互。下面的代码片段改编自 [`honeywell_string_lights`](https://github.com/home-assistant/core/pull/168450) 集成,该集成使用此 platform 驱动一套 Honeywell String Lights。 **1. 在 `manifest.json` 中声明依赖**: ```json { "dependencies": ["radio_frequency"] } ``` **2. 从 [`rf-protocols`](https://github.com/home-assistant-libs/rf-protocols) 库加载设备的命令**: ```python from rf_protocols import get_codes COMMANDS = get_codes("honeywell/string_lights") ``` 每个加载的命令会暴露设备使用的频率和调制方式,config flow 需要用这些信息筛选发射器。 **3. 在 config flow 中让用户选择发射器**,使用样本命令根据设备所需的频率和调制方式进行筛选: ```python from rf_protocols import RadioFrequencyCommand from homeassistant.components.radio_frequency import async_get_transmitters from homeassistant.exceptions import HomeAssistantError sample_command: RadioFrequencyCommand = await self.hass.async_add_executor_job( COMMANDS.load_command, "turn_on" ) try: transmitters = async_get_transmitters( self.hass, sample_command.frequency, sample_command.modulation ) except HomeAssistantError: return self.async_abort(reason="no_transmitters") if not transmitters: return self.async_abort(reason="no_compatible_transmitters") ``` 目前只支持 `ModulationType.OOK`(on-off keying),后续版本可以添加其他调制方式。 **4. 使用 helper 函数和存储的发射器 entity ID 发送 RF 命令**: ```python from homeassistant.components.radio_frequency import async_send_command async def async_turn_on(self, **kwargs: Any) -> None: """Turn on the light.""" command = await self.hass.async_add_executor_job( COMMANDS.load_command, "turn_on" ) await async_send_command(self.hass, self._transmitter, command) self._attr_is_on = True self.async_write_ha_state() ``` ## RF 协议和 codes RF protocol 编码器及设备 code 集合存放在 Home Assistant 之外的 [`rf-protocols`](https://github.com/home-assistant-libs/rf-protocols) 库中。常见协议和知名设备 codes 应贡献到那里。对于小众或专有协议,也可以使用单独的第三方库。 更多详情,请参阅 [radio frequency entity 文档](/developers/core/entity/radio-frequency.md)。 --- url: /developers/blog/2026-04-27-pyserial-to-serialx.md --- 与 serial port 通信的现有集成和库应从 `pyserial`、`pyserial-asyncio` 和 `pyserial-asyncio-fast` 迁移到 [`serialx`](https://github.com/puddly/serialx)。这个新库在所有平台上都原生支持 asyncio,将使你的集成和库能够利用 Home Assistant 中的 [ESPHome serial proxies](https://esphome.io/components/serial_proxy/),并包含对 asyncio event loop 稳定性的关键修复。 ## 背景 多年来,`pyserial` 一直是 Python 中的事实标准 serial 库,并对所有流行平台有广泛支持。然而,其 API 早于 Python 中的 asyncio,且仅支持 sync。后来发布了 `pyserial-asyncio` 包以桥接 `pyserial` 与 asyncio。不幸的是,`pyserial-asyncio` 的开发从未达到 1.0 稳定性或跨平台支持,而且 `pyserial` 和 `pyserial-asyncio` 在近五年内都没有 PyPI 发布。我们 fork 了 `pyserial-asyncio` 并发布了 [`pyserial-asyncio-fast`](/developers/blog/2026-01-05-pyserial-asyncio-fast.md),以修复影响 Core event loop 稳定性的未解决问题。 我们从零开发了 `serialx`,作为一个现代的 Python serial 库,具有原生的 sync 和 async APIs。它与 `serial`、`serial_asyncio` 和 `serial_asyncio_fast` 模块兼容,允许现有包以极少的变更(如果有的话)进行迁移。 ## 迁移 `serialx` 文档有一个 [详尽的迁移指南](https://puddly.github.io/serialx/how-to/pyserial-migration.html),提供了更多细节。 大多数包只需在 `setup.py` 或 `pyproject.toml` 文件中用 `serialx` 替换 `pyserial`、`pyserial-asyncio` 和 `pyserial-asyncio-fast`,并更新异常处理,将宽泛捕获 `SerialException` 替换为更细粒度的错误处理(如 `OSError` 和 `TimeoutError`)。 直接构造 sync `serial.Serial()` 对象的包应迁移到使用 `serialx.serial_for_url()` helper,以确保自动兼容所有支持的协议。 ### 给 agent 的 prompt 迁移本身是机械性的,将以下指令粘贴到你选择的 agent 中: > 将我的代码从 pyserial、pyserial-asyncio 和 pyserial-asyncio-fast 迁移到 serialx,使用 > https://raw.githubusercontent.com/puddly/serialx/refs/heads/dev/docs/how-to/pyserial-migration.md --- url: /developers/blog/2026-05-04-frontend-component-updates-2026.5.md --- ## 组件更新 ### ha-progress-bar 一个新的 component 替换了我们 codebase 中的 `mwc-progress-bar`,并且完全可主题化。查看这个 [PR](https://github.com/home-assistant/frontend/pull/51489) 了解一个完全自定义的 progress bar。 新的 component 特定 tokens: ```css --ha-progress-bar-indicator-color --ha-progress-bar-indicator-background --ha-progress-bar-track-color --ha-progress-bar-track-height --ha-progress-bar-border-radius --ha-progress-bar-animation-duration --ha-progress-bar-indicator-highlight-image --ha-progress-bar-indicator-highlight-width --ha-progress-bar-indicator-highlight-height ``` ### ha-switch `ha-switch` 已迁移到 webawesome。它现在有很多 CSS properties 以方便自定义。我们还移除了旧 switch 中的一些 tokens: 已移除的 tokens: ```css --switch-unchecked-button-color --switch-unchecked-track-color --switch-unchecked-color --switch-checked-button-color --switch-checked-track-color --switch-checked-color ``` 新的 component 特定 tokens: ```css --ha-switch-size --ha-switch-thumb-size --ha-switch-width --ha-switch-background-color --ha-switch-thumb-background-color --ha-switch-background-color-hover --ha-switch-thumb-background-color-hover --ha-switch-checked-background-color --ha-switch-checked-thumb-background-color --ha-switch-checked-background-color-hover --ha-switch-checked-thumb-background-color-hover --ha-switch-border-color --ha-switch-thumb-border-color --ha-switch-thumb-border-color-hover --ha-switch-checked-border-color --ha-switch-checked-thumb-border-color --ha-switch-checked-border-color-hover --ha-switch-checked-thumb-border-color-hover --ha-switch-thumb-box-shadow --ha-switch-disabled-opacity --ha-switch-required-marker --ha-switch-required-marker-offset ``` ### ha-checkbox `ha-checkbox` 也已迁移到 webawesome,并获得了新的 CSS properties。你不再能为其使用 MDC tokens,但我们添加了一组 tokens 来自定义新的 checkbox。 新的 component 特定 tokens: ```css --ha-checkbox-size --ha-checkbox-border-color --ha-checkbox-border-color-hover --ha-checkbox-background-color --ha-checkbox-background-color-hover --ha-checkbox-checked-background-color --ha-checkbox-checked-background-color-hover --ha-checkbox-checked-icon-color --ha-checkbox-checked-icon-scale --ha-checkbox-border-radius --ha-checkbox-border-width --ha-checkbox-required-marker --ha-checkbox-required-marker-offset ``` ### ha-textarea `ha-textarea` 已迁移到 webawesome,并获得了新的 CSS properties。你不再能为其使用 MDC tokens,但我们添加了一组 tokens 来自定义新的 textarea。 API 有细微变化。要使你的 textarea 自动增大尺寸,将 `resize` prop 设置为 `auto`。 ### ha-adaptive-popover 你可能已经知道(比较新的)`ha-adaptive-dialog` component。它通过结合 dialog 和 bottom sheet 来实现,在桌面端显示 dialog,在移动端显示 bottom sheet。 我们添加了 `ha-adaptive-popover` 作为 adaptive dialog 的 popover 对应组件。它在桌面端显示 popover,在移动端显示 bottom sheet。它基于 `ha-adaptive-dialog`,目前用于 tile card 的 date picker 功能。 ### 移除 ha-fab `ha-fab` 已被移除,我们现在直接使用普通的 `ha-button`,因为 position 样式一直是由父级 component 完成的。 ## 样式更新 ### Box shadow 令牌 我们添加了新的全局 box shadow tokens:`--ha-box-shadow-s`、`--ha-box-shadow-m`、`--ha-box-shadow-l` 但我们也移除了旧的 box shadow tokens: ```css --ha-color-shadow-light --ha-color-shadow-dark --ha-shadow-offset-x-... --ha-shadow-blur-... --ha-shadow-spread-.. ``` ### 表面颜色 在下一个版本中,我们计划改变处理 surface 背景颜色的方式。Tokens 现已引入,但目前仅用于 ha-tooltip。 新的 tokens: ```css --ha-color-surface-default --ha-color-surface-low --ha-color-surface-lower --ha-color-surface-default-inverted --ha-color-surface-low-inverted --ha-color-surface-lower-inverted ``` --- url: /developers/blog/2026-05-04-frontend-context-groups-decorators.md --- 上个版本我们引入了 lazy context,我们希望在传递 hass 对象方面更多地使用 hass context 和 lazy context。我们发现一些小任务经常需要订阅很多 contexts,因此我们将 Hass contexts 分组为逻辑组。 ## 上下文组 新增以下 context groups: * registriesContext:包含所有 registries(device、entity、area 等) * internationalizationContext:包含所有 internationalization 相关数据(locale、localize 等) * apiContext:包含所有 API 相关方法(callService、callWS 等) * connectionContext:包含所有 connection 相关数据(connection、connected、hassUrl 等) * uiContext:包含所有 UI 相关数据(themes、panels、dockedSidebar 等) * configContext:包含所有 config 相关数据(auth、config、user 等) ## 消费上下文条目装饰器 在上一篇 [blogpost](/developers/blog/2026-03-25-frontend-lazy-context.md) 中,我展示了如何使用 `@transform` 与 context 配合。`@transform` 功能强大,但有时你只需要一个 context entry,并不想定义 transform 函数。 为此,我们添加了直接消费单个 context entry 的 decorators。 你传入一个定义 entity ID 来源的数组(通常是 config 属性),decorator 会消费正确的 context 并将 entity ID 映射到正确的 registry entry。 它还会监视定义的路径,并在需要时更新 entry。 新的 decorators: * @consumeEntityState * @consumeEntityStates * @consumeEntityRegistryEntry 使用示例: ```ts @state() @consumeEntityRegistryEntry({ entityIdPath: ["_config", "entity"] }) _entity?: EntityRegistryDisplayEntry; ``` 我们将来可能会添加更多这类 decorators,例如用于 areas、devices 等。 ## 弃用 contexts 以下 contexts 仍然可用,但可能在未来版本中被移除。请使用新的 context groups 替代。 * connectionSingleContext * localizeContext * localeContext * configSingleContext * themesContext * selectedThemeContext * userContext * userDataContext * panelsContext * authContext --- url: /developers/blog/2026-05-07-config-entry-listener-together-with-reloading-methods.md --- 从 Home Assistant Core 2026.6 开始,在 config flow 中将 config entry listener 与任何 reloading methods 一起使用已被弃用,并将在 2026.12 产生错误。 ## 背景 在 config flow 中将 config entry listener 与任何 reloading methods 一起使用,可能导致集成重新加载两次和/或产生 race condition。 ## 可能的解决方案 * 移除 config entry listener,只依赖 config flow 中的 reloading methods。 * 用 `async_update_and_abort()` 替代 `async_update_reload_and_abort()`。 * 在调用 `_abort_if_unique_id_configured()` 时设置 `reload_on_update=False`。 更多详情可在 [core PR](https://github.com/home-assistant/core/pull/169198) 中找到。 --- url: /developers/blog/2026-05-11-format-entity-name-helper.md --- 从 Home Assistant 2026.4 开始,`hass` 对象暴露了一个 `formatEntityName` helper。这是内置卡片(tile card、entity rows 等)用来从 entity 的 registry 上下文(entity、device、area、floor)计算其显示名称的同一函数。自定义卡片可以使用它,以产生与 dashboard 其余部分保持一致的名称。 给定一个名为 `Temperature` 的温度传感器,位于一个名为 `Thermostat` 的设备上: ```js const stateObj = hass.states["sensor.living_room_thermostat_temperature"]; hass.formatEntityName( stateObj, [{ type: "device" }, { type: "entity" }], { separator: " · " } ); // "Thermostat · Temperature" ``` Frontend 还提供了一个 `entity_name` selector。如果你的卡片使用了 [内置 form editor](/developers/frontend/custom-ui/custom-card.md#using-the-built-in-form-editor),你可以向用户提供与内置卡片相同的名称选择器——接受自由格式的字符串或 registry items 的组合。 查看更新后的 [data 文档](/developers/frontend/data.md#hassformatentitynamestateobj-name-options),了解完整的参考和更多示例。 --- url: /developers/blog/2026-05-11-mqtt-publish-api-changes.md --- 将来,MQTT publish API 将要求为 `qos` 和 `retain` 显式提供值。对这两个参数传递 `None` 将不再受支持。 自定义集成应更新代码以接受默认值,或传递有效的 typed arguments。 `qos` 和 `retain` 从 `None` 回退到有效值的功能将在 HA Core 2027.6 中停止工作。 新的 API 签名为: ```python def publish( hass: HomeAssistant, topic: str, payload: PublishPayloadType, qos: int = 0, retain: bool = False, encoding: str | None = DEFAULT_ENCODING, ) -> None: """Publish message to a MQTT topic.""" hass.create_task(async_publish(hass, topic, payload, qos, retain, encoding)) ``` 以及 ```python async def async_publish( hass: HomeAssistant, topic: str, payload: PublishPayloadType, qos: int = 0, retain: bool = False, encoding: str | None = DEFAULT_ENCODING, ) -> None: """Publish message to a MQTT topic.""" ``` --- url: /developers/blog/2026-05-11-mqtt-publish-api-message-expiry-interval.md --- MQTT publish API 现在支持设置 message expiry interval。 以前,保留消息会存储在 broker 中,直到被替换或显式清除。设置了 `message_expiry_interval`(以秒为单位)后,发布的消息——包括保留消息——将在指定间隔后自动过期。 此选项仅在使用 MQTT 协议版本 5 时受支持;在使用早期协议版本时会被忽略。 新的 API 签名为: ```python def publish( hass: HomeAssistant, topic: str, payload: PublishPayloadType, qos: int = 0, retain: bool = False, encoding: str | None = DEFAULT_ENCODING, *, message_expiry_interval: int | None = None, ) -> None: """Publish message to a MQTT topic.""" ``` 以及 ```python async def async_publish( hass: HomeAssistant, topic: str, payload: PublishPayloadType, qos: int = 0, retain: bool = False, encoding: str | None = DEFAULT_ENCODING, *, message_expiry_interval: int | None = None, ) -> None: """Publish message to a MQTT topic.""" ``` --- url: /developers/blog/2026-05-13-condition-script-api-changes.md --- ## 摘要 Condition 和 script APIs 已经发生变更。 Conditions 现在是 condition classes 的实例,通过调用 `async_check` 方法进行求值,通过调用 `async_unload` 方法进行丢弃。此外,conditions 可以选择性地实现 `_async_setup` 或 `_async_unload` 方法。注意,condition 的使用者无需调用 condition 的 `async_setup` 方法。 在弃用期间(以 Home Assistant Core 2027.1 的发布结束),可以像 callable 一样使用 condition 对象。 Scripts 也拥有一个 `async_unload` 方法,当不再需要脚本时必须调用它。 ## 对自定义集成的影响 ### 创建 conditions 或 scripts 的自定义集成 创建 condition 对象的自定义集成应通过调用 `async_check` 方法来求值,并在不再需要该 condition 时调用 `async_unload` 方法。 示例: ```python from homeassistant.helpers.condition import ( async_condition_from_config, async_validate_condition_config, ) # 验证 condition config validated_config = await async_validate_condition_config(hass, config) # 创建一个 condition condition = await async_condition_from_config(hass, validated_config) ... # 求值 condition result = condition.async_check(...) ... # 丢弃 condition condition.async_unload() ``` 创建 scripts 的自定义集成应在不再需要脚本时调用 `async_unload` 方法。 示例: ```python from homeassistant.helpers.script import ( Script, async_validate_actions_config, ) # 验证 script config validated_config = await async_validate_actions_config(hass, config) # 创建一个 script script = Script(hass, validated_config, ...) ... # 执行 script result = await script.async_run(...) ... # 丢弃 script await script.async_unload() ``` ### 提供 condition platform 的自定义集成 提供 condition platform 的集成无需更改,但如果 platform 需要执行 async 初始化或 teardown,可以实现 `_async_setup` 和 `_async_unload` 方法。 示例: ```python from homeassistant.core import HomeAssistant from homeassistant.helpers.condition import ( Condition, ConditionCheckParams, ConditionConfig, ) from homeassistant.helpers.typing import ConfigType class CustomCondition(Condition): """A custom condition.""" @classmethod async def async_validate_config( cls, hass: HomeAssistant, config: ConfigType ) -> ConfigType: """Validate config.""" ... def __init__(self, hass: HomeAssistant, config: ConditionConfig) -> None: """Initialize condition.""" super().__init__(hass, config) ... async def _async_setup(self) -> None: """Set up the condition checker.""" ... def _async_unload(self) -> None: """Clean up any resources held by the checker.""" ... def _async_check(self, **kwargs: Unpack[ConditionCheckParams]) -> bool: """Check the condition.""" ... ``` --- url: /developers/blog/2026-05-20-browse-media-source-root-class.md --- `media_source` 集成中的 `BrowseMediaSource` class 已加强限制。`domain` 参数现在是一个必需的 `str`,而不是 `str | None`,特殊的"列出所有 media source"的 root node 已移动到它自己的 class `RootBrowseMediaSource` 中。 以前,`domain` 之所以可选,只是为了表示一种边界情况:在浏览 `media-source://` 且未选择特定 source 时返回的顶层 node。这使得类型提示对 99% 的情况来说具有误导性——每个实际的 media source 都有一个 domain——并且增加了一个消费者需要考虑的 `None` 分支。将 root 拆分到单独的 class 中移除了该分支。 ## 变更内容 * `BrowseMediaSource.__init__` 现在需要 `domain: str`。 * 新的 `RootBrowseMediaSource` class 表示列出所有可用 media sources 的 root browse node。它硬编码 `domain=None` 和 `identifier=None`,并使用 `media-source://` 作为其 content ID。 * `media_source.async_browse_media()` 和 `MediaSourceItem.async_browse()` 现在返回 `BrowseMediaSource | RootBrowseMediaSource`。 ## 对自定义集成的影响 大多数集成无需任何更改。如果你实现了 `media_source.py` platform,你已经在向 `BrowseMediaSource` 传递自己的 `domain`——这将继续工作。 你只有在以下情况下才需要采取行动: * **你将 `domain=None` 传递给 `BrowseMediaSource`。** 这不再被允许。改为设置你的集成 domain。 * **你调用 `media_source.async_browse_media()` 并为结果添加了类型注解。** 将类型提示更新为 `BrowseMediaSource | RootBrowseMediaSource`,或者在使用 domain 特定属性之前用 `isinstance()` 进行收窄: ```python from homeassistant.components.media_source import ( BrowseMediaSource, async_browse_media, ) result = await async_browse_media(hass, media_content_id) if isinstance(result, BrowseMediaSource): # 在这里 result.domain 保证是 str ... ``` 更多详情,请参阅更新后的 [media source platform 文档](/developers/core/platform/media_source.md)。 --- url: /developers/blog/2026-05-26-advanced-mode-config-flow-deprecation.md --- ## 摘要 用户资料中的 [advanced mode 即将移除](https://github.com/OpenHomeFoundation/roadmap/issues/54),这意味着集成再也不能在 data entry flows 中检查 advanced mode 是否已启用。 集成作者需要更新集成,在 UI 中使用替代的用户友好方式来展示额外选项,例如将额外选项分组到一个 section 中。 ### `FlowHandler.show_advanced_options` `FlowHandler.show_advanced_options` 属性已被弃用,并将在 Home Assistant Core 2027.6 发布时移除。在弃用期间,`FlowHandler.show_advanced_options` 无条件返回 `True`,以避免由该 flag 控制选项的用户无法访问。 ### `FlowHandler.context['show_advanced_options']` `FlowHandler.context` 中不再存在 `show_advanced_options` key。 ## 背景 用户资料中的 Advanced mode 开关是一个单一的 binary 开关,它控制着 Home Assistant 中一系列不相关功能的集合,从 app(add-on)可见性(Terminal & SSH)到配置选项和 UI 元素,我们在过去一年中一直在着手移除它。 更详细的解释,请参阅 [roadmap issue #54](https://github.com/OpenHomeFoundation/roadmap/issues/54)。 --- url: /developers/blog/2026-05-27-custom-card-suggestions.md --- 从 Home Assistant 2026.6 开始,自定义卡片可以作为建议显示在 card picker 中。当用户选择一个 entity 时,选择加入的自定义卡片会显示在内置建议下方的 **Community** 部分下。 要加入,在你的 `window.customCards` 条目中添加一个 `getEntitySuggestion` 函数。它接收 `hass` 对象和被选中的 entity id,并返回一个建议(如果该 entity 不受支持则返回 `null`): ```js window.customCards.push({ type: "my-card", name: "My Card", getEntitySuggestion: (hass, entityId) => { if (entityId.split(".")[0] !== "light") { return null; } return { config: { type: "custom:my-card", entity: entityId }, }; }, }); ``` 你也可以返回一个建议数组,以提供多个变体,每个变体都有自己的 `label`。 仅当卡片对该 entity 有意义时才建议你的卡片。使用 `hass` 对象检查 domain、device class 或 supported features,否则返回 `null`。为每个 entity 都建议你的卡片会使 picker 变得杂乱。 更多详情,请参阅 [custom card 文档](/developers/frontend/custom-ui/custom-card.md#suggesting-your-card-for-an-entity)。 --- url: /developers/blog/2026-05-27-frontend-component-updates-2026.6.md --- ## 组件更新 ### ha-radio updates `ha-radio` 已从我们的 codebase 中移除,我们现在使用基于 webawesome 的 `ha-radio-group` 配合 `ha-radio-option`。不再需要在 `ha-radio` 周围使用 `ha-formfield`,你可以使用新的 CSS properties 自定义 radio group 和 options。 新的 component 特定 tokens: ```css --ha-radio-group-required-marker --ha-radio-group-required-marker-offset --ha-radio-option-active-color --ha-radio-option-heigh --ha-radio-option-toggle-size --ha-radio-option-border-width --ha-radio-option-border-color --ha-radio-option-border-color-hover --ha-radio-option-background-color --ha-radio-option-background-color-hover --ha-radio-option-checked-background-color --ha-radio-option-checked-icon-color --ha-radio-option-checked-icon-scale --ha-radio-option-control-margin ``` ### ha-drawer updates `ha-drawer` 已更新为使用 webawesome drawer component。API 基本相同,只是现在使用 `--ha-sidebar-width` 而不是 `--mdc-drawer-width`。 ### top bar * `ha-top-app-bar` 已被完全移除。 * `ha-top-app-bar-fixed` 已从 MWC 迁移到纯 Lit。 * `ha-two-pane-top-app-bar-fixed` 已重写为扩展新实现,而不是 Material base code。 * `ha-header-bar` 已从 Material top-app-bar 样式包装器重写为原生 Lit component。 `--ha-top-app-bar-width` token 替换了 `--mdc-top-app-bar-width`。 ## 新装饰器 ### @consumeLocalize 继上个版本介绍的 [context entry decorators](/developers/blog/2026-05-04-frontend-context-groups-decorators.md) 之后,我们为从 `internationalizationContext` 读取最常见的单个字段——`localize` 函数——添加了一个快捷方式。 之前: ```ts @state() @consume({ context: internationalizationContext, subscribe: true }) @transform({ transformer: ({ localize }) => localize, }) private _localize!: LocalizeFunc; ``` 之后: ```ts @state() @consumeLocalize() private _localize!: LocalizeFunc; ``` 当 component 只需要 `localize` 函数时,使用 `@consumeLocalize()`。对于从 `internationalizationContext` 读取的其他单字段(例如 `locale`、`language`),继续使用 `@consume` + `@transform`。 --- url: /developers/blog/2026-06-15-device-tracker-changes.md --- ## 摘要 Device tracker entity model 最近发生了多项变更: * `battery_level` 属性已弃用 * `TrackerEntity` 的 `location_name` 属性已弃用 * 引入了新的 entity base class `BaseScannerEntity` * 用户可以将 scanners 与 home zone 之外的其他 zones 关联 * `TrackerEntity` 有一个新的 `in_zones` 属性 * `BaseScannerEntity` 和 `ScannerEntity` 有一个新的 state 属性 `in_zones` * 引入了新的 capability 属性 `tracking_type` * 计算 `TrackerEntity` 的 state 时,zones 现在按大小计算,再按到中心的距离计算 ## 详情 ### `battery_level` 的弃用 `battery_level` 属性已在所有 device tracker base classes 中弃用,并将在 Home Assistant Core 2027.7 中停止工作。集成应通过 battery sensor 来传达电池电量。 更多详情可在 [architecture proposal #627](https://github.com/home-assistant/architecture/discussions/627) 中找到 ### `location_name` 的弃用 `TrackerEntity` 的 `location_name` 属性已弃用,并将在 Home Assistant Core 2027.7 中停止工作。 拥有 device trackers 且不知道或不希望报告精确坐标、目前使用 `location_name` 报告 zone 名称的集成,应改为通过 `in_zones` 属性报告一组 zone entity IDs。 使用 `location_name` 提供额外上下文的 device trackers,可以通过单独的 sensor 或额外的 state 属性来实现。 更多详情可在 [architecture proposal #1387](https://github.com/home-assistant/architecture/discussions/1387) 中找到 ### `BaseScannerEntity` base class 的引入 [`BaseScannerEntity`](/developers/core/entity/device-tracker.md#basescannerentity) class 应被拥有 scanner 但不追踪与 WLAN 或其他本地网络连接状态的集成使用,例如追踪与 BLE beacon 连接的 scanners。 ### 用户可以将 `BaseScannerEntity` 和 `ScannerEntity` 与任意 zone 关联 `BaseScannerEntity` 和 `ScannerEntity` 将关联的 zone 作为 entity registry option 存储。Base class 会在连接时将 entity 的 state 设置为关联 zone 的名称,并将 `in_zones` state 属性设置为包含关联 zone 的所有 zones。 更多详情可在 [architecture proposal #1389](https://github.com/home-assistant/architecture/discussions/1389) 中找到 ### `in_zones` state 属性的引入 Device tracker entities 的 state 中有一个新的 state 属性 `in_zones`。该 state 属性由 `BaseScannerEntity` 和 `ScannerEntity` 自动计算。`TrackerEntity` 如果 `in_zones` 属性不为 `None`,将从 [`in_zones` 属性](https://developers.home-assistant.io/docs/core/entity/device-tracker#properties-2) 派生出 `in_zones` state 属性,如果为 `None`,则从报告的位置计算。 `in_zones` state 属性是一个 zone entity IDs 的列表,按大小排序,最小的 zone 在前,然后按到中心的距离排序。 ### `tracking_type` capability 属性的引入 Device tracker entities 的 state 中有一个新的 capability 属性 `tracking_type`。该 state 属性由 `BaseScannerEntity` 和 `ScannerEntity` 设置为 `connection`,由 `TrackerEntity` 设置为 `location`。集成不应覆盖此行为。 --- url: /developers/blog/2026-06-23-frontend-component-updates-2026.7.md --- ## 组件更新 ### Component sizes 使用 Web Awesome 名称 `ha-button`、`ha-button-toggle-group` 和 `ha-slider` 现在使用简短的 Web Awesome size 名称。 对于 `ha-button`,使用: ```html Save ``` 支持的值是 `xs`、`s`、`m`、`l` 和 `xl`。 对于 `ha-button-toggle-group`,使用 `s` 或 `m`: ```html ``` `ha-slider` 使用 `s` 或 `m`。 如果你的自定义卡片或 editor 仍然在这些 components 上使用 `small`、`medium` 或 `large`,请将它们迁移到 `s`、`m` 或 `l` 等简短值。 ### 虚拟列表 我们添加了两个用于大数据集的 list components: * `ha-list-virtualized` * `ha-list-selectable-virtualized` 当 picker 或 dialog 能够渲染足够多行从而影响到滚动或初始渲染时间时使用它们。Virtualized list 仅渲染可见行,同时保留 `ha-list-base` 的 roving-tabindex 键盘导航。 Rows 通过 `aria-setsize` 和 `aria-posinset` 暴露 accessibility metadata,因此辅助技术仍然能获得完整的 list 位置,即使只有部分 list 在 DOM 中。 对于可选择的 lists,渲染 `ha-list-item-option` rows。 ## Context 和 editor 基础设施 ### Dirty state 跟踪 Dialogs 和 editors 现在有共享的 dirty-state 基础设施: * `DirtyStateProviderMixin` * `dirtyStateContext` * `isDirtyState` * `isEffectiveDirtyState` 对于需要阻止 scrim 关闭、仅在编辑后启用 Save、或与子 components 协调 dirty state 的新 dialogs 或 editors,使用 `DirtyStateProviderMixin`。 ```ts class MyDialog extends DirtyStateProviderMixin()(LitElement) { public openDialog() { this._initDirtyTracking({ type: "shallow" }, this._state); } private _stateChanged(state: MyState) { this._updateDirtyState(state); } } ``` `isDirtyState` 是原始比较,通常适用于启用 Save。`isEffectiveDirtyState` 可以忽略等效的 config 输出,例如当 editor 将显式默认值规范化为相同的有效 config 时。 ### 相关上下文 Pages 和 editors 现在可以为附近的 pickers 发布 related context: * `relatedContext` * `fireRelatedContext` * `fireEntityRelatedContext` 当 card editor、badge editor、automation trace page 或类似表面知道当前的 entity、device 或 area 时,它可以提供该 context。Entity pickers 和 add-element searches 然后可以优先考虑相关的 entities、devices 和 areas。 ```ts fireEntityRelatedContext(this, "light.kitchen"); ``` 当 editor 不再有 related item 时,用 `undefined` 清除 context。 ### 窄视口上下文 `narrowViewportContext` 暴露主 Home Assistant viewport 是否处于 narrow layout。 只需要 narrow-layout state 的 components 可以消费此 context,而不是通过多层 properties 接收 `narrow`。 ```ts @consume({ context: narrowViewportContext, subscribe: true }) private _narrow!: boolean; ``` ## Lovelace 更新 ### Strategy regeneration 控制 Lovelace strategies 现在可以避免不必要的 regeneration。 Strategies 可以声明 `registryDependencies` 以仅对它们依赖的 registries 使用默认的 reference-change 检查: ```ts static registryDependencies = ["entities", "areas"] as const; ``` 对于自定义逻辑,实现 `shouldRegenerate()`: ```ts static shouldRegenerate(config, oldHomeAssistant, newHomeAssistant) { return oldHomeAssistant.entities !== newHomeAssistant.entities; } ``` 如果两者都未提供,strategies 保持先前的默认行为,并在 entities、devices、areas 或 floors 发生变更时重新生成。 --- url: /developers/blog/2026-06-30-async-initialize-triggers-home-assistant-start-deprecated.md --- `async_initialize_triggers` 的专用 `home_assistant_start` flag 已弃用,并将在 Home Assistant Core 2027.8 中移除。在弃用期间,该参数不再有任何效果。 该 flag 之所以存在,是因为 `homeassistant` start trigger 是一个伪 trigger:它不像真正的 trigger 那样运作,而是依赖于触发器 API 的调用者传递 `home_assistant_start=True`,以便 `async_initialize_triggers` 在启动期间触发该 trigger。 Start trigger 已被重写为像真正的 trigger 一样工作,因此不再需要该 flag。`async_initialize_triggers` 的调用者只需停止传递 `home_assistant_start` 即可。 为了使新实现成为可能,重写添加了 `HomeAssistant.async_add_startup_job`,它注册一个 job,该 job 将在所有对 `EVENT_HOMEASSISTANT_START` 的 listeners 执行之后、但在 `EVENT_HOMEASSISTANT_STARTED` 触发之前被调用。这镜像了已用于 homeassistant shutdown trigger 的方法,并避免了在 core states 和 events 之间已复杂的关 系中再添加另一个 core state 和 event。 更多详情,请参阅 [core PR 175160](https://github.com/home-assistant/core/pull/175160)。 --- url: /developers/blog/2026-06-30-new-unit-enumerators.md --- 从 Home Assistant Core 2026.7 开始,以下 unit 常量已被弃用,并由相应的 enum 替代: * `UnitOfDensity` enumerator 替代了质量除以体积的 `CONCENTRATION_***` 常量 (`"g/m³"`、`"mg/m³"`、`"μg/m³"`、`"μg/ft³"`) * `UnitOfRatio` enumerator 替代了无单位的比率 `CONCENTRATION_***` 常量 (`"ppm"`、`"ppb"`) `CONCENTRATION_PARTS_PER_CUBIC_METER` 仅被单个集成使用,已弃用且没有替代 unit。 请注意,将 `PERCENTAGE` 常量用作测量单位时也已弃用,即使常量本身并未弃用。 --- url: /developers/blog/2026-07-03-media-source-search.md --- Media sources 现在可以实现搜索。通过在你的 `MediaSource` 中添加 `async_search_media` 方法,用户可以直接从 media browser 中搜索你的媒体。 ```python from homeassistant.components.media_player import SearchMedia, SearchMediaQuery async def async_search_media( self, item: MediaSourceItem, query: SearchMediaQuery ) -> SearchMedia: """Search media.""" results = [...] # list of BrowseMediaSource items return SearchMedia(result=results) ``` 要告诉 media browser 哪些 items 可以搜索,请在浏览时返回的 `BrowseMediaSource` items(通常是目录)上将 `can_search` flag 设置为 `True`。其他集成可以通过新的 `media_source.async_search_media` helper 触发搜索。 更多信息,请参阅[更新后的文档](/developers/core/platform/media_source.md#searching-media)。 --- url: /developers/blog/2026-07-05-modernizing-modbus.md --- :::info Update — 2026 年 7 月 16 日 我们正在重新评估本文中描述的方法的 Home Assistant 方面。基础保持不变:一切仍将围绕 [`modbus-connection`](https://home-assistant-libs.github.io/modbus-connection/) PyPI 包构建,基于它构建的设备库仍然是正确的投资。我们重新思考的是连接在 Home Assistant 本身内部的呈现方式,我们希望专注于能够产生更好的用户体验。如果你正在开发设备集成,请暂缓将其连接到下面描述的 `modbus_connection` 集成——我们将很快在此分享更新后的方法。 ::: Modbus 无处不在地出现在现代家庭中:太阳能逆变器、电表、热泵以及各种进入室内的工业设备。Home Assistant 长期以来通过基于 YAML 的 `modbus` 集成来支持这些设备,用户在其中手写 register maps 配置。该集成不会消失,现有配置将继续工作。但手写 register maps 将理解设备协议的负担加在了每个用户身上,而且它不符合 Home Assistant 其他部分所采取的 config-flow、UI 优先方向。 因此我们添加了一种使用 Modbus 的新方式:基于集成的方法,设备集成拥有设备特定知识,用户只需在 UI 中选择设备,就像任何其他集成一样。 ## 共享连接 Modbus 连接是一个单一的、独占的资源:同一时间只能有一方在总线上通信。一个串行(RS-485)总线,或一个 TCP-to-serial 网关,可以同时承载多个设备,有时来自不同的制造商。如果两个集成各自向同一总线打开自己的连接,它们就会争夺总线,而从历史上看,Home Assistant 完全不支持在集成之间共享总线。 新的 [`modbus_connection`](https://github.com/home-assistant/core/tree/dev/homeassistant/components/modbus_connection) 集成通过将连接变成设备集成路由通过而不是拥有的东西来解决这个问题。用户在 UI 中设置一次连接,`modbus_connection` 保持其打开并管理其生命周期,包括在断线后重新连接。设备集成则从该共享连接中借用所需内容,而不是管理自己的连接。我们重新编写了 [Modbus 开发者文档](/developers/modbus/introduction.md) 来介绍其工作原理,并附带示例代码。 ## 独立库 `modbus_connection` 底层的连接抽象位于 [`modbus-connection`](https://home-assistant-libs.github.io/modbus-connection/),这是我们为此目的设计并发布在 PyPI 上的新库。它不绑定于 Home Assistant,可以在任何 Python 项目中独立使用。它提供一个通用的、与后端无关的接口,因此设备库作者无需考虑底层 Modbus 实现,只需针对一个 API 编写代码,它随附设备建模框架和 `pytest` 插件,使构建和测试设备库变得简单。 这将关注点保持在它们所属的位置。设备库是一个普通的 PyPI 包,知道如何与特定设备通信,而 Home Assistant 中的消费方集成将该库连接到共享连接并暴露 entities。两者都可以独立开发和测试。 更多背景,请参阅我们的[研究](https://gist.github.com/balloob/b9fa91ba1a0914a9787f8f6ceb637b83)。 ## 开始构建 有了这些新的构建模块,现在可以将一组 Modbus 的 YAML 配置转换为可以通过 UI 设置的制造商特定集成。如果你(对)这项工作感兴趣,请到 [Home Assistant Discord 的 #modbus 频道](https://discord.com/channels/330944238910963714/1347329854495916044) 看看,我们很乐意提供帮助。 如果你正在使用 AI agent,可以给它以下 prompt: > 我想使用新的 Modbus Connection 集成为 Home Assistant 创建一个新集成,文档如下:https://developers.home-assistant.io/docs/modbus/introduction > > 我们想要转换为设备库的 YAML 可以在这里找到:*TODO INSERT LOCATION OF MODBUS YAML!* > > 本任务的交付物将是 3 个文件夹: > > * 首先基于 YAML 创建设备库。以 https://github.com/Tom-Bom-badil/trovis-modbus/ 作为确切示例,包括如何使用 component models、所有 GitHub Actions、helper scripts 和 README。该库作为独立设备库,不应提及 Home Assistant。查看 modbus\_connection 的源码以了解所有支持的字段。 > > * 创建一个可以贡献给 Home Assistant core 的集成,遵循这个示例:https://github.com/home-assistant/core/tree/trovis557x-integration/homeassistant/components/trovis557x > > * 创建一个自定义集成版本,将设备库 vendorize,使其可以通过 HACS 由社区测试。遵循此模板 https://github.com/ludeeus/integration\_blueprint --- url: /developers/blog/2026-07-20-ai-policy.md --- AI 辅助开发已经成为许多贡献者日常现实的一部分,对我们维护者来说也是如此。这可能是一件好事:AI 工具帮助人们编写代码、改进英语,并在不熟悉的 codebase 中找到方向。但它也有不利的一面:未经审核的 AI 输出作为贡献提交,会耗费维护者大量时间,而维护者时间是开源项目最稀缺的资源。 今天,我们发布了 [Open Home Foundation AI Policy](/developers/ai_policy.md)。它适用于所有 Open Home Foundation 项目,包括 `home-assistant` 和 `home-assistant-libs` GitHub 组织中的每个仓库。 该政策归结为几点: * AI 工具作为辅助是被欢迎的。你仍然对你提交的一切负责。 * 不允许自主 agent 贡献。自主创建的 pull requests 和 issues 将被关闭。 * 你必须理解并能够用自己的话解释你提交的每个变更。这包括自己回答维护者的问题,而不是让 AI 代劳。 * 使用 AI 改进你自己撰写的文本的语法或清晰度是可以的。对于非英语母语者来说这确实有用,我们感谢这种努力。 我们正在将政策推广到两个组织中的每个仓库。每个仓库在其根目录获得一个 `AI_POLICY.md` 文件,现有的贡献指南和 `AGENTS.md` 文件将新增对其的引用,使人类和他们的 AI 工具都了解我们的期望。 在[开发者文档](/developers/ai_policy.md)中阅读完整政策。如果贡献不符合该政策,它将被关闭。如果你认为你的贡献被错误地这样处理,请联系维护者,我们会解决。 --- url: /developers/blog/2026-07-21-device-registry-single-config-entry.md --- ## 摘要 Device 现在由单个 config entry 拥有,并由单个(或无)config subentry 拥有。Devices 不再跨集成合并:由多个集成支持的物理设备现在由每个 config entry 一个 device 表示,而不是单个共享 device。 以前绑定到多个 config entries 的 devices,在 device registry 加载时会被拆分为每个 config entry 一个 device。Entity registry 会被更新,使 entities 指向正确的 device。 **大多数集成不直接与 device registry 交互,无需任何更改。** 与它直接交互的集成需要处理下面列出的弃用。 此实现在 core [PR #175785](https://github.com/home-assistant/core/pull/175785) 中,原因在 architecture proposal [home-assistant/architecture#1226](https://github.com/home-assistant/architecture/discussions/1226) 中有描述。这些变更将在 Home Assistant Core 2026.8 中落地。 ## 背景 直到现在,由多个集成支持的物理设备会被合并为单个共享 device。这是通过以全局唯一的 connections 和 identifiers 来标识 devices 来实现的,因此例如 device tracker 和指向同一 MAC 地址的原生集成最终会落在同一个 device 上。 这导致了一些问题: * 对于 device 信息(如名称或型号)没有单一可信来源;冲突的值被丢弃而不是保留。 * 用户获得令人困惑的体验,device page 包含来自多个集成的 entity 大杂烩。 * 存在长期 bug,修改 device 的 connections 和 identifiers 会导致多个 devices 拥有相同的 connections,违反了 device registry 的原始设计。 新行为是通过使 identifiers 和 connections 在每个 config entry 中唯一,而不是全局唯一来实现的。 ## 弃用项 使用下面已弃用的功能会在运行时记录警告。除非另有说明,已弃用的功能将持续支持到 Home Assistant Core 2027.8。 ### `DeviceEntry.config_entries` 已弃用,改用 `DeviceEntry.config_entry_id`。该属性作为兼容 shim 保留,返回一个包含 device 单个 config entry 的 set。 ### `DeviceEntry.config_entries_subentries` 已弃用,改用 `DeviceEntry.config_entry_id` 和 `DeviceEntry.config_subentry_id`。该属性作为兼容 shim 保留。 ### `DeviceEntry.primary_config_entry` 已弃用,改用 `DeviceEntry.config_entry_id`。Device 现在属于单个 config entry,这就是它的 primary config entry。 ### 读取 composite device 的 config entries `DeviceEntry.config_entries`、`DeviceEntry.config_entries_subentries` 和 `DeviceEntry.primary_config_entry` 仅对普通 devices(属于单个 config entry)弃用。当与合成的 composite device(向后兼容解析为迁移前 composite device id 返回的只读 device,见[向后兼容](#向后兼容))交互时,它们并未弃用。此类 device 跨多个 config entries,而 `config_entry_id` 和 `config_subentry_id` 无法表示,因此这三个报告跨拆分 device 的并集的属性,仍然是读取该信息的方式。 ### `DeviceInfo["via_device"]` 和 `DeviceRegistry.async_get_or_create(via_device=...)` 已弃用,改用 `via_device_id`。由于 identifiers 在每个 config entry 中唯一,一个 identifier 对不再明确指向单个 device,这就是为什么 `via_device` 被弃用。 同时传递 `via_device` 和 `via_device_id` 会引发 `HomeAssistantError`。 ### `DeviceRegistry.async_update_device()` 的 config entry 参数 `add_config_entry_id`、`add_config_subentry_id`、`remove_config_entry_id` 和 `remove_config_subentry_id` 参数都已弃用。Device 属于单个 config entry 和 subentry,因此添加和移除 config entries 不再有意义;device 取而代之被移动或移除。 要将 device 移动到另一个 config entry 或 subentry,传递新的 `new_config_entry_id` 和 `new_config_subentry_id` 参数: ```py device_registry.async_update_device( device.id, new_config_entry_id=config_entry.entry_id, new_config_subentry_id=subentry.subentry_id, ) ``` 使用旧参数移动 device 需要集成进行多次 `async_update_device` 调用,将 device 添加到新的 config entry 和 subentry,然后从旧的移除,对于仅在相同 config entry 内更改 subentry 的 device 还有单独的情况。上面显示的单个调用取代了所有这些。此外,device registry 现在在 device 移动到已启用的 config entry 时清除 `CONFIG_ENTRY` disable,因此集成不再需要手动在移动过程中携带 `disabled_by` flag。 相关地,`async_update_device` 现在验证 `disabled_by` flag 相对于拥有 config entry 的 disabled 状态。对 disabled config entry 上的 device 设置 `disabled_by=None`,或对 enabled config entry 上的 device 设置 `disabled_by=DeviceEntryDisabler.CONFIG_ENTRY` 是不一致的;此类值现在被忽略并记录,并将在 Home Assistant Core 2027.8 中引发。 核心集成已作为示例进行了更新:[PR #176662](https://github.com/home-assistant/core/pull/176662) 中的 `openai_conversation`、[PR #176663](https://github.com/home-assistant/core/pull/176663) 中的 `scrape`、[PR #176664](https://github.com/home-assistant/core/pull/176664) 中的 `waqi` 以及 [PR #176665](https://github.com/home-assistant/core/pull/176665) 中的 `wolflink`。 要移除 device,调用 `DeviceRegistry.async_remove_device()`: ```py device_registry.async_remove_device(device.id) ``` 核心集成已在 PRs [#176669](https://github.com/home-assistant/core/pull/176669)、[#176671](https://github.com/home-assistant/core/pull/176671)、[#176672](https://github.com/home-assistant/core/pull/176672) 和 [#176673](https://github.com/home-assistant/core/pull/176673) 中更新为以这种方式移除 devices。 ### `DeviceRegistry.async_get_device()` 已弃用。Identifiers 和 connections 在每个 config entry 中唯一,因此按 identifiers 或 connections 查找可以设计性地匹配多个 devices,`async_get_device` 返回的内容因此是模糊的。 当知道拥有 config entry 时,用新方法 `DeviceRegistry.async_get_device_by_identifier()` 或 `DeviceRegistry.async_get_device_by_connection()` 限定在该 config entry 范围内查找 device。每个方法接受单个 identifier 或 connection 元组加上 config entry id,因此查找不再模糊: ```py # 之前 device = device_registry.async_get_device(identifiers={(DOMAIN, serial_number)}) # 之后 device = device_registry.async_get_device_by_identifier( (DOMAIN, serial_number), entry.entry_id ) ``` 在 entity 内,优先使用 `self.device_entry` 而不是 registry 查找。如果你确实需要匹配某个 key 的每个 device(可能跨 config entries),使用 `DeviceRegistry.async_get_devices()`,它返回一个 list。 核心集成已迁移到新方法,`heos` 在 core [PR #176932](https://github.com/home-assistant/core/pull/176932) 中是一个示例。 在弃用期间,`async_get_device` 会如 [向后兼容](#向后兼容) 中所述解析模糊查找。注意,这种向后兼容的解析只通过 `DeviceRegistry` 的查找方法(如 `async_get()` 和 `async_get_device()`)发生;直接与 `devices` 容器交互(例如 `DeviceRegistry.devices.get(device_id)`)不会合成 composite device。 ### 将 helper config entry 添加到其他集成的 device 上 Helper 集成不得将它们的 config entry 添加到 source entity 的 device 或用户选择的 device 上,它们应该将自己的 entities 链接到该 device。这是此处描述变更的直接后果:device 现在属于单个 config entry,因此 helper config entry 不能再添加到由其他集成拥有的 device 上。 这已在去年 [Updated guidelines for helper integrations linking to other integration's device](/developers/blog/2025-07-18-updated-pattern-for-helpers-linking-to-devices.md) 中宣布,并将在 Home Assistant Core 2026.8 中停止工作。 ### `helpers.device.async_device_info_to_link_from_entity()` 和 `async_device_info_to_link_from_device_id()` 这两个 helper 现在总是返回 `None`。 它们返回一个携带另一个 device 的 identifiers 和 connections 的 `DeviceInfo`,这会隐式地将调用者的 config entry 添加到该 device。拥有单个 config entry 的 device 无法表示这种情况,它会静默地派生一个重复 device。 改为在 entity 的构造函数中设置 `self.device_entry` 将 helper entity 链接到 device: ```py self.device_entry = async_entity_id_to_device(hass, source_entity_id) ``` 这些 helper 将在 Home Assistant Core 2027.8 中移除。 ### `helpers.helper_integration.async_handle_source_entity_changes(add_helper_config_entry_to_device=...)` 该参数不再有任何效果,应从调用中移除。 当 source entity 移动到另一个 device 时,`async_handle_source_entity_changes` 现在仅更新 helper entity 以链接到新 device,不再从旧 device 移除 helper config entry 并添加到新 device。 传递该参数在 Home Assistant Core 2027.8 之前被接受,并会记录警告。 ### 清理 helper devices 用于从 config entry 迁移步骤清理 helper 集成 devices 的 helper 已在 core [PR #176714](https://github.com/home-assistant/core/pull/176714) 中从 `async_remove_helper_config_entry_from_source_device` 重命名为 `homeassistant.helpers.helper_integration.async_remove_helper_devices`。旧名称作为弃用别名保留,将持续工作到 Home Assistant Core 2027.8。新签名为: ```py def async_remove_helper_devices( hass: HomeAssistant, *, helper_config_entry_id: str, source_device_id: str | None, remove_all_devices: bool = False, keep_device_ids: Collection[str] = (), ) -> None: ``` ### `helpers.device.async_remove_stale_devices_links_keep_entity_device()` 和 `async_remove_stale_devices_links_keep_current_device()` 两者现在都是 no-ops。改为从 helper 的 `async_setup_entry` 中用 `remove_all_devices=True` 调用 `async_remove_helper_devices`: ```py async_remove_helper_devices( hass, helper_config_entry_id=entry.entry_id, source_device_id=entry.options.get(CONF_DEVICE_ID), remove_all_devices=True, ) ``` `template` helper 已在 core [PR #176900](https://github.com/home-assistant/core/pull/176900) 中作为示例进行了迁移。这些函数将在 Home Assistant Core 2027.8 中移除。 ## Devices 只能有一个 config subentry Device 不能再绑定到多于一个 config subentry。这是一个没有向后兼容 shim 的 breaking change;将多个 subentries 附加到同一 device 的集成必须为每个 subentry 创建一个 device。 ### 示例:`telegram_bot` `telegram_bot` 集成已在 core [PR #176606](https://github.com/home-assistant/core/pull/176606) 中为此进行了调整,可以作为示例。 它以前有一个由每个 chat 共享的单个 bot device,每个 chat 的 subentry 附加到同一个 device。现在它为每个 chat 创建一个单独的 device,作为 via device 链接到 bot device。Config entry 迁移将每个 chat 的 notify entity 移动到自己的 device 上,并从 bot device 剥离 chat subentries,使 bot device 不再拥有 subentry。 注意,该 PR 是在添加 `via_device_id` 之前编写的,新代码应改用 `via_device_id` 而不是 `via_device`。 当[child devices](https://github.com/home-assistant/architecture/discussions/1414) 引入时,用 via device 建模此类结构的集成应迁移到 child devices。 ## 将 entity 链接到拆分 device 迁移前的 composite device id 不再指向真实 device。尝试通过将 id 传递给 `EntityRegistry.async_get_or_create(device_id=...)` 或 `EntityRegistry.async_update_entity(device_id=...)` 将 entity 链接到此类 id,会被忽略并记录警告,而不是被应用。然后会创建一个没有 device 的新 entity,现有的 entity 保持其当前 device。传递真正不存在的 device id 仍会像以前一样引发 `ValueError`。 存储的 device 是一个没有 entity 的 config entry 所拥有的拆分的 composite device 的 entities,在 registry 加载时会被从 device 分离;拥有集成预期会将它们重新链接。 改为将 entities 链接到拆分 device 之一,用 `async_get_device_by_identifier` 或 `async_get_device_by_connection` 查找它。 ## Device registry 事件 拆分迁移前的 composite device 发生在 registry 从存储加载时,在任何 listeners 运行之前,因此不会发出 `EVENT_DEVICE_REGISTRY_UPDATED` events;devices 在启动时已经拆分。 对于订阅 `EVENT_DEVICE_REGISTRY_UPDATED` 或使用 `async_track_device_registry_updated_event` 并检查 payload 的集成,有两点变更: * `update` 事件的 `changes` dict 用 `config_entry_id` 和 `config_subentry_id` keys 报告 device 移动,取代先前的 `config_entries` 和 `config_entries_subentries`。 * 更新或移除迁移前的 composite device id 会将操作转发到每个拆分 device,因此每个拆分 device 发出一个 event,而不是为 composite id 发出单个 event。 Device 现在属于单个 config entry,因此它不能再丢失一个 config entry 同时继续存在用于另一个。以前观察 `update` 事件中 `config_entries` 或 `config_entries_subentries` keys 变更的集成(通常用于检测其 config entry 从与其他集成共享的 device 中移除),现在可能只需要处理 `remove` events:device 丢失 config entry 意味着 device 被移除。 ## 向后兼容 拆分 devices 会改变自定义集成可能依赖的假设,存储在 automations 和 scripts 中的 device ids 不再作为 devices 存在。为了缓解这一点,device registry 做出最大努力尝试保持未修改的自定义集成正常工作,通过将迁移前的 composite device id 解析为它被拆分成的 devices。 这是最大努力,不是保证。Shims 无法覆盖自定义集成与 device registry 交互的每种方式,对拆分 devices 之间模糊的操作根本无法应用。对 462 个直接与 device registry 交互的自定义集成的 AI 辅助分析表明,至少 90% 预期会不受影响地工作,这也意味着有些不会。请将你的集成迁移到新 API,而不是依赖这些 shims;它们将在 Home Assistant Core 2027.8 中移除。 在弃用期间: * `DeviceRegistry.async_get()` 在传入迁移前 composite device 的 id 时会合成一个只读恢复的 composite device。其 identifiers、connections 和 config entries 是拆分 devices 的并集。合成仅在 `async_get()` 中发生;直接与 `devices` 容器交互(例如 `DeviceRegistry.devices.get(device_id)`)不会合成 composite,对迁移前 composite device id 返回 `None`。 * `DeviceRegistry.async_get_device()` 在可能时将通过匹配多个 config entries 的 identifiers 或 connections 的查找解析为单个 device,优先选择 config entry domain 与查找的 identifier 匹配的 device。如果剩余匹配是一个迁移前 composite device 的拆分,则返回跨它们的只读 composite。对于共享 identifier 或 connection 的独立 devices,优先选择由调用集成拥有的 device,回退到第一个匹配。 * `DeviceRegistry.async_update_device()` 和 `DeviceRegistry.async_remove_device()` 将调用转发到每个拆分 device。重写 device 身份或移动它的参数在拆分 devices 之间是模糊的;它们被忽略并向违规集成报告。 * Entity registry `get_entries_for_device_id()` 和 `async_entries_for_device()` 将迁移前 composite device id 展开为它被拆分成的 devices 的 entities。 * 针对迁移前 composite device id 的 actions 级联到拆分 devices。 * 用户自定义(area、floor、labels、name)在 device 拆分时保留。 新方法 `DeviceRegistry.async_get_devices_for_composite_device_id()` 返回迁移前 composite device 被拆分成的 devices。`DeviceRegistry.async_is_composite_device_id()` 返回一个 device id 是否是迁移前 composite device id,即已被拆分为每个 config entry 一个 device 且不再指向注册 device 的 id。 --- url: /developers/blog/2026-07-22-button-standard-event-types.md --- Button event entities 现在有一组标准 event types,由新的 `ButtonEventType` enum 提供。使用 `EventDeviceClass.BUTTON` 的集成,当交互映射到其中一个 type 时,应使用这些 type 而不是自定义字符串。 查看 [architecture discussion](https://github.com/home-assistant/architecture/discussions/1377) 了解完整背景。 ## 原因 以前,每个集成为自己选择的 button 交互使用不同的字符串——`single`、`click`、`hold`、`double_press` 等等。这种不一致性使得无法构建跨集成工作的通用 button 自动化,也阻止了 frontend 提供有意义的触发器建议。 新的 `ButtonEventType` 标准 event types 通过为每个 button 集成提供共享词汇来解决常见交互。 ## 事件类型 `ButtonEventType` 定义了六个标准 event types: * `ButtonEventType.PRESS_START`:button 被按下。 * `ButtonEventType.PRESS_END`:button 在短暂按下后释放(标准的"click")。 * `ButtonEventType.LONG_PRESS_START`:button 被按住超过了持续时间阈值。 * `ButtonEventType.LONG_PRESS_END`:button 在长时间按住后释放。 * `ButtonEventType.MULTI_PRESS_ONGOING`:检测到多按序列中的中间按下。 * `ButtonEventType.MULTI_PRESS_END`:多按序列完成。 `MULTI_PRESS_ONGOING` 和 `MULTI_PRESS_END` events 在其 event data 中包含 `multi_press_count` 属性(`ATTR_MULTI_PRESS_COUNT` 常量),指示按下次数。 **这些都不是强制的。** 与 doorbell 的 `ring` event 不同,这里没有必需的 type。每个集成只映射其硬件实际能产生的交互,并在 `event_types` 中列出这些。 ## 需要做什么 从 `homeassistant.components.event` 导入 `ButtonEventType`,并在 entity 的 `event_types` 中包含你的设备支持的 types。当交互发生时触发它们: ```python from homeassistant.components.event import ( ATTR_MULTI_PRESS_COUNT, ButtonEventType, EventDeviceClass, EventEntity, ) class MyButtonEvent(EventEntity): _attr_device_class = EventDeviceClass.BUTTON _attr_event_types = [ ButtonEventType.PRESS_END, ButtonEventType.LONG_PRESS_END, ButtonEventType.MULTI_PRESS_END, ] @callback def _async_handle_multi_press(self, count: int) -> None: """Handle a completed multi-press sequence.""" self._trigger_event( ButtonEventType.MULTI_PRESS_END, {ATTR_MULTI_PRESS_COUNT: count}, ) self.async_write_ha_state() ``` ### 单事件设备 如果设备每次交互只发出一个 event,没有单独的按下和释放,将其映射到匹配的 `_end` type(短按用 `PRESS_END`,按住用 `LONG_PRESS_END`,以此类推)。这在不合成硬件从不发送的 events 的情况下,保持跨设备"button 被按下"触发的一致性。 ## 无需迁移 此变更仅添加共享常量;没有弃用,也没有集成被迫迁移。自定义 event types 仍然可以与标准 types 一起使用。当它适合你的设备时采用 `ButtonEventType`。 更多详情,请参阅 [event entity 文档](/developers/core/entity/event.md)。 --- url: /developers/blog/2026-07-31-frontend-component-updates-2026.8.md --- ## 组件更新 ### ha-split-panel 我们添加了 `ha-split-panel`,它是对 Web Awesome split panel component 的 Home Assistant 包装。 当 Home Assistant 的 page、dialog 或 tool 需要可调整大小的双窗格布局时使用它。自定义卡片作者可以使用 Home Assistant frontend components,但 Home Assistant 内部 UI APIs 可能会变更。 ```html
Editor
Preview
``` 新的 component-specific tokens: ```css --ha-split-panel-divider-width --ha-split-panel-divider-hit-area --ha-split-panel-min --ha-split-panel-max --ha-split-panel-grip-display ``` ### ha-tile-info updates `ha-tile-info` 为自定义卡片和 tile-like surfaces 获得更多 layout 控制。 新的 component-specific tokens: ```css --ha-tile-info-gap --ha-tile-info-min-height --ha-tile-info-primary-min-height --ha-tile-info-primary-line-clamp ``` 当 primary 文本需要换行到多行时使用 `--ha-tile-info-primary-line-clamp`,并使用 min-height tokens 在部分 tiles 有 secondary 文本而另一些没有时保持 rows 对齐。 ## Form 和 selector 更新 ### 条件 ha-form 字段 `ha-form` schemas 现在支持通过 `visible` 实现条件字段可见性。 ```ts [ { name: "advanced", selector: { boolean: {} }, }, { name: "advanced_name", visible: { field: "advanced", value: true }, selector: { text: {} }, }, ] ``` 支持的 operators 是: ```ts "eq" "not_eq" "in" "not_in" "exists" "not_exists" ``` 你也可以用 `and`、`or` 和 `not` 组合条件。 隐藏字段不会被渲染,并在验证期间被跳过,因此当 form 字段依赖于另一个值时,请使用 `visible` 而不是自定义的仅 frontend 隐藏逻辑。 ### Selector 新增 Text selector 现在支持 HTML pattern 验证: ```ts { text: { pattern: "[a-z0-9_]+", validation_message: "Use lowercase letters, numbers, and underscores", }, } ``` 这对单值和多值 text selectors 都适用。 Entity selectors 现在可以通过 entity 的 device 属性进行筛选: ```ts { entity: { filter: { domain: "sensor", device: { manufacturer: "Home Assistant", model: "Connect ZBT-1", }, }, }, } ``` 还添加了一个新的 `ui_clock_date_format` selector,用于 clock card 的 date format editor。 ## Lovelace 更新 ### state\_color 正在迁移到 color `entities` 和 `glance` cards 现在支持 `color` 作为 `state_color` 的替代。 之前: ```yaml type: entities state_color: true entities: - light.kitchen ``` 之后: ```yaml type: entities color: state entities: - light.kitchen ``` 用 `color: state` 对应旧的 `state_color: true` 行为,用 `color: none` 对应 `state_color: false`。 ## Custom panels 和 apps ### Safe-area 处理 Custom panels 和 add-on app iframes 现在默认获得 safe-area padding,因此内容保持在 notches、状态栏和主屏指示符之外。 已经自行处理 safe areas 的 custom panels 可以选择退出: ```yaml panel_custom: - name: my-panel module_url: /local/my-panel.js handle_safe_area: true ``` 对于基于 iframe 的 custom panels,Home Assistant 将解析后的 safe-area 值作为 CSS variables 转发到 iframe document: ```css --safe-area-inset-top --safe-area-inset-right --safe-area-inset-bottom --safe-area-inset-left ``` Add-on app iframes 在订阅 Home Assistant properties 时也可以选择自行管理 safe area: ```js window.parent.postMessage( { type: "home-assistant/subscribe-properties", handleSafeArea: true, }, "*" ); ``` Properties message 随后会包含 `safeAreaInsets`。 ## Context 和 editor 基础设施 ### 全局 dirty state `DirtyStateProviderMixin` 现在还会发布全局 dirty state。 当任何连接的 dirty-state provider 有未保存的变更时,会设置 `window.isDirtyState`,Home Assistant 会触发 `dirty-state-changed` event。 ```ts window.addEventListener("dirty-state-changed", (ev) => { console.log(ev.detail.isDirty); }); ``` 这对于需要避免干扰具有未保存变更的活动 editors 或 dialogs 的共享基础设施非常有用。 --- url: /developers/blog/2026-08-19-device-registry-websocket-api-changes.md --- ## 摘要 本文描述了 device registry **WebSocket API** 的变更——由 frontend、自定义卡片和其他 WebSocket clients 消费的 commands 和 device serialization。它们源于 device registry 的两项变更: * **将每个 device 限制为单个 config entry**(Home Assistant Core 2026.8)。此变更的 Python API 方面在 companion post [Devices are restricted to a single config entry and at most one subentry](/developers/blog/2026-07-21-device-registry-single-config-entry.md) 中描述。 * **引入 [child devices](#device-list-中的-child-devices)**(Home Assistant Core 2026.9,[architecture proposal #1414](https://github.com/home-assistant/architecture/discussions/1414))。 大多数 clients 只通过 `config/device_registry/list` 读取 devices,新的 device fields 是 additive 的,因此无需任何更改即可保持工作——但遍历 device list 的 clients 应准备好遇到 child devices,它们被序列化得不同。移除 devices 或检查 device 的 config entries 的 clients 请继续阅读。 ## 新的 device fields:`config_entry_id` 和 `config_subentry_id` `config/device_registry/list` 返回的每个 device,以及 `EVENT_DEVICE_REGISTRY_UPDATED` payload 中的每个 device,现在都携带两个新 fields: * `config_entry_id` — device 所属的单个 config entry 的 id。 * `config_subentry_id` — device 所属的单个 config subentry 的 id,或 `null`。 它们取代了以前的 fields,这些 fields 建模了可以跨多个 config entries 和 subentries 的 device: * `config_entries` — config entry ids 的 list。 * `config_entries_subentries` — 从 config entry id 到 subentry ids list 的 map。 * `primary_config_entry` — device 的 primary config entry 的 id。 旧 fields **为了向后兼容而保留,并已弃用**;计划在家 Home Assistant Core 2027.8 中移除。在弃用期间,它们从新值派生:device 将 `config_entries` 报告为单元素 list `[config_entry_id]`,将 `config_entries_subentries` 报告为 `{config_entry_id: [config_subentry_id]}`,`primary_config_entry` 等于 `config_entry_id`。 更新你的 client 以读取 `config_entry_id` 和 `config_subentry_id`。 ## Device list 中的 child devices {#device-list-中的-child-devices} Home Assistant Core 2026.9 引入了 **child devices**([architecture proposal #1414](https://github.com/home-assistant/architecture/discussions/1414),core [PR #178666](https://github.com/home-assistant/core/pull/178666))。Child device 是 parent device 的轻量级逻辑部分:它没有自己的硬件或固件 metadata,并通过 `parent_device_id` 引用其 parent。Parent 必须由相同的 config entry 注册,并属于相同的 config subentry。 `config/device_registry/list` 现在将 child devices 与普通 devices 一起返回,因此其结果是两种 entry 的混合。Child device 以更小的 field 集合进行序列化: ```json { "id": "child1234", "parent_device_id": "abcd1234", "config_entry_id": "wxyz5678", "config_subentry_id": null, "area_id": null, "name": "Left channel", "name_by_user": null, "labels": [], "identifiers": [["demo", "left"]], "disabled_by": null, "created_at": 1723987200.0, "modified_at": 1723987200.0 } ``` 与普通 device 相比,child device **没有** `connections`、`via_device_id`、`configuration_url`、`entry_type`、`manufacturer`、`model`、`model_id`、`hw_version`、`sw_version`、`serial_number`、`primary_config_entry`、`config_entries` 或 `config_entries_subentries`。读取 device list 的 clients 不能假设每个 entry 都携带这些 fields。 区分两者的可靠方式是 `parent_device_id` field:它仅出现在 child devices 上且非 null。普通 device 携带的是 `via_device_id`。 没有自己 `area_id` 的 child device 继承其 parent 的 area,因此 client 在解析 child device 的 area 时,如果 child 的 `area_id` 为 `null`,应回退到 parent device。 两个相关 commands 也理解 child devices: * `config/device_registry/update` 接受 child device id——设置 `area_id`、`disabled_by`、`labels` 或 `name_by_user`——并以上述缩减序列化返回更新后的 child device。 * `config/device_registry/list_linked_devices` 总是为 child device 返回空的 `linked_devices` list,因为 child 共享其 parent 的 per-config-entry identifier 命名空间,并且永远不会链接到其他 config entries 的 devices。 ## 新 command:`config/device_registry/remove` 一个新的 WebSocket command 按 id 移除 device: ```json { "type": "config/device_registry/remove", "device_id": "abcd1234" } ``` 由于 device 现在恰好属于一个 config entry,从该 config entry 移除它就移除了 device。该 command 需要 admin,并且以错误 `Cannot remove a composite device` 拒绝[composite device id](#composite-devices)。 它取代了 `config/device_registry/remove_config_entry`,该 command 同时接收 `device_id` 和 `config_entry_id`: ```json { "type": "config/device_registry/remove_config_entry", "config_entry_id": "wxyz5678", "device_id": "abcd1234" } ``` 该 command 仍然有效但已**弃用**:它记录警告,并将在 Home Assistant Core 2027.9 中移除。它的 `config_entry_id` 参数现在仅用于检查它与 device 的 config entry 匹配——不匹配会失败并返回 `Config entry not in device`——无论传递哪个 config entry,device 都会被移除。更新 clients 调用 `config/device_registry/remove` 并去掉 `config_entry_id`。 在 core [PR #178319](https://github.com/home-assistant/core/pull/178319) 中实现。 ## 新 command:`config/device_registry/list_linked_devices` 由于 connections 和 identifiers 现在在每个 config entry 中唯一,由多个集成支持的物理设备由每个 config entry 一个 device 表示,而不是单个共享 device。该 command 返回与给定 device 共享 connection 或 identifier 的其他 devices——在不同 config entries 下表示相同物理硬件的 sibling devices: ```json { "type": "config/device_registry/list_linked_devices", "device_id": "abcd1234" } ``` 结果: ```json { "linked_devices": ["ef567890", "12ab34cd"] } ``` 被查询的 device 本身被排除在结果之外。这让 client(例如)可以从 device page 链接到表示相同硬件的其他 devices。在 core [PR #177449](https://github.com/home-assistant/core/pull/177449) 中实现。 ## 新 command:`config/device_registry/list_composite_splits` {#composite-devices} 当 device registry 加载时,每个跨多个 config entries 的迁移前 device 被拆分为每个 config entry 一个 device,原始的("composite")device id 不再指向注册的 device。Composite device ids 仍被 automations、scripts、dashboards 和 target pickers 引用,因此该 command 将每个 composite device id 映射到它被拆分成的 devices: ```json { "type": "config/device_registry/list_composite_splits" } ``` 结果: ```json { "old_composite_id": { "split_ids": ["ef567890", "12ab34cd"], "primary_id": "ef567890" } } ``` 对于每个 composite device id,`split_ids` 列出替代 device ids,`primary_id` 是继承了 composite 先前 primary config entry 的拆分,或 `null`。用它将存储的 composite device id 解析为当前 device——例如,在存储的 id 是 composite id 时保持 device picker 工作。在 core [PR #176693](https://github.com/home-assistant/core/pull/176693) 中实现。 Companion post 的 [Backwards compatibility](/developers/blog/2026-07-21-device-registry-single-config-entry.md#backwards-compatibility) 部分描述了弃用期间行为的其余部分,例如针对 composite device id 的 actions 级联到拆分 devices。 ## Device registry 事件 订阅 `device_registry_updated` events(`EVENT_DEVICE_REGISTRY_UPDATED`)的 clients 看到两个变更,镜像了 Python API: * `update` 事件的 `changes` map 用 `config_entry_id` 和 `config_subentry_id` keys 报告 device 移动,取代先前的 `config_entries` 和 `config_entries_subentries`。 * Device 现在属于单个 config entry,因此它不能再丢失一个 config entry 同时继续存在用于另一个。Device 丢失其 config entry 现在是一个 `remove` event 而不是 `update`。 详情请参阅 companion post 中的 [Device registry events](/developers/blog/2026-07-21-device-registry-single-config-entry.md#device-registry-events)。 --- url: /developers/blog/index.md --- # 博客 ## 2026 * [Device registry WebSocket API 变更](/developers/blog/2026-08-19-device-registry-websocket-api-changes.md) * [Frontend component updates 2026.8](/developers/blog/2026-07-31-frontend-component-updates-2026.8.md) * [Button event entities 的标准 event types](/developers/blog/2026-07-22-button-standard-event-types.md) * [Devices 限制为单个 config entry,最多一个 subentry](/developers/blog/2026-07-21-device-registry-single-config-entry.md) * [介绍 Open Home Foundation AI Policy](/developers/blog/2026-07-20-ai-policy.md) * [在 Home Assistant 中现代化 Modbus](/developers/blog/2026-07-05-modernizing-modbus.md) * [Media sources 现在可以搜索](/developers/blog/2026-07-03-media-source-search.md) * [引入新的 unit enumerators](/developers/blog/2026-06-30-new-unit-enumerators.md) * [async\_initialize\_triggers 的 home\_assistant\_start flag 弃用](/developers/blog/2026-06-30-async-initialize-triggers-home-assistant-start-deprecated.md) * [Frontend component updates 2026.7](/developers/blog/2026-06-23-frontend-component-updates-2026.7.md) * [Device tracker entity models 的变更](/developers/blog/2026-06-15-device-tracker-changes.md) * [Frontend component updates 2026.6](/developers/blog/2026-05-27-frontend-component-updates-2026.6.md) * [Card picker 中的自定义卡片建议](/developers/blog/2026-05-27-custom-card-suggestions.md) * [Data entry flow 中 advanced mode 的弃用](/developers/blog/2026-05-26-advanced-mode-config-flow-deprecation.md) * [BrowseMediaSource:domain 现在是必需的](/developers/blog/2026-05-20-browse-media-source-root-class.md) * [Condition 和 script APIs 的变更](/developers/blog/2026-05-13-condition-script-api-changes.md) * [MQTT publish API 支持 message expiry interval](/developers/blog/2026-05-11-mqtt-publish-api-message-expiry-interval.md) * [MQTT publish API 变更](/developers/blog/2026-05-11-mqtt-publish-api-changes.md) * [在自定义卡片中格式化 entity 名称](/developers/blog/2026-05-11-format-entity-name-helper.md) * [弃用 config flow 中使用 reloading methods 的 config entry listener](/developers/blog/2026-05-07-config-entry-listener-together-with-reloading-methods.md) * [Frontend context groups、新的 context decorators 和已弃用的 contexts](/developers/blog/2026-05-04-frontend-context-groups-decorators.md) * [Frontend component updates 2026.5](/developers/blog/2026-05-04-frontend-component-updates-2026.5.md) * [认真对待 serial:从 pyserial 迁移到 serialx](/developers/blog/2026-04-27-pyserial-to-serialx.md) * [用于 RF 设备集成的新 radio frequency entity platform](/developers/blog/2026-04-24-radio-frequency-entity-platform.md) * [注册自定义 dashboard strategies](/developers/blog/2026-04-21-registering-custom-dashboard-strategies.md) * [Legacy device tracker platform API 弃用](/developers/blog/2026-04-20-legacy-device-tracker-deprecation.md) * [Doorbell event entities 的标准 event type](/developers/blog/2026-04-15-doorbell-standard-event-type.md) * [Domain 不匹配的 Entity IDs 已弃用](/developers/blog/2026-04-07-entity-id-mismatched-domain-deprecated.md) * [将 app builds 迁移到 Docker BuildKit](/developers/blog/2026-04-02-builder-migration.md) * [用于 IR 设备集成的新 infrared entity platform](/developers/blog/2026-03-30-infrared-entity-platform.md) * [Frontend lazy context](/developers/blog/2026-03-25-frontend-lazy-context.md) * [Frontend 新的 dialogs 方式](/developers/blog/2026-03-25-frontend-dialogs.md) * [Frontend component updates 2026.4](/developers/blog/2026-03-25-frontend-component-updates-2026.4.md) * [Backup agents 现在可以报告上传进度](/developers/blog/2026-03-11-backup-upload-progress.md) * [自定义集成现在可以自带品牌图片](/developers/blog/2026-02-24-brands-proxy-api.md) * [移除已弃用的 light features](/developers/blog/2026-02-23-remove-deprecate-light-features.md) * [OAuth 2.0 helper 错误处理的变更](/developers/blog/2026-02-19-oauth-token-request-error-handling.md) * [webhook helper 的 reconfiguration 支持](/developers/blog/2026-02-18-reconfiguration-support-for-webhook-helper.md) * [Labs 中的 async\_listen 已弃用](/developers/blog/2026-02-16-labs-async-listen-deprecation.md) * [用 prek 替代 pre-commit](/developers/blog/2026-01-13-replace-pre-commit-with-prek.md) * [解决 pyserial-asyncio 阻塞 event loop 的问题](/developers/blog/2026-01-05-pyserial-asyncio-fast.md) ## 2025 * [为 service action translations 引入 description placeholders](/developers/blog/2025-11-27-service-translation-placeholders.md) * [Store data 在 worker thread 中序列化现需 opt-in](/developers/blog/2025-11-25-storage-helper-opt-in-serialize-in-executor.md) * [为 MQTT subscription 添加状态回调](/developers/blog/2025-11-23-mqtt-subscribe-wait.md) * [设备识别按钮现被归类为 diagnostic](/developers/blog/2025-11-21-identify-buttons-diagnostic-category.md) * [引入 Labs:在成为标准之前预览功能](/developers/blog/2025-11-20-labs-preview-features.md) * [Data Update Coordinator 现支持 Retry After](/developers/blog/2025-11-17-retry-after-update-failed.md) * [CalculatedState 中的 capability\_attributes 字段已移除](/developers/blog/2025-11-10-calculated-state-capability-attributes-removed.md) * [无网络连接时 oauth2 配置的改进错误处理](/developers/blog/2025-11-05-config-entry-oauth2-error-handling.md) * [TemperatureConverter.convert\_interval 弃用](/developers/blog/2025-11-04-convert-interval-deprecation.md) * [Service translations 已从 WebSocket get\_services 和 REST /api/services 中移除](/developers/blog/2025-10-24-service-web-api-changes.md) * [Recorder statistics API 的变更](/developers/blog/2025-10-16-recorder-statistics-api-changes.md) * [target selector 中的 device filter 已被移除](/developers/blog/2025-10-14-device-filter-removed-from-target-selector.md) * [Update coordinator 现允许重新触发](/developers/blog/2025-10-05-coordinator-retrigger.md) * [注册 platform entity service 的改进 API](/developers/blog/2025-09-25-entity-services-api-changes.md) * [弃用 service helpers 中的 hass 参数](/developers/blog/2025-09-22-deprecate-hass-argument-service-helpers.md) * [统一测量单位中 μ 的编码](/developers/blog/2025-08-20-micro-sign-encoding.md) * [DeviceEntry.suggested\_area 属性已弃用并将被移除](/developers/blog/2025-08-01-suggested-area-removed-from-deviceentry.md) * [FlowResult typed dict 中的 result 属性已被移除](/developers/blog/2025-07-31-result-removed-from-flowresult.md) * [关于 helper 集成链接到其他集成 device 的更新指南](/developers/blog/2025-07-18-updated-pattern-for-helpers-linking-to-devices.md) * [media player 的 STANDBY state 已弃用](/developers/blog/2025-07-16-media-player-standby-state-deprecated.md) * [自 OS 16 起 add-on 中打开文件限制的处理](/developers/blog/2025-07-14-home-assistant-os-16-open-file-limit.md) * [Vacuum 电池属性已弃用](/developers/blog/2025-07-02-vacuum-battery-properties-deprecated.md) * [Sensor device classes 现拥有默认显示精度](/developers/blog/2025-05-26-sensor-default-display-precision.md) * [图标翻译现已支持范围](/developers/blog/2025-05-22-range-based-icons.md) * [Device tracker TrackerEntity location accuracy 属性类型变更](/developers/blog/2025-04-24-device-tracker-accuracy.md) * [在 media player 中搜索](/developers/blog/2025-04-17-search-media-play.md) * [UnitSystem dataclass 现已冻结](/developers/blog/2025-03-25-frozen-unit-system.md) * [ConfigSubentryFlow 的变更](/developers/blog/2025-03-24-config-subentry-flow-changes.md) * [Media player toggle 操作已变更](/developers/blog/2025-03-14-media-player-toggle-adjusted.md) * [BackupAgent API 的变更](/developers/blog/2025-03-04-backup-agent-api-changes.md) * [对 config flow unique ID 的新检查](/developers/blog/2025-03-01-config-flow-unique-id.md) * [Config entry state 转换已更改](/developers/blog/2025-02-19-new-config-entry-states.md) * [Backup agents](/developers/blog/2025-02-17-backup-agents.md) * [支持 config subentries](/developers/blog/2025-02-16-config-subentries.md) * [每距离能量单位](/developers/blog/2025-01-31-energy-distance-units.md) * [迁移 dhcp/ssdp/usb/zeroconf ServiceInfo models](/developers/blog/2025-01-15-service-info.md) ## 2024 * [新增面积 device class](/developers/blog/2024-12-26-area-squared-units.md) * [迁移到 Pydantic v2](/developers/blog/2024-12-21-moving-to-pydantic-v2.md) * [使用 Kelvin 作为首选 color temperature 单位](/developers/blog/2024-12-14-kelvin-preferred-color-temperature-unit.md) * [WaterHeaterEntityDescription 名称已更改](/developers/blog/2024-12-13-water-heater-entity-description.md) * [Vacuum 新增 state 属性](/developers/blog/2024-12-08-new-vacuum-state-property.md) * [Climate entity 现在支持独立的水平 swing](/developers/blog/2024-12-03-climate-horizontal-swing.md) * [Utility 函数 homeassistant.util.dt.utc\_to\_timestamp 已弃用](/developers/blog/2024-11-28-dt-util-utc-to-timestamp-deprecation.md) * [Camera API 变更](/developers/blog/2024-11-26-camera-deprecations.md) * [翻译 measurement 单位](/developers/blog/2024-11-21-unit-of-measurement-translations.md) * [集成质量等级](/developers/blog/2024-11-20-integration-quality-scale.md) * [OptionsFlow 新增辅助属性](/developers/blog/2024-11-12-options-flow.md) * [Sections view 中自定义卡片支持尺寸设置](/developers/blog/2024-11-06-custom-card-sections-support.md) * [Reauth 和 reconfigure flows 必须关联到一个 config entry](/developers/blog/2024-11-04-reauth-reconfigure-entry-id.md) * [Update entity 的变更](/developers/blog/2024-10-31-update-entity-changes.md) * [Core config 类已迁移](/developers/blog/2024-10-31-core-config-moved.md) * [Alarm control panel 新增 state 属性与 state enum](/developers/blog/2024-10-22-new-alarm-state-property.md) * [reauth 和 reconfigure flows 的新辅助函数与最佳实践](/developers/blog/2024-10-21-reauth-reconfigure-helpers.md) * [延长 hass.helpers 的 deprecation 期限](/developers/blog/2024-10-09-extend-deprecation-hass-helpers.md) * [UnitOfConductivity enum 的变更](/developers/blog/2024-10-08-unit-of-conductivity-changes.md) * [弃用 cover 相关 state 常量](/developers/blog/2024-10-08-state-constants-cover-deprecation.md) * [介绍 Assist satellite 实体](/developers/blog/2024-10-01-assist-satellite-entity.md) * [Update 平台的版本比较现在可以自定义覆盖](/developers/blog/2024-09-28-update-version-compare.md) * [device\_tracker 强制使用 SourceType 并新增 shorthand 属性和 EntityDescription](/developers/blog/2024-09-24-device-tracker-entity-description.md) * [Climate set\_temperature 方法新增额外校验](/developers/blog/2024-09-24-climate-set-temp-validation.md) * [弃用 lock 相关 state 常量](/developers/blog/2024-09-23-state-constants-lock-deprecation.md) * [弃用 camera 相关 state 常量](/developers/blog/2024-09-23-state-constants-camera-deprecation.md) * [弃用 Vacuum 相关 feature flag 常量](/developers/blog/2024-09-23-feature-flag-constants-vacuum-deprecation.md) * [弃用 Media Player 相关常量](/developers/blog/2024-09-23-constants-media-player-deprecation.md) * [延长 @bind\_hass 和 hass.components 的 deprecation 期限](/developers/blog/2024-09-11-extending-deprecation-hass-components.md) * [energy 类传感器新增卡路里单位](/developers/blog/2024-09-10-calories-units.md) * [Template.hass 在渲染模板时不再自动设置](/developers/blog/2024-09-02-template-hass-required.md) * [entity action schema 的验证](/developers/blog/2024-08-27-entity-service-schema-validation.md) * [icon translations schema 的变更](/developers/blog/2024-08-27-changed-icon-translations-schema.md) * [LawnMowerActivity 中的新 returning 类型](/developers/blog/2024-08-23-lawn-mower-activity-returning.md) * [使用 setup 方法设置 DataUpdateCoordinator](/developers/blog/2024-08-05-coordinator_async_setup.md) * [Climate entity 现在验证 action call 中提供的温度](/developers/blog/2024-07-24-climate-min-max-temperature-check.md) * [FanEntity 中的新 entity feature flag](/developers/blog/2024-07-19-fan-fanentityfeatures-turn-on_off.md) * [Services 现在称为 Actions](/developers/blog/2024-07-16-service-actions.md) * [为 DeviceInfo 添加 model\_id](/developers/blog/2024-07-16-device-info-model-id.md) * [新的 HVACAction DEFROSTING](/developers/blog/2024-07-07-climate-hvacaction-defrosting.md) * [使用 MATCH\_ALL 从 recording 中排除所有 state attribute](/developers/blog/2024-06-22-excluding-state-attributes-from-recording-match-all.md) * [通过 `async_register_static_paths` 使 http path 注册变为 async 安全](/developers/blog/2024-06-18-async_register_static_paths.md) * [将设置转发到 config entry platform](/developers/blog/2024-06-12-async_forward_entry_setups.md) * [Alarm Control Panel entity 的 code 验证](/developers/blog/2024-05-22-alarm_control_panel_validation.md) * [将 Home Assistant API 暴露给 LLMs](/developers/blog/2024-05-20-llm-api.md) * [处理时区而不阻塞 event loop](/developers/blog/2024-05-19-fix_zoneinfo_blocking_io.md) * [LockEntity 支持 open/opening state](/developers/blog/2024-05-10-lock-supports-open-state.md) * [使用 group integration 设置 entity platform 的变更](/developers/blog/2024-05-10-group-integration.md) * [我们如何设法加快 CI 速度,每月节省 168+ 天的执行时间](/developers/blog/2024-05-09-improving-ci-test-execution.md) * [notify entity platform 实现第二阶段](/developers/blog/2024-05-03-notify-title.md) * [改进 hass.data 的 typing](/developers/blog/2024-05-01-improved-hass-data-typing.md) * [在 config entry 中存储 runtime 数据](/developers/blog/2024-04-30-store-runtime-data-inside-config-entry.md) * [在成功的 re-auth flow 之后始终 reload](/developers/blog/2024-04-25-always-reload-after-successful-reauth-flow.md) * [用 `async_track_state_change_event` 替换 `async_track_state_change`](/developers/blog/2024-04-13-deprecate_async_track_state_change.md) * [新的 notify entity platform](/developers/blog/2024-04-10-new-notify-entity-platform.md) * [弃用旧的 backports 和 typing alias](/developers/blog/2024-04-08-deprecated-backports-and-typing-aliases.md) * [弃用 `async_add_hass_job`](/developers/blog/2024-04-07-deprecate_add_hass_job.md) * [uv 如何每月为 Home Assistant 节省 215 个计算小时](/developers/blog/2024-04-03-build-images-with-uv.md) * [弃用 hass.helpers 的使用](/developers/blog/2024-03-30-deprecate-hass-helpers.md) * [Config Entries 现在可以提供 reconfigure 步骤](/developers/blog/2024-03-21-config-entry-reconfigure-step.md) * [新的 state 时间戳 State.last\_reported](/developers/blog/2024-03-20-state_reported_timestamp.md) * [使用翻译抛出 exception](/developers/blog/2024-03-15-exception-translations.md) * [弃用 `async_run_job` 和 `async_add_job`](/developers/blog/2024-03-13-deprecate_add_run_job.md) * [Climate entity 的辅助加热器已弃用](/developers/blog/2024-03-10-climate-aux-heater-deprecated.md) * [在 executor 中导入集成以避免阻塞 event loop](/developers/blog/2024-03-09-import_executor_default.md) * [对单独文件中的平台翻译的支持将被移除](/developers/blog/2024-03-05-platform_entity_translations_deprecation.md) * [引入 device name 翻译功能](/developers/blog/2024-02-28-device-name-translations.md) * [弃用 @bind\_hass 和 hass.components 的使用](/developers/blog/2024-02-27-deprecate-bind-hass-and-hass-components.md) * [新的 single instance only manifest 选项](/developers/blog/2024-02-26-single-instance-only-manifest-option.md) * [新的 Climate entity toggle 方法](/developers/blog/2024-02-25-Climate-toggle-service.md) * [lights 现在必须设置 color mode](/developers/blog/2024-02-12-light-color-mode-mandatory.md) * [修改 config entries](/developers/blog/2024-02-12-async_update_entry.md) * [ha-state-icon 的 properties 变更](/developers/blog/2024-01-30-ha-state-icon-properties-changes.md) * [Climate entity 中的新 entity features](/developers/blog/2024-01-24-climate-climateentityfeatures-expanded.md) * [lights 显示 effect 时 light color mode 的变更](/developers/blog/2024-01-23-light-color-mode-changes.md) * [枚举 services](/developers/blog/2024-01-22-async_services_for_domain.md) * [Icon 翻译](/developers/blog/2024-01-19-icon-translations.md) * [引入 entity translation placeholders](/developers/blog/2024-01-19-entity-translations-placeholders.md) * [弃用 sensor unit of measurement 和 state class 的无效用法](/developers/blog/2024-01-17-deprecate-invalid-sensor-uom-state-class-use.md) * [FlowManager.async\_show\_progress 的变更](/developers/blog/2024-01-11-async-show-progress-changes.md) ## 2023 * [弃用所有 supported features 的 magic numbers](/developers/blog/2023-12-28-support-feature-magic-numbers-deprecation.md) * [已弃用的常量会产生日志条目](/developers/blog/2023-12-19-constant-deprecation.md) * [Config entry 现在支持 minor 版本](/developers/blog/2023-12-18-config-entry-minor-version.md) * [EntityDescription 数据类的变更](/developers/blog/2023-12-11-entity-description-changes.md) * [新的 scaling 工具与 import 变更](/developers/blog/2023-12-05-scaling-utils.md) * [服务调用期间的异常处理与翻译支持](/developers/blog/2023-11-30-service-exceptions-and-translations.md) * [配置处理与错误处理](/developers/blog/2023-11-27-config-validation-and-error-handling.md) * [公开 Add-on 配置](/developers/blog/2023-11-06-public-addon-config.md) * [Country selector](/developers/blog/2023-10-12-country_selector.md) * [移除已弃用的单位转换工具](/developers/blog/2023-10-03-conversion-functions-cleanup.md) * [Home Assistant 参与 Hacktoberfest 2023!](/developers/blog/2023-10-01-hacktoberfest-2023.md) * [排除 state 属性不参与 recording 的新方式](/developers/blog/2023-09-20-excluding-state-attributes-from-recording.md) * [websocket 命令 entity/source 已修改](/developers/blog/2023-09-12-ws-entity-source-simplified.md) * [HomeAssistant.**init** 要求向其传递字符串](/developers/blog/2023-08-29-homeassistant-changed-signature.md) * [Entity state 格式化](/developers/blog/2023-08-29-hass-format-state.md) * [数值型 sensor 不再允许将 state 设置为 NaN 或 inf](/developers/blog/2023-08-23-sensor-updates.md) * [Weather entity 预报类型](/developers/blog/2023-08-07-weather_entity_forecast_types.md) * [使用 DataUpdateCoordinator 避免不必要的回调](/developers/blog/2023-07-27-avoiding-unnecessary-callbacks-with-dataupdatecoordinator.md) * [MQTT entities 命名变更为符合 HA 指南](/developers/blog/2023-07-21-change-naming-mqtt-entities.md) * [翻译 services](/developers/blog/2023-07-11-translating-services.md) * [Vacuum entity 集成更新](/developers/blog/2023-07-10-vacuum-updates.md) * [自定义卡片的 Action 事件](/developers/blog/2023-07-07-action-event-custom-cards.md) * [服务调用描述过滤器](/developers/blog/2023-06-28-service-description-filters.md) * [Entity 命名变更](/developers/blog/2023-06-28-entity-name-changes.md) * [Service Call API 变更](/developers/blog/2023-06-14-service-calls.md) * [近期 MQTT 变更以提升整体性能](/developers/blog/2023-05-21-retained-mqtt-messages-filtered.md) * [Job:Home Assistant Core 开发者](/developers/blog/2023-05-07-job-home-assistant-core.md) * [Statistics WebSocket API 变更](/developers/blog/2023-04-30-statistics_impossible_values.md) * [Supervisor Add-ons 的新限制](/developers/blog/2023-04-13-new_limits_for_add_ons.md) * [Deprecating Polymer](/developers/blog/2023-04-04-deprecating_polymer.md) * [Calendar best practices](/developers/blog/2023-03-28-calendar_best_practices.md) * [翻译 entity 的 name 和 attributes](/developers/blog/2023-03-27-entity_name_translations.md) * [自定义 tile features](/developers/blog/2023-02-28-custom-tile-features.md) * [已移除 MQTT subscribe 的弃用 callback 签名](/developers/blog/2023-02-21-deprecated-callback-removed.md) * [新增 snapshot testing 支持](/developers/blog/2023-02-20-snapshot-testing.md) * [重构 json helper 和 utility](/developers/blog/2023-02-15-json.md) * [HassGetState intent](/developers/blog/2023-02-09-hassgetstate.md) * [显示 sensor state 时使用的小数位数现在可配置](/developers/blog/2023-02-08-sensor_presentation_rounding.md) * [在 review 流程中引入 PR drafting](/developers/blog/2023-02-07-introducing-PR-drafting-in-reviews.md) * [翻译文件已从 Core 仓库中移除](/developers/blog/2023-02-06-translations-files-removed-from-core.md) * [Intent Responses 和 Whitespace](/developers/blog/2023-02-03-responses.md) * [Sensor entity 现在可以对数值进行 rounding](/developers/blog/2023-01-25-sensor_rounding.md) * [为 Conversation 集成做未来兼容设计](/developers/blog/2023-01-24-conversation-updates.md) * [Cover intents 已弃用](/developers/blog/2023-01-20-cover-intent-deprecated.md) * [2023.2 及以后版本的 Bluetooth 更新](/developers/blog/2023-01-12-bluetooth-adapters.md) * [数据库 schema v32 更新](/developers/blog/2023-01-02-db-schema-v32.md) ## 2022 * [Multi-pan 暂时禁用](/developers/blog/2022-12-08-multi-pan-rollback.md) * [单位系统相关变更汇总](/developers/blog/2022-12-07-unit_system_changes.md) * [Entity state 颜色变更](/developers/blog/2022-12-07-entity-color-changes.md) * [添加更多单位枚举器](/developers/blog/2022-12-05-more-unit-enumerators.md) * [翻译 entity 的 state](/developers/blog/2022-12-01-entity_translations.md) * [添加更多单位枚举器](/developers/blog/2022-11-28-more-unit-enumerators.md) * [长期统计 API 的变更](/developers/blog/2022-11-16-statistics_refactoring.md) * [引入新的单位枚举器](/developers/blog/2022-10-26-new-unit-enumerators.md) * [添加新的降水强度单位](/developers/blog/2022-10-25-new-precipitation-intensity-units.md) * [引入虚拟集成并区分 hub、device 和 service](/developers/blog/2022-10-24-hubs-devices-services-virtual-integrations.md) * [代码所有者的 GitHub 命令](/developers/blog/2022-10-21-code-owner-commands.md) * [弃用 IMPERIAL\_SYSTEM 单位系统及相关常量和属性](/developers/blog/2022-10-14-deprecate-unit-system.md) * [为 SelectEntityDescription 添加 options](/developers/blog/2022-10-10-add-options-to-SelectEntityDescription.md) * [长期统计现在跟踪源实体的单位](/developers/blog/2022-09-29-statistics_refactoring.md) * [新的 sensor device classes](/developers/blog/2022-09-28-new_sensor_device_classes.md) * [弃用单位转换工具](/developers/blog/2022-09-28-deprecate-conversion-utilities.md) * [2022.10 的 Bluetooth async\_track\_unavailable API 变更](/developers/blog/2022-09-16-bluetooth-unavailable-api-changes.md) * [弃用 media player 常量](/developers/blog/2022-09-06-media-player-repeat-mode-deprecation.md) * [Issue registry 已移至 homeassistant.helpers](/developers/blog/2022-08-25-issue_registry_moved_to_helpers.md) * [全局可访问的 HomeAssistant 对象(hass)](/developers/blog/2022-08-24-globally_accessible_hass.md) * [LightEntity 不再支持 white\_value](/developers/blog/2022-08-18-light_white_value_removed.md) * [2022.9 的 AutomationActionType 弃用](/developers/blog/2022-08-15-automation-action-type-deprecation.md) * [2022.9 的 Bluetooth passive sensor API 变更](/developers/blog/2022-08-08-bluetooth-api-changes.md) * [2022.9 的 Device tracker 弃用](/developers/blog/2022-07-29-device-tracker_source-type-deprecation.md) * [采用一种新的实体命名方式](/developers/blog/2022-07-10-entity_naming.md) * [Store 现在是一个 Generic 类](/developers/blog/2022-07-08-generic-store.md) * [等待 config entry platforms](/developers/blog/2022-07-08-config_entry_forwards.md) * [重构 Weather entity 以支持单位转换](/developers/blog/2022-06-27-weather_entity_refactoring.md) * [重构 Number entity 以支持单位转换](/developers/blog/2022-06-14-number_entity_refactoring.md) * [避免在 config entry 设置时重新加载](/developers/blog/2022-06-13-unsafe_reloads_during_entry_setup.md) * [弃用 Data Entry Flow 常量](/developers/blog/2022-06-07-dataflow-constants-deprecation.md) * [在 update coordinator 中支持 context](/developers/blog/2022-06-02-update_coordinator-context.md) * [Media Player 更新:enqueue 变更,添加 announce](/developers/blog/2022-05-31-media-player-updates.md) * [Logbook API 移除 entity\_matches\_only 标志](/developers/blog/2022-05-24-entity_matches_only_removed_logbook_card.md) * [我们 Docker base images 上的 S6-Overlay 3.x 更新](/developers/blog/2022-05-12-s6-overlay-base-images.md) * [ServiceInfo model 改进和弃用](/developers/blog/2022-05-03-serviceinfo-model-improvements.md) * [2022.5 的常量弃用](/developers/blog/2022-05-03-constants-deprecations.md) * [TTS say service 使用 media source IDs](/developers/blog/2022-04-26-tts-say-media-source.md) * [告别 time\_changed 事件](/developers/blog/2022-04-20-saying-goodbye-to-event_time_changed.md) * [Calendar Data Model 改进和弃用](/developers/blog/2022-04-18-calendar-data-model.md) * [Local OAuth2 更新](/developers/blog/2022-04-16-local-oauth2.md) * [弃用所有 SUPPORT\_\* 常量](/developers/blog/2022-04-02-support-constants-deprecation.md) * [2022.4 中的开发者新功能](/developers/blog/2022-03-30-2022.4-new-dev-features.md) * [引入 update entity](/developers/blog/2022-03-20-update-entity.md) * [选择支持手动移除设备](/developers/blog/2022-02-28-opt-in-remove-device.md) * [Paper Elements 正在被移除](/developers/blog/2022-02-18-paper-elements.md) ## 2021 * [Device configuration URL 和 entity categories](/developers/blog/2021-10-26-config-entity.md) * [新的 sensor state class:total](/developers/blog/2021-09-20-state_class_total.md) * [Supervisor 更新](/developers/blog/2021-08-24-supervisor_update.md) * [新 sensor state class:total\_increasing](/developers/blog/2021-08-16-state_class_total.md) * [温度转换移至 SensorEntity](/developers/blog/2021-08-12-sensor_temperature_conversion.md) * [用于长期统计的新 sensor properties](/developers/blog/2021-05-25-sensor_attributes.md) * [升级到 Lit 2.0](/developers/blog/2021-05-19-lit-2.0.md) * [用 python-dateutil 替换 pytz](/developers/blog/2021-05-07-switch-pytz-to-python-dateutil.md) * [Astral 升级到 2.2 版本](/developers/blog/2021-04-09-astral-2.2.md) * [Custom integration 变更](/developers/blog/2021-01-29-custom-integration-changes.md) ## 2020 * [System Health 和 Templates](/developers/blog/2020-11-09-system-health-and-templates.md) * [add-ons 即将发生的变更](/developers/blog/2020-10-29-supervisor-update.md) * [Lazy-loading more-info controls](/developers/blog/2020-10-02-lazyMoreInfo.md) * [Lovelace:Custom View Layouts](/developers/blog/2020-09-30-customViewChanges.md) * [运行 Home Assistant 时提升 Python 速度 40%](/developers/blog/2020-07-13-alpine-python.md) * [Lovelace:getCardSize 现在可以是 async](/developers/blog/2020-06-01-getCardSize.md) * [Entity class names](/developers/blog/2020-05-14-entity-class-names.md) * [Custom icon sets](/developers/blog/2020-05-09-custom-iconsets.md) * [custom integrations 的 Logos](/developers/blog/2020-05-08-logos-custom-integrations.md) * [Instance URL helper](/developers/blog/2020-05-08-instance-url-helper.md) * [custom Lovelace 的 Translations](/developers/blog/2020-04-23-frontend-translations.md) * [custom components 的 Hassfest](/developers/blog/2020-04-16-hassfest.md) * [我们 Docker 容器的 S6 Overlay](/developers/blog/2020-04-12-s6-overlay.md) * [Translations 2.0](/developers/blog/2020-04-10-translation-handling.md) * [0.106 中可能影响 custom cards 的变更](/developers/blog/2020-02-18-106-custom-card-changes.md) * [Z-Wave integration 更新](/developers/blog/2020-02-04-new-zwave.md) ## 2019 * [Home Assistant 1.0 中的 Simple Mode](/developers/blog/2019-10-05-simple-mode.md) * [Hacktoberfest 2019](/developers/blog/2019-09-27-hacktoberfest.md) * [采用 Black](/developers/blog/2019-07-31-black.md) * [Building All The Things](/developers/blog/2019-07-19-building-all-the-things.md) * [Climate Cleanup](/developers/blog/2019-07-03-climate-cleanup.md) * [物联网与现代 Web](/developers/blog/2019-05-22-internet-of-things-and-the-modern-web.md) * [介绍 Integrations](/developers/blog/2019-04-12-new-integration-structure.md) * [我能拥有用户权限吗?](/developers/blog/2019-03-11-user-permissions.md) * [伟大的迁移](/developers/blog/2019-02-19-the-great-migration.md) ## 2018 * [弃用 homeassistant.remote](/developers/blog/2018-08-13-deprecating-remote-package.md) * [试用新的 auth 系统](/developers/blog/2018-07-02-trying-new-auth.md) * [0.71:改进的 custom panels 和 custom UI 的少量变更](/developers/blog/2018-06-01-071-custom-panels.md) * [Custom UI 和 Custom Panels 更新](/developers/blog/2018-05-22-custom-ui-panels-api.md) --- url: /developers/bluetooth.md --- ### 面向集成作者的最佳实践 * 需要使用蓝牙适配器的集成应在 [`manifest.json`](/developers/creating_integration_manifest.md) 中的 [`dependencies`](/developers/creating_integration_manifest.md#dependencies) 添加 `bluetooth_adapters`。[`manifest.json`](/developers/creating_integration_manifest.md) 条目可确保所有受支持的远程适配器在集成尝试使用它们之前均已连接。 * 调用 `bluetooth.async_get_scanner` API 获取 `BleakScanner` 实例并将其传递给你的库。返回的 scanner 可以避免运行多个 scanner 带来的开销,而这开销是显著的。此外,封装后的 scanner 在用户更改蓝牙适配器设置后将继续正常工作。 * 避免在连接之间复用 `BleakClient`,因为这会降低连接的可靠性。 * 连接超时时间至少设置为十(10)秒,因为 `BlueZ` 在首次连接新设备或已更新设备时必须解析服务。连接时瞬态错误很常见,且首次尝试并不总能成功。`bleak-retry-connector` PyPI 包可以省去快速可靠建立设备连接的繁琐操作。 ### 可连接与不可连接的蓝牙控制器 Home Assistant 支持远程蓝牙控制器。某些控制器仅支持监听 advertisement 数据,不支持连接设备。由于许多设备只需要接收 advertisement,我们引入了可连接设备(connectable devices)和不可连接设备(non-connectable devices)的概念。如果设备不需要主动连接,则将 `connectable` 参数设置为 `False` 以选择接收来自不支持发出出站连接的控制器的数据。当 `connectable` 设置为 `False` 时,将同时提供来自可连接和不可连接控制器的数据。 `connectable` 的默认值为 `True`。如果集成中有些设备需要连接而另一些不需要,`manifest.json` 应为相应设备正确设置该标志。如果无法构建 matcher 来区分相似的设备,请在 config flow discovery `BluetoothServiceInfoBleak` 中检查 `connectable` 属性,并拒绝需要出站连接的设备 flow。 --- url: /developers/config_entries_index.md --- 配置条目(Config entries)是由 Home Assistant 持久存储的配置数据。配置条目由用户通过 UI 创建。UI 流程由集成定义的 [config flow handler](/developers/core/integration/config_flow.md) 驱动。 创建后,用户可以删除配置条目。此外,用户还可以通过集成定义的 [reconfigure step](/developers/core/integration/config_flow.md#reconfigure) 或 [options flow handler](/developers/core/integration/options_flow.md) 修改配置条目。 ### 配置子条目 配置条目可以将存储的配置数据逻辑地分离为子条目,用户可以通过 UI 将子条目添加到现有配置条目中。例如,一个提供天气预报的集成,配置条目存储认证信息,每个需要预报天气的位置则作为子条目存储。 与配置条目类似,子条目可以选择性地支持 reconfigure step。 ## 生命周期 | 状态 | 描述 | | ----- | ----------- | | not loaded | 配置条目尚未加载。这是创建配置条目或重启 Home Assistant 时的初始状态。 | | setup in progress | 尝试加载配置条目时的中间状态。 | | loaded | 配置条目已加载。 | | setup error | 尝试设置配置条目时发生错误。 | | setup retry | 配置条目的依赖项尚未就绪。Home Assistant 将在未来自动重试加载此配置条目。重试间隔将自动增加。 | | migration error | 配置条目必须迁移到较新版本,但迁移失败。 | | unload in progress | 尝试卸载配置条目时的中间状态。 | | failed unload | 尝试卸载配置条目但失败,可能是因为不支持卸载或抛出了异常。 | 更多关于如何暴露错误和请求重试的信息,参见 [Handling Setup Failures](/developers/integration_setup_failures.md#integrations-using-async_setup_entry)。 ## 设置条目 启动时,Home Assistant 首先调用[普通集成 setup](/developers/creating_component_index.md), 然后对每个条目调用方法 `async_setup_entry(hass, entry)`。如果在运行时创建了新的 Config Entry,Home Assistant 也会调用 `async_setup_entry(hass, entry)` ([示例](https://github.com/home-assistant/core/blob/f18ddb628c3574bc82e21563d9ba901bd75bc8b5/homeassistant/components/hassio/__init__.py#L522))。 ### 对于 platforms 如果集成包含 platforms,它需要将 Config Entry 的设置转发给 platform。这可以通过在 config entry manager 上调用转发函数来完成([示例](https://github.com/home-assistant/core/blob/f18ddb628c3574bc82e21563d9ba901bd75bc8b5/homeassistant/components/hassio/__init__.py#L529)): ```python await hass.config_entries.async_forward_entry_setups(config_entry, ["light", "sensor", "switch"]) ``` Platform 要支持 config entries,需要添加 setup entry 函数([示例](https://github.com/home-assistant/core/blob/f18ddb628c3574bc82e21563d9ba901bd75bc8b5/homeassistant/components/hassio/__init__.py#L522)): ```python async def async_setup_entry( hass: HomeAssistant, config_entry: MyConfigEntry, async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry.""" ``` ## 卸载条目 集成可以选择性地支持卸载配置条目。卸载条目时,集成需要清理所有 entity、取消订阅任何事件监听器并关闭所有连接。要实现这一点,在集成中添加 `async_unload_entry(hass, entry)`([示例](https://github.com/home-assistant/core/blob/f18ddb628c3574bc82e21563d9ba901bd75bc8b5/homeassistant/components/hassio/__init__.py#L534))。在调用 `async_unload_entry` 之前,配置条目的状态被设置为 `ConfigEntryState.UNLOAD_IN_PROGRESS`。 对于每个你转发了配置条目的 platform,也需要转发卸载操作。 ```python async def async_unload_entry(hass: HomeAssistant, entry: MyConfigEntry) -> bool: """Unload a config entry.""" ``` 如果你需要在 platform 中清理 entity 使用的资源,让 entity 实现 [`async_will_remove_from_hass`](/developers/core/entity.md#async_will_remove_from_hass) 方法。 ## 删除条目 如果集成需要在条目被删除时清理代码,可以定义删除函数 `async_remove_entry`。在调用 `async_remove_entry` 之前,配置条目已从 `hass.config_entries` 中删除。 ```python async def async_remove_entry(hass: HomeAssistant, entry: MyConfigEntry) -> None: """Handle removal of an entry.""" ``` ## 将配置条目迁移到新版本 如果配置条目的版本发生变化,必须实现 `async_migrate_entry` 以支持旧条目的迁移。详细内容见 [config flow 文档](/developers/core/integration/config_flow.md#config-entry-migration)。 ```python async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: """Migrate old entry.""" ``` ## 修改配置条目 `ConfigEntry` 对象(包括 data 和 options)绝不应被集成直接修改,集成必须调用 `async_update_entry`,其用法在 [config flow 文档](/developers/core/integration/config_flow.md#config-entry-migration) 中有示例说明。 ## 订阅配置条目状态变更 如果你希望收到 `ConfigEntry` 的 `state` 变更通知(例如,从 `ConfigEntryState.LOADED` 变为 `ConfigEntryState.UNLOAD_IN_PROGRESS`),可以添加一个监听器,该监听器会在 `async_on_state_change` 中被通知。此辅助方法还返回一个回调,你可以调用它以再次移除监听器。因此,订阅变更直到条目卸载的写法为 `entry.async_on_unload(entry.async_on_state_change(notify_me))`。 --- url: /developers/core/bluetooth/api.md --- ### 订阅 Bluetooth 发现 一些集成可能需要立即知道设备被发现的时间。Bluetooth 集成提供了一个注册 API,用于在发现匹配特定 key 值的新设备时接收 callbacks。`manifest.json` 中 `bluetooth` 的匹配格式相同。除了 `manifest.json` 中使用的 matchers 外,`address` 也可用作 matcher。 函数 `bluetooth.async_register_callback` 提供了此功能。该函数返回一个 callback,调用它将取消注册。 以下示例展示了注册以在 Switchbot 设备附近时接收 callbacks: ```python from homeassistant.components import bluetooth ... @callback def _async_discovered_device(service_info: bluetooth.BluetoothServiceInfoBleak, change: bluetooth.BluetoothChange) -> None: """Subscribe to bluetooth changes.""" _LOGGER.warning("New service_info: %s", service_info) entry.async_on_unload( bluetooth.async_register_callback( hass, _async_discovered_device, {"service_uuid": "cba20d00-224d-11e6-9fb8-0002a5d5c51b", "connectable": False}, bluetooth.BluetoothScanningMode.ACTIVE ) ) ``` 以下示例展示了注册以获取 HomeKit 设备的 callbacks: ```python from homeassistant.components import bluetooth ... entry.async_on_unload( bluetooth.async_register_callback( hass, _async_discovered_homekit_device, {"manufacturer_id": 76, "manufacturer_data_first_byte": 6}, bluetooth.BluetoothScanningMode.ACTIVE ) ) ``` 以下示例展示了注册以获取 Nespresso Prodigios 的 callbacks: ```python from homeassistant.components import bluetooth ... entry.async_on_unload( bluetooth.async_register_callback( hass, _async_nespresso_found, {"local_name": "Prodigio_*")}, bluetooth.BluetoothScanningMode.ACTIVE ) ) ``` 以下示例展示了注册以获取 address 为 `44:33:11:22:33:22` 的设备的 callbacks: ```python from homeassistant.components import bluetooth ... entry.async_on_unload( bluetooth.async_register_callback( hass, _async_specific_device_found, {"address": "44:33:11:22:33:22")}, bluetooth.BluetoothScanningMode.ACTIVE ) ) ``` #### 请求按需 active 扫描 当 matcher 以特定 `address` 为目标且 `mode` 不是 `PASSIVE` 时,callback 注册也可以选择将该 address 加入 `AUTO` 模式 scanners 使用的 active-scan 调度器。这使得集成可以按适合其设备的 cadence 请求短时间 active-scan windows,而无需强制整个系统进入持续 active 扫描。 传递 `scan_interval`(窗口开始之间的秒数)和/或 `scan_duration`(每个窗口的秒数)作为关键字参数。两者都是可选的;省略时,使用 habluetooth 的默认值(5 分钟间隔,10 秒持续)。有效窗口被限制在 habluetooth 允许范围内。如果 matcher 中没有 `address`,则跳过 active-scan 请求;callback 本身仍正常触发。 ```python from homeassistant.components import bluetooth ... entry.async_on_unload( bluetooth.async_register_callback( hass, _async_specific_device_found, {"address": "44:33:11:22:33:22"}, bluetooth.BluetoothScanningMode.ACTIVE, scan_interval=600.0, scan_duration=10.0, ) ) ``` #### 控制历史记录重放顺序 注册 callback 时,Bluetooth 集成会重放缓存的 advertisements,以便新的 subscriber 立即看到所有已知设备。重放的顺序以及是否重放都可以通过 `replay` 关键字参数控制,它接受一个 `BluetoothCallbackReplay` 值: | Value | Behavior | |---|---| | `OLDEST_FIRST`(默认) | 按首次看到 advertisement 的顺序重放。 | | `NEWEST_FIRST` | 先重放最新的 advertisement。当消费者希望立即对当前设备状态做出响应时很有用。 | | `DISABLED` | 完全跳过重放。对于仅关心未来实时 advertisements 的消费者很有用。 | ```python from homeassistant.components import bluetooth ... entry.async_on_unload( bluetooth.async_register_callback( hass, _async_discovered_device, {"service_uuid": "cba20d00-224d-11e6-9fb8-0002a5d5c51b", "connectable": False}, bluetooth.BluetoothScanningMode.ACTIVE, replay=bluetooth.BluetoothCallbackReplay.NEWEST_FIRST, ) ) ``` ### 获取共享的 BleakScanner 实例 需要 `BleakScanner` 实例的集成应调用 `bluetooth.async_get_scanner` API。此 API 返回围绕单个 `BleakScanner` 的 wrapper,允许集成共享而不会使系统过载。 ```python from homeassistant.components import bluetooth scanner = bluetooth.async_get_scanner(hass) ``` ### 判断 scanner 是否正在运行 Bluetooth 集成可能已经设置好,但没有 connectable 适配器或 remotes。可以使用 `bluetooth.async_scanner_count` API 来确定是否有能够接收 advertisements 或生成可用于连接设备的 `BLEDevice` 的 scanner 正在运行。如果没有任何 scanner 能生成 connectable `BLEDevice` 对象,集成可能希望在设置期间抛出更有用的错误。 ```python from homeassistant.components import bluetooth count = bluetooth.async_scanner_count(hass, connectable=True) ``` ### 通过 source 访问 scanner `bluetooth.async_scanner_by_source` API 提供了通过其 source(MAC 地址)访问特定 Bluetooth scanner 的方法。这主要面向实现 Bluetooth client 并需要直接与 scanner 交互的集成。 ```python from homeassistant.components import bluetooth scanner = bluetooth.async_scanner_by_source(hass, "AA:BB:CC:DD:EE:FF") if scanner is not None: # 检查 scanner 属性(只读) if scanner.current_mode is not None: _LOGGER.debug("Scanner mode: %s", scanner.current_mode) ``` ### 访问所有当前 scanners `bluetooth.async_current_scanners` API 提供了访问所有当前活动 Bluetooth scanners 列表的方法,用于调试、diagnostics 和 scanner 状态的 introspection。此 API 返回所有已注册的 scanners(包括 connectable 和 non-connectable)作为 scanner 对象列表。 ```python from homeassistant.components import bluetooth scanners = bluetooth.async_current_scanners(hass) for scanner in scanners: # 检查 scanner 属性(只读) if scanner.current_mode is not None: _LOGGER.debug("Scanner %s is in mode %s", scanner.source, scanner.current_mode) ``` :::warning 关于 Scanner APIs 的重要信息 `async_scanner_by_source` 和 `async_current_scanners` 返回的 scanner 对象来自 `habluetooth` 包,它们的接口在 Home Assistant 发布之间不保证保持稳定。**你只能检查 scanner 属性,绝不能修改它们。** 直接修改 scanner 对象可能会破坏 Home Assistant 的 Bluetooth 功能。 **不要:** * 更改 scanner 属性或调用修改状态的 methods * 存储对 scanners 的引用超出你直接使用的范围 * 假设 scanner 接口在将来版本中保持不变 **应:** * 仅将 scanners 用于只读检查、调试和 diagnostics * 访问简单的属性,如 `source` 和 `current_mode` * 处理属性可能为 `None` 的情况 ::: ### 订阅不可用 callbacks 要在 Bluetooth 栈不再看到设备时收到 callback,请调用 `bluetooth.async_track_unavailable` API。出于性能原因,设备不再被看到后最多可能需要五分钟才能收到 callback。 如果 `connectable` 参数设置为 `True`,如果任何 `connectable` controller 都能到达该设备,则该设备将被视为可用。如果只有 non-connectable controllers 能到达该设备,则该设备将被视为不可用。如果参数设置为 `False`,如果任何 controller 都能看到该设备,则该设备将被视为可用。 ```python from homeassistant.components import bluetooth def _unavailable_callback(info: bluetooth.BluetoothServiceInfoBleak) -> None: _LOGGER.debug("%s is no longer seen", info.address) cancel = bluetooth.async_track_unavailable(hass, _unavailable_callback, "44:44:33:11:23:42", connectable=True) ``` ### 查询可用性超时 可用性基于自设备最后一次已知广播以来的时间。此超时根据设备的常规广播模式自动学习。你可以使用 `bluetooth.async_get_learned_advertising_interval` API 来查询它。 ```python from homeassistant.components import bluetooth learned_interval = bluetooth.async_get_learned_advertising_interval(hass, "44:44:33:11:23:42") ``` 如果 advertising interval 尚未知,这将返回 `None`。在这种情况下,unavailability tracking 将尝试该 address 的 fallback interval。以下示例返回由集成手动设置的 interval: ```python from homeassistant.components import bluetooth bluetooth.async_set_fallback_availability_interval(hass, "44:44:33:11:23:42", 64.0) fallback_interval = bluetooth.async_get_fallback_availability_interval(hass, "44:44:33:11:23:42") ``` 如果没有针对设备的 learned interval 或 fallback interval,则使用硬编码的安全默认 interval: ```python from homeassistant.components import bluetooth default_fallback_interval = bluetooth.FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS ``` ### 通过 address 获取 bleak `BLEDevice` 集成应通过调用 `bluetooth.async_ble_device_from_address` API 来避免启动额外 scanner 以解析 address 的开销,该 API 返回最接近可到达该设备的已配置 `bluetooth` 适配器的 `BLEDevice`。如果没有适配器能到达该设备,`bluetooth.async_ble_device_from_address` API 将返回 `None`。 假设集成希望从 `connectable` 和 non-connectable controllers 接收数据。在这种情况下,当它想要发起出站连接时,只要至少有一个 `connectable` controller 在范围内,它就可以将 `BLEDevice` 交换为 `connectable` 的一个。 ```python from homeassistant.components import bluetooth ble_device = bluetooth.async_ble_device_from_address(hass, "44:44:33:11:23:42", connectable=True) ``` ### 解释设备不可达的原因 当 `async_ble_device_from_address` 返回 `None` 或无法建立连接时,`bluetooth.async_address_reachability_diagnostics` API 返回一个人类可读的字符串,解释原因,适合嵌入错误或对日志消息中。传递一个 `BluetoothReachabilityIntent` 来描述你对设备的需求,因为相关事实各不相同:仅消费 advertisements 的调用者不关心 connectable 路径或连接槽位,而想要连接的设备则关心。 该字符串报告 address 是否在 connectable history 中、是否仅通过 non-connectable advertisements 看到、或从未看到过;哪些 scanners 当前看到它(及其 RSSI 和槽位分配);以及注册、扫描和 connectable 的 scanners 数量。它还特别指出了所有 scanner 都因忙于连接而暂停的情况,这意味着根本无法接收 advertisements。 返回的字符串仅供人类使用;其措辞不稳定,因此不要解析它。 ```python from homeassistant.components import bluetooth from homeassistant.components.bluetooth import BluetoothReachabilityIntent reason = bluetooth.async_address_reachability_diagnostics( hass, "44:44:33:11:23:42", BluetoothReachabilityIntent.CONNECTION ) ``` ### 获取设备的最新 `BluetoothServiceInfoBleak` 最新的 advertisement 和设备数据可以通过 `bluetooth.async_last_service_info` API 获取,它从具有最佳 RSSI 的指定 connectable 类型的 scanner 返回 `BluetoothServiceInfoBleak`。 ```python from homeassistant.components import bluetooth service_info = bluetooth.async_last_service_info(hass, "44:44:33:11:23:42", connectable=True) ``` ### 检查设备是否存在 要确定设备是否仍然存在,请调用 `bluetooth.async_address_present` API。如果你的集成需要设备存在才能认为其可用,此调用很有用。 ```python from homeassistant.components import bluetooth bluetooth.async_address_present(hass, "44:44:33:11:23:42", connectable=True) ``` ### 获取所有已发现设备 要访问先前发现设备的列表,请调用 `bluetooth.async_discovered_service_info` API。只有仍然存在且的设备才在缓存中。 ```python from homeassistant.components import bluetooth service_infos = bluetooth.async_discovered_service_info(hass, connectable=True) ``` ### 按每个 Bluetooth 适配器获取所有已发现设备和 advertisement 数据 要独立访问先前发现设备和每个适配器接收到的 advertisement 数据列表,请调用 `bluetooth.async_scanner_devices_by_address` API。该调用返回 `BluetoothScannerDevice` 对象列表。相同的设备和 advertisement 数据可能出现多次,每个到达它的 Bluetooth 适配器出现一次。 ```python from homeassistant.components import bluetooth device = bluetooth.async_scanner_devices_by_address(hass, "44:44:33:11:23:42", connectable=True) # device.ble_device 是 bleak `BLEDevice` # device.advertisement 是 bleak `AdvertisementData` # device.scanner 是找到该设备的 scanner ``` ### 触发设备重新发现 当 configuration entry 或 device 从 Home Assistant 中移除时,触发其 address 的重新发现,以确保它们无需重启 Home Assistant 即可设置为已设置。如果集成在每个 configuration entry 下管理多个设备,可以利用 device registry 的 Bluetooth connection property。 ```python from homeassistant.components import bluetooth bluetooth.async_rediscover_address(hass, "44:44:33:11:23:42") ``` ### 触发一次性 active 扫描 对于 config flow discovery 和其他一次性探测,`bluetooth.async_request_active_scan` 在所有 `AUTO` 模式 scanner 上运行按需 active sweep,而无需等待周期性 rediscovery cadence。它等待 `duration` 秒,以便调用者随后可以读取新发现的 advertisements。`duration` 是可选的;省略时,使用 habluetooth 的按需 sweep duration。调度器将值限制在其允许范围内。并发调用者去重为单个 bus 级 window。 只有 `AUTO` 模式 scanners 受影响;`PASSIVE` 和 `ACTIVE` scanners 是用户明确的选择,保持不变。 ```python from homeassistant.components import bluetooth await bluetooth.async_request_active_scan(hass) ``` ### 清除重新发现的匹配历史 Bluetooth 集成跟踪每个设备已看到哪些 advertisement 字段(manufacturer\_data UUIDs、service\_data UUIDs、service\_uuids),以确定何时触发 discovery。它只检查 UUIDs 是否曾被看到过,而不检查其内容是否已更改。 对于状态更改但保持相同 UUIDs 的设备(如工厂重置或在操作状态之间转换的设备),你可以清除 match history,以便当设备使用不同内容再次广播时允许重新发现。 `bluetooth.async_clear_address_from_match_history` API 清除特定 address 的 match history,而不会立即重新触发 discovery。这与 `async_rediscover_address` 不同,后者清除历史记录并立即使用缓存数据重新触发 discovery。 在以下情况下使用此 API: * 设备被工厂重置(状态更改但 UUIDs 保持不变) * 设备在具有相同 advertisement UUIDs 的操作状态之间转换 * 你想要为未来的 rediscovery 做准备而不立即触发 flow ```python from homeassistant.components import bluetooth # 清除 match history,允许未来的 advertisements 触发 discovery bluetooth.async_clear_address_from_match_history(hass, "44:44:33:11:23:42") ``` :::warning 性能考虑 不要对 advertisement 数据频繁更改的设备使用此 API(例如,在 advertisement 数据中更新温度读数的 sensors)。清除此类设备的 match history 将在每次 advertisement 更改时触发新的 discovery flow,这可能会使系统不堪重负并造成糟糕的用户体验。 此 API 旨在用于不频繁的状态更改,如工厂重置或主要操作模式转换,而不是常规数据更新。 ::: ### 清除缓存的 advertisement 历史 为减少开销,当 `manufacturer_data`、`service_data`、`service_uuids` 和 `name` 字段都与同一 address 先前看到的 advertisement 匹配时,Bluetooth manager 会丢弃 advertisements。这意味着发出不变的 "I am awake" advertisement 的设备将只将第一个数据包交付给你的 callback;后续相同的数据包将被静默去重。 `bluetooth.async_clear_advertisement_history` API 清除单个 address 的缓存 advertisement 状态,使下一个 advertisement 被视为新数据并分发给 callbacks,即使 payload 与前一个完全相同。 这对于通过 GATT 连接到设备读取传感器数据的集成很有用,并且需要知道设备何时再次唤醒;GATT session 结束后,调用 `async_clear_advertisement_history` 以便下一个唤醒 advertisement 被交付。 ```python from homeassistant.components import bluetooth # 从设备断开后,清除缓存的 advertisement # 以便下一个相同的 "I am awake" 数据包被分发给 callbacks bluetooth.async_clear_advertisement_history(hass, "44:44:33:11:23:42") ``` :::note 这仅清除 advertisement 去重状态;它不影响 integration matcher history。如果你还需要未来的 advertisements 重新触发 discovery flows,请使用 `async_clear_address_from_match_history` 或 `async_rediscover_address`。 ::: ### 等待特定 advertisement 要等待特定 advertisement,请调用 `bluetooth.async_process_advertisements` API。 ```python from homeassistant.components import bluetooth def _process_more_advertisements( service_info: BluetoothServiceInfoBleak, ) -> bool: """等待 manufacturer_data 中包含 323 的 advertisement。""" return 323 in service_info.manufacturer_data service_info = await bluetooth.async_process_advertisements( hass, _process_more_advertisements, {"address": discovery_info.address, "connectable": False}, BluetoothScanningMode.ACTIVE, ADDITIONAL_DISCOVERY_TIMEOUT ) ``` 当 `mode` 不是 `PASSIVE` 且 matcher 包含 `address` 时,`timeout` 也会作为 `scan_duration` 转发给 active-scan 调度器,以便在等待 advertisement 时 `AUTO` 模式 scanners 为该 address 翻转 ACTIVE。 ### 注册外部 scanner 提供 Bluetooth adapter 的集成应在 `manifest.json` 的 [`dependencies`](/developers/creating_integration_manifest.md#dependencies) 中添加 `bluetooth`,并被添加到 `bluetooth_adapters` 集成的 [`after_dependencies`](/developers/creating_integration_manifest.md#after-dependencies)。 要注册 external scanner,请调用 `bluetooth.async_register_scanner` API。scanner 必须继承自 `BaseHaScanner`。 如果 scanner 需要 connection slot 管理以避免使适配器过载,请通过 `connection_slots` 参数以整数形式传递连接槽位数。 ```python from homeassistant.components import bluetooth cancel = bluetooth.async_register_scanner(hass, scanner, connection_slots=slots) ``` scanner 需要将 advertisement 数据以 `BluetoothServiceInfoBleak` 对象的形式提供给中央 Bluetooth manager。将数据发送到中央 manager 所需的 callback 可以通过 `bluetooth.async_get_advertisement_callback` API 获取。 ```python callback = bluetooth.async_get_advertisement_callback(hass) callback(BluetoothServiceInfoBleak(...)) ``` ### 移除外部 scanner 要永久移除 external scanner,请使用 scanner 的 `source`(MAC 地址)调用 `bluetooth.async_remove_scanner` API。这将移除与该 scanner 关联的任何 advertisement history。 ```python from homeassistant.components import bluetooth bluetooth.async_remove_scanner(hass, source) ``` --- url: /developers/core/bluetooth/bluetooth_fetching_data.md --- ## 选择获取数据的方法 如果设备通知更新的主要方式是 Bluetooth advertisements,且其主要功能是 sensor、binary sensor 或触发事件: * 如果所有 sensors 都通过 Bluetooth advertisements 更新:[`PassiveBluetoothProcessorCoordinator`](#passivebluetoothprocessorcoordinator) * 如果某些 sensors 需要 active connection:[`ActiveBluetoothProcessorCoordinator`](#activebluetoothprocessorcoordinator) 如果设备通知更新的主要方式是 Bluetooth advertisements,且其主要功能**不是** sensor、binary sensor 或触发事件: * 如果所有 entities 都通过 Bluetooth advertisements 更新:[`PassiveBluetoothCoordinator`](#passivebluetoothcoordinator) * 如果需要 active connections:[`ActiveBluetoothDataUpdateCoordinator`](#activebluetoothcoordinator) 如果你的设备仅通过 active Bluetooth connection 通信而不使用 Bluetooth advertisements: * [`DataUpdateCoordinator`](/developers/integration_fetching_data.md) ## BluetoothProcessorCoordinator `ActiveBluetoothProcessorCoordinator` 和 `PassiveBluetoothProcessorCoordinator` 大幅减少了创建主要功能为 sensor、binary sensors 或触发事件的集成所需的代码。通过将传入 processor coordinators 的数据格式化为 `PassiveBluetoothDataUpdate` 对象,框架可以负责按需创建 entities,并允许使用最小的 `sensor` 和 `binary_sensor` platform 实现。 这些框架要求来自 library 的数据被格式化为 `PassiveBluetoothDataUpdate`,如下所示: ```python @dataclasses.dataclass(frozen=True) class PassiveBluetoothEntityKey: """Key for a passive bluetooth entity. Example: key: temperature device_id: outdoor_sensor_1 """ key: str device_id: str | None @dataclasses.dataclass(frozen=True) class PassiveBluetoothDataUpdate(Generic[_T]): """Generic bluetooth data.""" devices: dict[str | None, DeviceInfo] = dataclasses.field(default_factory=dict) entity_descriptions: Mapping[ PassiveBluetoothEntityKey, EntityDescription ] = dataclasses.field(default_factory=dict) entity_names: Mapping[PassiveBluetoothEntityKey, str | None] = dataclasses.field( default_factory=dict ) entity_data: Mapping[PassiveBluetoothEntityKey, _T] = dataclasses.field( default_factory=dict ) ``` ### PassiveBluetoothProcessorCoordinator 使用 `PassiveBluetoothProcessorCoordinator` 的集成 `__init__.py` 的 `async_setup_entry` 示例: ```python import logging from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.components.bluetooth import BluetoothScanningMode from homeassistant.components.bluetooth.passive_update_processor import ( PassiveBluetoothProcessorCoordinator, ) from homeassistant.const import Platform PLATFORMS: list[Platform] = [Platform.SENSOR] from your_library import DataParser _LOGGER = logging.getLogger(__name__) type ExampleConfigEntry = ConfigEntry[PassiveBluetoothProcessorCoordinator] async def async_setup_entry(hass: HomeAssistant, entry: ExampleConfigEntry) -> bool: """Set up example BLE device from a config entry.""" address = entry.unique_id data = DataParser() coordinator = PassiveBluetoothProcessorCoordinator( hass, _LOGGER, address=address, mode=BluetoothScanningMode.ACTIVE, update_method=data.update, ) entry.runtime_data = coordinator await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) entry.async_on_unload( # 仅在所有 platforms 都有机会订阅后才开始 coordinator.async_start() ) return True ``` `sensor.py` 示例: ```python from homeassistant.components.bluetooth.passive_update_processor import ( PassiveBluetoothDataProcessor, PassiveBluetoothDataUpdate, PassiveBluetoothEntityKey, PassiveBluetoothProcessorEntity, ) from homeassistant.components.sensor import SensorEntity from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import ExampleConfigEntry def sensor_update_to_bluetooth_data_update(parsed_data): """Convert a sensor update to a Bluetooth data update.""" # 此函数必须将 parsed_data # 从 library 的 update_method 转换为 `PassiveBluetoothDataUpdate` # 参见上面的结构 return PassiveBluetoothDataUpdate( devices={}, entity_descriptions={}, entity_data={}, entity_names={}, ) async def async_setup_entry( hass: HomeAssistant, entry: ExampleConfigEntry, async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the example BLE sensors.""" coordinator = entry.runtime_data processor = PassiveBluetoothDataProcessor(sensor_update_to_bluetooth_data_update) entry.async_on_unload( processor.async_add_entities_listener( ExampleBluetoothSensorEntity, async_add_entities ) ) entry.async_on_unload(coordinator.async_register_processor(processor)) class ExampleBluetoothSensorEntity(PassiveBluetoothProcessorEntity, SensorEntity): """Representation of an example BLE sensor.""" @property def native_value(self) -> float | int | str | None: """Return the native value.""" return self.processor.entity_data.get(self.entity_key) ``` ### ActiveBluetoothProcessorCoordinator `ActiveBluetoothProcessorCoordinator` 的功能与 `PassiveBluetoothProcessorCoordinator` 几乎相同, 但还会基于 `needs_poll_method` 和 `poll_method` 函数在设备的 Bluetooth advertisement 更改时建立 active connection 来轮询数据。`sensor.py` 的实现 与 `PassiveBluetoothProcessorCoordinator` 相同。 使用 `ActiveBluetoothProcessorCoordinator` 的集成 `__init__.py` 的 `async_setup_entry` 示例: ```python import logging from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import CoreState, HomeAssistant from homeassistant.components.bluetooth import BluetoothScanningMode from homeassistant.components.bluetooth import ( BluetoothScanningMode, BluetoothServiceInfoBleak, async_ble_device_from_address, ) from homeassistant.const import Platform from homeassistant.components.bluetooth.active_update_processor import ( ActiveBluetoothProcessorCoordinator, ) PLATFORMS: list[Platform] = [Platform.SENSOR] from your_library import DataParser _LOGGER = logging.getLogger(__name__) type ExampleConfigEntry = ConfigEntry[ActiveBluetoothProcessorCoordinator] async def async_setup_entry(hass: HomeAssistant, entry: ExampleConfigEntry) -> bool: """Set up example BLE device from a config entry.""" address = entry.unique_id assert address is not None data = DataParser() def _needs_poll( service_info: BluetoothServiceInfoBleak, last_poll: float | None ) -> bool: return ( hass.state == CoreState.running and data.poll_needed(service_info, last_poll) and bool( async_ble_device_from_address( hass, service_info.device.address, connectable=True ) ) ) async def _async_poll(service_info: BluetoothServiceInfoBleak): if service_info.connectable: connectable_device = service_info.device elif device := async_ble_device_from_address( hass, service_info.device.address, True ): connectable_device = device else: # 我们没有可用于轮询该设备的 Bluetooth controller raise RuntimeError( f"No connectable device found for {service_info.device.address}" ) return await data.async_poll(connectable_device) coordinator = ActiveBluetoothProcessorCoordinator( hass, _LOGGER, address=address, mode=BluetoothScanningMode.PASSIVE, update_method=data.update, needs_poll_method=_needs_poll, poll_method=_async_poll, # 我们将使用来自 non-connectable 设备的 advertisements, # 因为如果需要轮询它们,我们会用 BLEDevice 换取 connectable 的一个 connectable=False, ) entry.runtime_data = coordinator await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) entry.async_on_unload( # 仅在所有 platforms 都有机会订阅后才开始 coordinator.async_start() ) return True ``` #### 请求 active 扫描节奏 `PassiveBluetoothProcessorCoordinator` 和 `ActiveBluetoothProcessorCoordinator` 接受两个可选的关键字参数 `scan_interval` 和 `scan_duration`,当 coordinator 启动时它们会被转发给 Bluetooth manager。它们请求任何 `AUTO` 模式 scanner 为该 coordinator 的 address 提供周期性 active scan window,以便设备持续发出包含完整 payload 的 advertisements,而无需永久将 scanner 切换为 `ACTIVE` 模式。 这对于在某些时间未被 actively scanned 后会回退到 connectable poll 的设备很有用;选择一个短于该回退时间的 `scan_interval` 和一个足够长的 `scan_duration` 以捕获下一个 advertisement。 ```python coordinator = ActiveBluetoothProcessorCoordinator( hass, _LOGGER, address=address, mode=BluetoothScanningMode.PASSIVE, update_method=data.update, needs_poll_method=_needs_poll, poll_method=_async_poll, connectable=False, # 请求 AUTO 模式的 scanners 每 165 秒为 ACTIVE 翻转 10 秒 scan_interval=165.0, scan_duration=10.0, ) ``` 两个参数都默认为 `None`,让底层调度器保持其内置 cadence。`PASSIVE` 和 `ACTIVE` scanners 是用户明确的选择,不受影响;只有 `AUTO` 模式的 scanners 会遵循该请求。 ## BluetoothCoordinator `ActiveBluetoothDataUpdateCoordinator` 和 `PassiveBluetoothCoordinator` coordinators 的功能类似于 `DataUpdateCoordinators`,只是它们由传入的 advertisement 数据驱动,而不是轮询。 :::note `_async_handle_unavailable` 回调依赖于 Bluetooth 栈检测到设备已停止广播。在 macOS 上,CoreBluetooth 会缓存 advertisement 数据,可能不会将设备消失暴露给应用层,因此即使设备已停止广播,`_async_handle_unavailable` 也可能永远不会触发。 ::: ### PassiveBluetoothCoordinator 以下是一个 `PassiveBluetoothDataUpdateCoordinator` 的示例。传入的数据通过 `_async_handle_bluetooth_event` 接收,并由集成的 library 处理。 ```python import logging from typing import TYPE_CHECKING from homeassistant.components import bluetooth from homeassistant.components.bluetooth.active_update_coordinator import ( PassiveBluetoothDataUpdateCoordinator, ) from homeassistant.core import CoreState, HomeAssistant, callback if TYPE_CHECKING: from bleak.backends.device import BLEDevice class ExamplePassiveBluetoothDataUpdateCoordinator( PassiveBluetoothDataUpdateCoordinator[None] ): """Class to manage fetching example data.""" def __init__( self, hass: HomeAssistant, logger: logging.Logger, ble_device: BLEDevice, device: YourLibDevice, ) -> None: """Initialize example data coordinator.""" super().__init__( hass=hass, logger=logger, address=ble_device.address, mode=bluetooth.BluetoothScanningMode.ACTIVE, connectable=False, ) self.device = device @callback def _async_handle_unavailable( self, service_info: bluetooth.BluetoothServiceInfoBleak ) -> None: """Handle the device going unavailable.""" @callback def _async_handle_bluetooth_event( self, service_info: bluetooth.BluetoothServiceInfoBleak, change: bluetooth.BluetoothChange, ) -> None: """Handle a Bluetooth event.""" # 你的设备应处理传入的 advertisement 数据 ``` ### ActiveBluetoothDataUpdateCoordinator 以下是一个 `ActiveBluetoothDataUpdateCoordinator` 的示例。传入的数据通过 `_async_handle_bluetooth_event` 接收,并由集成的 library 处理。 传递给 `needs_poll_method` 的方法在每次 Bluetooth advertisement 更改时被调用,以确定是否应调用传递给 `poll_method` 的方法来与设备建立 active connection 以获取额外数据。 ```python import logging from typing import TYPE_CHECKING from homeassistant.components import bluetooth from homeassistant.components.bluetooth.active_update_coordinator import ( ActiveBluetoothDataUpdateCoordinator, ) from homeassistant.core import CoreState, HomeAssistant, callback if TYPE_CHECKING: from bleak.backends.device import BLEDevice class ExampleActiveBluetoothDataUpdateCoordinator( ActiveBluetoothDataUpdateCoordinator[None] ): """Class to manage fetching example data.""" def __init__( self, hass: HomeAssistant, logger: logging.Logger, ble_device: BLEDevice, device: YourLibDevice, ) -> None: """Initialize example data coordinator.""" super().__init__( hass=hass, logger=logger, address=ble_device.address, needs_poll_method=self._needs_poll, poll_method=self._async_update, mode=bluetooth.BluetoothScanningMode.ACTIVE, connectable=True, ) self.device = device @callback def _needs_poll( self, service_info: bluetooth.BluetoothServiceInfoBleak, seconds_since_last_poll: float | None, ) -> bool: # 仅在 hass 正在运行、需要轮询、 # 并且我们实际有办法连接到设备时才轮询 return ( self.hass.state == CoreState.running and self.device.poll_needed(seconds_since_last_poll) and bool( bluetooth.async_ble_device_from_address( self.hass, service_info.device.address, connectable=True ) ) ) async def _async_update( self, service_info: bluetooth.BluetoothServiceInfoBleak ) -> None: """Poll the device.""" @callback def _async_handle_unavailable( self, service_info: bluetooth.BluetoothServiceInfoBleak ) -> None: """Handle the device going unavailable.""" @callback def _async_handle_bluetooth_event( self, service_info: bluetooth.BluetoothServiceInfoBleak, change: bluetooth.BluetoothChange, ) -> None: """Handle a Bluetooth event.""" # 你的设备应处理传入的 advertisement 数据 ``` --- url: /developers/core/entity.md --- 关于实体的通用介绍,请参见 [entities architecture](/developers/architecture/devices-and-services.md)。 ## 基础实现 下面是一个 switch entity 的示例,它在内存中跟踪其 state。 此外,示例中的 switch 代表设备的主要 feature, 意味着 entity 与其 device 同名。 请查阅 [Entity naming](#entity-naming) 了解如何为 entity 设置自己的名称。 ```python from homeassistant.components.switch import SwitchEntity class MySwitch(SwitchEntity): _attr_has_entity_name = True def __init__(self): self._is_on = False self._attr_device_info = ... # 用于自动 device 注册 self._attr_unique_id = ... @property def is_on(self): """If the switch is currently on or off.""" return self._is_on def turn_on(self, **kwargs): """Turn the switch on.""" self._is_on = True def turn_off(self, **kwargs): """Turn the switch off.""" self._is_on = False ``` 构建一个 switch entity 就这么多内容!继续阅读以了解更多,或者查看 [视频教程](https://youtu.be/Cfasc9EgbMU?t=737)。 ## 更新 entity Entity 代表一个 device。有多种策略可以让你的 entity 与 device 的 state 保持同步,其中最常用的是 polling。 ### 轮询 在 polling 模式下,Home Assistant 会定时(取决于 component 的更新间隔)向 entity 请求最新的 state。当 `should_poll` 属性返回 `True`(默认值)时,Home Assistant 会轮询该 entity。你可以使用 `update()` 或异步方法 `async_update()` 来实现更新逻辑。该方法应从 device 获取最新的 state,并将其存储在 instance variable 中,以便 properties 返回它。 ### 订阅更新 当你订阅 updates 时,你的代码需要负责通知 Home Assistant 有新的更新可用。请确保 `should_poll` 属性返回 `False`。 每当通过订阅收到新的 state 时,你可以通过调用 `schedule_update_ha_state()` 或异步回调 `async_schedule_update_ha_state()` 来通知 Home Assistant 有更新可用。如果希望 Home Assistant 在将更新写入 Home Assistant 之前先调用你的 update method,请将布尔值 `True` 传入该方法。 ## 通用属性 Entity 基类有一些在所有 Home Assistant entity 中通用的属性。这些属性可以添加到任何 entity 中,无论其类型如何。所有这些属性都是可选的,不需要实现。 这些属性在 state 写入 state machine 时总是会被调用。 :::tip Properties 应该只从内存返回信息,而不要执行 I/O(如网络请求)。请实现 `update()` 或 `async_update()` 来获取数据。 由于这些 properties 在 state 写入 state machine 时总是会被调用,因此在 property 中应尽可能少地执行工作。 为了避免在 property 方法中进行计算,请设置相应的 [entity 类属性或实例属性](#entity-class-or-instance-attributes),或者如果值永不变化,请使用 [entity descriptions](#entity-description)。 ::: | Name | Type | Default | Description | ------------------------ | ------------------------------| ------- | ----------- | assumed\_state | `bool` | `False` | 如果 state 基于我们的假设而非从 device 读取,则返回 `True`。 | attribution | `str \| None` | `None` | API 提供商要求的品牌 text。 | available | `bool` | `True` | 指示 Home Assistant 是否能够读取 state 或控制底层 device,更多详情请见 [entity-unavailable](/developers/core/integration-quality-scale/rules/entity-unavailable.md)。 | device\_class | `str \| None` | `None` | 对 device 类型的额外分类。每个 domain 都有自己的定义。device class 可能附带对计量单位和受支持 features 的额外要求。 | entity\_picture | `str \| None` | `None` | 用于显示 entity 的图片 URL。 | extra\_state\_attributes | `dict \| None` | `None` | 存储在 state machine 中的额外信息。它应该是进一步解释 state 的信息,而不应该是 firmware 版本之类的静态信息。 | has\_entity\_name | `bool` | `False` | 如果 entity 的 `name` 属性代表 entity 本身(新集成所必需),则返回 `True`。下面有更详细的说明。 | name | `str \| None` | `None` | Entity 的名称。避免硬编码自然语言名称,请改用 [translated name](/developers/internationalization/core.md#name-of-entities)。 | should\_poll | `bool` | `True` | Home Assistant 是否应向 entity 检查更新的 state。如果设为 `False`,entity 需要通过调用其中一个 [schedule update 方法](integration_fetching_data.md#push-vs-poll) 来通知 Home Assistant 新更新。 | state | `str \| int \| float \| None` | `None` | Entity 的 state。在大多数情况下,这由 domain base entity 实现,集成不应自行实现。 | supported\_features | `int \| None` | `None` | 标志 entity 支持的 features。各 domain 有自己的定义。 | translation\_key | `str \| None` | `None` | 用于在集成的 `strings.json` 的 [`entity` section](/developers/internationalization/core.md#state-of-entities) 中查找 entity state 的 translations,并将 state 翻译为匹配的 [icon](#icons)。 | | translation\_placeholders | `dict \| None` | `None` | [translated entity name](/developers/internationalization/core.md#name-of-entities) 的占位符定义。 :::warning 允许更改 `device_class`、`supported_features` 或包含在 domain 的 `capability_attributes` 中的任何属性。但是,由于这些 entity 属性通常不应发生变化,且某些 entity consumers 可能无法以较高的速率更新它们,我们建议仅在绝对必要时更改它们,并保持适度的间隔。 例如,此类更改会导致 voice assistant 集成与支持它们的云服务重新同步。 ::: :::warning 产生大量 state 变更的 entity 在 `extra_state_attributes` 也频繁变化时,会迅速增加 database 的大小。通过移除非关键 attributes 或创建额外的 `sensor` entity,来最小化这些 entity 的 `extra_state_attributes` 数量。 ::: ## Registry 属性 以下属性用于填充 entity 和 device registries。每次 entity 被添加到 Home Assistant 时都会读取它们。这些属性只有在 `unique_id` 不为 None 时才会生效。 | Name | Type | Default | Description | ------------------------------- | --------------------------------------- | ------- | ----------- | device\_info | `DeviceInfo \| None` | `None` | [Device registry](/developers/device_registry_index.md) 描述符,用于 [automatic device registration](/developers/device_registry_index.md#automatic-registration-through-an-entity)。 | entity\_category | `EntityCategory \| None` | `None` | 非 primary entity 的分类。对于允许更改 device 配置的 entity(例如 switch entity,可以开启和关闭 switch 的背景照明),设为 `EntityCategory.CONFIG`。对于暴露 device 的配置参数或 diagnostics 但不允许更改的 entity(例如显示 RSSI 或 MAC address 的 sensor),设为 `EntityCategory.DIAGNOSTIC`。对于触发 device 识别机制的 button entity(使用 `IDENTIFY` device class),也请使用它。 | | entity\_registry\_enabled\_default | `bool` | `True` | 指示 entity 首次添加到 entity registry 时应启用还是禁用。这包括快速变化的 diagnostic entity 或假定较少使用的 entity。例如,暴露 RSSI 或 battery voltage 的 sensor 通常应设为 `False`,以防止这些 entity 引起不必要的(记录的)state 变更或 UI 杂乱。 | | entity\_registry\_visible\_default | `bool` | `True` | 指示 entity 首次添加到 entity registry 时应隐藏还是可见。 | | unique\_id | `str \| None` | `None` | 该 entity 的唯一标识符。它必须在平台内(如 `light.hue`)唯一。它不应可由用户配置或更改。[了解更多。](entity_registry_index.md#unique-id-requirements) | ## 附加属性 以下属性也可用于 entity,但应谨慎使用。这些属性在 state 写入 state machine 时总是会被调用。 | Name | Type | Default | Description | ------------------------------- | ---------------------------- | ------- | ----------- | capability\_attributes | `dict \| None` | `None` | 存储在 entity registry 中的 state attributes。该属性由 domain base entity 实现,集成不应自行实现。 | force\_update | `bool` | `False` | 每次更新都写入 state machine,即使数据相同。示例用法:当你直接从连接的 sensor 读取值而不是从 cache 读取时。请谨慎使用,会频繁写入 state machine。 | | icon | `str \| None` | `None` | 在前端使用的 icon。不建议使用此属性。[关于使用 icons 的更多信息](#icons)。 | | state\_attributes | `dict \| None` | `None` | Base domain 的 state attributes。该属性由 domain base entity 实现,集成不应自行实现。 | unit\_of\_measurement | `str \| None` | entity state 所表示的计量单位。在大多数情况下(例如 `number` 和 `sensor` domain),这由 domain base entity 实现,集成不应自行实现。 ## 系统属性 以下属性由 Home Assistant 使用和控制,集成不应 override。 | Name | Type | Default | Description | ------- | ------- | ------- | ----------- | enabled | `bool` | `True` | 指示 entity 是否在 entity registry 中启用。如果平台不支持 entity registry,也返回 `True`。被禁用的 entity 不会添加到 Home Assistant。 | ## Entity 命名 避免将 entity 的名称设置为硬编码的英文字符串,而是,名称应该被 [translated](/developers/internationalization/core.md#name-of-entities)。名称不应被翻译的示例包括专有名词、model 名称以及由第三方库提供的名称。 一些 entity 会根据其 device class 自动命名,这包括 [`binary_sensor`](/developers/core/entity/binary-sensor.md)、[`button`](/developers/core/entity/button.md)、[`number`](/developers/core/entity/number.md) 和 [`sensor`](/developers/core/entity/sensor.md) entity,在许多情况下不需要命名。 例如,一个未命名且 device class 设为 `temperature` 的 sensor 将被命名为 "Temperature"。 :::note 如果 entity 提供了 entity name 的 translations,所使用的名称取决于创建时的系统(backend)语言,而不是用户的 UI 语言。例如,如果你的 backend 设为德语,新 entity 将以德语命名——即使用户后来将 UI 切换为法语。更改 backend 语言只影响更改后创建的 entity;现有 entity 保留其原始名称。 ::: ### `has_entity_name` True(新集成必需) Entity 的 name 属性只标识 entity 所代表的数据点,不应包含 device 名称或 entity 类型。因此,对于代表其 device 功耗的 sensor,这应该是 "Power usage"。 如果 entity 代表 device 的单一主要 feature,该 entity 的 name 属性通常应返回 `None`。 Device 的"主要 feature"例如是智能灯泡的 `LightEntity`。 `friendly_name` state attribute 通过将 entity name 与 device name 组合生成,规则如下: * Entity 不是 device 的成员:`friendly_name = entity.name` * Entity 是 device 的成员且 `entity.name` 不为 `None`:`friendly_name = f"{device.name} {entity.name}"` * Entity 是 device 的成员且 `entity.name` 为 `None`:`friendly_name = f"{device.name}"` `entity_id` 通过将 entity name 与 device name 组合生成,规则如下: * Entity 不是 device 的成员,例如 helper "Everyone is home":`entity_id = binary_sensor.everyone_is_home` * Entity 是 device 的成员且 `entity.name` 不为 `None`,例如名为 "nightlight" 的 device 的电池:`entity_id = sensor.nightlight_battery` * Entity 是 device 的成员且 `entity.name` 为 `None`,例如名为 "nightlight" 的 device 的 light:`entity_id = light.nightlight` Entity name 应以大写开头,其余单词为小写(除非是专有名词或大写缩写)。 #### 作为 device 主要 feature 的 switch entity 示例 *注意:示例使用类属性实现 properties,其他实现方式请参见 [Property implementation](#property-implementation)。* *注意:示例不完整,必须实现 `unique_id` 属性,并且 entity 必须 [与 device 注册](/developers/device_registry_index.md#defining-devices)。* ```python from homeassistant.components.switch import SwitchEntity class MySwitch(SwitchEntity): _attr_has_entity_name = True _attr_name = None ``` #### 作为非 device 主要 feature 或非 device 一部分的 switch entity 示例: *注意:示例使用类属性实现 properties,其他实现方式* *请参见 [Property implementation](#property-implementation)。* *注意:如果 entity 是 device 的一部分,必须实现 `unique_id` 属性,并且 entity 必须 [与 device 注册](/developers/device_registry_index.md#defining-devices)。* ```python from homeassistant.components.switch import SwitchEntity class MySwitch(SwitchEntity): _attr_has_entity_name = True @property def translation_key(self): """Return the translation key to translate the entity's name and states.""" return "my_switch" ``` #### 非翻译的 switch entity 示例(非 device 主要 feature 或非 device 一部分): ```python from homeassistant.components.switch import SwitchEntity class MySwitch(SwitchEntity): _attr_has_entity_name = True @property def name(self): """Name of the entity.""" return "Model X" ``` ### `has_entity_name` 未实现或为 False(已弃用) Entity 的 name 属性可以是 device 名称与 entity 所代表的数据点的组合。 ## Property 实现 ### Property 函数 为每个 property 编写 property method 只需要几行代码, 例如 ```python class MySwitch(SwitchEntity): @property def icon(self) -> str | None: """Icon of the entity.""" return "mdi:door" ... ``` ### Entity 类属性或实例属性 另一种较短的形式是,按照以下任一模式设置 Entity 类属性或实例属性: ```python class MySwitch(SwitchEntity): _attr_icon = "mdi:door" ... ``` ```python class MySwitch(SwitchEntity): def __init__(self, icon: str) -> None: self._attr_icon = icon ... ``` 这与第一个示例完全相同,但依赖于基类中 property 的默认 实现。该属性的名称以 `_attr_` 开头,后跟 property 名称。例如,默认 的 `device_class` property 返回 `_attr_device_class` 类属性。 并非所有 entity 类都支持使用 `_attr_` 属性来实现其 entity 特定属性,请参阅相应 entity 类的文档以获取详细信息。 :::tip 如果集成需要访问自己的 properties,应访问 property(`self.name`),而不是类属性或实例属性(`self._attr_name`)。 ::: ### Entity 描述 设置 entity property 的第三种方法是使用 entity description。为此,请在 `Entity` 实例上设置一个名为 `entity_description` 的属性,其值为 `EntityDescription` 实例。Entity description 是一个 dataclass,其 attributes 对应于大多数可用的 `Entity` properties。每个支持 entity platform 的 entity 集成(例如 `switch` 集成)都会定义自己的 `EntityDescription` 子类,使用 entity descriptions 的实现 platform 应使用该子类。 默认情况下,`EntityDescription` 实例有一个必需的 attribute 名为 `key`。这是一个字符串,旨在对实现 platform 的所有 entity descriptions 保持唯一。该 attribute 的一个常见用例是将其包含在描述 entity 的 `unique_id` 中。 使用 entity descriptions 的主要好处是,它以一种声明式的方式定义了 platform 的不同 entity types,当存在许多不同 entity type 时,这使得代码更易读。 ### 示例 下面的代码片段示例说明了何时应实现 property 函数、何时使用类属性或实例属性以及何时使用 entity descriptions 的最佳实践。 ```py from __future__ import annotations from collections.abc import Callable from dataclasses import dataclass from example import ExampleDevice, ExampleException from homeassistant.components.sensor import ( SensorDeviceClass, SensorEntity, SensorEntityDescription, SensorStateClass, ) from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( EntityCategory, UnitOfElectricCurrent, ) from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .const import DOMAIN, LOGGER @dataclass(kw_only=True) class ExampleSensorEntityDescription(SensorEntityDescription): """Describes Example sensor entity.""" exists_fn: Callable[[ExampleDevice], bool] = lambda _: True value_fn: Callable[[ExampleDevice], StateType] SENSORS: tuple[ExampleSensorEntityDescription, ...] = ( ExampleSensorEntityDescription( key="estimated_current", native_unit_of_measurement=UnitOfElectricCurrent.MILLIAMPERE, device_class=SensorDeviceClass.CURRENT, state_class=SensorStateClass.MEASUREMENT, value_fn=lambda device: device.power, exists_fn=lambda device: bool(device.max_power), ), ) async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Example sensor based on a config entry.""" device: ExampleDevice = entry.runtime_data async_add_entities( ExampleSensorEntity(device, description) for description in SENSORS if description.exists_fn(device) ) class ExampleSensorEntity(SensorEntity): """Represent an Example sensor.""" entity_description: ExampleSensorEntityDescription _attr_entity_category = ( EntityCategory.DIAGNOSTIC ) # 这对所有 ExampleSensorEntity 实例是通用的 def __init__( self, device: ExampleDevice, entity_description: ExampleSensorEntityDescription ) -> None: """Set up the instance.""" self._device = device self.entity_description = entity_description self._attr_available = False # 这会覆盖默认值 self._attr_unique_id = f"{device.serial}_{entity_description.key}" def update(self) -> None: """Update entity state.""" try: self._device.update() except ExampleException: if self.available: # 读取当前 state,不需要加 _attr_ 前缀 LOGGER.warning("Update failed for %s", self.entity_id) self._attr_available = False # 设置 property 值 return self._attr_available = True # 这里不需要检查 device 是否可用 self._attr_native_value = self.entity_description.value_fn( self._device ) # 更新 "native_value" property ``` ## 生命周期钩子 使用这些 lifecycle hooks 在发生某些事件时执行代码。所有 lifecycle hooks 都是异步方法。 ### `async_added_to_hass()` 当 entity 被分配 entity\_id 和 hass 对象后,且第一次写入 state machine 之前调用。示例用途:恢复 state、订阅 updates 或设置 callback/dispatch function/listener。 ### `async_will_remove_from_hass()` 当 entity 即将从 Home Assistant 移除时调用。示例用途:断开与 server 的连接或取消订阅 updates。 ## 图标 Home Assistant 中的每个 entity 都有一个 icon,用作前端中更易识别 entity 的视觉指示器。Home Assistant 使用 [Material Design Icons](https://materialdesignicons.com/) icon 集。 在大多数情况下,Home Assistant 会根据 entity 的 domain、`device_class` 和 `state` 自动选择一个 icon。如果可能,优先使用默认 icon,以提供一致的体验并避免用户混淆。但是,也可以 override 默认值并为 entity 提供自定义 icon。 无论提供什么 icon,用户总可以在前端按照自己的喜好自定义 icon。 有两种方式为 entity 提供自定义 icon:通过提供 icon translations 或通过提供 icon identifier。 ### 图标翻译 这是为 entity 提供自定义 icon 的首选方式。Icon translations 的工作方式类似于 [常规 translations](/developers/internationalization/core.md#state-of-entities),但它们不是翻译 entity 的 state,而是将 entity 的 states 翻译为 icons。 请注意,translated states 必须像所有其他 translation key 一样是 `snake_case`。 Entity 的 `translation_key` 属性定义了要使用的 icon translation。该属性用于在集成的 `icons.json` 文件的 `entity` section 中查找 translation。 为了区分 entity 及其 translations,请提供不同的 translation keys。以下示例展示了 Moon domain `sensor` entity 的 `icons.json`,其 `translation_key` 属性设为 phase: ```json { "entity": { "sensor": { "phase": { "default": "mdi:moon", "state": { "new_moon": "mdi:moon-new", "first_quarter": "mdi:moon-first-quarter", "full_moon": "mdi:moon-full", "last_quarter": "mdi:moon-last-quarter" } } } } } ``` 请注意,icons 以 `mdi:` 开头,后跟一个 [identifier](https://materialdesignicons.com/)。当 entity 的 state 不在 `state` section 中时,使用 `default` icon。`state` section 是可选的,如果未提供,`default` icon 将用于所有 states。 在前端显示 state attributes 的 icons 时,也可以为 entity state attributes 提供 icons。示例包括 climate presets 和 fan modes。无法为其他 state attributes 提供 icons。以下示例为 `climate` entity 提供 icons,其 `translation_key` 属性设为 `ubercool`。该 entity 有一个 `preset_mode` state attribute,可以设为 `vacation` 或 `night`。前端将在例如 climate card 中使用它们。 请注意,translated state attributes 必须像所有其他 translation key 一样是 `snake_case`。 ```json { "entity": { "climate": { "ubercool": { "state_attributes": { "preset_mode": { "default": "mdi:confused", "state": { "vacation": "mdi:umbrella-beach", "night": "mdi:weather-night" } } } } } } } ``` ### 图标属性 为 entity 提供 icon 的另一种方法是设置 entity 的 `icon` 属性,该属性返回一个引用 `mdi` icon 的字符串。由于该属性是一个 method,与 icon translations 不同,它可以根据自定义逻辑返回不同的 icons。例如,可以像下面示例中那样根据 state 计算 icon,或者根据不属于 entity state 的内容返回不同的 icons。 ```python class MySwitch(SwitchEntity): @property def icon(self) -> str | None: """Icon of the entity, based on time.""" if now().hour < 12: return "mdi:weather-night" return "mdi:weather-sunny" ... ``` 无法通过 `icon` 属性为 state attributes 提供 icons。请注意,不建议使用 `icon` 属性;优先使用上述的 icon translations。 ## 从 recorder history 中排除状态属性 不适合进行 state history 记录的 state attributes 应通过将其包含在 `_entity_component_unrecorded_attributes` 或 `_unrecorded_attributes` 中来排除在 state history 记录之外。 * `_entity_component_unrecorded_attributes: frozenset[str]` 可在 base component 类中设置,例如在 `light.LightEntity` 中 * `_unrecorded_attributes: frozenset[str]` 可在集成的 platform 中设置,例如在 platform `hue.light` 中定义的 entity 类中。 `MATCH_ALL` 常量可用于排除所有 attributes,而无需逐一列出。对于提供未知 attributes 的集成,或者只是想排除所有而不逐一列出时,这非常有用。 使用 `MATCH_ALL` 常量不会停止对 `device_class`、`state_class`、`unit_of_measurement` 和 `friendly_name` 的记录,因为它们还可能服务于其他目的,因此不应排除在记录之外。 被排除在记录之外的 platform state attributes 示例包括 `image` entity 的 `entity_picture` attribute(一段时间后将会失效)和 `fan` entity 的 `preset_modes` attribute(不太可能变化)。 被排除在记录之外的集成特定 state attributes 示例包括 platform `trafikverket.camera` 中的 `description` 和 `location` state attributes(不会变化)。 :::tip `_entity_component_unrecorded_attributes` 和 `_unrecorded_attributes` 必须声明为类属性;实例属性将被忽略。 ::: ## 更改 entity model 如果你想为 entity 或其任何 subtype(light、switch 等)添加新 feature,你需要先在我们的 [architecture repo](https://github.com/home-assistant/architecture/discussions) 中提出。只考虑各种厂商通用的 features。 --- url: /developers/core/entity/ai-task.md --- AI Task 实体为 Home Assistant 中的 AI 驱动任务执行提供了一个框架。它使集成能够为根据自然语言指令生成数据、内容或执行结构化任务提供 AI 能力。 AI Task 实体派生自 [`homeassistant.components.ai_task.AITaskEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/ai_task/entity.py)。实体状态会跟踪最后一次活动的时间戳,用于监控目的。 ## 属性 *此实体没有属性。* ## 支持的功能 支持的功能通过使用 `AITaskEntityFeature` 枚举中的值来定义,并使用按位或(`|`)运算符进行组合。 | 值 | 描述 | ----- | ----------- | `GENERATE_DATA` | 实体可以根据自然语言指令生成数据。 | `SUPPORT_ATTACHMENTS` | 实体支持作为生成数据和图像任务一部分的附件。 | `GENERATE_IMAGE` | 实体可以根据自然语言指令生成图像。 ## 方法 ### 生成数据 此方法根据自然语言指令处理数据生成任务。 ```python from homeassistant.components.ai_task import AITaskEntity, GenDataTask, GenDataTaskResult class MyAITaskEntity(AITaskEntity): """Represent an AI Task entity.""" async def _async_generate_data( self, task: GenDataTask, chat_log: ChatLog ) -> GenDataTaskResult: """Handle a generate data task.""" # Process the task instructions and generate appropriate data # Use the chat_log to maintain conversation context. A common # pattern is to share an implementation between conversation and AI # task entities to process the chat log. # await self._async_handle_chat_log( # chat_log, # task.structure, # task.attachments # ) text = ... if not task.structure: return GenDataTaskResult( conversation_id=chat_log.conversation_id, data=text ) data = ... # process the text to match the structure return GenDataTaskResult( conversation_id=chat_log.conversation_id, data=data ) ``` `GenDataTask` 对象包含以下数据: | 名称 | 类型 | 描述 | ---- | ---- | ----------- | `name` | `str` | 任务的名称/标识符 | `instructions` | `str` | 给 AI 的自然语言指令 | `structure` | `vol.Schema` | `None` | 用于结构化输出验证的可选 schema | `attachments` | `list[conversation.Attachment]` | `None` | 包含在任务中的附件列表。 ### 生成图像 此方法根据自然语言指令处理图像生成任务。只有当实体设置了 `AITaskEntityFeature.GENERATE_IMAGE` 功能时,才会调用此方法。 ```python from homeassistant.components.ai_task import AITaskEntity, GenImageTask, GenImageTaskResult class MyAITaskEntity(AITaskEntity): """Represent an AI Task entity.""" async def _async_generate_image( self, task: GenImageTask, chat_log: ChatLog ) -> GenImageTaskResult: """Handle a generate image task.""" # Process the task instructions and generate the image. image_data = ... return GenImageTaskResult( conversation_id=chat_log.conversation_id, image_data=image_data, mime_type="image/png", ) ``` `GenImageTask` 对象包含以下数据: | 名称 | 类型 | 描述 | ---- | ---- | ----------- | `name` | `str` | 任务的名称/标识符 | `instructions` | `str` | 给 AI 的自然语言指令 | `attachments` | `list[conversation.Attachment]` | `None` | 与指令一起包含的可选附件列表。 返回的 `GenImageTaskResult` 对象包含以下数据: | 名称 | 类型 | 描述 | ---- | ---- | ----------- | `image_data` | `bytes` | 模型生成的原始图像数据 | `conversation_id` | `str` | 对话的唯一标识符 | `mime_type` | `str` | 生成图像的 MIME 类型 | `width` | `int` | `None` | 生成图像的可选宽度 | `height` | `int` | `None` | 生成图像的可选高度 | `model` | `str` | `None` | 用于生成图像的可选模型 | `revised_prompt` | `str` | `None` | 用于生成图像的可选修订提示词 ## 结构化输出 schema `structure` 参数允许你使用 Home Assistant 的 [selector 系统](https://www.home-assistant.io/docs/blueprint/selectors/) 来定义所生成数据的预期格式: ```python { "yes_no_field": { "description": "Description of the field", "required": True/False, # 可选,默认为 False "selector": { "boolean": {} # Selector 类型 } }, "text_field": { "description": "Description of the text field", "required": True/False, # 可选,默认为 False "selector": { "text": {} # Selector 类型 } }, "number_field": { "description": "Description of the number field", "required": True/False, # 可选,默认为 False "selector": { "number": { "min": 18, # 可选的最小值 "max": 100, # 可选的最大值 } } }, } ``` --- url: /developers/core/entity/air-quality.md --- ## 属性 :::caution Deprecated Air Quality 实体已被弃用,不应再使用。取而代之,请为这些测量值使用独立的 sensors。 仍依赖 Air Quality Entity 的集成应进行迁移。 ::: :::caution Air Quality 实体不支持用于 [属性实现](/developers/core/entity.md#entity-class-or-instance-attributes) 的属性简写 ::: | 名称 | 类型 | 默认值 | 描述 | ---- | ---- | ------- | ----------- | particulate\_matter\_2\_5 | `str \| int \| float \| None` | **必填** | 颗粒物 2.5(<= 2.5 μm)浓度。 | particulate\_matter\_10 | `str \| int \| float \| None` | `None` | 颗粒物 10(<= 10 μm)浓度。 | particulate\_matter\_0\_1 | `str \| int \| float \| None` | `None` | 颗粒物 0.1(<= 0.1 μm)浓度。 | air\_quality\_index | `str \| int \| float \| None` | `None` | Air Quality Index (AQI)。 | ozone | `str \| int \| float \| None` | `None` | O3(臭氧)浓度。 | carbon\_monoxide | `str \| int \| float \| None` | `None` | CO(一氧化碳)浓度。 | carbon\_dioxide | `str \| int \| float \| None` | `None` | CO2(二氧化碳)浓度。 | sulphur\_dioxide | `str \| int \| float \| None` | `None` | SO2(二氧化硫)浓度。 | nitrogen\_oxide | `str \| int \| float \| None` | `None` | N2O(氧化氮)浓度。 | nitrogen\_monoxide | `str \| int \| float \| None` | `None` | NO(一氧化氮)浓度。 | nitrogen\_dioxide | `str \| int \| float \| None` | `None` | NO2(二氧化氮)浓度。支持的单位:`ppb`、`ppm`、`µg/m³`。 属性必须遵循 `unit_system` 中定义的单位。 --- url: /developers/core/entity/alarm-control-panel.md --- Alarm control panel entity 控制一个 alarm。从 [`homeassistant.components.alarm_control_panel.AlarmControlPanelEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/alarm_control_panel/__init__.py) 派生 platform entity。 ## 属性 :::tip Properties 应该只从内存返回信息,而不要执行 I/O(如网络请求)。请实现 `update()` 或 `async_update()` 来获取数据。 ::: | Name | Type | Default | Description | ---- | ---- | ------- | ----------- | alarm\_state | `AlarmControlPanelState \| None` | **必需** | **States** 中列出的 alarm 值之一。 | code\_arm\_required | bool | `True` | 执行 arm actions 时是否需要 code。 | code\_format | `CodeFormat \| None` | `None` | **Code formats** section 中列出的 states 之一。 | changed\_by | `str \| None` | `None` | 上次变更的触发者。 ### 状态 设置 state 应在 `alarm_state` property 中返回一个 `AlarmControlPanelState` 枚举值。 | Value | Description | ----- | ----------- | `DISARMED` | Alarm 处于 disarmed 状态(`off`)。 | `ARMED_HOME` | Alarm 处于 home mode 的 armed 状态。 | `ARMED_AWAY` | Alarm 处于 away mode 的 armed 状态。 | `ARMED_NIGHT` | Alarm 处于 night mode 的 armed 状态。 | `ARMED_VACATION` | Alarm 处于 vacation mode 的 armed 状态。 | `ARMED_CUSTOM_BYPASS` | Alarm 处于 custom bypass mode 的 armed 状态,其中一个或多个 zones 或 sensors 被 bypass(禁用),且被 bypass 的 zones 和 sensors 的组合与标准的 away、home 或 night modes 不对应。不要使用此 state 来指示断开连接、故障或电量低的 sensor;请通过专门的 sensor entity 报告这些情况。 | `PENDING` | Alarm 处于 pending 状态(即将 `triggered`)。 | `ARMING` | Alarm 正在 arming。 | `DISARMING` | Alarm 正在 disarming。 | `TRIGGERED` | Alarm 已 triggered。 ## 支持的功能 Supported features 通过使用 `AlarmControlPanelEntityFeature` enum 中的值来定义, 并使用按位或(`|`)运算符组合。 | Constant | Description | |----------|--------------------------------------| | `AlarmControlPanelEntityFeature.ARM_AWAY` | Alarm 支持 away mode 的 arming。 | `AlarmControlPanelEntityFeature.ARM_CUSTOM_BYPASS` | Alarm 支持带 bypass 的 arming。 | `AlarmControlPanelEntityFeature.ARM_HOME` | Alarm 支持 home mode 的 arming。 | `AlarmControlPanelEntityFeature.ARM_NIGHT` | Alarm 支持 night mode 的 arming。 | `AlarmControlPanelEntityFeature.ARM_VACATION` | Alarm 支持 vacation mode 的 arming。 | `AlarmControlPanelEntityFeature.TRIGGER` | Alarm 可以远程触发。 ### 代码格式 Supported code formats 通过使用 `CodeFormat` enum 中的值来定义。 | Value | Description | ----- | ----------- | `None` | 不需要 code。 | `CodeFormat.NUMBER` | Code 是数字(前端显示十键 pad)。 | `CodeFormat.TEXT` | Code 是字符串。 ## 方法 ### 解除警报 发送 disarm 命令。 ```python class MyAlarm(AlarmControlPanelEntity): # 实现以下方法之一。 def alarm_disarm(self, code: str | None = None) -> None: """Send disarm command.""" async def async_alarm_disarm(self, code: str | None = None) -> None: """Send disarm command.""" ``` ### 布防 - 在家 发送 arm home 命令。 ```python class MyAlarm(AlarmControlPanelEntity): # 实现以下方法之一。 def alarm_arm_home(self, code: str | None = None) -> None: """Send arm home command.""" async def async_alarm_arm_home(self, code: str | None = None) -> None: """Send arm home command.""" ``` ### 布防 - 外出 发送 arm away 命令。 ```python class MyAlarm(AlarmControlPanelEntity): # 实现以下方法之一。 def alarm_arm_away(self, code: str | None = None) -> None: """Send arm away command.""" async def async_alarm_arm_away(self, code: str | None = None) -> None: """Send arm away command.""" ``` ### 布防 - 夜间 发送 arm night 命令。 ```python class MyAlarm(AlarmControlPanelEntity): # 实现以下方法之一。 def alarm_arm_night(self, code: str | None = None) -> None: """Send arm night command.""" async def async_alarm_arm_night(self, code: str | None = None) -> None: """Send arm night command.""" ``` ### 布防 - 度假 发送 arm vacation 命令。 ```python class MyAlarm(AlarmControlPanelEntity): # 实现以下方法之一。 def alarm_arm_vacation(self, code: str | None = None) -> None: """Send arm vacation command.""" async def async_alarm_arm_vacation(self, code: str | None = None) -> None: """Send arm vacation command.""" ``` ### 触发警报 发送 alarm trigger 命令。 ```python class MyAlarm(AlarmControlPanelEntity): # 实现以下方法之一。 def alarm_trigger(self, code: str | None = None) -> None: """Send alarm trigger command.""" async def async_alarm_trigger(self, code: str | None = None) -> None: """Send alarm trigger command.""" ``` ### 布防 - 自定义绕过 发送 arm custom bypass 命令。 ```python class MyAlarm(AlarmControlPanelEntity): # 实现以下方法之一。 def alarm_arm_custom_bypass(self, code: str | None = None) -> None: """Send arm custom bypass command.""" async def async_alarm_arm_custom_bypass(self, code: str | None = None) -> None: """Send arm custom bypass command.""" ``` --- url: /developers/core/entity/assist-satellite.md --- Assist Satellite 实体表示设备的由 Assist pipeline 驱动的语音助手功能。拥有此类实体的设备允许用户使用语音控制 Home Assistant。 Assist satellite 实体派生自 [`homeassistant.components.assist_satellite.AssistSatelliteEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/assist_satellite/__init__.py)。 ## 属性 | 名称 | 类型 | 默认值 | 描述 | |----------------------|------------------------|-------------------|-----------------------------------------------------------------------| | `pipeline_entity_id` | `str \| None` | `None` | 带有 [pipeline id](/developers/voice/pipelines.md) 的 `select` 实体的 Id,或 `None`。 | | `vad_sensitivity_entity_id` | `str \| None` | `None` | 带有 [语音活动检测灵敏度](https://github.com/home-assistant/core/blob/dev/homeassistant/components/assist_pipeline/vad.py) 的 `select` 实体的 Id,或 `None`。 | | `tts_options` | `dict \| None` | `None` | 在回复时传递给 [text-to-speech 系统](https://www.home-assistant.io/integrations/tts/) 的选项。 | ## 状态 `AssistSatelliteEntity` 的状态跟随其当前正在运行的 [pipeline](/developers/voice/pipelines.md)。`AssistSatelliteState` 枚举存储了可能的状态。 :::tip 当 text-to-speech 响应**播放完毕**时,必须在你的实体上调用 `tts_response_finished` 方法,以返回 `IDLE` 状态。 ::: | 常量 | 描述 | |--------------|--------------------------------------------------------------------------| | `IDLE` | 设备正在等待用户输入,例如唤醒词或按键。 | | `LISTENING` | 设备正在将语音指令的音频流式传输到 Home Assistant。 | | `PROCESSING` | Home Assistant 正在处理语音指令。 | | `RESPONDING` | 设备正在播放回复。 | ## 支持的功能 支持的功能通过使用 `AssistSatelliteEntityFeature` 枚举中的值来定义,并使用按位或(`|`)运算符进行组合。 | 值 | 描述 | |------------|---------------------------------------------------| | `ANNOUNCE` | 设备支持远程触发的公告。实现 `async_announce` 方法以播放 `AssistSatelliteAnnouncement` 中提供的 `media_id`。此方法应仅在设备上的公告播放完毕后才返回。 | | `START_CONVERSATION` | 设备支持远程触发的对话,即播放公告然后听取一个或多个语音指令。实现 `async_start_conversation` 方法以播放 `AssistSatelliteAnnouncement` 中提供的 `media_id`,然后听取语音指令。此方法应仅在公告播放完毕后才返回。 | ## 方法 ### 运行 pipeline 和处理事件 Satellite 实体应仅使用 `async_accept_pipeline_from_satellite` 方法运行 [Assist pipeline](/developers/voice/pipelines.md)。通过实现 `on_pipeline_event` 方法来处理 [来自 pipeline 的事件](/developers/voice/pipelines.md#events)。 运行 pipeline 时,satellite 实体的 [状态](#states) 会自动更新,`RESPONDING` 到 `IDLE` 除外。当 satellite 在设备上播放完回复后,开发者必须调用 `tts_response_finished` 方法。 ### 获取配置 `async_get_configuration` 方法必须返回一个(缓存的)`AssistSatelliteConfiguration`。如果实体必须与设备通信以检索配置,这应在初始化期间完成。 有一个 [websocket 命令](#getting-the-satellite-configuration) 可用于获取实体的配置。 ### 设置配置 `async_set_configuration` 方法更新设备的配置,并且只有在设备和 Home Assistant 的 `AssistSatelliteConfiguration` 同步后才返回。 有一个 [websocket 命令](#setting-the-active-wake-words) 可用于设置活动的唤醒词。 ### 公告 如果设备具有 `ANNOUNCE` [支持的功能](#supported-features),则应实现 `async_announce` 方法,以公告 `AssistSatelliteAnnouncement` 内提供的 `media_id`。如果提供了 `preannounce_media_id`,应在 `media_id` 之前播放。 `async_announce` 方法应仅在设备上的公告播放完毕后才返回。 有一个 [announce 操作](https://home-assistant.io/integrations/assist_satellite#action-assist_satelliteannounce) 可用于自动化公告。 ### 开始对话 如果设备具有 `START_CONVERSATION` [支持的功能](#supported-features),则应实现 `async_start_conversation` 方法,以执行以下操作: 1. 公告 `AssistSatelliteAnnouncement` 内的 `preannounce_media_id`(如果已提供) 2. 公告 `AssistSatelliteAnnouncement` 内提供的 `media_id`,然后 3. 听取一个或多个后续的语音指令 `async_start_conversation` 方法应仅在设备上的公告播放完毕后才返回。对话将在用户和 satellite 之间继续。 有一个 [start conversation 操作](https://home-assistant.io/integrations/assist_satellite#action-assist_satellitestart_conversation) 可用于自动化对话。 ## WebSocket API ### 拦截唤醒词 该集成提供了一个 websocket API,用于拦截唤醒词的检测并向用户公告。语音向导使用此功能来帮助用户上 hand 并熟悉唤醒词。 ```json { "type": "assist_satellite/intercept_wake_word", "entity_id": "assist_satellite.living_room" } ``` 实体 id 必须是支持 `ANNOUNCE` 功能的 Assist satellite 实体。 一旦检测到唤醒词,将返回如下响应: ```json { "wake_word_phrase": "okay nabu" } ``` ### 获取 satellite 配置 可以使用以下命令获取 satellite 的当前配置,包括可用和活动的唤醒词: ```json { "type": "assist_satellite/get_configuration", "entity_id": ENTITY_ID } ``` 将返回如下响应: ```json { "active_wake_words": [ "1234" ], "available_wake_words": [ { "id": "1234", "trained_languages": [ "en" ], "wake_word": "okay nabu" }, { "id": "5678", "trained_languages": [ "en" ], "wake_word": "hey jarvis" } ], "max_active_wake_words": 1, "pipeline_entity_id": "select.pipeline_entity", "vad_entity_id": "select.vad_entity" } ``` `active_wake_words` 列表包含 `available_wake_words` 中唤醒词的 ids。 `pipeline_entity_id` 包含控制设备将运行的 pipeline 的 select 实体的 id。 `vad_entity_id` 包含具有语音活动检测器 (VAD) 灵敏度级别的 select 实体的 id。 ### 设置活动的唤醒词 使用以下命令设置活动的唤醒词: ```json { "type": "assist_satellite/set_wake_words", "entity_id": ENTITY_ID, "wake_word_ids": ["1234", "5678"] } ``` `wake_word_ids` 必须包含来自 `assist_satellite/get_configuration` 命令的 `available_wake_words` 列表中的 ids。 `wake_word_ids` 的大小也不应超过 `max_active_wake_words`。 --- url: /developers/core/entity/binary-sensor.md --- Binary sensor 是一种只能有两个 states 的 sensor。从 [`homeassistant.components.binary_sensor.BinarySensorEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/binary_sensor/__init__.py) 派生 entity platforms。 ## 属性 :::tip Properties 应该只从内存中返回信息,不要执行 I/O(如网络请求)。实现 `update()` 或 `async_update()` 来获取数据。 ::: | Name | Type | Default | Description | ---- | ---- | ------- | ----------- | is\_on| `bool \| None` | `None` | **必需**。Binary sensor 当前是 on 还是 off。 | device\_class | `BinarySensorDeviceClass \| None` | `None` | Binary sensor 的类型。 ### 可用的设备类型 | Constant | Description | ----- | ----------- | `BinarySensorDeviceClass.BATTERY` | On 表示电量低,Off 表示正常。 | `BinarySensorDeviceClass.BATTERY_CHARGING` | On 表示正在充电,Off 表示未充电。 | `BinarySensorDeviceClass.CO` | On 表示检测到一氧化碳,Off 表示无一氧化碳(正常)。 | `BinarySensorDeviceClass.COLD` | On 表示温度低,Off 表示正常。 | `BinarySensorDeviceClass.CONNECTIVITY` | On 表示已连接,Off 表示已断开连接。 | `BinarySensorDeviceClass.DOOR` | On 表示打开,Off 表示关闭。 | `BinarySensorDeviceClass.GARAGE_DOOR` | On 表示打开,Off 表示关闭。 | `BinarySensorDeviceClass.GAS` | On 表示检测到燃气,Off 表示无燃气(正常)。 | `BinarySensorDeviceClass.HEAT` | On 表示温度高,Off 表示正常。 | `BinarySensorDeviceClass.LIGHT` | On 表示检测到光线,Off 表示无光线。 | `BinarySensorDeviceClass.LOCK` | On 表示打开(未锁定),Off 表示关闭(已锁定)。 | `BinarySensorDeviceClass.MOISTURE` | On 表示湿润,Off 表示干燥。 | `BinarySensorDeviceClass.MOTION` | On 表示检测到移动,Off 表示无移动(正常)。 | `BinarySensorDeviceClass.MOVING` | On 表示正在移动,Off 表示未移动(已停止)。 | `BinarySensorDeviceClass.OCCUPANCY` | On 表示有人,Off 表示无人(正常)。 | `BinarySensorDeviceClass.OPENING` | On 表示打开,Off 表示关闭。 | `BinarySensorDeviceClass.PLUG` | On 表示已插上,Off 表示未插上。 | `BinarySensorDeviceClass.POWER` | On 表示检测到电流,Off 表示无电流。 | `BinarySensorDeviceClass.PRESENCE` | On 表示在家,Off 表示外出。 | `BinarySensorDeviceClass.PROBLEM` | On 表示检测到问题,Off 表示无问题(正常)。 | `BinarySensorDeviceClass.RUNNING` | On 表示正在运行,Off 表示未运行。 | `BinarySensorDeviceClass.SAFETY` | On 表示不安全,Off 表示安全。 | `BinarySensorDeviceClass.SMOKE` | On 表示检测到烟雾,Off 表示无烟雾(正常)。 | `BinarySensorDeviceClass.SOUND` | On 表示检测到声音,Off 表示无声音(正常)。 | `BinarySensorDeviceClass.TAMPER` | On 表示检测到拆改,Off 表示无拆改(正常)。 | `BinarySensorDeviceClass.UPDATE` | On 表示有 update 可用,Off 表示已是最新。应避免使用此 device class,请考虑改用 [`update`](/developers/core/entity/update.md) entity。 | `BinarySensorDeviceClass.VIBRATION` | On 表示检测到振动,Off 表示无振动。 | `BinarySensorDeviceClass.WINDOW` | On 表示打开,Off 表示关闭。 --- url: /developers/core/entity/button.md --- Button entity 是一种可以触发事件/动作指向 device 或 service 的 entity,但从 Home Assistant 的角度来看它保持无状态。 它类似于真实的一次性 switch、push-button 或其他形式的无状态 switch。然而,它不适合实现实际的物理按钮;button entity 的唯一目的是在 Home Assistant 内提供一个虚拟按钮。 Button entity 从 [`homeassistant.components.button.ButtonEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/button/__init__.py) 派生, 对于控制 device features(包括但不限于以下)很有用: * 升级 firmware * 重启/重新启动 device * 冲泡一杯咖啡 * 重置某些内容(如 counter、filter usage) 如果你想表示一个可以开启和关闭的东西(因此具有实际的 state),应改用 `switch` entity。如果想在 Home Assistant 中集成真实的、物理的无状态按钮 device,可以通过触发自定义 events 来实现。Button entity 不适合这些情况。 ## 属性 由于该集成是无状态的,它没有提供任何特定的 property。 其他在所有 entity 中通用的 properties(如 `device_class`、`icon`、`name` 等)仍然适用。 ## 方法 ### 按下 Press method 可用于触发指向 device 或 service 的动作。 当用户按下按钮或调用了按下按钮的动作时,由 Home Assistant 调用。 ```python class MyButton(ButtonEntity): # 实现以下方法之一。 def press(self) -> None: """Handle the button press.""" async def async_press(self) -> None: """Handle the button press.""" ``` ### 可用的设备类型 选项性地指定 entity 的类型。它可能会映射到 Google device types。 | Constant | Description | ----- | ----------- | `ButtonDeviceClass.IDENTIFY` | Button entity 用于识别 device。 | `ButtonDeviceClass.RESTART` | Button entity 用于重启 device。 | `ButtonDeviceClass.UPDATE` | Button entity 用于更新 device 的软件。应避免使用此 device class,请考虑改用 [`update`](/developers/core/entity/update.md) entity。 --- url: /developers/core/entity/calendar.md --- Calendar entity 是一种代表一组具有开始和结束日期及/或时间的 events 的 entity,对 automations 很有用。Calendar entity 从 [`homeassistant.components.calendar.CalendarEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/calendar/__init__.py) 派生。 Calendar 集成应与 rfc5545 兼容,并可选项遵循 rfc5546 中建立的 patterns 支持 event 创建。支持 recurring events 的集成负责处理 recurring events 的 expansion,例如在返回 expansion 后事件序列(作为单独独立 events)的 service 或 API 中。 ## 属性 :::tip Properties 应该只从内存返回信息,而不要执行 I/O(如网络请求)。请实现 `update()` 或 `async_update()` 来获取数据。 ::: | Name | Type | Default | Description | | ----- | ------------- | --------------------- | ------------------------------------------------------- | | event | `CalendarEvent \| None` | **必需** | 当前或下一个即将到来的 `CalendarEvent`,或 `None`。 | | initial\_color | `str` | `None` | 用作 frontend 中日历初始颜色的十六进制 color 字符串(例如 `"#16a765"`)。 | ### 状态 `CalendarEntity` 的 state 类似于 binary sensor,反映是否存在 active event: | Constant | Description | | ----------- | ------------------------------------------- | | `STATE_ON` | 日历有 active event。 | | `STATE_OFF` | 日历没有 active event。 | Calendar entity 有一个 `event` property,返回当前或下一个即将到来的 `CalendarEvent`,用于确定 state。Calendar entity 的实现负责确定下一个即将到来的 event, 包括正确排序 events 以及在 Home Assistant timezone 中解释 all-day events。Entity 应调用 `homeassistant.util.dt.now` 来获取当前时间,该时间具有设置为 Home Assistant timezone 的 `tzinfo` 值,或者检查 `homeassistant.components.util.dt.DEFAULT_TIMEZONE`。 ## 支持的功能 Supported features 通过使用 `CalendarEntityFeature` enum 中的值来定义, 并使用按位或(`|`)运算符组合。 | Value | Description | | ------------------- | ------------------------------------------------------------------ | | `CREATE_EVENT` | Entity 实现了允许创建 events 的 methods。 | | `DELETE_EVENT` | Entity 实现了允许删除 events 的 methods。 | | `UPDATE_EVENT` | Entity 实现了允许更新 events 的 methods。 | ## 方法 ### 获取 events Calendar entity 可以返回发生在特定时间范围内的 events。给实现者的注意事项: * `start_date` 是下界,应用于 event 的 `end`(exclusive)。它具有本地 Home Assistant timezone 的 `tzinfo`。 * `end_date` 是上界,应用于 event 的 `start`(exclusive)。它与 `start_date` 具有相同的 `tzinfo`。 * Recurring events 应被展平并作为单独的 `CalendarEvent` 返回。 Calendar entity 负责按顺序返回 events,包括正确排序 all-day events。All-day event 应排序为在 Home Assistant timezone 中的午夜开始(例如从 start/end time 参数的 `tzinfo`, 或使用 `homeassistant.util.dt.start_of_local_day`)。注意,all-day events 仍应在 `CalendarEvent` 中设置 `datetime.date`,而不是带时间的日期。 ```python import datetime from homeassistant.core import HomeAssistant from homeassistant.components.calendar import CalendarEntity class MyCalendar(CalendarEntity): async def async_get_events( self, hass: HomeAssistant, start_date: datetime.datetime, end_date: datetime.datetime, ) -> list[CalendarEvent]: """Return calendar events within a datetime range.""" ``` ### 订阅 calendar events Frontend 和其他 consumers 可以通过 `calendar/event/subscribe` WebSocket API 订阅实时 calendar event updates。该订阅完全由 `CalendarEntity` 基类处理——集成开发者除了现有的 `async_get_events` 方法外不需要实现任何东西。 当 calendar entity 的 state 改变时(例如 event 开始或结束),基类会自动获取订阅时间范围内的最新 events,并将它们推送给所有 active subscribers。Updates 会进行 debounce 处理以避免过多调用 `async_get_events`。 #### 通知 subscribers 在创建、更新或删除 calendar events 时,state 不会自动更新。如果集成需要在 state 变更之外通知 subscribers(例如在 CRUD 操作之后),应调用 `CalendarEntity.async_update_event_listeners` 将更新的 events 推送给所有 active subscribers。 #### WebSocket API **订阅 events:** ```json { "type": "calendar/event/subscribe", "entity_id": "calendar.my_calendar", "start": "2025-01-01T00:00:00+00:00", "end": "2025-01-31T23:59:59+00:00" } ``` 订阅立即返回请求时间范围内的当前 events,然后在 entity state 改变时推送 updates。下面的示例仅显示内部的 `event` payload;实际的 WebSocket frame 还包含 `id` 和 `type` 字段: ```json { "event": { "events": [ { "start": "2025-01-15T09:00:00+00:00", "end": "2025-01-15T10:00:00+00:00", "summary": "Team meeting", "description": "Weekly sync", "location": "Room 1" } ] } } ``` 列表中的每个 event 仅包含有值的字段。可能的字段有 `start`、`end`、`summary`、`description` 和 `location`。如果在获取 events 时发生错误,`events` 将为 `null`。 ### 创建 events Calendar entity 可以通过指定 `CREATE_EVENT` supported feature 来支持创建 events。支持 mutation 的集成必须处理 rfc5545 fields 和最佳实践,例如保留所设置的新未知 fields 和 recurring events。 ```python from homeassistant.components.calendar import CalendarEntity class MyCalendar(CalendarEntity): async def async_create_event(self, **kwargs: Any) -> None: """Add a new event to calendar.""" ``` ### 删除 events Calendar entity 可以通过指定 `DELETE_EVENT` supported feature 来支持删除 events。支持 mutation 的集成必须支持 rfc5545 recurring events。 有三种删除 recurring events 的方式: * 仅指定 `uid` 将删除整个 series * 指定 `uid` 和 `recurrence_id` 将删除 series 中特定的 event instance * 指定 `uid`、`recurrence_id` 和 `recurrence_range` 值可能删除从 `recurrence_id` 开始的范围内的 events。当前 rfc5545 允许 [range](https://www.rfc-editor.org/rfc/rfc5545#section-3.2.13) 值 `THISANDFUTURE`。 ```python from homeassistant.components.calendar import CalendarEntity class MyCalendar(CalendarEntity): async def async_delete_event( self, uid: str, recurrence_id: str | None = None, recurrence_range: str | None = None, ) -> None: """Delete an event on the calendar.""" ``` ### 更新 events Calendar entity 可以通过指定 `UPDATE_EVENT` supported feature 来支持更新 events。支持 mutation 的集成必须支持 rfc5545 recurring events。 有三种更新 recurring events 的方式: * 仅指定 `uid` 将更新整个 series * 指定 `uid` 和 `recurrence_id` 将更新 series 中特定的 event instance * 指定 `uid`、`recurrence_id` 和 `recurrence_range` 值可能更新从 `recurrence_id` 开始的范围内的 events。当前 rfc5545 允许 [range](https://www.rfc-editor.org/rfc/rfc5545#section-3.2.13) 值 `THISANDFUTURE`。 ```python from homeassistant.components.calendar import CalendarEntity class MyCalendar(CalendarEntity): async def async_update_event( self, uid: str, event: dict[str, Any], recurrence_id: str | None = None, recurrence_range: str | None = None, ) -> None: """Update an event on the calendar.""" ``` ## 日历事件 `CalendarEvent` 代表 calendar 上的一个单独 event。 | Name | Type | Default | Description | | ----------- | ---------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- | | start | datetime or date | **必需** | 事件开始(inclusive)。必须在 `end` 之前。`start` 和 `end` 必须是同一类型。作为 datetime 时,必须有 timezone。 | | end | datetime or date | **必需** | 事件结束(exclusive)。必须在 `start` 之后。作为 datetime 时,必须有与 start 相同的 timezone。 | | summary | string | **必需** | 事件的标题或摘要。 | | location | string | `None` | 事件的地理位置。 | | description | string | `None` | 事件的详细描述。 | | uid | string | `None` | 事件的唯一标识符(mutation 必需) | | recurrence\_id | string | `None` | 针对 recurring event 的特定 instance 的可选标识符(recurring events 的 mutation 必需) | | rrule | string | `None` | 重复规则字符串,例如 `FREQ=DAILY` | ## 颜色管理 Calendar entity 可以选项性地为在 frontend 中显示提供默认颜色,方法是将 `initial_color` 设为十六进制 color 字符串(例如 `"#16a765"`)。该颜色在 entity 首次添加时自动存储在 entity registry options 中,用户可以通过 entity settings UI 自定义。 --- url: /developers/core/entity/camera.md --- Camera entity 可以显示 images,还可以选项性地显示 video stream。从 [`homeassistant.components.camera.Camera`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/camera/__init__.py) 派生 platform entity。 ## 属性 :::tip Properties 应该只从内存返回信息,而不要执行 I/O(如网络请求)。请实现 `update()` 或 `async_update()` 来获取数据。 ::: | Name | Type | Default | Description | | ------------------------ | ------------------------------------| ------- | --------------------------------------------------------------------------------------------------- | | brand | `str \| None` | `None` | Camera 的品牌(manufacturer)。 | | frame\_interval | `float` | 0.5 | Stream 中 frames 之间的间隔。 | | is\_on | `bool` | `True` | 指示 camera 是否开启。 | | is\_recording | `bool` | `False` | 指示 camera 是否正在 recording。用于确定 `state`。 | | is\_streaming | `bool` | `False` | 指示 camera 是否正在 streaming。用于确定 `state`。 | | model | `str \| None` | `None` | Camera 的 model。 | | motion\_detection\_enabled | `bool` | `False` | 指示 camera 是否启用了 motion detection。 | | use\_stream\_for\_stills | `bool` | `False` | 确定是否使用 `Stream` 集成来生成 still images | ### 状态 State 通过设置上述 properties 来定义。Resulting state 使用 `CameraState` enum 返回以下成员之一。 | Value | Description | |-------------|-----------------------------------------| | `RECORDING` | Camera 当前正在 recording。 | | `STREAMING` | Camera 当前正在 streaming。 | | `IDLE` | Camera 当前处于 idle。 | ## 支持的功能 Supported features 通过使用 `CameraEntityFeature` enum 中的值来定义, 并使用按位或(`|`)运算符组合。 | Value | Description | | -------- | -------------------------------------------- | | `ON_OFF` | Device 支持 `turn_on` 和 `turn_off` | | `STREAM` | Device 支持 streaming | ## 方法 ### 摄像头图像 当传入 width 和 height 时,应在最佳基础上进行 scaling。如果 camera 无法进行 scaling,UI 将回退到在 display 层进行 scaling。 * 返回满足最小 width 和最小 height 的最小 image。 * 在对 image 进行 scaling 时,必须保留 aspect ratio。如果 aspect ratio 与请求的 height 或 width 不同,则返回 image 的 width 和/或 height 预期大于请求值。 * 如果底层 camera 能够对 image 进行 scaling,则传递 width 和 height。 * 如果集成无法对 image 进行 scaling 且返回 jpeg image,则在请求时它会自动由 camera 集成进行 scaling。 ```python class MyCamera(Camera): # 实现以下方法之一。 def camera_image( self, width: int | None = None, height: int | None = None ) -> bytes | None: """Return bytes of camera image.""" raise NotImplementedError() async def async_camera_image( self, width: int | None = None, height: int | None = None ) -> bytes | None: """Return bytes of camera image.""" ``` ### 流源 Stream source 应返回一个 ffmpeg 可用的 URL(例如 RTSP URL)。需要 `CameraEntityFeature.STREAM`。 具有 stream source 的 camera entity 默认使用 `StreamType.HLS` 来告诉 frontend 使用带有 `stream` component 的 HLS feed。该 stream source 也会用于 `stream` 的 recording。 ```python class MyCamera(Camera): async def stream_source(self) -> str | None: """Return the source of the stream.""" ``` Camera entity 渲染 still image 的一种常见方式是将 stream source 传递给 `ffmpeg` component 中的 `async_get_image`。 ### WebRTC 流 WebRTC-enabled cameras 可以通过与 Home Assistant frontend 建立直接连接来使用。这种用法需要 `CameraEntityFeature.STREAM`,并且集成必须实现以下两个 methods 以支持原生 WebRTC: * `async_handle_async_webrtc_offer`:初始化 WebRTC stream。所有异步传入的消息/错误应通过 `send_message` callback 转发到 frontend。 * `async_on_webrtc_candidate`:Frontend 会在发送 offer 后用所有传入的 candidate 调用它。 以下 method 可以选项性地实现: * `close_webrtc_session`(可选):Frontend 会在 stream 关闭时调用它。可用于清理资源。 WebRTC streams 不使用 `stream` component,也不支持 recording。 通过实现 WebRTC methods,frontend 假设 camera 仅支持 WebRTC,因此不会回退到 HLS。 ```python class MyCamera(Camera): async def async_handle_async_webrtc_offer( self, offer_sdp: str, session_id: str, send_message: WebRTCSendMessage ) -> None: """Handle the async WebRTC offer. Async 意味着处理 offer 可能需要一些时间,responses/message 将通过 send_message callback 发送。 该方法由具有 CameraEntityFeature.STREAM 的 cameras 使用 覆盖此方法的集成还必须实现 async_on_webrtc_candidate。 集成可以使用原生 WebRTC 实现进行覆盖。 """ async def async_on_webrtc_candidate(self, session_id: str, candidate: RTCIceCandidate) -> None: """Handle a WebRTC candidate.""" @callback def close_webrtc_session(self, session_id: str) -> None: """Close a WebRTC session.""" ``` ### WebRTC 提供商 集成可以使用 `homeassistant.components.camera.webrtc` 中的库,从现有 camera 的 stream source 提供 WebRTC stream。集成可以实现 `CameraWebRTCProvider` 并通过 `async_register_webrtc_provider` 注册它。 ### 开启 ```python class MyCamera(Camera): # 实现以下方法之一。 def turn_on(self) -> None: """Turn on camera.""" async def async_turn_on(self) -> None: """Turn on camera.""" ``` ### 关闭 ```python class MyCamera(Camera): # 实现以下方法之一。 def turn_off(self) -> None: """Turn off camera.""" async def async_turn_off(self) -> None: """Turn off camera.""" ``` ### 启用移动侦测 ```python class MyCamera(Camera): # 实现以下方法之一。 def enable_motion_detection(self) -> None: """Enable motion detection in the camera.""" async def async_enable_motion_detection(self) -> None: """Enable motion detection in the camera.""" ``` ### 禁用移动侦测 ```python class MyCamera(Camera): # 实现以下方法之一。 def disable_motion_detection(self) -> None: """Disable motion detection in camera.""" async def async_disable_motion_detection(self) -> None: """Disable motion detection in camera.""" ``` --- url: /developers/core/entity/climate.md --- Climate entity 控制 temperature、humidity 或 fans,例如 A/C systems 和 humidifiers。从 [`homeassistant.components.climate.ClimateEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/climate/__init__.py) 派生 platform entity。 ## 属性 :::tip Properties 应该只从内存返回信息,而不要执行 I/O(如网络请求)。请实现 `update()` 或 `async_update()` 来获取数据。 ::: | Name | Type | Default | Description | | ----------------------- | ----------------------------------- | ------------------------------------ | -------------------------------------------------------------------------- | | current\_humidity | `float \| None` | `None` | 当前的 humidity。 | | current\_temperature | `float \| None` | `None` | 当前的 temperature。 | | fan\_mode | `str \| None` | **ClimateEntityFeature.FAN\_MODE 必需** | 当前的 fan mode。 | | fan\_modes | `list[str] \| None` | **ClimateEntityFeature.FAN\_MODE 必需** | 可用 fan modes 的列表。 | | hvac\_action | `HVACAction \| None` | `None` | 当前正在执行的动作。见下文。 | | hvac\_mode | `HVACMode \| None` | **必需** | 选择的 operation mode。见下文。用于确定 `state`。 | | hvac\_modes | `list[HVACMode]` | **必需** | 可用 operation modes 的列表。见下文。 | | max\_humidity | `float` | `DEFAULT_MAX_HUMIDITY`(值 == 99) | 最大 humidity。 | | max\_temp | `float` | `DEFAULT_MAX_TEMP`(值 == 35 °C) | `temperature_unit` 中的最大 temperature。 | | min\_humidity | `float` | `DEFAULT_MIN_HUMIDITY`(值 == 30) | 最小 humidity。 | | min\_temp | `float` | `DEFAULT_MIN_TEMP`(值 == 7 °C) | `temperature_unit` 中的最小 temperature。 | | precision | `float` | 根据 `temperature_unit` | 系统中 temperature 的 precision。默认为 `UnitOfTemperature.CELSIUS` 使用十分位,否则使用整数。 | | preset\_mode | `str \| None` | **ClimateEntityFeature.PRESET\_MODE 必需** | 当前活动的 preset。 | | preset\_modes | `list[str] \| None` | **ClimateEntityFeature.PRESET\_MODE 必需** | 可用的 presets。 | | swing\_mode | `str \| None` | **ClimateEntityFeature.SWING\_MODE 必需** | Swing 设置。 | | swing\_modes | `list[str] \| None` | **ClimateEntityFeature.SWING\_MODE 必需** | 返回可用 swing modes 的列表,如果实现了 horizontal swing,则仅返回 vertical modes。 | | swing\_horizontal\_mode | `str \| None` | **ClimateEntityFeature.SWING\_HORIZONTAL\_MODE 必需** | Horizontal swing 设置。 | | swing\_horizontal\_modes | `list[str] \| None` | **ClimateEntityFeature.SWING\_HORIZONTAL\_MODE 必需** | 返回可用 horizontal swing modes 的列表。 | | target\_humidity | `float \| None` | `None` | Device 试图达到的 target humidity。 | | target\_humidity\_step | `int \| None` | `None` | 在针对 device 的 action call 中 target humidity 可以增减的 supported step size。 | | target\_temperature | `float \| None` | `None` | 当前设置要达到的 temperature。 | | target\_temperature\_high | `float \| None` | **TARGET\_TEMPERATURE\_RANGE 必需** | 目标 temperature 的上界 | | target\_temperature\_low | `float \| None` | **TARGET\_TEMPERATURE\_RANGE 必需** | 目标 temperature 的下界 | | target\_temperature\_step | `float \| None` | `None` | 目标 temperature 可以增减的 supported step size | | temperature\_unit | str | **必需** | 系统的 temperature 计量单位(`UnitOfTemperature.CELSIUS` 或 `UnitOfTemperature.FAHRENHEIT`)。 | ### HVAC 模式 HVAC mode 是要求 device 执行的行为。 你只能使用 `HVACMode` enum 提供的内置 HVAC modes。 对于修改一个或多个 modes 行为的 device options,请添加一个 preset。 | Name | Description | | -------------------- | ------------------------------------------------------------------- | | `HVACMode.OFF` | Device 已关闭。 | | `HVACMode.HEAT` | Device 设置为加热到目标 temperature。 | | `HVACMode.COOL` | Device 设置为冷却到目标 temperature。 | | `HVACMode.HEAT_COOL` | Device 设置为加热/冷却到目标 temperature range。 | | `HVACMode.AUTO` | Device 设置为 schedule、learned behavior、AI。 | | `HVACMode.DRY` | Device 设置为 dry/humidity mode。 | | `HVACMode.FAN_ONLY` | Device 只开启 fan。没有加热或冷却操作。 | ### HVAC 动作 HVAC action 描述 device 为了完成请求的 HVAC mode 和 preset 而正在执行的 *当前* 动作, 由 device 自己的 control algorithms 决定。 你只能使用 `HVACAction` enum 提供的内置 HVAC actions。 :::note 除非 device 报告额外的信息,否则可能无法准确确定正确的 HVAC action。 例如: * 具有 hysteresis 的 thermostat 在目标 temperature 附近有一个 ambiguous temperature range,它可能正在执行动作,也可能处于 idle。 * 可变功率 device 在达到目标 temperature 后可能会继续以较低的功率运行,而不是变成 idle。 对于无法准确确定 HVAC action 的 devices,不要实现 `hvac_action`。 ::: | Name | Description | | ----------------------- | ----------------------------------------------------------------------------------------------------------- | | `HVACAction.OFF` | HVAC mode 为 `HVACMode.OFF`。除非更改 mode,否则 device 不会执行任何动作。 | | `HVACAction.PREHEATING` | Device 的 heat source 正在运行,但尚未达到 operating temperature。 | | `HVACAction.HEATING` | Device 正在向 space 添加热量。 | | `HVACAction.COOLING` | Device 正在从 space 移除热量。 | | `HVACAction.DRYING` | Device 正在从 space 中的空气中移除 moisture。 | | `HVACAction.FAN` | Device 开启 fan 以仅循环或通风 air。 | | `HVACAction.IDLE` | Device 当前未执行任何动作,但如果 conditions 改变,可能会开始执行动作。 | | `HVACAction.DEFROSTING` | Device 正在移除累积的 ice。 | ### 预设 Device 可能有不同的 presets,它可能希望向用户展示。常见的 presets 是 "Away" 或 "Eco"。有一些内置的 presets 会提供 translations,但也允许添加自定义 presets。 | Name | Description | | ---------- | ------------------------------------------------------ | | `NONE` | 没有活跃的 preset | | `ECO` | Device 正在运行节能模式 | | `AWAY` | Device 处于 away mode | | `BOOST` | Device 将所有阀门开到最大 | | `COMFORT` | Device 处于 comfort mode | | `HOME` | Device 处于 home mode | | `SLEEP` | Device 为睡眠做好准备 | | `ACTIVITY` | Device 对 activity 作出反应(例如 movement sensors) | ### 风扇模式 Device 的 fan 可以有不同 states。有一些内置的 fan modes,但也允许使用自定义 fan modes。 | Name | | ------------- | | `FAN_ON` | | `FAN_OFF` | | `FAN_AUTO` | | `FAN_LOW` | | `FAN_MEDIUM` | | `FAN_HIGH` | | `FAN_TOP` | | `FAN_MIDDLE` | | `FAN_FOCUS` | | `FAN_DIFFUSE` | ### 摆风模式 Device fan 可以有不同 swing modes,它希望用户了解/控制。 :::note 对于不能独立控制 vertical 和 horizontal swing 的集成,所有可能的 options 都应列在 `swing_modes` 中;否则 `swing_modes` 提供 vertical 支持,`swing_horizontal_modes` 应提供 horizontal 支持。 ::: | Name | Description | | ------------------ | ------------------------------------------------- | | `SWING_OFF` | Fan 未摆动。 | | `SWING_ON` | Fan 正在摆动。 | | `SWING_VERTICAL` | Fan 正在 vertical 摆动。 | | `SWING_HORIZONTAL` | Fan 正在 horizontal 摆动。 | | `SWING_BOTH` | Fan 正在 horizontal 和 vertical 摆动。 | ### 水平摆风模式 Device fan 可以有不同 horizontal swing modes,它希望用户了解/控制。 :::note 仅当集成能够独立控制 vertical 和 horizontal swing 时,才应实现此项。在这种情况下,`swing_modes` property 提供 vertical 支持,`swing_horizontal_modes` 提供 horizontal 支持。 ::: | Name | Description | | ------------------ | ------------------------------------------------- | | `SWING_OFF` | Fan 未摆动。 | | `SWING_ON` | Fan 正在摆动。 | ## 支持的功能 Supported features 通过使用 `ClimateEntityFeature` enum 中的值来定义, 并使用按位或(`|`)运算符组合。 | Value | Description | | -------------------------- | ------------------------------------------------------------------------------------------- | | `TARGET_TEMPERATURE` | Device 支持 target temperature。 | | `TARGET_TEMPERATURE_RANGE` | Device 支持 ranged target temperature。用于 HVAC modes `heat_cool` 和 `auto` | | `TARGET_HUMIDITY` | Device 支持 target humidity。 | | `FAN_MODE` | Device 支持 fan modes。 | | `PRESET_MODE` | Device 支持 presets。 | | `SWING_MODE` | Device 支持 swing modes。 | | `SWING_HORIZONTAL_MODE` | Device 支持 horizontal swing modes。 | | `TURN_ON` | Device 支持 turn on。 | | `TURN_OFF` | Device 支持 turn off。 | ## 方法 ### 设置 HVAC 模式 ```python class MyClimateEntity(ClimateEntity): # 实现以下方法之一。 def set_hvac_mode(self, hvac_mode: HVACMode) -> None: """Set new target hvac mode.""" async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None: """Set new target hvac mode.""" ``` ### 开启 ```python class MyClimateEntity(ClimateEntity): # 实现以下方法之一。 # `turn_on` method 应将 `hvac_mode` 设置为除 # `HVACMode.OFF` 之外的任何值,方法是从 service action # handler 中 optimistic 地设置它,或通过下一次 state update def turn_on(self) -> None: """Turn the entity on.""" async def async_turn_on(self) -> None: """Turn the entity on.""" ``` ### 关闭 ```python class MyClimateEntity(ClimateEntity): # 实现以下方法之一。 # `turn_off` method 应通过 # 从 service action handler 中 optimistic 地设置,或通过 # 下一次 state update 将 `hvac_mode` 设置为 `HVACMode.OFF` def turn_off(self) -> None: """Turn the entity off.""" async def async_turn_off(self) -> None: """Turn the entity off.""" ``` ### 切换 ```python class MyClimateEntity(ClimateEntity): # 不需要强制实现 `toggle` method,因为 base implementation # 会根据当前 HVAC mode 调用 `turn_on`/`turn_off`。 # 如果实现,`toggle` method 应通过 # 从 service action handler 中 optimistic 地设置 # 或通过下一次 state update,将 `hvac_mode` 设置为正确的 `HVACMode` def toggle(self) -> None: """Toggle the entity.""" async def async_toggle(self) -> None: """Toggle the entity.""" ``` ### 设置预设模式 ```python class MyClimateEntity(ClimateEntity): # 实现以下方法之一。 def set_preset_mode(self, preset_mode: str) -> None: """Set new target preset mode.""" async def async_set_preset_mode(self, preset_mode: str) -> None: """Set new target preset mode.""" ``` ### 设置风扇模式 ```python class MyClimateEntity(ClimateEntity): # 实现以下方法之一。 def set_fan_mode(self, fan_mode: str) -> None: """Set new target fan mode.""" async def async_set_fan_mode(self, fan_mode: str) -> None: """Set new target fan mode.""" ``` ### 设置湿度 ```python class MyClimateEntity(ClimateEntity): # 实现以下方法之一。 def set_humidity(self, humidity: int) -> None: """Set new target humidity.""" async def async_set_humidity(self, humidity: int) -> None: """Set new target humidity.""" ``` ### 设置摆风模式 ```python class MyClimateEntity(ClimateEntity): # 实现以下方法之一。 def set_swing_mode(self, swing_mode: str) -> None: """Set new target swing operation.""" async def async_set_swing_mode(self, swing_mode: str) -> None: """Set new target swing operation.""" ``` ### 设置水平摆风模式 ```python class MyClimateEntity(ClimateEntity): # 实现以下方法之一。 def set_swing_horizontal_mode(self, swing_horizontal_mode: str) -> None: """Set new target horizontal swing operation.""" async def async_set_swing_horizontal_mode(self, swing_horizontal_mode: str) -> None: """Set new target horizontal swing operation.""" ``` ### 设置温度 :::note `ClimateEntity` 有内置 validation,确保 `target_temperature_low` 参数小于或等于 `target_temperature_high` 参数。因此,集成不需要在自己的实现中对此进行 validation。 ::: ```python class MyClimateEntity(ClimateEntity): # 实现以下方法之一。 def set_temperature(self, **kwargs: Any) -> None: """Set new target temperature.""" async def async_set_temperature(self, **kwargs: Any) -> None: """Set new target temperature.""" ``` --- url: /developers/core/entity/conversation.md --- Conversation 实体允许用户与 Home Assistant 对话。 Conversation 实体派生自 [`homeassistant.components.conversation.ConversationEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/conversation/entity.py)。 ## 属性 :::tip 属性应始终仅返回内存中的信息,而不是执行 I/O(如网络请求)。 ::: | 名称 | 类型 | 默认值 | 描述 | ---- | ---- | ------- | ----------- | supported\_languages | `list[str]` | `Literal["*"]` | **必填** | 服务支持的语言。如果支持所有语言,则返回 `"*"`。 ## 支持的功能 支持的功能通过使用 `ConversationEntityFeature` 枚举中的值来定义,并使用按位或(`|`)运算符进行组合。 | 值 | 描述 | -------------------------- | ------------------------------------------------------------------------------------------- | `CONTROL` | 实体能够控制 Home Assistant。 ## 方法 ### 处理消息 此方法用于处理传入的聊天消息。 ```python from homeassistant.components.conversation import ChatLog, ConversationEntity class MyConversationEntity(ConversationEntity): """Represent a conversation entity.""" async def _async_handle_message( self, user_input: ConversationInput, chat_log: ChatLog, ) -> ConversationResult: """Call the API.""" # Add the response to the chat log. chat_log.async_add_assistant_content_without_tools( AssistantContent( agent_id=user_input.agent_id, content="Test response", ) ) response = intent.IntentResponse(language=user_input.language) response.async_set_speech("Test response") return agent.ConversationResult( conversation_id=None, response=response, continue_conversation=False, ) ``` `ConversationInput` 对象包含以下数据: | 名称 | 类型 | 描述 | ---- | ---- | ----------- | `text` | `str` | 用户输入 | `context` | `Context` | 附加到 HA 中操作的 HA context | `conversation_id` | `Optional[str]` | 可用于跟踪多轮对话。如果不支持则返回 None | `language` | `str` | 文本的语言。如果用户未提供,则设置为 HA 配置的语言。 *我们曾将 `async_process` 作为处理消息的方法来推荐。现已更改为 `_async_handle_message` 以自动包含 chat log。此更改向后兼容。* #### 聊天记录 chat log 对象允许 conversation 实体读取对话历史,并向其中添加消息和工具调用。 有关完整的类型化 API,请参阅 [Python 接口](https://github.com/home-assistant/core/blob/dev/homeassistant/components/conversation/chat_log.py)。 ### 准备 一旦 Home Assistant 知道请求即将到来,我们将让 conversation 实体为之做好准备。这可用于加载语言模型或其他资源。此函数为可选项。 ```python class MyConversationEntity(ConversationEntity): """Represent a conversation entity.""" async def async_prepare(self, language: str | None = None) -> None: """Prepare a language for processing.""" ``` --- url: /developers/core/entity/cover.md --- Cover entity 控制 opening 或 cover,例如 garage door 或 window shade。从 [`homeassistant.components.cover.CoverEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/cover/__init__.py) 派生 platform entity。 :::note Cover entity 应仅用于控制 opening 或 cover 的 devices。 对于其他类型的 device entities(如 [Number](/developers/core/entity/number.md)),应改用它们,即使过去并非如此。 ::: ## 属性 :::tip Properties 应该只从内存返回信息,而不要执行 I/O(如网络请求)。请实现 `update()` 或 `async_update()` 来获取数据。 ::: | Name | Type | Default | Description | ----------------------- | ---- | ------- | ----------- | current\_cover\_position | `int \| None` | `None` | Cover 的当前位置,其中 0 表示 closed,100 表示 fully open。 | current\_cover\_tilt\_position | `int \| None` | `None` | Cover 的当前 tilt position,其中 0 表示 closed/no tilt,100 表示 open/maximum tilt。 | is\_closed | `bool \| None` | **必需** | Cover 是否 closed。用于确定 `state`。 | is\_closing | `bool \| None` | `None` | Cover 是否正在 closing。用于确定 `state`。 | is\_opening | `bool \| None` | `None` | Cover 是否正在 opening。用于确定 `state`。 ### 状态 State 通过设置上述 properties 来定义。Resulting state 使用 `CoverState` enum 返回以下成员之一。 | Value | Description | |-------------|--------------------------------------------------------------------| | `CLOSED` | Cover 已 closed。 | | `CLOSING` | Cover 正在 closing。 | | `OPENING` | Cover 正在 opening。 | | `OPEN` | Cover 已 open。 | ### 设备类型 | Constant | Description |----------|-----------------------| | `CoverDeviceClass.AWNING` | 控制 awning,例如外部可伸缩 window、door 或 patio cover。 | `CoverDeviceClass.BLIND` | 控制 blinds,即连接的 slats,可以展开或折叠以覆盖 opening,或倾斜以部分覆盖 opening,例如 window blinds。 | `CoverDeviceClass.CURTAIN` | 控制 curtains 或 drapes,通常是悬挂在 window 或 door 上方的 fabric,可以拉开。 | `CoverDeviceClass.DAMPER` | 控制减少 air flow、sound 或 light 的机械 damper。 | `CoverDeviceClass.DOOR` | 控制提供进入通常属于结构一部分的区域 access 的 door。 | `CoverDeviceClass.GARAGE` | 控制提供进入 garage access 的 garage door。 | `CoverDeviceClass.GATE` | 控制提供进入 driveway 或其他区域 access 的 gate。Gates 位于结构外部,通常属于 fence 的一部分。 | `CoverDeviceClass.SHADE` | 控制 shades,即连续的 material plane 或连接的 cells,可以展开或折叠覆盖 opening,例如 window shades。 | `CoverDeviceClass.SHUTTER` | 控制 shutters,即连接的 slats,可以 swing out/in 以覆盖 opening,或倾斜以部分覆盖 opening,例如室内或室外 window shutters。 | `CoverDeviceClass.WINDOW` | 控制物理 window,可以打开和关闭,或可以倾斜。 ## 支持的功能 Supported features 通过使用 `CoverEntityFeature` enum 中的值来定义, 并使用按位或(`|`)运算符组合。 | Value | Description | | ------------------- | -------------------------------------------------------------------------------- | | `OPEN` | Cover 支持被 open。 | | `CLOSE` | Cover 支持被 closed。 | | `SET_POSITION` | Cover 支持在 open 和 closed 之间移动到特定 position。 | | `STOP` | Cover 支持停止当前 action(open、close、set position) | | `OPEN_TILT` | Cover 支持 tilt open。 | | `CLOSE_TILT` | Cover 支持 tilt closed。 | | `SET_TILT_POSITION` | Cover 支持在 open 和 closed 之间移动到特定 tilt position。 | | `STOP_TILT` | Cover 支持停止当前 tilt action(open、close、set position) | ## 方法 ### 打开 仅当设置了 `CoverEntityFeature.OPEN` 标志时,才实现此 method。 ```python class MyCover(CoverEntity): # 实现以下方法之一。 def open_cover(self, **kwargs: Any) -> None: """Open the cover.""" async def async_open_cover(self, **kwargs: Any) -> None: """Open the cover.""" ``` ### 关闭 仅当设置了 `CoverEntityFeature.CLOSE` 标志时,才实现此 method。 ```python class MyCover(CoverEntity): # 实现以下方法之一。 def close_cover(self, **kwargs: Any) -> None: """Close cover.""" async def async_close_cover(self, **kwargs: Any) -> None: """Close cover.""" ``` ### 设置位置 仅当设置了 `CoverEntityFeature.SET_POSITION` 标志时,才实现此 method。 ```python class MyCover(CoverEntity): # 实现以下方法之一。 def set_cover_position(self, **kwargs: Any) -> None: """Move the cover to a specific position.""" async def async_set_cover_position(self, **kwargs: Any) -> None: """Move the cover to a specific position.""" ``` ### 停止 仅当设置了 `CoverEntityFeature.STOP` 标志时,才实现此 method。 ```python class MyCover(CoverEntity): # 实现以下方法之一。 def stop_cover(self, **kwargs: Any) -> None: """Stop the cover.""" async def async_stop_cover(self, **kwargs: Any) -> None: """Stop the cover.""" ``` ### 打开 tilt 仅当设置了 `CoverEntityFeature.OPEN_TILT` 标志时,才实现此 method。 ```python class MyCover(CoverEntity): # 实现以下方法之一。 def open_cover_tilt(self, **kwargs: Any) -> None: """Open the cover tilt.""" async def async_open_cover_tilt(self, **kwargs: Any) -> None: """Open the cover tilt.""" ``` ### 关闭 tilt 仅当设置了 `CoverEntityFeature.CLOSE_TILT` 标志时,才实现此 method。 ```python class MyCover(CoverEntity): # 实现以下方法之一。 def close_cover_tilt(self, **kwargs: Any) -> None: """Close the cover tilt.""" async def async_close_cover_tilt(self, **kwargs: Any) -> None: """Close the cover tilt.""" ``` ### 设置 tilt 位置 仅当设置了 `CoverEntityFeature.SET_TILT_POSITION` 标志时,才实现此 method。 ```python class MyCover(CoverEntity): # 实现以下方法之一。 def set_cover_tilt_position(self, **kwargs: Any) -> None: """Move the cover tilt to a specific position.""" async def async_set_cover_tilt_position(self, **kwargs: Any) -> None: """Move the cover tilt to a specific position.""" ``` ### 停止 tilt 仅当设置了 `CoverEntityFeature.STOP_TILT` 标志时,才实现此 method。 ```python class MyCover(CoverEntity): # 实现以下方法之一。 def stop_cover_tilt(self, **kwargs: Any) -> None: """Stop the cover.""" async def async_stop_cover_tilt(self, **kwargs: Any) -> None: """Stop the cover.""" ``` --- url: /developers/core/entity/date.md --- `date` 是一种允许用户向集成输入日期的实体。从 [`homeassistant.components.date.DateEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/date/__init__.py) 派生实体平台。 ## 属性 :::tip 属性应始终仅返回内存中的信息,而不是执行 I/O(如网络请求)。实现 `update()` 或 `async_update()` 来获取数据。 ::: | 名称 | 类型 | 默认值 | 描述 | ---- | ---- | ------- | ----------- | native\_value | `datetime.date \| None` | **必填** | 日期的值。 所有实体共有的其他属性(如 `icon`、`name` 等)也适用。 ## 方法 ### 设置值 当用户或自动化想要更新值时调用。 ```python class MyDate(DateEntity): # 实现以下方法之一。 def set_value(self, value: date) -> None: """Update the current value.""" async def async_set_value(self, value: date) -> None: """Update the current value.""" ``` --- url: /developers/core/entity/datetime.md --- `datetime` 是一种允许用户向集成输入时间戳的实体。从 [`homeassistant.components.datetime.DateTimeEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/datetime/__init__.py) 派生实体平台。 ## 属性 :::tip 属性应始终仅返回内存中的信息,而不是执行 I/O(如网络请求)。实现 `update()` 或 `async_update()` 来获取数据。 ::: | 名称 | 类型 | 默认值 | 描述 | ---- | ---- | ------- | ----------- | native\_value | `datetime.datetime \| None` | **必填** | datetime 的值。必须包含时区信息。 所有实体共有的其他属性(如 `icon`、`name` 等)也适用。 ## 方法 ### 设置值 当用户或自动化想要更新值时调用。提供的 datetime 始终包含时区信息;无时区的 datetime 将被视为处于 Home Assistant 配置的时区。 ```python class MyDateTime(DateTimeEntity): # 实现以下方法之一。 def set_value(self, value: datetime) -> None: """Update the current value.""" async def async_set_value(self, value: datetime) -> None: """Update the current value.""" ``` --- url: /developers/core/entity/device-tracker.md --- Device tracker 是一种只读实体,提供存在信息。有三种类型的 device tracker 实体可供集成长使用:`BaseScannerEntity`、`ScannerEntity` 和 `TrackerEntity`。 ## BaseScannerEntity BaseScannerEntity 报告设备的连接状态,例如与蓝牙 beacons 的连接。如果设备已连接,BaseScannerEntity 的状态将是关联 zone 的名称,例如与 home zone 关联时为 `home`,如果设备未连接,状态将为 `not_home`。 基类设置了 `in_zones` 状态属性。当设备连接时,它将被填充为关联 zone 及其包含的 zone 的 `entity_id`,按大小排序;未连接时则为空。 基类还将 `tracking_type` 能力属性设置为 `TrackingType.CONNECTION`。 从 [`homeassistant.components.device_tracker.BaseScannerEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/device_tracker/__init__.py) 派生平台实体。 ### 属性 :::tip 属性应始终仅返回内存中的信息,而不是执行 I/O(如网络请求)。实现 `update()` 或 `async_update()` 来获取数据。 ::: | 名称 | 类型 | 默认值 | 描述 | | ------------- | ---------------| ------------------- | ----------------------------------- | | is\_connected | `bool \| None` | **必填** | 设备的连接状态。 | | source\_type | `SourceType` | **必填** | 设备的 source 类型。 | ## ScannerEntity ScannerEntity 报告设备在本地网络上的连接状态。如果设备已连接,ScannerEntity 的状态将是关联 zone 的名称,例如与 home zone 关联时为 `home`;如果设备未连接,状态将为 `not_home`。 基类设置了 `in_zones` 状态属性。当设备连接时,它将被填充为关联 zone 及其包含的 zone 的 `entity_id`,按大小排序;未连接时则为空。 基类还将 `tracking_type` 能力属性设置为 `TrackingType.CONNECTION`。 ScannerEntity 基于 BaseScannerEntity,旨在跟踪连接到 IP 网络且可通过 MAC 地址识别的设备。 从 [`homeassistant.components.device_tracker.ScannerEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/device_tracker/__init__.py) 派生平台实体。 ### 属性 :::tip 属性应始终仅返回内存中的信息,而不是执行 I/O(如网络请求)。实现 `update()` 或 `async_update()` 来获取数据。 ::: | 名称 | 类型 | 默认值 | 描述 | | ------------- | ---------------| ------------------- | ----------------------------------- | | hostname | `str \| None` | `None` | 设备的主机名。 | | ip\_address | `str \| None` | `None` | 设备的 IP 地址。 | | is\_connected | `bool \| None` | **必填** | 设备的连接状态。 | | mac\_address | `str \| None` | `None` | 设备的 MAC 地址。 | | source\_type | `SourceType` | `SourceType.ROUTER` | 设备的 source 类型。 | ### DHCP 发现 如果 device tracker 的 `source_type` 为 `router`,并且已设置 `ip_address`、`mac_address` 和 `hostname` 属性,数据将 加速 `DHCP discovery`,因为系统不必等待 DHCP discover 数据包来查找现有设备。 ## TrackerEntity TrackerEntity 跟踪设备的位置,并以 zone 名称或 `home` / `not_home` 状态报告。TrackerEntity 可使用 GPS 坐标或 `Zone` entity\_id 列表来确定其状态。应设置 `in_zones` 或 `latitude` 和 `longitude` 来报告状态。如果 `in_zones` 和 `latitude` + `longitude` 同时存在,则 `in_zones` 优先。如果未提供 `in_zones`,基类将计算一个 `in_zones` 列表,包含设备当前所处的 active 和 passive zone。实体的状态为 `in_zones` 列表中的第一个 active zone,如果第一个 active zone 是 home zone 则为 `home`,如果没有 active zone 则为 `not_home`。 基类将 `tracking_type` 能力属性设置为 `TrackingType.POSITION`。 从 [`homeassistant.components.device_tracker.TrackerEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/device_tracker/__init__.py) 派生平台实体。 ### 属性 :::tip 属性应始终仅返回内存中的信息,而不是执行 I/O(如网络请求)。实现 `update()` 或 `async_update()` 来获取数据。 ::: | 名称 | 类型 | 默认值 | 描述 | | ----------------- | --------------------| ---------------- | ---------------------------------------- | | in\_zones | `list[str] \| None` | `None` | 设备所在的 zones,包括 passive zones。此列表应按 zone 大小排序,然后按到 zone 中心的距离排序。 | | latitude | `float \| None` | `None` | 设备的纬度坐标,如果 `in_zones` 不为 `None` 则忽略。 | | location\_accuracy | `float` | `0` | 设备的位置精度(米)。 | | longitude | `float \| None` | `None` | 设备的经度坐标,如果 `in_zones` 不为 `None` 则忽略。 | | source\_type | SourceType | `SourceType.GPS` | 设备的 source 类型。 | --- url: /developers/core/entity/event.md --- Event 是在发生某事时发出的信号,例如用户按下门铃等物理按钮或按下遥控器上的按钮时。event 实体捕获物理世界中的这些事件,并将它们作为实体在 Home Assistant 中可用。 Event 实体派生自 [`homeassistant.components.event.EventEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/event/__init__.py)。 ## 状态 Event 实体是无状态的,这意味着你无需维护状态。相反,当物理世界中发生某事时,你可以触发一个事件。Home Assistant 会跟踪最后发出的事件,并将其显示为实体的当前状态。 实体的主要状态是最后发出事件的时间戳,此外,还会跟踪事件类型以及随事件提供的可选额外状态数据。 ## 属性 :::tip 属性应始终仅返回内存中的信息,而不是执行 I/O(如网络请求)。实现 `update()` 或 `async_update()` 来获取数据。 ::: | 名称 | 类型 | 默认值 | 描述 | | ----------- | --------------- | ------------ | ---------------------------------------------------- | | event\_types | `list[str]` | **必填** | 此实体可以发出的可能事件类型列表。 | 所有实体共有的其他属性(如 `device_class`、`icon`、`name` 等)也适用。 ## 触发事件 Event 实体与其他实体略有不同。Home Assistant 管理状态,但集成 负责触发事件。这是通过调用 event 实体上的 `_trigger_event` 方法来实现的。 此方法以事件类型作为第一个参数,以额外的状态数据作为可选的第二个参数。 ```python class MyEvent(EventEntity): _attr_device_class = EventDeviceClass.BUTTON _attr_event_types = ["single_press", "double_press"] @callback def _async_handle_event(self, event: str) -> None: """Handle the demo button event.""" self._trigger_event(event, {"extra_data": 123}) self.async_write_ha_state() async def async_added_to_hass(self) -> None: """Register callbacks with your device API/library.""" my_device_api.listen(self._async_handle_event) ``` 只能发出在 `event_types` 属性中定义的事件类型。如果发出未定义在 `event_types` 属性中的事件类型,将引发 `ValueError`。 :::tip 务必在实体从 Home Assistant 中移除时注销任何回调。 ::: ### 可用的 device class 可选指定实体是什么类型。 | 常量 | 描述 | | --------------------------- | ----------------------------------------------------- | | `EventDeviceClass.BUTTON` | 按下了遥控器上的按钮。 | | `EventDeviceClass.DOORBELL` | 专门用于用作门铃的按钮。 | | `EventDeviceClass.MOTION` | 用于运动传感器检测到的运动事件。 | ### 标准事件类型 某些 device class 定义了标准事件类型,以确保集成的了一致性,从而启用与底层集成无关的通用自动化。 #### 门铃 * `DoorbellEventType.RING`:表示标准的"门铃被按下"事件。**此事件类型是必需的**。 #### 按钮 * `ButtonEventType.PRESS_START`:按钮被按下。 * `ButtonEventType.PRESS_END`:按钮在短暂按下后释放(标准的"点击")。 * `ButtonEventType.LONG_PRESS_START`:按钮被按住超过某个阈值。 * `ButtonEventType.LONG_PRESS_END`:按钮在长按后释放。 * `ButtonEventType.MULTI_PRESS_ONGOING`:检测到多按序列中的中间一次按下。 * `ButtonEventType.MULTI_PRESS_END`:多按序列完成。 `MULTI_PRESS_ONGOING` 和 `MULTI_PRESS_END` 在 `event_data` 中包含 `multi_press_count` 属性,表示按下的次数。 如果设备每次交互仅发出一个事件,没有单独的按下和释放,则将其映射到对应的 `_end` 类型(短按为 `PRESS_END`,长按为 `LONG_PRESS_END`,以此类推)。 对于从单个来源报告方向的按钮(例如上/下滚轮),优先按方向暴露独立的实体。当无法拆分为多个实体时,使用非标准的 `direction` 属性是可接受的替代方案。 也允许其他非标准事件类型。 --- url: /developers/core/entity/fan.md --- Fan entity 是控制 fan 的各个向量(如 speed、direction 和 oscillation)的 device。从 [`homeassistant.components.fan.FanEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/fan/__init__.py) 派生 entity platforms。 ## 属性 :::tip Properties 应始终只从内存返回信息,而不要执行 I/O(如网络请求)。请实现 `update()` 或 `async_update()` 来获取数据。 ::: | Name | Type | Default | Description | ---- | ---- | ------- | ----------- | current\_direction | `str \| None` | `None` | Fan 当前的 direction。 | | is\_on | `bool \| None` | `None` | 如果 fan 已开启则为 `True`。 | | oscillating | `bool \| None` | `None` | 如果 fan 正在 oscillating 则为 `True`。 | | percentage | `int \| None` | `0` | 当前的 speed percentage。必须是 0(off)到 100 之间的值。 | | preset\_mode | `str \| None` | `None` | 当前的 preset\_mode。为 `preset_modes` 中的值之一,或如果没有活跃的 preset 则为 `None`。 | | preset\_modes | `list[str] \| None` | `None` | 支持的 preset\_modes 列表。这是一个任意 str 列表,不应包含任何 speed。 | | speed\_count | `int` | 100 | Fan 支持的 speed 数量。 | ### 预设模式 Fan 可能有 preset modes,自动控制 percentage speed 或其他功能。常见示例包括 `auto`、`smart`、`whoosh`、`eco` 和 `breeze`。如果没有设置 preset mode,`preset_mode` property 必须设为 `None`。 Preset modes 不应包含命名的(手动)speed settings,因为这些应表示为 percentage。 手动设置 speed 必须禁用任何已设置的 preset mode。如果可以在不禁用 preset mode 的情况下手动设置 percentage speed,请创建一个 switch 或 service action 来代表该 mode。 ## 支持的功能 Supported features 通过使用 `FanEntityFeature` 枚举中的值来定义, 并使用按位或(`|`)运算符组合。 | Value | Description | | ------------- | ------------------------------------------------------------------------ | | `DIRECTION` | Fan 支持更改 direction。 | | `OSCILLATE` | Fan 支持 oscillation。 | | `PRESET_MODE` | Fan 支持 preset modes。 | | `SET_SPEED` | Fan 支持设置 speed percentage 和可选 preset modes。 | | `TURN_OFF` | Fan 支持关闭。 | | `TURN_ON` | Fan 支持开启。 | ## 方法 ### 设置方向 仅当设置了 `FanEntityFeature.DIRECTION` 标志时,才实现此 method。 ```python class FanEntity(ToggleEntity): # 实现以下方法之一。 def set_direction(self, direction: str) -> None: """Set the direction of the fan.""" async def async_set_direction(self, direction: str) -> None: """Set the direction of the fan.""" ``` ### 设置预设模式 仅当设置了 `FanEntityFeature.PRESET_MODE` 标志时,才实现此 method。 ```python class FanEntity(ToggleEntity): # 实现以下方法之一。 def set_preset_mode(self, preset_mode: str) -> None: """Set the preset mode of the fan.""" async def async_set_preset_mode(self, preset_mode: str) -> None: """Set the preset mode of the fan.""" ``` ### 设置速度百分比 仅当设置了 `FanEntityFeature.SET_SPEED` 标志时,才实现此 method。 ```python class FanEntity(ToggleEntity): # 实现以下方法之一。 def set_percentage(self, percentage: int) -> None: """Set the speed percentage of the fan.""" async def async_set_percentage(self, percentage: int) -> None: """Set the speed percentage of the fan.""" ``` :::tip Converting speeds Home Assistant 包含用于转换 speed 的 utility。 如果 device 有命名的 speed 列表: ```python from homeassistant.util.percentage import ordered_list_item_to_percentage, percentage_to_ordered_list_item ORDERED_NAMED_FAN_SPEEDS = ["one", "two", "three", "four", "five", "six"] # 不包含 off percentage = ordered_list_item_to_percentage(ORDERED_NAMED_FAN_SPEEDS, "three") named_speed = percentage_to_ordered_list_item(ORDERED_NAMED_FAN_SPEEDS, 23) ... @property def percentage(self) -> Optional[int]: """Return the current speed percentage.""" return ordered_list_item_to_percentage(ORDERED_NAMED_FAN_SPEEDS, current_speed) @property def speed_count(self) -> int: """Return the number of speeds the fan supports.""" return len(ORDERED_NAMED_FAN_SPEEDS) ``` 如果 device 有数值的 speed range: ```python from homeassistant.util.percentage import ranged_value_to_percentage, percentage_to_ranged_value from homeassistant.util.scaling import int_states_in_range SPEED_RANGE = (1, 255) # 不包含 off percentage = ranged_value_to_percentage(SPEED_RANGE, 127) value_in_range = math.ceil(percentage_to_ranged_value(SPEED_RANGE, 50)) ... @property def percentage(self) -> Optional[int]: """Return the current speed percentage.""" return ranged_value_to_percentage(SPEED_RANGE, current_speed) @property def speed_count(self) -> int: """Return the number of speeds the fan supports.""" return int_states_in_range(SPEED_RANGE) ``` ::: ### 开启 仅当设置了 `FanEntityFeature.TURN_ON` 标志时,才实现此 method。 ```python class FanEntity(ToggleEntity): # 实现以下方法之一。 def turn_on(self, percentage: Optional[int] = None, preset_mode: Optional[str] = None, **kwargs: Any) -> None: """Turn on the fan.""" async def async_turn_on(self, percentage: Optional[int] = None, preset_mode: Optional[str] = None, **kwargs: Any) -> None: """Turn on the fan.""" ``` :::tip `speed` 已弃用。 对于新集成,不应实现 `speed`,而应仅使用 `percentage` 和 `preset_mode`。 ::: ### 关闭 仅当设置了 `FanEntityFeature.TURN_OFF` 标志时,才实现此 method。 ```python class FanEntity(ToggleEntity): # 实现以下方法之一。 def turn_off(self, **kwargs: Any) -> None: """Turn the fan off.""" async def async_turn_off(self, **kwargs: Any) -> None: """Turn the fan off.""" ``` ### 切换 可选。如果未实现,默认会通过检查 `is_on` property 来确定调用哪个 method。 仅当设置了 `FanEntityFeature.TURN_ON` 和 `FanEntityFeature.TURN_OFF` 标志时,才实现此 method。 ```python class FanEntity(ToggleEntity): # 实现以下方法之一。 def toggle(self, **kwargs: Any) -> None: """Toggle the fan.""" async def async_toggle(self, **kwargs: Any) -> None: """Toggle the fan.""" ``` ### 摆头 仅当设置了 `FanEntityFeature.OSCILLATE` 标志时,才实现此 method。 ```python class FanEntity(ToggleEntity): # 实现以下方法之一。 def oscillate(self, oscillating: bool) -> None: """Oscillate the fan.""" async def async_oscillate(self, oscillating: bool) -> None: """Oscillate the fan.""" ``` --- url: /developers/core/entity/geo-location.md --- Geolocation 实体表示一个与位置相关联的外部事件,例如地震、野火或外部 feed 发布的其他兴趣点。每个实体都携带坐标,通常显示为地图上的标记。 Geolocation 实体派生自 [`homeassistant.components.geo_location.GeolocationEvent`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/geo_location/__init__.py)。 ## 状态 Geolocation 实体的状态是事件位置到 Home Assistant 实例配置的 home location 的距离,四舍五入到一位小数。状态由基类实体管理,无法覆盖;应设置 `distance` 属性。距离的单位通过标准的 `unit_of_measurement` 属性声明。 ## 属性 :::tip 属性应始终仅返回内存中的信息,而不是执行 I/O(如网络请求)。实现 `update()` 或 `async_update()` 来获取数据。 ::: | 名称 | 类型 | 默认值 | 描述 | | --------- | --------------- | ------------ | ------------------------------------------------------------------------------ | | source | `str` | **必填** | 事件的来源,通常是提供该事件集成的 domain。 | | distance | `float \| None` | `None` | 从 home location 到事件的距离,单位为 `unit_of_measurement`。 | | latitude | `float \| None` | `None` | 事件的纬度。 | | longitude | `float \| None` | `None` | 事件的经度。 | 所有实体共有的其他属性(如 `icon`、`name` 等)也适用。 `latitude`、`longitude` 和 `source` 值会自动作为状态属性暴露;坐标四舍五入到五位小数。 ## 生命周期 与大多数实体不同,geolocation 实体通常表示短期外部事件,而不是设备:集成在新事件出现在外部 feed 中添加实体,并在事件不再被报告时将其移除。常见的模式是一个管理器订阅 feed 更新,并在每次更新时为新事件添加实体、更新现有实体,并通过调用其 `async_remove(force_remove=True)` 方法来移除已消失事件的实体——`force_remove` 标志确保已注册的实体从状态机中完全移除,而不是作为不可用而滞留。使用唯一 ID 创建的实体也应移除其 entity registry 条目。 [GDACS integration](https://github.com/home-assistant/core/blob/dev/homeassistant/components/gdacs/geo_location.py) 是此模式的示例,[demo platform](https://github.com/home-assistant/core/blob/dev/homeassistant/components/demo/geo_location.py) 提供了最小实现。 --- url: /developers/core/entity/humidifier.md --- Humidifier 实体是主要用途为控制湿度的设备,即加湿器或除湿器。从 [`homeassistant.components.humidifier.HumidifierEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/humidifier/__init__.py) 派生实体平台。 ## 属性 :::tip 属性应始终仅返回内存中的信息,而不是执行 I/O(如网络请求)。实现 `update()` 或 `async_update()` 来获取数据。 ::: | 名称 | 类型 | 默认值 | 描述 | | ----------------------- | ---------------------------------------------- | ------------------------------------- | -------------------------------------------------- | | action | `HumidifierAction \| None` | `None` | 返回设备的当前状态。 | | available\_modes | `list[str] \| None` | **MODES 必填** | 可用的模式。需要 `HumidifierEntityFeature.MODES`。 | | current\_humidity | `float \| None` | `None` | 设备测量的当前湿度。 | | device\_class | `HumidifierDeviceClass \| None` | `None` | hygrostat 的类型 | | is\_on | `bool \| None` | `None` | 设备是开启还是关闭。 | | max\_humidity | `float` | `DEFAULT_MAX_HUMIDITY`(值 == 100) | 最大湿度。 | | min\_humidity | `float` | `DEFAULT_MIN_HUMIDITY`(值 == 0) | 最小湿度。 | | mode | `str \| None` | **必填** | 当前活动的模式。需要 `HumidifierEntityFeature.MODES`。 | | target\_humidity | `float \| None` | `None` | 设备试图达到的目标湿度。 | | target\_humidity\_step | `float \| None` | `None` | 目标湿度可增加或减少的步长。 | ### 可用的 device class | 常量 | 描述 | | ------------------------------------ | ------------------------------------------ | | `HumidifierDeviceClass.DEHUMIDIFIER` | 除湿器 | | `HumidifierDeviceClass.HUMIDIFIER` | 加湿器 | ### 模式 设备可以有不同的操作模式,并希望向用户展示。它们可以被视为预设或某些设备状态,针对特殊条件具有缩减或增强的功能,即"auto"或"baby"。有几个内置模式会提供翻译,但如果自定义模式能更好地表示设备,也允许添加自定义模式。 | 名称 | 描述 | | -------------- | --------------------------------------- | | `MODE_NORMAL` | 无预设激活,正常运行 | | `MODE_ECO` | 设备正在运行节能模式 | | `MODE_AWAY` | 设备处于 away 模式 | | `MODE_BOOST` | 设备将所有阀门完全打开 | | `MODE_COMFORT` | 设备处于舒适模式 | | `MODE_HOME` | 设备处于 home 模式 | | `MODE_SLEEP` | 设备为睡眠做好了准备 | | `MODE_AUTO` | 设备自动控制湿度 | | `MODE_BABY` | 设备正在为婴儿优化 | ## 支持的功能 支持的功能通过使用 `HumidifierEntityFeature` 枚举中的值来定义,并使用按位或(`|`)运算符进行组合。 | 值 | 描述 | | ------- | ------------------------------------ | | `MODES` | 设备支持不同的模式。 | ## 动作 `action` 属性可以返回设备的当前操作状态,即正在加湿还是空闲。这是一个信息性属性。请注意,当设备关闭时,`action` 属性(如果存在)将自动替换为"off"。另请注意,将 `action` 设置为 `off` 不会替代 `is_on` 属性。 `HumidifierAction` 的当前值: | 名称 | 描述 | | ------------- | ------------------------------------------ | | `HUMIDIFYING` | 设备当前正在加湿。 | | `DRYING` | 设备当前正在除湿。 | | `IDLE` | 设备已开启但目前未活动。 | | `OFF` | 设备已关闭。 | ## 方法 ### 设置模式 ```python class MyHumidifierEntity(HumidifierEntity): # 实现以下方法之一。 def set_mode(self, mode: str) -> None: """Set new target preset mode.""" async def async_set_mode(self, mode: str) -> None: """Set new target preset mode.""" ``` ### 设置湿度 如果当前模式不允许调整目标湿度,设备应在此调用时自动更改其模式,以使其成为可能。 ```python class MyHumidifierEntity(HumidifierEntity): # 实现以下方法之一。 def set_humidity(self, humidity: int) -> None: """Set new target humidity.""" async def async_set_humidity(self, humidity: int) -> None: """Set new target humidity.""" ``` ### 开启 ```python class MyHumidifierEntity(HumidifierEntity): # 实现以下方法之一。 def turn_on(self, **kwargs: Any) -> None: """Turn the device on.""" async def async_turn_on(self, **kwargs: Any) -> None: """Turn the device on.""" ``` ### 关闭 ```python class MyHumidifierEntity(HumidifierEntity): # 实现以下方法之一。 def turn_off(self, **kwargs: Any) -> None: """Turn the device off.""" async def async_turn_off(self, **kwargs: Any) -> None: """Turn the device off.""" ``` --- url: /developers/core/entity/image.md --- Image 实体可以显示静态图像。从 [`homeassistant.components.image.ImageEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/image/__init__.py) 派生平台实体。 Image 实体是 [`camera`](/developers/core/entity/camera.md) 实体的简化版本,支持提供静态图像或可获取的图像 URL。 实现可以提供 URL,图像将从该 URL 自动获取,也可以提供 `bytes` 类型的图像数据。提供 URL 时,获取的图像将缓存在 `self._cached_image` 中;将 `self._cached_image` 设置为 `None` 以使缓存失效。 ## 属性 :::tip 属性应始终仅返回内存中的信息,而不是执行 I/O(如网络请求)。实现 `update()` 或 `async_update()` 来获取数据。 ::: | 名称 | 类型 | 默认值 | 描述 | | -------------------| --------------------------------- | ------------ | -------------------------------------------------------------------------------------------------------- | | content\_type | str | `image/jpeg` | 图像的 content-type,如果 image 实体提供了 URL 则自动设置。 | | image\_last\_updated | `datetime.datetime \| None` | `None` | 图像上次更新的时间戳。用于确定 `state`。前端在此值变更后会调用 `image` 或 `async_image`。 | | image\_url | `str \| None` | `UNDEFINED` | 可选的 URL,应从该 URL 获取图像。 | ## 方法 ### 图像 如果你的实体返回图像的 bytes 而不是提供 URL,请实现 `async_image` 或 `image`。前端将调用 `async_image` 或 `image` 来获取图像。如果图像是从远程获取的,应缓存图像数据,并在 `image_last_updated` 更改时使缓存失效。 注意: * image 实体的 `async_image` 或 `image` 方法仅在前端获取图像时调用。 * 前端将会: * 当加载包含 image 实体的页面时获取一次图像 * 当 image 实体通过更改 `image_last_updated` 改变状态时重新获取图像 这意味着在 `async def async_image` 中递增 `image_last_updated` 属性是不正确的。相反,image 实体应在图像更新可用时或定期(如果图像需要过一段时间后重新获取)更新 `image_last_updated` 时间戳。例如,这可以发生在 entity coordinator 更新的过程中。 ```python class MyImage(ImageEntity): # 实现以下方法之一。 def image(self) -> bytes | None: """Return bytes of image.""" async def async_image(self) -> bytes | None: """Return bytes of image.""" ``` --- url: /developers/core/entity/infrared.md --- Infrared 域提供了 IR 硬件(如 ESPHome、Broadlink 或 ZHA 设备)与需要发送或接收 IR 命令的设备特定集成(如 LG 或 Samsung 电视控制)之间的抽象层。它定义了两类虚拟实体——一个发送 IR 命令的**发射器**(emitter)和一个捕获传入 IR 信号的**接收器**(receiver),其他集成可以使用它们来控制或对 IR 设备做出反应。 发射器和接收器基类位于 [`homeassistant.components.infrared`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/infrared/entity.py)。 ## 架构概览 Infrared 集成在以下方面创建分离: 1. **Emitter 集成**(如 ESPHome、Broadlink):这些实现 `InfraredEmitterEntity`,以提供硬件特定的 IR 传输。 2. **Receiver 集成**(如 ESPHome、Broadlink):这些实现 `InfraredReceiverEntity`,以提供硬件特定的 IR 接收。 3. **Consumer 集成**(如 LG、Samsung):这些使用 infrared 辅助函数——或提供的 consumer 基类——通过发射器发送设备特定的 IR 命令和/或对来自接收器的信号做出反应。 ```mermaid flowchart TD subgraph consumers["Consumer integrations"] direction LR LG["LG"] ~~~ Samsung["Samsung"] ~~~ Daikin["Daikin"] ~~~ more1["..."] end subgraph infrared["infrared domain"] direction LR subgraph bases["Base classes"] direction TB InfraredEmitterEntity ~~~ InfraredReceiverEntity end subgraph helpers["Helper functions / consumer bases"] direction TB async_get_emitters ~~~ async_send_command ~~~ InfraredEmitterConsumerEntity async_get_receivers ~~~ async_subscribe_receiver ~~~ InfraredReceiverConsumerEntity end end subgraph emitters["Emitter / receiver integrations"] direction LR ESPHome["ESPHome"] ~~~ Broadlink["Broadlink"] ~~~ ZHA["ZHA"] ~~~ more2["..."] end consumers -->|"Use helpers / consumer bases"| helpers bases -->|"Implemented by"| emitters ``` ## 设备类型 Infrared 实体公开一个 [`InfraredDeviceClass`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/infrared/entity.py),反映其角色: | 值 | 含义 | | ---------- | ---------------------------------------------------- | | `emitter` | 发送 IR 命令。由 `InfraredEmitterEntity` 自动设置。 | | `receiver` | 接收 IR 信号。由 `InfraredReceiverEntity` 自动设置。 | Emitter 和 receiver 集成无需自行设置 device class——基类会自动分配。 ## InfraredEmitterEntity Emitter 实体封装了一个 IR 发射器硬件。基类是 `InfraredEmitterEntity`,由 `InfraredEmitterEntityDescription` 描述。 ### 状态 Infrared emitter 实体状态表示最后发送 IR 命令的时间戳。这在基类 InfraredEmitterEntity 中实现,集成不应更改。 ### 发送命令方法 `InfraredEmitterEntity.async_send_command` 方法必须由 emitter 集成实现,以处理实际的 IR 传输。 ```python class MyInfraredEmitter(InfraredEmitterEntity): """My infrared emitter.""" async def async_send_command(self, command: infrared_protocols.commands.Command) -> None: """Send an IR command. Args: command: The IR command to send. Raises: HomeAssistantError: If transmission fails. """ ``` :::important Consumer 集成不得直接调用 `InfraredEmitterEntity.async_send_command`。请使用 [`async_send_command`](#send-command) 辅助函数(或 [`InfraredEmitterConsumerEntity`](#emitter-consumer-base-class) 基类),它会自动处理状态更新和 context 传播。 ::: ## InfraredReceiverEntity Receiver 实体封装了一个 IR 接收器硬件。基类是 `InfraredReceiverEntity`,由 `InfraredReceiverEntityDescription` 描述。 ### 状态 Infrared receiver 实体状态表示最后接收 IR 信号的时间戳。这在基类 InfraredReceiverEntity 中实现,集成不应更改。 ### 报告接收到的信号 Receiver 集成在硬件上观察到 IR 信号时,从基类调用 `_handle_received_signal`。基类更新状态并通知订阅者。 ```python class MyInfraredReceiver(InfraredReceiverEntity): """My infrared receiver.""" def _on_hardware_signal(self, timings: list[int], modulation: int | None) -> None: self._handle_received_signal( InfraredReceivedSignal(timings=timings, modulation=modulation) ) ``` ## 辅助函数 Infrared 域公开了辅助函数,使 consumer 集成能够发现硬件并与之交互,而无需持有对实体实例的直接引用。 ### 获取 emitters 返回所有可用的 infrared emitter 实体的实体 IDs。 ```python from homeassistant.components import infrared emitters = infrared.async_get_emitters(hass) ``` ### 获取 receivers 返回所有可用的 infrared receiver 实体的实体 IDs。 ```python from homeassistant.components import infrared receivers = infrared.async_get_receivers(hass) ``` ### 发送命令 通过特定的 emitter 实体发送 IR 命令。 ```python from infrared_protocols.commands.nec import NECCommand from homeassistant.components import infrared command = NECCommand( address=0x04, command=0x08, modulation=38000, # 38 kHz carrier frequency ) await infrared.async_send_command( hass, emitter_entity_id, command, context=context, # 用于 logbook 跟踪的可选 context ) ``` ### 订阅接收器 订阅来自特定 receiver 实体的 IR 信号。返回一个取消订阅的回调。 ```python from homeassistant.components import infrared from homeassistant.components.infrared import InfraredReceivedSignal @callback def handle_signal(signal: InfraredReceivedSignal) -> None: ... unsubscribe = infrared.async_subscribe_receiver( hass, receiver_entity_id, handle_signal ) ``` ## Consumer 基类 Consumer 集成通常不需要直接调用发送/接收辅助函数。Infrared 集成提供了两个基类,负责跟踪底层硬件的可用性,以及(对于 receivers)管理订阅生命周期。 ### Emitter consumer 基类 `InfraredEmitterConsumerEntity` 跟踪所配置 emitter 的可用性,并暴露一个 `_send_command` 方法,通过 `async_send_command` 转发,包括实体的当前 context。 ```python from homeassistant.components.infrared import InfraredEmitterConsumerEntity class MyButton(InfraredEmitterConsumerEntity, ButtonEntity): """A button that emits an IR command.""" def __init__(self, emitter_entity_id: str) -> None: self._infrared_emitter_entity_id = emitter_entity_id async def async_press(self) -> None: await self._send_command(SOME_COMMAND) ``` 基类根据 emitter 的状态设置 `self._attr_available`,并在 emitter 变为可用或不可用时进行更新。 ### Receiver consumer 基类 `InfraredReceiverConsumerEntity` 跟踪所配置 receiver 的可用性,在可用时订阅其信号,并在 receiver 消失时自动取消订阅。子类实现 `_handle_signal`。 ```python from homeassistant.components.infrared import ( InfraredReceivedSignal, InfraredReceiverConsumerEntity, ) class MyRemote(InfraredReceiverConsumerEntity, EventEntity): """An event entity that fires when an IR signal is received.""" def __init__(self, receiver_entity_id: str) -> None: self._infrared_receiver_entity_id = receiver_entity_id @override @callback def _handle_signal(self, signal: InfraredReceivedSignal) -> None: ... ``` ## IR 命令 [`infrared-protocols`](https://github.com/home-assistant-libs/infrared-protocols) 库提供了命令类,将协议特定的数据(NEC、RC-5、Kaseikyo 等)转换为原始 timings。 所有 IR 命令继承自 `infrared_protocols.commands.Command` 并实现 `get_raw_timings()`。 --- url: /developers/core/entity/lawn-mower.md --- 从 [`homeassistant.components.lawn_mower.LawnMowerEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/lawn_mower/__init__.py) 派生实体平台。 ## 属性 :::tip 属性应始终仅返回内存中的信息,而不是执行 I/O(如网络请求)。实现 `update()` 或 `async_update()` 来获取数据。 ::: | 名称 | 类型 | 默认值 | 描述 | -------- | ------------------------------------------ | ------- | ----------------- | activity | `LawnMowerActivity \| None` | `None` | 当前活动。 ## 活动 | 活动 | 描述 | -------- | ----------- | `MOWING` | 割草机当前正在割草。 | `DOCKED` | 割草机已完成割草,当前已停靠。 | `PAUSED` | 割草机处于活动状态,现在已暂停。 | `RETURNING` | 割草机正在返回 dock。 | `ERROR` | 割草机在活动过程中遇到错误,需要协助。 ## 支持的功能 支持的功能通过使用 `LawnMowerEntityFeature` 枚举中的值来定义,并使用按位或(`|`)运算符进行组合。 | 值 | 描述 | | -------------- | ---------------------------------------------------- | | `START_MOWING` | 割草机支持 start mowing 命令。 | | `PAUSE` | 割草机支持暂停当前任务。 | | `DOCK` | 割草机支持返回 dock 命令。 | ## 方法 ### `start_mowing` 或 `async_start_mowing` 开始或恢复割草任务。 ### `dock` 或 `async_dock` 停止割草机,返回 dock。 ### `pause` 或 `async_pause` 在当前操作过程中暂停割草机。 --- url: /developers/core/entity/light.md --- Light entity 控制 light source 的 brightness、hue 和 saturation color value、white value、color temperature 和 effect。从 [`homeassistant.components.light.LightEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/light/__init__.py) 派生 platform entities。 ## 属性 | Name | Type | Default | Description | ---- | ---- | ---- | ---- | brightness | `int \| None` | `None` | 该 light 的 brightness,范围在 1..255 之间 | color\_mode | `ColorMode \| None` | `None` | Light 的 color mode。返回的 color mode 必须存在于 `supported_color_modes` property 中,除非 light 正在渲染 effect。 | color\_temp\_kelvin | `int \| None` | `None` | CT color value(单位为 K)。当 light 的 color mode 设为 `ColorMode.COLOR_TEMP` 时,此 property 会复制到 light 的 state attribute 中,否则忽略。 | effect | `str \| None` | `None` | 当前的 effect。如果 light 支持 effect 且当前未渲染任何 effect,则应为 `EFFECT_OFF`。 | effect\_list | `list[str] \| None` | `None` | 支持的 effect 列表。 | hs\_color | `tuple[float, float] \| None` | `None` | Hue 和 saturation color value(float, float)。当 light 的 color mode 设为 `ColorMode.HS` 时,此 property 会复制到 light 的 state attribute 中,否则忽略。 | is\_on | `bool \| None` | `None` | Light entity 是否开启。 | max\_color\_temp\_kelvin | `int \| None` | `None` | 该 light 支持的最冷 color\_temp\_kelvin。 | min\_color\_temp\_kelvin | `int \| None` | `None` | 该 light 支持的最暖 color\_temp\_kelvin。 | rgb\_color | `tuple[int, int, int] \| None` | `None` | RGB color value(int, int, int)。当 light 的 color mode 设为 `ColorMode.RGB` 时,此 property 会复制到 light 的 state attribute 中,否则忽略。 | rgbw\_color | `tuple[int, int, int, int] \| None` | `None` | RGBW color value(int, int, int, int)。当 light 的 color mode 设为 `ColorMode.RGBW` 时,此 property 会复制到 light 的 state attribute 中,否则忽略。 | rgbww\_color | `tuple[int, int, int, int, int] \| None` | `None` | RGBWW color value(int, int, int, int, int)。当 light 的 color mode 设为 `ColorMode.RGBWW` 时,此 property 会复制到 light 的 state attribute 中,否则忽略。 | supported\_color\_modes | `set[ColorMode] \| None` | `None` | 标志支持的 color modes。 | xy\_color | `tuple[float, float] \| None` | `None` | XY color value(float, float)。当 light 的 color mode 设为 `ColorMode.XY` 时,此 property 会复制到 light 的 state attribute 中,否则忽略。 ## 颜色模式 Light 必须同时实现 `color_mode` 和 `supported_color_modes`。Supported color modes 通过使用 `ColorMode` 枚举中的值来定义,`color_mode` 必须设为 `supported_color_modes` 中列出的 modes 之一。 设置 `supported_color_modes` 是必需的。未设置它的 light 在写入 state 时会引发 error。 可用的 color modes 有: | Value | Description |----------|----------------------- | `ColorMode.UNKNOWN` | Light 的 color mode 未知。 | `ColorMode.ONOFF` | Light 可以开启或关闭。如果 light 支持此 mode,它必须是唯一支持的 mode。 | `ColorMode.BRIGHTNESS` | Light 可以 dim。如果 light 支持此 mode,它必须是唯一支持的 mode。 | `ColorMode.COLOR_TEMP` | Light 可以 dim,且其 color temperature 出现在 state 中。 | `ColorMode.HS` | Light 可以 dim,且其 color 可以调整。Light 的 brightness 可以通过 `brightness` 参数设置,通过 `brightness` property 读取。Light 的 color 可以通过 `hs_color` 参数设置,通过 `hs_color` property 读取。`hs_color` 是 (h, s) tuple(不含 brightness)。 | `ColorMode.RGB` | Light 可以 dim,且其 color 可以调整。Light 的 brightness 可以通过 `brightness` 参数设置,通过 `brightness` property 读取。Light 的 color 可以通过 `rgb_color` 参数设置,通过 `rgb_color` property 读取。`rgb_color` 是 (r, g, b) tuple(未按 brightness 归一化)。 | `ColorMode.RGBW` | Light 可以 dim,且其 color 可以调整。Light 的 brightness 可以通过 `brightness` 参数设置,通过 `brightness` property 读取。Light 的 color 可以通过 `rgbw_color` 参数设置,通过 `rgbw_color` property 读取。`rgbw_color` 是 (r, g, b, w) tuple(未按 brightness 归一化)。 | `ColorMode.RGBWW` | Light 可以 dim,且其 color 可以调整。Light 的 brightness 可以通过 `brightness` 参数设置,通过 `brightness` property 读取。Light 的 color 可以通过 `rgbww_color` 参数设置,通过 `rgbww_color` property 读取。`rgbww_color` 是 (r, g, b, cw, ww) tuple(未按 brightness 归一化)。 | `ColorMode.WHITE` | Light 可以 dim,且其 color 可以调整。此外,Light 可以设为 white mode。Light 的 brightness 可以通过 `brightness` 参数设置,通过 `brightness` property 读取。Light 可以通过使用 `white` 参数(值为期望的 brightness)设为 white mode。注意,没有 `white` property。如果 `brightness` 和 `white` 都出现在 service action call 中,`white` 参数将更新为 `brightness` 的值。如果支持此 mode,light *必须*同时支持 `ColorMode.HS`、`ColorMode.RGB`、`ColorMode.RGBW`、`ColorMode.RGBWW` 或 `ColorMode.XY` 中的至少一种,且*不能*支持 `ColorMode.COLOR_TEMP`。 | `ColorMode.XY` | Light 可以 dim,且其 color 可以调整。Light 的 brightness 可以通过 `brightness` 参数设置,通过 `brightness` property 读取。Light 的 color 可以通过 `xy_color` 参数设置,通过 `xy_color` property 读取。`xy_color` 是 (x, y) tuple。 注意,在 color modes `ColorMode.RGB`、`ColorMode.RGBW` 和 `ColorMode.RGBWW` 中,`brightness` property 和 color 中都包含 brightness 信息。例如,如果 light 的 brightness 是 128 且 light 的 color 是 (192, 64, 32),light 的整体 brightness 为:128/255 \* max(192, 64, 32)/255 = 38%。 如果 light 处于 `ColorMode.HS`、`ColorMode.RGB` 或 `ColorMode.XY` mode,light 的 state attribute 将包含用 `hs`、`rgb` 和 `xy` color 格式表示的 light color。注意,当 light 处于 `ColorMode.RGB` mode 时,`hs` 和 `xy` state attributes 仅保留 `rgb` color 的 chromaticity,因为 `hs` 和 `xy` pair 不包含 brightness 信息。 如果 light 处于 `ColorMode.RGBW` 或 `ColorMode.RGBWW` mode,light 的 state attribute 将包含用 `hs`、`rgb` 和 `xy` color 格式表示的 light color。Color 转换是通过将 white channel 加到 color 上来近似完成的。 ### 白色颜色模式 有两种 white color modes:`ColorMode.COLOR_TEMP` 和 `ColorMode.WHITE`。两种 mode 的区别在于 `ColorMode.WHITE` 不允许调整 color temperature,而 `ColorMode.COLOR_TEMP` 允许调整 color temperature。 具有可调整 color temperature 的 lamp 通常由至少两组 LED 实现,具有不同的 color temperature,通常是一组 warm-white LED 和一组 cold-white LED。 具有不可调整 color temperature 的 light 通常只有一组 white LED。 ### 渲染 effect 时的 color mode 在渲染 effect 时,应根据 effect 支持的调整来设置 `color_mode`。如果 effect 不支持任何调整,`color_mode` 应设为 `ColorMode.ONOFF`。 如果 effect 允许调整 brightness,`color_mode` 应设为 `ColorMode.BRIGHTNESS`。 在渲染 effect 时,允许将 `color_mode` 设为比 `supported_color_mode` property 指示的更 restrictive 的 mode: * 支持 color 的 light 在由 effect 控制时可以将其 color\_mode 设为 `ColorMode.ONOFF` 或 `ColorMode.BRIGHTNESS` * 支持 brightness 的 light 在由 effect 控制时可以将其 color\_mode 设为 `ColorMode.ONOFF` ## 支持的功能 Supported features 通过使用 `LightEntityFeature` 枚举中的值来定义, 并使用按位或(`|`)运算符组合。 | Value | Description | | ------------ | -------------------------------------------------------------- | | `EFFECT` | 控制 light source 显示的 effect。 | | `FLASH` | 控制 light source 显示的 flash 持续时间。 | | `TRANSITION` | 控制 color 和 effect 之间 transition 的持续时间。 | ## 方法 ### 开启 light device ```python class MyLightEntity(LightEntity): def turn_on(self, **kwargs: Any) -> None: """Turn the device on.""" async def async_turn_on(self, **kwargs: Any) -> None: """Turn device on.""" ``` 注意,传递给 `async_turn_on` method 时没有 `color_mode`,而是只允许单个 color attribute。 保证 integration 在 `turn_on` call 中只会收到单个 color attribute,并且根据 light 的 `supported_color_modes` property,保证它被 light 支持。为确保这一点,如果 light 不支持相应的 color mode,service action call 中的 color 会在调用 entity 的 `async_turn_on` method 之前进行转换: | Color type | Translation |--------------|----------------------- | color\_temp | 如果不支持则从 service action call 中移除,如果 light 支持则转换为 `hs_color`、`rgb_color`、`rgbw_color`、`rgbww_color` 或 `xy_color`。 | hs\_color | 如果不支持则从 service action call 中移除,如果 light 支持则转换为 `rgb_color`、`rgbw_color`、`rgbww_color` 或 `xy_color`。 | rgb\_color | 如果不支持则从 service action call 中移除,如果 light 支持则转换为 `rgbw_color`、`rgbww_color`、`hs_color` 或 `xy_color`。 | rgbw\_color | 如果不支持则从 service action call 中移除。 | rgbww\_color | 如果不支持则从 service action call 中移除。 | xy\_color | 如果不支持则从 service action call 中移除,如果 light 支持则转换为 `hs_color`、`rgb_color`、`rgbw_color` 或 `rgbww_color`。 :::tip Scaling brightness Home Assistant 包含用于 scale brightness 的 utility。 如果 light 支持 brightness,有时 brightness value 需要 scaling: ```python from homeassistant.util.color import value_to_brightness BRIGHTNESS_SCALE = (1, 1023) ... @property def brightness(self) -> int | None: """Return the current brightness.""" return value_to_brightness(BRIGHTNESS_SCALE, self._device.brightness) ``` 将 brightness scale 到 device range: ````python from homeassistant.util.color import brightness_to_value BRIGHTNESS_SCALE = (1, 1023) ... class MyLightEntity(LightEntity): async def async_turn_on(self, **kwargs: Any) -> None: """Turn device on.""" ... value_in_range = math.ceil(brightness_to_value(BRIGHTNESS_SCALE, kwargs[ATTR_BRIGHTNESS])) ::: ### 关闭 light device ```python class MyLightEntity(LightEntity): def turn_off(self, **kwargs: Any) -> None: """Turn the device off.""" async def async_turn_off(self, **kwargs: Any) -> None: """Turn device off.""" ```` --- url: /developers/core/entity/lock.md --- Lock 实体可以被锁定和解锁。锁定和解锁可以选择用用户代码来保护。一些锁还允许打开 latch,这也可能用用户代码来保护。从 [`homeassistant.components.lock.LockEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/lock/__init__.py) 派生平台实体。 ## 属性 :::tip 属性应始终仅返回内存中的信息,而不是执行 I/O(如网络请求)。实现 `update()` 或 `async_update()` 来获取数据。 ::: | 名称 | 类型 | 默认值 | 描述 | ---- | ---- | ------- | ----------- | changed\_by | string | None | 描述上次更改是由什么触发的。 | code\_format | string | None | 用于验证传递给 lock、unlock 和 open 操作的代码的 Regex,如果不需代码则为 None。 | is\_locked | bool | None | 锁是否已锁定。用于确定 `state`。 | is\_locking | bool | None | 锁是否正在锁定过程中。用于确定 `state`。 | is\_unlocking | bool | None | 锁是否正在解锁过程中。用于确定 `state`。 | is\_open | bool | None | 锁是否已解锁并释放了 latch。仅对支持 `LockEntityFeature.OPEN` 的锁有意义。用于确定 `state`。 | is\_opening | bool | None | 锁是否正在释放 latch 的过程中。用于确定 `state`。 | is\_jammed | bool | None | 锁尝试移动但在完成前卡住。用于确定 `state`。 ### 状态 状态从上述属性派生,是以下 `LockState` 枚举成员之一: | 值 | 描述 | |-------------|--------------------------------------------------------------------| | `LOCKED` | 锁已锁定。 | | `LOCKING` | 锁正在锁定过程中。 | | `UNLOCKED` | 锁未锁定。 | | `UNLOCKING` | 锁正在解锁过程中。 | | `OPEN` | 锁未锁定并已释放 latch。 | | `OPENING` | 锁正在释放 latch 的过程中。 | | `JAMMED` | 锁尝试移动但在完成前卡住。 | :::note `OPEN` 状态和 `is_open` 属性要求锁既未锁定**又**已释放 latch。在锁仍锁定时释放 latch 并不是 open 状态。 ::: 当多个状态属性被设置时,它们按固定的优先级顺序评估,第一个匹配项决定状态: 1. `is_jammed` → `JAMMED` 2. `is_opening` → `OPENING` 3. `is_locking` → `LOCKING` 4. `is_open` → `OPEN` 5. `is_unlocking` → `UNLOCKING` 6. `is_locked` → `LOCKED`(当为 `True` 时),`UNLOCKED`(当为 `False` 时) 如果 `is_locked` 为 `None`,且没有其他状态属性为真值,则状态为 `unknown`。 ## 支持的功能 支持的功能通过使用 `LockEntityFeature` 枚举中的值来定义,并使用按位或(`|`)运算符进行组合。 | 值 | 描述 | | ------ | ------------------------------------------ | | `OPEN` | 此锁支持打开门 latch。 | ## 方法 ### 锁定 ```python class MyLock(LockEntity): def lock(self, **kwargs: Any) -> None: """Lock all or specified locks. A code to lock the lock with may optionally be specified.""" async def async_lock(self, **kwargs: Any) -> None: """Lock all or specified locks. A code to lock the lock with may optionally be specified.""" ``` ### 解锁 ```python class MyLock(LockEntity): def unlock(self, **kwargs: Any) -> None: """Unlock all or specified locks. A code to unlock the lock with may optionally be specified.""" async def async_unlock(self, **kwargs: Any) -> None: """Unlock all or specified locks. A code to unlock the lock with may optionally be specified.""" ``` ### 打开 仅当设置了 `LockEntityFeature.OPEN` 标志时实现此方法。 ```python class MyLock(LockEntity): def open(self, **kwargs: Any) -> None: """Open (unlatch) all or specified locks. A code to open the lock with may optionally be specified.""" async def async_open(self, **kwargs: Any) -> None: """Open (unlatch) all or specified locks. A code to open the lock with may optionally be specified.""" ``` --- url: /developers/core/entity/media-player.md --- :::info 未完成 此条目尚不完整。欢迎贡献。 ::: Media player entity 控制 media player。从 [`homeassistant.components.media_player.MediaPlayerEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/media_player/__init__.py) 派生 platform entity。 ## 属性 :::tip Properties 应该只从内存返回信息,而不要执行 I/O(如网络请求)。请实现 `update()` 或 `async_update()` 来获取数据。 ::: | Name | Type | Default | Description | ------------------------------- | ----------------------------------------------- | ------- | ----------- | app\_id | `str \| None` | `None` | 当前运行的 app 的 ID。 | app\_name | `str \| None` | `None` | 当前运行的 app 的名称。 | device\_class | `MediaPlayerDeviceClass \| None` | `None` | Media player 的类型。 | group\_members | `list[str] \| None` | `None` | 当前分组进行同步播放的 player entities 动态列表。如果 platform 有定义 group leader 的概念,leader 应是该列表的第一个元素。 | is\_volume\_muted | `bool \| None` | `None` | 如果 volume 当前已 muted,则为 `True`。 | media\_album\_artist | `str \| None` | `None` | 当前播放 media 的 album artist,仅限 music track。 | media\_album\_name | `str \| None` | `None` | 当前播放 media 的 album name,仅限 music track。 | media\_artist | `str \| None` | `None` | 当前播放 media 的 artist,仅限 music track。 | media\_channel | `str \| None` | `None` | 当前播放的 channel。 | media\_content\_id | `str \| None` | `None` | 当前播放 media 的 content ID。 | media\_content\_type | `MediaType \| str \| None` | `None` | 当前播放 media 的 content type。 | media\_duration | `int \| None` | `None` | 当前播放 media 的 duration(秒)。 | media\_episode | `str \| None` | `None` | 当前播放 media 的 episode,仅限 TV show。 | media\_image\_hash | `str \| None` | `None` | Media image 的 hash,如果 `media_image_url` 不为 `None`,默认为 `media_image_url` 的 SHA256。 | media\_image\_remotely\_accessible | `bool \| None` | `False` | 如果 property `media_image_url` 可以在 home network 外部访问,则为 `True`。 | media\_image\_url | `str \| None` | `None` | 当前播放 media 的 image URL。 | media\_playlist | `str \| None` | `None` | 当前播放的 Playlist 的 title。 | media\_position | `int \| None` | `None` | 当前播放 media 的 position(秒)。 | media\_position\_updated\_at | `datetime \| None` | `None` | `_attr_media_position` 上次更新的时间戳。时间戳应通过调用 `homeassistant.util.dt.utcnow()` 设置。 | media\_season | `str \| None` | `None` | 当前播放 media 的 season,仅限 TV show。 | media\_series\_title | `str \| None` | `None` | 当前播放 media 的 series title,仅限 TV show。 | media\_title | `str \| None` | `None` | 当前播放 media 的 title。 | media\_track | `int \| None` | `None` | 当前播放 media 的 track number,仅限 music track。 | repeat | `RepeatMode \| str \| None` | `None` | 当前的 repeat mode。 | shuffle | `bool \| None` | `None` | 如果 shuffle 已启用,则为 `True`。 | sound\_mode | `str \| None` | `None` | Media player 当前的 sound mode。 | sound\_mode\_list | `list[str] \| None` | `None` | 可用 sound modes 的动态列表。 | source | `str \| None` | `None` | Media player 当前选择的 input source。 | source\_list | `list[str] \| None` | `None` | Media player 可能的 input sources 列表。(该列表应包含适合 frontend 显示的 human readable names)。 | state | `MediaPlayerState \| None` | `None` | Media player 的 state。 | volume\_level | `float \| None` | `None` | Media player 的 volume level,范围(0..1)。 | volume\_step | `float \| None` | 0.1 | 用于 `volume_up` 和 `volume_down` service actions 的 volume step。 ## 支持的功能 Supported features 通过使用 `MediaPlayerEntityFeature` enum 中的值来定义, 并使用按位或(`|`)运算符组合。 | Value | Description | | ------------------- | ------------------------------------------------------------------ | | `BROWSE_MEDIA` | Entity 允许浏览 media。 | | `CLEAR_PLAYLIST` | Entity 允许清除 active playlist。 | | `GROUPING` | Entity 可以与其他 players 分组进行同步播放。 | | `MEDIA_ANNOUNCE` | Entity 支持 `play_media` action 的 announce 参数。 | | `MEDIA_ENQUEUE` | Entity 支持 `play_media` action 的 enqueue 参数。 | | `NEXT_TRACK` | Entity 允许跳过到下一个 media track。 | | `PAUSE` | Entity 允许暂停 media 的播放。 | | `PLAY` | Entity 允许播放/恢复 media 的播放。 | | `PLAY_MEDIA` | Entity 允许播放 media sources。 | | `PREVIOUS_TRACK` | Entity 允许返回到上一个 media track。 | | `REPEAT_SET` | Entity 允许设置 repeat。 | | `SEARCH_MEDIA` | Entity 允许搜索 media。 | | `SEEK` | Entity 允许在 media 播放期间 seek position。 | | `SELECT_SOUND_MODE` | Entity 允许选择 sound mode。 | | `SELECT_SOURCE` | Entity 允许选择 source/input。 | | `SHUFFLE_SET` | Entity 允许 shuffle active playlist。 | | `STOP` | Entity 允许停止 media 的播放。 | | `TURN_OFF` | Entity 可以关闭。 | | `TURN_ON` | Entity 可以开启。 | | `VOLUME_MUTE` | Entity 的 volume 可以 muted。 | | `VOLUME_SET` | Entity 的 volume 可以设为特定 levels。 | | `VOLUME_STEP` | Entity 的 volume 可以上下调整。 | ## 状态 设置 state 应在 `state` property 中返回一个 `MediaPlayerState` 枚举值。Resulting state 值是 enum 成员名称的小写版本(例如,`MediaPlayerState.PLAYING` 结果为 state `playing`)。 | Value | Description | |-------------|---------------------------------------------------------------------------------------------------------------------| | `OFF` | Entity 已关闭,在开启之前不接受 commands。 | | `ON` | Entity 已开启,但当前未知其 state 的详细信息。 | | `IDLE` | Entity 已开启并接收 commands,但当前未播放任何 media。可能处于某个 idle home screen。 | | `PLAYING` | Entity 当前正在播放 media。 | | `PAUSED` | Entity 有 active media,且当前已 paused | | `BUFFERING` | Entity 正在准备开始播放某些 media | :::note Media players 在 standby state 时通常无法控制。如果 Home Assistant 可以使用其他 protocol 或 method 开启 device,即使用于控制 device 的主要 channel 当前不可用,也应显示为 `off`。如果 Home Assistant 没有方法开启 device,应显示为 `unavailable`。更多详情请见 [entity-unavailable Exceptions](/developers/core/integration-quality-scale/rules/entity-unavailable.md#exceptions)。 ::: ## 方法 ### 播放媒体 通知 media player 播放 media。使用以下方法实现: ```python class MyMediaPlayer(MediaPlayerEntity): def play_media( self, media_type: str, media_id: str, enqueue: MediaPlayerEnqueue | None = None, announce: bool | None = None, **kwargs: Any ) -> None: """Play a piece of media.""" async def async_play_media( self, media_type: str, media_id: str, enqueue: MediaPlayerEnqueue | None = None, announce: bool | None = None, **kwargs: Any ) -> None: """Play a piece of media.""" ``` `enqueue` attribute 是字符串 enum `MediaPlayerEnqueue`: * `add`:将给定 media item 添加到队列末尾 * `next`:接下来播放给定的 media item,保留队列 * `play`:立即播放给定的 media item,保留队列 * `replace`:立即播放给定的 media item,清除队列 当 `announce` 布尔 attribute 设为 `true` 时,media player 应尝试暂停当前 music,向用户 announce media,然后恢复 music。 ### 浏览媒体 如果 media player 支持浏览 media,应实现以下 method: ```python class MyMediaPlayer(MediaPlayerEntity): async def async_browse_media( self, media_content_type: str | None = None, media_content_id: str | None = None ) -> BrowseMedia: """Implement the websocket media browsing helper.""" return await media_source.async_browse_media( self.hass, media_content_id, content_filter=lambda item: item.media_content_type.startswith("audio/"), ) ``` 如果 media player 也允许从 URL 播放 media,还可以添加对浏览 Home Assistant media sources 的支持。这些 sources 可以由任何集成提供。示例包括 text-to-speech 和 local media。 ```python from homeassistant.components import media_source from homeassistant.components.media_player.browse_media import ( async_process_play_media_url, ) class MyMediaPlayer(MediaPlayerEntity): async def async_browse_media( self, media_content_type: str | None = None, media_content_id: str | None = None ) -> BrowseMedia: """Implement the websocket media browsing helper.""" # 如果 media player 没有自己的 media sources 可供浏览,将所有 browse commands # 路由到 media source 集成。 return await media_source.async_browse_media( self.hass, media_content_id, # 这允许过滤 content。在本例中,它只显示 audio sources。 content_filter=lambda item: item.media_content_type.startswith("audio/"), ) async def async_play_media( self, media_type: str, media_id: str, enqueue: MediaPlayerEnqueue | None = None, announce: bool | None = None, **kwargs: Any ) -> None: """Play a piece of media.""" if media_source.is_media_source_id(media_id): media_type = MediaType.MUSIC play_item = await media_source.async_resolve_media(self.hass, media_id, self.entity_id) # play_item 在需要在 Home Assistant host 上解析时返回 relative URL # 此调用会将其转换为完整 URL media_id = async_process_play_media_url(self.hass, play_item.url) # 用调用 media player 播放 media 函数替换此处。 await self._media_player.play_url(media_id) ``` ### 搜索媒体 如果 media player 支持搜索 media,应实现以下 method: ```python class MyMediaPlayer(MediaPlayerEntity): async def async_search_media( self, query: SearchMediaQuery, ) -> SearchMedia: """Search the media player.""" # 在 library client 上搜索请求的 media。 result = await my_client.search(query=query.search_query) return SearchMedia(result=result) ``` SearchMediaQuery 是一个具有以下 properties 的 dataclass: | Attribute | Type | Default | Description | |-----------------------|---------------------------------------|-------------|------------------------------------| | `search_query` | `str` | *必需* | 搜索字符串或 query。 | | `media_content_type` | `MediaType \| str \| None` | `None` | 要搜索的 content type。 | | `media_content_id` | `str \| None` | `None` | 要搜索的 content ID。 | | `media_filter_classes`| `list[MediaClass] \| None` | `None` | 要过滤的 media classes 列表。 | ### 选择 sound mode 可选。切换 media player 的 sound mode。 ```python class MyMediaPlayer(MediaPlayerEntity): # 实现以下方法之一。 def select_sound_mode(self, sound_mode: str) -> None: """Switch the sound mode of the entity.""" async def async_select_sound_mode(self, sound_mode: str) -> None: """Switch the sound mode of the entity.""" ``` ### 选择来源 可选。切换 media player 选择的 input source。 ```python class MyMediaPlayer(MediaPlayerEntity): # 实现以下方法之一。 def select_source(self, source: str) -> None: """Select input source.""" async def async_select_source(self, source: str) -> None: """Select input source.""" ``` ### 媒体类型 必需。返回与 mediatype 匹配的 MediaType enum 值之一。 | CONST | |-------| |MediaType.MUSIC| |MediaType.TVSHOW| |MediaType.MOVIE| |MediaType.VIDEO| |MediaType.EPISODE| |MediaType.CHANNEL| |MediaType.PLAYLIST| |MediaType.IMAGE| |MediaType.URL| |MediaType.GAME| |MediaType.APP| ```python class MyMediaPlayer(MediaPlayerEntity): # 实现以下方法。 @property def media_content_type(self) -> MediaType | str | None: """Content type of current playing media.""" ``` :::info 在 `play_media` service action 中,使用集成名称作为 `media_content_type` 也是可接受的,前提是集成提供了不映射到已定义常量的处理。 ::: ### 可用的设备类型 可选。这是什么类型的 media device。它可能会映射到 Google device types。 | Value | Description | ----- | ----------- | projector | Device 是 projector 类型的 device。 | receiver | Device 是 audio video receiver 类型的 device,接收 audio 并输出到 speakers,video 输出到某个 display。 | speaker | Device 是 speakers 或 stereo 类型的 device。 | tv | Device 是 television 类型的 device。 ### 为 media browser 代理 album art 可选。如果 media player 只能从 internal network 访问,则需要通过 Home Assistant 代理 album art,以便在离开 home 或通过 mobile app 时能够正常工作。 要通过 Home Assistant 代理 image,请将 `BrowseMedia` item 的 `thumbnail` property 设为由 `self.get_browse_image_url(media_content_type, media_content_id, media_image_id=None)` method 生成的 URL。然后浏览器将获取此 URL,从而导致调用 `async_get_browse_image(media_content_type, media_content_id, media_image_id=None)`。 :::info 仅当 web request 源自网络外部时才使用代理 thumbnail。可以使用从 `homeassistant.helpers.network` 导入的 `is_local_request(hass)` 进行测试。 ::: 在 `async_get_browse_image` 中,使用 `self._async_fetch_image(url)` 从 local network 获取 image。不要使用 `self._async_fetch_image_from_cache(url)`,它只应用于当前播放的 artwork。 :::info 不要将 URL 作为 `media_image_id` 传入。这可能允许攻击者从 local network 获取任何数据。 ::: ```python class MyMediaPlayer(MediaPlayerEntity): # 实现以下方法。 async def async_get_browse_image( self, media_content_type: str, media_content_id: str, media_image_id: str | None = None, ) -> tuple[bytes | None, str | None]: """Serve album art. Returns (content, content_type).""" image_url = ... return await self._async_fetch_image(image_url) ``` ### 将 player entities 分组在一起 可选。如果 player 支持将 player entities 分组进行同步播放(由 `MediaPlayerEntityFeature.GROUPING` 指示),则需要定义一个 join method 和一个 unjoin method。 ```python class MyMediaPlayer(MediaPlayerEntity): # 实现以下 join methods 之一: def join_players(self, group_members: list[str]) -> None: """Join `group_members` as a player group with the current player.""" async def async_join_players(self, group_members: list[str]) -> None: """Join `group_members` as a player group with the current player.""" # 实现以下 unjoin methods 之一: def unjoin_player(self) -> None: """Remove this player from any group.""" async def async_unjoin_player(self) -> None: """Remove this player from any group.""" ``` --- url: /developers/core/entity/notify.md --- Notify 实体是一种可以向设备或服务发送消息的实体,但从 Home Assistant 的角度来看是无状态的。 Notify 实体派生自 [`homeassistant.components.notify.NotifyEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/notify/__init__.py), 在发送通知消息方面可能有所帮助(但不限于): * 短信 (SMS) * 电子邮件 * 直接消息或聊天 * 设备 LCD 显示屏上的屏幕消息 ## 状态 Notify 实体的状态是一个时间戳,代表最后发送消息的日期和时间。 与 `text` 实体不同,`notify` 实体没有可以设置的状态。 如果你想表示一个可以更改的文本值(从而有实际状态),应使用 `text` 实体。 ## 属性 由于此集成是无状态的,它不为其自身提供任何特定属性。 所有实体共有的其他属性(如 `icon`、`name` 等)仍然适用。 ## 方法 ### 发送消息 发送消息方法用于向设备或服务发送消息。 ```python class MyNotifier(NotifyEntity): # 实现以下方法之一。 def send_message(self, message: str, title: str | None = None) -> None: """Send a message.""" async def async_send_message(self, message: str, title: str | None = None) -> None: """Send a message.""" ``` ### 记录通知 一些集成为发送通知提供带有扩展的、集成特定功能的自定义操作,或以其他方式在 Home Assistant 内部触发通知。为了跟踪通知发送的时间,集成可以调用 `_async_record_notification` 或 `_record_notification`。 :::important 仅应记录源自 Home Assistant 内部的通知。外部生成的通知不得记录。对此应改用 event 实体。 ::: ```python class MyNotifier(NotifyEntity): # 默认通过 notify.send_message 操作发送通知的方法 async def async_send_message(self, message: str, title: str | None = None) -> None: """Send a message.""" await self._publish(message=message, title=title) # 集成为发送通知实现了自定义实体操作 async def publish(self, message: str, title: str | None = None, priority: int | None = None) -> None: """Send a message with priority.""" await self._publish(message=message, title=title, priority=priority) # 记录已发送通知 self._async_record_notification() ``` --- url: /developers/core/entity/number.md --- `number` 是一种允许用户向集成输入任意值的 entity。从 [`homeassistant.components.number.NumberEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/number/__init__.py) 派生 entity platforms。 ## 属性 :::tip Properties 应该只从内存返回信息,而不要执行 I/O(如网络请求)。请实现 `update()` 或 `async_update()` 来获取数据。 ::: | Name | Type | Default | Description | ---- | ---- | ------- | ----------- | device\_class | string | `None` | Number 的类型。 | mode | string | `auto` | 定义 number 在 UI 中的显示方式。建议使用默认值 `auto`。可以是 `box` 或 `slider` 以强制显示模式。 | native\_max\_value | float | 100 | Number 的 `native_unit_of_measurement` 中接受的最大值(inclusive) | native\_min\_value | float | 0 | Number 的 `native_unit_of_measurement` 中接受的最小值(inclusive) | native\_step | float | **见下文** | 定义 values 的 resolution,即 number 的 `native_unit_of_measurement` 中最小的增量或减量。 | native\_value | float | **必需** | Number 的 `native_unit_of_measurement` 中的 value。 | native\_unit\_of\_measurement | string | `None` | Number 的 value 所表示的计量单位。如果 `native_unit_of_measurement` 是 °C 或 °F,且其 `device_class` 是 temperature,则 number 的 `unit_of_measurement` 将为用户配置的 preferred temperature unit,number 的 `state` 将是可选单位转换后的 `native_value`。如果提供了 [unit translation](/developers/internationalization/core.md#unit-of-measurement-of-entities),则不应定义 `native_unit_of_measurement`。 其他在所有 entity 中通用的 properties(如 `icon`、`name` 等)也适用。 默认 step 值根据 range(max - min)值动态选择。如果 max\_value 和 min\_value 之间的差值大于 1.0,则默认 step 为 1.0。如果 range 较小,则 step 会迭代除以 10,直到小于 range。 ### 可用的设备类型 如果指定 device class,你的 number entity 还需要返回正确的计量单位。 | Constant | Supported units | Description | ---- | ---- | ----------- | `NumberDeviceClass.ABSOLUTE_HUMIDITY` | g/m³, mg/m³ | Absolute humidity | `NumberDeviceClass.APPARENT_POWER` | mVA, VA, kVA | Apparent power | `NumberDeviceClass.AQI` | None | Air Quality Index | `NumberDeviceClass.AREA` | m², cm², km², mm², in², ft², yd², mi², ac, ha | Area | `NumberDeviceClass.ATMOSPHERIC_PRESSURE` | cbar, bar, hPa, mmHG, inHg, inH₂O, kPa, mbar, Pa, psi | Atmospheric pressure | `NumberDeviceClass.BATTERY` | % | 剩余 battery 百分比 | `NumberDeviceClass.BLOOD_GLUCOSE_CONCENTRATION` | mg/dL, mmol/L | Blood glucose concentration\`\`\` | `NumberDeviceClass.CO2` | ppm | 二氧化碳浓度。 | `NumberDeviceClass.CO` | ppb, ppm, µg/m³, mg/m³ | 一氧化碳浓度。 | `NumberDeviceClass.CONDUCTIVITY` | S/cm, mS/cm, µS/cm | Conductivity | `NumberDeviceClass.CURRENT` | A, mA, µA | Current | `NumberDeviceClass.DATA_RATE` | bit/s, kbit/s, Mbit/s, Gbit/s, B/s, kB/s, MB/s, GB/s, KiB/s, MiB/s, GiB/s | Data rate | `NumberDeviceClass.DATA_SIZE` | bit, kbit, Mbit, Gbit, B, kB, MB, GB, TB, PB, EB, ZB, YB, KiB, MiB, GiB, TiB, PiB, EiB, ZiB, YiB | Data size | `NumberDeviceClass.DISTANCE` | km, m, cm, mm, mi, nmi, yd, in | Generic distance | `NumberDeviceClass.DURATION` | d, h, min, s, ms, µs | Time period。不应仅因时间流逝而更新。Device 或 service 需要给出新的数据点才能更新。 | `NumberDeviceClass.ENERGY` | J, kJ, MJ, GJ, mWh, Wh, kWh, MWh, GWh, TWh, cal, kcal, Mcal, Gcal | Energy,此 device class 应用于表示 energy consumption,例如 electricity meter。表示 *power* over *time*。不要与 `power` 混淆。 | `NumberDeviceClass.ENERGY_DISTANCE` | kWh/100km, Wh/km, mi/kWh, km/kWh | Energy per distance,此 device class 应用于表示按距离的 energy consumption,例如 electric car 消耗的 electric energy 量。 | `NumberDeviceClass.ENERGY_STORAGE` | J, kJ, MJ, GJ, mWh, Wh, kWh, MWh, GWh, TWh, cal, kcal, Mcal, Gcal | Stored energy,此 device class 应用于表示 stored energy,例如 battery 中当前存储的 electric energy 量或 battery 的 capacity。表示 *power* over *time*。不要与 `power` 混淆。 | `NumberDeviceClass.FREQUENCY` | mHz, Hz, kHz, MHz, GHz | Frequency | `NumberDeviceClass.GAS` | L, m³, ft³, CCF, MCF | Gas 的体积。以 kWh 的 energy 测量的 gas consumption 而不是体积,应归类为 energy。 | `NumberDeviceClass.HUMIDITY` | % | Relative humidity | `NumberDeviceClass.ILLUMINANCE` | lx | Light level | `NumberDeviceClass.IRRADIANCE` | W/m², BTU/(h⋅ft²) | Irradiance | `NumberDeviceClass.MOISTURE` | % | Moisture | `NumberDeviceClass.MONETARY` | [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217#Active_codes) | 带有 currency 的 Monetary value。 | `NumberDeviceClass.NITROGEN_DIOXIDE` | ppb, ppm, µg/m³ | 二氧化氮浓度 | `NumberDeviceClass.NITROGEN_MONOXIDE` | ppb, µg/m³ | 一氧化氮浓度 | `NumberDeviceClass.NITROUS_OXIDE` | µg/m³ | 一氧化二氮浓度 | `NumberDeviceClass.OZONE` | ppb, ppm, µg/m³ | 臭氧浓度 | `NumberDeviceClass.PH` | None | 水溶液的 Potential hydrogen(pH) | `NumberDeviceClass.PM1` | µg/m³ | 小于 1 微米的 particulate matter 浓度 | `NumberDeviceClass.PM25` | µg/m³ | 小于 2.5 微米的 particulate matter 浓度 | `NumberDeviceClass.PM4` | µg/m³ | 小于 4 微米的 particulate matter 浓度 | `NumberDeviceClass.PM10` | µg/m³ | 小于 10 微米的 particulate matter 浓度 | `NumberDeviceClass.POWER` | mW, W, kW, MW, GW, TW | Power。 | `NumberDeviceClass.POWER_FACTOR` | %, None | Power Factor | `NumberDeviceClass.PRECIPITATION` | cm, in, mm | Accumulated precipitation | `NumberDeviceClass.PRECIPITATION_INTENSITY` | in/d, in/h, mm/d, mm/h | Precipitation intensity | `NumberDeviceClass.PRESSURE` | cbar, bar, hPa, mmHg, inHg, kPa, mbar, Pa, psi, mPa | Pressure。 | `NumberDeviceClass.RADON` | Bq/m³, pCi/L | Radon 浓度 | `NumberDeviceClass.REACTIVE_ENERGY` | varh, kvarh | Reactive energy | `NumberDeviceClass.REACTIVE_POWER` | mvar, var, kvar | Reactive power | `NumberDeviceClass.SIGNAL_STRENGTH` | dB, dBm | Signal strength | `NumberDeviceClass.SOUND_PRESSURE` | dB, dBA | Sound pressure | `NumberDeviceClass.SPEED` | ft/s, in/d, in/h, in/s, km/h, kn, m/s, mph, mm/d, mm/s | Generic speed | `NumberDeviceClass.SULPHUR_DIOXIDE` | ppb, µg/m³ | 二氧化硫浓度 | `NumberDeviceClass.TEMPERATURE` | °C, °F, K | Temperature。 | `NumberDeviceClass.TEMPERATURE_DELTA` | °C, °F, K | 此 device class 表示 temperature interval(delta),即两个 temperature values 之间的差。 | `NumberDeviceClass.VOLATILE_ORGANIC_COMPOUNDS` | µg/m³, mg/m³ | Volatile organic compounds 浓度 | `NumberDeviceClass.VOLATILE_ORGANIC_COMPOUNDS_PARTS` | ppm, ppb | Volatile organic compounds 比率 | `NumberDeviceClass.VOLTAGE` | V, mV, µV, kV, MV | Voltage | `NumberDeviceClass.VOLUME` | L, mL, gal, fl. oz., m³, ft³, CCF, MCF | Generic volume,此 device class 应用于表示 consumption,例如 vehicle 消耗的 fuel 量。 | `NumberDeviceClass.VOLUME_FLOW_RATE` | m³/h, m³/min, m³/s, ft³/min, L/h, L/min, L/s, gal/d, gal/h, gal/min, mL/s | Volume flow rate,此 device class 应用于表示某些 volume 的 flow,例如瞬间消耗的水量。 | `NumberDeviceClass.VOLUME_STORAGE` | L, mL, gal, fl. oz., m³, ft³, CCF, MCF | Generic stored volume,此 device class 应用于表示 stored volume,例如 fuel tank 中的 fuel 量。 | `NumberDeviceClass.WATER` | L, gal, m³, ft³, CCF, MCF | Water consumption | `NumberDeviceClass.WEIGHT` | kg, g, mg, µg, oz, lb, st | Generic mass;`weight` 用于代替 `mass` 以符合日常语言。 | `NumberDeviceClass.WIND_DIRECTION` | ° | Wind direction | `NumberDeviceClass.WIND_SPEED` | ft/s, km/h, kn, m/s, mph | Wind speed ## 恢复 number 状态 在 restart 或 reload 后恢复 state 的 numbers 不应扩展 `RestoreEntity`,因为它不存储 `native_value`,而是存储可能被 number base entity 修改的 `state`。恢复 state 的 numbers 应扩展 `RestoreNumber`,并从 `async_added_to_hass` 调用 `await self.async_get_last_number_data`,以访问存储的 `native_min_value`、`native_max_value`、`native_step`、`native_unit_of_measurement` 和 `native_value`。 ## 方法 ### 设置值 当用户或 automation 想要更新 value 时调用。 ```python class MyNumber(NumberEntity): # 实现以下方法之一。 def set_native_value(self, value: float) -> None: """Update the current value.""" async def async_set_native_value(self, value: float) -> None: """Update the current value.""" ``` --- url: /developers/core/entity/radio-frequency.md --- Radio frequency 实体在 RF 收发器硬件(如 ESPHome、Broadlink 或基于 SDR 的设备)与需要发送 RF 命令的设备特定集成(如车库门开启器、RF 遥控器或无线开关)之间提供了一个抽象层。它充当一个虚拟 RF 发射器,可被其他集成用于控制 RF 设备。 Radio frequency 发射器实体派生自 [`homeassistant.components.radio_frequency.RadioFrequencyTransmitterEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/radio_frequency/__init__.py)。 ## 架构概览 Radio frequency 实体集成在以下方面创建分离: 1. **Transmitter 集成**(如 ESPHome、Broadlink):这些实现 `RadioFrequencyTransmitterEntity`,以提供硬件特定的 RF 传输能力。 2. **Consumer 集成**(如车库门或 RF 遥控器集成):这些使用 `radio_frequency` 辅助函数,通过可用的 transmitter 发送设备特定的 RF 命令。 ```mermaid flowchart TD subgraph consumers["Consumer integrations"] direction LR Garage["Garage door"] ~~~ Remote["RF remote"] ~~~ Switch["RF switch"] ~~~ more1["..."] end subgraph rf["radio_frequency domain"] direction LR base["RadioFrequencyTransmitterEntity base class"] subgraph helpers["Helper functions"] direction TB async_get_transmitters ~~~ async_send_command end end subgraph transmitters["Transmitter integrations"] direction LR ESPHome["ESPHome"] ~~~ Broadlink["Broadlink"] ~~~ SDR["SDR"] ~~~ more2["..."] end consumers -->|"Use helper functions"| helpers base -->|"Implemented by"| transmitters ``` ## RadioFrequencyTransmitterEntity 类 ### 状态 Radio frequency 实体状态表示最后发送 RF 命令的时间戳。这在基类 `RadioFrequencyTransmitterEntity` 中实现,集成不应更改。 ### 支持的频率范围 Transmitter 集成必须通过实现 `supported_frequency_ranges` 属性来声明其硬件可以在哪些频率范围内传输。每个范围是一个 `(min_hz, max_hz)` 元组。Consumer 集成使用这些范围来选择兼容的 transmitter。 ```python class MyRadioFrequencyTransmitterEntity(RadioFrequencyTransmitterEntity): """My RF transmitter entity.""" @property def supported_frequency_ranges(self) -> list[tuple[int, int]]: """Return list of (min_hz, max_hz) tuples.""" return [(300_000_000, 348_000_000), (433_050_000, 434_790_000)] ``` ### 发送命令方法 `RadioFrequencyTransmitterEntity.async_send_command` 方法必须由 transmitter 集成实现,以处理实际的 RF 传输。 ```python from rf_protocols import RadioFrequencyCommand class MyRadioFrequencyTransmitterEntity(RadioFrequencyTransmitterEntity): """My RF transmitter entity.""" async def async_send_command(self, command: RadioFrequencyCommand) -> None: """Send an RF command. Args: command: The RF command to send. Raises: HomeAssistantError: If transmission fails. """ ``` :::important 不要从 consumer 集成中直接调用 `RadioFrequencyTransmitterEntity.async_send_command`。请使用 [`radio_frequency.async_send_command`](#send-command),它会自动处理状态更新和 context 管理。 ::: ## 辅助函数 `radio_frequency` 域为 consumer 集成提供了发现 transmitter 和发送 RF 命令的辅助函数。 ### 获取 transmitters 返回所有支持给定频率和调制方式的 RF transmitter 的实体 IDs。 ```python from rf_protocols import ModulationType from homeassistant.components import radio_frequency transmitters = radio_frequency.async_get_transmitters( hass, frequency=433_920_000, # 433.92 MHz modulation=ModulationType.OOK, ) ``` 空列表表示没有可用的兼容 transmitter。 :::note 目前仅支持 `ModulationType.OOK`(开关键控,on-off keying)。未来版本可以添加其他调制类型。 ::: ### 发送命令 向特定的 radio frequency 实体发送 RF 命令。可以通过实体的 entity ID 或 entity registry UUID 来引用该实体。 ```python from rf_protocols.codes.garage import make_garage_command from homeassistant.components import radio_frequency command = make_garage_command(...) await radio_frequency.async_send_command( hass, rf_entity_id, command, context=context, # 用于 logbook 跟踪的可选 context ) ``` ## RF 命令 [rf-protocols 库](https://github.com/home-assistant-libs/rf-protocols) 提供了 RF 命令的基类,将协议特定的数据转换为原始 timings 和载波配置。 所有 RF 命令必须继承自 `rf_protocols.RadioFrequencyCommand`。 --- url: /developers/core/entity/remote.md --- Remote 实体可以表示两种不同类型的设备: 1. 发送命令的物理设备。 2. Home Assistant 中的虚拟设备,向另一个物理设备(如电视)发送命令。 从 [`homeassistant.components.remote.RemoteEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/remote/__init__.py) 派生实体平台。 ## 属性 :::tip 属性应始终仅返回内存中的信息,而不是执行 I/O(如网络请求)。实现 `update()` 或 `async_update()` 来获取数据。 ::: | 名称 | 类型 | 默认值 | 描述 | | ---- | ---- | ------- | ----------- | | is\_on | boolean | `None` | 设备当前是开启还是关闭。 | | current\_activity | str | `None` | 返回当前活动的 activity。 | | activity\_list | list | `None` | 返回可用的 activity 列表。 | ### 活动 Activity 是一个预定义的 activity 或宏,将 remote 置于特定状态。例如,"Watch TV" activity 可能会打开多个设备并将频道更改为特定频道。 ## 支持的功能 支持的功能通过使用 `RemoteEntityFeature` 枚举中的值来定义,并使用按位或(`|`)运算符进行组合。 | 值 | 描述 | | ---------------- | --------------------------------------------- | | `LEARN_COMMAND` | 实体允许从设备学习命令。 | | `DELETE_COMMAND` | 实体允许从设备删除命令。 | | `ACTIVITY` | 实体支持 activity。 | ## 方法 ### 开启命令 ```python class MyRemote(RemoteEntity): def turn_on(self, activity: str | None = None, **kwargs: Any) -> None: """Send the power on command.""" async def async_turn_on(self, activity: str | None = None, **kwargs: Any) -> None: """Send the power on command.""" ``` ### 关闭命令 ```python class MyRemote(RemoteEntity): def turn_off(self, activity: str | None = None, **kwargs: Any) -> None: """Send the power off command.""" async def async_turn_off(self, activity: str | None = None, **kwargs: Any) -> None: """Send the power off command.""" ``` ### 切换命令 ```python class MyRemote(RemoteEntity): def toggle(self, activity: str | None = None, **kwargs: Any) -> None: """Toggle a device.""" async def async_toggle(self, activity: str | None = None, **kwargs: Any) -> None: """Toggle a device.""" ``` ### 发送命令 ```python class MyRemote(RemoteEntity): def send_command(self, command: Iterable[str], **kwargs: Any) -> None: """Send commands to a device.""" async def async_send_command(self, command: Iterable[str], **kwargs: Any) -> None: """Send commands to a device.""" ``` ### 学习命令 仅当设置了 `RemoteEntityFeature.LEARN_COMMAND` 标志时实现此方法。 ```python class MyRemote(RemoteEntity): def learn_command(self, **kwargs: Any) -> None: """Learn a command from a device.""" async def async_learn_command(self, **kwargs: Any) -> None: """Learn a command from a device.""" ``` ### 删除命令 仅当设置了 `RemoteEntityFeature.DELETE_COMMAND` 标志时实现此方法。 ```python class MyRemote(RemoteEntity): def delete_command(self, **kwargs: Any) -> None: """Delete a command from a device.""" async def async_delete_command(self, **kwargs: Any) -> None: """Delete a command from a device.""" ``` --- url: /developers/core/entity/scene.md --- Scene 实体是一种 [可以为一组实体重现所需状态](/developers/core/platform/reproduce_state.md) 的实体。Scene 实体可以向一组设备激活 scene,但从 Home Assistant 的角度来看是无状态的。 Scene 实体派生自 [`homeassistant.components.scene.Scene`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/scene/__init__.py)。 如果你想表示一个可以开启和关闭的东西(从而有实际状态),应使用 `switch` 实体。 Scene 实体也可以 [通过 Scene 编辑器或 YAML 由用户创建](https://www.home-assistant.io/integrations/scene)。 ## 属性 由于此集成是无状态的,它不为其自身提供任何特定属性。 所有实体共有的其他属性(如 `icon`、`name` 等)仍然适用。 ## 方法 ### 激活 激活 scene。 ```python class MyScene(Scene): # 实现以下方法之一。 def activate(self, **kwargs: Any) -> None: """Activate scene. Try to get entities into requested state.""" async def async_activate(self, **kwargs: Any) -> None: """Activate scene. Try to get entities into requested state.""" ``` Activate 方法可用于向设备或服务激活 scene。 当用户按下 scene 的 `activate` 按钮或调用 `scene.turn_on` 操作来激活 scene 时,Home Assistant 会调用此方法。 一些集成可以接收外部事件,在 Home Assistant 外部激活 scene。这些激活不源自 Home Assistant UI 或服务调用,而是来自物理按钮等外部来源。 为了支持此场景,集成应从 `BaseScene` 而不是 `Scene` 派生,覆盖 `_async_activate()` 以处理来自 Home Assistant 侧的 scene 激活,并在发生外部 scene 激活时调用 `_async_record_activation()`。 此外,由于这些 scene 在 Home Assistant 外部激活,集成可能希望延迟更新 scene 状态时间戳,直到外部 scene 报告为活动状态,即使在 Home Assistant UI 中激活也是如此。 ```python # 继承自 BaseScene class MyScene(BaseScene): # 注意前面的下划线 async def _async_activate(self, **kwargs: Any) -> None: """Activate scene.""" # 调用服务以激活 scene await mqtt.async_publish(self.hass, self._topic, self._payload) # 在服务回调中记录激活 async def _state_received(self, msg: ReceiveMessage) -> None: self._async_record_activation() self.async_write_ha_state() ``` ### 可用的 device class 没有特定的 device class。`device_class` 属性未在 scene 实体上设置。 --- url: /developers/core/entity/select.md --- `select` 是一种允许用户从集成提供的有限 options 列表中选择 option 的 entity。从 [`homeassistant.components.select.SelectEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/select/__init__.py) 派生 entity platforms。 此 entity 应仅在没有更适合的 option 可用的情况下使用。 例如,bulb 可以有用户可选择的 light effects。虽然这可以使用此 `select` entity 实现,但它应该真正成为 `light` entity 的一部分,后者已经支持 light effects。 ## 属性 :::tip Properties 应该只从内存返回信息,而不要执行 I/O(如网络请求)。请实现 `update()` 或 `async_update()` 来获取数据。 ::: | Name | Type | Default | Description | ---- | ---- | ------- | ----------- | current\_option | str | None | 当前的 select option | options | list | **必需** | 可用 options 的列表(字符串形式) 其他在所有 entity 中通用的 properties(如 `icon`、`unit_of_measurement`、`name` 等)也适用。 ## 方法 ### 选择选项 当用户或 automation 想要更改当前选择的 option 时调用。 ```python class MySelect(SelectEntity): # 实现以下方法之一。 def select_option(self, option: str) -> None: """Change the selected option.""" async def async_select_option(self, option: str) -> None: """Change the selected option.""" ``` --- url: /developers/core/entity/sensor.md --- Sensor 是一种提供某些信息的 read-only entity。信息具有一个 value,以及选项性的计量单位。从 [`homeassistant.components.sensor.SensorEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/sensor/__init__.py) 派生 entity platforms。 ## 属性 :::tip Properties 应该只从内存返回信息,而不要执行 I/O(如网络请求)。请实现 `update()` 或 `async_update()` 来获取数据。 ::: | Name | Type | Default | Description | ---- | ---- | ------- | ----------- | device\_class | `SensorDeviceClass \| None` | `None` | Sensor 的类型。 | last\_reset | `datetime.datetime \| None` | `None` | 累积型 sensor(如 electricity usage meter、gas meter、water meter 等)被初始化的时间。如果初始化时间未知,设为 `None`。注意,`last_reset` property 返回的 `datetime.datetime` 在更新 entity 的 state attributes 时将被转换为 ISO 8601 格式字符串。更改 `last_reset` 时,`state` 必须是有效的 number。 | native\_unit\_of\_measurement | `str \| None` | `None` | Sensor 的 value 所表示的计量单位。如果 `native_unit_of_measurement` 是 °C 或 °F,且其 `device_class` 是 temperature,则 sensor 的 `unit_of_measurement` 将为用户配置的 preferred temperature unit,sensor 的 `state` 将是可选单位转换后的 `native_value`。如果提供了 [unit translation](/developers/internationalization/core.md#unit-of-measurement-of-entities),则不应定义 `native_unit_of_measurement`。 | native\_value | `str \| int \| float \| date \| datetime \| Decimal \| None` | **必需** | Sensor 的 `native_unit_of_measurement` 中的 value。使用 `device_class` 可能限制此 property 可返回的 types。 | options | `list[str] \| None` | `None` | 如果此 sensor 提供 text state,此 property 可用于提供可能的 states 列表。要求设置 `enum` device class。不能与 `state_class` 或 `native_unit_of_measurement` 组合使用。 | state\_class | `SensorStateClass \| str \| None` | `None` | State 的类型。如果非 `None`,则假设 sensor 为数值型,前端将显示为 line-chart 而不是离散 values。 | suggested\_display\_precision | `int \| None` | `None` | 显示 sensor 的 state 时应使用的小数位数。 | suggested\_unit\_of\_measurement | `str \| None` | `None` | 用于 sensor state 的计量单位。对于具有 `unique_id` 的 sensors,这将用作初始计量单位,用户随后可以覆盖。对于没有 `unique_id` 的 sensors,这将是 sensor state 的计量单位。此 property 旨在供集成覆盖自动单位转换规则,例如使 temperature sensor 无论配置的 unit system 首选 `°C` 还是 `°F` 都始终显示为 `°C`,或使 distance sensor 即使配置的 unit system 是 metric 也始终显示为 miles。 :::tip 对于 sensor entity,不要添加 `extra_state_attributes`,而应创建额外的 sensor entity。不改变的 attributes 只保存一次到 database 中。如果 `extra_state_attributes` 和 sensor value 都频繁变化,会迅速增加 database 的大小。 ::: ### 可用的设备类型 如果指定 device class,你的 sensor entity 还需要返回正确的计量单位。 | Constant | Supported units | Description | ---- | ---- | ----------- | `SensorDeviceClass.ABSOLUTE_HUMIDITY` | g/m³, mg/m³ | Absolute humidity | `SensorDeviceClass.APPARENT_POWER` | mVA, VA, kVA | Apparent power | `SensorDeviceClass.AQI` | None | Air Quality Index | `SensorDeviceClass.AREA` | m², cm², km², mm², in², ft², yd², mi², ac, ha | Area | `SensorDeviceClass.ATMOSPHERIC_PRESSURE` | cbar, bar, hPa, mmHG, inHg, inH₂O, kPa, mbar, Pa, psi | Atmospheric pressure | `SensorDeviceClass.BATTERY` | % | 剩余 battery 百分比 | `SensorDeviceClass.BLOOD_GLUCOSE_CONCENTRATION` | mg/dL, mmol/L | Blood glucose concentration | `SensorDeviceClass.CO2` | ppm | 二氧化碳浓度。 | `SensorDeviceClass.CO` | ppb, ppm, µg/m³, mg/m³ | 一氧化碳浓度。 | `SensorDeviceClass.CONDUCTIVITY` | S/cm, mS/cm, µS/cm | Conductivity | `SensorDeviceClass.CURRENT` | A, mA, µA | Current | `SensorDeviceClass.DATA_RATE` | bit/s, kbit/s, Mbit/s, Gbit/s, B/s, kB/s, MB/s, GB/s, KiB/s, MiB/s, GiB/s | Data rate | `SensorDeviceClass.DATA_SIZE` | bit, kbit, Mbit, Gbit, B, kB, MB, GB, TB, PB, EB, ZB, YB, KiB, MiB, GiB, TiB, PiB, EiB, ZiB, YiB | Data size | `SensorDeviceClass.DATE` | | Date。要求 `native_value` 是 Python `datetime.date` 对象,或 `None`。 | `SensorDeviceClass.DISTANCE` | km, m, cm, mm, mi, nmi, yd, in | Generic distance | `SensorDeviceClass.DURATION` | d, h, min, s, ms, µs | Time period。不应仅因时间流逝而更新。Device 或 service 需要给出新的数据点才能更新。 | `SensorDeviceClass.ENERGY` | J, kJ, MJ, GJ, mWh, Wh, kWh, MWh, GWh, TWh, cal, kcal, Mcal, Gcal | Energy,此 device class 应用于表示 energy consumption 的 sensors,例如 electricity meter。表示 *power* over *time*。不要与 `power` 混淆。 | `SensorDeviceClass.ENERGY_DISTANCE` | kWh/100km, Wh/km, mi/kWh, km/kWh | Energy per distance,此 device class 应用于表示按距离的 energy consumption,例如 electric car 消耗的 electric energy 量。 | `SensorDeviceClass.ENERGY_STORAGE` | J, kJ, MJ, GJ, mWh, Wh, kWh, MWh, GWh, TWh, cal, kcal, Mcal, Gcal | Stored energy,此 device class 应用于表示 stored energy 的 sensors,例如 battery 中当前存储的 electric energy 量或 battery 的 capacity。表示 *power* over *time*。不要与 `power` 混淆。 | `SensorDeviceClass.ENUM` | | Sensor 具有有限的(非 numeric)states 集。使用此 device class 时,`options` property 必须设为可能的 states 列表。 | `SensorDeviceClass.FREQUENCY` | mHz, Hz, kHz, MHz, GHz | Frequency | `SensorDeviceClass.GAS` | L, m³, ft³, CCF, MCF | Gas 的体积。以 kWh 的 energy 测量的 gas consumption 而不是体积,应归类为 energy。 | `SensorDeviceClass.HUMIDITY` | % | Relative humidity | `SensorDeviceClass.ILLUMINANCE` | lx | Light level | `SensorDeviceClass.IRRADIANCE` | W/m², BTU/(h⋅ft²) | Irradiance | `SensorDeviceClass.MOISTURE` | % | Moisture | `SensorDeviceClass.MONETARY` | [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217#Active_codes) | 带有 currency 的 Monetary value。 | `SensorDeviceClass.NITROGEN_DIOXIDE` | ppb, ppm, µg/m³ | 二氧化氮浓度 | `SensorDeviceClass.NITROGEN_MONOXIDE` | ppb, µg/m³ | 一氧化氮浓度 | `SensorDeviceClass.NITROUS_OXIDE` | µg/m³ | 一氧化二氮浓度 | `SensorDeviceClass.OZONE` | ppb, ppm, µg/m³ | 臭氧浓度 | `SensorDeviceClass.PH` | None | 水溶液的 Potential hydrogen(pH) | `SensorDeviceClass.PM1` | µg/m³ | 小于 1 微米的 particulate matter 浓度 | `SensorDeviceClass.PM25` | µg/m³ | 小于 2.5 微米的 particulate matter 浓度 | `SensorDeviceClass.PM4` | µg/m³ | 小于 4 微米的 particulate matter 浓度 | `SensorDeviceClass.PM10` | µg/m³ | 小于 10 微米的 particulate matter 浓度 | `SensorDeviceClass.POWER` | mW, W, kW, MW, GW, TW | Power。 | `SensorDeviceClass.POWER_FACTOR` | %, None | Power Factor | `SensorDeviceClass.PRECIPITATION` | cm, in, mm | Accumulated precipitation | `SensorDeviceClass.PRECIPITATION_INTENSITY` | in/d, in/h, mm/d, mm/h | Precipitation intensity | `SensorDeviceClass.PRESSURE` | cbar, bar, hPa, mmHg, inHg, kPa, mbar, Pa, psi, mPa | Pressure。 | `SensorDeviceClass.RADON` | Bq/m³, pCi/L | Radon 浓度 | `SensorDeviceClass.REACTIVE_ENERGY` | varh, kvarh | Reactive energy | `SensorDeviceClass.REACTIVE_POWER` | mvar, var, kvar | Reactive power | `SensorDeviceClass.SIGNAL_STRENGTH` | dB, dBm | Signal strength | `SensorDeviceClass.SOUND_PRESSURE` | dB, dBA | Sound pressure | `SensorDeviceClass.SPEED` | ft/s, in/d, in/h, in/s, km/h, kn, m/s, mph, mm/d, mm/s | Generic speed | `SensorDeviceClass.SULPHUR_DIOXIDE` | ppb, µg/m³ | 二氧化硫浓度 | `SensorDeviceClass.TEMPERATURE` | °C, °F, K | Temperature。 | `SensorDeviceClass.TEMPERATURE_DELTA` | °C, °F, K | 此 device class 表示 temperature interval(delta),即两个 temperature values 之间的差。 | `SensorDeviceClass.TIMESTAMP` | | Timestamp。要求 `native_value` 返回 Python `datetime.datetime` 对象,带 timezone 信息,或 `None`。 | `SensorDeviceClass.UPTIME` | | Timestamp。表示 device 上次 boot 的 datetime。要求 `native_value` 返回 Python `datetime.datetime` 对象,带 timezone 信息,或 `None`。 | `SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS` | µg/m³, mg/m³ | Volatile organic compounds 浓度 | `SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS_PARTS` | ppm, ppb | Volatile organic compounds 比率 | `SensorDeviceClass.VOLTAGE` | V, mV, µV, kV, MV | Voltage | `SensorDeviceClass.VOLUME` | L, mL, gal, fl. oz., m³, ft³, CCF, MCF | Generic volume,此 device class 应用于表示 consumption 的 sensors,例如 vehicle 消耗的 fuel 量。 | `SensorDeviceClass.VOLUME_FLOW_RATE` | m³/h, m³/min, m³/s, ft³/min, L/h, L/min, L/s, gal/d, gal/h, gal/min, mL/s | Volume flow rate,此 device class 应用于表示某些 volume 的 flow 的 sensors,例如瞬间消耗的水量。 | `SensorDeviceClass.VOLUME_STORAGE` | L, mL, gal, fl. oz., m³, ft³, CCF, MCF | Generic stored volume,此 device class 应用于表示 stored volume 的 sensors,例如 fuel tank 中的 fuel 量。 | `SensorDeviceClass.WATER` | L, gal, m³, ft³, CCF, MCF | Water consumption | `SensorDeviceClass.WEIGHT` | kg, g, mg, µg, oz, lb, st | Generic mass;`weight` 用于代替 `mass` 以符合日常语言。 | `SensorDeviceClass.WIND_DIRECTION` | ° | Wind direction,如果 wind speed 为 0 或太低而无法准确测量 wind direction,则应设为 `None`。 | `SensorDeviceClass.WIND_SPEED` | ft/s, km/h, kn, m/s, mph | Wind speed ### 可用的 state classes :::caution 选择 sensor 的 state class 时要谨慎。在大多数情况下,应选择 state class `SensorStateClass.MEASUREMENT` 或没有 `last_reset` 的 state class `SensorStateClass.TOTAL`,下面 [How to choose `state_class` and `last_reset`](#how-to-choose-state_class-and-last_reset) 中进一步解释了这一点。 ::: | Type | Description | ---- | ----------- | `SensorStateClass.MEASUREMENT` | State 表示 *present time 的 measurement*,而不是历史聚合(如统计)或未来预测。应归类为 `SensorStateClass.MEASUREMENT` 的示例有:current temperature、humidity 或 electric power。不应归类为 `SensorStateClass.MEASUREMENT` 的示例有:明天的 forecasted temperature、昨天的 energy consumption 或任何不包含 *current* measurement 的内容。对于支持的 sensors,每小时 min、max 和平均 sensor readings 的 statistics 每 5 分钟更新一次。 | `SensorStateClass.MEASUREMENT_ANGLE` | 与上述 `SensorStateClass.MEASUREMENT` 类似,state 表示以 degrees(`°`)测量的 angles 在 *present time 的 measurement*。应归类为 `SensorStateClass.MEASUREMENT_ANGLE` 的示例有:current wind direction | `SensorStateClass.TOTAL` | State 表示既可以增加又可以减少的 total amount,例如 net energy meter。从 sensor 首次添加以来其 value 的 accumulated growth 或 decline 的 statistics 每 5 分钟更新一次。此 state class 不应用于对 absolute value 感兴趣而不是 accumulated growth 或 decline 的 sensors,例如剩余 battery capacity 或 CPU load;在这种情况下应改用 state class `SensorStateClass.MEASUREMENT`。 | `SensorStateClass.TOTAL_INCREASING` | 类似于 `SensorStateClass.TOTAL`,但限制为 state 表示单调递增的 positive total,并定期从 0 重新开始计数,例如每日消耗的 gas 量、每周 water consumption 或 lifetime energy consumption。从 sensor 首次添加以来其 value 的 accumulated growth 的 statistics 每 5 分钟更新一次。Decreasing value 被解释为新 meter cycle 的开始或 meter 的更换。 ### entity 选项 Sensors 可以由用户配置,这是通过在其 entity registry entry 中存储 `sensor` entity options 来实现的。 | Option | Description | ------ | ----------- | `unit_of_measurement` | 对于 device class 为 `SensorDeviceClass.PRESSURE` 或 `SensorDeviceClass.TEMPERATURE` 的 sensors,可以覆盖 sensor 的计量单位。 ## 恢复 sensor 状态 在 restart 或 reload 后恢复 state 的 sensors 不应扩展 `RestoreEntity`,因为它不存储 `native_value`,而是存储可能被 sensor base entity 修改的 `state`。恢复 state 的 sensors 应扩展 `RestoreSensor`,并从 `async_added_to_hass` 调用 `await self.async_get_last_sensor_data`,以访问存储的 `native_value` 和 `native_unit_of_measurement`。 ## 长期统计 Home Assistant 支持将 sensors 存储为 long-term statistics,前提是 entity 具有 正确的 properties。要 opt-in 进入 statistics,sensor 必须将 `state_class` 设为有效的 state class 之一:`SensorStateClass.MEASUREMENT`、`SensorStateClass.TOTAL` 或 `SensorStateClass.TOTAL_INCREASING`。 对于某些 device classes,statistics 的 unit 会被 normalized,例如使 能够在单个 graph 中绘制多个 sensors。 ### 不表示总量的 entities Home Assistant 在 statistics 期间跟踪 min、max 和 mean value。 `state_class` property 必须设为 `SensorStateClass.MEASUREMENT`,且 `device_class` 不能 是 `SensorDeviceClass.DATE`、`SensorDeviceClass.ENUM`、`SensorDeviceClass.ENERGY`、`SensorDeviceClass.GAS`、`SensorDeviceClass.MONETARY`、 `SensorDeviceClass.TIMESTAMP`、`SensorDeviceClass.VOLUME` 或 `SensorDeviceClass.WATER` 中的任何一种。 ### 表示总量的 entities 跟踪 total amount 的 entities 具有一个可能定期重置的 value, 例如本月 energy consumption、今天的 energy production、过去一周用于供暖的 pellets 重量,或 stock portfolio 的年度增长。首次编译 statistics 时 sensor 的 value 用作初始零基准点。 #### 如何选择 `state_class` 和 `last_reset` 建议尽可能使用没有 `last_reset` 的 state class `SensorStateClass.TOTAL`,只有在没有 `last_reset` 的 state class `SensorStateClass.TOTAL` 不适用于 sensor 时,才应使用 state class `SensorStateClass.TOTAL_INCREASING` 或带有 `last_reset` 的 `SensorStateClass.TOTAL`。 示例: * Sensor 的 value 从不重置,例如 lifetime total energy consumption 或 production:state\_class `SensorStateClass.TOTAL`,`last_reset` 未设置或设为 `None` * Sensor 的 value 可能重置为 0,且其 value 只能增加:state class `SensorStateClass.TOTAL_INCREASING`。示例:与 billing cycle 对齐的 energy consumption(例如每月),每次断开连接时重置为 0 的 energy meter * Sensor 的 value 可能重置为 0,且其 value 既可以增加又可以减少:state class `SensorStateClass.TOTAL`,在 value 重置时更新 `last_reset`。示例:与 billing cycle 对齐的 net energy consumption(例如每月)。 * Sensor 的 state 每次 state update 时重置,例如每分钟更新一次、显示过去一分钟 energy consumption 的 sensor:state class `SensorStateClass.TOTAL`,每次 state change 时更新 `last_reset`。 #### 状态类 `SensorStateClass.TOTAL` 对于 state class 为 `SensorStateClass.TOTAL` 的 sensors,`last_reset` attribute 可以 选项性地设置,以获取对 meter cycles 的 manual control。 Sensor 首次添加到 Home Assistant 时的 state 用作初始 零基准点。当 `last_reset` 改变时,零基准点将设为 0。 如果未设置 last\_reset,则计算 `sum` statistics 时使用 sensor 首次添加时的 value 作为 零基准点。 换句话说:更新 statistics 时的逻辑是用当前 state 与前一个 state 之间的差来更新 sum 列,除非 `last_reset` 已改变,此时不添加任何内容。 没有 last\_reset 的 state class `SensorStateClass.TOTAL` 示例: | t | state | sum | sum\_increase | sum\_decrease | :--------------------- | -----: | -----: | -----------: | -----------: | 2021-08-01T13:00:00 | 1000 | 0 | 0 | 0 | 2021-08-01T14:00:00 | 1010 | 10 | 10 | 0 | 2021-08-01T15:00:00 | 0 | -1000 | 10 | 1010 | 2021-08-01T16:00:00 | 5 | -995 | 15 | 1010 带有 last\_reset 的 state class `SensorStateClass.TOTAL` 示例: | t | state | last\_reset | sum | sum\_increase | sum\_decrease | :--------------------- | -----: | ------------------- | -----: | -----------: | -----------: | 2021-08-01T13:00:00 | 1000 | 2021-08-01T13:00:00 | 0 | 0 | 0 | 2021-08-01T14:00:00 | 1010 | 2021-08-01T13:00:00 | 10 | 10 | 0 | 2021-08-01T15:00:00 | 1005 | 2021-08-01T13:00:00 | 5 | 10 | 5 | 2021-08-01T16:00:00 | 0 | 2021-09-01T16:00:00 | 5 | 10 | 5 | 2021-08-01T17:00:00 | 5 | 2021-09-01T16:00:00 | 10 | 15 | 5 新 meter cycle 开始时初始 state 不为 0、但将 0 用作零基准点的 state class `SensorStateClass.TOTAL` 示例: | t | state | last\_reset | sum | sum\_increase | sum\_decrease | :--------------------- | -----: | ------------------- | -----: | -----------: | -----------: | 2021-08-01T13:00:00 | 1000 | 2021-08-01T13:00:00 | 0 | 0 | 0 | 2021-08-01T14:00:00 | 1010 | 2021-08-01T13:00:00 | 10 | 10 | 0 | 2021-08-01T15:00:00 | 1005 | 2021-08-01T13:00:00 | 5 | 10 | 5 | 2021-08-01T16:00:00 | 5 | 2021-09-01T16:00:00 | 10 | 15 | 5 | 2021-08-01T17:00:00 | 10 | 2021-09-01T16:00:00 | 15 | 20 | 5 #### 状态类 `SensorStateClass.TOTAL_INCREASING` 对于 state\_class 为 `SensorStateClass.TOTAL_INCREASING` 的 sensors,decreasing value 被 解释为新 meter cycle 的开始或 meter 的更换。重要的是,集成要确保从带有 measurement noise 的 sensor 计算 value 时,value 不会错误地减少。 有一定的容差,state change 之间减少 < 10% 不会触发新 meter cycle。此 state class 适用于 gas meters、electricity meters、water meters 等。 计算 `sum` statistics 时,sensor reading 减少时的 value 不会用作零基准点,而是将零基准点设为 0。 换句话说:更新 statistics 时的逻辑是用当前 state 与前一个 state 之间的差来更新 sum 列,除非该差为负,此时不添加任何内容。 State class `SensorStateClass.TOTAL_INCREASING` 示例: | t | state | sum | :--------------------- | -----: | ---: | 2021-08-01T13:00:00 | 1000 | 0 | 2021-08-01T14:00:00 | 1010 | 10 | 2021-08-01T15:00:00 | 0 | 10 | 2021-08-01T16:00:00 | 5 | 15 Sensor 不重置为 0 的 state class `SensorStateClass.TOTAL_INCREASING` 示例: | t | state | sum | :--------------------- | -----: | ---: | 2021-08-01T13:00:00 | 1000 | 0 | 2021-08-01T14:00:00 | 1010 | 10 | 2021-08-01T15:00:00 | 5 | 15 | 2021-08-01T16:00:00 | 10 | 20 ### 处理从不支持到支持计量单位的迁移 集成可能有具有自定义计量单位的 sensors,即它们不使用 Home Assistant 常量来设置 units。 在将这样的 sensor 迁移到 Home Assistant unit system 支持的 unit 时,旧的自定义 unit 必须与 Home Assistant 常量的值完全匹配,否则 Home Assistant 会将其视为 unit change。 例如,集成可能已将 energy sensor 的 unit 设为 `KWh`,这与 `UnitOfEnergy.KILO_WATT_HOUR`(kWh)的值不同。 在编译 long-term statistics 时会检测到这种 unit change。在没有旧 unit 和新 unit 之间关系的知识的情况下, 会抑制 statistics 的收集并生成关于 unit 不稳定的 warning。 为了便于这些 migration 情况,集成可以提供自定义 unit mapping 来声明任何不支持的 unit 等同于一个支持的 unit。这通过在集成的目录中创建 recorder platform `recorder.py` 并实现函数 `async_custom_equivalent_units`,为任何相关的 `entity_id` 返回一个 equivalent units 字典来完成。 此 mapping 将在 statistics 编译期间收集,并使集成能够平稳过渡到 Home Assistant 的 unit system。 示例实现: ```python @callback def async_custom_equivalent_units(hass: HomeAssistant) -> dict[str, dict[str | None, str]]: """Return custom equivalent units per entity id.""" return { "sensor.example_sensor_1": { "b/s": UnitOfDataRate.BYTES_PER_SECOND, # B/s }, "sensor.example_sensor_2": { "KWh": UnitOfEnergy.KILO_WATT_HOUR, # kWh }, } ``` --- url: /developers/core/entity/siren.md --- Siren 实体是主要用途为控制 siren 设备(如门铃或铃声)的设备。从 [`homeassistant.components.siren.SirenEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/siren/__init__.py) 派生实体平台。 ## 属性 :::tip 属性应始终仅返回内存中的信息,而不是执行 I/O(如网络请求)。实现 `update()` 或 `async_update()` 来获取数据,或构建一种机制将状态更新推送到实体类实例。 ::: | 名称 | 类型 | 默认值 | 描述 | | ----------------------- | ------ | ------------------------------------- | --------------------------------------------------------------------------------------- | | is\_on | bool | `None` | 设备是开启还是关闭。 | | available\_tones | list 或 dict | `NotImplementedError()` | 设备上可用的 tones 列表或字典,传递给 `turn_on` 服务操作。如果提供字典,当用户使用 tone 的 dict 值时,它在传递给集成平台之前会转换为对应的 dict 键。需要 `SirenEntityFeature.TONES` 功能。 | ### 音调 设备可以有不同的 tones。集成在支持时负责提供可用的 tones。 ### 支持的功能 支持的功能常量使用按位或(`|`)运算符进行组合。 | 名称 | 描述 | | ------------------------- | ---------------------------------------------------------------------------------------------------------------- | | `SirenEntityFeature.TURN_ON` | 设备可以通过 `turn_on` 服务操作开启。 | | `SirenEntityFeature.TURN_OFF` | 设备可以通过 `turn_off` 服务操作关闭。 | | `SirenEntityFeature.TONES` | 设备支持不同的 tones(tone 可以传入 `turn_on` 服务操作)。 | | `SirenEntityFeature.DURATION` | 设备支持为 tone 设置持续时间(duration 可以传入 `turn_on` 服务操作)。 | | `SirenEntityFeature.VOLUME_SET` | 设备支持设置设备的音量级别(volume level 可以传入 `turn_on` 服务操作)。 | ## 方法 ### 开启 `turn_on` 服务操作需要 `SirenEntityFeature.TURN_ON` 功能。 有三个可选输入参数可以传入服务操作调用,每个由支持的功能标志门控。如果在服务操作调用中提供某个输入参数时相应的标志未设置,基础平台将在传递给集成之前从调用中过滤掉它。 | 参数名称 | 数据验证 | 支持的功能标志 | |---------------- |--------------------------------------- |------------------------------- | | `tone` | `vol.Any(vol.Coerce(int), cv.string)` | `SirenEntityFeature.TONES` | | `duration` | `cv.positive_int` | `SirenEntityFeature.DURATION` | | `volume_level` | `cv.small_float` | `SirenEntityFeature.VOLUME_SET` | ```python class MySirenEntity(SirenEntity): # 实现以下方法之一。 def turn_on(self, **kwargs: Any) -> None: """Turn the device on.""" async def async_turn_on(self, **kwargs: Any) -> None: """Turn the device on.""" ``` ### 关闭 `turn_off` 服务操作需要 `SirenEntityFeature.TURN_OFF` 功能。 ```python class MySirenEntity(SirenEntity): # 实现以下方法之一。 def turn_off(self, **kwargs: Any) -> None: """Turn the device off.""" async def async_turn_off(self, **kwargs: Any) -> None: """Turn the device off.""" ``` --- url: /developers/core/entity/stt.md --- Speech-to-text (STT) 实体允许其他集成或应用程序向 STT API 流式传输语音数据并获取文本。 Speech-to-text 实体派生自 [`homeassistant.components.stt.SpeechToTextEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/stt/__init__.py)。 ## 属性 :::tip 属性应始终仅返回内存中的信息,而不是执行 I/O(如网络请求)。 ::: | 名称 | 类型 | 默认值 | 描述 | ---- | ---- | ------- | ----------- | supported\_languages | list\[str] | **必填** | STT 服务支持的语言。 | supported\_formats | list\[AudioFormats] | **必填** | STT 服务支持的音频格式,wav 或 ogg。 | supported\_codecs | list\[AudioCodecs] | **必填** | STT 服务支持的音频编解码器,pcm 或 opus。 | supported\_bit\_rates | list\[AudioBitRates] | **必填** | STT 服务支持的音频比特率,8、16、24 或 32。 | supported\_sample\_rates | list\[AudioSampleRates] | **必填** | STT 服务支持的音频采样率。 | supported\_channels | list\[AudioChannels] | **必填** | STT 服务支持的音频声道,1 或 2。 ## 方法 ### 处理音频流 处理音频流方法用于向 STT 服务发送音频并获取文本。 ```python class MySpeechToTextEntity(SpeechToTextEntity): """Represent a Speech To Text entity.""" async def async_process_audio_stream( self, metadata: SpeechMetadata, stream: AsyncIterable[bytes] ) -> SpeechResult: """Process an audio stream to STT service. Only streaming content is allowed! """ ``` --- url: /developers/core/entity/switch.md --- Switch entity 开启或关闭某物,例如 relay。从 [`homeassistant.components.switch.SwitchEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/switch/__init__.py) 派生 platform entity。 要表示具有 on 或 off state 但无法控制的事物(例如只传输其 state 但无法从 Home Assistant 开启或关闭的 wall switch),使用 Binary Sensor 更好。 要表示没有 state 的事物(例如 door bell push button),使用自定义 event 或 Device Trigger 更好。 ## 属性 :::tip Properties 应该只从内存返回信息,而不要执行 I/O(如网络请求)。请实现 `update()` 或 `async_update()` 来获取数据。 ::: | Name | Type | Default | Description | ---- | ---- | ------- | ----------- | is\_on | boolean | `None` | Switch 当前是否开启或关闭。 ## 方法 ### 开启 开启 switch。 ```python class MySwitch(SwitchEntity): # 实现以下方法之一。 def turn_on(self, **kwargs: Any) -> None: """Turn the entity on.""" async def async_turn_on(self, **kwargs: Any) -> None: """Turn the entity on.""" ``` ### 关闭 关闭 switch。 ```python class MySwitch(SwitchEntity): # 实现以下方法之一。 def turn_off(self, **kwargs: Any) -> None: """Turn the entity off.""" async def async_turn_off(self, **kwargs: Any) -> None: """Turn the entity off.""" ``` ### 切换 可选。如果未实现,默认会通过检查 `is_on` property 来确定调用哪个 method。 ```python class MySwitch(SwitchEntity): # 实现以下方法之一。 def toggle(self, **kwargs: Any) -> None: """Toggle the entity.""" async def async_toggle(self, **kwargs: Any) -> None: """Toggle the entity.""" ``` ### 可用的设备类型 可选。这是什么类型的 device。它可能会映射到 Google device types。 | Constant | Description | ----- | ----------- | `SwitchDeviceClass.OUTLET` | Device 是 power 的 outlet。 | `SwitchDeviceClass.SWITCH` | Device 是某种类型 entity 的 switch。 --- url: /developers/core/entity/text.md --- Text 实体是一种允许用户向集成输入文本值的实体。从 [`homeassistant.components.text.TextEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/text/__init__.py) 派生实体平台。 ## 属性 :::tip 属性应始终仅返回内存中的信息,而不是执行 I/O(如网络请求)。实现 `update()` 或 `async_update()` 来获取数据,或构建一种机制将状态更新推送到实体类实例。 ::: | 名称 | 类型 | 默认值 | 描述 | ---- | ---- | ------- | ----------- | mode | string | `text` | 定义文本在 UI 中应如何显示。可以是 `text` 或 `password`。 | native\_max | int | 255 | 文本值中字符的最大数量(含)。 | native\_min | int | 0 | 文本值中字符的最小数量(含)。 | pattern | str | `None` | 文本值必须匹配的 regex 模式。 | native\_value | str | **必填** | 文本的值。 所有实体共有的其他属性(如 `icon`、`name` 等)也适用。 ## 方法 ### 设置值 ```python class MyTextEntity(TextEntity): # 实现以下方法之一。 def set_value(self, value: str) -> None: """Set the text value.""" async def async_set_value(self, value: str) -> None: """Set the text value.""" ``` --- url: /developers/core/entity/time.md --- `time` 是一种允许用户向集成输入时间的实体。从 [`homeassistant.components.time.TimeEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/time/__init__.py) 派生实体平台。 ## 属性 :::tip 属性应始终仅返回内存中的信息,而不是执行 I/O(如网络请求)。实现 `update()` 或 `async_update()` 来获取数据。 ::: | 名称 | 类型 | 默认值 | 描述 | ---- | ---- | ------- | ----------- | native\_value | time | None | `None` | 时间的值。 所有实体共有的其他属性(如 `icon`、`name` 等)也适用。 ## 方法 ### 设置值 当用户或自动化想要更新值时调用。 ```python class MyTime(TimeEntity): # 实现以下方法之一。 def set_value(self, value: time) -> None: """Update the current value.""" async def async_set_value(self, value: time) -> None: """Update the current value.""" ``` --- url: /developers/core/entity/todo.md --- 待办事项实体(To-do list entity)是一种代表待办事项列表的实体。待办事项列表包含按顺序排列的待办事项(To-do items),每个事项有状态(完成或进行中)。待办事项实体派生自 [`homeassistant.components.todo.TodoListEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/todo/__init__.py)。 ## 属性 :::tip Properties 应只从内存中返回信息,不要执行 I/O(如网络请求)。实现 `update()` 或 `async_update()` 来获取数据。 ::: | 名称 | 类型 | 默认值 | 描述 | | ----- | ------------- | --------------------- | ------------------------------------------------------- | | todo\_items | `list[TodoItem] \| None` | `None` | **必填。** 待办事项列表的有序内容。 | ### 状态 `TodoListEntity` 的 state 是待办事项列表中未完成事项的数量。 ## 支持的功能 Supported features 通过使用 `TodoListEntityFeature` enum 中的值定义,并使用按位或(`|`)运算符组合。 | 值 | 描述 | | -------------------------- | ------------------------------------------------------------------ | | `CREATE_TODO_ITEM` | 实体实现了允许创建待办事项的方法。 | | `DELETE_TODO_ITEM` | 实体实现了允许删除待办事项的方法。 | | `UPDATE_TODO_ITEM` | 实体实现了允许更新待办事项的方法。 | | `MOVE_TODO_ITEM` | 实体实现了允许重新排列待办事项的方法。 | | `SET_DUE_DATE_ON_ITEM` | 实体在创建或更新待办事项时,实现了将事项的 `due` 字段设置为 `datetime.date`。 | | `SET_DUE_DATETIME_ON_ITEM` | 实体在创建或更新待办事项时,实现了将事项的 `due` 字段设置为 `datetime.datetime`。 | | `SET_DESCRIPTION_ON_ITEM` | 实体在创建或更新待办事项时,实现了设置事项的 `description` 字段。 | ## 方法 ### 创建待办事项 待办事项实体可通过指定 `CREATE_TODO_ITEM` supported feature 来支持创建待办事项。 ```python from homeassistant.components.todo import TodoListEntity class MyTodoListEntity(TodoListEntity): async def async_create_todo_item(self, item: TodoItem) -> None: """Add an item to the To-do list.""" ``` ### 删除待办事项 待办事项实体可通过指定 `DELETE_TODO_ITEM` supported feature 来支持删除待办事项。集成必须支持删除多个事项。 ```python from homeassistant.components.todo import TodoListEntity class MyTodoListEntity(TodoListEntity): async def async_delete_todo_items(self, uids: list[str]) -> None: """Delete an item from the to-do list.""" ``` ### 更新待办事项 待办事项实体可通过指定 `UPDATE_TODO_ITEM` supported feature 来支持更新待办事项。`TodoItem` 字段 `uid` 始终存在,指示要更新哪个事项。传递的更新事项是原始事项的副本,部分字段已更新或清除。 ```python from homeassistant.components.todo import TodoListEntity class MyTodoListEntity(TodoListEntity): async def async_update_todo_item(self, item: TodoItem) -> None: """Add an item to the To-do list.""" ``` ### 移动待办事项 待办事项实体可通过指定 `MOVE_TODO_ITEM` supported feature 来支持在列表中重新排列待办事项。具有指定 `uid` 的待办事项应移动到列表中 `previous_uid` 指定事项之后(`None` 表示移动到列表第一位)。 ```python from homeassistant.components.todo import TodoListEntity class MyTodoListEntity(TodoListEntity): async def async_move_todo_item( self, uid: str, previous_uid: str | None = None ) -> None: """Move an item in the To-do list.""" ``` ## TodoItem `TodoItem` 表示待办事项列表中的单个事项。上述方法描述了在创建或更新时哪些字段是可选的。 | 名称 | 类型 | 默认值 | 描述 | | ----------- | ---------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- | | uid | `str \| None` | `None` | 待办事项的唯一标识符。此字段在更新和实体状态中必填。 | summary | `str \| None` | `None` | 待办事项的标题或摘要。此字段在实体状态中必填。 | status | `TodoItemStatus \| None` | `None` | 定义待办事项的整体状态,为 `NEEDS_ACTION` 或 `COMPLETED`。此字段在实体状态中必填。 | due | `datetime.date \| datetime.datetime \| None` | `None` | 待办事项预计完成的日期和时间。作为 datetime 时,必须有时区。 | description | `str \| None` | `None` | 比 summary 提供的更完整的待办事项描述。 | completed | `datetime.datetime \| None` | `None` | 指示此事项最后被标记为 `COMPLETED` 的时间戳。 --- url: /developers/core/entity/tts.md --- Text-to-speech (TTS) 实体使 Home Assistant 能够对你说话。 Text-to-speech 实体派生自 [`homeassistant.components.tts.TextToSpeechEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/tts/__init__.py)。 ## 属性 :::tip 属性应始终仅返回内存中的信息,而不是执行 I/O(如网络请求)。 ::: | 名称 | 类型 | 默认值 | 描述 | ---- | ---- | ------- | ----------- | supported\_languages | list\[str] | **必填** | TTS 服务支持的语言。 | default\_language | str | **必填** | TTS 服务的默认语言。 | supported\_options | list\[str] | None | TTS 服务支持的选项,如 voice、emotions。 | default\_options | Mapping\[str, Any] | None | TTS 服务的默认选项。 ## 方法 ### 获取支持的语音 此方法用于返回 TTS 服务某个语言支持的语音列表。 ```python class MyTextToSpeechEntity(TextToSpeechEntity): """Represent a Text To Speech entity.""" @callback def async_get_supported_voices(self, language: str) -> list[Voice] | None: """Return a list of supported voices for a language.""" ``` ### 一次性生成 TTS 音频 此方法以消息和语言作为输入,返回 TTS 音频。可以作为同步或异步实现,必须实现。 ```python class MyTextToSpeechEntity(TextToSpeechEntity): """Represent a Text To Speech entity.""" def get_tts_audio( self, message: str, language: str, options: dict[str, Any] ) -> TtsAudioType: """Load tts audio file from the engine.""" async def async_get_tts_audio( self, message: str, language: str, options: dict[str, Any] ) -> TtsAudioType: """Load tts audio file from the engine.""" ``` ### 以消息流式方式生成 TTS 音频 大型语言模型以块的形式生成文本。TTS 服务可以接收文本消息流,并以块的形式返回音频。 此方法是可选项。当未实现时,TTS 服务将使用最终消息调用一次性方法。 ```python class MyTextToSpeechEntity(TextToSpeechEntity): """Represent a Text To Speech entity.""" async def async_stream_tts_audio( self, request: TTSAudioRequest ) -> TTSAudioResponse: """Generate speech from an incoming message.""" ``` `TTSAudioRequest` 和 `TTSAudioResponse` 对象的定义如下: ```python @dataclass class TTSAudioRequest: """Request to get TTS audio.""" language: str options: dict[str, Any] message_gen: AsyncGenerator[str] @dataclass class TTSAudioResponse: """Response containing TTS audio stream.""" extension: str data_gen: AsyncGenerator[bytes] ``` --- url: /developers/core/entity/update.md --- Update entity 是一种指示 device 或 service 是否有 update 可用的 entity。 它可以是任何 update,包括 device(如 light bulb 或 router)的 firmware update,或 apps(以前称为 add-ons)或 containers 的 software updates。 它可用于: * 提供 device 或 service 是否有 update 可用的指示器。 * 提供一种 install method,允许安装 update 或 software 的特定 version。 * 允许在安装新 update 之前提供 backup。 ## 属性 :::tip Properties 应该只从内存返回信息,而不要执行 I/O(如网络请求)。请实现 `update()` 或 `async_update()` 来获取数据。 ::: | Name | Type | Default | Description | ---- | ---- | ------- | ----------- | auto\_update | bool | `False` | Entity 所代表的 device 或 service 具有 auto update logic。当此值设为 `True` 时,不能跳过 updates。 | display\_precision | int | `0` | 显示 update progress 的小数位数。 | in\_progress | bool | `False` | Update installation progress。应返回布尔值(进行中标记为 True,未进行标记为 False)。 | installed\_version | str | `None` | 当前已安装并使用的 software version。 | latest\_version | str | `None` | 可用 software 的最新 version。 | release\_summary | str | `None` | Release notes 或 changelog 的摘要。不适合长 changelogs,仅适合最多 255 字符的简短 update description 摘录。 | release\_url | str | `None` | 可用最新 version 的完整 release notes 的 URL。 | title | str | `None` | Software 的 title。这有助于区分 device 或 entity name 与已安装 software 的 title。 | update\_percentage | int, float | `None` | Update installation progress。可以返回一个 0 到 100% 的 progress 数字,或 None。 其他在所有 entity 中通用的 properties(如 `device_class`、`entity_category`、`icon`、`name` 等)仍然适用。 ## 支持的功能 Supported features 通过使用 `UpdateEntityFeature` enum 中的值来定义。 | Value | Description | |----------|--------------------------------------| | `BACKUP` | 可以在安装 update 之前自动创建 backup。 | `INSTALL` | 可以从 Home Assistant 安装 update。 | `PROGRESS` | 此集成能够提供 progress information。如果省略,Home Assistant 会尝试提供 progress status;尽管最好是从 device 或 service API 中提取 progress。 | `SPECIFIC_VERSION` | 可以使用 `update.install` service action 安装 update 的特定 version。 | `RELEASE_NOTES` | Entity 提供获取完整 changelog 的 methods。 ## 方法 ### 比较版本 在需要 override 默认 version comparison logic 时应实现此 method。 以下是一个示例: ```python def version_is_newer(self, latest_version: str, installed_version: str) -> bool: """Return True if latest_version is newer than installed_version.""" return AwesomeVersion( latest_version, find_first_match=True, ensure_strategy=[AwesomeVersionStrategy.SEMVER], ) > AwesomeVersion( installed_version, find_first_match=True, ensure_strategy=[AwesomeVersionStrategy.SEMVER], ) ``` 它允许 developers 指定自定义逻辑来确定一个 version 是否比另一个更新。首次尝试应基于 [AwesomeVersion library](https://github.com/ludeeus/awesomeversion?tab=readme-ov-file#awesomeversion-class) 提供的 strategies。 ### 安装 实现此 method 使用户可以直接从 Home Assistant 内安装提供的 update。 此 method 要求设置 `UpdateEntityFeature.INSTALL`。此外,如果此集成支持安装特定 version 或能够在开始 update installation process 之前创建 backup,则可以分别设置 `UpdateEntityFeature.SPECIFIC_VERSION` 和 `UpdateEntityFeature.BACKUP`。 ```python class MyUpdate(UpdateEntity): # 实现以下方法之一。 def install( self, version: str | None, backup: bool, **kwargs: Any ) -> None: """Install an update.""" async def async_install( self, version: str | None, backup: bool, **kwargs: Any ) -> None: """Install an update. Version 可以指定为安装特定 version。当为 `None` 时, 需要安装最新 version。 Backup 参数表示应在安装 update 之前创建 backup。 """ ``` ### 发布说明 实现此 method 使用户可以在安装 update 之前,在 Home Assistant Frontend 的 more-info dialog 中查看完整的 release notes。 返回的字符串可以包含 markdown,frontend 会正确格式化它。 此 method 要求设置 `UpdateEntityFeature.RELEASE_NOTES`。 ```python class MyUpdate(UpdateEntity): # 实现以下方法之一。 def release_notes(self) -> str | None: """Return the release notes.""" return "Lorem ipsum" async def async_release_notes(self) -> str | None: """Return the release notes.""" return "Lorem ipsum" ``` ### 可用的设备类型 选项性地指定 entity 的类型。 | Constant | Description | ----- | ----------- | `UpdateDeviceClass.FIRMWARE` | Update 是 device 的 firmware update。 --- url: /developers/core/entity/vacuum.md --- 从 [`homeassistant.components.vacuum.StateVacuumEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/vacuum/__init__.py) 派生 entity 平台。 ## 属性 :::tip 属性应始终仅返回内存中的信息,而不是执行 I/O(如网络请求)。实现 `update()` 或 `async_update()` 来获取数据。 ::: | 名称 | 类型 | 默认值 | 描述 | ---- | ---- | ------- | ----------- | fan\_speed | string | `none` | 当前的 fan speed。 | fan\_speed\_list | list | `NotImplementedError()`| 可用的 fan speeds 列表。 | name | string | **必填** | Entity 的名称。 | activity | VacuumActivity | **必填** | 返回下面"状态"部分所列状态之一。 ## 状态 设置 state 时应返回 `VacuumActivity` 枚举中的一个值,通过 `activity` 属性返回。 | 值 | 描述 | ----- | ----------- | `CLEANING` | 吸尘器当前正在清洁。 | `DOCKED` | 吸尘器当前已停放在 dock 上,假定 docked 也可能表示充电中。 | `IDLE` | 吸尘器既未暂停、未停放在 dock 上,也没有任何错误。 | `PAUSED` | 吸尘器曾正在清洁,但在未返回 dock 的情况下被暂停。 | `RETURNING` | 吸尘器已完成清洁,当前正在返回 dock,但尚未停放在 dock 上。 | `ERROR` | 吸尘器在清洁过程中遇到错误。 ## 支持的功能 支持的功能通过使用 `VacuumEntityFeature` 枚举中的值来定义, 并使用按位或(`|`)运算符组合。 注意,所有从 `homeassistant.components.vacuum.StateVacuumEntity` 派生的 vacuum entity 平台 都必须设置 `VacuumEntityFeature.STATE` 标志。 | 值 | 描述 | | -------------- | ---------------------------------------------------- | | `CLEAN_AREA` | 吸尘器支持清洁特定区域。 | | `CLEAN_SPOT` | 吸尘器支持点清洁。 | | `FAN_SPEED` | 吸尘器支持设置 fan speed。 | | `LOCATE` | 吸尘器支持定位。 | | `MAP` | 吸尘器支持获取其地图。 | | `PAUSE` | 吸尘器支持 pause 命令。 | | `RETURN_HOME` | 吸尘器支持返回 dock 的命令。 | | `SEND_COMMAND` | 吸尘器支持向吸尘器发送命令。 | | `START` | 吸尘器支持 start 命令。 | | `STATE` | 吸尘器支持返回其 state。 | | `STOP` | 吸尘器支持 stop 命令。 | ## 方法 ### `async_get_segments` 返回一个 `Segment` 对象列表,表示吸尘器报告的可清洁 segment。当支持 `CLEAN_AREA` 时,集成平台必须实现此方法。它在配置 area mapping 时被调用,因此应返回最新的信息。 ```python async def async_get_segments(self) -> list[Segment]: """Get the segments that can be cleaned.""" ``` `Segment` dataclass 定义如下: ```python @dataclass(slots=True) class Segment: """Represents a cleanable segment reported by a vacuum.""" id: str name: str group: str | None = None ``` `id` 必须对于给定 vacuum entity 的所有 segment 全局唯一,无论属于哪个 group。`group` 字段仅用于在 mapping UI 中对 segment 进行分组。 ### `clean_segments` 或 `async_clean_segments` 按 ID 清洁指定的 segment。当支持 `CLEAN_AREA` 时,集成平台必须实现此方法。它在 `clean_area` 服务将目标 area 解析为 segment 后被内部调用。 ```python async def async_clean_segments(self, segment_ids: list[str], **kwargs: Any) -> None: """Perform an area clean.""" ``` ### `last_seen_segments` 一个属性,返回吸尘器报告的、在上次配置 area mapping 时可用的 segment。集成可以在其更新周期中将其与当前设备 segment 进行比较,以检测变化,并在适当时调用 `async_create_segments_issue`。如果尚未保存任何 mapping,则返回 `None`,此时不应触发 issue。 ```python @property def last_seen_segments(self) -> list[Segment] | None: """Return segments as seen by the user, when last mapping the areas.""" ``` ### `async_create_segments_issue` 一个辅助方法,当吸尘器报告的 segment 与上次配置 area mapping 时可用的 segment 不同时创建 repair issue。当 segment 变化需要调整 area mapping 时,集成应调用此方法。产生的 repair issue 会提示用户重新配置 area mapping,从而相应地更新 `last_seen_segments`。 ```python @callback def async_create_segments_issue(self) -> None: """Create a repair issue when vacuum segments have changed.""" ``` ### `clean_spot` 或 `async_clean_spot` 执行点清洁。 ### `locate` 或 `async_locate` 定位吸尘器。 ### `pause` 或 `async_pause` 暂停清洁任务。 ### `return_to_base` 或 `async_return_to_base` 设置吸尘器返回 dock。 ### `send_command` 或 `async_send_command` 向吸尘器发送命令。 ### `set_fan_speed` 或 `async_set_fan_speed` 设置 fan speed。 ### `start` 或 `async_start` 启动或恢复清洁任务。 ### `stop` 或 `async_stop` 停止吸尘器,不返回 dock。 --- url: /developers/core/entity/valve.md --- Valve 实体控制如水阀或气阀等阀门设备。从 [`homeassistant.components.valve.ValveEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/valve/__init__.py) 派生平台实体。 ## 属性 :::tip 属性应始终仅返回内存中的信息,而不是执行 I/O(如网络请求)。实现 `update()` 或 `async_update()` 来获取数据。 ::: | 名称 | 类型 | 默认值 | 描述 | ----------------------- | ---- | ------- | ----------- | current\_valve\_position | `int \| None` | `None` | 阀门的当前位置,其中 0 表示关闭,100 表示完全打开。此属性在 `reports_position = True` 的阀门上必填,用于确定状态。 | is\_closed | `bool \| None` | `None` | 阀门是否已关闭。用于确定不报告位置的阀门的 `state`。 | is\_closing | `bool \| None` | `None` | 阀门是否正在关闭。用于确定 `state`。 | is\_opening | `bool \| None` | `None` | 阀门是否正在打开。用于确定 `state`。 | reports\_position | bool | **必填** | 阀门是否知道其位置。 ### 设备类型 | 常量 | 描述 |----------|-----------------------| | `ValveDeviceClass.WATER` | 水阀的控制。 | `ValveDeviceClass.GAS` | 气阀的控制。 ### 状态 状态通过设置其属性来定义。结果状态使用 `ValveState` 枚举返回以下成员之一。 | 值 | 描述 | |----------|--------------------------------------------------------------------| | `OPENING`| 阀门正在打开以达到设定的位置。 | | `OPEN` | 阀门已到达打开位置。 | | `CLOSING`| 阀门正在关闭以达到设定的位置。 | | `CLOSED` | 阀门已到达关闭位置。 | ## 支持的功能 支持的功能通过使用 `ValveEntityFeature` 枚举中的值来定义,并使用按位或(`|`)运算符进行组合。 | 值 | 描述 | | ------------------- | -------------------------------------------------------------------------------- | | `OPEN` | 阀门支持打开。 | | `CLOSE` | 阀门支持关闭。 | | `SET_POSITION` | 阀门支持移动到打开和关闭之间的特定位置。 | | `STOP` | 阀门支持停止当前操作(打开、关闭、设置位置) | ## 方法 ### 打开阀门 仅当设置了 `ValveEntityFeature.OPEN` 标志时实现此方法。对于可以设置位置的阀门,此方法应留空实现,仅需要 `set_valve_position`。 ```python class MyValve(ValveEntity): # 实现以下方法之一。 def open_valve(self) -> None: """Open the valve.""" async def async_open_valve(self) -> None: """Open the valve.""" ``` ### 关闭阀门 仅当设置了 `ValveEntityFeature.CLOSE` 标志时实现此方法。对于可以设置位置的阀门,此方法应留空实现,仅需要 `set_valve_position`。 ```python class MyValve(ValveEntity): # 实现以下方法之一。 def close_valve(self) -> None: """Close valve.""" async def async_close_valve(self) -> None: """Close valve.""" ``` ### 设置阀门位置 仅当设置了 `ValveEntityFeature.SET_POSITION` 标志时实现此方法。能够设置位置的阀门必须实现此方法。 ```python class MyValve(ValveEntity): # 实现以下方法之一。 def set_valve_position(self, position: int) -> None: """Move the valve to a specific position.""" async def async_set_valve_position(self, position: int) -> None: """Move the valve to a specific position.""" ``` ### 停止阀门 仅当设置了 `ValveEntityFeature.STOP` 标志时实现此方法。 ```python class MyValve(ValveEntity): # 实现以下方法之一。 def stop_valve(self) -> None: """Stop the valve.""" async def async_stop_valve(self) -> None: """Stop the valve.""" ``` --- url: /developers/core/entity/wake_word.md --- Wake word detection 实体允许其他集成或应用程序在音频流中检测唤醒词(也称为 hotwords)。 Wake word detection 实体派生自 [`homeassistant.components.wake_word.WakeWordDetectionEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/wake_word/__init__.py)。 ## 属性 :::tip 属性应始终仅返回内存中的信息,而不是执行 I/O(如网络请求)。 ::: 所有实体共有的属性(如 `icon`、`name` 等)适用。 ## 方法 ### 获取支持的唤醒词 返回实体支持的唤醒词。每个 `WakeWord` 都有一个 `id`(唯一标识符)、一个 `name`(人类可读的名称)和一个可选的 `phrase`。 ```python class MyWakeWordDetectionEntity(WakeWordDetectionEntity): """Represent a Wake Word Detection entity.""" async def get_supported_wake_words(self) -> list[WakeWord]: """Return a list of supported wake words.""" ``` ### 处理音频流 处理音频流方法用于检测唤醒词。它必须返回一个 `DetectionResult`,或者如果音频流在没有检测到的情况下结束则返回 `None`。 ```python class MyWakeWordDetectionEntity(WakeWordDetectionEntity): """Represent a Wake Word Detection entity.""" async def _async_process_audio_stream( self, stream: AsyncIterable[tuple[bytes, int]], wake_word_id: str | None ) -> DetectionResult | None: """Try to detect wake word(s) in an audio stream with timestamps. Audio must be 16Khz sample rate with 16-bit mono PCM samples. """ ``` 音频流由形如 `(audio_chunk, timestamp)` 的元组组成,其中: * `audio_chunk` 是一块 16 位有符号单声道 PCM 采样,采样率为 16Khz * `timestamp` 是自音频流开始以来的毫秒数 如果检测到唤醒词,将返回一个 `DetectionResult`,包含: * `wake_word_id` - 检测到的唤醒词的唯一标识符 * `timestamp` - 检测发生时音频块的 timestamp * `queued_audio` - 将转发到 speech-to-text 的可选音频块(见下文) 在 [Assist pipeline](/developers/voice/pipelines.md) 中,音频流在 wake word detection 和 speech-to-text 之间共享。这意味着在 wake word detection 期间移除的任何音频块**无法**由 speech-to-text 处理,除非通过 `DetectionResult` 的 `queued_audio` 传回。 --- url: /developers/core/entity/water-heater.md --- 从 [`homeassistant.components.water_heater.WaterHeaterEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/water_heater/__init__.py) 派生实体平台。 ## 属性 :::tip 属性应始终仅返回内存中的信息,而不是执行 I/O(如网络请求)。实现 `update()` 或 `async_update()` 来获取数据。 ::: | 名称 | 类型 | 默认值 | 描述 | --------------------- | ----------- | --------- | ----------- | `min_temp` | `float` | 110°F | 可以设置的最低温度。 | `max_temp` | `float` | 140°F | 可以设置的最高温度。 | `current_temperature` | `float` | `None` | 当前温度。 | `target_temperature` | `float` | `None` | 我们试图达到的温度。 | `target_temperature_high` | `float` | `None` | 我们试图达到的温度的上界。 | `target_temperature_low` | `float` | `None` | 我们试图达到的温度的下界。 | `target_temperature_step` | `float` | `None` | 目标温度可增加或减少的步长。 | `temperature_unit` | `str` | `NotImplementedError` | `UnitOfTemperature.CELSIUS`、`UnitOfTemperature.FAHRENHEIT` 或 `UnitOfTemperature.KELVIN` 之一。 | `current_operation` | `string` | `None` | 当前的 operation mode。 | `operation_list` | `List[str]` | `None` | 可能的 operation mode 列表。 | `supported_features` | `WaterHeaterEntityFeature` | `WaterHeaterEntityFeature(0)`(无功能) | 支持的功能列表。 | `is_away_mode_on` | `bool` | `None` | away mode 的当前状态。 允许的 operation mode 是基础组件中指定的状态,water\_heater 组件的实现不能有所不同。 属性必须遵循 `temperature_unit` 中定义的单位。 ## 状态 | 状态 | 描述 | ----- | ----------- | `STATE_ECO` | 节能模式,提供节能和快速加热。 | `STATE_ELECTRIC` | 仅电动模式,能耗最高。 | `STATE_PERFORMANCE` | 高性能模式。 | `STATE_HIGH_DEMAND` | 当热水器功率不足时满足高需求。 | `STATE_HEAT_PUMP` | 加热最慢,但能耗较少。 | `STATE_GAS` | 仅燃气模式,能耗最高。 | `STATE_OFF` | 热水器已关闭。 ## 支持的功能 支持的功能通过使用 `WaterHeaterEntityFeature` 枚举中的值来定义,并使用按位或(`|`)运算符进行组合。 | 值 | 描述 | | -------------------- | ------------------------- | | `TARGET_TEMPERATURE` | 可以设置温度 | | `OPERATION_MODE` | 可以设置 operation mode | | `AWAY_MODE` | 可以设置 away mode | | `ON_OFF` | 可以开启或关闭 | ## 方法 ### `set_temperature` 或 `async_set_temperature` 设置热水器应将水加热到的温度。 ### `set_operation_mode` 或 `async_set_operation_mode` 设置热水器的 operation mode。必须在 operation\_list 中。 ### `turn_away_mode_on` 或 `async_turn_away_mode_on` 将热水器设置为 away mode。 ### `turn_away_mode_off` 或 `async_turn_away_mode_off` 将热水器恢复到上一个 operation mode。关闭 away mode。 ### `turn_on` 或 `async_turn_on` 开启热水器。 ### `turn_off` 或 `async_turn_off` 关闭热水器。 --- url: /developers/core/entity/weather.md --- 从 [`homeassistant.components.weather.WeatherEntity`](https://github.com/home-assistant/core/blob/dev/homeassistant/components/weather/__init__.py) 派生 entity platforms。 ## 属性 :::tip Properties 应始终只从内存返回信息,而不要执行 I/O(如网络请求)。请实现 `update()` 或 `async_update()` 来获取数据。 ::: | Name | Type | Default | Description | ---- | ---- | ------- | ----------- | cloud\_coverage | int | `None` | 当前的 cloud coverage(%)。 | condition | string | **必需** | 当前的 weather condition。 | humidity | float | `None` | 当前的 humidity(%)。 | native\_apparent\_temperature | float | `None` | 当前的 apparent(体感)temperature,单位为 °C 或 °F。 | native\_dew\_point | float | `None` | 当前的 dew point temperature,单位为 °C 或 °F。 | native\_precipitation\_unit | string | `None` | 降水计量单位;mm 或 in。 | native\_pressure | float | `None` | 当前的 air pressure,单位为 hPa、mbar、inHg 或 mmHg。 | native\_pressure\_unit | string | `None` | Air pressure 单位;hPa、mbar、inHg 或 mmHg。如果设置了 native\_pressure,则为必需。 | native\_temperature | float | **必需** | 当前的 temperature,单位为 °C 或 °F。 | native\_temperature\_unit | string | **必需** | Temperature 单位;°C 或 °F。 | native\_visibility | float | `None` | 当前的 visibility,单位为 km 或 mi。 | native\_visibility\_unit | string | `None` | Visibility 单位;km 或 mi。如果设置了 native\_visibility,则为必需。 | native\_wind\_gust\_speed | float | `None` | 当前的 wind gust speed,单位为 Beaufort、m/s、km/h、mi/h、ft/s 或 kn。 | native\_wind\_speed | float | `None` | 当前的 wind speed,单位为 Beaufort、m/s、km/h、mi/h、ft/s 或 kn。 | native\_wind\_speed\_unit | string | `None` | Wind speed 单位;Beaufort、m/s、km/h、mi/h、ft/s 或 kn。如果设置了 native\_wind\_speed,则为必需。 | ozone | float | `None` | 当前的 ozone 浓度。 | uv\_index | float | `None` | 当前的 [UV index](https://en.wikipedia.org/wiki/Ultraviolet_index)。 | wind\_bearing | float or string | `None` | 当前的 wind bearing,表示为 azimuth angle(度数)或 1-3 字母的 cardinal direction。 ### 单位转换 Properties 必须遵循表中各自计量单位所提及的单位。 对于用户,properties 将根据 unit system 进行呈现。这是通过创建 state objects 时自动转换单位来实现的。 对于每个 weather entity,用户还可以选择覆盖 presentation units,即 state objects 中使用的单位。 ### state 和 condition 的推荐值 以下 weather conditions 已包含在我们的 translation files 中,并会显示相应的 icon。 | Condition | Description | --------- | ----------- | clear-night | 晴朗的夜空 | cloudy | 多云 | exceptional | 极端天气 | fog | 雾 | hail | 冰雹 | lightning | 雷电 / 雷暴 | lightning-rainy | 雷电 / 雷暴并伴随降雨 | partlycloudy | 少云 | pouring | 倾盆大雨 | rainy | 下雨 | snowy | 下雪 | snowy-rainy | 雨夹雪 | sunny | 晴天 | windy | 有风 | windy-variant | 有风并伴随云层 这意味着 `weather` platforms 不需要自己支持各种语言。 ## 支持的功能 Supported features 通过使用 `WeatherEntityFeature` enum 中的值来定义, 并使用按位或(`|`)运算符组合。 | Value | Description | | -------------------------- | ------------------------------------------------------------------------------------------- | | `FORECAST_DAILY` | Device 支持 daily forecast。 | | `FORECAST_HOURLY` | Device 支持 hourly forecast。 | | `FORECAST_TWICE_DAILY` | Device 支持 twice-daily forecast。 | ## 天气预报 Weather platform 可以选项性地提供 weather forecasts。对 weather forecasts 的支持通过设置正确的 [supported feature](#supported-features) 来指示。Weather forecasts 不属于 entity 的 state,而是通过单独的 API 提供。Consumer(例如 frontend)可以订阅 weather forecast updates。 ### 预报数据 Forecast data 可以是 daily、hourly 或 twice\_daily。集成可以提供其中任意一种或全部。 集成应实现下面文档中说明的一个或多个异步方法 `async_forecast_daily`、`async_forecast_hourly` 和 `async_forecast_twice_daily` 来获取 forecast data。 | Name | Type | Default | Description | ---- | ---- | ------- | ----------- | datetime | string | **必需** | UTC datetime,格式为 RFC 3339。 | is\_daytime | bool | `None` | `async_forecast_twice_daily` 返回的 forecast data 中必需,用于指示是白天还是夜晚。 | cloud\_coverage | int | `None` | Cloud coverage(%)。 | condition | string | `None` | 该 time point 的 weather condition。 | humidity | float | `None` | Humidity(%)。 | native\_apparent\_temperature | float | `None` | Apparent(体感)temperature,单位为 °C 或 °F。 | native\_dew\_point | float | `None` | Dew point temperature,单位为 °C 或 °F。 | native\_precipitation | float | `None` | 降水量,单位为 mm 或 in。 | native\_pressure | float | `None` | Air pressure,单位为 hPa、mbar、inHg 或 mmHg。 | native\_temperature | float | **必需** | 较高 temperature,单位为 °C 或 °F。 | native\_templow | float | `None` | 日间较低 temperature,单位为 °C 或 °F。 | native\_wind\_gust\_speed | int | `None` | Wind gust speed,单位为 Beaufort、m/s、km/h、mi/h、ft/s 或 kn。 | native\_wind\_speed | int | `None` | Wind speed,单位为 Beaufort、m/s、km/h、mi/h、ft/s 或 kn。 | precipitation\_probability | int | `None` | 降水概率(%)。 | uv\_index | float | `None` | UV index。 | wind\_bearing | float or string | `None` | Wind bearing,表示为 azimuth angle(度数)或 1-3 字母的 cardinal direction。 Forecast data 在适用的情况下,需要遵循与 properties 定义相同的计量单位。 ### 获取天气预报的方法 调用这些 methods 以从 api 获取 forecasts。 ```python class MyWeatherEntity(WeatherEntity): """Represent a Weather entity.""" async def async_forecast_daily(self) -> list[Forecast] | None: """返回 daily forecast,使用 native units。 仅在设置了 `WeatherEntityFeature.FORECAST_DAILY` 时实现此方法 """ async def async_forecast_twice_daily(self) -> list[Forecast] | None: """返回 twice daily forecast,使用 native units。 仅在设置了 `WeatherEntityFeature.FORECAST_TWICE_DAILY` 时实现此方法 """ async def async_forecast_hourly(self) -> list[Forecast] | None: """返回 hourly forecast,使用 native units。 仅在设置了 `WeatherEntityFeature.FORECAST_HOURLY` 时实现此方法 """ ``` ### 更新天气预报 强烈建议 weather entity 缓存获取到的 weather forecasts,以避免不必要的 API 访问。 当有新的 weather forecast 可用时,应使 weather forecast cache 失效,并 `await` `WeatherEntity.async_update_listeners` 方法,以触发将更新后的 weather forecast 推送到所有 active subscribers。如果有 active listeners,`WeatherEntity.async_update_listeners` 将调用相应的 `async_forecast_xxx` methods。如果没有 active listeners,`WeatherEntity.async_update_listeners` 不会调用任何 `async_forecast_xxx` methods。 --- url: /developers/core/integration-quality-scale/checklist.md --- import Checklist from './\_includes/checklist.jsx' 在更改集成的质量等级时,请确保在提交 PR 更改质量等级之前已完成所有规则。 在 PR 描述中,请附上本检查清单的副本,并标记已完成的规则。 请确保添加相关代码的链接,以加快评定流程。 --- url: /developers/core/integration-quality-scale/index.md --- import RuleOverview from './\_includes/rule\_overview.jsx' Integration quality scale 是 Home Assistant 根据用户体验、功能、代码质量和开发者体验对集成进行评级的框架。 为了进行评级,项目提出了一系列 tier,每个 tier 都有其特定含义。 ## 等级分级 共有 4 个 scaled tiers:bronze、silver、gold 和 platinum。 要达到某个 tier,集成必须满足该 tier 及其以下所有 tier 的全部规则。 这些 tier 定义如下。 ### 🥉 Bronze Bronze tier 是基准标准,也是所有新集成的要求。它满足代码质量、功能和用户体验方面的最低要求。它符合基本期望,为用户提供与设备和服务交互的可靠基础。 文档提供直接从 Home Assistant 用户界面设置集成的指南。 从技术角度来看,此集成已审查以符合所有基准标准,这是我们要求所有新集成遵守的标准,包括设置集成的自动化测试。 Bronze tier 具有以下特征: * 可以通过 UI 轻松设置。 * 源代码符合基本编码标准和开发准则。 * 保护此集成的自动化测试可以正确配置。 * 提供基本的最终用户文档,足以让用户轻松分步入门。 ### 🥈 Silver Silver tier 在 "Bronze" 级别的基础上提升了集成的可靠性和稳健性,确保稳定的运行时体验。它确保集成正确处理错误,例如当对设备或服务的认证失败时,处理离线设备以及其他错误。 这些集成的文档提供使用此集成时 Home Assistant 中可用的功能信息,以及出现问题时的故障排除信息。 此集成有一个或多个活跃的 code owners,帮助维护它以确保此级别上的体验现在和未来持续存在。 Silver tier 具有以下特征: * 提供 "Bronze" 的所有功能。 * 在各种条件下提供稳定的用户体验。 * 有一个或多个活跃的 code owners 帮助维护集成。 * 正确且自动地从连接错误或离线设备中恢复,不会填满日志文件,也不会产生不必要的消息。 * 如果与设备或服务的认证失败,自动触发重新认证。 * 提供有关集成功能的详细文档和问题故障排除说明。 ### 🥇 Gold 集成用户体验的金标准,为集成的设备和服务提供广泛而全面的支持。Gold-tier 集成旨在用户友好、功能齐全,并面向更广泛的受众。 在可能的情况下,设备会自动发现以实现轻松无缝的设置,并且它们的 firmware/software 可以直接从 Home Assistant 更新。 所有提供的设备和 entity 都有逻辑化的名称且完全可翻译,并且已正确分类并启用于长期统计使用。 这些集成的文档非常详细,主要面向最终用户且易于理解。除提供集成的一般信息外,文档还提供可能的示例用例、兼容设备列表、集成提供的已描述 entity 列表,以及集成提供的可用 actions 的广泛描述和使用示例。强烈建议结合示例 automations、dashboards、可用 Blueprints 以及指向额外外部资源的链接。 集成提供调试问题的手段,包括下载 diagnostic 信息和文档化的故障排除说明。如有需要,可以通过 UI 重新配置集成。 从技术角度来看,集成需要对其代码库具有完整的自动化测试覆盖,以确保当前和未来的集成质量得以保持。 所有在 Works with Home Assistant 项目中提供设备的集成至少需要达到此 tier。 Gold tier 具有以下特征: * 提供 "Silver" 的所有功能。 * 提供集成能够提供的最佳最终用户体验;流畅且直观。 * 可以被自动发现,简化集成设置。 * 集成可以被重新配置和调整。 * 支持 translations。 * 面向最终用户的详细文档。 * 在可能时支持通过 Home Assistant 更新设备的 software/firmware。 * 集成具有覆盖整个集成的自动化测试。 * Works with Home Assistant 项目中提供设备的集成的必需级别。 ### 🏆 Platinum Platinum 是集成可以达到的最高 tier,是 Home Assistant 中质量的典范。它不仅提供最佳的用户体验,还通过遵循最高标准、卓越的代码质量以及优化的性能和效率来实现技术卓越。 Platinum tier 具有以下特征: * 提供 "Gold" 的所有功能。 * 所有源代码遵循所有编码和 Home Assistant 集成标准及最佳实践,并通过类型注释和清晰的代码注释完全类型化,以提高代码清晰度和可维护性。 * 完全异步的集成代码库确保高效运行。 * 实现高效的数据处理,减少网络和 CPU 使用。 ### 跟踪已实现的规则 致力于达到更高 tier 或已有 tier 的集成,必须向其集成中添加 `quality_scale.yaml` 文件。 此文件的目的是跟踪已实现规则的进度,并跟踪被豁免的规则及豁免原因。 此文件的示例如下: ```yaml rules: config_flow: done docs_high_level_description: status: exempt comment: This integration does not connect to any device or service. ``` ### 调整集成的等级 Home Assistant 鼓励我们的贡献者将其集成提升到尽可能高的 tier,为我们的贡献者提供出色的编码体验,为用户带来最佳体验。 当集成达到某个 tier 的最低要求时,贡献者可以打开 pull request 来调整该集成的级别。 此请求需要附带每个 scale rule 的完整清单(包括所有较低 tier 的规则),证明其已满足这些要求。 清单可以在[此处](/developers/core/integration-quality-scale/checklist.md)找到。 Home Assistant core team 审查并批准后,集成将在 Home Assistant 的下一个 major release 中显示新的 tier。 除了将集成升级到更高的 tier 之外,集成也可能被降级到更低的 tier。 例如,当不再存在活跃的集成 code owner 时就会发生这种情况。 在此特定示例中,即使集成在其他方面完全符合 "Platinum" tier,它也将被降级为 "Bronze"。 无需创建文档 pull request。在集成的 tier 已在代码库中更新后,quality scale 将在 Home Assistant 的下一个 minor release 的文档中自动更新。 ### 对各等级中包含的规则的调整 IoT 世界以及 Home Assistant 使用的所有技术都在快速发展;不仅体现在 Home Assistant 可以支持或做的事情上,也体现在 Home Assistant 所基于的软件上。Home Assistant 正在以快速的速度在行业中引领技术。 这也意味着随着时间的推移会出现新的见解和新开发并采用的最佳实践,从而导致集成 quality scale 个别规则的新增和改进。 如果某个 tier 被调整,该 tier 中的所有集成都需要重新评估并相应调整。 :::info 一个例外是拥有属于 Works with Home Assistant 项目设备的集成。这些集成将被标记为沿用其现有 tier。 ::: ## 特殊等级 还有 4 个 special tiers,用于无法放入 scaled tier 列表的集成。 这是因为它们要么是 core 的内部组成部分,要么根本不在 core 中,要么不符合与 scaled tiers 相比评级的最低要求。 Special tiers 定义如下。 ### ❓ No score 这些集成可以通过 Home Assistant 用户界面设置。"No score" 并不表示它们差或有 bug,而是表示它们尚未根据 quality scale 进行评估,或者需要一些维护才能达到现在被视为最低的 "Bronze" 标准。 "No score" tier 不能分配给新集成,因为它们引入时至少需要达到 "Bronze" 级别。Home Assistant 项目鼓励社区帮助更新这些没有分数的集成,使其至少满足 "Bronze" 级别要求。 特征: * 尚未评分或缺乏足够的评分信息。 * 可以通过 UI 设置,但可能需要增强以获得更好的体验。 * 可能正常工作,但尚未根据当前标准进行验证。 * 文档通常只提供基本设置步骤。 ### 🏠 Internal 此 tier 分配给 Home Assistant 内部使用的集成。这些集成为 Home Assistant 的核心程序或其他集成在其之上构建提供基本组件和构建块。 Internal 集成由 Home Assistant 项目维护,并受严格的架构设计程序约束。 特征: * Home Assistant 核心程序的内部、内置构建块。 * 提供其他集成使用和在其之上构建的构建块。 * 由 Home Assistant 项目维护。 ### 💾 Legacy Legacy 集成是较旧的集成,已在 Home Assistant 中存留多年,可能从 inception 起就存在。它们只能通过 YAML 文件配置,并且往往缺乏活跃的维护者(code owners)。这些集成可能设置复杂,在使用和功能上不符合当前/现代最终用户的期望。 Home Assistant 项目鼓励社区帮助将这些集成迁移到 UI 并更新它们以符合现代标准,使这些集成对所有人可访问。 特征: * 设置过程复杂;只能通过 YAML 配置,没有基于 UI 的设置。 * 可能缺乏活跃的 code ownership 和维护。 * 可能缺少近期更新或 bug 修复。 * 文档可能仍面向开发者。 ### 📦 Custom Custom 集成由社区开发并发布,为 Home Assistant 提供额外的功能和设备与服务支持。这些集成不包含在官方的 Home Assistant 发布中,可以手动安装或通过第三方工具(如 HACS(Home Assistant Community Store))安装。 Home Assistant 项目不审查、安全审计、维护或支持第三方 custom 集成。鼓励用户在安装前谨慎行事,并审查 custom 集成的源代码和社区反馈。 鼓励并邀请开发者通过使 custom 集成与 integration quality scale 对齐并提交纳入请求,将其贡献给 Home Assistant 项目。 特征: * 不包含在官方的 Home Assistant 发布中。 * 可手动安装或通过社区工具(如 HACS)安装。 * 由个人开发者或社区成员维护。 * 用户体验可能差异很大。 * 功能、安全性和稳定性可能差异很大。 * 文档可能有限。 --- url: /developers/core/integration-quality-scale/rules.md --- import RuleOverview from './\_includes/rule\_overview.jsx' 每个 tier 的规则如下所述,并配有各自的页面,包含示例和更多信息。 ### 🥉 Bronze ### 🥈 Silver ### 🥇 Gold ### 🏆 Platinum --- url: /developers/core/integration-quality-scale/rules/action-exceptions.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 理由 执行 service action 时可能会出现意外情况。 当这种情况发生时,集成应引发异常以指示出了问题。 异常消息将显示在 UI 中给用户,可用于帮助诊断问题。 消息将从附加的 translation string 或异常参数中生成。 ## 示例实现 当问题由使用不当引起时(例如输入错误或引用不存在的内容),应引发 `ServiceValidationError`。 当问题由 service action 本身的错误引起时(例如网络错误或服务中的 bug),应引发 `HomeAssistantError`。 :::note 此规则不仅限于集成注册自定义 service actions。 平台操作(例如切换 `switch` 或打开 `light`)也适用于此规则,并在遇到失败时应引发异常。 ::: 在此示例中,我们展示了一个注册为 Home Assistant 中 service action 的函数。 如果输入不正确(当结束日期早于开始日期时),将引发 `ServiceValidationError`,如果无法连接到服务,则引发 `HomeAssistantError`。 ```python {8,12} showLineNumbers from homeassistant.exceptions import HomeAssistantError, ServiceValidationError async def async_set_schedule(call: ServiceCall) -> ServiceResponse: """Set the schedule for a day.""" start_date = call.data[ATTR_START_DATE] end_date = call.data[ATTR_END_DATE] if end_date < start_date: raise ServiceValidationError("End date must be after start date") try: await client.set_schedule(start_date, end_date) except MyConnectionError as err: raise HomeAssistantError("Could not connect to the schedule") from err ``` ## 附加资源 有关引发异常的更多信息,请参阅[文档](/developers/core/platform/raising_exceptions.md)。 ## 例外 此规则没有例外。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/action-setup.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 理由 集成可以向 Home Assistant 添加自己的 service actions。 过去,它们经常在 `async_setup_entry` 方法中注册,并在 `async_unload_entry` 方法中移除。 这导致 service actions 仅在存在已加载的 entry 时才可用。 这并不理想,因为这样我们无法验证用户使用这些 service actions 创建的 automations,因为可能存在 configuration entry 无法加载的情况。 我们更倾向于集成在 `async_setup` 方法中设置它们的 service actions。 这样,如果目标 configuration entry 未加载,我们可以让用户知道 service action 为什么不工作。 验证应在 service action 内部进行,如果输入无效应引发 `ServiceValidationError`。 ## 示例实现 以下是 service action 在 `async_setup` 方法中注册的代码片段。 在此示例中,service call 需要 configuration entry id 作为参数。 这用于首先获取 configuration entry,然后检查它是否已加载。 如果 configuration entry 不存在或找到的 configuration entry 未加载,我们将引发相关错误并显示给用户。 提供 description placeholders 以启用 service 参数的翻译,例如,引用需要独立于 service 描述进行本地化或更新的外部资源(如文档 URL)。 `__init__py`: ```python {13-20} showLineNumbers async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up my integration.""" async def async_get_schedule(call: ServiceCall) -> ServiceResponse: """Get the schedule for a specific range.""" if not (entry := hass.config_entries.async_get_entry(call.data[ATTR_CONFIG_ENTRY_ID])): raise ServiceValidationError("Entry not found") if entry.state is not ConfigEntryState.LOADED: raise ServiceValidationError("Entry not loaded") client = cast(MyConfigEntry, entry).runtime_data ... hass.services.async_register( DOMAIN, SERVICE_GET_SCHEDULE, async_get_schedule, schema=SERVICE_GET_SCHEDULE_SCHEMA, supports_response=SupportsResponse.ONLY, description_placeholders={"example_url": "https://schedule.example.com"} ) ``` ## 附加资源 有关如何设置 service actions 的更多信息,请参阅[service 文档](/developers/dev_101_services.md)。 ## 例外 此规则没有例外。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/appropriate-polling.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 理由 在理想世界中,所有集成都会使用基于推送的数据接口,即设备或服务会在有新数据时通知我们。 这样可以减少 Home Assistant 发出的请求数量。 然而,在现实世界中,许多设备和服务无法进行基于推送的通信,因此我们必须使用轮询。 为了负责任地进行轮询,我们应该设置一个适用于大多数用户的合适轮询间隔。 实际上并没有明确的定义来界定什么是合适的轮询间隔,因为它取决于被轮询的设备或服务。 例如,我们不应该每 5 秒轮询一次空气质量传感器,因为数据不会变化那么频繁。 在这些情况下,超过 99% 的用户都会接受一分钟或更长的轮询间隔。 再举一个例子,如果我们轮询一个云服务的太阳能板数据,而数据每小时更新一次。 每分钟轮询一次是没有意义的,因为两次轮询之间数据不会改变。 对于确实希望更频繁更新的用户,他们可以[定义自定义轮询间隔](https://www.home-assistant.io/common-tasks/general/#defining-a-custom-polling-interval) ## 示例实现 有两种方式设置轮询间隔。 使用哪种方式取决于集成如何轮询数据。 当使用 update coordinator 时,可以通过在 coordinator 中设置 `update_interval` 参数或属性来设置轮询间隔。 当使用内置的 entity update 方法时,通过设置 `should_poll` entity 属性为 `True`,可以在 platform 模块中设置 `SCAN_INTERVAL` 常量来设置轮询间隔。 `coordinator.py`: ```python {10} showLineNumbers class MyCoordinator(DataUpdateCoordinator[MyData]): """Class to manage fetching data.""" def __init__(self, hass: HomeAssistant) -> None: """Initialize coordinator.""" super().__init__( hass, logger=LOGGER, name=DOMAIN, update_interval=timedelta(minutes=1), ) ``` `sensor.py`: ```python {1} showLineNumbers SCAN_INTERVAL = timedelta(minutes=1) class MySensor(SensorEntity): """Representation of a Sensor.""" _attr_should_poll = True ``` ## 更多资源 关于轮询的更多信息,请参见[文档](/developers/integration_fetching_data.md)。 ## 例外 此规则没有例外。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/async-dependency.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 理由 Home Assistant 使用 asyncio 来高效处理任务。 为避免在 asyncio event loop 和其他线程之间切换上下文(这在性能上代价很高),理想情况下你的库也应使用 asyncio。 这不仅使系统更高效,代码也更加整洁。 ## 附加资源 有关如何创建库的更多信息,请参阅[文档](/developers/api_lib_index.md)。 ## 例外 此规则没有例外。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/brands.md --- ## 理由 品牌资源对于集成易于识别以及在所有集成中提供一致的外观和感觉非常重要。 项目在[brands 仓库](https://github.com/home-assistant/brands)中跟踪这些资源。 所需资源的要求可在 brands 仓库的 [readme](https://github.com/home-assistant/brands/blob/master/README.md) 中找到。 ## 例外 此规则没有例外。 --- url: /developers/core/integration-quality-scale/rules/common-modules.md --- ## 理由 Home Assistant 的代码库中有一些随时间积累而来的通用模式。 例如,大多数新集成都使用一个 coordinator 来集中处理数据获取。 coordinator 应放置在 `coordinator.py` 中。 这提高了集成之间的一致性,并更容易找到某个特定集成的 coordinator。 第二个通用模式是 base entity。 由于很多集成会提供多种类型的 entity,使用 base entity 可以有效减少代码重复。 base entity 应放置在 `entity.py` 中。 为提高集成之间一致性所做的努力,对代码库的质量和开发者体验都有积极影响。 ## 示例实现 在本示例中,我们有一个存储在 `coordinator.py` 中的 coordinator,以及一个存储在 `entity.py` 中的 base entity。 `coordinator.py` ```python showLineNumbers class MyCoordinator(DataUpdateCoordinator[MyData]): """Class to manage fetching data.""" def __init__(self, hass: HomeAssistant, client: MyClient) -> None: """Initialize coordinator.""" super().__init__( hass, logger=LOGGER, name=DOMAIN, update_interval=timedelta(minutes=1), ) self.client = client ``` `entity.py` ```python showLineNumbers class MyEntity(CoordinatorEntity[MyCoordinator]): """Base entity for MyIntegration.""" _attr_has_entity_name = True def __init__(self, coordinator: MyCoordinator) -> None: """Initialize the entity.""" super().__init__(coordinator) self._attr_device_info = ... ``` ## 例外 本规则没有例外。 --- url: /developers/core/integration-quality-scale/rules/config-entry-unloading.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 原因 集成应支持配置条目卸载。 这允许 Home Assistant 在运行时卸载集成,使用户能够在无需重启 Home Assistant 的情况下移除集成或重新加载它。 由于用户无需重启 Home Assistant 即可执行更多操作,这改善了用户体验。 ## 示例实现 在 `async_unload_entry` 接口函数中,集成应清理所有订阅,并关闭在集成设置期间打开的所有连接。 在此示例中,我们有一个监听器,存储在配置条目的 `runtime_data` 中,我们希望对其进行清理以避免内存泄漏。 `__init__.py`: ```python showLineNumbers async def async_unload_entry(hass: HomeAssistant, entry: MyConfigEntry) -> bool: """Unload a config entry.""" if (unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS)) entry.runtime_data.listener() return unload_ok ``` :::info 集成可以使用 `entry.async_on_unload` 注册回调函数,这些回调函数将在配置条目卸载或设置失败时被调用。 这对于无需自己跟踪清理方法来清理资源非常有用。 注册的回调函数将在以下情况下被调用: * `async_setup_entry` 抛出 `ConfigEntryError`、`ConfigEntryAuthFailed` 或 `ConfigEntryNotReady` * `async_unload_entry` 成功,即返回 True 且未抛出异常。 请注意,集成始终需要实现 `async_unload_entry` 以支持配置条目卸载,仅调用 `entry.async_on_unload` 是不够的。 ::: ## 更多资源 关于配置条目及其生命周期的更多信息,请参见[config entry 文档](/developers/config_entries_index.md)。 ## 例外 本规则没有例外。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/config-flow-test-coverage.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 理由 config flow 是用户与你的集成进行的第一次交互。 确保 config flow 按预期工作,使用户能够毫无问题地(或与 config flow 相关的错误地)完成集成设置,这一点非常重要。 这意味着我们希望对 config flow 达到 **100%** 的测试覆盖率。 在这些测试中,我们要求验证 flow 能够从错误中恢复,以确认即使用户遇到某些问题时也能顺利完成 flow。 为了让用户在使用其他集成 flow 时获得顺畅体验,本规则也适用于 reconfigure、reauthentication 和 options flow。 为集成编写测试的额外好处是,它可以引导开发者接触测试,使其更容易为集成的其他部分编写测试。 :::warning 尽管用于检查 config entry 唯一性的代码很可能会被 happy flow 测试触及,但仍请确保测试 flow 不允许添加超过一个唯一配置条目,以达到完整覆盖率。 ::: ## 示例实现 我们需要针对 config flow 可以被触发的每种方式(由用户触发、通过 discovery 触发或通过 import flow 触发)测试以下场景。 下面的示例展示了由用户发起的基本 happy flow。 `test_config_flow.py`: ```python showLineNumbers async def test_full_flow( hass: HomeAssistant, mock_my_client: AsyncMock, mock_setup_entry: AsyncMock, ) -> None: """Test full flow.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER}, ) assert result["type"] is FlowResultType.FORM assert result["step_id"] == "user" result = await hass.config_entries.flow.async_configure( result["flow_id"], {CONF_HOST: "10.0.0.131"}, ) assert result["type"] is FlowResultType.CREATE_ENTRY assert result["title"] == "My integration" assert result["data"] == { CONF_HOST: "10.0.0.131", } ``` ## 附加资源 关于 config flow 的更多信息,请参阅 [config flow 文档](/developers/core/integration/config_flow.md)。 关于集成测试的更多信息,请参阅 [测试文档](/developers/development_testing.md)。 ## 例外 本规则没有例外。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/config-flow.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 理由 自 2018 年推出以来,config flow 已成为在 Home Assistant 中设置集成的标准方式。 它们在各个集成中提供一致的用户体验,并提供一种引导用户完成设置过程的方式。 由于更好的用户体验,我们希望确保所有集成都能通过 config flow 设置。 由于这是用户开始使用集成的入口点,我们应该确保 config flow 非常用户友好且易于理解。 这意味着我们应该在合适的位置使用合适的 selectors,在需要的地方验证输入,并在 `strings.json` 中使用 `data_description` 来提供有关输入字段的上下文。 集成应将所有配置存储在 `ConfigEntry.data` 字段中,而所有连接不需要的设置应存储在 `ConfigEntry.options` 字段中。 ## 示例实现 要在集成中使用 config flow,你需要在集成文件夹中创建一个 `config_flow.py` 文件,并在 `manifest.json` 中将 `config_flow` 设置为 `true`。 config flow 中显示的文本在 `strings.json` 文件中定义。 `config_flow.py`: ```python class MyConfigFlow(ConfigFlow, domain=DOMAIN): """My config flow.""" async def async_step_user( self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Handle a flow initialized by the user.""" errors: dict[str, str] = {} if user_input: return self.async_create_entry( title="MyIntegration", data=user_input, ) return self.async_show_form( step_id="user", data_schema=vol.Schema({vol.Required(CONF_HOST): str}), errors=errors, ) ``` `strings.json`: ```json { "config": { "step": { "user": { "data": { "host": "Host" }, "data_description": { "host": "The hostname or IP address of the MyIntegration device." } } } } } ``` ## 附加资源 有关 config flows 的更多信息,请参阅[config flow 文档](/developers/core/integration/config_flow.md)。 有关 config flows 架构决策的更多信息,请参阅 [ADR-0010](https://github.com/home-assistant/architecture/blob/master/adr/0010-integration-configuration.md) ## 例外 在 [ADR-0010](https://github.com/home-assistant/architecture/blob/master/adr/0010-integration-configuration.md) 中豁免的集成不适用于此规则。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/dependency-transparency.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 原理说明 Home Assistant 的运行依赖大量第三方依赖项。 这些依赖项将随 Home Assistant 的新版本一起发布。 为了让项目能够信任这些依赖项,我们制定了一套依赖项应满足的要求。 * 该依赖项的源代码必须采用 OSI 批准的许可证发布。 * 该依赖项必须在 PyPI 上可用。 * 发布到 PyPI 的包应当由公开 CI 流水线构建并从中发布。 * PyPI 上发布的依赖项版本应对应一个开放在线仓库中的带标签(tagged)版本。 ## 例外情况 本规则没有例外。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/devices.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 原理说明 在 Home Assistant 中,设备(Devices)用于将实体(entities)分组,以表示单个物理设备或服务。 这非常有用,因为用户通常认为自己是在系统中添加一个设备或服务,而不是单个实体。 Home Assistant 将设备信息存储在设备注册表(device registry)中。 为了让用户获得最佳体验,设备的信息应尽可能完整。 ## 示例实现 在这个示例中,有一个传感器实体,它定义了自己在设备注册表中应被添加到哪个设备,同时还提供了该设备的一些元数据。 这将提供一个丰富的设备信息页面,用户可以根据设备名称、序列号及其他字段来识别设备。 `sensor.py`: ```python {8-18} showLineNumbers class MySensor(SensorEntity): """Representation of a sensor.""" _attr_has_entity_name = True def __init__(self, device: MyDevice) -> None: """Initialize the sensor.""" self._attr_device_info = DeviceInfo( connections={(CONNECTION_NETWORK_MAC, device.mac)}, name=device.name, serial_number=device.serial, hw_version=device.rev, sw_version=device.version, manufacturer="My Company", model="My Sensor", model_id="ABC-123", via_device=(DOMAIN, device.hub_id), ) ``` :::info 如果设备表示的是一个服务,请务必在 `DeviceInfo` 对象中添加 `entry_type=DeviceEntryType.SERVICE`,以将该设备标记为服务。 ::: ## 补充资料 更多有关设备的详细信息,请参阅 [device](/developers/device_registry_index.md) 文档。 ## 例外情况 本规则没有例外。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/diagnostics.md --- ## 理由 Diagnostics 是用户收集集成数据的便捷方式,在调试集成时可能很有用。 我们认为实现 diagnostics 是一项良好的实践。 需要注意的是,diagnostics 不应暴露任何敏感信息,例如密码、tokens 或坐标。 ## 示例实现 在以下示例中,我们提供了包含来自各种来源数据的 diagnostics,例如配置和集成的当前状态。 由于配置可能包含敏感信息,我们在返回 diagnostics 之前隐藏了敏感信息。 `diagnostics.py`: ```python showLineNumbers TO_REDACT = [ CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, ] async def async_get_config_entry_diagnostics( hass: HomeAssistant, entry: MyConfigEntry ) -> dict[str, Any]: """Return diagnostics for a config entry.""" return { "entry_data": async_redact_data(entry.data, TO_REDACT), "data": entry.runtime_data.data, } ``` ## 附加资源 要了解有关 diagnostics 的更多信息,请参阅[diagnostics 文档](/developers/core/integration/diagnostics.md)。 ## 例外 此规则没有例外。 --- url: /developers/core/integration-quality-scale/rules/discovery-update-info.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 原因 大多数终端用户的网络使用动态 IP 地址。 这意味着设备和服务可能会获得与首次设置时不同的 IP 地址。 为了避免需要用户将设备设置为静态 IP 地址(这并不总是可行的),集成应使用发现信息来更新设备或服务的网络信息。 只有在集成确定设备或服务与之前设置的是同一个时,才应更新设备或服务的 IP 地址。 ## 示例实现 在下面的示例中,我们有一个使用 mDNS 发现设备的集成。 每次启动 zeroconf 发现流程时,集成都会将流程的唯一 ID 设置为设备的序列号。 如果唯一 ID 已存在,当设备 IP 地址发生变化时将对其进行更新,然后流程将中止。 `manifest.json`: ```json { "zeroconf": ["_mydevice._tcp.local."] } ``` `config_flow.py`: ```python {14-15} showLineNumbers class MyConfigFlow(ConfigFlow, domain=DOMAIN): """My config flow.""" def __init__(self) -> None: """Initialize the config flow.""" self.data: dict[str, Any] = {} async def async_step_zeroconf( self, discovery_info: zeroconf.ZeroconfServiceInfo ) -> ConfigFlowResult: """Handle zeroconf discovery.""" self.data[CONF_HOST] = host = discovery_info.host await self.async_set_unique_id(discovery_info.properties["serialno"]) self._abort_if_unique_id_configured(updates={CONF_HOST: host}) client = MyClient(host) try: await client.get_data() except MyClientError: return self.async_abort(reason="cannot_connect") return await self.async_step_discovery_confirm() ``` :::info 如果你使用 DHCP 发现,并希望针对更新的 IP 地址接收发现流程,请务必在 device info 中注册 MAC 地址,并在 manifest 中将 `registered_devices` 设置为 `true`。 这将为这些设备创建设置流程。 ::: ## 更多资源 要了解有关配置流程的更多信息,请查阅[config flow 文档](/developers/core/integration/config_flow.md)。 要了解有关网络协议和发现的信息,请查阅[Networking and discovery 文档](/developers/network_discovery.md)。 ## 例外 本规则的例外情况是并非每个设备都可以被发现。 设备无法被发现的集成免于此规则。 --- url: /developers/core/integration-quality-scale/rules/discovery.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 原因 许多设备都具备被发现的能力。 这可以通过以下方法之一实现: * App(以前称为 add-ons) * [Bluetooth](/developers/creating_integration_manifest.md#bluetooth) * [DHCP](/developers/creating_integration_manifest.md#dhcp) * [HomeKit](/developers/creating_integration_manifest.md#homekit) * [mDNS](/developers/creating_integration_manifest.md#zeroconf) * [MQTT](/developers/creating_integration_manifest.md#mqtt) * [SSDP](/developers/creating_integration_manifest.md#ssdp) * [USB](/developers/creating_integration_manifest.md#usb) 这是一种让用户更容易找到和设置设备的好方法,因为用户无需手动查找应使用哪个集成,然后再输入 host。 这大大减少了设置设备所需的工作量,从而改善了用户体验。 使用基于网络的设置方式,还允许在设备获得新 IP 地址时更新集成的配置。 ## 示例实现 在下面的示例中,集成可以通过 mDNS 被发现。 设备通过提供 `_mydevice._tcp.local.` 服务来使自己可被发现。 Home Assistant 将捕获此信息并为用户启动发现流程。 用户随后可以确认发现结果并设置集成。 `manifest.json`: ```json {2} showLineNumbers { "zeroconf": ["_mydevice._tcp.local."] } ``` `config_flow.py`: ```python {8-23,25-36} showLineNumbers class MyConfigFlow(ConfigFlow, domain=DOMAIN): """My config flow.""" def __init__(self) -> None: """Initialize the config flow.""" self.data: dict[str, Any] = {} async def async_step_zeroconf( self, discovery_info: zeroconf.ZeroconfServiceInfo ) -> ConfigFlowResult: """Handle zeroconf discovery.""" self.data[CONF_HOST] = host = discovery_info.host await self.async_set_unique_id(discovery_info.properties["serialno"]) self._abort_if_unique_id_configured(updates={CONF_HOST: host}) client = MyClient(host) try: await client.get_data() except MyClientError: return self.async_abort(reason="cannot_connect") return await self.async_step_discovery_confirm() async def async_step_discovery_confirm( self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Confirm discovery.""" if user_input is not None: return self.async_create_entry( title="MyIntegration", data={CONF_HOST: self.data[CONF_HOST]}, ) self._set_confirm_only() return self.async_show_form(step_id="discovery_confirm") async def async_step_user( self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Handle a flow initialized by the user.""" errors: dict[str, str] = {} if user_input: client = MyClient(user_input[CONF_HOST]) try: serial_number = await client.check_connection() except MyException as exception: errors["base"] = "cannot_connect" else: await self.async_set_unique_id( serial_number, raise_on_progress=False ) self._abort_if_unique_id_configured() return self.async_create_entry( title="MyIntegration", data=user_input, ) return self.async_show_form( step_id="user", data_schema=vol.Schema( { vol.Required(CONF_HOST): TextSelector(), } ), errors=errors, ) ``` ## 更多资源 要了解有关配置流程的更多信息,请查阅[config flow 文档](/developers/core/integration/config_flow.md)。 要了解有关网络协议发现的信息,请查阅[Networking and discovery 文档](/developers/network_discovery.md)。 要了解有关蓝牙设备发现的信息,请查阅[Bluetooth 文档](/developers/bluetooth.md)。 要了解有关在 manifest 中指定不同发现方法的信息,请查阅[Integration Manifest 文档](/developers/creating_integration_manifest.md)。 ## 例外 本规则的例外情况是并非每个设备都可以被发现。 设备无法被发现的集成免于此规则。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/docs-actions.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 理由 集成可以注册 service action,以提供标准 entity 无法实现的功能。 这些 service action 可能比标准 service action 更难以使用,因此我们希望确保文档描述了它们的作用以及相关参数。 ## 示例实现 ```markdown showLineNumbers ## 操作 该集成提供以下 action。 ### Action:获取日程 `my_integration.get_schedule` service 用于从集成获取日程。 - **Data 属性**:`config_entry_id` - **说明**:要获取日程的 config entry 的 ID。 - **可选**:否 ``` ## 例外 本规则没有例外。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/docs-conditions.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 理由 集成可以注册 condition,以提供触发自动化(automation)的额外方式。 这些 condition 可能比标准 condition 更难以使用,因此我们希望确保文档描述了它们的作用以及相关参数。 为避免集成文档显得杂乱,我们希望为每个 condition 设置单独的页面,并从集成文档中链接到该页面。 每个 condition 页面应包含该 condition 的作用说明、可用参数列表,以及通过 UI 和 YAML 使用该 condition 的概述。 ## 示例实现 ```markdown showLineNumbers --- title: "检测到一氧化碳" condition: air_quality.is_co_detected domain: air_quality description: "测试是否有一个或多个一氧化碳传感器正在检测一氧化碳。" related_conditions: - air_quality.is_co_cleared - air_quality.is_co_value --- **检测到一氧化碳** 条件在一个或多个一氧化碳传感器主动检测到一氧化碳(CO)时通过。由于一氧化碳无色无味,传感器是确认其存在的唯一途径。将本条件添加到自动化中,可确保安全措施(如触发警报、启动通风或发送紧急通知)仅在危险被确认时才执行。这能避免传感器短暂闪烁引发的误报,并将响应聚焦于真实威胁。 {% include conditions/ui_header.md %} 要在自动化中使用此条件: 1. 前往 {% my automations title="**设置** > **自动化与场景**" %}。 2. 打开现有自动化,或选择 **创建自动化** > **创建新自动化**。 3. 在 **And if** 部分,选择 **添加条件**。 4. 选择你要检查的内容。在 **按目标**(见 [Targets](#targets))下,选择一氧化碳传感器所在的区域(如厨房或车库)。你也可以选择楼层、设备、具体 entity 或 label。 5. 在该目标显示的条件中,选择 **检测到一氧化碳**。 6. 在 **条件通过条件**(见 [Behavior](#behavior-with-multiple-targets))下,选择 **任一** 或 **全部**,以控制在针对多个传感器时检查的行为。 7. 选择 **保存**。 ### UI 中的选项 {% options_ui %} 条件通过条件: description: 当针对多个传感器时,控制结果如何组合。选择 **任一** 在至少一个目标传感器检测到大一氧化碳时通过,或选择 **全部** 仅在每个目标传感器都检测到大一氧化碳时通过。 {% endoptions_ui %} {% include conditions/yaml_header.md %} 在 YAML 中,将此条件引用为 `air_quality.is_co_detected`。一个基本示例如下: {% example %} condition: | condition: air_quality.is_co_detected target: entity_id: binary_sensor.hallway_co {% endexample %} 当走廊一氧化碳传感器当前正在检测 CO 时,此条件通过。 ### YAML 中的选项 YAML 有时为更复杂的用例提供 UI 中不可用的额外选项。 {% options_yaml %} behavior: description: > 当针对多个传感器时,控制结果如何组合。接受 `all` 或 `any`。 required: true type: string default: any {% endoptions_yaml %} {% include conditions/targets.md %} {% include conditions/behavior.md %} ## 小贴士 - 不可用(`unavailable`)或状态未知(`unknown`)的传感器不算作检测到。使用 **任一** 行为时,它们会被跳过。使用 **全部** 行为时,如果每个目标传感器都不可用,则该条件失败。 - 要检查是否不再检测到大一氧化碳,请使用 [大一氧化碳已清除](/conditions/air_quality.is_co_cleared/)。 - 要检查实际 CO 浓度而非仅仅二元检测结果,请使用 [大一氧化碳数值](/conditions/air_quality.is_co_value/)。 {% include conditions/try_it.md %} {% include conditions/more_examples.md %} ### 自动化:在 CO 事件期间有人到家时提醒家人 如果家人外出期间室内 CO 积聚,第一个回家的人需要在进门之前收到警告。此自动化在有人进入家 zone 时触发,并检查走廊 CO 传感器是否仍在检测大一氧化碳。如果是,则发送紧急通知提醒他们待在室外并拨打紧急电话。 - **触发器**:进入 Zone - **目标**:Frenck(`person.frenck`) - **Zone**:Home(`zone.home`) - **条件**:检测到一氧化碳 - **目标**:走廊 CO 传感器 - **条件通过条件**:任一 - **动作**:发送通知消息 - **目标**:My Device(`notify.my_device`) {% details "到家时 CO 警告的 YAML 示例" %} {% example %} automation: | alias: "CO warning on arrival home" triggers: - trigger: zone.entered target: entity_id: person.frenck options: zone: zone.home conditions: - condition: air_quality.is_co_detected target: entity_id: binary_sensor.hallway_co options: behavior: any actions: - action: notify.send_message target: entity_id: notify.my_device data: title: "Carbon monoxide detected at home" message: > The hallway CO sensor is detecting carbon monoxide. Stay outside and call emergency services. {% endexample %} {% enddetails %} {% include conditions/stuck.md %} {% include conditions/related.md %} ``` ## 例外 本规则没有例外。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/docs-configuration-parameters.md --- ## 原理说明 集成可以提供 options flow,允许用户更改集成的配置。 本规则确保所有配置选项都被文档化,以便用户了解每个选项的作用以及如何使用它。 ## 示例实现 以下示例针对一个具有多个配置选项、使用 `configuration_basic` 标签的集成。 ```markdown showLineNumbers {% include integrations/option_flow.md %} {% configuration_basic %} 国家代码: description: 您可以指定显示在摄像头中的国家代码(NL 或 BE)。 时间范围: description: 降水预测传感器向前查看的分钟数(最小 5,最大 120)。 {% endconfiguration_basic %} ``` ## 例外情况 本规则没有例外。 --- url: /developers/core/integration-quality-scale/rules/docs-data-update.md --- ## 原理说明 为了让用户了解集成的工作原理,我们应描述集成的数据是如何更新的。 这将帮助用户对集成在其使用场景下的表现建立预期。 例如,一个每 5 分钟才轮询一次的运动传感器,其可用性低于一个主动推送更新(push)的运动传感器。 由于用户可以为轮询型集成定义自己的轮询间隔,我们应说明当前的轮询速率,并描述任何限制。 例如,如果我们要连接的设备在处理过多请求时存在已知问题,我们应在文档中加以说明。 ## 示例实现 ```markdown showLineNumbers ## 数据更新 我的集成默认每 5 分钟从设备获取一次数据。 较新的设备(运行 MyOS 的设备)支持推送数据。 在集成启动时,我们会尝试启用该功能;如果失败,则回退到 {% term polling %}。 ``` ## 例外情况 本规则没有例外。 --- url: /developers/core/integration-quality-scale/rules/docs-examples.md --- ## 原理说明 为了展示集成如何使用,请提供一组有限的 blueprint,其中包含常见或实用的示例。 这将帮助用户更快、更容易地开始使用集成。 请将 blueprint 上传到 [`https://github.com/home-assistant/home-assistant.io/tree/current/source/blueprints/integrations`](https://github.com/home-assistant/home-assistant.io/tree/current/source/blueprints/integrations) 下的 blueprints 文件夹,或上传到 [论坛的 blueprint exchange](https://community.home-assistant.io/c/blueprints-exchange)。在集成页面上添加指向该 blueprint 的链接。 请不要将文档页面作为 blueprint 文件夹或 blueprint exchange 的集合或替代品。 ## 示例实现 ```markdown showLineNumbers ## 示例 ### 夜间关闭 LED 设备上的状态 LED 可能比较亮。 为了解决这一问题,您可以使用这个 blueprint 轻松实现日落后自动关闭 LED。 link to blueprint ``` ## 例外情况 本规则没有例外。 --- url: /developers/core/integration-quality-scale/rules/docs-high-level-description.md --- ## 原理说明 集成的用户文档应提供对集成品牌、产品或服务的高级描述。 这些信息可能有助于用户判断集成是否适合他们及其使用场景。 如果可能的话,文档还应包含指向品牌、产品或服务网站的链接,以便用户获取更多详细信息。 ## 示例实现 ```markdown showLineNumbers **my integration** {% term integration %} 用于与 [MyCompany](https://www.mycompany.com) 的设备进行集成。 该公司生产各种智能家居电器和设备,以其 MyProduct 而闻名。 ``` ## 例外情况 不与设备或服务集成的集成(如内部集成)无法包含对设备或服务的描述,因此不受此规则约束。 --- url: /developers/core/integration-quality-scale/rules/docs-installation-instructions.md --- ## 原理说明 我们希望用户在设置集成时获得流畅的体验。 这意味着文档应提供清晰简洁的安装说明。 这包括安装集成所需的所有先决条件。 ## 示例实现 ```markdown showLineNumbers ## 先决条件 1. 打开应用商店并安装 **MyProduct** 应用。 2. 创建账号。 3. 在应用中添加一个设备。 4. 打开应用并进入 **Settings** 页面。 5. 选择 **Expose API**。 {% include integrations/config_flow.md %} ``` ## 例外情况 本规则没有例外。 --- url: /developers/core/integration-quality-scale/rules/docs-installation-parameters.md --- ## 原理说明 在设置集成时,没有什么比不知道需要填写哪些信息更令人沮丧了。 为了提升用户体验,文档应描述安装过程中所需的所有参数。 这将帮助用户在开始安装过程之前收集好所有必要的信息。 ## 示例实现 如果集成通过 config flow 使用: ```markdown showLineNumbers {% configuration_basic %} Host: description: "您的 bridge 的 IP 地址。您可以在路由器中找到,或在集成应用的 **Bridge Settings** > **Local API** 下找到。" Local access token: description: "您的 bridge 的本地访问令牌。您可以在集成应用的 **Bridge Settings** > **Local API** 下找到。" {% endconfiguration_basic %} ``` 如果集成通过 `configuration.yaml` 中的 YAML 设置: ```markdown showLineNumbers {% configuration %} Host: description: "您的 bridge 的 IP 地址。您可以在路由器中找到,或在集成应用的 **Bridge Settings** -> **Local API** 下找到。" required: false type: string Local access token: description: "您的 bridge 的本地访问令牌。您可以在集成应用的 **Bridge Settings** -> **Local API** 下找到。" required: false type: string {% endconfiguration %} ``` ## 例外情况 本规则没有例外。 --- url: /developers/core/integration-quality-scale/rules/docs-known-limitations.md --- ## 理由 在文档中描述集成的已知限制,可以让用户了解对集成的预期表现。 我们应避免记录 bug,因为我们使用 GitHub 的 issue tracker 来处理它们,并且不希望重复信息。 ## 示例实现 ```markdown showLineNumbers ## 已知限制 该集成不提供重启功能,此操作可通过制造商的应用来完成。 ``` ## 例外 本规则没有例外。 --- url: /developers/core/integration-quality-scale/rules/docs-removal-instructions.md --- ## 理由 从 Home Assistant 中移除设备或服务并不总是很简单。 文档应提供有关如何移除设备或服务的清晰说明。 ## 示例实现 ```markdown showLineNumbers ## 移除集成 此集成遵循标准的集成移除方式。无需额外步骤。 {% include integrations/remove_device_service.md %} 删除集成后,请前往制造商的应用,并从中移除 Home Assistant 集成。 ``` ## 例外 本规则没有例外。 --- url: /developers/core/integration-quality-scale/rules/docs-supported-devices.md --- ## 原理说明 许多 Home Assistant 用户会根据 Home Assistant 是否支持来决定购买哪些设备。 为了让用户更容易确认某设备是否受支持,文档应描述已知支持或不支持的设备。 这将减少用户尝试设置设备时才得知设备不受支持所带来的糟糕体验。 ## 示例实现 ```markdown showLineNumbers ## 支持的设备 以下设备已知受该集成支持: - Device 1 - Device 2 - 所有运行 MyOS 的设备 ## 不支持的设备 以下设备不受该集成支持: - Device 3 - 2010 年之前生产的设备 ``` ## 例外情况 本规则不适用于不连接设备或服务的集成。 本规则也不适用于不集成物理设备的集成。 --- url: /developers/core/integration-quality-scale/rules/docs-supported-functions.md --- ## 原理说明 用户应能够了解该集成将为他们(计划购买的)设备带来什么价值。 这将有助于建立用户的预期。 例如,如果用户正在寻找一款新冰箱,我们应清楚地说明他们能从该集成中获得什么。 如果集成仅支持查看门是开还是关,而用户却期望能看到冰箱温度,那他们将会失望。 ## 示例实现 按实体类型排序的示例: ```markdown showLineNumbers ## 支持的功能 ### 实体 XY 集成提供以下实体。 #### 按钮 - **Start backflush** - **描述**:启动机器的回冲过程。激活后您有 15 秒时间拨动手柄。 - **适用机器**:所有 #### 数字 - **Dose** - **描述**:每个按键的剂量(以刻度为单位) - **适用机器**:GS3 AV、Linea Mini - **备注**:GS3 会多次出现此项,每个物理按键(1-4)各一次,且这些实体默认为禁用状态。 #### 传感器 - **Current coffee temperature** - **描述**:咖啡锅炉的当前温度。 - **适用机器**:所有 - **备注**:当机器达到温度时,由于测量点不同,该值将比 `Coffee target temperature` 高约 3 度。 - **Current steam temperature** - **描述**:蒸汽锅炉的当前温度。 - **适用机器**:Linea Micra、GS3 AV、GS3 MP - **备注**:- #### 更新 - **Gateway firmware** - **描述**:网关的固件状态。 - **适用机器**:所有 #### 选择器 - **Prebrew/-infusion mode** - **描述**:是否使用 prebrew、preinfusion,或都不使用。 - **选项**:Disabled、Prebrew、Preinfusion - **适用机器**:Linea Micra、Linea Mini、GS3 AV - **Steam level** - **描述**:蒸汽锅炉应运行的档位。 - **选项**:1、2、3 - **适用机器**:Linea Micra ``` 按设备排序的示例: ```markdown ## 支持的功能 ### XYZ 产品名空气净化器、空气加湿器和落地扇 #### 传感器 - **Filter lifetime remaining**:滤网剩余寿命(以年为单位)。默认为启用状态。 - **Purify volume**:已净化空气的体积(以立方米为单位)。默认为禁用状态。 #### 数字 - **Favorite level**:设置偏好档位。可能的取值为 0 到 10。`0` 表示关闭。 - **Volume**:设置音量。以百分比表示。`0%` 表示关闭。 ``` ## 例外情况 本规则没有例外。 --- url: /developers/core/integration-quality-scale/rules/docs-triggers.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 理由 集成可以注册 trigger,以提供触发自动化(automation)的额外方式。 这些 trigger 可能比标准 trigger 更难以使用,因此我们希望确保文档描述了它们的作用以及相关参数。 为避免集成文档显得杂乱,我们希望为每个 trigger 设置单独的页面,并从集成文档中链接到该页面。 每个 trigger 页面应包含该 trigger 的作用说明、可用参数列表,以及通过 UI 和 YAML 使用该 trigger 的概述。 ## 示例实现 ```markdown showLineNumbers --- title: "二氧化碳水平发生变化" trigger: air_quality.co2_changed domain: air_quality description: "当一个或多个二氧化碳水平发生变化时触发。" related_triggers: - air_quality.co2_crossed_threshold --- **二氧化碳水平发生变化** trigger 在一个或多个空气质量传感器的二氧化碳(CO2)读数发生显著变化后触发。二氧化碳会在有人居住的房间中由于呼吸、烹饪和取暖而自然积聚。晚上关着门的卧室或午餐后人员密集的会议室,都是 CO2 悄悄上升而不被察觉的典型场所。CO2 升高是最明显的室内空气需要新鲜的信号之一。 想象一下:卧室通风风扇在深夜自动启动,因为 CO2 在你睡觉时升高了,所以你醒来时神清气爽而不是昏沉。使用此 trigger 来自动通风、记录室内空气质量趋势,或在 CO2 发生明显变化时提醒家庭成员打开窗户。 {% include triggers/ui_header.md %} 要在自动化中使用此 trigger: 1. 前往 {% my automations title="**设置** > **自动化与场景**" %}。 2. 打开现有自动化,或选择 **创建自动化** > **创建新自动化**。 3. 在 **When** 部分,选择 **添加触发器**。 4. 选择你要监控的内容。在 **按目标**(见 [Targets](#targets))下,选择 CO2 传感器所在的区域(如客厅或卧室)。你也可以选择楼层、设备、具体 entity 或 label。 5. 在该目标显示的 trigger 中,选择 **二氧化碳水平发生变化**。 6. 在 **阈值类型** 下,设置水平变化多少才触发该 trigger。 7. 选择 **保存**。 ### UI 中的选项 {% options_ui %} 阈值类型: description: 二氧化碳水平需要变化多少才会触发该 trigger。可以是固定数值,也可以引用提供该值的 helper entity。 {% endoptions_ui %} {% include triggers/yaml_header.md %} 在 YAML 中,将此 trigger 引用为 `air_quality.co2_changed`。一个基本示例如下: {% example %} trigger: | trigger: air_quality.co2_changed target: entity_id: sensor.bedroom_co2 options: threshold: 50 {% endexample %} 每当卧室 CO2 传感器读数变化至少 50 ppm 时,就会触发此 trigger。 ### YAML 中的选项 YAML 有时为更复杂的用例提供 UI 中不可用的额外选项。 {% options_yaml %} threshold: description: > 二氧化碳水平触发前必须变化的最小量。接受一个数值,或对 `input_number`、`number` 或 `sensor` entity 的引用。 required: true type: any {% endoptions_yaml %} {% include triggers/targets.md %} ## 小贴士 - 室内 CO2 水平通常在约 400 ppm(通风良好)到超过 1,000 ppm(闷热的房间)之间。50 到 100 ppm 的阈值适用于大多数通风自动化。 - 只要变化达到阈值,无论水平上升还是下降,都会触发该 trigger。 - 如果只想在 CO2 朝一个方向越过特定水平时作出响应,请使用 [二氧化碳水平越过阈值](/triggers/air_quality.co2_crossed_threshold/)。 {% include triggers/try_it.md %} {% include triggers/more_examples.md %} ### 自动化:卧室 CO2 升高时启动通风 在密闭的卧室中睡觉会令 CO2 在夜间积聚,让你早上醒来时昏沉。此自动化在 CO2 水平发生显著变化时启动卧室通风风扇,保持空气新鲜,让你醒来时精力充沛。 - **Trigger**:二氧化碳水平发生变化 - **目标**:卧室 CO2 传感器 - **阈值类型**:100 - **动作**:打开风扇 {% details "基于 CO2 的卧室通风 YAML 示例" %} {% example %} automation: | alias: "Ventilate bedroom on CO2 change" triggers: - trigger: air_quality.co2_changed target: entity_id: sensor.bedroom_co2 options: threshold: 100 actions: - action: fan.turn_on target: entity_id: fan.bedroom_ventilation {% endexample %} {% enddetails %} {% include triggers/stuck.md %} {% include triggers/related.md %} ``` ## 例外 本规则没有例外。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/docs-troubleshooting.md --- ## 理由 我们应提供解决常见问题的说明。 在可能的情况下,故障排除主题应包含症状描述以及解决问题所需的步骤。 这能减少支持请求的数量,并改善用户体验。 ## 示例实现 ```markdown showLineNumbers ## 故障排除 ### 无法设置设备 #### 症状:"无法访问此设备" 在尝试设置集成时,表单显示消息"无法访问此设备"。 ##### 说明 这意味着设备的设置不正确,因为设备需要启用本地通信功能。 ##### 解决方法 要解决此问题,请尝试以下步骤: 1. 确保设备已上电(LED 亮起)。 2. 确保设备已连接到互联网: - 确保制造商的应用能够看到该设备。 3. 确保设备已启用本地通信: - 检查设备的设置。 - 检查设备的用户手册。 ... ### 我看不到我的设备 请确保设备可通过制造商的应用看到并控制。 如果不能,请检查设备的电源和网络连接。 ### 设备一天后变为不可用 请确保你已关闭设备的省电模式。 ``` ## 例外 本规则没有例外。 --- url: /developers/core/integration-quality-scale/rules/docs-use-cases.md --- ## 原理说明 有时候,看到某个设备或服务被集成到 Home Assistant 中,你会不禁想:"我为什么要集成这个?" 对于一些集成,其预期用途和好处比其他集成更为明显。 文档中的使用场景示例可以展示集成的价值。 ## 示例实现 ```markdown showLineNumbers MyCompany 的运动检测设备便宜且实用。 将它与他们的其他设备结合使用时,您可以实现 x。 ``` ## 例外情况 本规则没有例外。 --- url: /developers/core/integration-quality-scale/rules/dynamic-devices.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 理由 正如规则 [stale-devices](/developers/core/integration-quality-scale/rules/stale-devices.md) 所解释的,当我们可以确定设备不再连接时,设备应被自动移除。 本规则解释的是另一面:一旦新设备连接,我们应该自动为该设备创建相应的 entity。 这能改善用户体验,因为用户只需将设备添加到集成中,它就会自动出现在 Home Assistant 中。 ## 示例实现 在下面的示例中,我们使用 coordinator 从服务获取所有数据。 每次更新时,`_check_device` 都会检查是否有需要创建 entity 的新设备,并将它们添加到 Home Assistant。 `coordinator.py` ```python showLineNumbers class MyCoordinator(DataUpdateCoordinator[dict[str, MyDevice]]): """Class to manage fetching data.""" def __init__(self, hass: HomeAssistant, client: MyClient) -> None: """Initialize coordinator.""" super().__init__( hass, logger=LOGGER, name=DOMAIN, update_interval=timedelta(minutes=1), ) self.client = client async def _async_update_data(self) -> dict[str, MyDevice]: try: return await self.client.get_data() except MyException as ex: raise UpdateFailed(f"The service is unavailable: {ex}") ``` `sensor.py` ```python {9,11-16,18-21} showLineNumbers async def async_setup_entry( hass: HomeAssistant, entry: MyConfigEntry, async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up My integration from a config entry.""" coordinator = entry.runtime_data known_devices: set[str] = set() def _check_device() -> None: current_devices = set(coordinator.data) new_devices = current_devices - known_devices if new_devices: known_devices.update(new_devices) async_add_entities([MySensor(coordinator, device_id) for device_id in new_devices]) _check_device() entry.async_on_unload( coordinator.async_add_listener(_check_device) ) ``` ## 例外 本规则没有例外。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/entity-category.md --- ## 理由 entity 应分配适当的 EntityCategory,以确保在默认 category 不适当时,它们能被正确分类并容易被识别。 entity category 用于例如自动生成的 dashboard。 ## 示例实现 在本示例中,我们有一个返回诊断值的 sensor。 `sensor.py` ```python {4} showLineNumbers class MySensor(SensorEntity): """Representation of a sensor.""" _attr_entity_category = EntityCategory.DIAGNOSTIC def __init__(self, ...) -> None: ``` ## 附加资源 要了解有关 registry properties 的更多信息,请参阅[文档](/developers/core/entity.md#registry-properties)。 ## 例外 本规则没有例外。 --- url: /developers/core/integration-quality-scale/rules/entity-device-class.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 原理说明 Device class 是一种为实体提供上下文的方式。 Home Assistant 出于多种目的使用 device class: * 允许用户切换到设备提供的测量单位以外的其他单位。 * 用于语音控制,以提出诸如"客厅温度是多少?"之类的问题。 * 用于将实体暴露给 Google Assistant 和 Amazon Alexa 等基于云的系统生态。 * 用于调整 Home Assistant UI 中的显示方式。 * 可用于设置实体的默认名称,以减轻译者的负担。 出于这些原因,尽可能使用 device class 非常重要。 ## 示例实现 在下面的示例中,我们有一个温度传感器,它使用了 device class `temperature`。 该实体的名称将是 `My device temperature`。 `sensor.py` ```python {5} showLineNumbers class MyTemperatureSensor(SensorEntity): """Representation of a sensor.""" _attr_has_entity_name = True _attr_device_class = SensorDeviceClass.TEMPERATURE def __init__(self, device: Device) -> None: """Initialize the sensor.""" self._attr_device_info = DeviceInfo( identifiers={(DOMAIN, device.id)}, name="My device", ) ``` ## 补充资料 可用 device class 的列表可在 [entity](/developers/core/entity.md) 页面下的实体页面中找到。 更多有关实体命名的信息可在 [entity](/developers/core/entity.md#has_entity_name-true-mandatory-for-new-integrations) 文档中找到。 ## 例外情况 本规则没有例外。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/entity-disabled-by-default.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 理由 Home Assistant 会跟踪 entity 状态的变化。 这样做是为了能够在 UI 中显示 entity 的历史记录。 每一个被跟踪的状态都会占用一定的资源。 频繁改变状态的 entity(嘈杂的 entity)比较少改变状态的 entity 更频繁地进行此操作。 我们认为,默认禁用不常用或嘈杂的 entity 是一种良好实践。 如果用户对此类 entity 有使用场景,他们可以自行启用。 这样,对于没有使用场景的用户来说,就不必承担跟踪 entity 状态的成本。 关于什么算作常用 entity 并没有硬性规则,因为这取决于集成和设备。 例如,一个蓝牙温度传感器可以有一个表示设备信号强度的 entity。 对于大多数用户来说,这个 entity 并不是很有用,因此应该默认禁用。 而如果有一个提供设备来测量信号强度的集成,那么这个 entity 对大多数用户是有用的,应该默认启用。 ## 示例实现 在下面的示例中,entity 默认被禁用。 `sensor.py` ```python {8} showLineNumbers class MySignalStrengthSensor(SensorEntity): """Representation of a sensor.""" _attr_has_entity_name = True _attr_entity_category = EntityCategory.DIAGNOSTIC _attr_device_class = SensorDeviceClass.SIGNAL_STRENGTH _attr_native_unit_of_measurement = SIGNAL_STRENGTH_DECIBELS_MILLIWATT _attr_entity_registry_enabled_default = False def __init__(self, device: Device) -> None: """Initialize the sensor.""" ... ``` ## 附加资源 要了解有关 entity registry properties 的更多信息,请参阅[文档](/developers/core/entity.md#registry-properties)。 ## 例外 本规则没有例外。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/entity-event-setup.md --- ## 理由 entity 可能需要订阅事件,例如来自集成库的事件,并在新事件到来时更新状态。 为了正确地做到这一点,entity 应该在 entity 方法 `async_added_to_hass` 中订阅并注册 update callback。 此 entity 方法在 entity 被 entity platform helper 注册后调用,此时 entity 将拥有所有可调用接口,如 `self.hass` 和 `self.async_write_ha_state`。 在此阶段之前注册 update callback 会导致错误,例如 callback 尝试访问 `self.hass` 或写入状态更新时。 为避免内存泄漏,entity 应该在 entity 方法 `async_will_remove_from_hass` 中取消订阅事件,即注销 update callback。 ## 示例实现 在下面的示例中,`self.client.events.subscribe` 返回一个函数,调用该函数即可取消实体对事件的订阅。 因此,我们在 `async_added_to_hass` 中订阅事件,在 `async_will_remove_from_hass` 中取消订阅。 `sensor.py` ```python {10-13,15-19} showLineNumbers class MySensor(SensorEntity): """Representation of a sensor.""" unsubscribe: Callable[[], None] | None = None def __init__(self, client: MyClient) -> None: """Initialize the sensor.""" self.client = client async def async_added_to_hass(self) -> None: """Subscribe to the events.""" await super().async_added_to_hass() self.unsubscribe = self.client.events.subscribe("my_event", self._handle_event) async def async_will_remove_from_hass(self) -> None: """Unsubscribe from the events.""" if self.unsubscribe: self.unsubscribe() await super().async_will_remove_from_hass() async def _handle_event(self, event: Event) -> None: """Handle the event.""" ... self.async_write_ha_state() ``` :::info 上述示例可以使用 lifecycle 函数进行简化。 这样就不需要在 entity 中存储 callback 函数。 ```python showLineNumbers async def async_added_to_hass(self) -> None: """Subscribe to the events.""" await super().async_added_to_hass() self.async_on_remove( self.client.events.subscribe("my_event", self._handle_event) ) ``` ::: ## 例外 本规则没有例外。 --- url: /developers/core/integration-quality-scale/rules/entity-translations.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 理由 Home Assistant 被世界各地的人们使用。 为了让非英语用户也能更轻松地使用 Home Assistant,entity 具有翻译后的名称非常重要。 这能帮助用户更容易理解 entity 的含义。 ## 示例实现 在本示例中,sensor 的英文名称为 "Phase voltage"。 结合设备名称,此 entity 会将自己命名为 "My device Phase voltage"。 `sensor.py`: ```python {5} showLineNumbers class MySensor(SensorEntity): """Representation of a sensor.""" _attr_has_entity_name = True _attr_translation_key = "phase_voltage" def __init__(self, device_id: str) -> None: """Initialize the sensor.""" self._attr_device_info = DeviceInfo( identifiers={(DOMAIN, device_id)}, name="My device", ) ``` `strings.json`: ```json {5} showLineNumbers { "entity": { "sensor": { "phase_voltage": { "name": "Phase voltage" } } } } ``` :::info 如果 entity 的 platform 是 `binary_sensor`、`number`、`sensor` 或 `update`,并且设置了 device class,而你希望 entity 使用与 device class 相同的名称,则可以省略 translation key,因为此时 entity 将自动使用 device class 名称。 ::: ## 附加资源 关于翻译流程的更多信息,请参阅 [翻译文档](/developers/internationalization/core.md),其中还包含有关 [entity 翻译](/developers/internationalization/core.md#name-of-entities)的信息。 关于 entity 命名的更多信息,请参阅 [entity 文档](/developers/core/entity.md#has_entity_name-true-mandatory-for-new-integrations)。 ## 例外 本规则没有例外。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/entity-unavailable.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 理由 如果我们无法从设备或服务获取数据,应将其标记为不可用。 这样做的目的是反映更准确的状态,而不是仅仅显示上一次已知状态。 如果我们能成功获取数据,但暂时缺少部分数据,则应将 entity 状态标记为 unknown。 ## 示例实现 由于实现方式多种多样,我们只针对使用 coordinator 的集成以及通过 `async_update` 更新状态的 entity 提供示例。 ### 使用 coordinator 的集成示例 在本示例中,我们有一个使用 coordinator 获取数据的集成。 coordinator 与 `CoordinatorEntity` 结合使用时,具备内置的可用性逻辑。 如果需要额外的可用性逻辑,请务必纳入 `super().available` 的值。 在示例的 sensor 中,当更新失败或该设备的数据缺失时,我们将 entity 标记为不可用。 `coordinator.py` ```python {18} showLineNumbers class MyCoordinator(DataUpdateCoordinator[dict[str, MyDevice]]): """Class to manage fetching data.""" def __init__(self, hass: HomeAssistant, client: MyClient) -> None: """Initialize coordinator.""" super().__init__( hass, logger=LOGGER, name=DOMAIN, update_interval=timedelta(minutes=1), ) self.client = client async def _async_update_data(self) -> dict[str, MyDevice]: try: return await self.client.get_data() except MyException as ex: raise UpdateFailed(f"The service is unavailable: {ex}") ``` `sensor.py` ```python {6} showLineNumbers class MySensor(SensorEntity, CoordinatorEntity[MyCoordinator]): @property def available(self) -> bool: """Return True if entity is available.""" return super().available and self.identifier in self.coordinator.data ``` ### 通过 `async_update` 更新的 entity 示例 在本示例中,我们有一个通过 `async_update` 更新值的 sensor。 如果无法获取数据,我们通过简写方式将 entity 设置为不可用。 如果能获取数据,则将 entity 设置为可用并更新值。 `sensor.py` ```python {7,9} showLineNumbers class MySensor(SensorEntity): async def async_update(self) -> None: try: data = await self.client.get_data() except MyException as ex: self._attr_available = False else: self._attr_available = True self._attr_native_value = data.value ``` ## 附加资源 有关管理集成状态的更多信息,请参阅[文档](/developers/integration_fetching_data.md)。 ## 例外 如果集成可以打开设备(无论是通过用户定义的自动化 trigger,还是通过自动创建辅助控制通道,例如使用 Wake-on-LAN 或红外发射器),则当设备处于待机状态且对主通道(例如 TCP)无响应时,应报告为 `off`。如果不存在此类方法,并且设备在当前状态下无法被控制,则应报告为 `unavailable`。 以下是一个示例场景:一个进入待机模式且只能通过外部设备(例如红外发射器)打开的媒体播放器: * 当首次添加到 Home Assistant 且没有活动连接时,设备显示为 `unavailable`。 * 如果用户配置自动化(例如使用红外发射器)来打开它,设备在待机时将显示为 `off`。 * 一旦通过外部方法打开且主连接建立,状态将更新为 `on`。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/entity-unique-id.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 原理说明 在过去,实体(entities)是未被持久化的。 Home Assistant 不跟踪过去已知哪些实体、又不知道哪些实体。 为了允许对实体进行自定义(如重命名实体或更改测量单位),Home Assistant 需要一种在重启之间跟踪每个实体的方式。 为了解决这个问题,Home Assistant 引入了 entity registry(实体注册表)。 Entity registry 是 Home Assistant 跟踪其所知所有实体的中心位置。 Entity registry 中的每个实体都有一个 unique ID(唯一 ID),该 ID 在每个集成 domain 和每个平台 domain 下是唯一的。 如果实体没有 unique ID,用户对实体的控制就会减少。 因此,确保实体具有 unique ID 可以改善用户体验。 ## 示例实现 在这个示例中,有一个温度传感器使用简写表示法设置其 unique ID。 `sensor.py`: ```python {6} showLineNumbers class MySensor(SensorEntity): """Representation of a sensor.""" def __init__(self, device_id: str) -> None: """Initialize the sensor.""" self._attr_unique_id = f"{device_id}_temperature" ``` ## 补充资料 更多有关 unique ID 要求的信息可在 [documentation](/developers/entity_registry_index.md#unique-id-requirements) 中找到。 ## 例外情况 本规则没有例外。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/exception-translations.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 原理说明 有时会出现问题,我们想向用户显示错误消息。 由于 Home Assistant 被世界各地的人使用,确保这些错误消息可被翻译非常重要。 这提高了不使用英语的用户的 Home Assistant 可用性。 Home Assistant 内置了对来自 `HomeAssistantError` 异常的翻译消息的支持。 ## 示例实现 在这个示例中,我们展示了一个注册为 Home Assistant 服务 action 的函数。 在抛出异常时,会传入集成 domain 和翻译的 key。 异常应继承自 `HomeAssistantError` 以支持翻译。 错误消息随后在集成的 `strings.json` 文件中定义。 ```python {6-9,13-16} showLineNumbers async def async_set_schedule(call: ServiceCall) -> ServiceResponse: """Set the schedule for a day.""" start_date = call.data[ATTR_START_DATE] end_date = call.data[ATTR_END_DATE] if end_date < start_date: raise ServiceValidationError( translation_domain=DOMAIN, translation_key="end_date_before_start_date", ) try: await client.set_schedule(start_date, end_date) except MyConnectionError as err: raise HomeAssistantError( translation_domain=DOMAIN, translation_key="cannot_connect_to_schedule", ) from err ``` `strings.json`: ```json { "exceptions": { "end_date_before_start_date": { "message": "The end date cannot be before the start date." }, "cannot_connect_to_schedule": { "message": "Cannot connect to the schedule." } } } ``` ## 补充资料 有关抛出异常的更多信息,请参阅 [documentation](/developers/core/platform/raising_exceptions.md)。 ## 例外情况 本规则没有例外。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/has-entity-name.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 理由 `has_entity_name` 是一个 entity 属性,用于改善 Home Assistant 中 entity 的命名。 它的引入旨在根据名称显示的上下文,向用户展示更好的 entity 名称。 我们认为这是一种良好实践,因为它允许不同集成之间的命名保持一致性。 ## 示例实现 在下面的示例中,如果设备名称为 "My device",字段为 "temperature",则 entity 名称将显示为 "My device temperature"。 `sensor.py` ```python {4} showLineNumbers class MySensor(SensorEntity): """Representation of a sensor.""" _attr_has_entity_name = True def __init__(self, device: Device, field: str) -> None: """Initialize the sensor.""" self._attr_device_info = DeviceInfo( identifiers={(DOMAIN, device.id)}, name=device.name, ) self._attr_name = field ``` 但是,当 entity 名称设置为 `None` 时,将使用设备名称作为 entity 名称。 在这种情况下,lock entity 将直接称为 "My device"。 这应用于设备的主要功能。 `lock.py` ```python {4-5,11} showLineNumbers class MyLock(LockEntity): """Representation of a lock.""" _attr_has_entity_name = True _attr_name = None def __init__(self, device: Device) -> None: """Initialize the lock.""" self._attr_device_info = DeviceInfo( identifiers={(DOMAIN, device.id)}, name=device.name, ) ``` ## 附加资源 关于 entity 命名的更多信息,请参阅 [entity 文档](/developers/core/entity.md#has_entity_name-true-mandatory-for-new-integrations)。 关于设备的更多信息,请参阅 [device 文档](/developers/device_registry_index.md)。 ## 例外 本规则没有例外。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/icon-translations.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 原理说明 在过去,图标(icons)是集成状态(state)的一部分。 这其实并不是必需的,因为它们通常是静态的,或者具有固定的一组状态。 为了减轻状态机(state machine)的负担,引入了 icon translations。 这个功能的名称听起来有些奇怪,因为它并不是要翻译图标本身,而是通过 translation key 来引用图标。 Icon translations 背后的想法是:由集成在一个文件中定义图标,然后由前端使用该文件来显示图标。 此外,这还为状态属性(state attribute)的不同值添加了图标支持,例如气候实体(climate entity)可能的预设模式(preset modes)。 :::info 请注意,实体也可以从 device class 获取图标。 如果实体的上下文与 device class 完全相同,我们不应覆盖该图标,以保持集成之间的一致性。 例如,PM2.5 传感器实体将不会获得自定义图标,因为 device class 已经在相同的上下文中提供了图标。 ::: ## 示例实现 ### 基于状态的图标 在这个示例中,我们定义一个具有 translation key 的传感器实体。 在 `icons.json` 文件中,我们为传感器实体定义图标,并为状态 `high` 定义一个状态图标。 因此,当实体状态为 `high` 时,将显示图标 `mdi:tree-outline`;否则将显示 `mdi:tree`。 `sensor.py` ```python {5} showLineNumbers class MySensor(SensorEntity): """Representation of a sensor.""" _attr_has_entity_name = True _attr_translation_key = "tree_pollen" ``` `icons.json` ```json { "entity": { "sensor": { "tree_pollen": { "default": "mdi:tree", "state": { "high": "mdi:tree-outline" } } } } } ``` ### 基于范围的图标 对于数值型实体,您可以定义根据数值范围变化的图标。该功能消除了集成代码中自定义逻辑的需求,并提供了一致的可视化方式来表示不同的传感器值。 基于范围的 icon translations 特别适用于: * 电池电量指示器 * 信号强度计 * 温度传感器 * 空气质量指示器 * 填充液位传感器 #### 配置 在 `icons.json` 文件中,按升序定义各范围及其对应的图标: ```json { "entity": { "sensor": { "battery_level": { "default": "mdi:battery-unknown", "range": { "0": "mdi:battery-outline", "10": "mdi:battery-10", "20": "mdi:battery-20", "30": "mdi:battery-30", "40": "mdi:battery-40", "50": "mdi:battery-50", "60": "mdi:battery-60", "70": "mdi:battery-70", "80": "mdi:battery-80", "90": "mdi:battery-90", "100": "mdi:battery" } } } } } ``` 系统会选择与小于或等于实体当前数值状态的最高范围值相关联的图标。例如,使用上述配置时: * 值为 15 将显示 `mdi:battery-10` 图标(15 大于 10 但小于 20) * 值为 45 将显示 `mdi:battery-40` 图标(45 大于 40 但小于 50) * 值为 100 将显示 `mdi:battery` 图标(100 等于定义的最高范围值) * 值为 5 将显示 `mdi:battery-outline` 图标(5 大于 0 但小于 10) * 值为 -10 将显示 `mdi:battery-unknown` 默认图标(值在定义的范围之外) * 值为 120 将显示 `mdi:battery` 图标(任何超出最后一个定义的范围条目 100 的值,都将使用该最终范围值所对应的图标) 在实现基于范围的图标时,请注意: * 范围值必须为数值,并且必须按升序定义 * 支持整数("0"、"100")和小数("0.5"、"99.9")范围值 * 给定状态的图标是从小于或等于实体当前值的最高范围值中选出的 * 在以下情况下使用默认图标: * 实体的状态值落在所有定义范围之外 * 实体不可用 * 实体的状态无法解析为有效数字 * 如果在同一个 translation key 中同时定义了基于状态的图标和基于范围的图标,则基于状态的图标优先于基于范围的图标 * 定义的范围数量没有限制,但请考虑性能和可读性 ## 补充资料 更多有关 icon translations 的信息,请参阅 [entity](/developers/core/entity.md#icon-translations) 文档。 ## 例外情况 本规则没有例外。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/inject-websession.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 原理说明 由于许多设备和服务通过 HTTP 连接,活跃 web session 的数量可能会很高。 为提高这些 web session 的效率,建议在集成使用的依赖客户端中支持传入 web session。 Home Assistant 支持 [`aiohttp`](https://docs.aiohttp.org/en/stable/) 和 [`httpx`](https://www.python-httpx.org/) 这两种方式。 这意味着集成的依赖应使用这两个库中的一个。 ## 示例实现 在下面的示例中,将一个 `aiohttp` session 传入客户端。 `httpx` 的等效实现为 `get_async_client`。 ```python {4} showLineNumbers async def async_setup_entry(hass: HomeAssistant, entry: MyConfigEntry) -> bool: """Set up my integration from a config entry.""" client = MyClient(entry.data[CONF_HOST], async_get_clientsession(hass)) ``` :::info 在某些情况下可能不需要共享 session,例如使用 cookies 时。 在这种情况下,可以使用 `async_create_clientsession`(针对 `aiohttp`)或 `create_async_httpx_client`(针对 `httpx`)来创建新 session。 ::: ## 例外情况 如果集成不发出任何 HTTP 请求,则此规则不适用。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/integration-owner.md --- ## 原因 Home Assistant 集成了成千上万种不同的设备和服务,大多数集成是由项目核心维护者以外的人员贡献的。 我们鼓励添加和维护集成的贡献者成为"集成所有者"(integration owner)。 这个角色赋予贡献者在 GitHub 上处理该集成相关的 issue 和 pull request 时更大的权限,同时也意味着贡献者承担了该集成维护的责任。 每当有针对其集成的新 issue 或 pull request 时,集成所有者将自动收到通知。 在 GitHub 上,集成所有者被称为"codeowner"。 集成所有者记录在每个集成的 `manifest.json` 文件中。 要成为集成所有者,请提交一个 pull request,将你的 GitHub 用户名添加到 manifest 中的 `"codeowners"` 字段。 一个集成可以有多个所有者。 我们非常看重集成所有者! 我们相信拥有所有者的集成能得到更好的维护。 在代码评审中,我们将集成所有者视为该集成方面的专家,并赋予其意见更高的权重。 ## 示例实现 集成所有者在 `manifest.json` 中设置。 ```json {4} showLineNumbers { "domain": "my_integration", "name": "My Integration", "codeowners": ["@me"] } ``` ## 更多资源 关于集成所有者的更多信息,请参见 [ADR-0008](https://github.com/home-assistant/architecture/blob/master/adr/0008-code-owners.md)。 ## 例外 本规则没有例外。 --- url: /developers/core/integration-quality-scale/rules/log-when-unavailable.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 理由 当设备或服务无法访问时,entities 通常会变为 unavailable。 为了允许用户了解原因,集成应在此发生时进行记录。 确保总共只记录一次,以避免日志刷屏。 当设备或服务再次可访问时,集成也应记录这一点。 这对于使用日志查找设备或服务何时不可用、何时恢复在线非常有用。 :::info 日志应使用 `info` 级别。 ::: ## 示例实现 由于实现方式多种多样,我们只针对使用 coordinator 的集成和通过 `async_update` 更新的 entity 提供示例。 ### 使用 coordinator 的集成示例 在此示例中,我们有一个使用 coordinator 获取数据的集成。 coordinator 内置了只记录一次的逻辑。 你在 coordinator 中唯一需要做的是,当设备或服务不可用时抛出 `UpdateFailed`。 `coordinator.py` ```python {18} showLineNumbers class MyCoordinator(DataUpdateCoordinator[MyData]): """Class to manage fetching data.""" def __init__(self, hass: HomeAssistant, client: MyClient) -> None: """Initialize coordinator.""" super().__init__( hass, logger=LOGGER, name=DOMAIN, update_interval=timedelta(minutes=1), ) self.client = client async def _async_update_data(self) -> MyData: try: return await self.client.get_data() except MyException as ex: raise UpdateFailed(f"The device is unavailable: {ex}") ``` ### 通过 `async_update` 更新的 entity 示例 在此示例中,我们有一个通过 `async_update` 更新其值的 sensor。 示例将在 sensor 不可用时记录,并在 sensor 重新上线时记录。 注意,使用实例属性来跟踪消息是否已记录,以避免日志刷屏。 `sensor.py` ```python {10-12,16-18} showLineNumbers class MySensor(SensorEntity): _unavailable_logged: bool = False async def async_update(self) -> None: try: data = await self.client.get_data() except MyException as ex: self._attr_available = False if not self._unavailable_logged: _LOGGER.info("The sensor is unavailable: %s", ex) self._unavailable_logged = True else: self._attr_available = True self._attr_native_value = data.value if self._unavailable_logged: _LOGGER.info("The sensor is back online") self._unavailable_logged = False ``` ## 更多资源 有关管理集成状态的更多信息,请参见[文档](/developers/integration_fetching_data.md) ## 例外 此规则没有例外。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/parallel-updates.md --- ## 原因 某些设备或服务不擅长同时接收大量请求。 为了避免这种情况,Home Assistant 内置了一项限制同时发送给某个设备或服务的请求数量的功能。 该限制将同时应用于实体更新和 action 调用。 我们建议显式设置并行更新数量,并将其视为良好实践。 ## 示例实现 在下面的示例中,我们将并行更新数量设置为 1。 这意味着如果 sensor platform 上有多个实体,它们将被逐个更新。 如果不需要限制并行更新数量,可以将其设置为 0。 `sensor.py` ```python {1} showLineNumbers PARALLEL_UPDATES = 1 class MySensor(SensorEntity): """Representation of a sensor.""" def __init__(self, device: Device) -> None: """Initialize the sensor.""" ... ``` ### 使用 coordinator 时 使用 coordinator 时,数据更新已经集中处理。 这意味着对于只读 platform(`binary_sensor`、`sensor`、`device_tracker`、`event`),可以设置 `PARALLEL_UPDATES = 0`,此时只需考虑 action 调用是否需要设置合适的并行更新数量。 :::note coordinator 仅集中处理入站数据更新;它不会限制出站 action 调用。 这意味着即使对于使用 coordinator 的 platform,你仍然需要为包含 action 的 platform 考虑合适的并行更新数量(例如,切换 `switch` 或打开 `light`)。 ::: `sensor.py` ```python {1,2} showLineNumbers # Coordinator is used to centralize the data updates PARALLEL_UPDATES = 0 class MySensor(CoordinatorEntity, SensorEntity): """Representation of a sensor.""" def __init__(self, device: Device) -> None: """Initialize the sensor.""" ... ``` ## 更多资源 关于请求并行性的更多信息,请查阅[相关文档](/developers/integration_fetching_data.md#request-parallelism)。 ## 例外 本规则没有例外。 --- url: /developers/core/integration-quality-scale/rules/reauthentication-flow.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 原因 用户可能会更改设备或服务密码,却忘记设备或账户仍然与 Home Assistant 关联。 为了避免用户必须删除配置条目并重新添加,我们会启动重新身份验证流程。 在此流程中,用户可以提供新的凭据以供后续使用。 这是一种非常友好的方式,让用户知道他们需要采取行动并更新凭据。 ## 示例实现 在下面的示例中,我们展示了一个身份验证流程,允许用户使用新的 API token 重新验证身份。 当我们收到新 token 时,会检查是否能够连接到服务,以避免用户输入无效的 token。 如果连接成功,我们将使用新 token 更新配置条目。 `config_flow.py`: ```python {6-11,13-35} showLineNumbers class MyConfigFlow(ConfigFlow, domain=DOMAIN): """My config flow.""" host: str async def async_step_reauth( self, entry_data: Mapping[str, Any] ) -> ConfigFlowResult: """Perform reauthentication upon an API authentication error.""" self.host = entry_data[CONF_HOST] return await self.async_step_reauth_confirm() async def async_step_reauth_confirm( self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Confirm reauthentication dialog.""" errors: dict[str, str] = {} if user_input: client = MyClient(self.host, user_input[CONF_API_TOKEN]) try: user_id = await client.check_connection() except MyException as exception: errors["base"] = "cannot_connect" else: await self.async_set_unique_id(user_id) self._abort_if_unique_id_mismatch(reason="wrong_account") return self.async_update_reload_and_abort( self._get_reauth_entry(), data_updates={CONF_API_TOKEN: user_input[CONF_API_TOKEN]}, ) return self.async_show_form( step_id="reauth_confirm", data_schema=vol.Schema({vol.Required(CONF_API_TOKEN): TextSelector()}), errors=errors, ) async def async_step_user( self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Handle a flow initialized by the user.""" errors: dict[str, str] = {} if user_input: client = MyClient(user_input[CONF_HOST], user_input[CONF_API_TOKEN]) try: user_id = await client.check_connection() except MyException as exception: errors["base"] = "cannot_connect" else: await self.async_set_unique_id(user_id) self._abort_if_unique_id_configured() return self.async_create_entry( title="MyIntegration", data=user_input, ) return self.async_show_form( step_id="user", data_schema=vol.Schema( { vol.Required(CONF_HOST): TextSelector(), vol.Required(CONF_API_TOKEN): TextSelector(), } ), errors=errors, ) ``` ## 更多资源 关于处理过期凭据的更多信息,请查阅[相关文档](/developers/integration_setup_failures.md#handling-expired-credentials)。 ## 例外 如果集成不需要任何身份验证,本规则不适用。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/reconfiguration-flow.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 原因 用户可能会更改设备或服务的某些设置,例如修改密码或更改 IP 地址。 理想情况下,Home Assistant 能检测到这些事件并通知用户需要进行重新身份验证或关注。 重新配置流程让用户能够主动触发重新配置,从而更新设备或服务的配置,而无需删除并重新添加设备或服务。 这为用户提供了更多尝试修复问题的方式,无需重启软件或触发重新身份验证。 ## 示例实现 在 `config_flow.py` 文件中,添加一个名为 `reconfigure` 的新步骤,允许用户重新配置集成。 在以下示例中,我们检查新的 api token 是否有效。 同时,我们会确认用户是否试图用不同的账户重新配置集成,因为集成使用的账户不应改变。 `config_flow.py`: ```python {4-31} showLineNumbers class MyConfigFlow(ConfigFlow, domain=DOMAIN): """My config flow.""" async def async_step_reconfigure( self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Handle reconfiguration of the integration.""" errors: dict[str, str] = {} if user_input: client = MyClient(user_input[CONF_HOST], user_input[CONF_API_TOKEN]) try: user_id = await client.check_connection() except MyException as exception: errors["base"] = "cannot_connect" else: await self.async_set_unique_id(user_id) self._abort_if_unique_id_mismatch(reason="wrong_account") return self.async_update_reload_and_abort( self._get_reconfigure_entry(), data_updates=user_input, ) return self.async_show_form( step_id="reconfigure", data_schema=vol.Schema( { vol.Required(CONF_HOST): TextSelector(), vol.Required(CONF_API_TOKEN): TextSelector(), } ), errors=errors, ) async def async_step_user( self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Handle a flow initialized by the user.""" errors: dict[str, str] = {} if user_input: client = MyClient(user_input[CONF_HOST], user_input[CONF_API_TOKEN]) try: user_id = await client.check_connection() except MyException as exception: errors["base"] = "cannot_connect" else: await self.async_set_unique_id(user_id) self._abort_if_unique_id_configured() return self.async_create_entry( title="MyIntegration", data=user_input, ) return self.async_show_form( step_id="user", data_schema=vol.Schema( { vol.Required(CONF_HOST): TextSelector(), vol.Required(CONF_API_TOKEN): TextSelector(), } ), errors=errors, ) ``` ## 更多资源 关于重新配置流程的更多信息,请参见[重新配置流程文档](/developers/core/integration/config_flow.md#reconfigure)。 ## 例外 配置流程中没有设置项的集成免于此规则。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/repair-issues.md --- ## 原因 Repair issues 和 repair flows 是一种非常友好的方式,让用户知道出现了问题,并且他们可以对此采取行动。 Repair issues 只是告知用户问题可以自行修复,而 repair flows 则可以帮用户自动修复。 Repair issues 和 repair flows 应该是可操作的,并能提供关于问题的详细信息。 因此,我们不应该仅为了告知用户存在问题而提出 repair issue,特别是用户无法自行修复的问题。 ## 示例实现 在下面的示例中,我们有一个用于本地托管服务的集成。 启动时,我们会检查是否支持正在运行的服务版本。 如果不支持,我们会提出一个 repair issue,告知用户在能够再次使用集成之前,应该先更新服务。 `__init__.py` ```python {6-14} showLineNumbers async def async_setup_entry(hass: HomeAssistant, entry: MyConfigEntry) -> None: """Set up the integration from a config entry.""" client = MyClient(entry.data[CONF_HOST]) version = await client.get_version() if version < MINIMUM_VERSION: ir.async_create_issue( hass, DOMAIN, "outdated_version", is_fixable=False, issue_domain=DOMAIN, severity=ir.IssueSeverity.ERROR, translation_key="outdated_version", ) raise ConfigEntryError( "Version of MyService is %s, which is lower than minimum version %s", version, MINIMUM_VERSION, ) ``` ## 更多资源 关于 repair issues 和 repair flows 的更多信息,请参见[repairs 文档](/developers/core/platform/repairs.md)。 ## 例外 本规则没有例外。 --- url: /developers/core/integration-quality-scale/rules/runtime-data.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 原因 `ConfigEntry` 对象有一个 `runtime_data` 属性,可用于存储运行时数据。 这对于存储那些不需要持久化到配置文件存储、但在配置条目生命周期内所需的数据很有用。 通过使用 `runtime_data`,我们为开发者提供了一致且类型安全的方式来存储运行时数据。 由于增加了类型标注,我们可以使用工具来避免类型错误。 ## 示例实现 `ConfigEntry` 的类型可以通过放入 `runtime_data` 的数据类型进行扩展。 在下面的示例中,我们使用 `MyClient` 扩展 `ConfigEntry` 类型,这意味着 `runtime_data` 属性将为 `MyClient` 类型。 `__init__.py`: ```python {1,4,9} showLineNumbers type MyIntegrationConfigEntry = ConfigEntry[MyClient] async def async_setup_entry(hass: HomeAssistant, entry: MyIntegrationConfigEntry) -> bool: """Set up my integration from a config entry.""" client = MyClient(entry.data[CONF_HOST]) entry.runtime_data = client await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) return True ``` :::info 如果集成实现了 `strict-typing`,则必须使用自定义类型标注的 `MyIntegrationConfigEntry`,并在全局范围内使用。 ::: ## 更多资源 关于配置条目及其生命周期的更多信息,请参见[config entry 文档](/developers/config_entries_index.md)。 ## 例外 本规则没有例外。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/stale-devices.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 原因 当设备从 hub 或账户中移除时,也应从 Home Assistant 中移除。 这样,用户界面就不会再显示已不可用的设备。 我们只应移除那些确定已不可用的设备。 如果无法确定设备是否仍可用,请务必实现 `async_remove_config_entry_device`。 这将允许用户手动从 device registry 中删除设备。 ## 示例实现 在此示例中,我们有一个从服务获取数据的 coordinator。 当数据更新时,我们会检查是否有设备被移除。 如果有,我们会将它们从 device registry 中移除。 同时也会导致与该设备关联的所有实体被移除。 `coordinator.py` ```python {13,20-30} showLineNumbers class MyCoordinator(DataUpdateCoordinator[dict[str, MyDevice]]): """Class to manage fetching data.""" def __init__(self, hass: HomeAssistant, client: MyClient) -> None: """Initialize coordinator.""" super().__init__( hass, logger=LOGGER, name=DOMAIN, update_interval=timedelta(minutes=1), ) self.client = client self.previous_devices: set[str] = set() async def _async_update_data(self) -> dict[str, MyDevice]: try: data = await self.client.get_data() except MyException as ex: raise UpdateFailed(f"The service is unavailable: {ex}") current_devices = set(data) if (stale_devices := self.previous_devices - current_devices): device_registry = dr.async_get(self.hass) for device_id in stale_devices: device = device_registry.async_get_device(identifiers={(DOMAIN, device_id)}) if device: device_registry.async_update_device( device_id=device.id, remove_config_entry_id=self.config_entry.entry_id, ) self.previous_devices = current_devices return data ``` 为了展示一个用户可以手动从 device registry 中删除设备的示例,我们在 `__init__.py` 中实现 `async_remove_config_entry_device`。 定义此函数将在 UI 的设备页面上启用删除按钮。 在此示例中,集成只能获取设备的更新,而无法获取已连接设备的完整列表,因此无法自动删除设备。 在 `async_remove_config_entry_device` 中,我们应该实现一个函数来检查设备是否仍然可用。 如果不可用,我们返回 `True` 以允许用户手动删除设备。 此处,如果一段时间内没有收到设备的任何更新,则假设设备已无法工作。 `__init__.py` ```python showLineNumbers async def async_remove_config_entry_device( hass: HomeAssistant, config_entry: MyConfigEntry, device_entry: dr.DeviceEntry ) -> bool: """Remove a config entry from a device.""" return not any( identifier for identifier in device_entry.identifiers if identifier[0] == DOMAIN and identifier[1] in config_entry.runtime_data.data ) ``` ## 更多资源 关于设备的更多信息,请查阅[device registry 文档](/developers/device_registry_index.md)。 ## 例外 本规则没有例外。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/strict-typing.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 原因 Python 是一种动态类型语言,这可能是许多 bug 的来源。 通过使用类型标注,你可以在早期发现 bug 并避免引入它们。 类型标注由 mypy 进行检查,mypy 是一个 Python 静态类型检查器。 由于 Python 的类型机制以及类型标注在 Python 中是可选的,mypy 只会检查已知已进行类型标注的代码。 为了改进这一点,我们建议完整地为你的库添加类型标注,并使其符合 PEP-561 规范。 这意味着你需要在库中添加一个 `py.typed` 文件。 该文件告诉 mypy 你的库是完全类型标注的,此后 mypy 就可以从你的库中读取类型标注。 在 Home Assistant 代码库中,你可以将你的集成添加到 [`.strict-typing`](https://github.com/home-assistant/core/blob/dev/.strict-typing) 文件中,这将为你集成启用严格的类型检查。 :::warning 如果集成实现了 `runtime-data`,则必须使用自定义类型标注的 `MyIntegrationConfigEntry`,并在全局范围内使用。 ::: ## 更多资源 要了解更多关于 `py.typed` 文件的信息,请参见 [PEP-561](https://peps.python.org/pep-0561/)。 ## 例外 本规则没有例外。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/test-before-configure.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 原因 配置流程不仅非常易于使用,还是一种让用户在配置完成后立即知道某些设置无法正常工作的有效方式。 它可以捕获以下问题: * DNS 问题 * 防火墙问题 * 错误的凭据 * 错误的 IP 地址或端口 * 不支持的设备 一旦集成设置完成,这类问题往往很难排查,因此最好尽早捕获,避免用户被一个无法正常工作的集成困住。 由于这改善了用户体验,在配置流程中测试连接是必需的。 ## 示例实现 要验证用户输入,你可以像往常一样使用数据调用你的库,并进行一次测试调用。 如果调用失败,你可以向用户返回错误信息。 在下面的示例中,如果 `client.get_data()` 调用抛出 `MyException`,用户将看到一条集成无法连接的错误信息。 `config_flow.py`: ```python {10-17} showLineNumbers class MyConfigFlow(ConfigFlow, domain=DOMAIN): """My config flow.""" async def async_step_user( self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Handle a flow initialized by the user.""" errors: dict[str, str] = {} if user_input: client = MyClient(user_input[CONF_HOST]) try: await client.get_data() except MyException: errors["base"] = "cannot_connect" except Exception: # noqa: BLE001 LOGGER.exception("Unexpected exception") errors["base"] = "unknown" else: return self.async_create_entry( title="MyIntegration", data=user_input, ) return self.async_show_form( step_id="user", data_schema=vol.Schema({vol.Required(CONF_HOST): TextSelector()}), errors=errors, ) ``` ## 更多资源 关于配置流程的更多信息,请参见[config flow 文档](/developers/core/integration/config_flow.md)。 ## 例外 不与设备或服务建立连接的集成(例如 helpers)无需在配置流程中测试连接,免于此规则。 依赖运行时自动发现的集成(如 Google Cast)也免于此规则。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/test-before-setup.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 原因 初始化集成时,我们应该检查是否能够正确设置。 这样可以立即让用户知道集成无法正常工作。 实现这些检查可以提高集成正确工作的信心,并以用户友好的方式展示错误。 这将改善用户体验。 ## 示例实现 当失败的原因是临时性的(例如设备暂时离线),我们应该抛出 `ConfigEntryNotReady`,Home Assistant 稍后会重试设置。 如果失败的原因是密码不正确或 api key 无效,我们应该抛出 `ConfigEntryAuthFailed`,Home Assistant 会提示用户重新进行身份验证(如果已实现重新身份验证流程)。 如果我们预计集成在可预见的将来无法工作,我们应该抛出 `ConfigEntryError`。 `__init__.py`: ```python {6-13} showLineNumbers async def async_setup_entry(hass: HomeAssistant, entry: MyIntegrationConfigEntry) -> bool: """Set up my integration from a config entry.""" client = MyClient(entry.data[CONF_HOST]) try: await client.async_setup() except OfflineException as ex: raise ConfigEntryNotReady("Device is offline") from ex except InvalidAuthException as ex: raise ConfigEntryAuthFailed("Invalid authentication") from ex except AccountClosedException as ex: raise ConfigEntryError("Account closed") from ex entry.runtime_data = client await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) return True ``` :::info 请注意,使用 data update coordinator 并通过 `await coordinator.async_config_entry_first_refresh()` 时,也可能隐式实现此功能。 ::: ## 更多资源 关于配置条目及其生命周期的更多信息,请参见[config entry 文档](/developers/config_entries_index.md)。 ## 例外 本规则没有例外。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/test-coverage.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 原因 由于我们支持大量的不同集成,我们并非拥有每一个设备或服务来进行手动测试。 为确保在接受代码更改时不会破坏任何功能,我们需要对所有集成模块有良好的测试覆盖率。 这可以防止 bug 和回归的引入。 这也让新开发者能够理解代码库,并在不破坏任何现有用例的情况下进行更改。 ## 更多资源 关于测试以及如何计算测试覆盖率的更多信息,请参见[Testing your code](/developers/development_testing.md)页面。 ## 例外 本规则没有例外。 ## 相关规则 --- url: /developers/core/integration-quality-scale/rules/unique-config-entry.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 原因 由于通过 UI 设置集成非常简便,用户可能会意外地将同一设备或服务设置两次。 这可能导致重复的设备以及具有相同唯一标识符的实体发生冲突,从而产生负面影响。 任何发现流程也必须确保配置条目具有唯一标识性,否则就会发现已经设置过的设备。 为了防止这种情况,我们需要确保用户只能设置一次设备或服务。 ## 示例实现 集成检查自己是否已经设置过通常有两种常见方式。 第一种方式是为配置条目分配 `unique_id`。 第二种方式是检查配置条目中的数据片段是否唯一。 以下示例展示了如何在配置流程中实现这些检查。 ### 唯一标识符 第一种方式是为配置条目分配 `unique_id`。 该唯一 ID 在每个集成 domain 内是唯一的,因此其他集成可以使用相同的唯一 ID 而不会出现问题。 下面是一个配置流程的示例,它通过 client 获取输入配置对应的 `unique_id`,并检查该 `unique_id` 是否已经存在。 如果已存在,流程将中止并向用户显示错误信息。 `config_flow.py`: ```python {16-17} showLineNumbers async def async_step_user( self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Handle a flow initialized by the user.""" errors: dict[str, str] = {} if user_input: client = MyClient(user_input[CONF_HOST]) try: identifier = await client.get_identifier() except MyException: errors["base"] = "cannot_connect" except Exception: # noqa: BLE001 LOGGER.exception("Unexpected exception") errors["base"] = "unknown" else: await self.async_set_unique_id(identifier) self._abort_if_unique_id_configured() return self.async_create_entry( title="MyIntegration", data=user_input, ) return self.async_show_form( step_id="user", data_schema=vol.Schema({vol.Required(CONF_HOST): TextSelector()}), errors=errors, ) ``` ### 唯一数据 第二种方式是检查配置条目中的数据片段是否唯一。 在下面的示例中,用户输入 host 和密码。 如果已经存在针对同一 host 的配置条目,流程将中止并向用户显示错误信息。 `config_flow.py`: ```python async def async_step_user( self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Handle a flow initialized by the user.""" errors: dict[str, str] = {} if user_input: self._async_abort_entries_match({CONF_HOST: user_input[CONF_HOST]}) client = MyClient(user_input[CONF_HOST], user_input[CONF_PASSWORD]) try: await client.get_data() except MyException: errors["base"] = "cannot_connect" except Exception: # noqa: BLE001 LOGGER.exception("Unexpected exception") errors["base"] = "unknown" else: return self.async_create_entry( title="MyIntegration", data=user_input, ) return self.async_show_form( step_id="user", data_schema=vol.Schema( { vol.Required(CONF_HOST): TextSelector(), vol.Required(CONF_PASSWORD): TextSelector(), } ), errors=errors, ) ``` ## 更多资源 关于配置流程的更多信息,请参见[config flow 文档](/developers/core/integration/config_flow.md)。 关于唯一标识符要求的更多信息,请参见[相关文档](/developers/entity_registry_index.md#unique-id-requirements)。 ## 例外 本规则没有例外。 ## 相关规则 --- url: /developers/core/integration/brand_images.md --- 为了帮助用户从视觉上识别集成和硬件,Home Assistant 会为集成和硬件实体显示图标和 logo。 图标是用于在空间有限的 UI 中显示的正方形图片,而 logo 是用于集成配置页面及其他有更大空间的矩形图片。 Home Assistant 支持亮色和暗色模式图片。 ## 如何添加品牌图片 添加品牌图片的方式取决于集成的类型。 ### Core 集成 对于 core 集成,品牌图片通过向 [brands repository] 创建 pull request 来添加。 图片应添加到 `core_integrations/` 目录中一个以集成 domain 命名的目录下。 例如,Philips Hue 集成的品牌图片应放在 `core_integrations/hue` 中。 :::info 这些图片在服务端进行缓存,因此一旦 pull request 被合并,图片可能不会立即可用。 ::: #### Material design icons 有些集成(如 helpers)没有代表其品牌的标识。 在这种情况下,你可以在 `core_integrations/` 中的对应文件夹中放置一个 `icon.txt` 文件,其内容为要使用的图标名称,前面加上 `mdi:` 前缀,从而使用 Material Design Icons 库中的图标。 ### Core 品牌 与 core 集成类似,\[core 品牌] 也是通过向 [brands repository] 创建 pull request 来添加。 图片应添加到 `core_brands/` 目录中一个以品牌 domain 命名的目录下。 例如,Google 品牌的品牌图片应放在 `core_brands/google` 中。 如果品牌的图片与其某个集成的图片相同,可以创建 symlink 以避免重复。 例如,Samsung 品牌的图片与 Samsung TV 集成的图片相同,因此 `core_integrations/samsung_tv` 目录中包含指向 `core_brands/samsung` 中图片的 symlink。 ### Custom 集成 在 Home Assistant 2026.3 之前,custom 集成也被要求将品牌图片添加到 [brands repository]。 从 Home Assistant 2026.3 开始,custom 集成可以通过在集成目录内添加 `brand/` 目录来包含自己的品牌图片。 例如,如果你有一个 domain 为 `my_integration` 的 custom 集成,你可以在 `custom_components/my_integration/brand/` 中添加品牌图片。 本地品牌图片优先于来自 [brands repository] 的图片,因此如果 custom 集成有本地 `brand/` 目录,Home Assistant 将使用这些图片而不是来自 [brands repository] 的图片。 :::info 如果 custom 集成将贡献给 Home Assistant Core,请务必移除本地品牌图片,并改为打开 PR 将它们添加到 [brands repository]。 ::: [core brands]: /docs/creating_integration_brand.md [brands repository]: https://github.com/home-assistant/brands ## 品牌图片如何被提供 品牌图片通过本地 API 提供,以便它们与 frontend 来自同一来源。 可用的 API endpoint 如下: * `/api/brands/integration/{domain}/{image}` - 集成的图标和 logo * `/api/brands/hardware/{category}/{image}` - 硬件图片 如果请求的图片不存在,所有 endpoint 默认返回通用占位图片。 若要选择退出并在图片不存在时返回 404,请添加 `?placeholder=no` 查询参数。 这些 endpoint 需要认证。请求可以使用标准已认证会话(Bearer token)或通过在 `token` 查询参数中传递 access token 来认证。 frontend 通过 `brands/access_token` WebSocket 命令获取此 access token,并自动将其附加到所有品牌图片 URL。 --- url: /developers/core/integration/config_flow.md --- 集成可以通过用户界面进行设置,只需为集成添加对 config flow 的支持以创建 config entry。想要支持 config entry 的集成需要定义一个 Config Flow Handler。该 handler 负责管理从用户输入、discovery 或其他来源(如 Home Assistant OS)创建条目。 Config Flow Handler 控制存储在 config entry 中的数据。这意味着 Home Assistant 启动时无需验证配置是否正确。同时也能防止 breaking changes,因为当版本发生变化时,我们可以将配置条目迁移到新格式。 在实例化 handler 时,Home Assistant 会确保加载所有依赖并安装集成的 requirements。 ## 更新 manifest 你需要更新集成的 manifest,以告知 Home Assistant 该集成具有 config flow。做法是将 `config_flow: true` 添加到 manifest 中([docs](/developers/creating_integration_manifest.md#config-flow))。 ## 定义你的 config flow Config entries 使用 [data flow entry framework](/developers/data_entry_flow_index.md) 来定义它们的 config flows。config flow 需要在集成文件夹的文件 `config_flow.py` 中定义,继承 `homeassistant.config_entries.ConfigFlow`,并在继承 `ConfigFlow` 时传入一个 `domain` 键。 ```python from homeassistant import config_entries from .const import DOMAIN class ExampleConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): """Example config flow.""" ``` 更新 manifest 并创建 `config_flow.py` 后,需要运行 `python3 -m script.hassfest`(仅一次),Home Assistant 就会为你的集成激活 config entry。 ## Config flow 标题 config flow 的标题可以被集成影响,并按以下优先级顺序确定: 1. 如果 config flow 中的 `title_placeholders` 被设置为非空字典,它将用于动态计算 config flow 的标题。Reauth 和 reconfigure flows 会自动将 `title_placeholders` 设置为 `{"name": config_entry_title}`。 1. 如果集成提供了本地化的 `flow_title`,将使用它,并从 `title_placeholders` 替换任何翻译占位符。 2. 如果集成未提供 `flow_title`,但 `title_placeholders` 包含 `name`,则将使用 `name` 作为 flow 的标题。 2. 如果存在,将 flow 标题设置为集成本地化的 `title`。 3. 如果存在,将 flow 标题设置为集成 manifest 的 `name`。 4. 将 flow 标题设置为集成的 domain。 请注意,这个优先级顺序意味着: * 如果 `title_placeholders` 字典缺失或为空,即使本地化的 `flow_title` 不包含任何占位符,也会被忽略 * 如果 `title_placeholders` 非空,但不存在本地化的 `flow_title` 且 `title_placeholders` 不包含 `name`,则会被忽略 ## 定义步骤 你的 config flow 需要定义配置流程的各个步骤。每个步骤由一个唯一的 step name(`step_id`)标识。step 回调方法遵循 `async_step_` 的模式。[Data Entry Flow](/developers/data_entry_flow_index.md) 的文档描述了 step 的不同返回值。以下是一个定义 `user` step 的示例: ```python import voluptuous as vol class ExampleConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): async def async_step_user(self, info): if info is not None: pass # TODO: process info return self.async_show_form( step_id="user", data_schema=vol.Schema({vol.Required("password"): str}) ) ``` 有一些 step name 是预留给系统使用的: | Step name | Description | | ----------- |---------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `bluetooth` | 如果集成通过 Bluetooth 被发现,则被调用,如 [使用 manifest 中的 `bluetooth`](/developers/creating_integration_manifest.md#bluetooth) 所指定的。 | | `discovery` | *已废弃* 如果集成被发现且未定义匹配的 step,则被调用。 | | `dhcp` | 如果集成通过 DHCP 被发现,则被调用,如 [使用 manifest 中的 `dhcp`](/developers/creating_integration_manifest.md#dhcp) 所指定的。 | | `hassio` | 如果集成通过 Supervisor add-on 被发现,则被调用。 | | `homekit` | 如果集成通过 HomeKit 被发现,则被调用,如 [使用 manifest 中的 `homekit`](/developers/creating_integration_manifest.md#homekit) 所指定的。 | | `mqtt` | 如果集成通过 MQTT 被发现,则被调用,如 [使用 manifest 中的 `mqtt`](/developers/creating_integration_manifest.md#mqtt) 所指定的。 | | `ssdp` | 如果集成通过 SSDP/uPnP 被发现,则被调用,如 [使用 manifest 中的 `ssdp`](/developers/creating_integration_manifest.md#ssdp) 所指定的。 | | `usb` | 如果集成通过 USB 被发现,则被调用,如 [使用 manifest 中的 `usb`](/developers/creating_integration_manifest.md#usb) 所指定的。 | | `user` | 当用户通过用户界面发起 flow,或发现时且未定义匹配的 discovery step 时被调用。 | | `reconfigure` | 当用户通过用户界面发起 flow 以重新配置现有 config entry 时被调用。 | | `zeroconf` | 如果集成通过 Zeroconf/mDNS 被发现,则被调用,如 [使用 manifest 中的 `zeroconf`](/developers/creating_integration_manifest.md#zeroconf) 所指定的。 | | `reauth` | 如果集成指示它[需要重新认证,例如由于凭据过期](#reauthentication),则被调用。 | | `import` | 预留给从 YAML 配置迁移到 config entries。 | ## 唯一标识符(Unique IDs) config flow 可以附加一个 unique ID(必须是字符串),以避免同一设备被设置两次。unique ID 不需要全局唯一,只需在集成 domain 内唯一即可。 通过设置 unique ID,用户可以选择忽略你的 config entry 的 discovery。这样,他们就不会再被它打扰。 如果集成使用 Bluetooth、DHCP、HomeKit、Zeroconf/mDNS、USB 或 SSDP/uPnP 来发现,则必须提供 unique ID。 如果没有可用的 unique ID,则可以选择省略 `bluetooth`、`dhcp`、`zeroconf`、`hassio`、`homekit`、`ssdp`、`usb` 和 `discovery` steps,即使它们在集成 manifest 中已配置。在这种情况下,当条目被发现时将调用 `user` step。 或者,如果集成不能总是获取到 unique ID(例如,多个设备,有的有、有的没有),则可以使用一个 helper,它仍然允许发现,只要尚未配置该集成的任何实例。 以下是处理 unique ID 并非总是可用的 discovery 的示例: ```python if device_unique_id: await self.async_set_unique_id(device_unique_id) else: await self._async_handle_discovery_without_unique_id() ``` ### 在 config flows 中管理 unique IDs 设置 unique ID 后,如果已有另一个 flow 正在处理此 unique ID,则当前 flow 将立即中止。你还可以快速中止——如果此 ID 已有现有 config entry。Config entries 将获得创建它们的 flow 的 unique ID。 在 config flow step 内部调用: ```python # 为 flow 分配 unique ID,如果另一个具有相同 unique ID 的 flow 正在进行,则中止当前 flow await self.async_set_unique_id(device_unique_id) # 如果存在具有相同 unique ID 的 config entry,则中止 flow self._abort_if_unique_id_configured() ``` 如果 config flow 随后中止,`strings.json` 中 `abort` 部分的键 `already_configured` 的文本资源将作为中止原因显示给用户。 ```json { "config": { "abort": { "already_configured": "[%key:common::config_flow::abort::already_configured_device%]" } } } ``` ### 唯一标识符要求 unique ID 用于将 config entry 与底层设备或 API 匹配。unique ID 必须稳定,不应允许用户更改,且必须是字符串。 Unique ID 可用于在设备访问信息更改时更新 config entry 数据。例如,对于通过本地网络通信的设备,如果由于新的 DHCP 分配导致 IP 地址更改,集成可以使用 Unique ID 通过以下代码片段更新 host: ``` await self.async_set_unique_id(serial_number) self._abort_if_unique_id_configured(updates={CONF_HOST: host, CONF_PORT: port}) ``` #### unique ID 的可接受来源示例 * 设备的序列号 * MAC 地址:使用 `homeassistant.helpers.device_registry.format_mac` 格式化;仅从设备 API 或 discovery handler 获取 MAC 地址。依赖读取 arp 缓存或本地网络访问的工具(如 `getmac`)并非在所有受支持的網絡环境中都能正常工作,不可接受。 * 表示纬度和经度或其他唯一地理位置的字符串 * 物理印刷在设备上或烧录到 EEPROM 中的唯一标识符 #### 本地设备的 unique ID 有时可接受的来源 * Hostname:如果 hostname 的子集包含其中一个可接受的来源,则可以使用该部分 #### 云服务有时可接受的 unique ID 来源 * Email Address:必须规范化为小写 * Username:如果用户名不区分大小写,必须规范化为小写 * Account ID:不得有冲突 #### unique ID 的不可接受来源 * IP Address * Device Name * Hostname(如果可以被用户更改) * URL ## 发现步骤 当集成被发现时,会调用相应的 discovery step(如 `async_step_dhcp` 或 `async_step_zeroconf`),并传入发现信息。该 step 需要检查以下内容: * 确保没有其他此 config flow 的实例正在设置所发现的设备。如果有多种方式可以发现某设备在网络上,就可能发生这种情况。 * 在大多数情况下,在 flow 上设置 unique ID 并检查是否已有具有相同 unique ID 的 config entry 就足够了,如[在 config flows 中管理 unique IDs](#managing-unique-ids-in-config-flows)部分所述 * 在某些情况下,无法确定 unique ID,或因为不同发现源可能有不同的计算方式而导致 unique ID 不明确。在这种情况下: 1. 在 flow 上实现方法 `def is_matching(self, other_flow: Self) -> bool`。 2. 调用 `hass.config_entries.flow.async_has_matching_flow(self)`。 3. 然后,你的 flow 的 `is_matching` 方法将对每个其他正在进行的 flow 调用一次。 * 确保设备尚未被设置。 * 调用 discovery step 绝不应导致 flow 完成并产生 config entry。始终需要用户确认。 ## 无需身份验证的可发现集成 如果你的集成可以被发现且无需任何身份验证,你将能够使用内置的 Discoverable Flow。此 flow 提供以下功能: * 在 config flow 完成之前,检测设备/服务是否可以在网络上被发现。 * 支持所有基于 manifest 的 discovery 协议。 * 限制仅 1 个 config entry。发现所有可用设备由 config entry 负责。 要开始使用,运行 `python3 -m script.scaffold config_flow_discovery` 并按照说明操作。这将创建使用 discovery 配置集成所需的所有样板代码。 ## 通过 OAuth2 配置 Home Assistant 内置了对提供使用 [OAuth2 authorization framework](https://www.rfc-editor.org/rfc/rfc6749) 进行账户链接的集成的支持。要利用此功能,你需要将 Python API library 组织成允许 Home Assistant 负责刷新 token 的方式。请参阅我们的 [API library guide](/developers/api_lib_index.md) 了解如何操作。 内置的 OAuth2 支持开箱即用地与使用 [Application Credentials platform](/developers/core/platform/application_credentials.md) 配置的本地 client ID / secret 配合使用,并与 Home Assistant Cloud Account Linking 服务配合使用。此服务允许用户将其账户与集中管理的 client ID/secret 链接。如果你希望你的集成成为此服务的一部分,请通过 联系我们。 要开始使用,运行 `python3 -m script.scaffold config_flow_oauth2` 并按照说明操作。这将创建使用 OAuth2 配置集成所需的所有样板代码。 ## 翻译 [config flow](/developers/internationalization/core.md#config--options--subentry-flows) handlers 的 translations 在集成翻译文件 `strings.json` 的 `config` 键下定义。以 Hue 集成为例: ```json { "title": "Philips Hue Bridge", "config": { "step": { "init": { "title": "Pick Hue bridge", "data": { "host": "Host" } }, "link": { "title": "Link Hub", "description": "Press the button on the bridge to register Philips Hue with Home Assistant.\n\n![Location of button on bridge](/static/images/config_philips_hue.jpg)" } }, "error": { "register_failed": "Failed to register, please try again", "linking": "Unknown linking error occurred." }, "abort": { "discover_timeout": "Unable to discover Hue bridges", "no_bridges": "No Philips Hue bridges discovered", "all_configured": "All Philips Hue bridges are already configured", "unknown": "Unknown error occurred", "cannot_connect": "Unable to connect to the bridge", "already_configured": "Bridge is already configured" } } } ``` 当 translations 合并到 Home Assistant 后,它们将自动上传到 [Lokalise](https://lokalise.com/),翻译团队将帮助将其翻译为其他语言。在本地开发时,需要运行 `python3 -m script.translations develop` 以查看对 `strings.json` 所做的更改。[更多信息请参阅翻译 Home Assistant。](/developers/translations.md) ## Config entry 迁移 每个 config entry 都有一个分配给它的 version,由 major 和 minor version 组成。这是为了能够在 config entry schema 更改时将 config entry 数据迁移到新格式。如果未在 config flow 中显式设置,`VERSION` 和 `MINOR_VERSION` 都默认为 `1`,因此集成只有在实现 migration 时才需要设置它们。 migration 可以通过在集成的 `__init__.py` 文件中实现函数 `async_migrate_entry` 来以编程方式处理。如果 migration 成功,该函数应返回 `True`。 如果 minor versions 不同但 major versions 相同,即使集成未实现 `async_migrate_entry`,也允许集成设置继续。这意味着 minor version bump 是向后兼容的,而 major version bump 则不然,如果用户在没有从备份恢复配置的情况下降级 Home Assistant Core,会导致集成设置失败。 要设置新 version,将 `VERSION` 和/或 `MINOR_VERSION` 添加到 config flow 类: ```python class ExampleConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): """Example config flow.""" VERSION = 2 MINOR_VERSION = 2 ``` ```python # Example migration function async def async_migrate_entry(hass, config_entry: ConfigEntry): """Migrate old entry.""" _LOGGER.debug("Migrating configuration from version %s.%s", config_entry.version, config_entry.minor_version) if config_entry.version == 1: new_data = {**config_entry.data} if config_entry.minor_version < 2: # TODO: modify Config Entry data with changes in version 1.2 pass if config_entry.minor_version < 3: # TODO: modify Config Entry data with changes in version 1.3 pass hass.config_entries.async_update_entry( config_entry, data=new_data, minor_version=3, version=1 ) _LOGGER.debug("Migration to configuration version %s.%s successful", config_entry.version, config_entry.minor_version) return True ``` ## 重新配置 config entry 可以通过添加 `reconfigure` step 来允许重新配置。这为集成提供了一种方式,使用户能够更改 config entry 数据,而无需为实现不打算作为可选的 setup 数据的 `OptionsFlow`。 这不是用来处理身份验证问题或对其进行重新配置的。为此我们有 [`reauth`](#reauthentication) step,应该在认证出现问题时自动启动。 ```python import voluptuous as vol class ExampleConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): """Config flow for Example integration.""" async def async_step_reconfigure(self, user_input: dict[str, Any] | None = None): if user_input is not None: # TODO: process user input await self.async_set_unique_id(user_id) self._abort_if_unique_id_mismatch() return self.async_update_reload_and_abort( self._get_reconfigure_entry(), data_updates=data, ) return self.async_show_form( step_id="reconfigure", data_schema=vol.Schema({vol.Required("input_parameter"): str}), ) ``` 成功后,reconfiguration flows 预期更新当前条目并中止;它们不应创建新条目。 这通常使用 `return self.async_update_reload_and_abort` helper 完成。 自动化测试应验证 reconfigure flow 更新现有 config entry 且不创建额外条目。 检查是否处于 reconfigure flow 可以使用 `if self.source == SOURCE_RECONFIGURE`。 也可以使用 `self._get_reconfigure_entry()` 访问对应的 config entry。 确保 `unique_id` 未更改应使用 `await self.async_set_unique_id` 后跟 `self._abort_if_unique_id_mismatch()`。 ## 重新认证 优雅地处理认证错误(如无效、过期或撤销的 token)是在 [Integration Quality Scale](/developers/core/integration-quality-scale.md) 上进步所必需的。以下是如何为 `script.scaffold` 创建的 OAuth flow 添加 reauth 的示例,遵循 [Building a Python library](/developers/api_lib_auth.md#oauth2) 中的模式。如果你正在查找如何触发 reauthentication flow,请参阅 [handling expired credentials](/developers/integration_setup_failures.md#handling-expired-credentials)。 此示例捕获 `__init__.py` 中 config entry setup 的认证异常,并指示用户访问集成页面以重新配置集成。 要允许用户更改非可选的 config entry 数据(`OptionsFlow`),并且与认证无直接关系的数据(例如更改的 host name),集成应实现 [`reconfigure`](#reconfigure) step。 ```python from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntry from homeassistant.core import HomeAssistant from . import api async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): """Set up a config entry.""" # TODO: Replace with actual API setup and exception auth = api.AsyncConfigEntryAuth(...) try: await auth.refresh_tokens() except TokenExpiredError as err: raise ConfigEntryAuthFailed(err) from err # TODO: Proceed with integration setup ``` `config_flow.py` 中的 flow handler 还需要一些额外的步骤来支持 reauth,包括显示确认、启动 reauth flow、更新现有 config entry 以及重新加载以再次调用 setup。 ```python class OAuth2FlowHandler( config_entry_oauth2_flow.AbstractOAuth2FlowHandler, domain=DOMAIN ): """Config flow to handle OAuth2 authentication.""" async def async_step_reauth( self, entry_data: Mapping[str, Any] ) -> ConfigFlowResult: """Perform reauth upon an API authentication error.""" return await self.async_step_reauth_confirm() async def async_step_reauth_confirm( self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Dialog that informs the user that reauth is required.""" if user_input is None: return self.async_show_form( step_id="reauth_confirm", data_schema=vol.Schema({}), ) return await self.async_step_user() async def async_oauth_create_entry(self, data: dict) -> dict: """Create an oauth config entry or update existing entry for reauth.""" await self.async_set_unique_id(user_id) if self.source == SOURCE_REAUTH: self._abort_if_unique_id_mismatch() return self.async_update_reload_and_abort( self._get_reauth_entry(), data_updates=data, ) self._abort_if_unique_id_configured() return await super().async_oauth_create_entry(data) ``` 默认情况下,`async_update_reload_and_abort` helper 方法在更新和重新加载后以 `reauth_successful` 中止 flow。默认情况下,entry 将始终被重新加载。如果仅应在 config entry 已更新时重新加载 config entry,请指定 `reload_even_if_entry_is_unchanged=False`。 根据集成的细节,可能还有额外的注意事项,例如确保 reauth 时使用的是同一账户,或处理多个 config entries。 reauth 确认对话框需要在 `strings.json` 中为 reauth 确认和成功对话框添加额外的定义: ```json { "config": { "step": { "reauth_confirm": { "title": "[%key:common::config_flow::title::reauth%]", # TODO: Replace with the name of the integration "description": "The Example integration needs to re-authenticate your account" } }, "abort": { "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]" }, } ``` 请参阅 [Translations](#translations) 的本地开发说明。 认证失败(如撤销的 oauth token)可能比较难以手动测试。一个建议是复制 `config/.storage/core.config_entries`,并根据你想要测试的场景手动更改 `access_token`、`refresh_token` 和 `expires_at` 的值。然后可以逐步推进 reauth flow,确认值被替换为新的有效 token。 成功后,reauth flows 预期更新当前条目并中止;它们不应创建新条目。 这通常使用 `return self.async_update_reload_and_abort` helper 完成。 自动化测试应验证 reauth flow 更新现有 config entry 且不创建额外条目。 检查是否处于 reauth flow 可以使用 `if self.source == SOURCE_REAUTH`。 也可以使用 `self._get_reauth_entry()` 访问对应的 config entry。 确保 `unique_id` 未更改应使用 `await self.async_set_unique_id` 后跟 `self._abort_if_unique_id_mismatch()`。 ## 子条目流 集成可以实现 subentry flows,以允许用户添加(并可选地重新配置)subentries。一个示例是提供天气预报的集成,其中 config entry 存储认证详细信息,而每个需要天气预报的位置则存储为 subentry。 Subentry flows 类似于 config flows,只是 subentry flows 不支持 reauthentication 或 discovery;subentry flow 只能通过 `user` 或 `reconfigure` steps 启动。 ```python class ExampleConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): """Config flow for Example integration.""" ... @classmethod @callback def async_get_supported_subentry_types( cls, config_entry: ConfigEntry ) -> dict[str, type[ConfigSubentryFlow]]: """Return subentries supported by this integration.""" return {"location": LocationSubentryFlowHandler} class LocationSubentryFlowHandler(ConfigSubentryFlow): """Handle subentry flow for adding and modifying a location.""" async def async_step_user( self, user_input: dict[str, Any] | None = None ) -> SubentryFlowResult: """User flow to add a new location.""" ... ``` ### Subentry 唯一标识符 Subentries 可以设置 unique ID。规则与 config entries 的 [unique IDs](#unique-ids) 类似,只是 subentry unique IDs 只需在 config entry 内唯一。 ### Subentry 翻译 [subentry flow](/developers/internationalization/core.md#config--options--subentry-flows) handlers 的 translations 在集成翻译文件 `strings.json` 的 `config_subentries` 键下定义,例如: ```json { "config_subentries": { "location": { "title": "Weather location", "step": { "user": { "title": "Add location", "description": "Configure the weather location" }, "reconfigure": { "title": "Update location", "description": "..." } }, "error": { }, "abort": { } } } } ``` ### Subentry 重新配置 Subentries 可以被重新配置,类似于 [config entries 可以被重新配置](#reconfigure) 的方式。要为 subentry flow 添加 reconfigure 支持,请实现一个 `reconfigure` step。 ```python class LocationSubentryFlowHandler(ConfigSubentryFlow): """Handle subentry flow for adding and modifying a location.""" async def async_step_user( self, user_input: dict[str, Any] | None = None ) -> SubentryFlowResult: """User flow to add a new location.""" ... async def async_step_reconfigure( self, user_input: dict[str, Any] | None = None ) -> SubentryFlowResult: """User flow to modify an existing location.""" # 检索父 config entry 作为引用 config_entry = self._get_entry() # 检索要更新的目标 subentry config_subentry = self._get_reconfigure_subentry() ... ``` ## 继续另一个 flow config flow 可以启动另一个 config flow,并告知 frontend 当第一个 flow 完成后应显示另一个 flow。为此,第一个 flow 需要将 `next_flow` 参数传递给 `async_create_entry` 方法。参数应为形式为 `(flow_type, flow_id)` 的元组。 ```python from homeassistant.config_entries import SOURCE_USER, ConfigFlow, FlowType class ExampleFlow(ConfigFlow): """Example flow.""" async def async_step_user( self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Show create entry with next_flow parameter.""" result = await self.hass.config_entries.flow.async_init( "another_integration_domain", context={"source": SOURCE_USER}, ) return self.async_create_entry( title="Example", data={}, next_flow=(FlowType.CONFIG_FLOW, result["flow_id"]), ) ``` ### 使用 async\_on\_create\_entry `async_on_create_entry` 提供了一个选项,用于在 config entry 创建并 flow 最终确定后修改最终的 `ConfigFlowResult`。 由于 subentry flows 和 option flows 依赖于 main config entry 存在后才能启动,这些 flow 类型只能与 config flow 中的 `async_on_create_entry()` 方法一起使用: ```python from homeassistant.config_entries import ( ConfigFlow, FlowType, SOURCE_USER, SubentryFlowContext, ) class ExampleFlow(ConfigFlow): """Example flow.""" async def async_on_create_entry( self, result: ConfigFlowResult ) -> ConfigFlowResult: """Create subentry flow after creating the main entry.""" subentry_result = await self.hass.config_entries.subentries.async_init( (result["result"].entry_id, "subentry_type"), context=SubentryFlowContext(source=SOURCE_USER), ) result["next_flow"] = ( FlowType.CONFIG_SUBENTRIES_FLOW, subentry_result["flow_id"], ) return result async def async_step_user( self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Create entry.""" return self.async_create_entry( title="Example", data={}, ) ``` ## 使用 SchemaConfigFlowHandler 处理简单 flows 对于 helper 和具有简单 config flows 的集成,你可以改用 `SchemaConfigFlowHandler`。 与使用完整的 config flow 相比,`SchemaConfigFlowHandler` 有一些限制需要注意: * 所有用户输入都保存在结果 config entry 的 `options` 字典中。因此,它不适合在需要连接数据、api key 或其他应存储在 config entry `data` 中的信息的集成中使用。 * 如果你有大量的验证、设置 unique id 或检查重复 config entries,使用普通的 config flow handler 可能更简单。 * 不建议使用 `user` 和 `import` 以外的其他 steps 来启动 flow。 ```python from homeassistant.helpers.schema_config_entry_flow import ( SchemaCommonFlowHandler, SchemaConfigFlowHandler, SchemaFlowError, SchemaFlowFormStep, ) async def validate_setup( handler: SchemaCommonFlowHandler, user_input: dict[str, Any] ) -> dict[str, Any]: """Validate options.""" if user_input[CONF_SOME_SETTING] == "error": # 'setup_error' 需要在 string.json 的 config errors 部分中存在 raise SchemaFlowError("setup_error") return user_input DATA_SCHEMA_SETUP = vol.Schema( { vol.Required(CONF_NAME, default=DEFAULT_NAME): TextSelector() } ) DATA_SCHEMA_OPTIONS = vol.Schema( { vol.Optional(CONF_SOME_SETTING): TextSelector() } ) CONFIG_FLOW = { "user": SchemaFlowFormStep( schema=DATA_SCHEMA_SETUP, next_step="options", ), "options": SchemaFlowFormStep( schema=DATA_SCHEMA_OPTIONS, validate_user_input=validate_setup, ), } OPTIONS_FLOW = { "init": SchemaFlowFormStep( DATA_SCHEMA_OPTIONS, validate_user_input=validate_setup, ), } class MyConfigFlowHandler(SchemaConfigFlowHandler, domain=DOMAIN): """Handle a config flow.""" config_flow = CONFIG_FLOW options_flow = OPTIONS_FLOW options_flow_reloads = True # Reload without a config entry listener def async_config_entry_title(self, options: Mapping[str, Any]) -> str: """Return config entry title from input.""" return cast(str, options[CONF_NAME]) ``` ## 测试你的 config flow 具有 config flow 的集成需要 `config_flow.py` 中所有代码的完整测试覆盖才能被纳入 core。[测试你的代码](/developers/development_testing.md#running-a-limited-test-suite) 包含更多有关如何生成 coverage 报告的细节。 --- url: /developers/core/integration/contributing_to_core.md --- 在此页面上,你将找到有关如何将集成贡献到 Home Assistant Core 的信息。 我们非常乐意接收向 Home Assistant Core 贡献的新集成。 由于这些更改通常比对现有集成的功能更复杂,我们有一组准则,将使所有相关人员的过程更顺利。 ## 集成是否适合纳入? 作为流行的项目,Home Assistant 收到了大量贡献。我们希望确保将时间和资源花在审查和维护用户今天和未来都能受益的集成上。 这意味着我们有一些要求,集成必须满足才能被纳入 Home Assistant Core: * 集成所连接的产品或服务应该可供 Home Assistant 用户购买和使用。这意味着我们不接受尚未发布的产品或处于 private beta 阶段的服务(如 Kickstarter 项目或类似项目)的集成。 * 产品或服务应该是成熟的。我们希望避免公司利用 Home Assistant 作为其新产品的营销平台,因此我们要求产品或服务已广泛可用并拥有一定的用户基础。 如果你的集成不符合这些要求,你可以改为将其作为 custom integration 发布到 GitHub 和 HACS 上。 ## 集成需要满足哪些要求? 符合条件的新集成应满足一系列要求才能被接受。 ### 集成质量量表 为了衡量集成的质量,我们使用 [integration quality scale]。 该量表定义了一套集成应遵循的规则,以被视为达到特定质量级别。 这些规则涵盖集成的各个方面,如文档、测试、代码质量等。 新集成必须达到集成质量量表的 [bronze] 级别。 不要立即追求更高的级别——正如在 [使你的 pull request 尽可能小](#make-your-pull-request-as-small-as-possible) 部分所述,我们应该保持 pull request 小而集中。 [bronze]: /docs/core/integration-quality-scale/rules#-bronze [integration quality scale]: /docs/core/integration-quality-scale ### 用于通信的 Python library 一个重要的 \[集成质量量表规则] 是要求使用 Python library 与产品或服务进行通信。 如果我们需要在集成中实现与产品或服务的通信,Home Assistant 代码库将会非常庞大,也会使维护和测试集成变得更加困难。 通过使用 Python library,我们可以将集成代码聚焦在 Home Assistant 特定的部分(如 entity 定义),并将与产品或服务的通信委托给 library。 这也允许该 library 被其他项目和集成重用,从而改善整个生态系统。 要查看 Python library 的要求,请查看集成质量量表中的 [dependency transparency] 规则。 :::tip 有关如何创建 Python library 的更多信息,请查阅我们关于 \[创建 Python library] 的指南。 ::: [integration quality scale rule]: /docs/core/integration-quality-scale/rules/dependency-transparency.md [dependency transparency]: /docs/core/integration-quality-scale/rules/dependency-transparency.md [creating a Python library]: /docs/api_lib_index.md ## 如何将集成贡献到 Core 一旦你的集成处于良好状态并准备好贡献到 Home Assistant Core,你需要遵循几个步骤来确保它能够被审查。 ### 使你的 pull request 尽可能小 新集成应具有最少的代码和功能,以对用户有用。 范围明确的 pull request 更容易审查和合并,因为这允许审查者审批和合并较小的代码块。 **包含大型代码转 dump 且不遵循这些准则的 pull request 可能会被关闭。** 对于新集成,这意味着: * 限制为单一 platform。 * 不要添加对初始 platform 工作非必要的功能。这包括以下功能: * Diagnostics * Custom service actions * Reauthentication 和 reconfiguration flows * 理想情况下,避免复杂的集成质量量表规则(如 `dynamic-devices` 和 `stale-devices`)。 要了解更多有关如何界定 pull request 范围的信息,请查看我们关于 \[创建完美的 PR] 的指南。 [creating the perfect PR]: /docs/review-process.md#creating-the-perfect-pr ### 确保代码检查通过 请确保你已经设置了合适的开发环境,并在打开 pull request 之前已在本地运行了代码检查。 如果 CI checks 因你的更改而失败,在 checks 通过之前我们无法审查和合并你的 pull request。 请注意,某些测试可能不稳定,因此如果你确信失败与你的代码无关,请等待维护者,而不是每次失败时都尝试重新运行 CI。 :::info 我们的 pre-commit checks 可以更新你的集成目录之外的文件。这些更改应包含在你的 pull request 中。 ::: ### 在 pull request 描述中提供足够的上下文 当你打开 pull request 以将集成贡献到 Home Assistant Core 时,请确保在 pull request 描述中提供足够的上下文。 这包括: * 描述集成所连接的产品或服务。 * 指向用于与产品或服务通信的 library 的 git repository 链接。 --- url: /developers/core/integration/diagnostics.md --- 集成可以提供 diagnostics 以帮助用户收集数据,辅助进行故障排除。可以为 config entries 提供 diagnostics,也可以单独为每个 device entry 提供。 用户可以从集成页面上的 config entry options 菜单下载 config entry diagnostics。对于 device diagnostics,用户可以从 device 信息部分下载(或从其菜单下载,具体取决于集成)。请注意,如果集成未实现 device diagnostics,则 device 页面将提供 config entry diagnostics。 :::warning 确保不暴露敏感数据至关重要。包括但不限于: * 密码和 API keys * Authentication tokens * 位置数据 * 个人信息 Home Assistant 提供了 `async_redact_data` 工具函数,你可以使用它安全地从 diagnostics 输出中删除敏感数据。 ::: 以下是一个实现 config entry 和 device entry diagnostics 的示例: ```python TO_REDACT = [ CONF_API_KEY, APPLIANCE_CODE ] async def async_get_config_entry_diagnostics( hass: HomeAssistant, entry: MyConfigEntry ) -> dict[str, Any]: """Return diagnostics for a config entry.""" return { "entry_data": async_redact_data(entry.data, TO_REDACT), "data": entry.runtime_data.data, } async def async_get_device_diagnostics( hass: HomeAssistant, entry: MyConfigEntry, device: DeviceEntry ) -> dict[str, Any]: """Return diagnostics for a device.""" appliance = _get_appliance_by_device_id(hass, device.id) return { "details": async_redact_data(appliance.raw_data, TO_REDACT), "data": appliance.data, } ``` 集成可以同时提供这两种类型的 diagnostics,或者只提供其中一种。 --- url: /developers/core/integration/options_flow.md --- 通过 config entry 配置的集成可以向用户公开 options,以允许调整集成的行为,例如应集成哪些设备或位置。 Config Entry Options 使用 [Data Flow Entry framework](data_entry_flow_index.md) 允许用户更新 config entry 的 options。想要支持 config entry options 的组件需要定义一个 Options Flow Handler。 ## 选项支持 为了让集成支持 options,它需要在 config flow handler 中有一个 `async_get_options_flow` 方法。调用它将返回组件 options flow handler 的实例。 ```python @staticmethod @callback def async_get_options_flow( config_entry: ConfigEntry, ) -> OptionsFlowHandler: """Create the options flow.""" return OptionsFlowHandler() ``` ## Flow 处理器 Flow handler 的工作原理与 config flow handler 相同,只是 flow 中的第一个 step 始终是 `async_step_init`。当前 config entry 的详细信息可通过 `self.config_entry` 属性访问。 ```python from homeassistant.config_entries import OptionsFlow OPTIONS_SCHEMA = vol.Schema( { vol.Required("show_things"): bool, } ) class OptionsFlowHandler(OptionsFlow): async def async_step_init( self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Manage the options.""" if user_input is not None: return self.async_create_entry(data=user_input) return self.async_show_form( step_id="init", data_schema=self.add_suggested_values_to_schema( OPTIONS_SCHEMA, self.config_entry.options ), ) ``` ## 自动重新加载的选项流 如果集成应在 config options 更改后重新加载,它可以继承 `OptionsFlowWithReload` 而不是 `OptionsFlow`。一旦 options 更改,`OptionsFlowWithReload` 将自动重新加载集成。 由于添加 update listener 最常见的原因是当 options 更改时重新加载集成,因此 `OptionsFlowWithReload` 避免了需要该 listener。 ```python from homeassistant.config_entries import OptionsFlowWithReload OPTIONS_SCHEMA = vol.Schema( { vol.Required("show_things"): bool, } ) class MyOptionsFlow(OptionsFlowWithReload): async def async_step_init( self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Manage the options.""" if user_input is not None: return self.async_create_entry(data=user_input) return self.async_show_form( step_id="init", data_schema=self.add_suggested_values_to_schema( OPTIONS_SCHEMA, self.config_entry.options ), ) ``` ## 信号更新 如果集成应在 options 更新后做出响应,你可以注册一个 update listener 到 config entry,当 entry 被更新时将调用它。通过在集成的 `__init__.py` 中的 `async_setup_entry` 函数中添加以下内容来注册 listener: ```python entry.async_on_unload(entry.add_update_listener(update_listener)) ``` 使用上述方法意味着 Listener 在 entry 加载时附加,并在卸载时分离。Listener 应是一个 async 函数,其输入与 async\_setup\_entry 相同。然后可以从 `entry.options` 访问 Options。 ```python async def update_listener(hass: HomeAssistant, config_entry: ConfigEntry): """Handle options update.""" ``` --- url: /developers/core/integration/system_health.md --- system health platform 允许集成为用户提供帮助了解集成状态的信息。这可以包括诸如 endpoint 的可用性、集成当前连接到的 server、还剩多少请求配额等详细信息。 用户可以通过前往 **设置** -> **系统** -> **维修**,然后在上部右侧三点菜单中选择 **系统信息** 来查看聚合的系统健康信息。 ## Implementing the system health platform 向集成添加 `system_health.py` 文件,并实现 `async_register` 方法,以注册 info 回调: ```python """Provide info to system health.""" from homeassistant.components import system_health from homeassistant.core import HomeAssistant, callback @callback def async_register(hass: HomeAssistant, register: system_health.SystemHealthRegistration) -> None: """Register system health callbacks.""" register.async_register_info(system_health_info) ``` info 回调应返回一个字典,其值可以是任何类型,包括 coroutine。如果字典条目设置了 coroutine,frontend 将显示等待指示器,并在 coroutine 完成并提供结果后自动更新。 ```python async def system_health_info(hass: HomeAssistant) -> dict[str, Any]: """Get info for the info page.""" config_entry: ExampleConfigEntry = hass.config_entries.async_entries(DOMAIN)[0] quota_info = await config_entry.runtime_data.async_get_quota_info() return { "consumed_requests": quota_info.consumed_requests, "remaining_requests": quota_info.requests_remaining, # checking the url can take a while, so set the coroutine in the info dict "can_reach_server": system_health.async_check_can_reach_url(hass, ENDPOINT), } ``` :::tip system\_health 组件提供 `async_check_can_reach_url` helper 作为一种轻松实现检查 URL 可用性的方式。 ::: 使用 `strings.json` 文件中的 `system_health` 部分翻译 info 字典中的每个 key,以提供良好的描述: ```json "system_health": { "info": { "can_reach_server": "Reach Example server", "remaining_requests": "Remaining allowed requests" } } ``` --- url: /developers/core/integration/yaml_configuration.md --- `configuration.yaml` 是由用户定义的配置文件。它由 Home Assistant 在首次启动时自动创建。它定义了要加载哪些组件。 :::info 关于设备和/或服务 YAML 配置的说明 与设备和/或服务通信的集成通过 config flow 进行配置。在极少数情况下,我们可以做例外处理。现有但不应该有 YAML 配置的集成被允许并鼓励实现 config flow 并移除 YAML 支持。对于这些现有集成的 YAML 配置的更改将不再被接受。 更多详细信息请阅读 [ADR-0010](https://github.com/home-assistant/architecture/blob/master/adr/0010-integration-configuration.md#decision) ::: ## 预处理 Home Assistant 将根据指定要加载的组件对配置进行一些预处理。 ### CONFIG\_SCHEMA 如果组件定义了变量 `CONFIG_SCHEMA`,传入的 config 对象将是 config 通过 `CONFIG_SCHEMA` 运行后的结果。`CONFIG_SCHEMA` 应是一个 voluptuous schema。 ### PLATFORM\_SCHEMA :::info 下面描述的 platform-key 配置结构(配置列在实体组件 domain 下,如 `switch`)是实体组件的现有机制。新集成不得使用它。根据 [ADR-0007](https://github.com/home-assistant/architecture/blob/master/adr/0007-integration-config-yaml-structure.md),如果存在,集成的所有 YAML 配置必须放在集成自己的 domain key 下,通过 `discovery.async_load_platform` 加载 platforms。现有集成中 platform 部分中的 YAML 配置在该集成被重构前被冻结。 ::: 如果组件定义了变量 `PLATFORM_SCHEMA`,该组件将被视为实体组件。实体组件的配置是一个 platform 配置列表。 Home Assistant 将收集该组件的所有 platform 配置。它会通过在组件的 domain(即 `light`)下以及任何 domain + 附加文本的条目下查找配置条目来完成此操作。 在收集 platform 配置时,Home Assistant 会对其进行验证。它会检查 platform 是否存在,如果 platform 定义了 `PLATFORM_SCHEMA`,则验证是否符合该 schema。如果未定义,则验证配置是否符合组件中定义的 `PLATFORM_SCHEMA`。任何引用不存在的 platforms 或包含无效配置的内容都将被移除。 以下 `configuration.yaml`: ```yaml unrelated_component: some_key: some_value switch: platform: example1 switch living room: - platform: example2 some_config: true - platform: invalid_platform ``` 将被传递给组件如下: ```python { "unrelated_component": { "some_key": "some_value" }, "switch": [ { "platform": "example1" }, { "platform": "example2", "some_config": True } ], } ``` --- url: /developers/core/llm/index.md --- Home Assistant 可以与大型语言模型(LLMs)交互。通过将 Home Assistant API 暴露给 LLM,LLM 可以获取数据或控制 Home Assistant 以更好地协助用户。Home Assistant 自带内置的 LLM API,但 custom integrations 可以注册自己的 API 以提供额外功能。 ## 内置 Assist API Home Assistant 具有内置的 API,可将 Assist API 暴露给 LLMs。此 API 允许 LLMs 通过 [intents](/developers/intent_builtin.md) 与 Home Assistant 交互,并可以通过注册 intents 来扩展。 Assist API 等同于内置 conversation agent 也能访问的 capabilities 和 exposed entities。无法执行任何管理任务。 ## 贡献工具 集成可以向 LLM API 贡献 tools,而无需拥有完整的 API。`llm` 集成发现 `/llm.py` platform,该 platform 暴露 `async_get_tools` hook。该 platform 被延迟导入,仅在 LLM 请求需要其 tools 时才被查询。 `async_get_tools` 是一个回调,对每个请求根据请求的 `LLMContext` 和被组装 API 的 `api_id` 进行评估。它返回要暴露的 tools,以及一个与该 tools 一起传输的可选 prompt fragment;如果集成没有为某个 API 贡献内容,则返回 `None`。因为它按请求运行,所以它可以根据上下文返回不同的 tools 集合,例如发起请求的 assistant 或 device,或所选 API。 ```python # example_integration/llm.py from homeassistant.components import llm from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.llm import LLMContext @callback def async_get_tools( hass: HomeAssistant, llm_context: LLMContext, api_id: str ) -> llm.LLMTools | None: """Return the tools to expose to the LLM.""" return llm.LLMTools( tools=[MyTool()], prompt="Use MyTool to ...", # Optional prompt fragment ) ``` 该 hook 仅在 `llm` 集成设置完成后才被调用,因此 platform 本身不需要依赖于 `llm`。 请参阅 [Tools](#tools) 了解如何实现 platform 返回的 `Tool` 对象。 ## 支持 LLM API LLM API 需要在集成中的两个位置进行集成。用户需要能够配置使用哪些 APIs,并在与 LLM 交互时将 APIs 提供的 tools 传递给 LLM。 ### 选项流程 所选的 API 应存储在 config entry options 中。它应持有所选 API ID 的字符串或列表(如有)。如果没有选择 API,则必须省略该 key。 在 options flow 中,应向用户提供 selector 以选择使用哪个 API。 ```python from types import MappingProxyType from homeassistant.const import CONF_LLM_HASS_API from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import llm from homeassistant.helpers.selector import ( SelectOptionDict, SelectSelector, SelectSelectorConfig, ) @callback def async_get_options_schema( hass: HomeAssistant, options: MappingProxyType[str, Any], ) -> vol.Schema: """Return the options schema.""" apis: list[SelectOptionDict] = [ SelectOptionDict( label=api.name, value=api.id, ) for api in llm.async_get_apis(hass) ] return vol.Schema( { vol.Optional( CONF_LLM_HASS_API, description={"suggested_value": options.get(CONF_LLM_HASS_API)}, ): SelectSelector(SelectSelectorConfig(options=apis, multiple=True)), } ) ``` ### 获取工具 在与 LLM 交互时,提供的 `ChatLog` 将从所选 API 提供任何 selected tools,conversation entity 应将它们与 API 提供的额外 prompt 一起传递给 LLM。 ```python from homeassistant.const import CONF_LLM_HASS_API, CONF_PROMPT from homeassistant.core import HomeAssistant, callback from homeassistant.components import conversation from homeassistant.helpers import intent, llm from .const import DOMAIN class MyConversationEntity(conversation.ConversationEntity): def __init__(self, entry: ConfigEntry) -> None: """Initialize the agent.""" self.entry = entry ... async def _async_handle_message( self, user_input: conversation.ConversationInput, chat_log: conversation.ChatLog, ) -> conversation.ConversationResult: """Call the API.""" try: await chat_log.async_provide_llm_data( user_input.as_llm_context(DOMAIN), self.entry.options.get(CONF_LLM_HASS_API), self.entry.options.get(CONF_PROMPT), user_input.extra_system_prompt, ) except conversation.ConverseError as err: return err.as_conversation_result() tools: list[dict[str, Any]] | None = None if chat_log.llm_api: tools = [ _format_tool(tool) # TODO format the tools as your LLM expects for tool in chat_log.llm_api.tools ] messages = [ m for content in chat_log.content for m in _convert_content(content) # TODO format messages ] # 与 LLM 交互并传递 tools request = user_input.text for _iteration in range(10): response = ... # 向 LLM 发送请求并获取流式响应 messages.extend( [ _convert_content(content) # TODO format messages async for content in chat_log.async_add_delta_content_stream( user_input.agent_id, _transform_stream(response) # TODO call tools and stream responses ) ] ) if not chat_log.unresponded_tool_results: break # 向用户发送最终响应 intent_response = intent.IntentResponse(language=user_input.language) intent_response.async_set_speech(chat_log.content[-1].content or "") return conversation.ConversationResult( response=intent_response, conversation_id=chat_log.conversation_id, continue_conversation=chat_log.continue_conversation, ) ``` ## 创建你自己的 API 要创建自己的 API,需要创建一个继承自 `API` 的类,并实现 `async_get_api_instance` 方法。它返回一个 `APIInstance`,其中包含代表你想要暴露给 LLM 的功能的 `Tool` 对象列表,以及告诉 LLM 如何使用它们的 prompt。 ### 工具 `llm.Tool` 类表示 LLM 可以调用的工具。 ```python from homeassistant.core import HomeAssistant from homeassistant.helpers import llm from homeassistant.helpers.llm import LLMContext, ToolInput from homeassistant.util import dt as dt_util from homeassistant.util.json import JsonObjectType class TimeTool(llm.Tool): """Tool to get the current time.""" name = "GetTime" description = "Returns the current time." # 可选。输入参数的 voluptuous schema。 parameters = vol.Schema({ vol.Optional('timezone'): str, }) async def async_call( self, hass: HomeAssistant, tool_input: ToolInput, llm_context: LLMContext ) -> JsonObjectType: """Call the tool.""" if "timezone" in tool_input.tool_args: tzinfo = dt_util.get_time_zone(tool_input.tool_args["timezone"]) else: tzinfo = dt_util.DEFAULT_TIME_ZONE return {"time": dt_util.now(tzinfo).isoformat()} ``` `llm.Tool` 类具有以下属性: | Name | Type | Description | |---------------------|------------|----------------------------------------------------------------------------------------------------------------| | `name` | string | 工具的名称。必需。 | | `description` | string | 工具的描述,帮助 LLM 理解何时以及如何调用它。可选,但推荐。 | | `parameters` | vol.Schema | 参数的 voluptuous schema。默认为 vol.Schema({}) | `llm.Tool` 类具有以下方法: #### `async_call` 当被 LLM 调用时执行工具的实际操作。这必须是一个 async 方法。其参数为 `hass`、`llm.ToolInput` 实例以及请求的 `llm.LLMContext`。 响应数据必须是 dict 且可序列化为 JSON [`homeassistant.util.json.JsonObjectType`](https://github.com/home-assistant/core/blob/dev/homeassistant/util/json.py)。 错误必须作为 `HomeAssistantError` 异常(或其子类)抛出。响应数据不应包含用于错误处理的错误代码。 `ToolInput` 具有以下属性: | Name | Type | Description | |-------------------|---------|---------------------------------------------------------------------------------------------------------| | `tool_name` | string | 正在调用的工具的名称 | | `tool_args` | dict | LLM 提供的参数。使用 `parameters` schema 进行转换和验证。 | | `id` | string | 工具调用的唯一标识符。默认为新生成的 ULID。 | | `external` | bool | 工具调用是否在 Home Assistant 之外执行(例如由 model provider 执行)。External 工具调用不会分发给 API 的 tools。默认为 `False`。 | 在请求的所有 tools 之间共享的上下文(conversation agent、请求的 device 等)作为 `async_call` 的 `llm.LLMContext` 单独提供。 `LLMContext` 具有以下属性: | Name | Type | Description | |-------------------|---------|---------------------------------------------------------------------------------------------------------| | `platform` | string | 处理 LLM 请求的 conversation agent 的 DOMAIN | | `context` | Context | 请求的 `homeassistant.core.Context` | | `language` | string | conversation agent 的语言,或 "\*" 表示任意语言 | | `assistant` | string | 用于控制 exposed entities 的 assistant 名称。目前仅支持 `conversation`。 | | `device_id` | string | 用户用来发起对话的 device 的 device\_id。 | ### API API 对象允许创建 API instances。API Instance 代表一组将提供给 LLM 的 tools。 ```python from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers import llm from homeassistant.helpers.llm import APIInstance, LLMContext from homeassistant.util import dt as dt_util from homeassistant.util.json import JsonObjectType class MyAPI(llm.API): """My own API for LLMs.""" async def async_get_api_instance(self, llm_context: LLMContext) -> APIInstance: """Return the instance of the API.""" return APIInstance( api=self, api_prompt="Call the tools to fetch data from Home Assistant.", llm_context=llm_context, tools=[TimeTool()], ) async def async_setup_api(hass: HomeAssistant, entry: ConfigEntry) -> None: """Register the API with Home Assistant.""" # 如果 API 与 Config Entry 关联,则当 config entry 卸载时,必须注销 LLM API。 unreg = llm.async_register_api( hass, MyAPI( hass=hass, id=f"my_unique_key-{entry.entry_id}", name=entry.title, ), ) entry.async_on_unload(unreg) ``` `llm.API` 类具有以下属性: | Name | Type | Description | |-------------------|---------------|---------------------------------------------------------------------------------------------------------| | `hass` | HomeAssistant | Home Assistant 实例。必需。 | | `id` | string | API 的唯一标识符。必需。 | | `name` | string | API 的名称。必需。 | 所有字段都是仅关键字的,因此 API 必须使用关键字参数实例化。 `llm.APIInstance` 类具有以下属性: | Name | Type | Description | |----------------------|-------------|---------------------------------------------------------------------------------------------------------| | `api` | API | API 对象。必需。 | | `api_prompt` | string | 对 LLM 如何使用 LLM tools 的说明。必需。 | | `llm_context` | LLMContext | 工具调用的上下文。必需。 | | `tools` | list\[Tool] | 此 API 中可用的 tools。必需。 | | `custom_serializer` | Callable | 可选函数,用于将 voluptuous schemas(如 selectors)转换为 LLM 期望的 JSON schema。默认为 `None`。 | ## 通过 MCP 暴露 API 你无需执行任何特殊操作即可使 API 通过 [Model Context Protocol (MCP)](https://modelcontextprotocol.io) 可用。一旦用户设置好 [MCP Server 集成](https://www.home-assistant.io/integrations/mcp_server/),每个已注册的 LLM API 都会自动通过 MCP 提供。 每个 API 都可以访问自己的 Streamable HTTP endpoint,通过其 API ID 寻址: ```text /api/mcp/ ``` 例如,内置的 Assist API 在 `/api/mcp/assist` 可用,而使用 `llm.async_register_api` 注册的 custom API 在 `/api/mcp/` 可用。 这些 per-API endpoints 需要 admin access token(Assist API 除外)。MCP Server 集成还在 `/api/mcp` 暴露单个配置的 API,供不通过 ID 指向特定 API 的 clients 使用。 ### 列出已注册的 API 由于这些 endpoints 是通过 API ID 寻址的,clients 需要一种方式来查找哪些 ID 存在。已注册的 APIs 可以通过 [WebSocket API](/developers/api/websocket.md) 列出: ```json { "id": 1, "type": "llm/api/list" } ``` server 以注册顺序响应每个已注册 API 的 ID 和名称: ```json { "id": 1, "type": "result", "success": true, "result": { "apis": [ { "id": "assist", "name": "Assist" } ] } } ``` API 的 `id` 是 `/api/mcp/` 中使用的值,而 `name` 是向用户显示的名称。此命令需要 admin 用户。 --- url: /developers/core/platform/application_credentials.md --- 集成可以支持 [通过 OAuth2 配置](/developers/core/integration/config_flow.md#configuration-via-oauth2),允许用户链接其账户。集成可以添加 `application_credentials.py` 文件并实现下面描述的功能。 OAuth2 需要在应用程序和 provider 之间共享的凭据。在 Home Assistant 中,集成特定的 OAuth2 凭据通过一种或多种方法提供: * *本地 OAuth 与 Application Credentials 组件*:用户与云 provider 创建自己的凭据,通常作为 application 开发者操作,然后将凭据注册到 Home Assistant 和集成中。此方法对所有支持 OAuth2 的集成是*必需的*。 * *Cloud Account Linking 与 Cloud 组件*:Nabu Casa 与云 provider 注册凭据,提供无缝的用户体验。此方法提供无缝的用户体验,是*推荐的*([更多信息](/developers/core/integration/config_flow.md#configuration-via-oauth2))。 ## 添加支持 集成通过在 `manifest.json` 中添加对 `application_credentials` 组件的依赖来支持 application credentials: ```json { ... "dependencies": ["application_credentials"], ... } ``` 然后在集成文件夹中添加名为 `application_credentials.py` 的文件,并实现以下内容: ```python from homeassistant.core import HomeAssistant from homeassistant.components.application_credentials import AuthorizationServer async def async_get_authorization_server(hass: HomeAssistant) -> AuthorizationServer: """Return authorization server.""" return AuthorizationServer( authorize_url="https://example.com/auth", token_url="https://example.com/oauth2/v4/token" ) ``` ### AuthorizationServer `AuthorizationServer` 表示集成使用的 [OAuth2 授权服务器](https://datatracker.ietf.org/doc/html/rfc6749)。 | Name | Type | | Description | | ------------- | ---- | -------------------------------------------------------------------------------------------------- | ----------- | | authorize\_url | str | **必需** | 用户在配置流程中被重定向到的 OAuth 授权 URL。 | | token\_url | str | **必需** | 用于获取 access token 的 URL。 | ### 自定义 OAuth2 实现 集成也可以在 `application_credentials.py` 中提供自定义的 `AbstractOAuth2Implementation`,如下所示: ```python from homeassistant.core import HomeAssistant from homeassistant.helpers import config_entry_oauth2_flow from homeassistant.components.application_credentials import AuthImplementation, AuthorizationServer, ClientCredential class OAuth2Impl(AuthImplementation): """Custom OAuth2 implementation.""" # ... 覆盖 AbstractOAuth2Implementation 细节 async def async_get_auth_implementation( hass: HomeAssistant, auth_domain: str, credential: ClientCredential ) -> config_entry_oauth2_flow.AbstractOAuth2Implementation: """Return auth implementation for a custom auth implementation.""" return OAuth2Impl( hass, auth_domain, credential, AuthorizationServer( authorize_url="https://example.com/auth", token_url="https://example.com/oauth2/v4/token" ) ) ``` ### 支持 PKCE 的授权流程 如果你想支持 [PKCE](https://www.rfc-editor.org/rfc/rfc7636),可以在 `application_credentials.py` 中返回 `LocalOAuth2ImplementationWithPkce`,如下所示: ```python from homeassistant.core import HomeAssistant from homeassistant.helpers.config_entry_oauth2_flow import AbstractOAuth2Implementation, LocalOAuth2ImplementationWithPkce from homeassistant.components.application_credentials import AuthImplementation, ClientCredential async def async_get_auth_implementation( hass: HomeAssistant, auth_domain: str, credential: ClientCredential ) -> AbstractOAuth2Implementation: """Return auth implementation for a custom auth implementation.""" return LocalOAuth2ImplementationWithPkce( hass, auth_domain, credential.client_id, authorize_url="https://example.com/auth", token_url="https://example.com/oauth2/v4/token", client_secret=credential.client_secret, # 可选,默认 `""` code_verifier_length=128 # 可选 ) ``` ## 导入 YAML 凭据 以前接受 YAML 凭据的集成可以使用 application credentials 集成提供的 import API `async_import_client_credential` 导入凭据。 以下是来自一个以前接受 YAML 凭据的集成的示例: ```python from homeassistant.components.application_credentials import ( ClientCredential, async_import_client_credential, ) # 集成的示例 configuration.yaml schema CONFIG_SCHEMA = vol.Schema( { DOMAIN: vol.Schema( { vol.Required(CONF_CLIENT_ID): cv.string, vol.Required(CONF_CLIENT_SECRET): cv.string, } ) }, ) async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up the component.""" if DOMAIN not in config: return True await async_import_client_credential( hass, DOMAIN, ClientCredential( config[DOMAIN][CONF_CLIENT_ID], config[DOMAIN][CONF_CLIENT_SECRET], ), ) ``` 新集成不应在 configuration.yaml 中接受凭据,因为用户可以在 Application Credentials 用户界面中输入凭据。 ### ClientCredential `ClientCredential` 表示由用户提供的 client 凭据。 | Name | Type | | Description | | ------------- | ---- | ------------------------------------------------------------------------- | ----------- | | client\_id | str | **必需** | 用户提供的 OAuth Client ID。 | | client\_secret | str | **必需** | 用户提供的 OAuth Client Secret。 | ## 翻译 Application Credentials 的 translations 在组件翻译文件 `strings.json` 的 `application_credentials` key 下定义。例如: ```json { "application_credentials": { "description": "导航到 [developer console]({console_url}) 创建凭据,然后在下方输入。", } } ``` 你还可以可选地添加 description placeholder keys,通过在 `application_credentials.py` 中添加新方法来将占位符添加到消息中,如下所示: ```python from homeassistant.core import HomeAssistant async def async_get_description_placeholders(hass: HomeAssistant) -> dict[str, str]: """Return description placeholders for the credentials dialog.""" return { "console_url": "https://example.com/developer/console", } ``` 在本地开发时,你需要运行 `python3 -m script.translations develop` 才能看到对 `strings.json` 所做的更改。[更多关于翻译 Home Assistant 的信息。](translations.md) --- url: /developers/core/platform/backup.md --- 集成实现备份平台有两个主要目的: 1. 添加一个 backup agent,可以将备份上传到某个本地或远程位置。 2. 在创建备份之前暂停或准备集成操作,和/或在备份后运行某些操作。 ## 备份代理 要添加一个或多个 backup agents,请在 `backup.py` 中实现 `async_get_backup_agents` 和 `async_register_backup_agents_listener` 这两个方法。示例: ```python async def async_get_backup_agents( hass: HomeAssistant, ) -> list[BackupAgent]: """Return a list of backup agents.""" if not hass.config_entries.async_loaded_entries(DOMAIN): LOGGER.debug("No config entry found or entry is not loaded") return [] return [ExampleBackupAgent()] @callback def async_register_backup_agents_listener( hass: HomeAssistant, *, listener: Callable[[], None], **kwargs: Any, ) -> Callable[[], None]: """Register a listener to be called when agents are added or removed. :return: A function to unregister the listener. """ hass.data.setdefault(DATA_BACKUP_AGENT_LISTENERS, []).append(listener) @callback def remove_listener() -> None: """Remove the listener.""" hass.data[DATA_BACKUP_AGENT_LISTENERS].remove(listener) return remove_listener ``` 存储在 `async_register_backup_agents_listener` 中的 listener 应在每次需要重新加载 backup agents 时被调用,以移除过期的 agents 并添加新的 agents。这可以通过在 `async_setup_entry` 期间注册 listeners 来完成: ```python async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up config entry.""" # do things to set up your config entry # 通知 backup listeners def notify_backup_listeners() -> None: for listener in hass.data.get(DATA_BACKUP_AGENT_LISTENERS, []): listener() entry.async_on_unload(entry.async_on_state_change(notify_backup_listeners)) return True ``` Backup agent 应实现 `BackupAgent` 基类的抽象接口,如下例所示: ```python from homeassistant.components.backup import BackupAgent, BackupAgentError, OnProgressCallback from .const import DOMAIN class ExampleBackupAgent(BackupAgent): """Backup agent interface.""" domain = DOMAIN name = "Example Backup-Agent" unique_id = "example_stable_id" async def async_download_backup( self, backup_id: str, **kwargs: Any, ) -> AsyncIterator[bytes]: """Download a backup file. Raises BackupNotFound if the backup does not exist. :param backup_id: The ID of the backup that was returned in async_list_backups. :return: An async iterator that yields bytes. """ async def async_upload_backup( self, *, open_stream: Callable[[], Coroutine[Any, Any, AsyncIterator[bytes]]], backup: AgentBackup, on_progress: OnProgressCallback, **kwargs: Any, ) -> None: """Upload a backup. :param open_stream: A function returning an async iterator that yields bytes. :param backup: Metadata about the backup that should be uploaded. :param on_progress: A callback to report the number of uploaded bytes. """ async def async_delete_backup( self, backup_id: str, **kwargs: Any, ) -> None: """Delete a backup file. Raises BackupNotFound if the backup does not exist. :param backup_id: The ID of the backup that was returned in async_list_backups. """ async def async_list_backups(self, **kwargs: Any) -> list[AgentBackup]: """List backups.""" async def async_get_backup( self, backup_id: str, **kwargs: Any, ) -> AgentBackup: """Return a backup. Raises BackupNotFound if the backup does not exist. """ ``` Backup agents 应在出错时抛出 `BackupAgentError`(或 `BackupAgentError` 的子类)异常。其他异常不应从 backup agent 中抛出。 ### 报告上传进度 `async_upload_backup` 方法接收一个 `on_progress` callback,agents 可以使用它来报告上传进度。调用 callback 时传入到目前为止上传的总字节数(整数): ```python on_progress(bytes_uploaded=bytes_sent) ``` 备份管理器使用此信息来触发 `UploadBackupEvent` 事件,允许 frontend 向用户显示上传进度。Agents 应在上传过程中定期调用此 callback,例如在每次发送数据块之后。 ## 预操作和后操作 当 Home Assistant 正在创建备份时,可能需要暂停集成中的某些操作,或 dump 数据以便正确恢复。 这是通过在 `backup.py` 中添加两个函数(`async_pre_backup` 和 `async_post_backup`)来完成的。 ### 添加支持 为新集成添加备份支持的最快方法是使用我们内置的 scaffold 模板。从 Home Assistant 开发环境运行 `python3 -m script.scaffold backup` 并按照说明操作。 如果你更喜欢手动方式,请在集成文件夹中创建一个名为 `backup.py` 的新文件,并实现以下方法: ```python from homeassistant.core import HomeAssistant async def async_pre_backup(hass: HomeAssistant) -> None: """Perform operations before a backup starts.""" async def async_post_backup(hass: HomeAssistant) -> None: """Perform operations after a backup finishes.""" ``` --- url: /developers/core/platform/media_source.md --- media source platform 允许集成为 Home Assistant 暴露可浏览和可播放的媒体。Media sources 出现在 media browser UI 中,让用户可以浏览层级化的媒体库并在 media player 设备上播放内容。 ## 实现媒体源 要添加 media source 支持,请在集成目录中创建 `media_source.py` 文件。无需更改 `manifest.json`——Home Assistant 通过 integration platform 机制自动发现 `media_source.py` 模块。 该模块必须定义一个 `async_get_media_source` 函数,返回你的 `MediaSource` 子类实例: ```python from homeassistant.components.media_player import BrowseError, MediaClass, MediaType from homeassistant.components.media_source import ( BrowseMediaSource, MediaSource, MediaSourceItem, PlayMedia, Unresolvable, ) from homeassistant.core import HomeAssistant from .const import DOMAIN async def async_get_media_source(hass: HomeAssistant) -> MyMediaSource: """Set up my media source.""" return MyMediaSource(hass) class MyMediaSource(MediaSource): """Provide media from my integration.""" name = "My Service" def __init__(self, hass: HomeAssistant) -> None: """Initialize the media source.""" super().__init__(DOMAIN) self.hass = hass async def async_resolve_media(self, item: MediaSourceItem) -> PlayMedia: """Resolve a media item to a playable URL.""" ... async def async_browse_media(self, item: MediaSourceItem) -> BrowseMediaSource: """Browse media.""" ... ``` ## `MediaSource` 基类 你的 media source 必须继承 `MediaSource` 并实现 `async_resolve_media` 和 `async_browse_media`。可以可选地实现 `async_search_media` 以允许用户搜索你的媒体。 | Method | Description | |---|---| | `async_resolve_media(item)` | 将 `MediaSourceItem` 解析为包含可播放 URL 和 MIME type 的 `PlayMedia`。如果项目无法解析,抛出 `Unresolvable`。 | | `async_browse_media(item)` | 返回表示给定项目处可浏览结构的 `BrowseMediaSource`。如果浏览失败,抛出 `BrowseError`。 | | `async_search_media(item, query)` | 可选。返回给定 `SearchMediaQuery` 的 `SearchMedia` 结果。请参阅 [搜索媒体](#searching-media)。 | 将类属性 `name` 设置为你 source 的人类可读名称。如果未设置,则默认为集成 domain。 ## 浏览媒体 `async_browse_media` 方法接收一个 `MediaSourceItem` 并必须返回 `BrowseMediaSource` 树。当 `item.identifier` 为空时,返回媒体层级的根。对于非空 identifiers,返回该项目下的子项。 ```python async def async_browse_media(self, item: MediaSourceItem) -> BrowseMediaSource: """Browse media.""" if item.identifier: raise BrowseError("Unknown item") children = [ BrowseMediaSource( domain=DOMAIN, identifier=entity.entity_id, media_class=MediaClass.VIDEO, media_content_type=entity.content_type, title=entity.name, thumbnail=f"/api/my_proxy/{entity.entity_id}", can_play=True, can_expand=False, ) for entity in self.hass.data[DATA_COMPONENT].entities ] return BrowseMediaSource( domain=DOMAIN, identifier=None, media_class=MediaClass.APP, media_content_type="", title="My Service", can_play=False, can_expand=True, children_media_class=MediaClass.VIDEO, children=children, ) ``` ### `BrowseMediaSource` `BrowseMediaSource` 扩展了 media player 的 `BrowseMedia`,并自动从 `domain` 和 `identifier` 构造 `media_content_id`。 | Parameter | Type | Description | |---|---|---| | `domain` | `str` | 你的集成 domain。 | | `identifier` | `str \| None` | 项目特定的标识符。根项目使用 `None`。 | | `media_class` | `MediaClass` | 媒体类型(例如 `MediaClass.APP`、`MediaClass.DIRECTORY`、`MediaClass.MUSIC`、`MediaClass.VIDEO`、`MediaClass.IMAGE`)。 | | `media_content_type` | `MediaType \| str` | 内容的 MIME type 或媒体类型(例如 `"audio/mpeg"`)。 | | `title` | `str` | 向用户显示的标题。 | | `can_play` | `bool` | 项目是否可以直接播放。 | | `can_expand` | `bool` | 项目是否可以进一步浏览(有子项)。 | | `can_search` | `bool` | 项目是否可以被搜索。当为 `True` 时,media browser 会为此项目显示搜索栏。默认为 `False`。请参阅 [搜索媒体](#searching-media)。 | | `search_media_classes` | `list[MediaClass] \| None` | 可选的 media class 列表,作为此项目的搜索过滤器。设置后,media browser 允许用户将搜索范围缩小到这些 class,它们随后作为 `SearchMediaQuery` 中的 `media_filter_classes` 传回。默认为 `None`。请参阅 [搜索媒体](#searching-media)。 | | `children` | `list[BrowseMediaSource] \| None` | 子项。仅在浏览的父项目上设置。 | | `children_media_class` | `MediaClass \| None` | 子项的 media class。未设置时自动计算。 | | `thumbnail` | `str \| None` | 缩略图片的 URL。 | | `not_shown` | `int` | 未包含的子项数量(例如,被过滤掉)。默认为 `0`。 | ### 分层浏览 对于深层媒体层级,使用 identifier 编码路径。一种常见的模式是在 identifier 内使用 `/` 作为分隔符: ```python async def async_browse_media(self, item: MediaSourceItem) -> BrowseMediaSource: """Browse media.""" category, _, sub_id = (item.identifier or "").partition("/") if category == "albums" and sub_id: return await self._async_browse_album(sub_id) if category == "albums": return await self._async_browse_albums() # 根 return BrowseMediaSource( domain=DOMAIN, identifier=None, media_class=MediaClass.APP, media_content_type="", title="My Service", can_play=False, can_expand=True, children=[ BrowseMediaSource( domain=DOMAIN, identifier="albums", media_class=MediaClass.DIRECTORY, media_content_type=MediaType.MUSIC, title="Albums", can_play=False, can_expand=True, ), ], ) ``` ## 搜索媒体 搜索是可选的。实现 `async_search_media` 以允许用户从 media browser 搜索你的 media source。它接收正在搜索的 `MediaSourceItem`(搜索开始的位置)和一个 `SearchMediaQuery`,并返回 `SearchMedia` 结果: ```python from homeassistant.components.media_player import SearchMedia, SearchMediaQuery async def async_search_media( self, item: MediaSourceItem, query: SearchMediaQuery ) -> SearchMedia: """Search media.""" tracks = await self.api.search(query.search_query) results = [ BrowseMediaSource( domain=DOMAIN, identifier=track.id, media_class=MediaClass.MUSIC, media_content_type=track.mime_type, title=track.title, can_play=True, can_expand=False, ) for track in tracks ] return SearchMedia(result=results) ``` `item` 参数告诉你搜索从哪里开始,因此你可以将结果范围限定为该部分层级。当 `query.media_filter_classes` 被设置时,仅返回 `media_class` 在列表中的项目。 ### `SearchMediaQuery` 传递给 `async_search_media` 的 `SearchMediaQuery` 具有以下属性: | Attribute | Type | Default | Description | |---|---|---|---| | `search_query` | `str` | *必需* | 用户输入的搜索字符串。 | | `media_content_type` | `MediaType \| str \| None` | `None` | 要搜索的内容类型。 | | `media_content_id` | `str \| None` | `None` | 要搜索的内容 ID。 | | `media_filter_classes` | `list[MediaClass] \| None` | `None` | 设置后,仅返回 `media_class` 在此列表中的项目。 | ### `SearchMedia` `SearchMedia` 包装匹配项目列表。 | Field | Type | Description | |---|---|---| | `result` | `Sequence[BrowseMedia]` | 与查询匹配的项目。 | ### 宣传搜索支持 media browser 仅为宣传了搜索的项目显示搜索栏。将 `can_search=True` 设置在 `async_browse_media()` 返回的 `BrowseMediaSource` 项目上,以在浏览时支持搜索: ```python async def async_browse_media(self, item: MediaSourceItem) -> BrowseMediaSource: """Browse media.""" return BrowseMediaSource( domain=DOMAIN, identifier=item.identifier, media_class=MediaClass.APP, media_content_type="", title="My Service", can_play=False, can_expand=True, can_search=True, children=[BrowseMediaSource(...), BrowseMediaSource(...)], ) ``` 如果只想在特定路径启用搜索支持,可以在浏览时基于当前 `MediaSourceItem`(通常是可浏览的目录)将 `can_search=True` 设置在 `async_browse_media()` 返回的 `BrowseMediaSource` 项目上: ```python async def async_browse_media(self, item: MediaSourceItem) -> BrowseMediaSource: """Browse media.""" can_search = False # 根节点的 item.identifier 将为 None if item.identifier: can_search = is_searchable(item.identifier) return BrowseMediaSource( domain=DOMAIN, identifier=item.identifier, media_class=MediaClass.APP, media_content_type="", title="My Service", can_play=False, can_expand=True, can_search=can_search, children=[BrowseMediaSource(...), BrowseMediaSource(...)], ) ``` ### 宣传搜索过滤器 要让用户缩小搜索范围,在可搜索项目上将 `search_media_classes` 设置为该位置有意义的 `MediaClass` 值列表。media browser 将这些作为过滤器选项提供,用户选择的 class 作为 [`SearchMediaQuery`](#searchmediaquery) 中的 `media_filter_classes` 传回。在 `async_search_media` 中遵循该列表,仅返回 `media_class` 被包含的项目: ```python from homeassistant.components.media_player import MediaClass async def async_browse_media(self, item: MediaSourceItem) -> BrowseMediaSource: """Browse media.""" return BrowseMediaSource( domain=DOMAIN, identifier=item.identifier, media_class=MediaClass.APP, media_content_type="", title="My Service", can_play=False, can_expand=True, can_search=True, search_media_classes=[MediaClass.ALBUM, MediaClass.ARTIST, MediaClass.TRACK], children=[BrowseMediaSource(...), BrowseMediaSource(...)], ) ``` ## 解析媒体 `async_resolve_media` 方法将媒体项目解析为可播放 URL。它接收一个 `MediaSourceItem` 并返回 `PlayMedia` 实例: ```python async def async_resolve_media(self, item: MediaSourceItem) -> PlayMedia: """Resolve a media item to a playable URL.""" track = await self.api.get_track(item.identifier) if not track: raise Unresolvable(f"Could not resolve: {item.identifier}") return PlayMedia(track.stream_url, track.mime_type) ``` ### `PlayMedia` | Field | Type | Description | |---|---|---| | `url` | `str` | 要播放的 URL。可以是绝对 URL 或由 Home Assistant 提供的相对路径。 | | `mime_type` | `str` | 媒体的 MIME type(例如 `"audio/mpeg"`、`"video/mp4"`、`"image/jpeg"`)。 | | `path` | `Path \| None` | 可选的本地文件系统路径。仅用于本地文件源。 | ### `MediaSourceItem` 传递给这两个方法的 `MediaSourceItem` 具有以下属性: | Attribute | Type | Description | |---|---|---| | `domain` | `str \| None` | 你的集成 domain。 | | `identifier` | `str` | URI 中的项目标识符。 | | `target_media_player` | `str \| None` | 将播放媒体的 media player 的 entity ID。可用于自定义解析的 URL。 | ## URI 方案 Media sources 使用 `media-source://` URI scheme: ``` media-source://domain/identifier ``` 例如: * `media-source://radio_browser/popular` — radio\_browser 的 "popular" 类别 * `media-source://tts/message` — TTS 消息 使用 `generate_media_source_id` helper 构造 URI: ```python from homeassistant.components.media_source import generate_media_source_id media_id = generate_media_source_id(DOMAIN, "my_track_123") # 返回: "media-source://my_integration/my_track_123" ``` 使用 `is_media_source_id` 检查字符串是否为有效的 media source URI: ```python from homeassistant.components.media_source import is_media_source_id if is_media_source_id(media_content_id): # 作为 media source 处理 ... ``` ## 错误处理 出错时抛出适当的异常: | Exception | 何时抛出 | |---|---| | `Unresolvable` | 在 `async_resolve_media` 中,当媒体项目无法解析为可播放 URL 时。 | | `BrowseError` | 在 `async_browse_media` 中,当无法获取媒体结构时,或在 `async_search_media` 中搜索失败时。 | 两个异常都支持 translations: ```python raise Unresolvable( translation_domain=DOMAIN, translation_key="item_not_found", translation_placeholders={"item": item.identifier}, ) ``` ## 在其他集成中使用媒体源 其他集成(如 media players)可以使用 media source helpers 浏览和解析媒体: ```python from homeassistant.components.media_player import SearchMediaQuery from homeassistant.components.media_source import ( async_browse_media, async_resolve_media, async_search_media, is_media_source_id, ) # 浏览 media sources result = await async_browse_media(hass, "media-source://my_domain") # 搜索 media source search_result = await async_search_media( hass, "media-source://my_domain", SearchMediaQuery(search_query="jazz"), ) # 将媒体项目解析为可播放 URL play_media = await async_resolve_media( hass, "media-source://my_domain/track_123", target_media_player="media_player.living_room", ) ``` --- url: /developers/core/platform/raising_exceptions.md --- ## 在 service action handler 中抛出异常 像 service action 调用和 entity 方法(例如 *Set HVAC Mode*)这样的操作应该正确地抛出异常。 当用户做错了某事时,集成应抛出 `ServiceValidationError`(而不是 `ValueError`)。在这种情况下,堆栈跟踪仅在 debug 级别打印。 对于其他故障,如与设备通信时出现问题,应抛出 `HomeAssistantError`。请注意,在这种情况下,异常堆栈跟踪将被打印到日志中。 ## 本地化异常 Home Assistant [支持本地化](/developers/internationalization/core.md#exceptions),适用于 `HomeAssistantError` 及其子类如 `ServiceValidationError`。 --- url: /developers/core/platform/repairs.md --- Home Assistant 会跟踪需要引起用户注意的问题。这些问题可以由集成或 Home Assistant 本身创建。问题可以通过 RepairsFlow 修复,也可以通过链接到包含用户自行解决方法的网站来修复。 维修问题也是面向用户的集成中 [deprecation](/developers/deprecating.md) 的宣布方式,这是它们最常见的用途之一。Core API 的 deprecation 则通过日志警告报告给开发者。 ## 创建问题 ```python from homeassistant.helpers import issue_registry as ir ir.async_create_issue( hass, DOMAIN, "manual_migration", breaks_in_ha_version="2022.9.0", is_fixable=False, severity=ir.IssueSeverity.ERROR, translation_key="manual_migration", ) ``` | 属性 | 类型 | 默认值 | 描述 | | --------- | -------- | ------- | ----------- | | domain | string | | 引发该问题的 domain | | issue\_id | string | | 问题的标识符,在 `domain` 内必须唯一 | | breaks\_in\_ha\_version | string | `None` | 问题成为破坏性的版本 | | data | dict | `None` | 任意数据,不向用户显示 | | is\_fixable | boolean | | 如果问题可以自动修复则为 True | | is\_persistent | boolean | | 如果问题应在 Home Assistant 重启后持续存在则为 True | | issue\_domain | string | `None` | 由代为其他集成创建问题的集成设置 | | learn\_more\_url | string | `None` | 用户可以查找更多关于问题详细信息的 URL | | severity | IssueSeverity | | 问题的严重程度 | | translation\_key | str | | 包含问题简要说明的 translation key | | translation\_placeholders | dict | `None` | 将注入到翻译中的占位符 | ### 问题的严重程度 为了更好地理解应选择哪个严重程度级别,请参阅下面的列表。 | IssueSeverity | 描述 | |---------------|--------------------------------------------------------------------| | CRITICAL | 保留级别,仅用于真正的紧急情况 | | ERROR | 当前有某事物已损坏,需要立即关注 | | WARNING | 将来某事物将损坏(例如 API 关闭),需要关注 | ## 修复问题 如果问题的 `is_fixable` 设置为 `True`,用户将被允许修复该问题。成功修复的问题将从 issue registry 中移除。 如果可以进行自动修复,应使用 RepairsFlow 来实现。 ### 提供自动修复 在集成文件夹中创建一个名为 `repairs.py` 的新 platform 文件,并根据下面的模式添加代码。 ```python from __future__ import annotations import voluptuous as vol from homeassistant import data_entry_flow from homeassistant.components.repairs import ConfirmRepairFlow, RepairsFlow from homeassistant.core import HomeAssistant class Issue1RepairFlow(RepairsFlow): """Handler for an issue fixing flow.""" async def async_step_init( self, user_input: dict[str, str] | None = None ) -> data_entry_flow.FlowResult: """Handle the first step of a fix flow.""" return await (self.async_step_confirm()) async def async_step_confirm( self, user_input: dict[str, str] | None = None ) -> data_entry_flow.FlowResult: """Handle the confirm step of a fix flow.""" if user_input is not None: return self.async_create_entry(title="", data={}) return self.async_show_form(step_id="confirm", data_schema=vol.Schema({})) async def async_create_fix_flow( hass: HomeAssistant, issue_id: str, data: dict[str, str | int | float | None] | None, ) -> RepairsFlow: """Create flow.""" if issue_id == "issue_1": return Issue1RepairFlow() ``` ## 问题生命周期 ### 问题持久性 问题将保留在 issue registry 中,直到被创建它的集成或用户通过[修复](#fixing-an-issue)将其移除。 `is_persistent` 标志控制问题是否应在 Home Assistant 重启后向用户显示: * 如果设置了 `is_persistent` 标志,问题将在重启后再次向用户显示。适用于只能在发生时检测到的问题(更新失败、自动化中未知操作)。 * 如果未设置 `is_persistent` 标志,问题将在重启后不再向用户显示,直到其集成重新创建它。适用于可以检查的问题,如磁盘空间不足。 ### 被忽略的问题 用户可以"忽略"问题。被忽略的问题将被忽略,直到被明确删除——由集成删除或用户成功走完其[维修流程](#fixing-an-issue)——并重新创建。忽略问题在 Home Assistant 重启后仍然生效,无论[问题持久性](#issue-persistence)如何。 ## 删除问题 集成通常不需要删除问题,但在某些情况下可能有用。 ```python from homeassistant.helpers import issue_registry as ir ir.async_delete_issue(hass, DOMAIN, "manual_migration") ``` --- url: /developers/core/platform/reproduce_state.md --- Home Assistant 支持 scenes。Scenes 是一组(部分)entity 状态。当 scene 被激活时,Home Assistant 将尝试调用正确的 service actions 以使指定的 scene 处于其指定的状态。 集成负责向 Home Assistant 添加支持,以便能够调用正确的 service actions 来重现 scene 中的状态。 ## 添加支持 为新集成添加 reproduce state 支持的最快方法是使用我们内置的 scaffold 模板。从 Home Assistant 开发环境运行 `python3 -m script.scaffold reproduce_state` 并按照说明操作。 如果你更喜欢手动方式,请在集成文件夹中创建一个名为 `reproduce_state.py` 的新文件,并实现以下方法: ```python import asyncio from collections.abc import Iterable from typing import Any from homeassistant.core import Context, HomeAssistant, State async def async_reproduce_states( hass: HomeAssistant, states: Iterable[State], *, context: Context | None = None, reproduce_options: dict[str, Any] | None = None, ) -> None: """Reproduce component states.""" # TODO reproduce states ``` --- url: /developers/core/platform/significant_change.md --- Home Assistant 不仅收集数据,还将数据导出到各种服务。并非所有这些服务都对每一次变更感兴趣。为了帮助这些服务过滤不重要的变更,你的 entity 集成可以添加重要变更支持。 此支持通过创建一个包含 `async_check_significant_change` 函数的 `significant_change.py` platform 文件来实现。 ```python from typing import Any, Optional from homeassistant.core import HomeAssistant, callback @callback def async_check_significant_change( hass: HomeAssistant, old_state: str, old_attrs: dict, new_state: str, new_attrs: dict, **kwargs: Any, ) -> bool | None: ``` 该函数接收之前被认为是重要的 state 和新的 state。它传递的不仅仅是最近 2 个已知 state。函数应返回布尔值,表示是否重要,或者返回 `None` 表示函数无法判断。 在判断重要性时,务必考虑所有已知 attributes。使用 device classes 来区分 entity 类型。 以下是一些不重要的变更示例: * 电池电量减少 0.1% * 温度传感器变化 0.1 摄氏度 * 灯光亮度变化 2 Home Assistant 将自动处理 `unknown` 和 `unavailable` 等情况。 要为 entity 集成添加重要 state 支持,运行 `python3 -m script.scaffold significant_change`。 --- url: /developers/core/pr_review_guide.md --- # PR 审查指南 审查 `home-assistant/core` 上 pull requests 的实用指南。 *** ## 1. 第一遍检查:门禁检查 在阅读任何代码之前,先验证这些内容。如果有任何失败,发表评论并停止。继续审查会浪费你的时间。 * **CLA 已签署。** 检查是否存在 `cla-signed` 标签。如果存在 `cla-needed`,评论要求贡献者签署,然后跳过。在 CLA 解决之前不要审查代码。 * **CI 是绿的。** 所有检查必须通过。如果 CI 因贡献者的更改而变红,转换为 draft 并要求他们修复。不要审查有问题的代码。 * **PR 有单一目的。** 一个 bugfix、一个 feature、一个 integration 或一个 refactor。如果 PR 混合了关注点(例如,依赖更新同时也重构测试),要求作者拆分。 * **PR 类型复选框与内容匹配。** PR 模板有类型复选框:验证只有一个被勾选且与代码实际内容匹配。 * **不依赖于其他打开的 PR。** 检查是否有指向其他未合并 PR 的引用。依赖 PR 不应提交,直到其依赖项合并。 * **描述有用。** "Proposed change" 部分应解释*为什么*,而不只是*什么*。对于 bugfix,应有链接的 issue。对于新集成,应有品牌/设备的上下文。 * **PR 描述没有未填充的占位符。** 检查是否有空的 Breaking Change 部分、未填充的 `fixes #` 占位符。 ### 1.1 分类信号:此 PR 是否可能完成? 早期识别高风险 PR 的信号可以节省审查者的时间。 **高风险指标**(在解决之前考虑优先推迟审查): * **首次贡献者的大型 PR。** 首次贡献者的新集成 PR 废弃率最高。如果 PR 是新集成且作者没有先前的已合并 PR,考虑等待 CI 通过并处理初始 bot 反馈后再投入深度审查时间。 * **AI 生成 PR 信号。** 注意那些解决理论而非实际问题的 PR、格式异常完美的描述但代码表现出根本性误解的 PR、在没有相应行为更改的情况下修改 test fixtures 的 PR,或为不可能发生的条件添加防御性代码的 PR。 *** ## 2. 新集成 PR(`new-integration`) 这些审查非常密集。quality scale 的 bronze 规则是基准线:每个新集成都必须满足它们。 ### 2.1 范围 * **仅限单一 platform。** 初始 PR 应只暴露一个 entity platform(例如,仅 `sensor` 或仅 `switch`)。检查 `__init__.py` 中的 `PLATFORMS` 列表——如果有多于一个条目,要求作者选择一个并将其余推迟。 * **无 diagnostics。** 初始集成 PR 中不应存在 `diagnostics.py`。这是 gold 级别的 quality scale feature,应放在后续 PR 中。 * **无 reconfigure flow。** `config_flow.py` 中的 reconfigure flow(`async_step_reconfigure`)是 gold 级别。要求作者将其删除并单独提交。 * **无 options flow(通常)。** 除非集成确实从一开始就需要用户可配置的 options,否则 options flow 应放在后续 PR 中。 * **无万能集成。** 注意添加所有可能 entity 的 PR。初始 PR 应最小且功能可用。额外的 platforms、entities 和 features 在后续 PR 中添加。 ### 2.2 Manifest (`manifest.json`) * **`iot_class` 正确。** 必须与集成实际的通信方式匹配:`local_polling`、`cloud_push` 等。 * **Library 是开源的。** PyPI 依赖必须公开可用源代码并带有开源 license。检查 repo 链接。 * **License 与 Apache-2.0 兼容。** HA Core 是 Apache-2.0。依赖必须使用兼容 license(MIT、BSD、Apache-2.0、LGPL、MPL-2.0、ISC、Unlicense 均可)。**GPL-2.0、GPL-3.0 和 AGPL 不兼容。** * **存在 License 元数据。** library 必须在 PyPI 上声明 license。没有 license 的 library 在法律上等于 "all rights reserved"。 * **License identifier 与 LICENSE 文件匹配。** 验证 `pyproject.toml`/`setup.cfg` 中的 `license` 字段与源代码仓库中实际的 LICENSE 文件文本匹配。不匹配表示错误或误导。 * **传递依赖的 license 兼容。** MIT library 引入 GPL-3.0 传递依赖会产生同样的不兼容性。检查完整的依赖树。 * **Library 未废弃或近期未转移。** 检查提交历史和 PyPI maintainer。一个 2+ 年没有活动的 library 突然出现新的 maintainer 值得审查。 ### 2.3 质量等级(`quality_scale.yaml`) * **所有 bronze 规则都已处理。** 每个 bronze rule 都应标记为 `done` 或 `exempt`(附带原因)。不应有 `todo`。 * **Exempt 原因有效。** 如果任何 rule 被标记为 `exempt`,原因应是合理的(例如,"此集成没有 actions" 适用于 `action-setup`)。 * **声称 `done` 的规则确实完成了。** 抽查几个:quality-scale-rule-verifier agent 在此处可以提供帮助。 ### 2.4 Config flow * **`test-before-configure` 已实现。** config flow 必须尝试连接到设备/服务,如果无法连接则以用户友好的错误优雅失败。 * **`unique-config-entry` 防止重复。** flow 应调用 `self._abort_if_unique_id_configured()` 或等效方法来防止添加同一设备两次。 * **Reconfigure 时有建议值。** 如果存在 reconfigure flow(初始 PR 中不应存在,但对于后续 PR):输入字段应使用 `suggested_value` 预填充当前值。 ### 2.5 发现流程(Zeroconf / DHCP / SSDP) Discovery 配置是反复拉锯的常见来源。 * **Discovery patterns 足够具体。** Zeroconf service types、DHCP hostnames 和 SSDP manufacturers 应只匹配目标设备。过于宽泛的模式(例如,匹配 `duco` 而实际上意味着 `duco [`)会意外声明不相关的设备。问自己:"此模式是否可能匹配它不应匹配的内容?" * **适当位置使用 `raise_on_progress=False`。** 从多个 steps 调用 `async_set_unique_id` 的 flows 需要在 flow source 应优先于 discovery flow 的 steps 中传递 `raise_on_progress=False` 参数。例如,由用户启动的 flow 应始终优先于同一设备 unique id 的 discovery flow。 * **DHCP 作为后备。** 如果集成支持 Zeroconf,考虑是否也应添加 DHCP discovery 作为后备,用于 mDNS 效果不佳的网络。 * **考虑 `registered_devices` 支持。** 对于设备 hostname/IP 可能更改的集成,`registered_devices` 允许重新发现已配置的设备。 * **Manifest discovery entries 与实现匹配。** 如果 `manifest.json` 声明了 `zeroconf`、`dhcp` 或 `ssdp`,请验证 config flow 实际上实现了相应的 `async_step_*` 方法。 ### 2.6 协调器与数据获取 * **使用 `DataUpdateCoordinator` 进行轮询。** 轮询集成不应实现自己的轮询循环。例外情况是集成使用[每个 individual entity 的单独轮询](/developers/integration_fetching_data.md#separate-polling-for-each-individual-entity)。 * **一次性工作用 `_async_setup`,轮询用 `_async_update_data`。** 一次性设置工作(认证、连接设置、初始设备信息获取)属于 `_async_setup`。`_async_update_data` 方法在每次 poll cycle 运行——不要在这里放入设置逻辑。 * **认证错误使用 `ConfigEntryAuthFailed`。** 当 API 在数据更新期间返回 auth 错误时,coordinator 必须抛出 `ConfigEntryAuthFailed`(而不是 `UpdateFailed`)。这将触发 reauth flow 而不是只是记录错误并永远重试。要让 reauth flow 实际启动,集成必须已实现 `async_step_reauth` 方法;没有它,entry 只是保持在失败状态。 * **Coordinator 数据已正确类型化。** coordinator 应使用 generics(`DataUpdateCoordinator[MyDataType]`),以便 entity 代码获得类型检查对 coordinator 数据的访问。 * **轮询频率合理。** 检查 `update_interval`:对设备/服务是否合适?天气 API 不需要 10 秒轮询。本地设备可能需要更快的更新。 ### 2.7 Entities * **稳定的 `unique_id`。** Entity unique IDs 不得使用 IP addresses、hostnames 或任何可能更改的内容。优先使用 MAC addresses(使用 `format_mac()` 规范化)、序列号或设备分配 ID。 * **MAC addresses 已规范化。** 如果 MAC address 用作 unique ID 或在 device info 中,必须通过 `homeassistant.helpers.device_registry` 的 `format_mac()` 处理。 * **使用 Entity description。** 新 entity 应使用基于 dataclass 的 [entity description](/developers/core/entity.md#entity-description)(如 `SensorEntityDescription`)来定义。链接文档中描述的其他模式也被接受,但在新代码中优先使用 entity description 模式。 * **设置 `PARALLEL_UPDATES`。** 对于基于 coordinator 的集成,在每个 platform 模块中设置 `PARALLEL_UPDATES = 0`(因为 coordinator 处理同步)。 * **Entity categories 正确。** 请参阅第 8 节获取详细的 `EntityCategory` 指导:这是最常见的审查模式之一。 * **Debug entities 默认禁用。** 用于调试目的的 entities(信号强度、rate limits、固件版本)应设置 `entity_registry_enabled_default=False`。 ### 2.8 Strings & translations * **所有面向用户的字符串在 `strings.json` 中。** Python 代码中不得有硬编码的英文字符串。 * **Sentence case。** `strings.json` 中所有 string 值必须使用 sentence case(不是 Title Case,不是 ALL CAPS)。 * **适用时使用 Common translation keys。** 如果字符串匹配现有的 common key(如通用名称 "Temperature"、"Humidity"),引用 common key 而不是定义新的。 * **代码样式的字面量用反引号包围。** Translatable strings 渲染为 markdown,因此用反引号包围代码样式的字面量(entity IDs、action 名称、文件名、状态值)。协议和品牌名称不加反引号;按其官方大小写书写(如 MQTT、Z-Wave、Zigbee)。 * **Integration name 不在 log messages 中。** Integration domain 已经是 logger name 的一部分——不要在消息文本中重复。 *** ## 3. 新功能 PR(`new-feature`) 向现有集成添加功能。 ### 3.1 范围与兼容性 * **范围适当。** feature 应该是单一、连贯的添加。一次添加三个新的 entity platforms 太多了——拆分开。 * **与现有集成风格一致。** 新代码应遵循集成中已建立的约定(命名、结构、模式)。 * **维持 quality scale 级别。** 如果集成有 quality scale 级别,新代码不得使其回退。检查新 entity 是否遵循所有适用规则。 * **新字符串遵循 translation 规则。** 与新集成相同的规则:`strings.json`、sentence case、common keys。 * **Breaking changes 已记录。** 如果 feature 更改了现有行为(重命名 entities、更改状态值格式、修改 service schemas),PR 描述必须包含为最终用户编写的 "Breaking change" 部分。什么算 "breaking" 需要理解用户可见的契约:这是 AI reviewer 持续搞错的人类判断。 ### 3.2 Config entry lifecycle * **Schema 更改时进行 config entry migration。** 如果 feature 更改了存储在 config entry 中的内容,必须有 migration:在 config flow 类中 bump `VERSION`,实现 `async_migrate_entry`,并添加涵盖从旧格式到新格式的迁移的测试。 * **VERSION bump 与 schema 更改匹配。** 如果 config entry 数据字段被添加、删除或重组,且 config flow `VERSION` 没有被 bump,标记它。反之,如果 `VERSION` 被 bump,则应有相应的迁移代码。 * **`async_unload_entry` 清理所有资源。** 当 config entry 被卸载时,所有 event listeners、polling tasks 和 connections 都应被清理。缺少清理会导致资源泄漏和 stale 状态。 * **设置失败后不访问 `runtime_data`。** 如果 `async_setup_entry` 中途失败,错误处理程序中的代码不应尝试访问 `entry.runtime_data`:它可能尚未被设置。 ### 3.3 发现与设备注册 * **需要时更新 Discovery patterns。** 如果 feature 添加了对新设备型号的支持,检查 `manifest.json` discovery entries(Zeroconf、DHCP、SSDP)是否需要扩展。 * **Device info 完整。** 新 entity 应包含完整的 `DeviceInfo`,在可用时包含 manufacturer、model、serial number 和 firmware version。 *** ## 4. Bugfix PRs (`bugfix`) Bugfix 虽然概念上比其他更改更简单,但生成的审查评论却很多——因为审查者会仔细审视修复是否真正正确且完整。 * **存在关联的 issue。** Bugfix PR 应引用它们修复的 issue(`fixes #XXXX`)。如果没有 issue,询问原因:应确认 bug 确实存在。 * **修复最小化。** 更改应只修复报告的 bug,不做其他改动。没有顺手重构,没有"顺便修一下"的改进。 * **根本原因已解决。** 修复应解决实际原因,而不是掩盖症状。如果 `TypeError` 崩溃是因为 `value` 为 `None`,修复应在适当层级处理 `None`,而不仅仅是在 `try/except` 中包装所有内容。 * **包含回归测试。** 最好有一个本应捕获此 bug 的测试。该测试在没有修复时应失败,有修复时应通过。并非所有集成都需要测试,但具有测试的现有集成应始终维持测试覆盖。 * **无无关的测试更改。** 测试重构(snapshot 更新、parametrize 重写)不应混入 bugfix PR 中。 ### 4.1 Bugfix 中的错误处理 * **`HomeAssistantError` 从 service/action handlers 传播。** 当 service handler 捕获来自底层 library 的异常时,应重新抛出为 `HomeAssistantError`(或像 `ServiceValidationError` 这样的子类),以便错误通过 UI 到达用户。在 service handler 中静默吞没异常是一种常见的 bug 模式。 * **错误具体性。** 添加错误处理的 bugfix 应捕获特定的异常类型,而不是宽泛的 `except Exception`。请参阅第 10 节了解详情。 * **认证相关的 bugfix 使用 `ConfigEntryAuthFailed`。** 如果 bugfix 处理 coordinator 中的认证问题,请验证它抛出 `ConfigEntryAuthFailed`(而不是 `UpdateFailed`)以触发 reauth flow。 *** ## 5. 代码质量 PR(`code-quality`) 通常由 quality-scale 改进驱动。 * **改进是真实的。** 更改应使代码可测量地更好(更易读、更快、更易维护),而不仅仅是不同。 * **无行为变更。** Code quality PR 不应更改功能。如果更改了,应以不同方式标记。 * **测试已更新以匹配。** 如果代码结构更改,测试应相应更新——但测试重构应与代码更改匹配,不应超出。 * **Breaking changes 已注明。** 即使 code-quality PR 也可能是 breaking 的(例如,删除已弃用的常量)。如适用,必须填写 "Breaking change" 部分。 * **已验证 quality scale 声明。** 验证所有声称的规则确实满足:quality-scale-rule-verifier agent 可以自动化此操作。 *** ## 6. 依赖更新 PR(`dependency`) 与 new-integration PR 相比,Dependency PR 生成的审查评论较少,但出现的模式很具体,更大的担忧是在更新依赖时的安全风险。 ### 6.1 范围与结构 * **仅更新依赖。** PR 应触及 `manifest.json`(version bump)以及跟踪依赖的 requirements 文件(如重新生成的 `requirements_all.txt`),以及新版本所需的最少代码更改。仅此而已。 * **无顺手重构。** 如果贡献者还重构了测试、清理了 imports 或做了样式更改——要求他们将其拆分为单独的 PR。 * **`quality_scale` 未被意外移除。** 检查 `manifest.json` 是否丢失了 `quality_scale` 或 `loggers` 字段:这在依赖更新中出人意料地经常发生。 ### 6.2 上游更改审查 * **Changelog/release notes 已链接。** PR 描述应包含指向 library changelog 或版本间 diff 的链接,以便审查者能看到上游更改了什么。 * **Breaking library 更改已处理。** 如果上游 library 做了 breaking changes,验证集成代码正确适应。 * **已审查 Upstream diff 的安全隐患。** 检查 library 在旧版本和新版本之间实际更改了什么。查找:新的网络调用、新的 `requests`/`aiohttp`/`socket`/`subprocess`/`os.system` imports 或调用、新的环境变量访问、预期路径之外的新文件 I/O。 * **无新的传递依赖。** 如果 library 版本添加了新的传递依赖,应明确提及。新的传递依赖是最常见的供应链攻击向量。 * **PyPI maintainer 未更改。** 如果 library 的 PyPI maintainer 在版本之间发生了变化,这是一个重要的信任事件(可能的账户接管)。标记以仔细检查。 * **Source repo 未移动或未归档。** 验证 library 仍然具有相同的公共 source repository。版本之间的 repo 转移、归档或删除是危险信号。 ### 6.3 许可证合规 * **版本之间 license 未更改。** 版本之间的 license 更改(如 MIT → GPL-3.0)将是关键问题。比较 PyPI 上两个版本的 `license` 字段。 * **License 仍与 Apache-2.0 兼容。** 与新集成相同的规则:GPL-2.0/3.0/AGPL 与 HA Core 的 Apache-2.0 license 不兼容。 * **License identifier 仍与 LICENSE 文件匹配。** 验证声明的 license identifier 与实际 LICENSE 文本匹配:每次更新都应重新验证,而不仅仅是首次引入时。 *** ## 7. 测试审查(所有 PR 类型) ### 7.1 结构 * **测试在正确位置。** Integration tests 应放在 `tests/components//` 中。 * **所有测试函数参数都有类型注释。** 使用具体类型(`HomeAssistant`、`MockConfigEntry`),不要使用 `Any`。 * **测试练习 HA 的公共接口。** Integration 行为测试应通过 `async_setup_component()` 或 `hass.config_entries.async_setup()` 设置集成,通过 `hass.states` 断言状态,并通过 `hass.services` 触发 actions。它们不应直接实例化集成类或调用内部方法。针对隔离的 helpers 和 utilities 或纯逻辑的聚焦 unit tests 在该边界确实是预期边界时可以直接调用这些方法。 ### 7.2 模式 * **实体 platform 使用 Snapshot testing。** Platform 测试(sensor、switch 等)应使用 `snapshot_platform` 验证 entity 状态,而不是手动断言各个属性。 * **`@pytest.mark.parametrize` 用于重复案例。** 如果多个测试函数使用不同输入测试相同行为,应将它们参数化为一个函数。但不要过度参数化:一个场景的单个测试不需要 parametrize。 * **时间测试使用 `freezer`。** 涉及时间的测试必须使用 `freezer` fixture——绝不能直接 mock `datetime`、`time` 或 `utcnow`。 * **不要在 `sys.modules` 上使用 `mock.patch`。** 这是脆弱的且会破坏其他测试。使用适当的 mocking patterns。 * **Config flow 测试有完整覆盖。** config flow 中的每个分支都应被测试:happy path、错误处理、用户中止、每个 step。测试 step 错误的测试应继续 flow 以创建 entry 结果以显示错误恢复。早期审查 config flow 测试通常是快速发现其余代码中 bug 的好方法。 * **错误/恢复场景已测试。** 测试应覆盖设备/服务不可用、返回错误或需要重新认证时会发生什么。这是最常被请求的缺失测试类型。 * **测试脆弱性最小化。** 避免硬编码依赖上游数据的值(如特定节假日)。使用 mocking 或选择稳定的测试数据,这样依赖更新时不会更改。 ### 7.3 Mocking * **Mock library,而不是 HA 内部。** Mocks 应针对第三方 library 的 API 调用,而不是 Home Assistant 的内部机制。例如,mock 集成调用的 client methods(或在 `conftest.py` 中 patch client class),而不是 patch `DataUpdateCoordinator`、`hass` helpers 或 entity 内部。Mock HA 内部会使测试变脆弱并停止测试真实的集成 wiring。 * **Fixtures 在 `conftest.py` 中。** 共享测试 fixtures(mock client、config entry 设置)应放在集成的 `conftest.py` 中,而不是在测试文件中重复。 *** ## 8. 实体模式(所有 PR 类型) Entity 相关的反馈占审查者注意力的主导地位。本节适用于添加或修改 entity 的所有 PR。 ### 8.1 `EntityCategory` 分类 贡献者经常错误分类 entity。规则: **决策树:** 1. 用户是否希望此 entity 出现在主 dashboard 上?→ **无 category**(默认) 2. 它是否是控制集成行为的设置?(模式、阈值、开关)→ **`EntityCategory.CONFIG`** 3. 它是否是 debug/diagnostic 信息?(固件版本、信号强度、rate limits、IP 地址、MAC 地址)或者是设备类为 IDENTIFY 的特定 button entity → **`EntityCategory.DIAGNOSTIC`** 标记为 `CONFIG` 或 `DIAGNOSTIC` 的 entity 会从默认 dashboards 中隐藏并排除在 voice assistants 之外。 * **Diagnostic entities 标记为 `EntityCategory.DIAGNOSTIC`。** 用于调试的 entity——信号强度、rate limits、固件版本、连接统计、错误计数——必须是 `EntityCategory.DIAGNOSTIC`。 * **Config entities 标记为 `EntityCategory.CONFIG`。** 重置按钮、模式选择器、配置开关、阈值设置——任何控制集成或设备如何运行的都必须是 `EntityCategory.CONFIG`。 * **Debug/diagnostic entities 默认禁用。** 除了 `EntityCategory.DIAGNOSTIC` 外,纯粹用于调试的 entity 应设置 `entity_registry_enabled_default=False`。 * **主要功能 entity 无 category。** 用户交互的主要 entity(thermostat 温度、switch 状态、light 亮度)应**没有** `EntityCategory`。不要过度分类。 ### 8.2 可用性与 `None` 处理 这是审查者需要理解的最重要模式之一——也是 AI 最难正确处理的一个。 **核心区别:** * **`native_value` 返回 `None`** = entity 可用,但当前值未知 → entity 在 UI 中显示 "unknown" * **`_attr_available = False`** = 设备/服务不可达 → entity 在 UI 中显示 "unavailable" 这是非常不同的用户体验。搞错意味着要么显示错误的数据,要么隐藏真实的故障。 * **`None` 不被类型转换隐藏。** `bool(None)` 返回 `False`,这会隐藏数据缺失的事实。`int(None)` 抛出 `TypeError`。当 API 的值可能为 `None` 时,entity property 应返回 `None`(或 `bool | None`),而不是将其转换为具体值。 * **不可用信号正确。** 当设备无响应或 API 失败时,entity 应变得不可用(`_attr_available = False`),而不是显示 stale 数据。检查 coordinator 错误处理:失败的更新是否将 entity 标记为不可用? * **`None` 返回是有意为之,而非偶然。** 如果 `native_value` 可以返回 `None`,请验证这是预期行为。有时 `None` 意味着 "API 未包含此字段",此时 entity 应该是不可用的。 ### 8.3 额外状态属性与独立实体 HA 项目正在积极迁移 away 从 `extra_state_attributes`。审查者一致推动将 attributes 拆分为单独的 entity。 * **Extra state attributes 是有理由的。** 如果 PR 使用 `extra_state_attributes`,询问每个属性是否应该成为自己的 entity。问题是:"此数据是否独立有用?用户是否希望专门基于它进行自动化?"如果为是,它应该是单独的 entity。 * **不再添加新的 `extra_state_attributes`。** 在新代码中,优先使用单独的 entity 而不是 extra attributes。唯一的例外是真正仅在 parent entity 上下文中才有意义的辅助数据。 ### 8.4 乐观状态更新 * **Optimistic 更新是合适的。** 当 entity 发送命令(打开 switch、设置温度)时,它应该立即更新其状态(optimistic)还是等待下一次 poll/push 确认?这取决于: * 设备是否可靠地回传状态? * poll cycle 有多快? * 延迟的 UI 反馈是否可接受? 没有普遍正确的答案。具有快速 push 更新的本地设备通常不需要 optimistic 更新。轮询慢的 cloud-controlled 设备通常需要。 ### 8.5 Device class & state class * **适用的情况下设置 Device class 且正确。** Sensor、binary sensor 和其他 typed entities 在适用时应具有适当的 `device_class`。这决定了 UI 图标、单位处理和图表渲染。`device_class` 是可选的——当没有 class 匹配时省略它。 * **支持统计的数值 sensor 设置 State class。** 其值符合长期统计资格的数值 sensor 应设置 `state_class`(`MEASUREMENT`、`TOTAL`、`TOTAL_INCREASING`)。某些 device classes(如 `date`、`timestamp`、`enum`)不符合资格,不应设置 `state_class`。 *** ## 9. 代码风格与模式(所有 PR 类型) ### 9.1 架构 * **常量在 `const.py` 中,从那里导入。** 在多个模块之间共享的集成常量(`CONF_*`、`DOMAIN`、entity keys)应放在 `const.py` 中并从那里导入——而不是从 `__init__.py` 或其他 re-exporting 模块导入。如果常量只在单个模块中使用,它应保留在那里。应该是常量 magic strings 应被提取出来。 * **提前返回 / guard clauses。** 优先使用 `if not condition: return` 而不是将整个函数体包裹在 `if condition:` 中。避免深层嵌套。 * **验证后直接使用 dict 访问。** 当验证保证 key 存在时,使用 `data["key"]` 而不是 `data.get("key")`。契约违规应被暴露,而不是静默掩盖。 * **不在 service actions 上添加不必要的防御性检查。** HA 的 service/action schemas 已经验证输入。不要为 schema 验证过的字段添加冗余检查。 * **集成目录中没有 `.gitignore` 文件。** 这些偶尔会从贡献者的本地仓库中混入。 * **使用 dataclasses 处理结构化数据。** 当传递多个相关值时,使用 dataclass 而不是 tuple、dict 或单独的变量。 ### 9.2 错误处理 * **Service/action handlers 中使用 `HomeAssistantError`。** 捕获 library 异常的 service handler 必须重新抛出为 `HomeAssistantError`(或 `ServiceValidationError`),以便错误通过 UI 传播给用户。静默吞没异常意味着用户在 action 失败时看不到任何反馈。 * **Narrow exception handling。** `except Exception:` 捕获包括编程错误在内的一切。只捕获预期的 connection/API 异常。 * **Narrow try blocks。** 只将可能抛出你要捕获的异常的语句保留在 `try` block 中。宽 try blocks 使调试更困难,因为可能捕获到错误的行。 * **`async_unload_entry` 完整。** 当 config entry 被卸载时,所有 event listeners、timers 和 connections 必须被清理。检查在 `async_setup_entry` 中创建的一切是否有相应的 teardown。 * **关机时关闭连接。** 当 Home Assistant 停止时,连接应该被关闭。监听 `EVENT_HOMEASSISTANT_STOP` 事件来调度清理。Home Assistant 进程终止时内存会自动释放。 ### 9.3 字符串与日志 * **Log messages 中没有 integration domain。** Logger 已经包含 domain。 * **所有面向用户的字符串使用 sentence case。** 包括 entity names、config flow labels、错误消息。 * **正确的 log levels。** 用户应采取操作的事项用 `_LOGGER.error`,降级但仍能功能运行的状态用 `_LOGGER.warning`,开发者 diagnostics 用 `_LOGGER.debug`。不要用 `error` 处理预期条件,如 "device offline"。 ### 9.4 属性与状态 * **`@property` vs attributes 用于值。** 考虑 property 还是 instance attribute 是正确的选择。如果值每次访问时都需要从其他数据计算,使用 `@property` 而不是将其存储为 instance variable。但检查值是否计算昂贵——如果是,考虑缓存它。如果不需要计算,或者我们可以用单个方法计算并且计算的需求是由方法驱动的而不是由我们访问值驱动的,则使用 instance attribute。大多数 `Entity` 状态属性都有 `_attr_` 前缀的 attributes,推荐直接实现 property。不要在同一位置存储相同的值。 * **Entity `native_value` 返回正确的类型。** 当值真正未知时返回 `None`。不要返回掩盖未知状态的默认值(0、`False`、`""`)。请参阅第 8.2 节。 *** ## 10. 常见陷阱与令人困惑的 API 这些模式代表了贡献者(和自动化审查者)持续出错的地方。 ### 10.1 类型转换陷阱 Python 的 truthiness 规则是 HA 集成中常见的 bug 来源: | Expression | Result | Problem | | ---------- | ------ | ------- | | `bool(None)` | `False` | 隐藏缺失数据:entity 显示 "off" 而不是 "unknown/unavailable" | | `bool("0")` | `True` | 非空字符串是 truthy:entity 在值为 "0" 时显示 "on" | | `bool(0)` | `False` | 正确,但如果 API 更改为返回 `"0"` 则脆弱 | | `int(None)` | `TypeError` | 崩溃而不是返回 `None` | | `float("nan")` | `nan` | `nan != nan` 为 `True`,静默破坏比较 | * **不在 value 可能为 `None` 的地方使用 `bool(value)`。** 使用显式比较:`value is not None`、`value == "1"`,或返回 `bool | None` 并让 entity framework 处理它。 * **不在 value 可能为 `None` 的地方使用 `int(value)` 或 `float(value)`。** 改为返回 `None` 或在转换前检查。 * **String-to-bool 转换是显式的。** 如果 API 返回 `"0"`/`"1"` 或 `"true"`/`"false"`,显式转换(`value == "1"`)而不是依赖 Python truthiness。 ### 10.2 生产代码中的 `assert` Python 的 `assert` 语句在 Python 使用 `-O`(optimize)运行时被剥离。对运行时验证使用 `if not condition: raise ValueError(...)` 或类似方式。`assert` 仅用于测试或类型提示。 * **测试文件中的 `assert`。** 测试使用 `assert` 语句验证测试在那一时刻的状态。 * **用于类型提示的 `assert`。** 有时可能需要 `assert` 语句向类型检查器解释类型。只有当调整类型注释以取得相同结果很繁琐或不可能时才使用它。始终将此类语句包裹在 `if TYPE_CHECKING:` 条件中。 ### 10.3 协调器生命周期混淆 `DataUpdateCoordinator` 有两个看起来相似但用途不同的方法: | Method | 何时运行 | 用途 | | ------ | ------------ | ------- | | `_async_setup` | **一次**,在 coordinator 初始化时 | 认证、连接设置、获取设备信息、初始状态 | | `_async_update_data` | **每次 poll cycle**(例如,每 30 秒) | 从设备/API 获取当前状态/数据 | 将设置逻辑放入 `_async_update_data` 意味着它会在每次 poll 时运行——浪费资源并可能导致 auth token 刷新或连接重新建立。 * **一次性设置在 `_async_setup` 中。** 如果你在 `_async_update_data` 中看到连接建立、auth token 获取或设备信息获取,应将其移动到 `_async_setup`。 ### 10.4 `ConfigEntryAuthFailed` vs `UpdateFailed` coordinator 中最常被混淆的错误类型: | Exception | 效果 | 何时使用 | |-----------|--------|-------------| | `ConfigEntryAuthFailed` | 触发 **reauth flow**:用户被提示重新认证 | API 返回 401/403、token 过期、凭据无效 | | `UpdateFailed` | 记录错误,**下次 poll 时重试** | 临时网络故障、API 超时、rate limiting | 对 auth 错误使用 `UpdateFailed` 意味着集成会永远用错误的凭据重试,而不是提示用户修复它们。 * **Auth 错误抛出 `ConfigEntryAuthFailed`。** 在 `_async_update_data` 中,任何捕获认证相关异常的 `except` block(401、403、`InvalidToken`、`AuthenticationError`)应抛出 `ConfigEntryAuthFailed`,而不是 `UpdateFailed`。要允许用户重新认证,集成还需要实现 `async_step_reauth` 方法。 ### 10.5 `HomeAssistantError` propagation 集成中的 service/action handlers 必须将错误传播给用户。如果 service 调用(`turn_on`、`set_temperature`、custom actions)捕获了 library 异常,应重新抛出为 `HomeAssistantError` 以便错误出现在 UI 中。 ```python # 错误 — 用户看不到任何反馈 async def async_turn_on(self, **kwargs): try: await self.device.turn_on() except DeviceError: _LOGGER.error("Failed to turn on") # 仅在日志中,用户看不到 # 正确 — 错误到达用户 async def async_turn_on(self, **kwargs): try: await self.device.turn_on() except DeviceError as err: raise HomeAssistantError(f"Failed to turn on: {err}") from err ``` * **Service handlers 传播 `HomeAssistantError`。** 检查 service/action handlers 是否没有静默吞没异常。错误应到达用户。确保避免重复错误日志记录。传递给抛出的 `HomeAssistantError` 的参数应包含错误消息,该消息默认会被记录。不要单独记录此错误消息。 *** ## 11. Git 与 PR 卫生 * **Commits 讲述故事。** 每个 commit 应是一个逻辑单元。审查者应能跟踪进展。 * **打开后不 amend/squash/rebase。** 根据 repo 政策:"不要 amend、squash 或 rebase 已经在 PR review 开始后推送到 PR 分支的 commits。" 从 `dev` 拉取最新更改的 merge commits 没问题。 * **从 base branch unclean merge 或 rebase 后没有无关 commits。** 如果 PR 包含来自 `dev` 的无关 commits,git history 已损坏。要求作者创建干净的分支并打开新的 PR。 * **没有注释掉的代码。** Dead code 应被删除,而不是注释。 *** ## 12. 审查者工作流程 审查 PR 的建议顺序: 1. **Gate checks**(第 1 节):如果 CLA 缺失、CI 是红的或 PR 显示高风险 triage 信号,在此停止。 2. **Scope 检查**(第 2.1 节 / 特定类型章节):此 PR 是否在做一件事? 3. **Manifest & 元数据**(第 2.2-2.3 节):快速结构检查。 4. **Config flow 测试**(第 7.2 节):早期审查 config flow 测试通常能很快暴露其余代码中的问题。 5. **Entity patterns**(第 8 节):Entity categories 正确?Availability 处理得当?无 type casting traps? 6. **剩余测试审查**(第 7 节):测试是否真的测试了重要内容?使用了 snapshot?覆盖了错误场景? 7. **代码审查**(第 9-10 节):架构、模式、风格、常见陷阱。 8. **Strings & translations**(第 2.8 节):快速浏览 `strings.json`。 9. **整体评估**:批准、请求更改或评论。 **请求更改时:** 具体说明需要更改什么及原因。尽可能链接到文档。如果 PR 需要重大返工,明确说明,而不是留下许多加起来等于"推倒重来"的 inline comments。 *** *此指南基于对 home-assistant/core 中 1,100+ PR 和 8,200+ 审查评论的分析,以及官方开发者文档和仓库约定。数据收集于 2026 年 4 月。在 AI 生成后经过人工策展。* --- url: /developers/creating_component_code_review.md --- 添加新组件时要做的事情清单。 :::info 并非所有现有代码都遵循本清单中的要求。这不能作为不遵循要求的理由! ::: ### 0. Common 1. 遵循我们的[风格指南](/developers/development_guidelines.md) 2. 使用 [`const.py`](https://github.com/home-assistant/core/blob/dev/homeassistant/const.py) 中现有的常量 * 只有当常量被广泛使用时才添加到 `const.py` 中。否则,请在组件级别保留它们 ### 1. External requirements 1. 依赖项已添加到 [`manifest.json`](/developers/creating_integration_manifest.md)。`REQUIREMENTS` 常量已弃用。 2. 依赖项版本必须固定:`"requirements": ['phue==0.8.1']` 3. 每个依赖项都满足[库要求](/developers/api_lib_index.md#basic-library-requirements)。 ### 2. Configuration 1. 有用于[配置验证](/developers/development_validation.md) 的 Voluptuous schema 2. 默认参数在 voluptuous schema 中指定,而不是在 `setup(…)` 中 3. 尽可能多地使用来自 `homeassistant.const` 的通用配置键 4. 如果你的组件有平台,请定义 `PLATFORM_SCHEMA` 而不是 `CONFIG_SCHEMA`。 5. 如果使用与 `EntityComponent` 配合的 `PLATFORM_SCHEMA`,请从 `homeassistant.helpers.config_validation` 导入基础 schema 6. 永远不要依赖用户在 `customize` 中添加内容来配置你的组件内部行为。 ### 3. Component/platform communication 1. 可以通过 `hass.data[DOMAIN]` 与你的平台共享数据。 2. 如果组件获取的数据导致其相关平台实体更新,可以使用 `homeassistant.helpers.dispatcher` 中的 dispatcher 代码来通知它们。 ### 4. Communication with devices/services 1. 所有与 API 相关的代码必须作为 PyPi 上托管的第三方库的一部分。Home Assistant 应该只与对象交互,而不直接调用 API。 ```python # bad status = requests.get(url("/status")) # good from phue import Bridge bridge = Bridge(...) status = bridge.status() ``` [关于发布你自己的 PyPI 包的教程](https://towardsdatascience.com/how-to-open-source-your-first-python-package-e717444e1da0) 其他关于发布 Python 包的值得注意的资源: [Cookiecutter Project](https://cookiecutter.readthedocs.io/) [flit](https://flit.readthedocs.io/) [Poetry](https://python-poetry.org/) ### 5. Make your pull request as small as possible 将新集成保持在能让人从中获得价值的最小功能范围。这允许审查者一次一批地签署较小代码块,让我们能更早地获得你的新集成/功能。**包含大量代码倾倒的 pull request 不会成为审查的优先级,可能会被关闭。** * 限制为单个平台 * 不要添加不支持该单个平台所需的功能(如自定义 service actions) * 不要在单个 pull request 中混合清理工作与新功能 * 不要在单个 pull request 中解决多个问题 * 不要提交依赖于其他尚未合并工作的 pull request 在"现代化"某个长时间未触及的集成时,可能会倾向于打开一个大型 PR,以利用所有最新可用功能。正确的方法是尽可能将功能拆分为独立的功能性更改,并按顺序提交 PR。 处理顺序 PR 的一个策略是,在 `current` PR 的分支上为 `next` PR 创建一个分支,然后可以开始编写代码。如果你已经将 PR 拆分使得一个依赖于前一个,这种策略是有优势的,因为你是在 PR 合并后会在 `dev` 中的代码基础上工作。如果你因为更改/审查反馈而向 `current` PR 添加额外的提交,你可以对 `next` PR 的分支执行 rebase,并更容易地整合任何 merge conflicts。一旦你的 `current` PR 被合并,在 `next` PR 分支中 squash 来自 `current` PR 分支的提交,然后在 `dev` 上 rebase。然后就可以提交 `next` PR 分支进行审查,并根据需要重复此过程。 ### 6. Event names 使用 domain 名称作为组件事件名称的前缀。例如,对于 `netatmo` 组件,使用 `netatmo_person` 而不是 `person`。请注意我们在 [Data Science portal](https://data.home-assistant.io/docs/events/#database-table) 上记录的数据结构。 ### 7. Tests 强烈考虑为你的组件添加测试,以尽量减少未来的回归问题。 --- url: /developers/creating_component_generic_discovery.md --- 大多数集成只包含单个平台。在这种情况下,只需定义该平台即可。但是,如果你要添加第二个平台,就需要将连接逻辑集中管理。这需要在组件(`__init__.py`)内部完成。 如果你的集成可以通过 `configuration.yaml` 配置,那么你的配置入口点将会发生变化,因为用户现在需要直接设置你的集成,而平台的设置则由你的集成负责。 ## 通过 config entry 配置时加载平台 如果你的集成通过 config entry 设置,你需要将 config entry 转发给相应的集成以设置你的平台。更多信息,请参阅 [config entry 文档](/developers/config_entries_index.md#for-platforms)。 ## 通过 configuration.yaml 配置时加载平台 如果你的集成没有使用 config entries,则需要使用我们的 discovery helpers 来设置平台。注意,这种方式不支持卸载。 为此,你需要使用 discovery helper 中的 `load_platform` 和 `async_load_platform` 方法。 * 参见一个[实现此逻辑的完整示例](https://github.com/home-assistant/example-custom-config/tree/master/custom_components/example_load_platform/) --- url: /developers/creating_component_index.md --- 好了,是时候为你的集成编写第一段代码了。太棒了!不用担心,我们已经尽力让它尽可能简单。在 Home Assistant 开发环境中,输入以下命令并按照提示操作: ```shell python3 -m script.scaffold integration ``` 这将为你准备好通过用户界面设置集成所需的一切。更多的集成示例可从[我们的示例仓库](https://github.com/home-assistant/example-custom-config/tree/master/custom_components/)中获得。 :::tip 这个示例仓库展示了存放在 `/custom_components` 目录中的自定义集成。它们必须在[清单文件](/developers/creating_integration_manifest.md#version)中包含 `version` 键。核心集成存放在 `homeassistant/components` 目录中,不需要 `version` 键。两种情况下的架构是相同的。 ::: ## 最低要求 scaffold 集成比最低要求略多一些。最低要求是定义一个包含集成 domain 的 `DOMAIN` 常量。第二个部分是它需要定义一个 setup 方法,如果设置成功则返回一个布尔值。 根据你的需求,创建文件 `homeassistant/components/hello_state/__init__.py` 并使用以下两个代码块之一: * 同步 component: ```python from homeassistant.core import HomeAssistant from homeassistant.helpers.typing import ConfigType DOMAIN = "hello_state" def setup(hass: HomeAssistant, config: ConfigType) -> bool: hass.states.set("hello_state.world", "Paulus") # 返回布尔值表示初始化成功。 return True ``` * 如果你更喜欢异步 component: ```python from homeassistant.core import HomeAssistant from homeassistant.helpers.typing import ConfigType DOMAIN = "hello_state" async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: hass.states.async_set("hello_state.world", "Paulus") # 返回布尔值表示初始化成功。 return True ``` 此外,还需要一个 manifest 文件,最低要求包含以下键。创建 `homeassistant/components/hello_state/manifest.json`。 ```json { "domain": "hello_state", "name": "Hello, state!" } ``` 要加载它,在 `configuration.yaml` 文件中添加 `hello_state:`。 ## scaffold 提供的功能 使用 scaffold 脚本时,它将超过集成的最低要求。它将包含 config flow、config flow 的测试以及基本的翻译基础设施,为你的 config flow 提供国际化支持。 --- url: /developers/creating_integration_brand.md --- 一个商业品牌可能拥有多个集成,分别提供对该品牌下不同产品的支持。此外,一个品牌也可能提供符合某个 IoT 标准(例如 Zigbee 或 Z-Wave)的设备。 第一种情况的示例是,有多个集成分别提供对不同 Google 产品的支持,例如 `google` 集成提供的 Google Calendar,以及 `google_sheets` 集成提供的 Google Sheets。 第二种情况的示例是,Innovelli 提供 Zigbee 和 Z-Wave 设备,并不需要它自己的集成。 为了让用户更容易找到这些集成,应该将它们收集到 `homeassistant/brands` 文件夹中的一个文件中。 示例: ```json { "domain": "google", "name": "Google", "integrations": ["google", "google_sheets"] } ``` ```json { "domain": "inovelli", "name": "Inovelli", "iot_standards": ["zigbee", "zwave"] } ``` 或者一个可以直接复制到你的项目中的最小示例: ```json { "domain": "your_brand_domain", "name": "Your Brand", "integrations": [], "iot_standards": [] } ``` ## 域名 domain 是由字符和下划线组成的短名称。该 domain 必须唯一,且无法更改。Google 品牌的 domain 示例:`google`。domain 键必须与该品牌文件所在的文件名相匹配。如果存在一个与品牌同名的集成,它必须列在该品牌的 `integrations` 中。 ## 名称 品牌的名称。 ## 集成 实现该品牌产品的集成 domain 列表。 ## IoT 标准 该品牌的设备所支持的 IoT 标准列表。可能的值是 `homekit`、`matter`、`zigbee` 和 `zwave`。请注意,某个特定设备可能不支持列出的任何 IoT 标准。 ## 品牌图片 品牌图片(图标和徽标)存储于 [brands 仓库](https://github.com/home-assistant/brands)。有关品牌图片及其提供方式的更多详情,请参阅 [品牌图片](/developers/core/integration/brand_images.md)。 --- url: /developers/creating_integration_file_structure.md --- 每个集成都存储在一个以其集成 domain 命名的目录中。domain 是由字符和下划线组成的短名称。该 domain 必须唯一,且无法更改。mobile app 集成的 domain 示例:`mobile_app`。因此,该集成的所有文件都在文件夹 `mobile_app/` 中。 该文件夹的最基本内容如下: * `manifest.json`:manifest 文件描述该集成及其依赖。[更多信息](/developers/creating_integration_manifest.md) * `__init__.py`:component 文件。如果该集成只提供了一个 platform,可以将此文件限制为一段介绍该集成的 docstring,例如 `"""The Mobile App integration."""`。 ## 集成设备 - `light.py`、`switch.py` 等 如果你的集成需要集成一个或多个设备,你需要通过创建一个与实体集成交互的 platform 来实现。例如,如果你想在 Home Assistant 中表示一个灯光设备,就需要创建 `light.py`,其中将包含用于 light 集成的 light platform。 * 更多有关[可用实体集成](/developers/core/entity.md)的信息。 * 更多有关[创建 platform](/developers/creating_platform_index.md)的信息。 ## 集成服务动作 - `services.yaml` 如果你的集成需要注册服务动作(service action),它需要提供可用动作的描述。该描述存储在 `services.yaml` 中。[更多有关 `services.yaml` 的信息。](/developers/dev_101_services.md) ## Data update coordinator - `coordinator.py` 你的集成可以通过多种途径接收数据,包括 push 或 poll。通常,集成会通过一次跨所有实体的协调 poll 来获取数据,这需要用到 `DataUpdateCoordinator`。 如果你打算使用它,并且选择创建一个它的子类,建议在 `coordinator.py` 中定义该 coordinator 类。[更多有关 `DataUpdateCoordinator` 的信息](/developers/integration_fetching_data.md#coordinated-single-api-poll-for-data-for-all-entities)。 ## Home Assistant 在哪里查找集成 当 Home Assistant 在配置文件中看到对某个 domain 的引用(即 `mobile_app:`),或者它是另一个集成的依赖时,就会查找该集成。Home Assistant 会查看以下位置: * `/custom_components/` * `homeassistant/components/`(内置集成) 你可以在 `/custom_components` 文件夹中放置一个与内置集合同名 domain 的集成,从而覆盖内置集成。[当覆盖核心集成时,`manifest.json` 文件要求包含一个 version 标签](/developers/creating_integration_manifest.md#version)。一个被覆盖的核心集成可以通过概览中集成框右上角的特定图标来识别 [![打开你的 Home Assistant 实例并显示你的集成。](https://my.home-assistant.io/badges/integrations.svg)](https://my.home-assistant.io/redirect/integrations/) 注意,不建议覆盖内置集成,因为你不会再收到更新。建议使用一个唯一的名称。 ## 品牌图片 - `brand/` 自定义集成可以通过在集成目录中添加 `brand/` 目录来包含其自己的品牌图片。 有关品牌图片及其提供方式的更多信息,请参阅 [品牌图片](/developers/core/integration/brand_images.md)。 --- url: /developers/creating_integration_manifest.md --- 每个集成都有一个 manifest 文件,用于指定其基本信息。该文件以 `manifest.json` 的形式存储在你的集成目录中。添加该文件是必需的。 ```json { "domain": "hue", "name": "Philips Hue", "after_dependencies": ["http"], "codeowners": ["@balloob"], "dependencies": ["mqtt"], "documentation": "https://www.home-assistant.io/components/hue", "integration_type": "hub", "iot_class": "local_polling", "issue_tracker": "https://github.com/balloob/hue/issues", "loggers": ["aiohue"], "requirements": ["aiohue==1.9.1"], "quality_scale": "platinum" } ``` 或者一个可以直接复制到你的项目中的最小示例: ```json { "domain": "your_domain_name", "name": "Your Integration", "codeowners": [], "dependencies": [], "documentation": "https://www.example.com", "integration_type": "hub", "iot_class": "cloud_polling", "requirements": [] } ``` ## 域名 domain 是由字符和下划线组成的短名称。该 domain 必须唯一,且无法更改。mobile app 集成的 domain 示例:`mobile_app`。domain 键必须与该文件所在的目录相匹配。 ## 名称 集成名称必须遵循以下规则: * 如果某个产品或服务同时提供本地和云端集成,则云端版本应在名称后附加"Cloud"(例如,**LIFX Cloud**)。 * 本地版本(或同时支持本地和云端通信的版本)应直接使用不带后缀的产品或服务名称(例如,**LIFX**)。不要附加"Local"。 * 对本身即基于云端的产品或服务,其集成应直接使用原名称,不加任何后缀(例如,**iCloud** 而不是 **iCloud Cloud**)。 ## 版本 对于核心集成,应省略此项。 自定义集成必须提供集成版本。版本必须是 [AwesomeVersion](https://github.com/ludeeus/awesomeversion) 认可的有效版本,例如 [CalVer](https://calver.org/) 或 [SemVer](https://semver.org/)。 ## 集成类型 集成被分为多种类型。每个集成必须在它们的 manifest 中提供一个 `integration_type`,用于描述其主要用途。 :::warning 对于具有 config flow 的核心集成,设置 `integration_type` 是必需的。对于自定义集成和基于 YAML 的集成,如果未设置 `integration_type`,则默认值为 `hub`,但建议显式设置正确的类型。 ::: | 类型 | 描述 | ---- | ----------- | `device` | 提供单个设备,例如 ESPHome。 | | `entity` | 提供基本的实体 platform,例如 sensor 或 light。通常不应使用。 | | `hardware` | 提供硬件集成,例如 Raspberry Pi 或 Hardkernel。通常不应使用。 | | `helper` | 提供实体来帮助用户进行自动化,例如 input boolean、derivative 或 group。 | | `hub` | 提供 hub 集成,包含多个设备或服务,例如 Philips Hue。 | | `service` | 提供单个服务,例如 DuckDNS 或 AdGuard。 | | `system` | 提供系统集成,是预留的,通常不应使用。 | | `virtual` | 本身并不是一个集成。它指向另一个集成或 IoT 标准。请参阅 [virtual integration](#virtual-integration) 部分。 | :::info `hub` 与 `service` 或 `device` 之间的区别由集成的性质决定。`hub` 提供通往多个其他设备或服务的网关。`service` 和 `device` 是每次 config entry 提供一个设备或服务的集成。 ::: ## 文档 包含集成使用文档的网站。如果该集成正在提交以纳入 Home Assistant,则应该是 `https://www.home-assistant.io/integrations/`。 ## 问题跟踪器 你集成的 issue tracker,用户在此报告问题。如果该集成正在提交以纳入 Home Assistant,则应省略此项。对于内置集成,Home Assistant 会自动生成正确的链接。 ## 依赖项 依赖项是指其他 Home Assistant 集成,你需要 Home Assistant 在加载本集成之前成功设置它们。将某个集成添加到 dependencies 中,可以确保被依赖的集成先于本集成加载,但这并不能保证所有依赖的配置条目(config entry)都已设置完成。如果你希望提供来自其他集成的功能(例如 webhooks 或 MQTT 连接),添加依赖项可能是必要的。如果某个依赖项是可选的但不是关键性的,添加一个[后置依赖(after dependency)](#after-dependencies)可能是更好的选择。有关在 MQTT 方面的处理详情,请参阅 [MQTT 部分](#mqtt)。 内置集成在 `dependencies` 中只能指定其他内置集成。自定义集成可以在 `dependencies` 中同时指定内置集成和自定义集成。 ## 后置依赖项 此选项用于指定集成可能会使用但不是必需的依赖项。当存在 `after_dependencies` 时,集成的设置会等待 `after_dependencies` 中列出的集成(通过 YAML 或 config entry 配置的)先完成设置,然后再设置本集成。它还会确保安装 `after_dependencies` 的 requirements,以便集成中的方法可以安全地导入,而不论 `after_dependencies` 中列出的集成是否已配置。例如,如果 `camera` 集成在某些配置中可能会使用 `stream` 集成,将 `stream` 添加到 `camera` 的 manifest 的 `after_dependencies` 中,就能确保如果 `stream` 已配置,它会在 `camera` 之前加载,并且 `stream` 的任何依赖都会被安装并可由 `camera` 导入。如果 `stream` 未配置,`camera` 仍然会正常加载。 内置集成在 `after_dependencies` 中只能指定其他内置集成。自定义集成可以在 `after_dependencies` 中同时指定内置集成和自定义集成。 ## 代码所有者 负责该集成的 GitHub 用户名或团队名称。你应该至少在此添加自己的 GitHub 用户名,以及所有帮助编写已包含代码的人员。 ## 配置流 如果你的集成具有 config flow 以创建 config entry,请指定 `config_flow` 键。当指定时,文件 `config_flow.py` 必须存在于你的集成中。 ```json { "config_flow": true } ``` ### 仅支持单个 config entry 如果你的集成只支持一个 config entry,请指定 `single_config_entry` 键。当指定时,将不允许用户为该集成添加多于一个的 config entry。 ```json { "single_config_entry": true } ``` ## 需求 requirements 是你在正常使用 `pip` 为你的 component 安装的 Python 库或模块。如果你没有使用 `venv`,Home Assistant 会尝试将 requirements 安装到 Home Assistant[配置目录](https://www.home-assistant.io/docs/configuration/)的 `deps` 子目录中;如果你运行在虚拟环境中,则会安装到类似 `path/to/venv/lib/python3.6/site-packages` 的位置。这将确保在启动时所有 requirements 都已就位。如果某些步骤失败,例如编译模块所需的包缺失或其他安装错误,该 component 将无法加载。 requirements 是一个字符串数组。每个条目都是一个与 `pip` 兼容的字符串。例如,media player 的 Cast platform 依赖于 Python 包 PyChromecast v3.2.0:`["pychromecast==3.2.0"]`。 ### 开发和测试期间的自定义 requirements 在开发 component 期间,测试某个 requirement 的不同版本可能很有用。可以分两步完成,以 `pychromecast` 为例: ```shell pip install pychromecast==3.2.0 --target ~/.homeassistant/deps hass --skip-pip-packages pychromecast ``` 这将使用指定的版本,并阻止 Home Assistant 尝试用 `requirements` 中指定的版本覆盖它。如果要阻止任何包被自动覆盖,而无需指定依赖,可以使用全局 `--skip-pip` 标志启动 Home Assistant。 如果需要修改某个 requirement 以支持你的 component,也可以使用 `pip install -e` 安装该 requirement 的开发版本: ```shell git clone https://github.com/balloob/pychromecast.git pip install -e ./pychromecast hass --skip-pip-packages pychromecast ``` 也可以使用公开的 git 仓库来安装 requirement。例如,在将 requirement 依赖的更改发布到 PyPI 之前,测试这些更改非常有用。语法如下: ```json { "requirements": ["@git+https://github.com//.git@"] } ``` `` 可以是任意 git 引用:分支、标签、commit hash 等。请参阅 [PIP 有关 git 支持的文档](https://pip.pypa.io/en/stable/topics/vcs-support/#git)。 以下示例将直接从 GitHub 安装 `pycoolmaster` 库的 `except_connect` 分支: ```json { "requirements": ["pycoolmaster@git+https://github.com/issacg/pycoolmaster.git@except_connect"] } ``` ### 自定义集成的 requirements 自定义集成只应包含 Core [requirements.txt](https://github.com/home-assistant/core/blob/dev/requirements.txt) 中未包含的 requirements。 ## 日志记录器 `loggers` 字段是一个名称列表,表示该集成的 requirements 在其 [getLogger](https://docs.python.org/3/library/logging.html?highlight=logging#logging.getLogger) 调用中使用的名称。 ## 蓝牙 如果你的集成支持通过蓝牙发现,可以在你的 manifest 中添加一个 matcher。如果用户加载了 `bluetooth` 集成,那么在发现设备时,将加载你的集成的 config flow 的 `bluetooth` 步骤。我们支持通过匹配 `connectable`、`local_name`、`service_uuid`、`service_data_uuid`、`manufacturer_id` 和 `manufacturer_data_start` 来监听蓝牙发现。`manufacturer_data_start` 字段期望一个以 0-255 整数编码的字节列表。manifest 值是一个 matcher 字典列表。如果蓝牙数据中找到了任意指定 matcher 的所有项,你的集成就会被发现。去重则由你的 config flow 负责。 `local_name` 的匹配在前三个(3)字符中不得包含任何模式。 如果设备只需要 advertisement 数据,将 `connectable` 设置为 `false` 将选择加入接收来自那些不支持建立连接的蓝牙控制器的发现。 以下示例将匹配 Nespresso Prodigio 机器: ```json { "bluetooth": [ { "local_name": "Prodigio_*" } ] } ``` 以下示例将匹配用于 SwitchBot bot 和窗帘设备的 128 位 uuid 的 service data: ```json { "bluetooth": [ { "service_uuid": "cba20d00-224d-11e6-9fb8-0002a5d5c51b" } ] } ``` 如果你想匹配具有 16 位 uuid 的 service data,需要先将它转换为 128 位 uuid,方法是将 `00000000-0000-1000-8000-00805f9b34fb` 中的第 3 和第 4 个字节替换为 16 位 uuid。例如,对于 Switchbot sensor 设备,16 位 uuid 是 `0xfd3d`,对应的 128 位 uuid 变为 `0000fd3d-0000-1000-8000-00805f9b34fb`。因此,以下示例将匹配用于 SwitchBot sensor 设备的 16 位 uuid 的 service data: ```json { "bluetooth": [ { "service_data_uuid": "0000fd3d-0000-1000-8000-00805f9b34fb" } ] } ``` 以下示例将匹配 HomeKit 设备: ```json { "bluetooth": [ { "manufacturer_id": 76, "manufacturer_data_start": [6] } ] } ``` ## Zeroconf 如果你的集成支持通过 [Zeroconf](https://en.wikipedia.org/wiki/Zero-configuration_networking) 发现,可以在你的 manifest 中添加类型。如果用户加载了 `zeroconf` 集成,那么在发现设备时,将加载你的集成的 config flow 的 `zeroconf` 步骤。 Zeroconf 是一个列表,因此你可以指定多个类型进行匹配。 ```json { "zeroconf": ["_googlecast._tcp.local."] } ``` 某些 zeroconf 类型非常通用(例如 `_printer._tcp.local.`、`_axis-video._tcp.local.` 或 `_http._tcp.local`)。在这种情况下,你应该包含一个 Name(`name`)或 Properties(`properties`)过滤器: ```json { "zeroconf": [ {"type":"_axis-video._tcp.local.","properties":{"macaddress":"00408c*"}}, {"type":"_axis-video._tcp.local.","name":"example*"}, {"type":"_airplay._tcp.local.","properties":{"am":"audioaccessory*"}}, ] } ``` 注意,`properties` 过滤器中的所有值必须是小写的,并且可以包含 fnmatch 类型的通配符。 ## SSDP 如果你的集成支持通过 [SSDP](https://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol) 发现,可以在你的 manifest 中添加类型。如果用户加载了 `ssdp` 集成,那么在发现设备时,将加载你的集成的 config flow 的 `ssdp` 步骤。我们支持通过 SSDP 的 ST、USN、EXT 和 Server 头(头名称小写)以及 [UPnP 设备描述](https://openconnectivity.org/developer/specifications/upnp-resources/upnp/basic-device-v1-0/) 中的数据来进行 SSDP 发现。manifest 值是一个 matcher 字典列表,如果 SSDP/UPnP 数据中找到了任意指定 matcher 的所有项,你的集成就会被发现。去重则由你的 config flow 负责。 以下示例包含一个由三项组成的 matcher,必须全部匹配才能通过此配置进行发现。 ```json { "ssdp": [ { "st": "roku:ecp", "manufacturer": "Roku", "deviceType": "urn:roku-com:device:player:1-0" } ] } ``` ## HomeKit 如果你的集成支持通过 HomeKit 发现,可以在你的 manifest 中添加受支持的型号名称。如果用户加载了 `zeroconf` 集成,那么在发现设备时,将加载你的集成的 config flow 的 `homekit` 步骤。 HomeKit 发现是通过测试发现的模型名是否以 manifest.json 中指定的任何模型名开头来实现的。 ```json { "homekit": { "models": [ "LIFX" ] } } ``` 通过 HomeKit 发现并不意味着你必须使用 HomeKit 协议来与你的设备通信。你可以以任何你合适的方式与设备通信。 当发现信息因为你在 manifest 中的此条目而被路由到你的集成时,该发现信息不再被路由到监听 HomeKit zeroconf 类型的集成。 ## MQTT 如果你的集成支持通过 MQTT 发现,可以在你的 manifest 中添加用于发现的 topic。如果用户加载了 `mqtt` 集成,那么在发现设备时,将加载你的集成的 config flow 的 `mqtt` 步骤。 MQTT 发现是通过订阅在 manifest.json 中指定的 MQTT topic 来实现的。 ```json { "mqtt": [ "tasmota/discovery/#" ] } ``` 如果你的集成需要 `mqtt`,请确保它被添加到了[依赖项](#dependencies)中。 依赖于 MQTT 的集成应该使用 `await mqtt.async_wait_for_mqtt_client(hass)` 等待 MQTT client 可用后才能订阅。`async_wait_for_mqtt_client` 方法会阻塞,并在 MQTT client 可用时返回 `True`。 ## DHCP 如果你的集成支持通过 DHCP 发现,可以在你的 manifest 中添加类型。如果用户加载了 `dhcp` 集成,那么在发现设备时,将加载你的集成的 config flow 的 `dhcp` 步骤。我们支持被动监听 DHCP 发现,基于 `hostname` 和 [OUI](https://en.wikipedia.org/wiki/Organizationally_unique_identifier) 进行匹配,或者在 `registered_devices` 设置为 `true` 时,匹配 device registry 中的 mac address。manifest 值是一个 matcher 字典列表,如果 DHCP 数据中找到了任意指定 matcher 的所有项,你的集成就会被发现。使用[Unix 文件名模式匹配](https://docs.python.org/3/library/fnmatch.html)进行匹配。去重则由你的 config flow 负责。 如果集成希望在设备上线时接收发现流程以更新设备的 IP 地址,但 `hostname` 或 `oui` 匹配过于宽泛,并且它已经使用 `CONNECTION_NETWORK_MAC` 在 device registry 中注册了 mac address,那么它应该添加一个 `registered_devices` 设置为 `true` 的 DHCP 条目。 如果集成支持 `zeroconf` 或 `ssdp`,则应优先于 `dhcp` 使用,因为它通常能提供更好的用户体验。 以下示例包含两个由两项组成的 matcher。任意 matcher 中的所有项都必须匹配,才能通过此配置进行发现。 例如: * 如果 `hostname` 为 `Rachio-XYZ` 且 `macaddress` 为 `00:9D:6B:55:12:AA`,则会触发发现(第 1 个 matcher)。 * 如果 `hostname` 为 `Dachio-XYZ` 或 `Pachio-XYZ`,且 `macaddress` 为 `00:9D:6B:55:12:AA`,则会触发发现(第 3 个 matcher)。 * 如果 `hostname` 为 `Rachio-XYZ` 且 `macaddress` 为 `00:00:00:55:12:AA`,则不会触发发现(MAC 不匹配)。 * 如果 `hostname` 为 `NotRachio-XYZ` 且 `macaddress` 为 `00:9D:6B:55:12:AA`,则不会触发发现(hostname 不匹配)。 ```json { "dhcp": [ { "hostname": "rachio-*", "macaddress": "009D6B*" }, { "hostname": "[dp]achio-*", "macaddress": "009D6B*" } ] } ``` 设置 `registered_devices` 为 `true` 的示例: ```json { "dhcp": [ { "hostname": "myintegration-*", }, { "registered_devices": true, } ] } ``` ## USB 如果你的集成支持通过 usb 发现,可以在你的 manifest 中添加类型。如果用户加载了 `usb` 集成,那么在发现设备时,将加载你的集成的 config flow 的 `usb` 步骤。我们通过从 USB 描述符中提取 VID(Vendor ID)、PID(Device ID)、序列号(Serial Number)、制造商(Manufacturer)和描述(Description)来支持发现。有关如何识别这些值的帮助,请参阅[如何识别设备](https://wiki.debian.org/HowToIdentifyADevice/USB)。manifest 值是一个 matcher 字典列表。如果 USB 数据中找到了任意指定 matcher 的所有项,你的集成就会被发现。去重则由你的 config flow 负责。 :::warning 某些 VID 和 PID 组合被许多互不相关的设备使用。例如 VID `10C4` 和 PID `EA60` 可以匹配任何 Silicon Labs CP2102 USB-Serial 桥接芯片。在匹配此类设备时,重要的是要匹配 `description` 或其他标识符,以避免意外的发现。 ::: 以下示例包含两个由两项组成的 matcher。任意一个 matcher 中的所有项都必须匹配,才能通过此配置进行发现。 例如: * 如果 `vid` 为 `AAAA` 且 `pid` 为 `AAAA`,则会触发发现。 * 如果 `vid` 为 `AAAA` 且 `pid` 为 `FFFF`,则不会触发发现。 * 如果 `vid` 为 `CCCC` 且 `pid` 为 `AAAA`,则不会触发发现。 * 如果 `vid` 为 `1234`,`pid` 为 `ABCD`,`serial_number` 为 `12345678`,`manufacturer` 为 `Midway USB`,`description` 为 `Version 12 Zigbee Stick`,则会触发发现。 ```json { "usb": [ { "vid": "AAAA", "pid": "AAAA" }, { "vid": "BBBB", "pid": "BBBB" }, { "vid": "1234", "pid": "ABCD", "serial_number": "1234*", "manufacturer": "*midway*", "description": "*zigbee*" }, ] } ``` ## 集成质量等级 [Integration Quality Scale](/developers/core/integration-quality-scale.md) 根据代码质量和用户体验对集成进行评分。质量等级的每一级都包含一个要求列表。如果集成符合所有要求,则认为它已达到该级别。 新集成至少需要满足 bronze 级别,因此请务必查看[Integration Quality Scale](/developers/core/integration-quality-scale.md)的要求列表。它有助于极大地改进代码和用户体验。 ```json { "quality_scale": "silver" } ``` ## IoT 类别 [IoT class][iot_class] 描述集成如何与设备或服务进行连接。有关 IoT 类别的更多信息,请阅读关于["分类物联网"](https://www.home-assistant.io/blog/2016/02/12/classifying-the-internet-of-things/#classifiers)的博客。 manifest 中接受的 IoT 类别如下: * `assumed_state`:我们无法获取设备的状态。我们只能根据最后一次命令来推测状态。 * `cloud_polling`:此设备的集成通过云端进行,需要活跃的互联网连接。轮询状态意味着状态的更新可能会稍后才会被注意到。 * `cloud_push`:此设备的集成通过云端进行,需要活跃的互联网连接。一旦有新状态可用,Home Assistant 就会收到通知。 * `local_polling`:提供与设备的直接通信。轮询状态意味着状态的更新可能会稍后才会被注意到。 * `local_push`:提供与设备的直接通信。一旦有新状态可用,Home Assistant 就会收到通知。 * `calculated`:集成不自己处理通信,而是提供了一个计算结果。 [iot_class]: https://www.home-assistant.io/blog/2016/02/12/classifying-the-internet-of-things/#classifiers ## 虚拟集成 有些产品是由不以该产品命名的集成支持的。例如,Yale Home 门锁是通过 August 集成集成的,而 IKEA SYMFONISK 产品线可以与 Sonos 集成一起使用。 还有一种情况是,某产品线只支持标准的 IoT 标准,例如 Zigbee 或 Z-Wave。例如,U-tec ultraloq 通过 Z-Wave 工作,没有特定的专用集成。 对于最终用户来说,找到如何将那些产品与 Home Assistant 集成起来可能会感到困惑。为了帮助处理上述情况,Home Assistant 提供了"Virtual integrations"。这些集成并不是真正的集成,而是用于帮助用户为其设备找到正确的集成。 virtual integration 是一个只包含单个 manifest 文件的集成,没有任何其他代码。有两种类型的 virtual integration:由另一个集成支持的 virtual integration 和使用现有 IoT 标准的 virtual integration。 :::info virtual integration 只能由 Home Assistant Core 提供,不能由自定义集成提供。 ::: ### 支持来源 "Supported by" virtual integration 是指向另一个集成的集成,由后者提供其实现。例如,Yale Home 门锁是通过 August (`august`) 集成集成的。 示例 manifest: ```json { "domain": "yale_home", "name": "Yale Home", "integration_type": "virtual", "supported_by": "august" } ``` `domain` 和 `name` 与其他任何集成相同,但 `integration_type` 设置为 `virtual`。 此 virtual integration 的 domain 的 logo 必须添加到我们的[brands 仓库](https://github.com/home-assistant/brands/),因此在这种情况下,会使用 Yale Home 的品牌标识。 `supported_by` 是为该产品提供实现的集成的 domain。在上面的示例中,Yale Home 门锁由 August 集成支持,并指向其 domain `august`。 结果: * Yale Home 会列在我们的用户文档网站的集成部分下,并附带一个自动生成的 stub 页面,引导用户使用该集成。 * Yale Home 会在 Home Assistant 中点击"添加集成"时列出。选中后,我们会向用户解释该产品是通过另一个集成集成的,然后用户继续进入 Xioami Miio 的 config flow。 ### IoT 标准 "IoT Standards" virtual integration 是指使用现有 IoT 标准来与设备进行连接的集成。例如,U-tec ultraloq 通过 Z-Wave 工作,没有特定的专用集成。 示例 manifest: ```json { "domain": "ultraloq", "name": "ultraloq", "integration_type": "virtual", "iot_standards": ["zwave"], } ``` `domain` 和 `name` 与其他任何集成相同,但 `integration_type` 设置为 `virtual`。 此 virtual integration 的 domain 的 logo 应添加到我们的[brands 仓库](https://github.com/home-assistant/brands/)。 `iot_standards` 是该产品用于连接的标准。在上面的示例中,U-tech ultraloq 产品使用 Z-Wave 与 Home Assistant 集成。 结果: * U-tech ultraloq 会列在我们的用户文档网站的集成部分下,并附带一个自动生成的 stub 页面,引导用户使用该集成。 * U-tech ultraloq 会在 Home Assistant 中点击"添加集成"时列出。选中后,我们会引导用户添加此 Z-Wave 设备(如果 Z-Wave 尚未设置,则先设置 Z-Wave)。 :::info 品牌也[支持设置 IoT 标准](/developers/creating_integration_brand.md#iot-standards)。 优先建议在品牌层面设置 IoT 标准,只有在会对最终用户造成混淆的情况下,才使用 virtual integration。 ::: --- url: /developers/creating_integration_tests_file_structure.md --- 每个集成的测试都存储在一个以其集成 domain 命名的目录中。例如,mobile app 集成的测试应存储在 `tests/components/mobile_app` 中。 该文件夹的内容如下: * `__init__.py`:`pytest` 需要它来找到测试,可以将此文件限制为一段介绍集成测试的 docstring,例如 `"""Tests for the Mobile App integration."""`。 * `conftest.py`:Pytest 测试 fixtures * `test_xxx.py`:测试集成对应部分的测试文件。`__init__.py` 中功能的测试(例如设置、重新加载和卸载 config entry),应该在名为 `test_init.py` 的文件中。 ## 与其他集成共享 test fixtures 如果你的集成是一个实体集成(其他集成在它上面有 platforms),例如 `light` 或 `sensor`,则该集成可以提供其他集成编写测试时可使用的 test fixtures。 例如,`light` 集成可以通过向 `tests/components/conftest.py` 添加 fixture stubs,并在 `tests/components/light/common.py` 中实现这些 fixtures 的实际代码,来提供用于创建 mocked light 实体的 fixtures。 --- url: /developers/creating_platform_code_review.md --- 添加新 platform 时需要完成的事项清单。 :::info 并非所有现有的 platforms 都遵循本清单中的要求。这不能作为不遵循它们的理由! ::: ### 0. Common 1. 遵循我们的 [Style guidelines](/developers/development_guidelines.md) 2. 使用 [`const.py`](https://github.com/home-assistant/core/blob/dev/homeassistant/const.py) 中已有的常量 * 只有当常量被广泛使用时才将其添加到 `const.py` 中。否则请将其保留在 platform 级别 * 使用 `CONF_MONITORED_CONDITIONS` 代替 `CONF_MONITORED_VARIABLES` ### 1. External requirements 1. Requirements 已添加到 [`manifest.json`](/developers/creating_integration_manifest.md)。`REQUIREMENTS` 常量已弃用。 2. Requirement 版本应该被固定:`"requirements": ['phue==0.8.1']` 3. 我们不再希望 requirements 托管在 GitHub 上。请上传到 PyPi。 4. 每个 requirement 都满足 [library requirements](/developers/api_lib_index.md#basic-library-requirements)。 ### 2. Configuration 1. 如果 platform 可以直接设置,添加一个 voluptuous schema 用于 [configuration validation](/developers/development_validation.md) 2. Voluptuous schema 扩展自 component 的 schema (例如,`hue.light.PLATFORM_SCHEMA` 扩展自 `light.PLATFORM_SCHEMA`) 3. 默认参数在 voluptuous schema 中指定,而不是在 `setup_platform(...)` 中 4. 你的 `PLATFORM_SCHEMA` 应尽可能多地使用来自 `homeassistant.const` 的通用 config keys 5. 永远不要依赖用户在 `customize` 中添加内容来配置你 platform 内部的行为。 ```python import voluptuous as vol from homeassistant.const import CONF_FILENAME, CONF_HOST from homeassistant.components.light import PLATFORM_SCHEMA import homeassistant.helpers.config_validation as cv CONF_ALLOW_UNREACHABLE = "allow_unreachable" DEFAULT_UNREACHABLE = False PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { vol.Required(CONF_HOST): cv.string, vol.Optional(CONF_ALLOW_UNREACHABLE, default=DEFAULT_UNREACHABLE): cv.boolean, vol.Optional(CONF_FILENAME): cv.string, } ) ``` ### 3. Setup platform 1. 验证传入的配置(user/pass/host 等)是否有效。 2. 尽可能将你的 `add_entities` 调用分组。 3. 如果 platform 添加了额外的 actions,格式应为 `.`。因此,如果你的 integration domain 是 "awesome\_sauce",并且你正在制作一个 light platform,你会在 `awesome_sauce` domain 下注册 service actions。确保你的 service actions [verify permissions](/developers/auth_permissions.md#checking-permissions)。 ### 4. Entity 1. 继承你要为其构建 platform 的 integration 的 entity。 ```python from homeassistant.components.light import Light class HueLight(Light): """Hue light component.""" ``` 2. 避免将 `hass` 作为参数传递给 entity。`hass` 将在 entity 被添加到 Home Assistant 时被设置到 entity 上。这意味着你可以在 entity 内部通过 `self.hass` 访问 `hass`。 3. 不要在 constructor 中调用 `update()`,而是使用 `add_entities(devices, update_before_add=True)`。 4. 不要在 properties 中进行任何 I/O。改为在 `update()` 内部缓存值。 5. 处理时间时,state 和/或 attributes 不应包含某事发生以来的相对时间。相反,它应该存储 UTC timestamps。 6. 利用 [entity lifecycle callbacks](/developers/core/entity.md#lifecycle-hooks) 来附加 event listeners 或清理 connections。 ### 5. 与 devices/services 通信 1. 所有与 API 相关的代码必须托管在 PyPi 上的第三方 library 的一部分。Home Assistant 应该只与 objects 交互,而不直接调用 API。 ```python # bad status = requests.get(url("/status")) # good from phue import Bridge bridge = Bridge(...) status = bridge.status() ``` [发布你自己的 PyPI package 的教程](https://towardsdatascience.com/how-to-open-source-your-first-python-package-e717444e1da0) 其他值得注意的发布 python packages 的资源: [Cookiecutter Project](https://cookiecutter.readthedocs.io/) [flit](https://flit.readthedocs.io/) [Poetry](https://python-poetry.org/) --- url: /developers/creating_platform_index.md --- Home Assistant 有各种内置的 integrations,它们对 device types 进行了抽象。有 [lights](/developers/core/entity/light.md)、[switches](/developers/core/entity/switch.md)、[covers](/developers/core/entity/cover.md)、[climate devices](/developers/core/entity/climate.md),以及[更多](/developers/core/entity.md)。你的 integration 可以通过创建 platform 来接入这些 integrations。对于你要集成的每一个 integration,你都需要一个 platform。 要创建 platform,你需要创建一个文件,文件名为你为其构建 platform 的 integration 的 domain name。因此,如果你正在构建一个 light,你会在你的 integration folder 中添加一个新文件 `light.py`。 我们创建了两个示例 integrations,可以让你了解其工作原理: * [Example sensor platform](https://github.com/home-assistant/example-custom-config/tree/master/custom_components/example_sensor/): platform 的 hello world。 * [Example light platform](https://github.com/home-assistant/example-custom-config/tree/master/custom_components/example_light/): 展示最佳实践。 ### 与 devices 交互 Home Assistant 的一条规则是 integration 永远不要直接与 devices 交互。相反,它应该与一个第三方 Python 3 library 交互。这样,Home Assistant 可以与 Python 社区共享代码,并保持项目的可维护性。 一旦你的 Python library [准备就绪并发布到 PyPI](/developers/api_lib_index.md),将其添加到 [manifest](/developers/creating_integration_manifest.md) 中。现在,是时候实现你为其创建 platform 的 integration 所提供的 Entity base class 了。 在 [entity index](/developers/core/entity.md) 中找到你的 integration,以查看可以实现的 methods 和 properties。 --- url: /developers/data_entry_flow_index.md --- Data Entry Flow 是 Home Assistant 的一部分,一个数据录入框架。数据录入通过 data entry flows 完成。一个 flow 可以表示一个简单的登录表单,也可以表示为 component 提供的多步骤 setup wizard。Flow Manager 管理所有进行中的 flows,并处理新 flows 的创建。 Data Entry Flow 在 Home Assistant 中用于登录、创建 config entries、处理 options flow、修复 issues。 ## Flow 管理器 这是一个管理进行中 flows 的类。在实例化它时,你需要传入两个 async callbacks: ```python async def async_create_flow(handler, context=context, data=data): """Create flow.""" ``` 该 manager 通过此 async callback 将 config flow handlers 的实例化委托给调用方。这让 manager 的父级可以定义自己的方式来查找 handlers 并为实例化准备 handler。例如,在 config entry manager 的情况下,它会确保 dependencies 和 requirements 已设置好。 ```python async def async_finish_flow(flow, result): """Finish flow.""" ``` 当一个 flow 完成或被中止时,会调用此 async callback,即 `result['type'] in [FlowResultType.CREATE_ENTRY, FlowResultType.ABORT]`。该 callback 函数可以修改 result 并将其返回,如果 result type 变成了 `FlowResultType.FORM`,flow 会继续运行,显示另一个表单。 如果 result type 是 `FlowResultType.FORM`,result 应如下所示: ```python { # The result type of the flow "type": FlowResultType.FORM, # the id of the flow "flow_id": "abcdfgh1234", # handler name "handler": "hue", # name of the step, flow.async_step_[step_id] will be called when form submitted "step_id": "init", # a voluptuous schema to build and validate user input "data_schema": vol.Schema(), # an errors dict, None if no errors "errors": errors, # a detail information about the step "description_placeholders": description_placeholders, } ``` 如果 result type 是 `FlowResultType.CREATE_ENTRY`,result 应如下所示: ```python { # Data schema version of the entry "version": 2, # The result type of the flow "type": FlowResultType.CREATE_ENTRY, # the id of the flow "flow_id": "abcdfgh1234", # handler name "handler": "hue", # title and data as created by the handler "title": "Some title", "result": { "some": "data" }, } ``` 如果 result type 是 `FlowResultType.ABORT`,result 应如下所示: ```python { # The result type of the flow "type": FlowResultType.ABORT, # the id of the flow "flow_id": "abcdfgh1234", # handler name "handler": "hue", # the abort reason "reason": "already_configured", } ``` ## Flow 处理器 Flow handlers 处理单个 flow。一个 flow 包含一个或多个 steps。当一个 flow 被实例化时,会调用 `FlowHandler.init_step` step。每个 step 都有几种可能的结果: * [显示表单(Show Form)](#show-form) * [创建条目(Create Entry)](#create-entry) * [中止(Abort)](#abort) * [外部步骤(External Step)](#external-step--external-step-done) * [显示进度(Show Progress)](#show-progress--show-progress-done) * [显示菜单(Show Menu)](#show-menu) 每个 flow handler 至少需要定义一个版本号和一个 step。这个 step 不一定是 `init`,因为 `async_create_flow` 可以根据当前工作流分配 `init_step`,例如在 configuration 中,`context.source` 会被用作 `init_step`。 例如,最基本的 config flow 如下: ```python from homeassistant import data_entry_flow @config_entries.HANDLERS.register(DOMAIN) class ExampleConfigFlow(data_entry_flow.FlowHandler): # The schema version of the entries that it creates # Home Assistant will call your migrate method if the version changes # (this is not implemented yet) VERSION = 1 async def async_step_user(self, user_input=None): """Handle user step.""" ``` Data entry flows 依赖 translations 来显示 steps 中的文本。这取决于 data entry flow manager 的父级决定存储在哪里。对于 config 和 option flows,分别存储在 `strings.json` 的 `config` 和 `option` 下。 关于 `strings.json` 的更详细解释,请参阅 [backend translation](/developers/internationalization/core.md) 页面。 ### 显示表单(Show form) 这种 result type 会向用户显示一个需要填写的表单。你定义当前 step、数据 schema(使用 voluptuous 和/或 [selectors](https://www.home-assistant.io/docs/blueprint/selectors/) 的混合)以及可选的错误字典。 ```python from homeassistant.data_entry_flow import section from homeassistant.helpers.selector import selector class ExampleConfigFlow(data_entry_flow.FlowHandler): async def async_step_user(self, user_input=None): # Specify items in the order they are to be displayed in the UI data_schema = { vol.Required("username"): str, vol.Required("password"): str, # Items can be grouped by collapsible sections vol.Required("ssl_options"): section( vol.Schema( { vol.Required("ssl", default=True): bool, vol.Required("verify_ssl", default=True): bool, } ), # Whether or not the section is initially collapsed (default = False) {"collapsed": False}, ) } if self.show_advanced_options: data_schema[vol.Optional("allow_groups")] = selector({ "select": { "options": ["all", "light", "switch"], } }) return self.async_show_form(step_id="init", data_schema=vol.Schema(data_schema)) ``` #### 输入字段的分组 如上例所示,输入字段可以在 sections 中按视觉进行分组。 每个 section 都有一个 [可翻译的 name 和 description](#labels--descriptions),还可以指定一个 icon。 将输入字段按 section 分组会影响向用户展示输入的方式,也会影响用户输入的 structure。 在上面的例子中,用户输入的 structure 如下: ```python { "username": "user", "password": "hunter2", "ssl_options": { "ssl": True, "verify_ssl": False, }, } ``` 只允许单层 sections;不允许在 section 内嵌套 section。 要为某个 section 指定 icon,请按照下面的示例更新 `icons.json`: ```json { "config": { "step": { "user": { "sections": { "ssl_options": "mdi:lock" } } } } } ``` #### 标签与描述 表单的 translations 添加到 `strings.json` 中,key 为对应的 `step_id`。该 object 可以包含以下 keys: | Key | Value | Notes | | :----------------: | :-----------------: | :------------------------------------------------------------------------------------------------------------------------------------------- | | `title` | Form heading | 不要包含你的品牌名称,它会自动从 manifest 中注入。 | | `description` | Form instructions | 可选。不要链接到文档,因为那会自动链接。不要包含 "可以在这里设置 X" 这类的基本信息。 | | `data` | Field labels | 保持简洁,并在适当的时候与其他 integrations 保持一致,以提供最佳的用户体验。 | | `data_description` | Field descriptions | 可选的说明文本,显示在字段下方。 | | `section` | Section translation | Sections 的 translations,每个 section 可以有该 section 的 `name` 和 `description`,以及其字段的 `data` 和 `data_description`。 | 关于翻译 data entry flows 的更多细节,可以在 [core translations documentation](/developers/internationalization/core.md) 中找到。 字段 labels 和 descriptions 以一个字典形式提供,其 keys 对应你的 schema。下面是一个简单的示例: ```json { "config": { "step": { "user": { "title": "Add Group", "description": "Some description", "data": { "entities": "Entities" }, "data_description": { "entities": "The entities to add to the group" }, "sections": { "additional_options": { "name": "Additional options", "description": "A description of the section", "data": { "advanced_group_option": "Advanced group option" }, "data_description": { "advanced_group_option": "A very complicated option which does abc" }, } } } } } } ``` #### 启用浏览器自动填充 假设你的 integration 正在收集表单数据,而这些数据可以由浏览器或密码管理器自动填充,比如登录凭据或联系信息。你应该尽可能启用自动填充,以提供最佳的用户体验和可访问性。有两种方式可以启用它。 第一种方式是使用 Voluptuous,并使用 frontend 可识别的 data keys。Frontend 会识别 `"username"` 和 `"password"` keys,并分别添加值为 `"username"` 和 `"current-password"` 的 HTML `autocomplete` 属性。Autocomplete 的支持仅限于 `"username"` 和 `"password"` 字段,主要是为了让许多收集这些字段的 integrations 能够快速启用自动填充,而不需要将它们的 schemas 转换为 selectors。 第二种方式是使用 [text selector](https://www.home-assistant.io/docs/blueprint/selectors/#text-selector)。Text selector 可以完全控制 input type,并允许指定 `autocomplete` 的任何允许值。一个收集特定可填充数据的假设 schema 可能如下: ```python import voluptuous as vol from homeassistant.const import CONF_PASSWORD, CONF_USERNAME from homeassistant.helpers.selector import ( TextSelector, TextSelectorConfig, TextSelectorType, ) STEP_USER_DATA_SCHEMA = vol.Schema( { vol.Required(CONF_USERNAME): TextSelector( TextSelectorConfig(type=TextSelectorType.EMAIL, autocomplete="username") ), vol.Required(CONF_PASSWORD): TextSelector( TextSelectorConfig( type=TextSelectorType.PASSWORD, autocomplete="current-password" ) ), vol.Required("postal_code"): TextSelector( TextSelectorConfig(type=TextSelectorType.TEXT, autocomplete="postal-code") ), vol.Required("mobile_number"): TextSelector( TextSelectorConfig(type=TextSelectorType.TEL, autocomplete="tel") ), } ) ``` #### 默认值与建议值 如果你想在表单中预填数据,你有两种选择。第一种是使用 `default` 参数。这既会预填该字段,又会在用户留空该字段时作为默认值。 ```python data_schema = { vol.Optional("field_name", default="default value"): str, } ``` 另一种选择是使用 suggested value——这也会预填表单字段,但允许用户在需要时将其留空。 ```python data_schema = { vol.Optional( "field_name", description={"suggested_value": "suggested value"} ): str, } ``` 你也可以将两者混合使用——通过 `suggested_value` 预填,并在字段留空时使用另一个 `default` 值,但这可能会让用户感到困惑,请谨慎使用。 使用 suggested values 还可以声明一个静态 schema,并从现有输入中合并 suggested values。`add_suggested_values_to_schema` helper 可以做到这一点: ```python OPTIONS_SCHEMA = vol.Schema( { vol.Optional("field_name", default="default value"): str, } ) class ExampleOptionsFlow(config_entries.OptionsFlow): async def async_step_init( self, user_input: dict[str, Any] | None = None ) -> FlowResult: return self.async_show_form( data_schema = self.add_suggested_values_to_schema( OPTIONS_SCHEMA, self.entry.options ) ) ``` 注意:对于 select 类型的输入(由 `vol.In(...)` schema 创建),如果没有指定 `default`,则 frontend 会默认选择第一个选项。 #### 显示只读信息 某些 integrations 的 options 在初始配置后会被冻结。在显示 options flow 时,你可以以只读方式展示这些信息,以便用户记住在初始配置时选择了哪些 options。为此,像往常一样定义一个可选 selector,但将 `read_only` 标志设置为 `True`。 ```python # Example Config Flow Schema DATA_SCHEMA_SETUP = vol.Schema( { vol.Required(CONF_ENTITY_ID): EntitySelector() } ) # Example Options Flow Schema DATA_SCHEMA_OPTIONS = vol.Schema( { vol.Optional(CONF_ENTITY_ID): EntitySelector( EntitySelectorConfig(read_only=True) ), vol.Optional(CONF_TEMPLATE): TemplateSelector(), } ) ``` 这会在启动 options flow 时,将初始配置中选中的 entity 作为只读属性显示。 #### 验证 用户填写完表单后,step 方法会被再次调用,并传入用户输入。只有当用户输入通过你的 data schema 时,你的 step 才会被调用。当用户传入 data 时,你需要对 data 进行额外的验证。例如,你可以验证传入的 username 和 password 是否有效。 如果有问题,你可以返回一个包含 errors 的字典。错误字典中的每个 key 都对应包含错误信息的字段名称。如果你想显示一个与特定字段无关的错误,请使用 key `base`。所指定的 errors 需要引用 translation 文件中的一个 key。 ```python class ExampleConfigFlow(data_entry_flow.FlowHandler): async def async_step_user(self, user_input=None): errors = {} if user_input is not None: # Validate user input valid = await is_valid(user_input) if valid: # See next section on create entry usage return self.async_create_entry(...) errors["base"] = "auth_error" # Specify items in the order they are to be displayed in the UI data_schema = { vol.Required("username"): str, vol.Required("password"): str, } return self.async_show_form( step_id="init", data_schema=vol.Schema(data_schema), errors=errors ) ``` #### 多步骤 flows 如果用户输入通过了验证,你可以再次返回其中一种可能的 step types。如果你要引导用户进入下一个 step,请返回该 step 的返回值: ```python class ExampleConfigFlow(data_entry_flow.FlowHandler): async def async_step_init(self, user_input=None): errors = {} if user_input is not None: # Validate user input valid = await is_valid(user_input) if valid: # Store info to use in next step self.init_info = user_input # Return the form of the next step return await self.async_step_account() ... ``` ### 创建条目(Create entry) 当 result 为 "Create Entry" 时,会创建一个条目并传递给 flow manager 的父级。会向用户显示一条成功消息,flow 即告完成。你通过传入 title、data 以及可选的 options 来创建条目。Title 可以在 UI 中用于向用户指示这是哪个条目。Data 和 options 可以是任何数据类型,只要它们可 JSON 序列化。Options 用于可变 data,例如 radius。而 Data 用于不会在 entry 中更改的不可变 data,例如 location data。 ```python class ExampleConfigFlow(data_entry_flow.FlowHandler): async def async_step_user(self, user_input=None): return self.async_create_entry( title="Title of the entry", data={ "username": user_input["username"], "password": user_input["password"] }, options={ "mobile_number": user_input["mobile_number"] }, ) ``` 注意:用户可以更改密码,这在技术上是可变 data,但对于更改 authentication credentials,你需要使用 [reauthentication](/developers/core/integration/config_flow.md#reauthentication),它可以修改 config entry data。 ### 中止(Abort) 当一个 flow 无法完成时,你需要中止它。这会结束 flow 并通知用户 flow 已完成。一个 flow 无法完成的原因可能是设备已经被配置,或者与 Home Assistant 不兼容。 ```python class ExampleConfigFlow(data_entry_flow.FlowHandler): async def async_step_user(self, user_input=None): return self.async_abort(reason="not_supported") ``` ### 外部步骤 & 外部步骤完成(External step & external step done) 有时用户需要通过在外部网站上执行操作来完成 config flow。例如,通过重定向到外部网页来设置一个 integration。这通常由使用 OAuth2 来授权用户的 integrations 使用。 *这个示例是关于 config entries 的,但同样适用于使用 data entry flows 的其他部分。* 流程如下: 1. 用户在 Home Assistant 中启动 config flow。 2. Config flow 提示用户在外部网站上完成 flow。 3. 用户打开外部网站。 4. 外部步骤完成后,用户的浏览器会被重定向到 Home Assistant 的一个 endpoint,以传递响应。 5. Endpoint 验证响应,验证通过后,将外部步骤标记为完成,并返回用于关闭窗口:`` 的 JavaScript 代码。 为了能够将外部步骤的结果路由到 Home Assistant endpoint,你需要确保 config flow ID 包含在内。如果你的外部步骤是一个 OAuth2 flow,你可以利用 oauth2 state 来实现这一点。这是一个不被 authorization 页面解释、而是原样传递给 Home Assistant endpoint 的变量。 6. 窗口关闭,Home Assistant 带有 config flow 的用户界面会再次显示给用户。 7. 当外部步骤被标记为完成时,config flow 会自动推进到下一个 step。用户会被提示进入下一个 step。 包含外部步骤的示例 configuration flow。 ```python from homeassistant import config_entries @config_entries.HANDLERS.register(DOMAIN) class ExampleConfigFlow(data_entry_flow.FlowHandler): VERSION = 1 data = None async def async_step_user(self, user_input=None): if not user_input: return self.async_external_step( step_id="user", url=f"https://example.com/?config_flow_id={self.flow_id}", ) self.data = user_input return self.async_external_step_done(next_step_id="finish") async def async_step_finish(self, user_input=None): return self.async_create_entry(title=self.data["title"], data=self.data) ``` 在返回 `async_mark_external_step_done` 之前,不要根据外部步骤的 data 执行工作。相反,应该在标记外部步骤完成时,将其作为 `next_step_id` 引用的那个 step 中执行工作。这会在执行工作期间在 UI 中显示一个 spinner,从而提供更好的用户体验。 如果你把工作在 authorize callback 内部执行,用户会一直盯着空白屏幕,直到数据转发完成,窗口突然关闭。如果你在标记外部步骤完成之前执行工作,用户仍然会看到带有 "Open external website" 按钮的表单,同时后台工作正在进行。这也令人不快。 用于标记外部步骤为完成的示例代码: ```python from homeassistant import data_entry_flow async def handle_result(hass, flow_id, data): result = await hass.config_entries.async_configure(flow_id, data) if result["type"] == data_entry_flow.FlowResultType.EXTERNAL_STEP_DONE: return "success!" else: return "Invalid config flow specified" ``` ### 显示进度 & 显示进度完成(Show progress & show progress done) 如果一个 data entry flow step 需要相当长的时间才能完成,我们应该告知用户。 *这个示例是关于 config entries 的,但同样适用于使用 data entry flows 的其他部分。* 流程如下: 1. 用户在 Home Assistant 中启动 config flow。 2. Config flow 创建一个 `asyncio.Task` 来执行长时间运行的任务。 3. Config flow 通过调用 `async_show_progress` 并传入 `asyncio.Task` object 来告知用户一个任务正在进行中,并且需要一些时间才能完成。Flow 应该将一个与任务特定的字符串作为 `progress_action` 参数传递,以表示提示信息的翻译文本。 4. 任务完成后,config flow 会被自动调用,但也可以在任务完成之前被调用,例如当 frontend 重新加载时。 * 如果任务尚未完成,flow 不应再创建另一个任务,而是再次调用 `async_show_progress`。 * 如果任务已完成,flow 必须调用 `async_show_progress_done`,指示下一个 step 5. 每次我们调用 show progress 或 show progress done 时,frontend 都会更新。 6. 当 progress 被标记为完成时,config flow 会自动推进到下一个 step。用户会被提示进入下一个 step。 7. 任务可以选择性地调用 `async_update_progress(progress)`,其中 progress 是一个介于 0 和 1 之间的 float,表示任务的完成程度。 包含两个顺序 progress 任务的示例 configuration flow。 ```python import asyncio from homeassistant import config_entries from .const import DOMAIN class TestFlow(config_entries.ConfigFlow, domain=DOMAIN): VERSION = 1 task_one: asyncio.Task | None = None task_two: asyncio.Task | None = None async def async_step_user(self, user_input=None): uncompleted_task: asyncio.Task[None] | None = None if not self.task_one: coro = asyncio.sleep(10) self.task_one = self.hass.async_create_task(coro) if not self.task_one.done(): progress_action = "task_one" uncompleted_task = self.task_one if not uncompleted_task: if not self.task_two: self.async_update_progress(0.5) # tell frontend we are 50% done coro = asyncio.sleep(10) self.task_two = self.hass.async_create_task(coro) if not self.task_two.done(): progress_action = "task_two" uncompleted_task = self.task_two if uncompleted_task: return self.async_show_progress( progress_action=progress_action, progress_task=uncompleted_task, ) return self.async_show_progress_done(next_step_id="finish") async def async_step_finish(self, user_input=None): if not user_input: return self.async_show_form(step_id="finish") return self.async_create_entry(title="Some title", data={}) ``` ### 显示菜单(Show menu) 这会将一个 navigation menu 显示给用户,方便选择下一个 step。Menu labels 可以通过指定一个 `{step_id: label}` 字典硬编码,或者在指定一个列表时,通过 `strings.json` 中的 "menu\_options" 进行翻译。此外,menu descriptions 可以通过 `strings.json` 中的 "menu\_option\_descriptions" 提供。 ```python class ExampleConfigFlow(data_entry_flow.FlowHandler): async def async_step_user(self, user_input=None): return self.async_show_menu( step_id="user", menu_options=["discovery", "manual"], description_placeholders={ "model": "Example model", } ) # Example showing the other approach return self.async_show_menu( step_id="user", menu_options={ "option_1": "Option 1", "option_2": "Option 2", } ) ``` ```json { "config": { "step": { "user": { "menu_options": { "discovery": "Discovery", "manual": "Manual ({model})", }, "menu_option_descriptions": { "discovery": "Description of discovery", "manual": "Description of manual", } } } } } ``` 向 `async_show_menu` 传递 `sort=True` 还会按照用户语言对 menu items 的 label 进行排序。 ## 从外部源初始化 config flow 你可能希望通过编程方式初始化一个 config flow。例如,当我们在网络上发现一个需要用户交互才能完成 setup 的设备时。为此,在初始化 flow 时传入一个 source 参数以及可选的用户输入: ```python await flow_mgr.async_init( "hue", context={"source": data_entry_flow.SOURCE_DISCOVERY}, data=discovery_info ) ``` Config flow handler 不会从 `init` step 开始。相反,它会用一个与 source 相等的 step 名称来实例化。该 step 应该遵循与正常 step 相同的返回值。 ```python class ExampleConfigFlow(data_entry_flow.FlowHandler): async def async_step_discovery(self, info): """Handle discovery info.""" ``` Config flow 的 source 在 `FlowHandler` 上以 `self.source` 的形式提供。 --- url: /developers/deprecating.md --- Deprecation 是预定在未来执行的 breaking change:旧行为仍然有效,所有受影响者都会收到警告,而真正的移除发生在之后的某个 release 中。 任何移除都必须先经过 deprecation。即使你认为只影响少数用户也是如此,因为一个 entity、action 或 constant 可能从我们看不到的 automations、scripts 和 dashboards 中被引用。 | Who is affected | Minimum period | | --- | --- | | 用户(YAML configuration、actions、entities、attributes、integrations) | 6 个月 | | 开发者(constants、helpers、entity properties、custom integrations 使用的 platform APIs) | 12 个月 | 如果生态系统尚未跟上,deprecation 期限可以延长,但绝不会缩短。请使用 [calendar version format](/developers/versioning.md) 格式,将移除发生的 release 声明为 `breaks_in_ha_version`。 在旧行为仍然有效时,使用 `IssueSeverity.WARNING`;只有当它已停止工作(因为 integration 已被移除或 migration 失败,用户的 configuration 已不再生效)时,才使用 `IssueSeverity.ERROR`。对于无法触发 repair issue 的 developer-facing features 移除,log levels 同样遵循这一划分。 ## 面向用户的 deprecations 每个需要用户介入的 deprecation 都会对应一个 [repair issue](/developers/core/platform/repairs.md)。当 integration 可以被多次设置时,应按 config entry 范围来设定 `issue_id`,否则 issues 会发生冲突。Deprecation 期限结束后,创建一个后续的 pull request,移除 repair issue 和旧行为。 在你自己的 domain 下注册的每个 issue,都需要在 integration 的 [`strings.json`](/developers/internationalization/core.md) 中有匹配的 `issues.` 条目。注册在 `HOMEASSISTANT_DOMAIN` 下的 issues(如 `deprecated_yaml`)会重用已经存在于 core 中的文本,本地无需额外定义。 ### 移除整个 integration 的 YAML 支持 要为整个 integration 移除 YAML 支持,请为 integration 添加一个 [config flow](/developers/core/integration/config_flow.md) 和一个 import flow,并使用 `integration_title` 和 `domain` placeholders 触发 core 的 `deprecated_yaml` repair issue。由于该 issue 文本存在于 `homeassistant` domain 中,请使用 `HOMEASSISTANT_DOMAIN` 注册,并将 `issue_domain` 设置为你的 domain。 ```python async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up the integration.""" if DOMAIN not in config: return True result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_IMPORT}, data=config[DOMAIN] ) if ( result.get("type") is FlowResultType.ABORT and (reason := result["reason"]) != "single_instance_allowed" ): async_create_import_error_issue(hass, reason) return True ir.async_create_issue( hass, HOMEASSISTANT_DOMAIN, f"deprecated_yaml_{DOMAIN}", breaks_in_ha_version="2027.1.0", is_fixable=False, issue_domain=DOMAIN, severity=ir.IssueSeverity.WARNING, translation_key="deprecated_yaml", translation_placeholders={"domain": DOMAIN, "integration_title": "Example"}, ) return True ``` 只有在 import 成功之后才触发 `deprecated_yaml` issue。如果在提前触发而 import 后来中止,用户会被告知他们的 configuration 已被导入,而实际上并没有。当 import 中止时,他们的 configuration 没有生效,因此应改用 `ERROR` severity 触发你自己的 issue。 一旦 deprecation 期限已过,YAML handling 本身也已移除,请将 `cv.config_entry_only_config_schema(DOMAIN)` 保留为 `CONFIG_SCHEMA`。它会在仍然有人在 `configuration.yaml` 中包含该 integration 时记录错误并触发 repair issue。 ### 弃用单个 YAML config keys 如果你只想弃用单个 YAML key 或一组 YAML keys(例如因为一次性弃用整个 YAML config 太复杂),我们会在读取 YAML 的 `async_setup` 中触发一个 repair issue,并且只在 key 实际存在时才触发。该 key 会一直工作到 deprecation 期限结束。 ```python async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up the integration.""" if CONF_IPV6 in config[DOMAIN]: ir.async_create_issue( hass, DOMAIN, "deprecated_ipv6", breaks_in_ha_version="2027.1.0", is_fixable=False, severity=ir.IssueSeverity.WARNING, translation_key="deprecated_ipv6", ) ... ``` 一旦期限结束,不要只是从 schema 中移除该 key。请在其位置保留 `cv.removed(CONF_IPV6)`,这样会告诉用户该 option 已消失,而不是用一条泛化的 validation 错误失败。 ### 操作 从 handler 中创建 repair issue: ```python async def render_image(call: ServiceCall) -> ServiceResponse: ir.async_create_issue( call.hass, DOMAIN, "deprecated_generate_image", breaks_in_ha_version="2026.9.0", is_fixable=False, severity=ir.IssueSeverity.WARNING, translation_key="deprecated_generate_image", ) ``` 弃用 action 的单个参数处理方式相同,但只有在参数实际被传递时才触发 issue。 ### Entities 和 attributes 当一个 attribute 变成它自己的 entity、一个 entity 被另一个 platform 上的 entity 替换,或一个 entity 被完全移除时,(请先创建新 entity)在 deprecation 期间保持旧的继续工作。 对每一个仍然存在且启用的已弃用 entity 都触发 issue。使用 `automations_with_entity()` 和 `scripts_with_entity()` 让消息更具体,并警告用户特定的 automations 或 scripts 将被破坏。[禁用 entity](https://www.home-assistant.io/common-tasks/general/#enabling-or-disabling-entities) 是用户确认 deprecation 的方式。一旦它被禁用且没有任何引用,就移除 registry entry,使其不会被重新创建。该 issue 本身不是持久的,因此重启后会自动消失。 ```python def async_deprecate_entity( hass: HomeAssistant, entity_registry: er.EntityRegistry, description: ExampleSwitchEntityDescription, ) -> bool: """Return whether the deprecated entity should still be created.""" entity_id = entity_registry.async_get_entity_id( Platform.SWITCH, DOMAIN, description.unique_id ) if entity_id is None: return False items = automations_with_entity(hass, entity_id) + scripts_with_entity(hass, entity_id) if entity_registry.async_get(entity_id).disabled and not items: entity_registry.async_remove(entity_id) return False ir.async_create_issue( hass, DOMAIN, f"deprecated_entity_{entity_id}", breaks_in_ha_version="2027.2.0", is_fixable=False, severity=ir.IssueSeverity.WARNING, translation_key="deprecated_entity_used" if items else "deprecated_entity", translation_placeholders={ "entity_id": entity_id, "new_entity_id": description.replacement_entity_id, } | ({"items": "\n".join(items)} if items else {}), ) return True ``` 在 platform 的 `async_setup_entry` 中调用它,此处 entities 被构建,其返回值决定哪些会被添加: ```python async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the switch platform.""" entity_registry = er.async_get(hass) entities = [ExampleSwitch(coordinator, description) for description in SWITCHES] entities.extend( ExampleSwitch(coordinator, description) for description in DEPRECATED_SWITCHES if async_deprecate_entity(hass, entity_registry, description) ) async_add_entities(entities) ``` 对一个尚不存在的 entity 返回 `False` 意味着,只有已经拥有该 entity 的用户才会重新创建它,因此新用户永远不会得到它。 消息必须点明该 entity 可能被使用的每一个位置,不仅仅是 automations 和 scripts,还要告诉用户禁用它才是移除它的方式: ```json "deprecated_entity": { "title": "Deprecated switch detected", "description": "The switch `{entity_id}` is deprecated because it has been replaced with `{new_entity_id}`.\n\nUpdate your dashboards, templates, automations and scripts to use the replacement entity, then disable the deprecated switch and restart Home Assistant." }, "deprecated_entity_used": { "title": "[%key:component::example::issues::deprecated_entity::title%]", "description": "The switch `{entity_id}` is deprecated because it has been replaced with `{new_entity_id}`.\n\nThe switch was used in the following automations or scripts:\n{items}\n\nUpdate the above, along with any dashboards and templates that use it, to use the replacement entity, then disable the deprecated switch and restart Home Assistant." } ``` ### 移除一个 integration 当一个 integration 完全停止工作且没有更新计划时,应该将其移除,同时触发一个 repair,让用户知道发生了什么。这是通过将其精简为一个会触发 `ERROR` issue 的 stub 来实现,同时保留一个最基础的 `config_flow.py`,以便现有的 entries 仍然可以加载。既定的 translation key 是 `integration_removed`,应在 `strings.json` 中添加并说明移除原因: ```python async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up the integration from a config entry.""" ir.async_create_issue( hass, DOMAIN, DOMAIN, is_fixable=False, severity=ir.IssueSeverity.ERROR, translation_key="integration_removed", translation_placeholders={ "entries": f"/config/integrations/integration/{DOMAIN}", }, ) return True ``` `entries` placeholder 是一个指向用户现有 config entries 的链接: ```json "integration_removed": { "title": "The Example integration has been removed", "description": "The Example integration has been removed from Home Assistant, as the vendor shut down the API it relied on.\n\nTo resolve this issue, remove the (now defunct) integration entries from your Home Assistant setup. [Click here to see your existing Example integration entries]({entries})." } ``` 在 `async_unload_entry` 中再次删除该 issue,但只有在该 domain 的最后一条 config entry 卸载之后才删除。 当 integration 是被后继者替代而不是消失时,应改用 `WARNING` 加 `breaks_in_ha_version`,并以 `deprecated` 原因中止 config flow,以便不会创建新的 entries。 ### 文档和测试 Deprecation 通过 repair issue 和 release notes 公告。不要在 [home-assistant.io](/developers/documenting/standards.md) 上留下 deprecation 通知,因为该文档只描述当前有效的内容。 使用 `issue_registry` fixture 测试该 issue 是否被创建,以及在最后一条 config entry 卸载后是否被再次删除。 ## 面向开发者的 deprecations 其他 integrations 导入或子类化的任何东西都算作 core API,无论它位于 `homeassistant/helpers/`、`homeassistant/const.py`,还是像 `homeassistant/components/sensor/` 这样的 entity platform 中。弃用其中之一会影响 custom integration 作者,他们需要一个自己的 release cycle 来应对。这些有 12 个月的时间,并且会在本网站的 [blog](/developers/blog.md) 上发布公告,说明替换方案(如有)和移除版本。 这些机制会将警告记录到被指责的 integration。它们 **不会** 创建 repair issue,因为用户无法修复 custom integration 的代码。 ### Constants、aliases 和 enum members 以 `_DEPRECATED_` 为前缀的名称注册替换项,并安装三个 module hooks,这样读取旧名称时只警告一次: ```python from functools import partial from homeassistant.helpers.deprecation import ( DeprecatedConstantEnum, all_with_deprecated_constants, check_if_deprecated_constant, dir_with_deprecated_constants, ) _DEPRECATED_CONCENTRATION_GRAMS_PER_CUBIC_METER = DeprecatedConstantEnum( UnitOfDensity.GRAMS_PER_CUBIC_METER, "2027.8" ) # These can be removed if no deprecated constants are in this module anymore __getattr__ = partial(check_if_deprecated_constant, module_globals=globals()) __dir__ = partial(dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]) __all__ = all_with_deprecated_constants(globals()) ``` 对于普通值使用 `DeprecatedConstant`,对于 enum member 使用 `DeprecatedConstantEnum`,当类或函数移动时使用 `DeprecatedAlias`。要弃用你要保留的 enum 中的单个 member,请改用 `EnumWithDeprecatedMembers` metaclass: ```python class MediaPlayerState( StrEnum, metaclass=EnumWithDeprecatedMembers, deprecated={ "STANDBY": ("MediaPlayerState.OFF or MediaPlayerState.IDLE", "2026.8.0"), }, ): """State of media player entities.""" OFF = "off" IDLE = "idle" STANDBY = "standby" ``` :::note Deprecated constants 只有在调用方可以被归因于某个 integration 时才会警告。来自 core 代码或测试的访问是静默的,这就是为什么下面的测试 helpers 会通过一个 custom integration 来访问该 constant。 ::: ### Functions、methods 和 classes ```python @deprecated_function( "homeassistant.helpers.sun.get_astral_observer", breaks_in_ha_version="2027.7", ) @callback def get_astral_location(hass: HomeAssistant) -> tuple[Location, Elevation]: ``` `@deprecated_class` 会在实例化时警告,是保留已重命名 class 作为 alias 的工具。两者都以字符串形式接受替换项。要弃用一个你不再需要的 leading `hass` 参数,请使用 `@deprecated_hass_argument`,它会警告并剥离该参数。 ### 使用模式 当问题不是一个符号,而是一种模式时,例如设置一个你想要移除的 property,或调用一个 platform 现在已经替代的 registration function,请使用 `report_usage()`。它能区分 core 代码和 integrations,这样 core 内部的错误会大声失败,而 integrations 只会收到警告: ```python report_usage( "calls system_health.async_register_info, which is deprecated; " "add a system_health platform instead", breaks_in_ha_version="2027.1", core_behavior=ReportBehavior.ERROR, exclude_integrations={DOMAIN}, ) ``` 第一个参数 `what` 会被插入到 `Detected that integration 'domain' {what}` 中,因此请将它写为动词短语。 `report_usage()` 在 core 中运行,因此它通过遍历调用栈来识别负责的 integration。当 integration 自己调用了已弃用的 function 时这有效。当 core 只是读取 integration 之前设置的内容(如已弃用的 entity property)时无效,因为那时 integration 已经不在栈上了。这种情况下请传入 `integration_domain`,从一个知道自身来源的 object 中获取,例如 entity 上的 `self.platform.platform_name`。 谁会收到什么由三个独立参数控制,每个都接受一个 `ReportBehavior`,可以是 `IGNORE`(什么都不说)、`LOG`(在 `level` 级别记录,每个 caller 一次)或 `ERROR`(记录并抛出 `RuntimeError`): | Parameter | Applies to | Default | | --- | --- | --- | | `core_behavior` | `homeassistant/` 中栈上没有 integration 的代码 | `ERROR` | | `core_integration_behavior` | 一个 built-in integration | `LOG` | | `custom_integration_behavior` | 一个 custom integration | `LOG` | 这些默认值通常是想要的:core 代码在测试中大声失败,而 integrations 只收到警告。在仍在迁移 built-in integrations 时,可以将 `core_integration_behavior` 降为 `IGNORE`,这样警告才能触达 custom integration 作者,而不会被你已经在修复的 offenders 刷屏。 ### 测试 `tests/common.py` 为 symbols 提供了 `import_and_test_deprecated_constant`、`import_and_test_deprecated_constant_enum`、`import_and_test_deprecated_alias` 和 `help_test_all`。`mock_integration_frame` fixture 覆盖 `report_usage` 警告。 --- url: /developers/dev_101_config.md --- 在 [`hass` 对象](/developers/dev_101_hass.md) 上存在一个 `Config` 类的实例。`Config` 类包含了用户首选的单位、config 目录路径以及加载了哪些 components。 | Name | Type | Description | | ---- | ---- | ----------- | | latitude | float | 实例位置的纬度 | | longitude | float | 实例位置的经度 | | elevation | int | 实例的海拔 | | location\_name | str | 实例名称 | | time\_zone | str | 时区 | | units | UnitSystem | 单位系统 | | internal\_url | str | 可在内部访问实例的 URL | | external\_url | str | 可在外部访问实例的 URL | | currency | str | 首选货币 | | country | str | 实例所在的国家 | | language | str | 首选语言 | | config\_source | ConfigSource | 配置是通过 UI 设置还是存储在 YAML 中 | | skip\_pip | bool | 如果为 `True`,启动时会跳过对 requirements 的 pip install | | skip\_pip\_packages | list\[str] | 启动时安装 requirements 时要跳过的包列表 | | components | set\[str] | 已加载的 components 列表 | | api | ApiConfig | API (HTTP) 服务器配置 | | config\_dir | str | 存放配置的目录 | | allowlist\_external\_dirs | set\[str] | 允许访问的外部目录列表 | | allowlist\_external\_urls | set\[str] | 允许 integrations 使用的外部 URL 列表 | | media\_dirs | dict\[str, str] | integrations 可使用的媒体文件夹字典 | | safe\_mode | bool | Home Assistant 是否正在以 safe mode 运行 | | legacy\_templates | bool | 使用旧的模板行为 | 它还提供了若干 helper 方法。 --- url: /developers/dev_101_events.md --- Home Assistant 的核心由事件驱动。这意味着,如果你想对某件事做出响应,就必须对事件做出响应。大多数情况下你不会直接与 event system 交互,而是使用其中一个 [event listener helpers][helpers]。 Event system 非常灵活。对 event type 没有限制,只要它是一个字符串。每个 event 都可以包含 data。该 data 是一个字典,可以包含任何数据,只要它是 JSON 可序列化的。这意味着你可以使用数字、字符串、字典和列表。 [Home Assistant 发出的事件列表。][object] ## 发出事件(Firing events) 要发出事件,你需要与 event bus 交互。Event bus 在 Home Assistant 实例上以 `hass.bus` 的形式提供。请注意 [Data Science portal](https://data.home-assistant.io/docs/events/#database-table) 上记录的 data 结构。 以下是一个 component 示例,加载时会发出事件。注意自定义 event 名称以前缀 component 名称开头。 ```python from homeassistant.core import HomeAssistant from homeassistant.helpers.typing import ConfigType DOMAIN = "example_component" def setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up is called when Home Assistant is loading our component.""" # Fire event example_component_my_cool_event with event data answer=42 hass.bus.fire("example_component_my_cool_event", {"answer": 42}) # Return successful setup return True ``` ## 监听事件(Listening to events) 大多数情况下你不会发出事件,而是监听事件。例如,实体的 state 变更会以事件形式广播。 ```python from homeassistant.core import Event, HomeAssistant from homeassistant.helpers.typing import ConfigType DOMAIN = "example_component" def setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up is called when Home Assistant is loading our component.""" count = 0 # Listener to handle fired events def handle_event(event: Event) -> None: nonlocal count count += 1 print(f"Answer {count} is: {event.data.get('answer')}") # Listen for when example_component_my_cool_event is fired hass.bus.listen("example_component_my_cool_event", handle_event) # Return successful setup return True ``` ### 辅助函数 Home Assistant 附带了许多 bundled helpers 来监听特定类型的事件。有用于跟踪某个时间点的 helper,用于跟踪时间间隔的 helper,跟踪 state 变更的 helper,以及跟踪日落的 helper。[查看可用的 methods。][helpers] [helpers]: https://developers.home-assistant.io/docs/integration_listen_events#available-event-helpers [object]: https://www.home-assistant.io/docs/configuration/events/ --- url: /developers/dev_101_hass.md --- 在开发 Home Assistant 时,你会看到一个无处不在的变量:`hass`。这是 Home Assistant 的实例,通过它可以访问系统的各个部分。 ### The `hass` object Home Assistant 实例包含四个对象,帮助你与系统进行交互。 | Object | Description | | ------ | ----------- | | `hass` | 这是 Home Assistant 的实例。允许启动、停止以及排队新任务(jobs)。 | | `hass.config` | 这是 Home Assistant 的核心配置,暴露位置、温度偏好和 config 目录路径。 | | `hass.states` | 这是 StateMachine。允许你设置 state 并跟踪它们的变更。[了解更多。](https://developers.home-assistant.io/docs/dev_101_states) | | `hass.bus` | 这是 EventBus。允许你触发事件和监听事件。[了解更多。](https://developers.home-assistant.io/docs/dev_101_events) | | `hass.services` | 这是 ServiceRegistry。允许你注册 service actions。[了解更多。](https://developers.home-assistant.io/docs/dev_101_services) | Home Assistant 核心架构概览 ### Where to find `hass` 根据你编写的内容不同,`hass` 对象的提供方式也有所不同。 **Component** 通过 `setup(hass, config)` 或 `async_setup(hass, config)` 传入。 **Platform** 通过 `setup_platform(hass, config, add_entities, discovery_info=None)` 或 `async_setup_platform(hass, config, async_add_entities, discovery_info=None)` 传入。 **Entity** 在 platform 内部通过 `add_entities` 回调添加 entity 后,可作为 `self.hass` 使用。 --- url: /developers/dev_101_services.md --- Home Assistant 提供了许多现成的 actions,但并非总能覆盖一切。与其试图更改 Home Assistant,更好的做法是先将其作为 service action 添加到你自己的 integration 下。一旦我们在这些 service actions 中看到某种模式,再讨论如何将其通用化。 \[Service actions 应始终注册](/docs/core/integration-quality-scale/rules/action-setup),以确保引用它们的 automations 可以被编辑和验证,并且即使 integration 没有加载的 config entries,在调用 service 时也能给出说明性的错误信息。请在 integration 的 `async_setup` 或 `setup` 函数中注册 services,而不是在 integration 的 `async_setup_entry` 或 platform 的 `async_setup_entry`、`async_setup_platform`、`setup_platform` 中注册。 这是一个简单的 "hello world" 示例,用于展示注册 service action 的基本方法。要使用此示例,创建文件 `/custom_components/hello_action/__init__.py` 并复制下面的示例代码。 Actions 可以从 automations 调用,也可以从前端的 **Tools** 中的 **Actions** 标签页调用。 ```python from homeassistant.core import HomeAssistant, ServiceCall, callback from homeassistant.helpers.typing import ConfigType DOMAIN = "hello_action" ATTR_NAME = "name" DEFAULT_NAME = "World" async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up is called when Home Assistant is loading our component.""" @callback def handle_hello(call: ServiceCall) -> None: """Handle the service action call.""" name = call.data.get(ATTR_NAME, DEFAULT_NAME) hass.states.async_set("hello_action.hello", name) hass.services.async_register(DOMAIN, "hello", handle_hello) # Return boolean to indicate that initialization was successful. return True ``` 要在 Home Assistant 中加载该 integration,需要创建一个 `manifest.json`,并在 `configuration.yaml` 中添加一个条目。当 component 加载后,应该会出现一个可调用 service。 ```yaml # configuration.yaml entry hello_action: ``` `manifest.json` 示例: ```json { "domain": "hello_action", "name": "Hello Action", "documentation": "https://developers.home-assistant.io/docs/dev_101_services", "iot_class": "local_push", "version": "0.1.0" } ``` 打开前端,在侧边栏中点击 developer tool 区域中的第一个图标。这会打开 Actions developer tool。在右侧找到你的 action 并点击它,会自动填入正确的值。 现在按下 "Perform action" 将以不带任何参数的方式调用你的 service action。这会让你的 service action 创建一个名为 'World' 的默认 state。如果你想指定名称,需要通过 service action Data 提供参数。在 YAML 模式下,添加以下内容,然后再次按下 "Perform Service"。 ```yaml service: hello_action.hello data: name: Planet ``` Service action 现在会用 "Planet" 覆盖之前的 state。 ## Service action 描述 添加 actions 只有在用户知道它们时才有用。在 Home Assistant 中,我们通过将 `services.yaml` 作为 integration 的一部分来描述 service actions。 Actions 发布在 integration 的 domain 名称下,因此在 `services.yaml` 中我们只使用 service action 名称作为 base key。 ### Service action description 示例 ```yaml # Example services.yaml entry # Service ID set_speed: # If the service action accepts entity IDs, target allows the user to specify # entities by entity, device, or area. If `target` is specified, `entity_id` # should not be defined in the `fields` map. By default it shows only targets # matching entities from the same domain as the action, but if further # customization is required, target supports the entity, device, and area # selectors (https://www.home-assistant.io/docs/blueprint/selectors/). # Entity selector parameters will automatically be applied to device and area, # and device selector parameters will automatically be applied to area. target: entity: domain: fan # If not all entities from the action's domain support an action, entities # can be further filtered by the `supported_features` state attribute. An # entity will only be possible to select if it supports at least one of the # listed supported features. supported_features: - fan.FanEntityFeature.SET_SPEED # If a service action requires more than one supported feature, the item # should be given as a list of required supported features. For example, # if the service action requires both SET_SPEED and OSCILLATE it would # be expressed like this - - fan.FanEntityFeature.SET_SPEED - fan.FanEntityFeature.OSCILLATE # Different fields that your service action accepts fields: # Key of the field speed: # Whether or not field is required (default = false) required: true # Example value that can be passed for this field example: "low" # The default field value default: "high" # Selector (https://www.home-assistant.io/docs/blueprint/selectors/) to control # the input UI for this field selector: select: translation_key: "fan_speed" options: - "off" - "low" - "medium" - "high" # Fields can be grouped in collapsible sections, this is useful to initially hide # less commonly used fields and to group related fields. Note that the collapsible section # only affect presentation to the user, service action data will not be nested. additional_fields: # Whether or not the section is initially collapsed (default = false) collapsed: true # Input fields in this section fields: speed_pct: selector: number: min: 0 max: 100 ``` :::info Service actions 的名称和描述在我们的 [translations](/developers/internationalization/core.md) 中设置,而不是在 service action description 中。每个 service action 和 service action field 都必须有对应的 translation 定义。Description placeholders 允许你排除 URL 等元素而不翻译。 ```python ... hass.services.async_register( DOMAIN, "hello", handle_hello, description_placeholders={"docs_url": "https://example.com/hello_world"}, ) ... ``` ::: ### Service action fields 的分组 输入字段可以在 sections 中按视觉进行分组。将输入字段按 section 分组只影响向用户展示输入方式,不影响 service action data 的结构。 在 [service action description 示例](#service-action-description-example) 中,`speed_pct` 输入字段位于一个默认折叠的 section `additional_fields` 内。 示例中该 service 的 service action data 是 `{"speed_pct": 50}`,而不是 `{"additional_fields": {"speed_pct": 50}}`。 ### Service action fields 的过滤 在某些情况下,action 的 domain 中的实体可能不支持所有 service action fields。 通过为 field description 提供 `filter`,只有当至少有一个选中的实体按照配置的 filter 支持该字段时,该字段才会显示。 filter 必须指定 `supported_features` 或 `attribute` 其中之一,不能同时使用两者。 `supported_features` filter 通过一个 supported features 列表来指定。只有当至少一个选中的实体支持所列特征之一时,字段才会显示。 `attribute` filter 将一个 attribute 与一个 values 列表组合起来。只有当至少一个选中的实体的 attribute 被设置为所列的 attribute states 之一时,字段才会显示。如果 attribute state 是一个列表,只有当选中的实体的 attribute state 中至少有一个项被设置为所列的 attribute states 之一时,字段才会显示。 以下是一个字段的局部示例,只有当至少一个选中的实体支持 `ClimateEntityFeature.TARGET_TEMPERATURE` 时才会显示该字段: ```yaml fields: temperature: name: Temperature description: New target temperature for HVAC. filter: supported_features: - climate.ClimateEntityFeature.TARGET_TEMPERATURE ``` 以下是一个字段的局部示例,只有当至少一个选中的实体的 `supported_color_modes` attribute 包含 `light.ColorMode.COLOR_TEMP` 或 `light.ColorMode.HS` 时才会显示该字段: ```yaml color_temp: name: Color temperature description: Color temperature for the light in mireds. filter: attribute: supported_color_modes: - light.ColorMode.COLOR_TEMP - light.ColorMode.HS ``` ## 图标 Actions 也可以有 icons。这些 icons 在 Home Assistant UI 中显示 service action 的地方使用,比如在 automation 和 script 编辑器中。 每个 service action 要使用的 icon 可以在 integration 文件夹的 `icons.json` translation 文件中定义,位于 `services` key 下。key 应该是 service action 名称,value 应该是要使用的 icon。 以下示例展示如何为 integration 的 `turn_on` 和 `turn_off` service actions 提供 icons: ```json { "services": { "turn_on": {"service": "mdi:lightbulb-on"}, "turn_off": {"service": "mdi:lightbulb-off"} } } ``` 此外,也可以为 collapsible sections 选择性地指定 icon。 以下示例展示如何为 `additional_options` section 提供 icon: ```json { "services": { "start_brewing": { "service": "mdi:flask", "sections": { "additional_options": "mdi:test-tube" } } } } ``` ## 为 service actions 选择合适的 target 注册 service action 时,应将其指向 [data hierarchy](/developers/architecture/devices-and-services.md#entity-data-hierarchy) 中该 action 真正需要运行的层级。不要指向比所需层级更高或更低的层级,即使这些层级可以互相解析。 * **Entity level** — 如果 service action 是对某个特定实体进行操作或需要某个特定实体才能工作,请使用 `entity_id` 作为 target。例如控制一个 light。将这些注册为 [entity service actions](#entity-service-actions)。 * **Device level** — 如果 service action 是对整个设备进行操作,并且需要一个 device entry(而不是某个特定实体)才能工作,请使用 `device_id` 字段作为 target。即使可以将实体解析为其父级设备,也不要使用 `entity_id` 作为替代。例如,重启设备这样的 action 是针对设备本身的,而不是它暴露的任何特定实体,因此应该以设备为 target。 * **Config entry level** — 如果 service action 是对 integration 实例进行操作,并且需要一个 config entry 才能工作,请使用 `config_entry_id` 作为 target。即使可以将它们解析回 config entry,也不要使用 `device_id` 或 `entity_id` 作为替代。例如,在外部 API 中创建一个新资源的 action,该资源对整个 account 或 connection 通用,应该以代表该 account 或 connection 的 config entry 为 target,而不是以它下面的 device 或 entity 为 target。 :::tip 指导原则是:**将 target 指向 action 真正操作的对象**。如果 action 需要 device,就以 device 为 target。如果需要 config entry,就以 config entry 为 target。从较低层级进行解析(例如从 entity 查找 config entry)会引入不必要的间接关系,使 action 接口与 integration 中 data hierarchy 的假设耦合,也会让用户更难理解 action 操作的对象。 ::: :::caution 当 service action 需要一个 target 时,该 target 不应是可选的。不要在没有指定 target 时实现一个默认 target。 将 target 设为可选看起来很方便,但当配置因添加 entities 或 entries 而发生变化时,会让 automations 和 scripts 变得不可预测。要求明确的 target 可以让 action 调用在任何用户当前配置下都保持可预测。 ::: ## 实体 service actions 有时你想提供额外的 actions 来控制你的 entities。例如,Sonos integration 提供了用于将 devices 分组和取消分组的 action。Entity service actions 的特殊之处在于用户有多种指定 entities 的方式。它可以是 areas、一个 group 或一个 entities 列表。 使用 `homeassistant.helpers.service.async_register_platform_entity_service` 注册 entity service actions。请在 integration domain 下注册 actions,例如 `sonos`,而不是在 platform domain 下注册,例如 `media_player`。如果 entity service action 有 fields,你可以将一个 schema 传递给 `async_register_platform_entity_service`。该 schema 可以是: * 一个字典,会被自动传递给 `cv._make_entity_service_schema` * `cv._make_entity_service_schema` 返回的 validator * `cv._make_entity_service_schema` 返回的 validator,被包裹在一个 `vol.Schema` 中 * `cv._make_entity_service_schema` 返回的 validator,被包裹在一个 `vol.All` 中 添加到 `homeassistant/components/sonos/__init__.py` 的示例代码: ```python from homeassistant.components.media_player import DOMAIN as MEDIA_PLAYER_DOMAIN from homeassistant.core import HomeAssistant from homeassistant.helpers.typing import ConfigType from homeassistant.helpers import config_validation as cv, service import voluptuous as vol DOMAIN = "sonos" SERVICE_SET_TIMER = "set_sleep_timer" async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up the Sonos integration.""" # This will call each targeted entity's `set_sleep_timer` method with `sleep_time=VALUE` service.async_register_platform_entity_service( hass, DOMAIN, SERVICE_SET_TIMER, entity_domain=MEDIA_PLAYER_DOMAIN, schema={vol.Required("sleep_time"): cv.time_period}, func="set_sleep_timer", ) return True ``` 如果你需要对 service action 调用进行更精细的控制,也可以传递一个 async function,该 function 会被调用以替代 `"set_sleep_timer"`: ```python async def custom_set_sleep_timer(entity, service_call): await entity.set_sleep_timer(service_call.data['sleep_time']) ``` ## 响应数据 Actions 可以使用 data 对 action 调用做出响应,以支撑更复杂的 automations。有以下额外的实现要求: * Response data 必须是一个 `dict`,并且可 JSON 序列化为 [`homeassistant.util.json.JsonObjectType`](https://github.com/home-assistant/core/blob/dev/homeassistant/util/json.py),以便与系统的其他部分(如 frontend)互操作。 * Errors 必须像任何其他 service action 调用一样作为 exceptions 抛出, 因为我们不希望终端用户在 scripts 和 automations 中进行复杂的错误处理。 Response data 中不应包含用于错误处理的错误码。 示例代码: ```python import datetime import voluptuous as vol from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, ServiceCall, ServiceResponse, SupportsResponse from homeassistant.helpers import config_validation as cv, entity_platform, service from homeassistant.util.json import JsonObjectType SEARCH_ITEMS_SERVICE_NAME = "search_items" SEARCH_ITEMS_SCHEMA = vol.Schema({ vol.Required("start"): datetime.datetime, vol.Required("end"): datetime.datetime, }) async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up the integration.""" async def search_items(call: ServiceCall) -> ServiceResponse: """Search in the date range and return the matching items.""" items = await my_client.search(call.data["start"], call.data["end"]) return { "items": [ { "summary": item["summary"], "description": item["description"], } for item in items ], } hass.services.async_register( DOMAIN, SEARCH_ITEMS_SERVICE_NAME, search_items, schema=SEARCH_ITEMS_SCHEMA, supports_response=SupportsResponse.ONLY, ) ``` Response data 的用途适用于那些不符合 Home Assistant state 的情况。例如,对象的响应流。相反,对于符合 entity state 的情况,不应使用 response data。例如,温度值应该只是一个 sensor。 ### 支持 response data Action 调用在注册时会带有一个 `SupportsResponse` 值,用于指示是否支持 response data。 | Value | Description | | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `OPTIONAL` | 执行一个 action,并可以选择性地返回 response data。Service action 应当根据 `ServiceCall` 属性 `return_response` 进行条件判断,以决定是否返回 response data,或返回 `None`。 | | `ONLY` | 不执行任何 actions,始终返回 response data。 | --- url: /developers/dev_101_states.md --- Home Assistant 通过 state machine 跟踪 entities 的 states。State machine 的要求非常少: * 每个 state 都与一个由 entity id 标识的 entity 相关联。这个 id 由 domain 和 object id 组成。例如 `light.kitchen_ceiling`。你可以任意组合 domain 和 object id,甚至可以覆盖现有的 states。 * 每个 state 都有一个主要属性,用于描述 entity 的 state。对于 light 来说,这可能是 "on" 和 "off"。你可以在 state 中存储任何你想要的内容,只要它是一个字符串(如果不是字符串,会被转换)。 * 你可以通过设置 attributes 来存储更多关于 entity 的信息。Attributes 是一个字典,可以包含你想要的任何数据。唯一的约束是它必须是 JSON 可序列化的,所以你只能使用数字、字符串、字典和列表。 [state 对象的描述。](https://www.home-assistant.io/docs/configuration/state_object/) ## 在 component 中使用 states 这是一个简单的教程/示例,介绍如何创建和设置 states。我们将在一个名为 "hello\_state" 的 component 中进行操作。这个 component 的目的是在 frontend 中显示给定的文本。 要开始,创建文件 `/custom_components/hello_state.py` 并复制下面的示例代码。 ```python """ Support for showing text in the frontend. For more details about this component, please refer to the documentation at https://developers.home-assistant.io/docs/dev_101_states """ import logging from homeassistant.core import HomeAssistant from homeassistant.helpers.typing import ConfigType _LOGGER = logging.getLogger(__name__) DOMAIN = "hello_state" def setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up the Hello State component.""" _LOGGER.info("The 'hello state' component is ready!") return True ``` 1. 在文件头部我们决定添加一些细节:一个简短的描述和指向文档的链接。 2. 我们需要做一些 logging。这意味着我们导入 Python logging 模块并创建一个别名。 3. Component 名称与 domain 名称相同。 4. `setup` 函数负责初始化我们的 component。 该 component 只写入一条 log message。请记住以后你有多个严重性级别可选: * `_LOGGER.info(msg)` * `_LOGGER.warning(msg)` * `_LOGGER.error(msg)` * `_LOGGER.critical(msg)` * `_LOGGER.exception(msg)` 5. 如果一切正常,我们返回 `True`。 将 component 添加到你的 `configuration.yaml` 文件。 ```yaml hello_state: ``` 在 Home Assistant 启动或重启后,该 component 会在 log 中创建一条记录。 ```log 16-03-12 14:16:42 INFO (MainThread) [custom_components.hello_state] The 'hello state' component is ready! ``` 下一步是引入 configuration options。用户可以通过 `configuration.yaml` 将 configuration options 传递给我们的 component。要使用它们,我们将使用传入 `setup` 方法的 `config` 变量。 ```python import logging from homeassistant.core import HomeAssistant from homeassistant.helpers.typing import ConfigType _LOGGER = logging.getLogger(__name__) DOMAIN = "hello_state" CONF_TEXT = "text" DEFAULT_TEXT = "No text!" def setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up the Hello State component. """ # Get the text from the configuration. Use DEFAULT_TEXT if no name is provided. text = config[DOMAIN].get(CONF_TEXT, DEFAULT_TEXT) # States are in the format DOMAIN.OBJECT_ID hass.states.set("hello_state.Hello_State", text) return True ``` 要使用我们 component 的最新特性,请更新 `configuration.yaml` 文件中的条目。 ```yaml hello_state: text: 'Hello, World!' ``` 得益于 `DEFAULT_TEXT` 变量,即使 `configuration.yaml` 文件中没有使用 `text:` 字段,该 component 也能正常启动。很多时候有些变量是必需的。重要的是检查所有必需的 configuration variables 是否都已提供。如果没有,setup 应该失败。我们将使用 `voluptuous` 作为 helper 来实现这一点。下面的列表展示了关键部分。 ```python import voluptuous as vol import homeassistant.helpers.config_validation as cv CONFIG_SCHEMA = vol.Schema( {DOMAIN: vol.Schema({vol.Required(CONF_TEXT): cv.string,})}, extra=vol.ALLOW_EXTRA ) ``` 现在,当 config 中缺少 `text:` 时,Home Assistant 会提醒用户,而不会 setup 你的 component。 在 Home Assistant 启动或重启后,如果 `configuration.yaml` 文件已更新,该 component 将在 frontend 中可见。

要为一个 platform 暴露 attributes,你需要在 entity 类上定义一个名为 `extra_state_attributes` 的 property,它会返回一个 attributes 字典: ```python @property def extra_state_attributes(self): """Return entity specific state attributes.""" return self._attributes ``` :::tip Entities 也有一个类似的 property `state_attributes`,integration 不应覆盖它。该 property 由 base entity components 使用,用于向 state 添加标准的一组 attributes。例如:light component 使用 `state_attributes` 向 state 字典中添加亮度。如果你在设计一个新的 integration,你应该改为定义 `extra_state_attributes`。 ::: 要让你的 integration 被包含在 Home Assistant 的 releases 中,请按照 [Submit your work](/developers/development_submitting.md) 部分描述的步骤操作。基本上你只需要将 integration 移动到你 fork 的 `homeassistant/component/` 目录,并创建一个 Pull Request。 --- url: /developers/development/labs.md --- Home Assistant Labs 提供了一种标准化的方式来发布预览功能,用户可以在其成为标准功能之前选择加入。本指南说明如何将新的预览功能添加到 Labs。 ## 什么是 Labs 预览功能? Labs 预览功能是已经过充分测试且功能完整的特性,其用户界面和设计理念正在通过真实使用场景和反馈进行打磨,之后才会成为 Home Assistant 的标准功能。这些功能的特点如下: * **可选**: 默认禁用,用户必须显式启用 * **充分测试**: 生产就绪的代码,而非实验性或不完整的实现 * **可能变更**: 根据反馈,可能存在 breaking changes、扩展新功能或被移除 * **可逆**: 随时可以禁用,无需重启 Labs 的目的在于打磨用户界面和设计理念,而不是测试 bug。这与 beta 测试不同,beta 测试评估的是即将发布的 Home Assistant 版本的稳定性。 ## 何时使用 Labs Labs 适用于以下场景: * 重大的 UI 变更或重新设计 * 重大的架构性变更 * 用户反馈将影响最终设计和实现的功能 Labs **不适用于**以下场景: * 应作为标准功能的配置选项(应改用 integration options 或 config flow) * 可以直接进入发布的微小变更 * 无法在运行时切换的功能 * 存在关键 bug 或本质上不完整的功能(这些应保持在开发阶段) ## 添加 Labs 预览功能 ### 1. 在 manifest.json 中定义功能 在集成的 `manifest.json` 中,将功能添加到 `preview_features` 部分: ```json { "domain": "my_integration", "name": "My Integration", "preview_features": { "my_preview_feature": { "feedback_url": "https://community.home-assistant.io/t/...", "learn_more_url": "https://www.home-assistant.io/integrations/my_integration", "report_issue_url": "https://github.com/home-assistant/core/issues/new?template=bug_report.yml" } } } ``` **字段说明:** * `feedback_url`: 指向社区论坛主题、反馈表单或讨论的链接,用于收集反馈 * `learn_more_url`: 指向有关该功能的文档的链接 * `report_issue_url`: 指向 GitHub issues 的链接,用于提交 bug 报告 所有字段都是可选的,但强烈建议提供,以便帮助用户反馈问题并报告 issue。 ### 2. 添加翻译 在集成的 `strings.json` 中添加翻译: ```json { "preview_features": { "my_preview_feature": { "name": "My preview feature", "description": "Enables the new preview feature that does X, Y, and Z.\n\nThis feature is stable but may change based on user feedback." } } } ``` 描述的编写指南: * 清楚地说明该功能的作用 * 保持简洁但富有信息量 * 提及该功能集是否可能在未来版本中扩展 * 可以使用 Markdown 格式(粗体、链接等) #### 自定义确认消息(可选) 可以自定义用户在启用或禁用功能时看到的确认消息。如果你的功能有特定行为或后果需要让用户了解,这会非常有用: ```json { "preview_features": { "my_preview_feature": { "name": "My preview feature", "description": "Enables the new preview feature that does X, Y, and Z.\n\n**Note:** Enabling this feature will migrate your configuration to a new format. The configuration will remain in the new format even if you disable the feature later.\n\nThis feature is stable but may change based on user feedback.", "enable_confirmation": "This will migrate your existing configuration to the new format. You can disable the feature later, but the configuration will remain migrated.", "disable_confirmation": "This will stop the new behavior, but your configuration will remain in the migrated format." } } } ``` **何时使用自定义确认消息:** * 你的功能会进行持久化更改(迁移、新实体等) * 用户需要了解特定的后果 * 该功能以不直观的方式与其他系统交互 * 希望明确用户对启用/禁用行为的预期 **指南:** * **在描述中包含重要后果**:用户应该能通过阅读描述来理解会发生什么,而不仅仅依靠确认消息 * 使用确认消息在用户执行操作的那一刻提醒他们关键点 * 明确说明启用/禁用时会发生什么 * 保持消息简洁但富有信息量 * 不要重复通用信息(用户已经能看到标准警告) ### 3. 实现功能 #### 后端功能 对于后端功能,在代码中检查 flag: ```python from homeassistant.components.labs import async_is_preview_feature_enabled from homeassistant.core import HomeAssistant async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up the integration.""" if async_is_preview_feature_enabled(hass, DOMAIN, "my_preview_feature"): # Enable preview functionality await setup_preview_feature(hass) # Standard setup continues return True ``` #### 前端功能 对于前端功能,在 TypeScript 中检查 flag: ```typescript import { fetchLabFeatures } from "../../../data/labs"; const features = await fetchLabFeatures(this.hass); const featureEnabled = features.find( (f) => f.domain === "my_integration" && f.preview_feature === "my_preview_feature" )?.enabled; if (featureEnabled) { // Load preview UI component } ``` #### 响应功能切换 使用 `async_subscribe_preview_feature()` 辅助函数来订阅功能切换事件。监听器会接收事件数据作为参数,并支持 async coroutine 函数: ```python from homeassistant.components.labs import ( EventLabsUpdatedData, async_subscribe_preview_feature, ) from homeassistant.core import HomeAssistant async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up the integration.""" async def _async_update_my_preview_feature( event_data: EventLabsUpdatedData, ) -> None: """Enable or disable the preview feature based on current state.""" if event_data["enabled"]: # Enable feature await async_enable_my_feature(hass) else: # Disable feature await async_disable_my_feature(hass) # Subscribe to changes for this specific feature entry.async_on_unload( async_subscribe_preview_feature( hass, DOMAIN, "my_preview_feature", _async_update_my_preview_feature, ) ) return True ``` `async_subscribe_preview_feature()` 辅助函数会自动过滤针对你的 domain 和 feature 的事件,并将事件数据(包括 `enabled` 状态)直接传递给监听器。 :::info 对于更复杂的场景或多个预览功能,仍然可以直接使用较低层级的 `EVENT_LABS_UPDATED` 事件。`async_subscribe_preview_feature()` 辅助函数适用于大多数用例,因为它减少了样板代码并提高了代码可读性。 ::: ### 4. 需要运行时激活 **关键要求**:所有 Labs 预览功能必须在运行时激活和停用,而不能要求重启 Home Assistant。 好的模式: * 动态加载/卸载 UI 组件 * 在功能切换时创建/删除实体 * 启用/禁用后台任务 * 注册/注销事件监听器 不好的模式: * 更改核心 bootstrap 行为 * 修改仅在启动时加载的集成 * 从根本上改变系统初始化过程的功能 * 要求更改 `configuration.yaml` ### 5. 创建反馈渠道 在发布功能之前,创建合适的反馈渠道: 1. **社区论坛**:在 "Beta" 或 "Feature Requests" 类别中创建主题 2. **GitHub**:可选地创建 discussion 或指定一个 issue 用于收集反馈 3. 在你的功能定义的 `feedback_url` 中链接这些渠道 选择最适合需求的渠道。社区论坛主题适合开放讨论,而 GitHub 更适合技术反馈和 issue 跟踪。 ### 6. 更新生成文件 修改 `manifest.json` 后,运行: ```bash python -m script.hassfest ``` 这将使用你的功能更新 `homeassistant/generated/labs.py`。 ### 7. 编写功能文档 添加关于预览功能的文档: * 更新集成的文档页面,提及该 Labs 功能 * 说明正在预览的内容以及正在寻求哪些反馈 * 提供启用它的清晰说明 ### 8. 创建 My Home Assistant 链接(可选) 可以创建 My Home Assistant 链接,直接导航到 Labs 中的功能。这对于以下场景尤其有用: * 宣布新预览功能的 release notes * 带有明确行动号召的文档 * 希望用户轻松测试功能的社区讨论 链接格式为: ```text https://my.home-assistant.io/redirect/labs/?domain=&preview_feature= ``` 例如: ```text https://my.home-assistant.io/redirect/labs/?domain=kitchen_sink&preview_feature=special_repair ``` 当用户点击此链接时: 1. 他们会被重定向到 Home Assistant 实例中的 Labs 面板 2. 页面会自动滚动到你的特定功能 3. 功能卡片会高亮显示 3 秒以吸引注意力 可以在以下位置使用这些链接: * Release notes: "通过访问 Labs 面板来试用新功能" * 文档: 包含一个 My 链接按钮,让用户可以轻松启用该功能 * 社区论坛帖子: 引导用户测试特定功能 **Markdown 示例:** ```markdown To try this new preview feature, visit {% my labs domain="kitchen_sink" preview_feature="special_repair" title="Labs" %} and enable the "Special repair" feature. ``` ## 完整示例:Kitchen Sink special repair 参见 Kitchen Sink 集成获取完整的工作示例: `manifest.json`: ```json { "domain": "kitchen_sink", "preview_features": { "special_repair": { "feedback_url": "https://community.home-assistant.io", "learn_more_url": "https://www.home-assistant.io/integrations/kitchen_sink", "report_issue_url": "https://github.com/home-assistant/core/issues/new" } } } ``` `strings.json`: ```json { "preview_features": { "special_repair": { "name": "Special repair", "description": "Creates a **special repair issue** when enabled.\n\nThis demonstrates how lab features can interact with other Home Assistant integrations.", "enable_confirmation": "This will create a special repair issue to demonstrate how preview features can interact with the repairs system. The repair will be removed when you disable this feature.", "disable_confirmation": "This will remove the special repair issue that was created by this preview feature." } }, "issues": { "special_repair": { "title": "Special repair feature preview", "description": "This is a special repair created by a preview feature! This demonstrates how lab features can interact with the Home Assistant repair system. You can disable this by turning off the kitchen sink special repair feature in Settings > System > Labs." } } } ``` `__init__.py`: ```python from homeassistant.components.labs import ( EventLabsUpdatedData, async_is_preview_feature_enabled, async_subscribe_preview_feature, ) from homeassistant.core import HomeAssistant from homeassistant.helpers.issue_registry import ( IssueSeverity, async_create_issue, async_delete_issue, ) async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up the integration.""" async def _async_update_special_repair( event_data: EventLabsUpdatedData | None = None, ) -> None: """Create or delete the special repair issue. Creates a repair issue when the special_repair lab feature is enabled, and deletes it when disabled. This demonstrates how lab features can interact with Home Assistant's repair system. """ enabled = ( event_data["enabled"] if event_data is not None else async_is_preview_feature_enabled(hass, DOMAIN, "special_repair") ) if enabled: async_create_issue( hass, DOMAIN, "kitchen_sink_special_repair_issue", is_fixable=False, severity=IssueSeverity.WARNING, translation_key="special_repair", ) else: async_delete_issue(hass, DOMAIN, "kitchen_sink_special_repair_issue") # Subscribe to labs feature updates entry.async_on_unload( async_subscribe_preview_feature( hass, DOMAIN, "special_repair", _async_update_special_repair, ) ) # Check if lab feature is currently enabled and create repair if so await _async_update_special_repair() return True ``` ## 最佳实践 ### 功能设计 * 保持预览功能专注且易于测试 * 提供清晰的启用/禁用行为 * 出现问题时优雅地失败 * 适当记录日志(对非关键信息使用 debug 级别) * 使功能完全可逆 ### 处理变更 虽然 Labs 功能可以有 breaking changes: * **尽可能避免 breaking changes**:即使是预览阶段,也应尽量保持兼容性 * **在可行的情况下提供自动迁移**:当 breaking changes 不可避免时,如果可行,自动迁移用户数据和设置 * **沟通变更**:更新功能描述并通过合适渠道通知用户 * **重视用户**:虽然是预览阶段,但用户在家中依赖这些功能 ### 代码组织 ```python # Good: Conditional logic is clear and separated if async_is_preview_feature_enabled(hass, DOMAIN, "my_feature"): await preview_setup(hass) else: await standard_setup(hass) # Bad: Mixing preview and stable code without clear separation await setup(hass, preview=async_is_preview_feature_enabled(hass, DOMAIN, "my_feature")) ``` ### 测试 同时测试启用和禁用状态: ```python async def test_feature_enabled(hass, hass_storage, mock_config_entry): """Test with feature enabled.""" # Enable the feature by pre-populating storage hass_storage["core.labs"] = { "version": 1, "data": { "preview_feature_status": [ {"domain": "my_integration", "preview_feature": "my_feature"}, ] }, } await hass.config_entries.async_setup(mock_config_entry.entry_id) # Test preview behavior async def test_feature_disabled(hass, mock_config_entry): """Test with feature disabled.""" # Feature disabled by default (no storage entry) await hass.config_entries.async_setup(mock_config_entry.entry_id) # Test standard behavior async def test_feature_toggle(hass, mock_config_entry, hass_ws_client): """Test toggling the feature on and off.""" await hass.config_entries.async_setup(mock_config_entry.entry_id) client = await hass_ws_client(hass) # Enable feature await client.send_json_auto_id({ "type": "labs/update", "domain": "my_integration", "preview_feature": "my_feature", "enabled": True, }) msg = await client.receive_json() assert msg["success"] # Verify feature behavior # ... # Disable feature await client.send_json_auto_id({ "type": "labs/update", "domain": "my_integration", "preview_feature": "my_feature", "enabled": False, }) msg = await client.receive_json() assert msg["success"] # Verify feature disabled # ... ``` ## 功能生命周期 ### 预览期间 * 定期监控反馈渠道 * 根据用户反馈迭代 * 按需更新功能(这是预览!) * 如果 breaking changes 能改进功能,则是可接受的,但应在可能的情况下避免 * 当 breaking changes 不可避免时,在可行的情况下为用户提供自动迁移 * 保持功能描述的准确性 * 及时响应 bug 报告 ### 毕业为标准功能 当功能准备成为标准功能时: 1. 从 `manifest.json` 中的 `preview_features` 移除该功能 2. 移除所有 `async_is_preview_feature_enabled()` 检查 3. 使功能始终处于活动状态 4. 运行 `python -m script.hassfest` 以更新生成文件 5. 更新文档以反映它已成为标准功能 6. 在 release notes 中宣布 ### 移除 如果功能最终不可行: 1. 从 `manifest.json` 中的 `preview_features` 移除该功能 2. 移除所有相关代码 3. 清理翻译 4. 运行 `python -m script.hassfest` 5. 在 release notes 中宣布移除并附上说明 ## 常见陷阱 ❌ **不要**将 Labs 用于永久性设置或配置选项 ❌ **不要**创建需要重启的功能 ❌ **不要**长期保留预览功能而不将其毕业或移除 ❌ **不要**将 Labs 用于存在关键 bug 或本质上不完整的功能 ❌ **不要**忘记记录你需要什么样的反馈 ✅ **应该**使功能在运行时完全可逆 ✅ **应该**提供清晰、简洁的描述 ✅ **应该**从一开始就规划毕业或移除 ✅ **应该**积极参与用户反馈 ✅ **应该**在添加到 Labs 之前确保功能已充分测试且生产就绪 ✅ **应该**在反馈基础上可能扩展功能集时进行说明 --- url: /developers/development_catching_up.md --- 如果你的功能开发耗时较长,并希望跟上当前 Home Assistant `dev` 分支的内容,可以使用 `git merge` 或 `git rebase`。下面提供了使用 `git merge` 的操作说明。这会在本地拉取最新的 Home Assistant 更改,并通过创建 merge commit 将它们合并到你的分支中。 你应该在 clone fork 之后添加一个额外的 `remote`。如果还没有添加,请在继续之前执行以下操作: ```shell git remote add upstream https://github.com/home-assistant/core.git ``` ```shell # Run this from your feature branch git fetch upstream dev # to fetch the latest changes into a local dev branch git merge upstream/dev # to put those changes into your feature branch before your changes ``` 如果 git 检测到冲突,请按以下步骤解决: 1. 使用 `git status` 查看有冲突的文件;编辑该文件,并解决 `<<<< | >>>>` 之间的行 2. 添加已修改的文件:`git add ` 或 `git add .` 3. 通过提交来结束合并(可以保持默认的 merge commit 消息不变):`git commit` 最后,像平常一样推送更改: ```shell # Run this from your feature branch git push ``` 如果该命令失败,说明自上次更新以来,该分支上有新工作被推送,来源可能是你或其他贡献者。在这种情况下,只需将它们拉取到本地分支,解决任何冲突,然后再次推送所有内容: ```shell # Run this from your feature branch git pull --no-rebase git push ``` 其他工作流在 [Github documentation](https://docs.github.com/get-started/quickstart/fork-a-repo) 中有详细说明。 --- url: /developers/development_checklist.md --- 在你提交任何更改之前,请对照以下要求检查工作成果: * 与外部设备或服务的所有通信都必须封装在一个托管于 [pypi](https://pypi.org/) 的外部 Python 库中。 * 该库必须提供 source distribution 包;不允许依赖只有 binary distribution 包的包。 * 与外部设备或服务通信的外部 Python 库必须启用 issue tracker。 * 如果该库主要用于 Home Assistant,且你是该集成的 code owner,鼓励使用带链接到 [Home Assistant Core Issues](https://github.com/home-assistant/core/issues) 的 issue template picker。例如:[zwave-js-server-python - New Issue](https://github.com/home-assistant-libs/zwave-js-server-python/issues/new/choose) * 新依赖项已添加到 `requirements_all.txt`(如适用),使用 `python3 -m script.gen_requirements_all` * 新 codeowners 已添加到 `CODEOWNERS`(如适用),使用 `python3 -m script.hassfest` * `.strict-typing` 文件已更新以包含你的代码(如果它提供了完全类型标注的源代码)。 * 代码已使用 Ruff 格式化(`ruff format`)。 * 任何删除或更改现有行为的内容都遵循[废弃流程](/developers/deprecating.md)。 * 已为 [home-assistant.io](https://home-assistant.io/) 开发文档 * 访问[网站文档](/developers/documenting.md)以获取更多有关为 [home-assistant.io](https://github.com/home-assistant/home-assistant.io) 做贡献的信息。 --- url: /developers/development_environment.md --- {/\* MDX 组件 \*/} import {useState} from 'react'; export const RepositoryOpener = () => { const \[value, setValue] = useState(""); const repoUrl = `vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=${encodeURIComponent(value)}`; return
\ setValue(ev.target.value)} style={{width: "80%", display: "inline-block", marginRight: 16}} /> \
} 如果你想为 Home Assistant 开发新功能或 component,需要设置一个开发环境。继续阅读以了解如何设置。 ## 使用 Visual Studio Code + devcontainer 进行开发 请按照我们的[devcontainer 开发环境](/developers/setup_devcontainer_environment.md)指南,先设置好合适的开发环境。 :::note 由于此方法使用容器,你可能会遇到在容器中暴露 USB 设备和适配器(板载蓝牙、Zigbee 等)进行测试的挑战。在 Linux 主机上进行开发时这是可能的;然而,如果你使用 Windows 或 MacOS 计算机进行开发,则无法直接访问此类硬件。 ::: **前提条件** * [Docker](https://docs.docker.com/get-docker/) * [Visual Studio code](https://code.visualstudio.com/) * [Git](https://git-scm.com/) **入门:** 1. 前往 [Home Assistant core 仓库](https://github.com/home-assistant/core) 并点击 **Fork**。 2. 复制你的 fork 的 URL 并粘贴到下方,然后点击 **Open**: 3. 浏览器会提示你是否使用 Visual Studio Code 打开该链接,点击 **Open Link**。 4. 当 Visual Studio Code 询问你是否要安装 Dev Containers 扩展时,点击 **Install**。 5. dev container 镜像将被构建(这可能需要几分钟),完成之后,你的开发环境就准备好了。 6. 你可以通过以下步骤验证 dev container 是否设置正确: 1. 在 Visual Studio Code 中打开命令面板: * Mac: `Shift`+`Command`+`P` * Windows/Linux: `Ctrl`+`Shift`+`P` 2. 选择 **Tasks: Run Task** -> **Run Home Assistant Core** 3. 终端应该会打开并开始输出活动。检查是否有错误,并等待输出停止或减缓。 4. 在浏览器中访问 `http://localhost:8123`,你应该能看到 Home Assistant 的设置屏幕。 将来,如果你想回到开发环境:打开 Visual Studio Code,点击侧边栏中的 **Remote Explorer** 按钮,在侧边栏顶部选择 **Containers**。 **故障排除** * 如果你的容器因为依赖项过时或先前构建的 devcontainer 而无法构建,它可能使用的是你仓库的过时 fork。请按照以下步骤操作: * 确保你的 GitHub fork 与主 Home Assistant core 仓库保持最新。 * 在终端中运行 `docker buildx prune` 清理本地 Docker 构建文件。 * 如果构建仍然失败: * 选择"Open configuration in recovery devcontainer." * 打开终端(如果尚未打开)。 * 运行 `git pull upstream dev` 并确保它应用了最新版本。 * 在 Visual Studio Code 中打开命令面板 - `Shift`+`Command`+`P`(Mac)/ `Ctrl`+`Shift`+`P`(Windows/Linux)。 * 选择"Dev Containers: Rebuild Container." ### 任务 dev container 附带了一些有用的任务,可帮助你进行开发。你可以通过 `Shift`+`Command`+`P`(Mac)/ `Ctrl`+`Shift`+`P`(Windows/Linux)打开命令面板,选择 **Tasks: Run Task**,然后选择要运行的任务来运行这些任务。 当某个任务正在运行时(例如文档的 `Preview`),可以通过打开命令面板并选择 **Tasks: Restart Running Task**,然后选择要重启的任务来重新启动它。 ### 使用 Visual Studio Code 进行调试 如果 dev container 设置正确,它默认就支持开箱即用的调试。它提供了必要的调试配置,因此按下 F5 应该会启动 Home Assistant。代码中设置的所有断点都应该被触发,调试器会停止。 也可以通过按照[此处](https://www.home-assistant.io/integrations/debugpy/)描述的过程,调试一个远程的 Home Assistant 实例(例如生产实例)。 ## 手动环境 *如果你不想使用 devcontainers,才需要这些说明。* 也可以设置一个更传统的开发环境。请在下方找到对应你操作系统的部分。确保你的 Python 版本是 3.14.2 或更高。 :::note 如果没有安装正确的 Python 版本就继续进行,你将得到一个与 Home Assistant 不兼容的虚拟环境。安装正确版本后,删除 `venv` 目录并继续设置,以使用正确版本重新创建它。 ::: ### 在 Ubuntu / Debian 上开发 安装核心依赖项。 ```shell sudo apt-get update sudo apt-get install python3-pip python3-dev python3-venv autoconf libssl-dev libxml2-dev libxslt1-dev libjpeg-dev libffi-dev libudev-dev zlib1g-dev pkg-config libavformat-dev libavcodec-dev libavdevice-dev libavutil-dev libswscale-dev libswresample-dev libavfilter-dev ffmpeg libgammu-dev build-essential ``` ### 在 Fedora 上开发 安装核心依赖项。 ```shell sudo dnf update sudo dnf install python3-pip python3-devel python3-virtualenv autoconf openssl-devel libxml2-devel libxslt-devel libjpeg-turbo-devel libffi-devel systemd-devel zlib-devel pkgconf-pkg-config libavformat-free-devel libavcodec-free-devel libavdevice-free-devel libavutil-free-devel libswscale-free-devel ffmpeg-free-devel libavfilter-free-devel ffmpeg-free gcc gcc-c++ cmake ``` ### 在 Arch / Manjaro 上开发 安装核心依赖项。 ```shell sudo pacman -Sy base-devel python python-pip python-virtualenv autoconf libxml2 libxslt libjpeg-turbo libffi systemd zlib pkgconf ffmpeg gcc cmake ``` ### 在 NixOS 上开发 将下面的内容保存为 `default.nix` 并放入你检出的仓库中,然后使用例如 [direnv](https://direenv.net/) 来激活它。 ```nix let pkgs = import { }; in pkgs.mkShell { packages = with pkgs; [ autoconf clang cmake ffmpeg ffmpeg.dev gammu libffi.dev libjpeg.dev libxml2.dev libxslt.dev openssl_3.dev pkg-config python314 zlib.dev ]; env = { LD_LIBRARY_PATH = "${pkgs.libjpeg.out}/lib"; }; } ``` ### 在 Windows 上开发 要在 Windows 上开发,你需要使用 Linux 子系统(WSL)。请按照[WSL 安装说明](https://learn.microsoft.com/windows/wsl/install)操作,并从 Windows 商店安装 Ubuntu。一旦能够访问 Linux,就按照 Linux 的说明操作。 在 WSL 中工作时,请确保将所有代码/仓库保留在 WSL 环境中,以避免出现文件权限问题。 :::tip 如果你发现在使用 WSL 时无法通过 访问开发实例,请改在 WSL 终端中运行 `ip addr show eth0` 查找 `eth0` 适配器的 `inet` 地址。然后使用该地址(排除 CIDR 块)来访问开发实例,例如,如果你的 `inet` 显示为 `172.20.37.6/20`,则使用 。 ::: :::tip WSL 中的默认网络模式是 NAT。它有一些缺点,例如 Home Assistant 无法发现网络上的设备,并且使从 LAN 访问 Home Assistant 变得困难。或者,可以将网络模式设置为"Mirrored",这将使 WSL 使用与主机相同的网络接口(它们甚至有相同的 IP),并且具有诸如支持 Multicast(启用 mDNS 设备发现)等好处。 请查看 [WSL Mirrored 模式网络文档](https://learn.microsoft.com/en-us/windows/wsl/networking#mirrored-mode-networking) 以获取有关如何启用它的详细信息。 ::: ### 在 macOS 上开发 安装 [Homebrew](https://brew.sh/),然后使用它安装依赖项: ```shell brew install python3 autoconf ffmpeg cmake make ``` Home Assistant 的某些 Python 依赖项(如 `cryptography` 和 `orjson`)包含用 Rust 编写的扩展。如果你的 Python 版本和平台没有可用的预构建 wheel,pip 会从源代码构建它们,这需要 [Rust 工具链](https://www.rust-lang.org/tools/install)。如果下面的 `script/setup` 脚本因缺少 `rustc` 或 `cargo` 而失败,请同时安装 Rust: ```shell brew install rust ``` 如果在运行下面的 `script/setup` 脚本时遇到 `cryptography` 的构建问题,请查看 cryptography 文档中的[安装说明](https://cryptography.io/en/latest/installation/#building-cryptography-on-macos)。 ### 设置本地仓库 访问 [Home Assistant Core 仓库](https://github.com/home-assistant/core) 并点击 **Fork**。 完成 fork 后,使用以下命令设置源代码的本地副本: ```shell git clone https://github.com/YOUR_GIT_USERNAME/name_of_your_fork cd name_of_your_fork git remote add upstream https://github.com/home-assistant/core.git ``` 使用一个名为 `setup` 的脚本安装 requirements。 ```shell script/setup ``` 这将创建一个虚拟环境并安装所有必要的 requirements。现在你可以开始了! 每次你开始一个新的终端会话,都需要激活你的虚拟环境: ```shell source .venv/bin/activate ``` 之后你可以这样运行 Home Assistant: ```shell hass -c config ``` 如果在 *macOS* 上运行此命令时遇到崩溃(`SIGKILL`),这很可能是由于缺少蓝牙权限造成的。你可以通过为你的终端应用程序添加此权限来修复它(**System Preferences** -> **Security & Privacy** -> **Bluetooth**)。 Home Assistant 的配置存储在你的仓库根目录下的 `config` 目录中。 --- url: /developers/development_guidelines.md --- Home Assistant 对所有提交的代码都强制执行严格的 [PEP8 style](https://peps.python.org/pep-0008/) 和 [PEP 257 (Docstring Conventions)](https://peps.python.org/pep-0257/) 规范。 我们使用 [Ruff](https://docs.astral.sh/ruff/) 进行代码格式化。每个 pull request 都会作为 linting 过程的一部分自动进行检查,我们不会合并不符合规范的提交。 相关要点摘要: * 注释应为完整的句子,并以句号结尾。 * [Imports](https://peps.python.org/pep-0008/#imports) 应按顺序排列。 * 常量以及列表和字典的内容应按字母顺序排列。 建议调整 IDE 或编辑器设置以符合这些要求。 ## 我们的建议 对于某些情况,[PEPs](https://peps.python.org/) 并没有明确规定。本节涵盖了我们关于代码风格的建议。这些要点来自现有代码,并基于贡献者和开发者最常使用的实践。这基本上是一个多数决定,因此你可能并不认同。但我们希望鼓励你遵循这些建议,以保持代码的一致性。 ### 文件头部 文件头部 docstring 应描述该文件的作用。 ```python """Support for MQTT lights.""" ``` ### 日志消息 无需在日志消息中附加平台或组件名称,这会自动完成。与 `syslog` 消息一样,末尾不应有句号。一种广泛使用的风格如下所示,但你可以自由组合消息内容。 ```python _LOGGER.error("No route to device: %s", self._resource) ``` ```log 2017-05-01 14:28:07 ERROR [homeassistant.components.sensor.arest] No route to device: 192.168.0.18 ``` 不要打印 API keys、tokens、用户名或密码(即使它们有误)。 谨慎使用 `_LOGGER.info`,对于不面向用户的内容,请使用 `_LOGGER.debug`。 ### 使用新式字符串格式化 优先使用 [f-strings](https://docs.python.org/3/reference/lexical_analysis.html#f-strings),而不是 `%` 或 `str.format`。 ```python # New f"{some_value} {some_other_value}" # Old, wrong "{} {}".format("New", "style") "%s %s" % ("Old", "style") ``` 一个例外是日志记录,它使用百分比格式化。这是为了在日志消息被抑制时避免格式化。 ```python _LOGGER.info("Can't connect to the webservice %s at %s", string1, string2) ``` ### Typing 我们鼓励完全为你的代码添加类型注解。这有助于在我们代码库中发现/防止问题和 bug,也有助于其他贡献者在未来对你代码进行调整。 默认情况下,Home Assistant 会在自动化 CI 流程中进行静态类型检查。 如果 Python 模块已经完成了完整的类型标注,可以通过在 Home Assistant Core 项目根目录的 `.strict-typing` 文件中添加条目,将其纳入严格检查。 #### 使用 `assert` 缩小类型范围 有时候类型检查器无法确定代码中某一点的变量确切类型,即使你明确知道它的类型更具体。在这种情况下,可以在 `TYPE_CHECKING` 代码块中使用 `assert` 语句来帮助类型检查器缩小类型范围。这些 assert 语句**只能**用于 `TYPE_CHECKING` 代码块中,使其仅对类型检查器有效,不影响运行时行为。 ```python from typing import TYPE_CHECKING if TYPE_CHECKING: assert something is not None something.do_work() ``` ### 函数 docstring 约定 类型注解通常用于记录函数参数。 当你需要更详细的文档时,请使用 [Google style](https://google.github.io/styleguide/pyguide.html#383-functions-and-methods) 编写 docstring,记录参数、返回值或异常。在这些情况下,参数和返回值的类型信息应该已经在类型注解中指定,并从 docstring 中省略。 ```python def some_method(self, param1: str, param2: str) -> int: """Example Google-style docstring. Args: param1: The first parameter. param2: The second parameter. Returns: An integer result. Raises: KeyError: If the key doesn't exist. """ return 0 ``` --- url: /developers/development_index.md --- Home Assistant 的核心从一开始就被设计为易于通过集成来扩展。在本节中,我们重点关注如何开发集成。 在开始之前,请确保你已阅读了[Home Assistant 整体架构](/developers/architecture_index.md),以便熟悉构成 Home Assistant 的概念。 如需获取支持或就为 Home Assistant 的开发做贡献提出问题,请加入 [Discord](https://www.home-assistant.io/join-chat/) 上的 **#developers** 频道,或在 **#support** 频道中创建主题。 分配 Developer 角色:在侧边栏中,选择 **Channels & Roles**,然后选择 **I want to contribute dev skills to Home Assistant** 即可获得访问这些频道的权限。 --- url: /developers/development_submitting.md --- :::tip 请始终基于当前的 **`dev`** 分支创建 Pull Requests,而不是 `master`。 ::: 使用 GitHub [Pull Requests](https://docs.github.com/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests),一次一个地将你的改进、修复和新功能提交给 Home Assistant。步骤如下: 1. 从你的 fork 的 dev 分支中,创建一个新分支来保存你的更改: `git checkout -b some-feature` 2. 进行你的更改,创建[新平台](/developers/creating_platform_index.md),开发[新集成](/developers/creating_component_index.md),或修复[issues](https://github.com/home-assistant/core/issues)。 3. [测试你的更改](/developers/development_testing.md) 并检查是否存在风格违规。 考虑添加测试以确保你的代码能够正常工作。 4. 如果根据这些[必须项](/developers/development_checklist.md) 一切看起来都没问题,提交你的更改: `git add .` `git commit -m "Add some feature"` * 编写有意义的提交消息,而不仅仅是 `Update` 或 `Fix` 之类的内容。 * 使用大写字母开头,并且不要在末尾加句号。 * 不要用 `[bla.bla]` 或 `platform:` 前缀你的提交消息。 * 使用祈使语气编写提交消息,例如 `Add some feature`,而不是 `Adds some feature`。 5. 将提交的更改推送到你在 GitHub 上的 fork: `git push origin HEAD` 6. 按照[这些步骤](https://docs.github.com/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) 创建你的 pull request。 * 在 GitHub 上,导航到 [Home Assistant 仓库的主页面](https://github.com/home-assistant/core)。 * 在 "Branch" 菜单中,选择包含你提交(来自你的 fork)的分支。 * 点击 Branch 菜单右侧的 **New pull request**。 * 使用 base branch 下拉菜单选择要将更改合并到的分支,然后使用 compare branch 下拉菜单选择你进行更改的主题分支。确保 Home Assistant 分支与你的 fork 分支(`dev`)匹配,否则你将提交所有分支之间的提交。 * 输入标题并填写 pull request 的提供模板。 * 点击 **Create pull request**。 7. 检查你的 pull request 上的评论和建议,并关注 [CI output](https://github.com/home-assistant/core/actions)。 :::info 如果你是第一次提交 pull request,CI 在维护者批准之前不会运行。只需等待,维护者最终会前来并批准。 ::: --- url: /developers/development_testing.md --- 如[风格指南部分](/developers/development_guidelines.md)所述,所有代码都会进行检查,以验证以下内容: * 所有单元测试通过 * 所有代码通过 linting 工具的检查 本地测试使用 [pytest](https://docs.pytest.org/) 进行,并使用 [prek](https://prek.j178.dev/) 来运行 linting 工具,它已在[虚拟环境](/developers/development_environment.md)中运行 `script/setup` 时安装。 在运行测试之前,需要先安装 Python 测试依赖。可以通过使用 VScode devcontainer 及相应的任务来实现。请查看 [devcontainer 文档](/developers/development_environment.md#tasks) 了解运行任务的指导。 要在整个代码库上运行 linting 工具,请执行以下命令: ```shell prek run --all-files ``` 要启动测试并运行完整的测试套件,激活虚拟环境并运行以下命令: ```shell pytest tests ``` 或者,在 Visual Studio Code 中,启动 **Pytest** 任务。 根据你的发行版/操作系统,可能需要安装额外的包: * Fedora: `sudo dnf -y install systemd-devel gcc-c++` * Ubuntu: `sudo apt-get install libudev-dev` :::info Important 在创建 pull request 之前运行 `pytest` 和 `prek`,以避免令人烦恼的修复。 `prek` 会在 git 提交更改时自动调用。 ::: :::note 运行完整的 `pytest` 测试套件需要相当长的时间,因此作为 pull request 的最低要求,请至少运行与你的代码更改相关的测试(见下文了解如何操作)。完整的测试套件无论如何都会在创建 pull request 之后、合并之前由 CI 运行。 ::: 运行 `pytest` 会在本地可用的 Python 版本上运行单元测试。我们会在 CI 中针对所有受支持的 Python 版本运行测试。 ### 向测试环境添加新依赖 如果你正在为某个集成编写测试并更改了依赖项,请运行 `script/gen_requirements_all.py` 脚本来更新所有需求文件。 接下来,可以通过运行以下命令更新开发环境中的所有依赖项: ```shell uv pip install -r requirements_all.txt -r requirements_test.txt ``` 或者,在 Visual Studio Code 中,启动 **Install all (test & production) Requirements** 任务。 ### 运行有限的测试套件 可以向 `pytest` 传递参数,以运行单个测试套件或测试文件。 以下是一些有用的命令: ```shell # Stop after the first test fails $ pytest tests/test_core.py -x # Run test with specified name $ pytest tests/test_core.py -k test_split_entity_id # Fail a test after it runs for 2 seconds $ pytest tests/test_core.py --timeout 2 # Show the 10 slowest tests $ pytest tests/test_core.py --duration=10 ``` 如果你只想测试你的集成,并包含测试覆盖率报告,建议使用以下命令: ```shell pytest ./tests/components// --cov=homeassistant.components. --cov-report term-missing -vv ``` 或者,在 Visual Studio Code 中,启动 **Code Coverage** 任务。 ### 防止 linter 错误 多个 linting 工具已配置为在尝试提交时自动运行,作为在[虚拟环境](/developers/development_environment.md)中运行 `script/setup` 的一部分。 也可以手动运行这些 linting 工具: ```shell prek run --show-diff-on-failure ``` 或者,在 Visual Studio Code 中,启动 **Prek** 任务。 linting 工具也直接可用,可以对单个文件运行测试: ```shell ruff check homeassistant/core.py pylint homeassistant/core.py ``` ### 关于 PyLint 和 PEP8 验证的注意事项 如果无法避免某个 PyLint 警告,请添加注释,使用 `# pylint: disable=YOUR-ERROR-NAME` 禁用该行的 PyLint 检查。一个无法避免的示例是,当 PyLint 错误报告某个对象没有某个成员时。 ### 为集成编写测试 * 确保在集成的测试中不要与集成的内部细节交互。遵循此模式将使测试在面对集成变更时更加健壮。 * 使用核心接口,通过 [`async_setup_component`](https://github.com/home-assistant/core/blob/4cce724473233d4fb32c08bd251940b1ce2ba570/homeassistant/setup.py#L44-L46) 或(如果该集成支持 config entries)[`hass.config_entries.async_setup`](https://github.com/home-assistant/core/blob/4cce724473233d4fb32c08bd251940b1ce2ba570/homeassistant/config_entries.py#L693) 来设置集成。 * 通过核心 state machine [`hass.states`](https://github.com/home-assistant/core/blob/4cce724473233d4fb32c08bd251940b1ce2ba570/homeassistant/core.py#L887) 断言 entity 状态。 * 通过核心 service registry [`hass.services`](https://github.com/home-assistant/core/blob/4cce724473233d4fb32c08bd251940b1ce2ba570/homeassistant/core.py#L1133) 执行 service action 调用。 * 通过 [device registry](https://github.com/home-assistant/core/blob/4cce724473233d4fb32c08bd251940b1ce2ba570/homeassistant/helpers/device_registry.py#L101) 断言 `DeviceEntry` 状态。 * 通过 [entity registry](https://github.com/home-assistant/core/blob/4cce724473233d4fb32c08bd251940b1ce2ba570/homeassistant/helpers/entity_registry.py#L120) 断言 entity registry `RegistryEntry` 状态。 * 通过 config entries 接口 [`hass.config_entries`](https://github.com/home-assistant/core/blob/4cce724473233d4fb32c08bd251940b1ce2ba570/homeassistant/config_entries.py#L570) 修改 `ConfigEntry`。 * 通过 [`ConfigEntry.state`](https://github.com/home-assistant/core/blob/4cce724473233d4fb32c08bd251940b1ce2ba570/homeassistant/config_entries.py#L169) 属性断言 config entry 的状态。 * 通过 [`tests/common.py`](https://github.com/home-assistant/core/blob/4cce724473233d4fb32c08bd251940b1ce2ba570/tests/common.py#L658) 中的 `MockConfigEntry` 类来 mock 一个 config entry。 ### 快照测试 Home Assistant 支持一种称为 snapshot testing(也称为 approval tests)的测试概念,即通过将值与存储的引用值(snapshot)进行断言的测试。 snapshot 测试不同于常规(功能性)测试,也不能取代功能性测试,但对于测试较大的测试输出非常有用。在 Home Assistant 中,它们可以用于: * 确保 entity 状态的输出符合预期并保持不变。 * 确保 registry 中的 area、config、device、entity 或 issue entry 符合预期并保持不变。 * 确保诊断 dump 的输出符合预期并保持不变。 * 确保 FlowResult 符合预期并保持不变。 以及更多具有较大输出的情况,如 JSON、YAML 或 XML 结果。 snapshot 测试与常规测试的主要区别在于,结果是通过以特殊模式运行测试来捕获并创建 snapshot 的。随后测试的每次顺序运行都会将结果与 snapshot 进行比较。如果结果不同,测试将失败。 Home Assistant 中的 snapshot testing 建立在 [Syrupy](https://github.com/tophat/syrupy) 之上,因此编写 Home Assistant 测试时可以适用其文档。以下是一个断言 entity 状态输出的 snapshot 测试: ```python # tests/components/example/test_sensor.py from homeassistant.core import HomeAssistant from syrupy.assertion import SnapshotAssertion async def test_sensor( hass: HomeAssistant, snapshot: SnapshotAssertion, ) -> None: """Test the sensor state.""" state = hass.states.get("sensor.whatever") assert state == snapshot ``` 首次运行此测试时,它会失败,因为不存在 snapshot。 要创建(或更新)snapshot,请使用 `--snapshot-update` 标志运行测试: ```shell pytest tests/components/example/test_sensor.py --snapshot-update ``` 或者,在 Visual Studio Code 中,启动 **Update syrupy snapshots** 任务。 这会在 `tests/components/example/snapshots` 中创建一个 snapshot 文件。snapshot 文件以测试文件命名,在本例中为 `test_sensor.ambr`,并且是人工可读的。snapshot 文件必须提交到仓库中。 再次运行测试时(不带更新标志),会将结果与存储的 snapshot 进行比较,一切应该通过。 当测试结果发生变化时,测试会失败,需要再次更新 snapshot。 请谨慎使用 snapshot testing!因为创建 snapshot 非常容易,容易让人倾向于对一切内容进行 snapshot 断言。然而,请记住,它不是功能性测试的替代品。 例如,在测试 device 返回错误时 entity 是否会变为 unavailable,更好的做法是断言你期望的特定变更:断言该 entity 的状态变为 `unavailable`。这种功能性测试比使用 snapshot 断言该 entity 的完整状态要好,因为后者假设其按预期工作(在创建 snapshot 时)。 --- url: /developers/development_tips.md --- 本页提供一些可能对你有帮助的技巧和窍门,作为 Home Assistant 的贡献者。这里的列表绝不完整,如果你发现了其他未记录的技巧和窍门,请提交 PR 将它们添加到这里。 ## 技巧与窍门 ### 保持 PR 简单 有关 PR 的预期,请参阅[Component 检查清单](/developers/creating_component_code_review.md#5-make-your-pull-request-as-small-as-possible)。 ### 在 Home Assistant 中测试包依赖项的更改 有关更多信息,请参阅[API 库文档](/developers/api_lib_index.md#trying-your-library-inside-home-assistant)。 ### 在你生产环境的 Home Assistant 中测试 Core 集成更改 要在生产 Home Assistant 环境中测试 core 集成的更改: 1. 将集成文件夹复制到 `/config/custom_components`。 2. 在 `manifest.json` 中添加 **version** 字段(例如,`"version": "0.0.0"`)。 3. 如果该集成使用了本地化的字符串,请按照[自定义集成本地化](/developers/internationalization/custom_integration.md)中的说明,将 `strings.json` 复制到集成文件夹下的 `translations/en.json`。 4. 重启 Home Assistant。 Home Assistant 总是优先考虑 `custom_components` 中的集成而不是 core 集成。测试完成后,别忘了移除它,否则你将停留在该版本上。 ### 为集成添加 config flow 时,请注意前端 Home Assistant 前端会进行积极缓存,因此,当你首次使用新更改运行 Home Assistant 时,集成可能不会出现在集成列表中。请检查日志以确保没有错误,如果没有,请对浏览器窗口执行强制刷新(hard refresh),然后重试;在很多情况下,这就能解决问题。 ### 获取更多支持 Home Assistant [Discord](https://www.home-assistant.io/join-chat/) 服务器上的 `#developers` 频道是提问的好地方。专业提示:在发布问题之前,将正在工作的代码推送到一个分支,并将该分支推到某个公开位置,然后将链接连同你的问题一起粘贴,这样帮助你的人就能看到你的代码。请不要将代码大片段粘贴到频道中,因为这样很难阅读,而且会掩盖其他问题/讨论。 如果你发现可以改进开发者文档的地方,请将它传递下去,提交 PR 来更新它们。有关更多详情,请查看下一个技巧。 ### 开发者文档中缺失的信息 Home Assistant 维护者努力保持开发者文档的最新状态,但我们也依赖像你这样的贡献者来帮助纠正、改进和扩展现有的文档。与 Home Assistant 一样,[此文档是开源的](https://github.com/home-assistant/developers.home-assistant),欢迎提交 PR。如有疑问,请点击左下角的 `Edit this page` 按钮,进入源文件并直接在 GitHub 上编辑该文件。无需命令行! --- url: /developers/development_typing.md --- Python 中的 type hints 是对变量和函数的静态标注,便于人类更容易理解代码。请参见标准库 [docs](https://docs.python.org/3/library/typing.html) 以及这场 PyCascades 2018 的 [演讲](https://youtu.be/zKre4DKAB30)。 目前在 Home Assistant 中,并非所有模块都要求 type hints,但我们的目标是尽可能实现完整的覆盖。 为了改进和鼓励这一点,所有代码都会在我们的持续集成流程中进行类型检查,并假设所有内容都已进行类型检查,除非被明确排除在类型检查之外。 为现有代码库添加 type hints 可能是一项艰巨的任务。为了加快这一过程并帮助开发者,Instagram 制作了 [`monkeytype`](https://pypi.org/project/MonkeyType/) 程序。它会在运行时分析调用情况,并尝试为代码分配正确的 type hints。 参见 [这篇 Instagram 博客文章](https://instagram-engineering.com/let-your-code-type-hint-itself-introducing-open-source-monkeytype-a855c7284881) 了解使用 monkeytype 程序所涉及的工作流程。 我们添加了一个脚本,用于启动测试套件或测试模块的运行,并告诉 `monkeytype` 程序分析该运行。 ### 基本工作流程 1. 运行 `script/monkeytype tests/path/to/your_test_module.py`。 2. 运行 `monkeytype stub homeassistant.your_actual_module`。 3. 查看 monkeytyped typing stub 的输出。如果结果不太糟糕,则将 stub 应用到你的模块。在最后一部通常需要手动编辑类型标注。 4. 运行 `monkeytype apply homeassistant.your_actual_module`。 5. 检查 diff,并在需要时手动纠正类型标注。提交、推送分支并创建 PR。 **注意:** 将 monkeytyped stub 应用到已有类型标注的模块可能会出错且无法工作。该工具对完全未标注类型的模块最有用。 ### 包含用于严格类型检查的模块 虽然我们鼓励使用 type hints,但目前我们不要求集成必须使用。 默认情况下,我们的 CI 会进行静态类型检查。如果某个模块已经完全标注类型,可以通过将其添加到位于 Home Assistant Core 项目根目录的 `.strict-typing` 文件中,将其标记为启用严格检查。 --- url: /developers/development_validation.md --- `configuration.yaml` 文件包含组件和平台的配置选项。我们使用 [voluptuous](https://pypi.python.org/pypi/voluptuous) 来确保用户提供的配置是有效的。某些条目是可选的,或者是设置平台或组件所必需的。其他条目必须为已定义的类型或来自已定义的列表。 我们会测试配置,以确保用户在 Home Assistant 运行之前,如果平台或组件设置有问题,能尽量减少通知并保持良好的体验。 除了 [voluptuous](https://pypi.python.org/pypi/voluptuous) 默认类型外,还有许多自定义类型。要概览它们,请查看 [config\_validation.py](https://github.com/home-assistant/core/blob/dev/homeassistant/helpers/config_validation.py) helper。 * Types: `string`、`byte` 和 `boolean` * Entity ID: `entity_id` 和 `entity_ids` * Numbers: `small_float` 和 `positive_int` * Time: `time`、`time_zone` * Misc: `template`、`slug`、`temperature_unit`、`latitude`、`longitude`、`isfile`、`sun_event`、`ensure_list`、`port`、`url` 和 `icon` 对于使用 [MQTT](https://www.home-assistant.io/components/mqtt/) 的平台验证,可使用 `valid_subscribe_topic` 和 `valid_publish_topic`。 需要注意的事项: * 使用 `const.py` 中定义的常量 * 从你正在集成的 integration 中导入 `PLATFORM_SCHEMA` 并对其进行扩展 * 首选顺序是先 `required`,后 `optional` * 可选配置键的默认值必须是有效值。不要使用 `None` 作为默认值,如 `vol.Optional(CONF_SOMETHING, default=None): cv.string`,如果需要,请将默认值设置为 `default=''` ### 代码片段 本节包含我们使用的验证代码片段。 #### 默认名称 如果用户没有提供名称,为 sensor 设置默认值是很常见的做法。 ```python DEFAULT_NAME = "Sensor name" PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { # ... vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, } ) ``` #### 限制值 你可能希望将用户的输入限制在少数几个选项。 ```python DEFAULT_METHOD = "GET" PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { # ... vol.Optional(CONF_METHOD, default=DEFAULT_METHOD): vol.In(["POST", "GET"]), } ) ``` #### 端口 所有端口号范围都是 1 到 65535。 ```python DEFAULT_PORT = 993 PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { # ... vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port, } ) ``` #### 列表 如果 sensor 有一个预定义的可用选项列表,请测试以确保配置条目与列表匹配。 ```python SENSOR_TYPES = { "article_cache": ("Article Cache", "MB"), "average_download_rate": ("Average Speed", "MB/s"), } PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { # ... vol.Optional(CONF_MONITORED_VARIABLES, default=[]): vol.All( cv.ensure_list, [vol.In(SENSOR_TYPES)] ), } ) ``` --- url: /developers/device_automation_action.md --- :::warning 我们目前正在探索 device automations 的替代方案。现有的 device automations 将继续工作,但新的 device automations 将不再被接受。 ::: Device actions 允许用户让设备执行某个操作。例如,打开一盏灯或打开一扇门。 Device actions 被定义为字典。这些字典由你的集成创建,并传回你的集成以生成一个执行该动作的函数。 Device actions 可以由提供该设备的集成(例如 ZHA、deCONZ)提供,也可以由设备拥有实体的实体集成(例如 light、switch)提供。 前者的例子可以是重启设备,而后者的例子可以是打开一盏灯。 如果动作需要静态的 `ACTION_SCHEMA` 无法提供的动态校验,可以实现一个 `async_validate_action_config` 函数。 ```py async def async_validate_action_config(hass: HomeAssistant, config: ConfigType) -> ConfigType: """Validate config.""" ``` Home Assistant 提供了一个模板来帮助你开始编写 device actions。在开发环境中运行 `python3 -m script.scaffold device_action` 即可开始。 该模板会在你的集成文件夹中创建一个新的 `device_action.py` 文件和对应的测试文件。该文件包含以下函数和常量: #### `ACTION_SCHEMA` 这是动作的 schema。基础 schema 应扩展自 `homeassistant.helpers.config_validation.DEVICE_ACTION_BASE_SCHEMA`。不要手动应用该 schema。如果动作 schema 被定义为集成 `device_action.py` 模块中的常量,核心会自动应用该 schema。 #### `async_get_actions` ```py async def async_get_actions(hass: HomeAssistant, device_id: str) -> list[dict]: """List device actions for devices.""" ``` 返回该设备支持的动作列表。 #### `async_call_action_from_config` ```py async def async_call_action_from_config( hass: HomeAssistant, config: dict, variables: dict, context: Context | None ) -> None: """Execute a device action.""" ``` 执行传入的动作。 --- url: /developers/device_automation_condition.md --- :::warning 我们目前正在探索 device automations 的替代方案。现有的 device automations 将继续工作,但新的 device automations 将不再被接受。 ::: Device conditions 允许用户检查某个条件是否满足。例如,灯是否打开,或者地面是否潮湿。 Device conditions 被定义为字典。这些字典由你的集成创建,并传回你的集成以生成一个检查条件的函数。 Device conditions 可以由提供该设备的集成(例如 ZHA、deCONZ)提供,也可以由设备拥有实体的实体集成(例如 light、humidity sensor)提供。 后者的例子可以是检查灯是否打开,或地面是否潮湿。 如果条件需要静态的 `CONDITION_SCHEMA` 无法提供的动态校验,可以实现一个 `async_validate_condition_config` 函数。 ```py async def async_validate_condition_config(hass: HomeAssistant, config: ConfigType) -> ConfigType: """Validate config.""" ``` Home Assistant 提供了一个模板来帮助你开始编写 device conditions。在开发环境中运行 `python3 -m script.scaffold device_condition` 即可开始。 该模板会在你的集成文件夹中创建一个新的 `device_condition.py` 文件和对应的测试文件。该文件包含以下函数和常量: #### `CONDITION_SCHEMA` 这是条件的 schema。基础 schema 应扩展自 `homeassistant.helpers.config_validation.DEVICE_CONDITION_BASE_SCHEMA`。 #### `async_get_conditions` ```py async def async_get_conditions( hass: HomeAssistant, device_id: str ) -> list[dict[str, str]]: """List device conditions for devices.""" ``` 返回该设备支持的条件列表。 #### `async_condition_from_config` ```py @callback def async_condition_from_config( config: ConfigType, config_validation: bool ) -> condition.ConditionCheckerType: """Create a function to test a device condition.""" ``` 根据配置创建一个条件函数。条件函数应当是一个 async 友好的 callback,用于评估条件并返回一个 `bool`。 `config_validation` 参数将被核心用来根据定义的 `CONDITION_SCHEMA` 有条件地应用配置校验。 --- url: /developers/device_automation_index.md --- :::warning 我们目前正在探索 device automations 的替代方案。现有的 device automations 将继续工作,但新的 device automations 将不再被接受。 ::: Device Automations 在 Home Assistant 的核心概念之上为用户提供了以设备为中心的抽象层。在创建自动化时,用户不再需要直接处理 state 和 event 等核心概念。相反,他们可以选择一个设备,然后从预定义的 trigger、condition 和 action 列表中进行选择。 集成可以通过暴露生成预定义 trigger、condition、action 的函数,以及能够监听 trigger、检查 condition 并执行 action 的函数来接入该系统。 Device automations 并未提供额外的功能,而是让用户无需学习新概念的一种方式。Device automations 在底层使用了 event、state 和 service action 的辅助工具。 ### 次要设备自动化 某些设备可能会暴露大量的 device automation。为了避免给用户带来过多负担,可以将某个 device automation 标记为 secondary。被标记为 secondary 的 device automation 仍然会展示给用户,但可能会在其他 device automation 之后展示,或者要求用户选择"显示更多"选项或类似操作。 如果 device automation 通过 `entity_id` 键引用了一个实体,那么当被引用的实体被隐藏时,或者当被引用实体的 entity category 不是 `None` 时,secondary 标志将自动设置为 `True`。下面的示例展示了如何将 device automation 标记为 secondary。 ```python from homeassistant.const import ( CONF_DEVICE_ID, CONF_DOMAIN, CONF_PLATFORM, CONF_TYPE, ) from homeassistant.helpers import device_registry as dr async def async_get_triggers(hass, device_id): """Return a list of triggers.""" device_registry = dr.async_get(hass) device = device_registry.async_get(device_id) triggers = [] # Determine which triggers are supported by this device_id ... triggers.append({ # Required fields of TRIGGER_BASE_SCHEMA CONF_PLATFORM: "device", CONF_DOMAIN: "mydomain", CONF_DEVICE_ID: device_id, # Required fields of TRIGGER_SCHEMA CONF_TYPE: "less_important_trigger", # Mark the trigger as secondary "metadata": {"secondary": True}, }) return triggers ``` --- url: /developers/device_automation_trigger.md --- :::warning 我们目前正在探索 device automations 的替代方案。现有的 device automations 将继续工作,但新的 device automations 将不再被接受。 ::: Device triggers 是与特定设备和 event 或 state change 关联的自动化触发器。例如,"灯被打开"或"检测到水"。 Device triggers 可以由提供该设备的集成(例如 ZHA、deCONZ)提供,也可以由设备拥有实体的实体集成(例如 light、switch)提供。前者的例子是不与实体关联的 event,例如遥控器或触摸面板上的按键;后者的例子则可能是灯被打开。 若要添加 Device Triggers 支持,一个集成需要包含一个 `device_trigger.py` 文件,并完成以下工作: * *定义 `TRIGGER_SCHEMA`*:一个代表触发器的字典,例如设备和 event 类型 * *创建触发器*:创建包含设备或实体以及按 schema 定义所支持的 event 或 state change 的字典。 * *关联触发器*:将触发器配置与一个 event 或 state change 关联,例如在 event bus 上触发的消息。 * *添加文本和翻译*:为每个触发器提供一个人类可读的名称。 不要手动应用静态 schema。如果触发器 schema 被定义为集成 `device_trigger.py` 模块中的常量,核心会自动应用该 schema。 如果触发器需要静态的 `TRIGGER_SCHEMA` 无法提供的动态校验,可以实现一个 `async_validate_trigger_config` 函数。 ```py async def async_validate_trigger_config(hass: HomeAssistant, config: ConfigType) -> ConfigType: """Validate config.""" ``` Home Assistant 提供了一个模板来帮助你开始编写 device triggers。在开发环境中运行 `python3 -m script.scaffold device_trigger` 即可开始。 该模板会在你的集成文件夹中创建一个新的 `device_trigger.py` 文件和对应的测试文件。该文件包含以下函数和常量: #### 定义 `TRIGGER_SCHEMA` Device triggers 被定义为字典。这些字典由你的集成创建,并被你的集成消费以关联触发器。 这是一个 voluptuous schema,用于验证某个特定的触发器字典是否表示你的集成可以处理的配置。它应该扩展自 `device_automation/__init__.py` 中的 TRIGGER\_BASE\_SCHEMA。 ```python from homeassistant.const import ( CONF_ENTITY_ID, CONF_TYPE, ) TRIGGER_TYPES = {"water_detected", "noise_detected"} TRIGGER_SCHEMA = TRIGGER_BASE_SCHEMA.extend( { vol.Required(CONF_TYPE): vol.In(TRIGGER_TYPES), } ) ``` 该示例有一个 `type` 字段,指示所支持的事件类型。 #### 创建触发器 `async_get_triggers` 方法返回该设备或其关联实体所支持的触发器列表。这些是向用户暴露以供创建自动化的触发器。 ```python from homeassistant.const import ( CONF_DEVICE_ID, CONF_DOMAIN, CONF_PLATFORM, CONF_TYPE, ) from homeassistant.helpers import device_registry as dr async def async_get_triggers(hass, device_id): """Return a list of triggers.""" device_registry = dr.async_get(hass) device = device_registry.async_get(device_id) triggers = [] # Determine which triggers are supported by this device_id ... triggers.append({ # Required fields of TRIGGER_BASE_SCHEMA CONF_PLATFORM: "device", CONF_DOMAIN: "mydomain", CONF_DEVICE_ID: device_id, # Required fields of TRIGGER_SCHEMA CONF_TYPE: "water_detected", }) return triggers ``` #### 关联触发器 要进行接线:给定一个 `TRIGGER_SCHEMA` 配置,确保在触发器被触发时调用 `action`。 例如,你可以将触发器和 action 关联到你的集成在 event bus 上触发的[事件](/developers/integration_events.md)。 ```python async def async_attach_trigger(hass, config, action, trigger_info): """Attach a trigger.""" event_config = event_trigger.TRIGGER_SCHEMA( { event_trigger.CONF_PLATFORM: "event", event_trigger.CONF_EVENT_TYPE: "mydomain_event", event_trigger.CONF_EVENT_DATA: { CONF_DEVICE_ID: config[CONF_DEVICE_ID], CONF_TYPE: config[CONF_TYPE], }, } ) return await event_trigger.async_attach_trigger( hass, event_config, action, trigger_info, platform_type="device" ) ``` 返回值是一个用于解除触发器关联的函数。 #### 添加文本和翻译 Automation 用户界面会显示一个映射到 event 类型的人类可读字符串。用你支持的 trigger 类型和子类型更新 `strings.json`: ```json { "device_automation": { "trigger_type": { "water_detected": "Water detected", "noise_detected": "Noise detected" } } ``` 在开发过程中测试你的翻译,请运行 `python3 -m script.translations develop`。 --- url: /developers/device_registry_index.md --- Device registry 是 Home Assistant 用于跟踪设备的注册表。一个设备在 Home Assistant 中通过一个或多个 entity 来表示。例如,一个电池供电的温度和湿度传感器可能会暴露温度、湿度和电池电量的 entity。 Device registry overview ## 什么是设备? Home Assistant 中的设备代表一个拥有独立控制单元的物理设备,或者一项服务。控制单元本身不需要是智能的,但它应该掌控所发生的事情。例如,一个带有 4 个房间传感器的 Ecobee 温控器在 Home Assistant 中等于 5 个设备,其中一个是包含其内部所有传感器的温控器,另一个对应每个房间传感器。 如果你将一个传感器连接到另一个设备来读取它的一些数据,它仍然应该被表示为两个不同的设备。这样做的原因是,传感器可能被移动去读取另一个设备的数据。 一个提供多个 endpoint 的设备,可以被拆分为单独的设备,并通过 `via_device` 属性指向父设备。这样可以将不同的 endpoint 分配给建筑物中不同的 area,也便于对 entity 进行逻辑分组。典型的需要拆分为父设备和多个子设备的例子包括智能排插或多路墙壁开关。父设备将拥有表示排插或多路开关状态的 entity,例如网络连接状态和固件更新。子设备则将绑定到某一个通道的 entity 进行分组,例如每个通道一个开关 entity 和能耗 sensor。 :::info 虽然目前尚未可用,但我们可以考虑为用户提供合并设备的选项。 ::: ## Device 属性 | Attribute | Description | |----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | area\_id | 设备所在的 area。 | | config\_entries | 与此设备关联的 config entries。 | | configuration\_url | 可以在其上配置设备或服务的 URL,链接到 Home Assistant UI 内部的路径可以通过使用 `homeassistant://` 来完成。 | | connections | `(connection_type, connection identifier)` 元组的集合。connection types 定义在 device registry 模块中。集合中的每一项都唯一地定义了一个设备条目,这意味着另一个设备不能拥有相同的 connection。 | | default\_manufacturer | 设备的制造商,如果设置了 `manufacturer` 则会被覆盖。例如,对于显示网络上所有设备的集成非常有用。 | | default\_model | 设备的型号,如果设置了 `model` 则会被覆盖。例如,对于显示网络上所有设备的集成非常有用。 | | default\_name | 此设备的默认名称,如果设置了 `name` 则会被覆盖。例如,对于显示网络上所有设备的集成非常有用。 | | entry\_type | 条目的类型。可能的值为 `None` 和 `DeviceEntryType` 枚举成员(仅 `service`)。 | | hw\_version | 设备的硬件版本。 | | id | 设备的唯一 ID(由 Home Assistant 生成) | | identifiers | `(DOMAIN, identifier)` 元组的集合。identifiers 用于在外部世界中识别设备。例如序列号。集合中的每一项都唯一地定义了一个设备条目,这意味着另一个设备不能拥有相同的 identifier。 | | name | 此设备的名称 | | name\_by\_user | 用户配置的设备名称。 | | manufacturer | 设备的制造商。 | | model | 设备的型号名称。 | | model\_id | 设备的型号标识符。 | | serial\_number | 设备的序列号。与 `identifiers` 集合中的序列号不同,此字段不需要唯一。 | | sw\_version | 设备的固件版本。 | | via\_device | 在此设备与 Home Assistant 之间路由消息的设备标识符。这类设备的例子包括 hub 或子设备的父设备。这用于在 Home Assistant 中显示设备拓扑。 | ## 定义设备 ### 通过 entity 自动注册 :::tip 仅当 entity 通过 [config entry](/developers/config_entries_index.md) 加载且定义了 `unique_id` 属性时,才会读取 entity 的 device info。 ::: 每个 entity 都能够通过 `device_info` 属性来定义一个设备。当 entity 通过 config entry 添加到 Home Assistant 时,会读取该属性。设备会通过提供的 identifiers 或 connections(如序列号或 MAC 地址)与现有设备进行匹配。如果同时提供了 identifiers 和 connections,device registry 会先尝试通过 identifiers 进行匹配。每个 identifier 和每个 connection 都会被单独匹配(例如,只需要匹配一个 connection 就会被视为同一个设备)。 ```python # Definition of DeviceInfo TypedDict class DeviceInfo(TypedDict, total=False): """Entity device information for device registry.""" configuration_url: str | URL | None connections: set[tuple[str, str]] created_at: str default_manufacturer: str default_model: str default_name: str entry_type: DeviceEntryType | None identifiers: set[tuple[str, str]] manufacturer: str | None model: str | None model_id: str | None modified_at: str name: str | None serial_number: str | None suggested_area: str | None sw_version: str | None hw_version: str | None translation_key: str | None translation_placeholders: Mapping[str, str] | None via_device: tuple[str, str] # Inside a platform class HueLight(LightEntity): @property def device_info(self) -> DeviceInfo: """Return the device info.""" return DeviceInfo( identifiers={ # Serial numbers are unique identifiers within a specific domain (hue.DOMAIN, self.unique_id) }, name=self.name, manufacturer=self.light.manufacturername, model=self.light.productname, model_id=self.light.modelid, sw_version=self.light.swversion, via_device=(hue.DOMAIN, self.api.bridgeid), ) ``` 除了 device 属性之外,`device_info` 还可以包含 `default_manufacturer`、`default_model`、`default_name`。如果尚未定义其他值,这些值将被添加到 device registry 中。对于了解一些信息但不够具体的集成,这非常有用。例如,一个根据 MAC 地址识别设备的路由器。 ### 手动注册 当没有实体代表某些设备时,component 也能够注册设备。例如,一个与灯具通信的 hub。 ```python # Definition of DeviceRegistry.async_get_or_create: class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]): ... @callback def async_get_or_create( self, *, config_entry_id: str, config_subentry_id: str | None | UndefinedType = UNDEFINED, configuration_url: str | URL | None | UndefinedType = UNDEFINED, connections: set[tuple[str, str]] | None | UndefinedType = UNDEFINED, created_at: str | datetime | UndefinedType = UNDEFINED, # will be ignored default_manufacturer: str | None | UndefinedType = UNDEFINED, default_model: str | None | UndefinedType = UNDEFINED, default_name: str | None | UndefinedType = UNDEFINED, # To disable a device if it gets created disabled_by: DeviceEntryDisabler | None | UndefinedType = UNDEFINED, entry_type: DeviceEntryType | None | UndefinedType = UNDEFINED, hw_version: str | None | UndefinedType = UNDEFINED, identifiers: set[tuple[str, str]] | None | UndefinedType = UNDEFINED, manufacturer: str | None | UndefinedType = UNDEFINED, model: str | None | UndefinedType = UNDEFINED, model_id: str | None | UndefinedType = UNDEFINED, modified_at: str | datetime | UndefinedType = UNDEFINED, # will be ignored name: str | None | UndefinedType = UNDEFINED, serial_number: str | None | UndefinedType = UNDEFINED, suggested_area: str | None | UndefinedType = UNDEFINED, sw_version: str | None | UndefinedType = UNDEFINED, translation_key: str | None = None, translation_placeholders: Mapping[str, str] | None = None, via_device: tuple[str, str] | None | UndefinedType = UNDEFINED, ) -> DeviceEntry: ... # Inside a component from homeassistant.helpers import device_registry as dr device_registry = dr.async_get(hass) device_registry.async_get_or_create( config_entry_id=entry.entry_id, connections={(dr.CONNECTION_NETWORK_MAC, config.mac)}, identifiers={(DOMAIN, config.bridgeid)}, manufacturer="Signify", suggested_area="Kitchen", name=config.name, model=config.modelname, model_id=config.modelid, sw_version=config.swversion, hw_version=config.hwversion, ) ``` ## 删除设备 集成可以选择允许用户从 UI 中删除设备。为此,集成应在其 `__init__.py` 模块中实现函数 `async_remove_config_entry_device`。 ```py async def async_remove_config_entry_device( hass: HomeAssistant, config_entry: ConfigEntry, device_entry: DeviceEntry ) -> bool: """Remove a config entry from a device.""" ``` 当用户点击设备的删除按钮并确认时,会等待 `async_remove_config_entry_device` 执行,如果返回 `True`,config entry 将从该设备中移除。如果它是该设备唯一的 config entry,设备将从 device registry 中删除。 在 `async_remove_config_entry_device` 中,集成应采取必要的步骤为设备移除做准备,并在成功时返回 `True`。集成也可以根据 `EVENT_DEVICE_REGISTRY_UPDATED` 进行操作(如果这比在 `async_remove_config_entry_device` 中清理更方便的话)。 --- url: /developers/discovery.md --- import RelatedRules from './\_includes/related\_rules.jsx' ## 理由 很多设备都具有被发现的机制。 这可以通过以下方法之一发生: * App(以前称为 add-ons) * [Bluetooth](/developers/creating_integration_manifest.md#bluetooth) * [DHCP](/developers/creating_integration_manifest.md#dhcp) * [HomeKit](/developers/creating_integration_manifest.md#homekit) * [mDNS](/developers/creating_integration_manifest.md#zeroconf) * [MQTT](/developers/creating_integration_manifest.md#mqtt) * [SSDP](/developers/creating_integration_manifest.md#ssdp) * [USB](/developers/creating_integration_manifest.md#usb) 这是一个让用户更容易找到并设置设备的好方法,因为他们不必手动查找使用哪个集成,然后再输入主机。 这大大减少了设置设备所需的精力,从而改善了用户体验。 使用基于网络的设置,还允许在设备获得新 IP 地址时更新集成的配置。 ## 示例实现 在下面的示例中,集成可以通过 mDNS 被发现。 设备会通过提供一个 `_mydevice._tcp.local.` 服务来让自己可被发现。 Home Assistant 会捕获到这个服务,并开始为用户启动一个发现流程。 然后用户将能够确认发现并设置该集成。 `manifest.json`: ```json {2} showLineNumbers { "zeroconf": ["_mydevice._tcp.local."] } ``` `config_flow.py`: ```python {8-23,25-36} showLineNumbers class MyConfigFlow(ConfigFlow, domain=DOMAIN): """My config flow.""" def __init__(self) -> None: """Initialize the config flow.""" self.data: dict[str, Any] = {} async def async_step_zeroconf( self, discovery_info: zeroconf.ZeroconfServiceInfo ) -> ConfigFlowResult: """Handle zeroconf discovery.""" self.data[CONF_HOST] = host = discovery_info.host await self.async_set_unique_id(discovery_info.properties["serialno"]) self._abort_if_unique_id_configured(updates={CONF_HOST: host}) client = MyClient(host) try: await client.get_data() except MyClientError: return self.async_abort(reason="cannot_connect") return await self.async_step_discovery_confirm() async def async_step_discovery_confirm( self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Confirm discovery.""" if user_input is not None: return self.async_create_entry( title="MyIntegration", data={CONF_HOST: self.data[CONF_HOST]}, ) self._set_confirm_only() return self.async_show_form(step_id="discovery_confirm") async def async_step_user( self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Handle a flow initialized by the user.""" errors: dict[str, str] = {} if user_input: client = MyClient(user_input[CONF_HOST]) try: serial_number = await client.check_connection() except MyException as exception: errors["base"] = "cannot_connect" else: await self.async_set_unique_id( serial_number, raise_on_progress=False ) self._abort_if_unique_id_configured() return self.async_create_entry( title="MyIntegration", data=user_input, ) return self.async_show_form( step_id="user", data_schema=vol.Schema( { vol.Required(CONF_HOST): TextSelector(), } ), errors=errors, ) ``` ## 附加资源 要了解有关 config flow 的更多信息,请查看[config flow 文档](/developers/core/integration/config_flow.md)。 要了解有关网络协议上的发现更多信息,请查看[网络与发现文档](/developers/network_discovery.md)。 要了解有关蓝牙设备发现的更多信息,请查看[蓝牙文档](/developers/bluetooth.md)。 要了解有关在 manifest 中指定不同发现方法的更多信息,请查看[集成 Manifest 文档](/developers/creating_integration_manifest.md)。 ## 例外 此规则的例外情况是,并非每个设备都可以被发现。 对于设备无法被发现的集成,此规则不适用。 ## 相关规则 --- url: /developers/documenting.md --- 用户文档位于 。 本节提供有关创建或修改内容的更多详细信息。 [home-assistant.io](https://home-assistant.io) 网站是使用 [Jekyll](https://github.com/jekyll/jekyll) 构建的。 页面是用 [Markdown](https://spec.commonmark.org/current/) 编写的。要添加一个页面,你不需要了解 HTML。 ## 文档 PR 审查流程 在提交 PR 之前,请通读[通用 PR 审查流程](/developers/review-process.md)。 此外,在贡献文档时,还需考虑以下文档指南。 文档仓库有两个主要分支:`current` 和 `next`: * 如果你在编写新集成或正在向代码添加功能的文档,请将目标指向 `next` 分支。 * 如果你在改进现有文档,请将目标指向 `current` 分支。 我们主要遵循 Microsoft Writing Style Guide,并有一些额外的指南: * [文档标准](/developers/documenting/standards.md) * [文档风格指南](/developers/documenting/general-style-guide.md) * [Microsoft Writing Style Guide](https://learn.microsoft.com/en-us/style-guide/welcome/) * [Merriam-Webster Dictionary](https://www.merriam-webster.com/) * [YAML 风格指南](/developers/documenting/yaml-style-guide.md) ## 小的更改 你可以使用 **Edit** 按钮或 **Edit this page** 链接来编辑页面,它会自动在 GitHub 中创建一个 fork,并允许你快速编辑。请注意,使用这种方式工作时无法上传图片。你在自己的更改上工作并通过 PR 提出。 创建 PR 时,可以通过点击 Netlify 评论中的 **Deploy Preview** 链接来查看拟议更改的预览。 ## 较大的更改 对于较大的更改,我们建议你克隆网站仓库。这样,你可以在本地查看更改。在网站上工作的过程与在 Home Assistant 本身上工作的过程没有区别。 ### 使用 Visual Studio Code + devcontainer 进行开发 开始开发最简单的方法是使用带有 devcontainers 的 Visual Studio Code,这与在 Home Assistant Core 开发中工作的方式相同。请查看[开发环境](/developers/development_environment.md)页面获取说明。 在按照这些说明操作时,将 Home Assistant Core 仓库替换为 `home-assistant.io` 仓库。 要查看更改,请打开 VS Code 命令面板并选择 **Tasks: Run Task** > **Preview**。 你应该能够访问在 `http://localhost:4000` 上本地运行的文档网站。 ### 手动环境 也可以设置一个更传统的开发环境。 #### 安装依赖项 要在本地测试更改,你需要 Ruby 及其依赖项(称为 gems)。 1. Fork 并克隆 home-assistant.io 的 [git 仓库](https://github.com/home-assistant/home-assistant.io)。 2. 在本地 `home-assistant.io` 目录中,安装 Ruby。当前所需的版本请查看 [.ruby-version](https://github.com/home-assistant/home-assistant.io/blob/current/.ruby-version)。 3. 为你的操作系统安装 Ruby 和 Bundler。 * Fedora: ```shell sudo dnf -y install \ gcc-c++ ruby ruby-devel rubygem-bundler rubygem-json rubygem-rake bundle ``` * Debian/Ubuntu: ```shell sudo apt-get install \ ruby ruby-dev ruby-bundler ruby-json g++ zlib1g-dev bundle ``` * macOS,如果捆绑的 Ruby 不起作用: ```shell RUBY_FORMULA="ruby@$(cut -d . -f 1,2 .ruby-version)" brew install "$RUBY_FORMULA" export PATH="$(brew --prefix "$RUBY_FORMULA")/bin:$PATH" ``` 4. 如果在上一步中尚未安装 gems,请在 `home-assistant.io` 目录中运行 `bundle`。 ##### 可选:使用 mise-en-place 安装 Ruby 如果你使用 [mise-en-place](https://mise.jdx.dev/) 管理 Ruby,请使用 `mise` 代替主流程中的第 3 步。 在 Fedora 上,首先安装 `mise` 安装 Ruby 所需的包: ```shell sudo dnf -y install \ gcc-c++ make perl-FindBin openssl-devel readline-devel \ zlib-ng-compat-devel libyaml-devel gmp-devel ``` 信任仓库配置,以便 `mise` 从 `.ruby-version` 读取所需版本: ```shell mise trust mise install ruby gem install bundler bundle ``` #### 在本地预览网站 1. 生成第一次预览: ```shell bundle exec rake generate ``` 这可能需要一分钟的时间。 2. 创建、编辑或更新页面。集成文档位于 `source/_integrations/` 中。Home Assistant 文档位于 `source/_docs/` 中。 3. 启动本地预览: ```shell bundle exec rake preview ``` 4. 在浏览器中打开 。在预览运行期间,文件更改会被自动检测,受影响的页面会重新构建。在浏览器中刷新页面即可查看更新。 5. 准备提交 PR 时,请按照[文档 PR 审查流程](#documentation-pull-request-review-process)操作。 #### 在无头机器上预览网站 通过 `bundle exec rake` 生成的站点只能本地访问。如果你在无头机器上进行开发,请使用端口转发: ```shell ssh -L 4000:localhost:4000 user_on_headless_machine@ip_of_headless_machine ``` --- url: /developers/documenting/create-page.md --- 要创建新的集成页面,请按照以下步骤操作: 1. 文档仓库有两个主要分支:`current` 和 `next`: * 如果正在为即将添加到代码中的新集成编写文档,切换到 `next` 分支。 2. 复制[integration documentation template](https://github.com/home-assistant/home-assistant.io/tree/current/source/_integrations/_integration_docs_template.markdown)并进行编辑。 3. 确保集成页面的文件名与集成的 domain 名称匹配。 * [Integration overview](https://www.home-assistant.io/integrations/)和[Examples section](https://www.home-assistant.io/cookbook/)是自动生成的,因此无需向这些页面添加链接。 4. 确保遵循我们的文档[标准](documenting/standards.md),包括: * [General style guide](/developers/documenting/general-style-guide.md) * [YAML Style Guide](/developers/documenting/yaml-style-guide.md) * [Documentation structure and example text](/developers/documenting/integration-docs-examples.md) 5. 确保为 brands 仓库添加[icon 和 logo](#images-icons-and-logos)。 * 如果你的集成原本是 custom integration(HACS),现在变为 core integration,将 brand 文件移入 `core_integrations` 文件夹。 * 在 PR 模板中,添加指向该 brands PR 的链接。 6. 在[codeowners file](https://github.com/home-assistant/home-assistant.io/blob/next/CODEOWNERS)中添加集成和 codeowners。 7. 如有需要,记录获取第三方服务或设备 API keys 或 access token 所需的步骤。 8. 确保文档不引用 custom integrations。步骤和示例(包括 automation 示例)不应依赖于 custom cards 或 custom integrations。 9. 当你知道有多种设备时,添加已测试的设备类型(包括 firmware)。 10. 添加 blueprints 时,将其上传到 [`https://github.com/home-assistant/home-assistant.io/tree/current/source/blueprints/integrations`](https://github.com/home-assistant/home-assistant.io/tree/current/source/blueprints/integrations) 下的 blueprints 文件夹,或上传到[forums 上的 blueprint exchange](https://community.home-assistant.io/c/blueprints-exchange)。在集成页面中,添加指向 blueprint exchange 的链接。 11. 在将 PR 标记为 **Ready for review** 之前,删除注释。 ## 关于集成页面标题格式 每个集成页面都以一个 YAML front matter 头部开始,提供关于集成的元数据。这些元数据驱动集成概览页面、discovery、quality badges 等。包含的 key 取决于集成的功能。 ```text --- title: "Awesome Sensor" description: "home-assistant.io web presence" ha_release: 2026.6 ha_category: Sensor ha_platforms: - sensor ha_iot_class: "Local Polling" ha_quality_scale: silver ha_config_flow: true ha_codeowners: - '@balloob' ha_domain: awesome ha_integration_type: hub related: - docs: /voice_control/s3_box_voice_assistant/ title: Creating a ESP32-S3-BOX-3 voice assistant - url: https://esphome.io/projects/index.html title: ESPHome projects website --- Content... Written in markdown. ### 标题头 ... ``` 以下 key 可用于集成页面文件头部: * `description`:集成页面的简短描述。 * `featured`:设为 `true` 可在集成分页中突出显示该集成。这不是 `ha_` 前缀的 key。不要使用。 * `ha_bluetooth`:如果集成支持通过 Bluetooth 发现,则设为 `true`,否则省略。 * `ha_brand`:如果页面代表[品牌](/developers/creating_integration_brand.md)而非真正的集成,则设为 `true`,否则省略。品牌将同一制造商的多个集成或产品归在一个名称下,方便用户查找。它与[virtual integration](/developers/creating_integration_manifest.md#virtual-integration)不同。例如,`google` 品牌页面将 `google` 和 `google_sheets` 集成归为一组,`inovelli` 品牌页面则指向其设备使用的 Zigbee 和 Z-Wave IoT 标准。常规集成页面请省略此 key。 * `ha_category`:此条目用于在[Integration overview](https://www.home-assistant.io/integrations/)中对集成进行分组。 * `ha_codeowners`:负责该集成的 GitHub 用户名或团队名称(以 `@` 开头)。应与集成 manifest 文件中列出的 codeowners 匹配。 * `ha_config_flow`:如果集成有[Data Entry Flow](/developers/data_entry_flow_index.md),则设为 `true`,否则省略。 * `ha_dhcp`:如果集成支持通过 DHCP 发现,则设为 `true`,否则省略。 * `ha_domain`:集成在 Home Assistant Core 中的 domain。必须与[integration manifest](/developers/creating_integration_manifest.md)文件中的名称匹配。 * `ha_homekit`:如果集成支持通过 HomeKit 发现,则设为 `true`,否则省略。 * `ha_integration_type`:集成在 Home Assistant Core 中的类型。必须与[integration manifest](/developers/creating_integration_manifest.md)文件中的名称匹配。 * `ha_iot_class`:[IoT class](https://www.home-assistant.io/blog/2016/02/12/classifying-the-internet-of-things)是对设备行为的分类器。 * `ha_iot_standard`:仅用于"IoT standards"类型的[virtual integration](/developers/creating_integration_manifest.md#virtual-integration)。产品用于连接性的 IoT 标准。必须与 virtual integration 的[manifest](/developers/creating_integration_manifest.md)文件中的 `iot_standards` 值匹配。它用于指导你使用相应标准添加设备。可以列出以下一个或多个标准: * `homekit`:产品通过 HomeKit 连接。 * `zigbee`:产品通过 Zigbee 连接。 * `zwave`:产品通过 Z-Wave 连接。 * `ha_mqtt`:如果集成支持通过 MQTT 发现,则设为 `true`,否则省略。 * `ha_platforms`:此条目列出所有实现的[platforms](/developers/creating_platform_index.md)。 * `ha_quality_scale`:集成在[quality scale](https://www.home-assistant.io/docs/quality_scale/)上的评级(如 bronze、silver、gold、platinum 或 internal)。对于新集成,请设为 `bronze`。此字段在从 Core 代码库进行文档同步期间更新。通常无需手动更新文档。 * `ha_release`:集成被包含时的 Home Assistant 版本。 * 如果当前版本是 2025.8,则将 `ha_release` 设为 2025.9。 * 对于 10 月版本,即 '2025.10',需要用引号引起来,否则前导零不会显示。 * `ha_ssdp`:如果集成支持通过 SSDP 发现,则设为 `true`,否则省略。 * `ha_supporting_domain`:仅用于"supported by"类型的[virtual integration](/developers/creating_integration_manifest.md#virtual-integration)。为此产品提供实际实现的集成的 domain。必须与 virtual integration 的[manifest](/developers/creating_integration_manifest.md)文件中的 `supported_by` 值匹配。例如,`dacia` virtual integration 将 `ha_supporting_domain` 设为 `renault`,因为它由 Renault 集成实现。 * `ha_supporting_integration`:仅用于"supported by"类型的[virtual integration](/developers/creating_integration_manifest.md#virtual-integration)。`ha_supporting_domain` 中引用的 supporting integration 的人类可读名称(例如 `Renault`)。用于生成的 stub 页面中,告知你使用哪个集成。 * `ha_zeroconf`:如果集成支持通过 mDNS/Zeroconf 发现,则设为 `true`,否则省略。 * `related`:可选。在页面末尾添加一个包含相关主题链接的部分。本地链接使用 `docs`,外部链接使用 `url`。使用 `docs` 时,`title` key 是可选的。如果不设置,将使用你所指向页面的标题。 * `title`:此标题应与集成 manifest 文件中编写的集成名称匹配。 * `works_with`:不要使用。通常此 key 由维护者添加。一个值列表,表示品牌或产品是 [Works with Home Assistant](https://works-with.home-assistant.io/) 合作伙伴计划的一部分。添加此 key 会显示 "Works with Home Assistant" 徽章,并在页面中生成特定于计划的文本。每个条目代表产品获得认证的连接方式。以下值被识别: * `zwave`:产品通过 Z-Wave 连接。渲染为 "Z-Wave",并添加 Z-Wave onboarding 文本和徽章。 * `zigbee`:产品通过 Zigbee 连接。渲染为 "Zigbee",并添加 Zigbee onboarding 文本和徽章。 * `matter`:产品通过 Matter 连接。渲染为 "Matter",并添加 Matter onboarding 文本和徽章。 * `bluetooth`:产品通过 Bluetooth 连接。 * `local`:产品在本地集成(例如通过本地网络)。 * 任何其他值将在生成的文本中原样使用(首字母大写)。 * 当产品获得多种连接方式认证时,可以列出多个值(例如同时列出 `zigbee` 和 `matter`)。 ### 配置 每个集成页面都应包含配置示例。对于有 config flow 的集成,这包括 UI 变量描述;对于尚不支持 config flow 的集成,则包括 YAML 配置。 ### UI 变量 * 描述**UI 变量**时使用 `{% configuration_basic %}` section。 * `{% configuration_basic %}` block 与 `{% configuration %}` block 类似,但没有 `required` 或 `type` 字段。 ### 关于配置变量 * **Configuration variables** section 仅用于 YAML 配置。 * **Configuration variables** section 必须使用 `{% configuration %}` tag。 * 配置变量必须记录默认值(如果有)。 * 配置变量必须记录该变量是否必需(`false` 或 `true`)。如果变量有默认值,则它不是必需的,`required` 字段应设为 `false`。 * 配置变量必须记录接受的值类型(见[configuration variables details](#configuration))。 * 对于接受多种类型的配置变量,用逗号分隔类型(即 `string, integer`)。 ### 示例配置变量 block ```yaml {% configuration %} some_key: description: This is a description of what this key is for. required: false type: string default: Optional default value - leave out if there isn't one {% endconfiguration %} ``` ```text {% configuration %} api_key: description: The API key to access the service. required: true type: string name: description: Name to use in the frontend. required: false default: The default name to use in the frontend. type: string monitored_conditions: description: Conditions to display in the frontend. required: true type: map keys: weather: description: A human-readable text summary. temperature: description: The current temperature. {% endconfiguration %} ``` 可用的 key: * **`description:`**:该变量的用途说明。 * **`required:`**:该变量是否必需。 ```text required: true #=> Required required: false #=> Optional required: inclusive #=> Inclusive required: exclusive #=> Exclusive required: any string here #=> Any string here ``` * **`type:`**:变量的类型。允许的值:`action`、`boolean`、`string`、`integer`、`float`、`time`、`template`、`device_class`、`icon`、`map`/`list`(用于条目列表)、`date`、`datetime`、`timedelta`、`selector` 和 `any`。对于多种可能性,使用 `[string, integer]`。如果使用 `map`/`list`,则应定义 `keys:`(参见 [`template` sensor](https://www.home-assistant.io/integrations/sensor.template/) 作为示例)。如果使用 `boolean`,则必须定义 `default:`。 ### 嵌入代码 可以使用[默认 markdown 语法](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#code)生成语法高亮的代码。对于 inline code,用反引号包裹代码。 编写将在终端上执行的代码时,不要以 `$` 为前缀,因为这样会使复制粘贴命令变得困难。不过,当需要区分输入的命令和命令输出时除外。在这些情况下,必须用 `$` 为命令加前缀。 ### 模板 [configuration templating](https://www.home-assistant.io/docs/configuration/templating/) 使用 [Jinja](http://jinja.pocoo.org/)。更多详情,请参阅[文档标准](documenting/standards.md)。 如果不转义 templates,它们将被渲染并在网站上显示为空白。 ### HTML 支持直接使用 HTML,但不推荐。Note boxes 是一个例外。 ```html
You need to enable telnet on your router.
``` 请注意,如果想在 HTML block 内使用 Markdown,它必须前后各有一个空行。 ```html
You need to enable [**telnet**](https://en.wikipedia.org/wiki/Telnet) on your router.
``` ### 图像、图标和标志 为集成添加 logo 可以让最终用户快速识别该集成。 从文档的角度来看,无需特定配置即可启用 logo 的使用,但 logo 必须存在于我们的 Brands 仓库中。 * 要为集成添加 logo 和 icon,请在 [Home Assistant Brands](https://github.com/home-assistant/brands) 仓库中提交 pull request。 * 要添加其他图片(显示在集成页面或任何其他文档页面上),请根据用途将图片存储在相应目录中: | Type | Location | | :---------- | :------------------------ | | blog | source/images/blog | | screenshots | source/images/integrations/your-integration | ### 从侧边栏链接 如果要添加需要从侧边栏链接的新页面,请编辑: * [`docs_navigation.html`](https://github.com/home-assistant/home-assistant.io/blob/current/source/_includes/asides/docs_navigation.html) * [`docs_sitemap.html`](https://github.com/home-assistant/home-assistant.io/blob/current/source/_includes/asides/docs_sitemap.html) --- url: /developers/documenting/general-style-guide.md --- Home Assistant 的文档使用 Markdown 编写,遵循 [GitHub Flavored Markdown specification](https://github.github.com/gfm/)。 总体而言,文档应遵循 [Microsoft Style Guide](https://learn.microsoft.com/style-guide/welcome/)。需要更多细节时,参考 [Merriam-Webster Dictionary](https://www.merriam-webster.com/)。Microsoft Style Guide 本身也使用 Merriam-Webster。本页汇总了我们额外遵循的一些更具体的指导原则。 ## 语言与语气 * 文档使用美式英语。 * 在包含三个或更多项的列表中,连词前使用序列逗号(又称 Oxford comma)。例如:"Through the use of additional adapters, Home Assistant allows the use of Zigbee, Z-Wave, and other protocols"。 * 遵循语法和句法规则。例如,句末加句号。 * 避免过度使用 em dash(AI 生成的内容常出现)。如使用 em dash,请遵循 [Merriam-Webster style](https://www.merriam-webster.com/grammar/em-dash-en-dash-how-to-use),em dash 两侧不留空格。 * 一般来说,可考虑将句子拆分为较短的句子。 * 如果 em dash 用于引入列表,改用冒号。 * 如果用于插入语,可考虑改用括号。 * 保持客观,不偏袒任何性别,不引起分裂,不涉及种族或宗教不当内容。不符合此要求的贡献可能违反我们的 [Code of Conduct](https://github.com/home-assistant/core/blob/master/CODE_OF_CONDUCT.md)。 * 不要使用 "e.g."。改用 *for example*、*such as* 或 *like*。 * [不要使用 "master/slave"](https://learn.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/m/master-slave)。改用 "client/server"、"leader/follower"、"main/replica" 或 "controller/device" 等替代词。 * 品牌名、服务名、协议名、集成名和平台名的大小写必须与其官方对应。例如,"Z-Wave",*不是* "Zwave"、"Z-wave"、"Z Wave" 或 "ZWave"。同样,"Input Select",*不是* "input select" 或 "Input select"。 ## 格式基础 以下是最常见的格式问题: * 不限制行长度。采用流畅的段落式写法。 * 句号后不要加两个空格。 ## 标题 页面中的第一个标题是其页面标题,在页面顶部的 front matter 中定义: ```markdown --- title: "Documentation style guide" --- ``` 使用 Markdown 的 2 至 6 级标题: ```markdown ## 标题级别 2 ### 标题级别 3 #### 标题级别 4 ##### 标题级别 5 ###### 标题级别 6 ``` 使用 [sentence-style capitalization](https://learn.microsoft.com/en-us/style-guide/capitalization)。 不要跳过标题级别。 右侧目录中只显示 2 级和 3 级标题。 ## 强调 要强调某个词,使用斜体。 用下划线(`_`)表示斜体,例如:`_emphasized words_`。不要用星号(`*`)。 不要使用全大写表示强调。 ## UI 元素与操作步骤 引用 UI 元素时使用粗体。 用双星号(`**`)表示粗体,例如:`**bolded words**`。 书写 UI 步骤时,在面包屑导航中使用大于号(`>`)。 不要加粗。 例如: ```markdown 1. Under **Settings**, select the three dots menu. 2. Select **Restart Home Assistant** > **Quick reload**. ``` 另请参见:[My links](#my-links)。 ### 选择 UI 元素 避免使用 "click" 这个动词。它仅适用于鼠标操作。改用适用于多种设备的动词,如 "select"。 描述具体鼠标动作时,可以使用 "click"。例如 "right-click" 或 "double-click"。 ## 文件路径、文件名、变量与文本输入 引用文件路径、文件名、变量名或在字段中输入的文本时使用反引号。 例如: * `/boot/config.txt` 文件 * `this` 变量 * 输入 `/newbot` ## 列表 * 无序列表使用 `-`,不要用 `*`。 * 有序列表使用递增数字。 ```yaml # Good 1. List item 1. 2. List item 2. 3. List item 3. # Bad 1. List item 1. 1. List item 2. 1. List item 3. ``` ## 代码块 使用 Markdown 代码块,以三个反引号分隔: ````markdown ```markdown 1. Under **Settings**, select... ``` ```` 要在代码块中嵌套代码块(如上面的示例),外部代码块使用四个或更多反引号: `````markdown In general, use Markdown code blocks, delimited by three backticks: ````markdown ```markdown 1. Under **Settings**, select... ``` ```` ````` 在开引号后,可以指定用于语法高亮的语言,例如: * `markdown` * `shell` * `yaml` 所有支持的语言见 [list of Rouge lexers](https://github.com/rouge-ruby/rouge/wiki/list-of-supported-languages-and-lexers)。 ## 表格 * 避免使用表格。改用列表。如无法避免表格,尽量减少列数,并将文本内容尽可能缩短: * 过宽的表格在手持设备上难以浏览。 * 内容更少使表格更易读。 * 如果表格只有两列,它很可能应该是一个列表。 * 当无法限制文本量时,考虑使用其他数据结构来表示信息。例如,可以使用列表或 `{% configuration_basic %}`。 ## 链接 * 不要使用文件的扩展名(`.markdown`、`.md`、`.mdx`),改用斜杠。 例如:`[ZBT-2](/connect/zbt-2/)` 而不是 `[ZBT-2](/connect/zbt-2.markdown)`。 * 链接到同一仓库中的页面时: * 使用绝对链接,但忽略 `source` 目录。 * 忽略第一级目录前的下划线(`_`)。 例如,要链接到 `source/_integrations/date.markdown`,使用:`[Date](/integrations/date/)`。 * 不要使用联盟链接或追踪链接。 * 不要使用裸 URL:`https://example.org` 或 ``。 ### 图片 如果使用图片,请上传到文档仓库中的 `images` 文件夹及其相关子文件夹。 不要链接到外部图片,例如你自己的私人 GitHub 仓库中的图片。 对于截图,使用 Markdown 语法: ```markdown ![descriptive alt text](/images/my_image.png) ``` 也可以使用 HTML: * 在文档以深色模式查看时反转图片颜色,请使用带 `invertDark` class 的 HTML。 * 要添加说明文字,将其放入 `

` 标签中。 例如: ```html

Styling of a glossary term tooltip 词表术语 tooltip 的样式

``` 添加集成时关于图片的内容,请参见 [Images, icons, and logos](/developers/documenting/create-page.md#images-icons-and-logos)。 #### 灯箱 当文档页面和博客文章中的图片足够大,且不是链接、按钮、SVG、内联图标、品牌 logo 或被标记为排除时,可以点击并在 lightbox 中打开。 若要防止图片在 lightbox 中打开,请在 `` 标签或其父元素上添加 `data-no-lightbox` 属性或 `no-lightbox` class。 例如: ```html Description of the image ``` ```html Description of the image ``` ### 视频 使用以下语法引用 YouTube 上的视频。 使用 `videoStartAt` 可在视频的特定时间开始播放。

YouTube video starting at a specified time 在指定时间开始的 YouTube 视频

`videoid` 使用 YouTube URL 中 `watch?v=` 之后的部分。 ```html ``` ## 可复用文本 对于某些主题,有预定义的文本元素可供复用。 要引入 [`source/_includes`](https://github.com/home-assistant/home-assistant.io/tree/current/source/_includes) 中的片段,使用以下 Liquid 语法: ```liquid {% include path/to/file.md %} ``` 关于编写集成文档时有用的示例,请参见 [Configuration](/developers/documenting/create-page.md#configuration)。 ## Liquid 语法 我们在 Markdown 中使用 [Liquid](https://shopify.github.io/liquid/) 语法进行模板渲染。 ### 我的链接 要指示 UI 中的位置,请使用 [My link](https://www.home-assistant.io/docs/tools/quick-search/#my-links)。 选择 My link 会在用户自己的 Home Assistant 安装中打开对应页面。

Styling of My links Styling of My links

例如: ```markdown 1. Go to {% my integrations title="**Settings** > **Devices & services**" %} and select your integration. ``` ```markdown - {% my areas title="**Settings** > **Areas, labels & zones**" %} - {% my automations title="**Settings** > **Automations & scenes**" %} - {% my backup title="**Settings** > **System** > **Backups**" %} - {% my general title="**Settings** > **System** > **General**" %} - {% my logs title="**Settings** > **System** > **Logs**" %} - {% my network title="**Settings** > **System** > **Network**" %} - {% my profile title="**User profile**" %} ``` 要在 Home Assistant 中识别 My link,打开感兴趣的页面并按 `m` 键。 ### 术语表引用 一些 Home Assistant 的术语和概念在 [the glossary](https://www.home-assistant.io/docs/glossary/) 中有解释。 如果添加了术语定义的引用,术语定义将作为 tooltip 显示。

Styling of a glossary term tooltip 词表术语 tooltip 的样式

语法: ```markdown {% term [] %} ``` 使用示例: ```markdown {% term integration %} {% term entity %} {% term "configuration.yaml" %} {% term "Home Assistant Operating System" %} ``` 关于 glossary 用法的更多推荐信息,请参见 [Glossary & terminology tooltips](/developers/documenting/standards.md#glossary--terminology-tooltips)。 ### 缩写和缩略语 如果可能,尽量避免使用缩写和首字母缩略词。 如需使用,可以添加缩写标签,将全称作为 tooltip 显示。

Styling of an abbreviation tooltip 缩写 tooltip 的样式

示例: ```markdown A/V, CT, DSMR, eMMC, FLV, LLMs, MCP, PTZ, RTMP, RTSP, or USB-OTG. ``` ### 内联图标 要引用 UI 中的图标,可以使用来自 [Iconify library](https://icon-sets.iconify.design/mdi/) 的图标。

Some inline icons 一些内联图标

使用示例: ```markdown - Three dots menu: {% icon "mdi:dots-vertical" %} - Hamburger menu: {% icon "mdi:menu" %} - Edit: {% icon "mdi:edit" %} - Revert {% icon "mdi:restore" %} - Eye: {% icon "mdi:eye" %} - Trash: {% icon "mdi:trash" %} - Cog: {% icon "mdi:cog" %} - Cog outline: {% icon "mdi:cog-outline" %} - Drag: {% icon "mdi:drag" %} - Move-cursor: {% icon "mdi:cursor-move" %} - Arrow left: {% icon "mdi:arrow-left-bold" %} - Arrow right: {% icon "mdi:arrow-right-bold" %} - Checkbox list: {% icon "mdi:order-checkbox-ascending" %} - Upload network: {% icon "mdi:upload-network" %} - Security network: {% icon "mdi:security-network" %} - Routes: {% icon "mdi:routes" %} ``` ### 可折叠文本块 使用 details 块使文本块可折叠。不要使用 HTML5 变体,而应使用我们的 Liquid 变体。

Behavior of a collapsible text block 可折叠文本块的行为

例如: ```markdown {% details "Generate Client ID and Client Secret" %} 1. Your Fitbit account must be registered as a Developer account at the [Fitbit Developer Portal](https://dev.fitbit.com), and have a verified email address. 2. Visit the [fitbit developer page](https://dev.fitbit.com/apps/new) to register an application. 3. Enter an **Application Name** of your choosing, for example **Home Assistant**. 4. ... {% enddetails %} ``` ### 文本框 使用文本框突出显示重要信息。 不要过度使用,因为它们可能会在视觉上使文档过载。

Example text boxes 文本框示例:

#### 提示 ```liquid {% tip %} 使用 tip 来突出推荐。 {% endtip %} ``` #### 备注 ```liquid {% note %} 使用 note 来突出一个章节。 {% endnote %} ``` #### 重要 ```liquid {% important %} 使用 "important" 来突出你认为非常重要的章节。 {% endimportant %} ``` #### 注意 ```liquid {% caution %} 使用 "caution" 来建议不要执行可能导致数据丢失、意外行为或其他难以撤销后果的操作。 {% endcaution %} ``` #### 警告 ```liquid {% warning %} 使用 warning 来提醒用户注意可能危及系统安全性或完整性,或造成人身伤害的风险。 {% endwarning %} ``` #### 实验功能 在文档化 Labs 中的功能时使用此文本框: ```liquid {% labs %} Requires the **Feature Name** Labs preview feature. Enable it at {% my labs title="**Settings** > **System** > **Labs**" %}. {% endlabs %} ``` #### YAML 示例 使用此文本框为某些元素提供交互式语法高亮。要查看下面的渲染效果,请参见 [Automation: sync a ceiling fan speed to the ceiling light](https://www.home-assistant.io/triggers/light.brightness_changed/#automation-sync-a-ceiling-fan-speed-to-the-ceiling-light)。 ```liquid {% example %} automation: | alias: "Match fan to ceiling light" triggers: - trigger: light.brightness_changed target: entity_id: light.living_room_ceiling options: threshold: 10 actions: - action: fan.set_percentage target: entity_id: fan.living_room data: percentage: "{{ state_attr('light.living_room_ceiling', 'brightness_pct') | int }}" {% endexample %} ``` 第一行的单词(此处为 `automation`)会渲染在代码块上方。 可用的单词(在 [`plugins/example.rb`](https://github.com/home-assistant/home-assistant.io/blob/current/plugins/example.rb) 的 `INPUT_TYPES` 中定义): * `action` * `automation` * `condition` * `script` * `template` * `trigger` 此外,还可以使用 `output` 渲染代码的结果。在文档化 template 时非常有用。例如: ```liquid {% example %} template: | {% from 'formatter.jinja' import format_entity %} {{ format_entity('sensor.outdoor_temperature') }} {{ format_entity('sensor.indoor_temperature') }} output: | Outdoor temperature: 22.5 Indoor temperature: 21.0 {% endexample %} ``` --- url: /developers/documenting/integration-docs-examples.md --- 本页展示集成页面的推荐结构和有用的可复用文本。 本页概述集成页面的高层级结构。请将此结构与以下文档配合使用: * [Documentation standards](/developers/documenting/standards.md) * [Documentation style guide](/developers/documenting/general-style-guide.md) * [Integration Quality Scale](/developers/core/integration-quality-scale.md) 的文档规则 ## 集成页面的基本结构 可以复制粘贴的模板,请参见 `home-assistant.io` 仓库中的集成文档模板:[/\_integrations/\_integration\_docs\_template.markdown](https://github.com/home-assistant/home-assistant.io/tree/current/source/_integrations/_integration_docs_template.markdown)。 集成页面遵循以下结构: * 介绍 * 用例 * 支持/不支持的设备 * 先决条件 * 配置 * 配置选项 * 支持的功能 * trigger 列表 * condition 列表 * action 列表 * 示例 * 数据更新 * 已知限制 * 故障排除 * 社区说明 * 移除集成 ## 文档化 automation triggers、conditions 和 actions 编写集成文档时,为集成中的每个 trigger、condition 和 action 创建单独的文件。然后在主集成页面中通过以下方式引入它们: ```liquid {% include integrations/triggers.md %} {% include integrations/conditions.md %} {% include integrations/actions.md %} ``` 如果集成同时包含这三种组件(trigger、condition 和 action),可以使用合并模板: ```liquid {% include integrations/triggers_conditions_actions.md %} ``` ### 在 UI 步骤中引用 automation triggers、conditions 和 actions 在 UI 步骤或 automation 示例中引用 automation trigger、condition 或 action 时,使用 UI 显示的名称。 对于不涉及特定品牌、产品或服务的通用或共享集成,不要添加集成 domain 作为前缀。这适用于 `fan`、`vacuum`、`media_player` 和 `climate` 等集成。 * Bad:`**Action**: Fan: Turn on fan` * Good:`**Action**: Turn on fan` 对于涉及特定品牌、产品或服务的集成,在 trigger、condition 或 action 名称前加上集成名称。这有助于读者区分集成特有的项目与名称相同的通用或共享项目。 * Good:`**Action**: Jellyfin: Play media` ### 模板:trigger 在 `home-assistant.io` 仓库的 `source/_triggers` 中创建文件。 保存为 `..markdown`,例如:`light.brightness_changed.markdown`。 根据你的集成调整此模板: ```md --- title: "Light brightness changed" trigger: light.brightness_changed domain: light description: "Triggers after the brightness of one or more lights changes." related_triggers: - light.brightness_crossed_threshold - light.turned_on --- The **Light brightness changed** trigger fires after... Use it to... {% include triggers/ui_header.md %} To use this trigger in an automation: 1. Go to {% my automations title="**Settings** > **Automations & scenes**" %}. 2. Open an existing automation, or select **Create automation** > **Create new automation**. 3. In the **When** section, select **Add trigger**. 4. From the search box, search for and select **Light brightness changed**. 5. Select what you want to monitor. Under **By target** (see [Targets](#targets)), pick... You can also select a floor, a device, a specific entity, or a label. 6. From the triggers shown for that target, select... 7. Under **Trigger when** (see [Behavior](#behavior-with-multiple-targets)), pick **Any**, **First**, or **Last** to control how multiple targets interact. 8. Under **Threshold type**, set how much the level has to change before the trigger fires. 9. Under **Another field**, set... 10. Select **Save**. ### UI 中的选项 {% options_ui %} Threshold type: description: How much the brightness has to change before the trigger fires, as a percentage of full brightness. Can be a fixed number, or reference a helper entity that provides the value. required: false {% endoptions_ui %} {% include triggers/yaml_header.md %} In YAML, refer to this trigger as `light.brightness_changed`. A basic example looks like this: {% example %} trigger: | trigger: light.brightness_changed target: entity_id: light.living_room options: threshold: 10 behavior: description: > 当针对多个传感器时,控制触发何时触发。接受 `any`、`first` 或 `last`。 required: false type: string default: any {% endexample %} 这会在客厅灯光亮度变化至少百分之十时触发。 ### YAML 中的选项 YAML 有时提供一些通过 UI 无法获得的、用于更复杂用例的额外选项。 {% options_yaml %} threshold: description: > 亮度在触发前必须变化的最小量(以百分比为单位)。接受一个数字,或对带百分比单位的 `input_number`、`number` 或 `sensor` entity 的引用。 required: true type: any {% endoptions_yaml %} {% include triggers/targets.md %} {% include triggers/behavior.md %} ## 需要了解的信息 - 在此添加额外信息。 {% include triggers/try_it.md %} {% include triggers/more_examples.md %} ### 自动化:将吊扇速度与顶灯同步 When you dim the ceiling light down, slow the fan down too. 当你调低天花板灯光时,也降低风扇转速。这是一个经典的 "场景氛围" 自动化,保持房间协调一致。 - **Trigger**: Light brightness changed - **Target**: Living room ceiling light - **Threshold type**: 10 - **Action**: Set fan speed {% details "YAML example for a ceiling-light-linked fan" %} {% example %} automation: | alias: "Match fan to ceiling light" triggers: - trigger: light.brightness_changed target: entity_id: light.living_room_ceiling options: threshold: 10 actions: - action: fan.set_percentage target: entity_id: fan.living_room data: percentage: "{{ state_attr('light.living_room_ceiling', 'brightness_pct') | int }}" {% endexample %} {% enddetails %} {% include triggers/stuck.md %} {% include triggers/related.md %} ``` ### 模板:condition 在 `home-assistant.io` 仓库的 `source/_conditions` 中创建文件。 保存为 `..markdown`,例如:`light.is_on.markdown`。 根据你的集成调整此模板: ```md --- title: "Light is on" condition: light.is_on domain: light description: "Tests if one or more lights are on." related_conditions: - light.is_off - light.is_brightness --- The **Light is on** condition passes when... Use it to... {% include conditions/ui_header.md %} To use this condition in an automation: 1. Go to {% my automations title="**Settings** > **Automations & scenes**" %}. 2. Open an existing automation, or select **Create automation** > **Create new automation**. 3. In the **And if** section, select **Add condition**. 4. From the search box, search for and select **Light is on**. 5. Select what you want to check. Under **By target** (see [Targets](#targets)), pick the area your ... is in (like your living room or bedroom). You can also select a floor, a device, a specific entity, or a label. 6. Under **Condition passes if** (see [Behavior](#behavior-with-multiple-targets)), pick **Any** or **All**. 7. Select **Save**. ### UI 中的选项 {% options_ui %} Condition passes if: description: When multiple lights are targeted, controls how results combine. Pick **Any** to pass if at least one targeted light is on, or **All** to pass only when every targeted light is on. {% endoptions_ui %} {% include conditions/yaml_header.md %} In YAML, refer to this condition as `light.is_on`. A basic example looks like this: {% example %} condition: | condition: light.is_on target: entity_id: light.living_room {% endexample %} 当客厅灯光当前为开启状态时通过。 ### YAML 中的选项 YAML 有时提供一些通过 UI 无法获得的、用于更复杂用例的额外选项。 {% options_yaml %} behavior: description: > 当针对多个灯时,控制结果如何合并。接受 `all` 或 `any`。 required: false type: string default: any {% endoptions_yaml %} {% include conditions/targets.md %} {% include conditions/behavior.md %} ## 需要了解的信息 - 在此添加额外信息。 {% include conditions/try_it.md %} {% include conditions/more_examples.md %} ### 自动化:仅在客厅有灯光时播报门铃 当门铃响起时,仅当客厅灯已开启时才通过客厅音箱播报。当房间无人时保持房子安静。 - **Trigger**: State: Doorbell button pressed - **Condition**: Light is on - **Target**: Living room light - **Condition passes if**: Any - **Action**: Play media {% details "YAML example for a doorbell announcement gated on lights" %} {% example %} automation: | alias: "Doorbell announce when living room lit" triggers: - trigger: state entity_id: binary_sensor.doorbell to: "on" conditions: - condition: light.is_on target: entity_id: light.living_room options: behavior: any actions: - action: media_player.play_media target: entity_id: media_player.living_room data: media_content_id: "media-source://tts/cloud?message=Someone+is+at+the+door" media_content_type: music announce: true {% endexample %} {% enddetails %} {% include conditions/stuck.md %} {% include conditions/related.md %} ``` ### 模板:action 在 `home-assistant.io` 仓库的 `source/_actions` 中创建文件。 保存为 `..markdown`,例如:`light.turn_on.markdown`。 根据你的集成调整此模板: ```md --- title: "Turn on a light" action: light.turn_on domain: light description: "Turn a light on. Optionally set brightness, color, color temperature, an effect, or a transition." since: "0.7" related_actions: - light.turn_off - light.toggle --- The **Turn on a light** action turns a light on... This action works with any light {% term entity %} in Home Assistant... If the light is already on, calling the action... {% include actions/ui_header.md %} To turn a light on from an automation or a script: 1. Go to {% my automations title="**Settings** > **Automations & scenes**" %}. 2. Open an existing automation or script, or select **Create automation** > **Create new automation**. 3. If you're setting up a new automation, add a trigger in the **When** section. Scripts don't need a trigger. They run when something else calls them. 4. In the **Then do** section, select **Add action**. 5. From the search box, search for and select **Turn on light**. 6. Select what you want to control. Under **By target** (see [Targets](#targets)), pick the area your ... is in (like your hallway or entryway). You can also select a floor, a device, a specific entity, or a label. 7. Select **Save**. ### UI 中的选项 {% options_ui %} Transition: description: How long, in seconds, it takes to get to the next state. Use this for a smooth fade instead of switching instantly. {% endoptions_ui %} {% include actions/yaml_header.md %} In YAML, refer to this action as `light.turn_on`. A basic example looks like this: {% example %} action: | action: light.turn_on target: entity_id: light.kitchen {% endexample %} 以之前的亮度和颜色开启 `light.kitchen`。 ### YAML 中的选项 YAML 有时提供一些通过 UI 无法获得的、用于更复杂用例的额外选项。 {% options_yaml %} transition: description: > 到达下一个状态所需的时间,以秒为单位。使用此选项可以平滑淡入淡出,而不是瞬间切换。 required: false type: integer {% endoptions_yaml %} {% include actions/targets.md %} ## 需要了解的信息 - 在此添加额外信息。 {% include actions/try_it.md %} {% include actions/more_examples.md %} ### 自动化:设置舒适的暖白光 When you start winding down in the evening, dim the kitchen light to a warm white tone. 当你在傍晚开始放松时,将厨房灯光调至温暖的白光。 - **Action**: Turn on light - **Target**: Kitchen light - **Brightness percentage**: 80 - **Color**: warm_white {% details "YAML example for a cozy warm white scene" %} {% example %} action: | action: light.turn_on target: entity_id: light.kitchen data: brightness_pct: 80 color_name: warm_white {% endexample %} {% enddetails %} {% include actions/stuck.md %} {% include actions/related.md %} ``` ## 集成可复用文本 你可以[复用文本](/developers/documenting/general-style-guide.md#reusable-text),即跨多个页面重复出现的内容。 以下片段对集成页面很有用。 ### 配置

Screenshot showing predefined configuration text block 截图显示预定义的配置文本块

要使用此元素,添加以下行: ```markdown {% include integrations/config_flow.md %} ``` 查看当前片段内容,请参见 [`config_flow.md`](https://github.com/home-assistant/home-assistant.io/blob/current/source/_includes/integrations/config_flow.md)。 ### Configuration\_basic 块 如果集成通过 config flow 设置,使用 `configuration_basic` block 来描述配置选项。

Screenshot showing a configuration variable block for integrations that are set up in the UI 截图显示为在 UI 中设置的集成准备的配置变量块

```markdown {% configuration_basic %} Host: description: "The IP address of your bridge. You can find it in your router or in the Integration app under **Bridge Settings** > **Local API**." Local access token: description: "The local access token for your bridge. You can find it in the Integration app under **Bridge Settings** > **Local API**." {% endconfiguration_basic %} ``` ### 面向 YAML 集成的 Configuration block 如果集成仅通过 YAML 设置,使用 `configuration` block 来描述配置选项。

Screenshot showing a configuration variable block for YAML integrations 截图显示为 YAML 集成准备的配置变量块

```markdown {% configuration %} Host: description: "The IP address of your bridge. You can find it in your router or in the Integration app under **Bridge Settings** > **Local API**." required: false type: string Local access token: description: "The local access token for your bridge. You can find it in the Integration app under **Bridge Settings** > **Local API**." required: false type: string {% endconfiguration %} ``` --- url: /developers/documenting/remove-page.md --- 如果删除了集成,也应删除相关的集成文档。 1. 删除相关的[集成文档页面](https://github.com/home-assistant/home-assistant.io/tree/current/source/_integrations)及其相关的[triggers](https://github.com/home-assistant/home-assistant.io/tree/current/source/_triggers)、[conditions](https://github.com/home-assistant/home-assistant.io/tree/current/source/_conditions)和[actions](https://github.com/home-assistant/home-assistant.io/tree/current/source/_actions)(如适用)。 2. 从[Brands 仓库](https://github.com/home-assistant/brands)中删除相关的 logos 和 icons。 3. 从[`codeowners` file](https://github.com/home-assistant/home-assistant.io/blob/current/CODEOWNERS)中删除该条目,如[此 PR](https://github.com/home-assistant/home-assistant.io/pull/41531/files#diff-fcf14c4b7b34fe7a11916195871ae66a59be87a395f28db73e345ebdc828085bL268)所示。 4. 在[redirect file](https://github.com/home-assistant/home-assistant.io/blob/current/source/_redirects#L516)中的**Removed integrations** section 添加一个 `301` 条目。 --- url: /developers/documenting/standards.md --- 为了确保 Home Assistant 的文档对所有读者一致且易于遵循,我们要求你在编写文档时遵循一套严格的标准。 ## 样式指南 文档应遵循[文档 style guide](/developers/documenting/general-style-guide.md)和[Microsoft Style Guide](https://learn.microsoft.com/style-guide/welcome/)。 ## 集成与 platform 页面 * 除非明确说明,所有示例都应格式化为可包含在 `configuration.yaml` 中。 * 使用大写字母和 `_` 表示需要替换的值。例如,`api_key: YOUR_API_KEY` 或 `api_key: REPLACE_ME`。 * 集成和 platform 名称应链接到它们各自的文档页面。 ### Deprecated features 或 integrations 当功能被废弃或集成从 Home Assistant 中移除时,删除其文档。有关执行废弃本身的操作,请遵循[deprecating](/developers/deprecating.md)。 * 如果功能被废弃,从集成页面中删除相关 section。 * 不要在文档中添加废弃通知。 * 如果整个集成被废弃,请遵循[删除集成页面](/developers/documenting/remove-page.md)中的步骤。 ## YAML 和 Templates 对于 YAML 以及在 YAML 中使用 Jinja2 templates,请遵循[YAML Style Guide](/developers/documenting/yaml-style-guide.md)。 ## 术语表与术语提示 文档应以人人可理解的方式编写。为此,我们有一个在 Home Assistant 各处(包括文档)使用的[术语表](https://www.home-assistant.io/docs/glossary/)。 如果使用不在术语表中的术语,请随意添加;或改进现有术语的定义。 此外,我们提供了一个术语 tooltip,可以在文档的任何地方添加并使用。当用户将鼠标悬停在其上时,该 tooltip 会显示术语的定义,并附有更多信息的链接。它为用户提供即时上下文,帮助他们理解可能不熟悉的术语。 添加术语 tooltip 的语法为: ```liquid {% term [] %} ``` 所引用的术语必须列在我们的术语表中,该术语表是 tooltip 的来源。 例如,如果编写关于 automations 的文本,可以添加如下 tooltip: ```liquid This is an example text about {% term automations %}, which is used to demonstrate the use of tooltips, in this case, for the term "automations" earlier in this sentence. ``` `` 是可选的,当你想为与术语本身不同的文本添加术语 tooltip 时非常有用。在下面的示例中,automation 术语的 tooltip 被添加到 "automate everything" 文本上: ```liquid Awesome, because this allowed me to {% term automation "automate everything" %} in my home! I love it! ``` ### 添加 glossary 条目 要向术语表添加条目,请编辑 [`source/_data/glossary.yml`](https://github.com/home-assistant/home-assistant.io/blob/current/source/_data/glossary.yml)。 ## 重命名页面 有时集成或 platform 会被重命名,此时文档也需要相应更新。如果重命名页面,请按照下面所示在 `_redirects` 文件中添加条目。请在页面中添加详细说明,如版本号或旧的集成/platform 名称,放在[note](/developers/documenting/create-page.md#html)中。 ```text --- ... /getting-started/scripts /docs/scripts --- ``` 如果在[文档](https://www.home-assistant.io/docs/)中重新组织内容,同样需要添加 redirect。 --- url: /developers/documenting/testing.md --- Home Assistant 文档仓库使用 GitHub Actions 测试文档变更。 当前的 workflow 见 [`test.yml`](https://github.com/home-assistant/home-assistant.io/blob/current/.github/workflows/test.yml)。 该 workflow 运行两个 lint 任务: * **Lint Markdown** 使用 remark 检查 Markdown 结构和格式。 * **Lint Text** 使用 textlint 检查拼写、术语和措辞。 该 workflow 还会检查 `source/_integrations` 中的集成页面使用 `.markdown` 文件扩展名而非 `.md`。 ## 在本地运行测试 在 `home-assistant.io` 仓库中安装 Node.js 依赖: ```shell npm install ``` 然后运行与 CI 相同的命令: ```shell npm run markdown:lint npm run textlint ``` 这些命令定义在 [`package.json`](https://github.com/home-assistant/home-assistant.io/blob/current/package.json) 中。 ## Markdown 检查 Markdown 检查在 CI 中使用 [remark](https://remark.js.org/)。 `markdown:lint` 脚本运行: ```shell remark --quiet --frail . ``` remark 规则定义在 [`.remarkrc.js`](https://github.com/home-assistant/home-assistant.io/blob/current/.remarkrc.js) 中。 配置包括对代码块卫生、标题卫生、列表一致性和禁用字符串的检查。 remark 忽略的文件和目录列在 [`.remarkignore`](https://github.com/home-assistant/home-assistant.io/blob/current/.remarkignore) 中。 ### 添加 remark 规则 要添加 Markdown 规则: 1. 使用 `npm install --save-dev ` 安装 remark lint 规则包。这会更新 [`package.json`](https://github.com/home-assistant/home-assistant.io/blob/current/package.json) 和 [`package-lock.json`](https://github.com/home-assistant/home-assistant.io/blob/current/package-lock.json)。 2. 在 [`.remarkrc.js`](https://github.com/home-assistant/home-assistant.io/blob/current/.remarkrc.js) 中启用并配置该规则。 3. 运行 `npm run markdown:lint`。 4. 修复现有的违规项,或在 [`.remarkignore`](https://github.com/home-assistant/home-assistant.io/blob/current/.remarkignore) 中添加有充分理由的排除项。 ## 文本检查 文本检查使用 [textlint](https://textlint.github.io/)。 `textlint` 脚本检查选定的文档目录,包括: * `source/_docs` * `source/_faq` * `source/_integrations` * `source/_dashboards` * `source/cloud` * `source/getting-started` * `source/hassio` * `source/dashboards` textlint 规则定义在 [`.textlintrc.json`](https://github.com/home-assistant/home-assistant.io/blob/current/.textlintrc.json) 中。 当前配置使用: * `common-misspellings` 用于常见拼写错误。 * `terminology` 用于产品名称、推荐术语和措辞替换。 * `comments` 使贡献者可以在需要时禁用特定 section 的 textlint。 * `allowlist` 用于 textlint 应忽略的文本。 ### 添加术语条目 在 [`.textlintrc.json`](https://github.com/home-assistant/home-assistant.io/blob/current/.textlintrc.json) 中将术语条目添加到 `terminology` 规则的 `terms` 列表中。 对于必须保持拼写或大小写不变的接受术语,使用字符串: ```json "Home Assistant", "Z-Wave", "GitHub" ``` 对于标记一种拼写或短语并建议另一种的替换对,使用替换对: ```json ["addon", "add-on"], ["Github", "GitHub"], ["repo\\b", "repository"] ``` 替换对中的第一个值是 textlint 要匹配的 pattern。 第二个值是显示给贡献者的建议替换。 对 JSON 或正则表达式中具有特殊含义的字符进行转义。 将新条目放在相关现有条目附近。 更改术语后,在 `home-assistant.io` 仓库中运行 `npm run textlint`。 ### 内联禁用 textlint 对于误报,可以在受影响文本周围使用 HTML 注释禁用 textlint: ```html Text that textlint should ignore. ``` 要仅禁用一个规则,添加规则名称: ```html Text that textlint should ignore for this rule. ``` 内联禁用应尽可能范围狭窄。 textlint 注释前后各留一个空行,除非这样会破坏周围的 Markdown 结构。 不要将这些注释放在 [Liquid text boxes](/developers/documenting/general-style-guide.md#text-boxes) 内。 ### 添加 textlint 规则 要添加文本规则: 1. 在 [`package.json`](https://github.com/home-assistant/home-assistant.io/blob/current/package.json) 中添加 textlint 规则包,并更新 [`package-lock.json`](https://github.com/home-assistant/home-assistant.io/blob/current/package-lock.json)。 2. 在 [`.textlintrc.json`](https://github.com/home-assistant/home-assistant.io/blob/current/.textlintrc.json) 中启用并配置该规则。 3. 运行 `npm run textlint`。 4. 修复现有的违规项,或在 [`.textlintrc.json`](https://github.com/home-assistant/home-assistant.io/blob/current/.textlintrc.json) 的 `allowlist` section 中添加范围狭窄的排除项。 ## Markdownlint 配置 仓库中有一个 [`.markdownlint.json`](https://github.com/home-assistant/home-assistant.io/blob/current/.markdownlint.json) 文件。 该文件定义了 markdownlint 兼容的设置,例如禁用行长度规则和允许 inline HTML。 推荐的 VS Code 扩展在 [`.vscode/extensions.json`](https://github.com/home-assistant/home-assistant.io/blob/current/.vscode/extensions.json) 中包含了 markdownlint,因此贡献者可能会在编辑器中看到 markdownlint 警告。 Markdownlint 不会由当前的 GitHub Actions 测试 workflow 或 `package.json` 脚本运行。 如果添加或更改 markdownlint 规则,且该规则必须在 pull request 中强制执行,也请添加一个 script 和 CI step。 --- url: /developers/documenting/yaml-style-guide.md --- 除了我们的通用[文档标准](/developers/documenting/standards.md)外,我们还有一套针对 YAML 片段文档化的标准。本页描述的标准适用于项目中的所有基于 YAML 的代码,主要关注文档部分。 我们的 YAML 标准为最终用户提供一致的外观、最佳实践以及统一的 YAML 问题解决方式。 ## YAML 本节介绍基本的 YAML 用法,与 Home Assistant 无关。 ### 缩进 必须使用 2 个空格的缩进。 ```yaml # Good example: one: 1 # Bad example: bad: 2 ``` ### 布尔值 应避免在 YAML 中使用 truthy 布尔值。它们往往会让人困惑,尤其是对 YAML 新手。因此,我们只允许使用小写的 `true` 和 `false` 作为布尔值。 这也保持了与 YAML 1.2 规范的兼容性,因为该版本取消了对多个未加引号的 truthy 布尔值的支持(例如 `y`、`n`、`yes`、`no`、`on`、`off` 等)。 ```yaml # Good one: true two: false # Bad one: True two: on three: yes ``` ### 注释 在 YAML 块中添加注释,确实有助于读者更好地理解示例。 注释的缩进级别应与当前缩进级别一致。注释最好写在所描述行的上方,否则在较小显示屏上可能难以阅读。 注释应以大写字母开头,并在注释符 `#` 与注释内容之间加一个空格。 ```yaml # Good example: # Comment one: true # Acceptable, but prefer the above example: one: true # Comment # Bad example: # Comment one: false #Comment two: false # comment three: false ``` ### 序列 YAML 中的 sequences 也称为列表或数组。在 Home Assistant 世界中,我们在面向最终用户的文档中称它们为列表。这源于 Home Assistant core 开发所基于的 Python 语言。 Sequences 有两种书写风格:block style 和 flow style。我们更倾向于使用 block style sequences。 #### Block style 序列 Block style sequences 必须缩进在其所属的 key 下方。 ```yaml # Good example: - 1 - 2 - 3 # Bad example: - 1 - 2 - 3 ``` #### Flow style 序列 应避免使用 flow style。虽然简洁、简短、干净,但数据较长时变得难以阅读。 如使用 flow style,每个逗号 `,` 后应有空格,且开闭括号前不应有空格: ```yaml # Good example: [1, 2, 3] # Bad example: [ 1,2,3 ] example: [ 1, 2, 3 ] example: [1,2,3] example: ["light.living_room_window", "light.living_room_corner", "light.living_room_table"] ``` ### 映射 YAML 中的 mappings 也称为关联数组、哈希表、key/value pairs、collections 或 dictionaries。在 Home Assistant 世界中,我们在面向最终用户的文档中称它们为 mappings。 Mappings 有多种书写风格,但我们只允许使用 block style mappings。Flow style(看起来像 JSON)不允许使用。 ```yaml # Good example: one: 1 two: 2 # Bad example: { one: 1, two: 2 } ``` ### Null 值 Null 值应隐式标记。应避免使用显式 null 值(`~` 和 `null`)。 ```yaml # Good example: # Bad example: ~ example: null ``` ### 字符串 字符串最好用双引号(`"`)引用。 ```yaml # Good example: "Hi there!" # Avoid example: Hi there! # Bad example: 'Hi there!' ``` #### 多行字符串 在 YAML 配置中,应尽可能避免使用 `\n` 或其他换行符。同样,也应避免使用冗长的单行字符串。 改为使用 literal style(保留换行符)和 folded style(不保留换行符)字符串。 ```yaml # Good literal_example: | This example is an example of literal block scalar style in YAML. It allows you to split a string into multiple lines. folded_example: > This example is an example of a folded block scalar style in YAML. It allows you to split a string into multi lines, however, it magically removes all the new lines placed in your YAML. # Bad literal_example: "This example is an example of literal block scalar style in YAML.\nIt allows you to split a string into multiple lines.\n" folded_example_same_as: "This example is an example of a folded block scalar style in YAML. It allows you to split a string into multi lines, however, it magically removes all the new lines placed in your YAML.\n" ``` 上述示例中使用了 no chomping 操作符(`|`、`>`)。这是首选方式,除非示例需要对末尾换行符进行不同的处理。在这些情况下,可以使用 strip 操作符(`|-`、`>-`:无末尾换行符,并删除所有额外的末尾换行符)或 keep 操作符(`|+`、`>+`:保留末尾换行符,并保留所有额外的末尾换行符)。 ### 额外的字符串指导 Home Assistant 的 YAML 部分提供了有关如何在 Home Assistant 配置示例中处理字符串的额外指导。 ## Home Assistant YAML 在 Home Assistant 中,虽然仍遵循上述样式规则,但某些内容可以有多种方式处理。本节就是为了处理这些问题。 ### 默认值 使用默认值的配置选项,不应包含在示例中。除非该示例是专门为说明该选项而编写的。 例如,automation 中的 `condition` 选项是可选的,默认为空列表 `[]`。 ```yaml # Good - alias: "Test" triggers: - trigger: state entity_id: binary_sensor.motion # Bad - alias: "Test" triggers: - trigger: state entity_id: binary_sensor.motion condition: [] ``` ### 字符串(续) 如第一章所述,字符串最好用双引号引用。然而,以下值的类型不受此规则限制,因为这样可以使我们的示例更具可读性: * Entity IDs(例如 `binary_sensor.motion`) * Entity attributes(例如 `temperature`) * Device IDs * Area IDs * Platform types(例如 `light`、`switch`) * Condition types(例如 `numeric_state`、`state`) * Trigger types(例如 `state`、`time`) * Action 名称(例如 `light.turn_on`) * Device classes(例如 `problem`、`motion`) * Event 名称 * 接受有限的可能值(硬编码)的值。例如 automation 中的 `mode`。 ```yaml # Good actions: - action: notify.frenck data: message: "Hi there!" - action: light.turn_on target: entity_id: light.office_desk area_id: living_room data: transition: 10 # Bad actions: - action: "notify.frenck" data: message: Hi there! ``` ### Service action 目标 如果想针对 entity ID 触发 service action 调用(例如打开灯),可以通过三种方式实现。 Entity ID 可以作为 service action target 中的 entity 指定,作为 action 级别的属性,或作为 service action 调用中发送的数据的一部分。 Service action target 是最现代的方式,允许针对 entity、device 或 area 触发 service action 调用。因此,target 是可用选项中最灵活的,应当使用它。 ```yaml # Good actions: # Service action target is an entity - action: light.turn_on target: entity_id: light.living_room # Service action target is an area - action: light.turn_on target: area_id: light.living_room # Service action target is an area plus an entity plus a device - action: light.turn_on target: area_id: living_room entity_id: light.office_desk device_id: 21349287492398472398 # Bad actions: - action: light.turn_on entity_id: light.living_room - action: light.turn_on data: entity_id: light.living_room ``` ### 接受标量或标量列表的属性 Home Assistant 有很多地方既可以接受标量值,也可以接受标量值列表。此外,有时它甚至接受以逗号分隔的字符串值作为列表。 在接受单个值或标量值列表时,遵循以下规则: * 不得将多个值放入单个标量值中(逗号分隔的字符串)。 * 如果使用列表,必须使用 block style。 * 不应使用只包含单个标量值的列表。 * 允许使用单个标量值。 ```yaml # Good entity_id: light.living_room entity_id: - light.living_room - light.office # Bad entity_id: light.living_room, light.office entity_id: [light.living_room, light.office] entity_id: - light.living_room ``` ### 接受 mapping 或 mapping 列表的属性 Home Assistant 有可以接受 mapping 或 mapping 列表的属性。常见的例子有:`condition`、`action`、`sequence`。 当属性接受单个 mapping 或 mapping 列表时,必须使用 mapping 列表,即使只传入一个 mapping。 这样更容易理解可以添加更多项目,也更容易将单个项目复制粘贴到自己的代码中。 ```yaml # Good actions: - action: light.turn_on target: entity_id: light.living_room # Bad actions: action: light.turn_on target: entity_id: light.living_room ``` ### 模板 Home Assistant 的 templates 功能强大,但可能非常令人困惑或难以理解。因此,如果存在纯 YAML 版本,应避免使用 templates。 ```yaml # Good conditions: - condition: numeric_state entity_id: sun.sun attribute: elevation below: 4 # Bad conditions: - condition: template value_template: "{{ state_attr('sun.sun', 'elevation') < 4 }}" ``` #### 引号风格 Templates 是字符串,因此使用双引号。因此,template 内部应使用单引号。 ```yaml # Good example: "{{ 'some_value' == some_other_value }}" # Bad example: '{{ "some_value" == some_other_value }}' ``` #### Template 字符串长度 应避免模板中的长行,并将其拆分为多行,以便更清楚地了解发生了什么,并保持可读性。 有关多行字符串格式的更多信息,请参见上文关于字符串的章节。 ```yaml # Good value_template: >- {{ is_state('sensor.bedroom_co_status', 'Ok') and is_state('sensor.kitchen_co_status', 'Ok') and is_state('sensor.wardrobe_co_status', 'Ok') }} # Bad value_template: "{{ is_state('sensor.bedroom_co_status', 'Ok') and is_state('sensor.kitchen_co_status', 'Ok') and is_state('sensor.wardrobe_co_status', 'Ok') }}" ``` #### 简写 style condition 语法 优先使用 shorthand style templates 而非 verbose format,因为它提供 cleaner 的语法。 ```yaml # Good conditions: "{{ some_value == some_other_value }}" # Bad conditions: - condition: template value_template: "{{ some_value == some_other_value }}" ``` #### 过滤器 过滤器管道标记 `|` 两侧的空格是必需的。如果这导致可读性不清楚,建议使用额外的括号。 ```yaml # Good conditions: - "{{ some_value | float }}" - "{{ some_value == (some_other_value | some_filter) }}" # Bad conditions: - "{{ some_value == some_other_value|some_filter }}" - "{{ some_value == (some_other_value|some_filter) }}" ``` #### 访问 state 与 state 属性 如果有 helper 方法可用,不允许直接使用 states 对象。 例如,不要使用 `states.sensor.temperature.state`,而应使用 `states('sensor.temperature')`。 ```yaml # Good one: "{{ states('sensor.temperature') }}" two: "{{ state_attr('climate.living_room', 'temperature') }}" # Bad one: "{{ states.sensor.temperature.state }}" two: "{{ states.climate.living_room.attributes.temperature }}" ``` 此规则适用于 `states()`、`is_state()`、`state_attr()` 和 `is_state_attr()`,以避免在 entity 尚未就绪时(例如 Home Assistant 启动期间)出现错误和错误消息。 --- url: /developers/entity_registry_disabled_by.md --- Entity registry 跟踪所有具有 unique IDs 的 entities。对于每个 entity,registry 会跟踪影响 entity 如何与 core 交互的选项。其中之一是 `disabled_by`。 当 `disabled_by` 被设置且不为 `None` 时,当 integration 将该 entity 传递给 `async_add_entities` 时,该 entity 不会被添加到 Home Assistant 中。 ## 集成架构 Integrations 需要确保当它们的 entities 被禁用时能正常工作。如果你的 integration 保存了对已创建的 entity objects 的引用,它应该只在 entity 的 lifecycle method `async_added_to_hass` 内部注册这些引用。该 lifecycle method 只有在 entity 实际被添加到 Home Assistant(即未被禁用)时才会被调用。 Entity 禁用机制适用于通过 config entry 或 configuration.yaml 中的条目提供的 entities。如果你的 integration 是通过 config entry 设置的,并且支持 [unloading](/developers/config_entries_index.md#unloading-entries),Home Assistant 将能够在 entities 被启用/禁用后重新加载你的 integration,而无需重启即可应用更改。 ## 用户编辑 entity registry 禁用 entity 的一种方式是通过 UI 由用户编辑 entity registry。在这种情况下,`disabled_by` 值将被设置为 `RegistryEntryDisabler.USER`。这只适用于已经注册的 entities。 ## Integration 为新 entity registry entries 设置 disabled\_by 的默认值 作为 integration,你可以控制你的 entity 在首次注册时是否被启用。这由 `entity_registry_enabled_default` 属性控制。它默认为 `True`,这意味着 entity 将被启用。 如果该属性返回 `False`,新注册 entity 的 `disabled_by` 值将被设置为 `RegistryEntryDisabler.INTEGRATION`。 ## Config entry system options 为新 entity registry entries 设置 disabled\_by 的默认值 用户还可以通过将 config entry 的 system option `disable_new_entities` 设置为 `True`,来控制与 config entry 相关的新 entities 如何被接收。这可以通过 UI 完成。 如果一个 entity 正在被注册,并且此 system option 被设置为 `True`,则 `disabled_by` 属性将被初始化为 `RegistryEntryDisabler.CONFIG_ENTRY`。 如果 `disable_new_entities` 被设置为 `True`,且 `entity_registry_enabled_default` 返回 `False`,则 `disabled_by` 值将被设置为 `RegistryEntryDisabler.INTEGRATION`。 ## Integration 提供控制 disabled\_by 的选项 一些 integrations 希望为用户提供选项来控制哪些 entities 被添加到 Home Assistant。例如,Unifi integration 提供选项来启用/禁用无线和有线客户端。 Integrations 可以通过 [configuration.yaml](/developers/core/integration/yaml_configuration.md) 或使用 [Options Flow](/developers/core/integration/options_flow.md) 为用户提供选项。 如果 integration 提供了此选项,你不应该在 entity registry 中利用 disabled\_by 属性。相反,如果 entities 是通过 config options flow 禁用的,应从 device 和 entity registry 中移除它们。 --- url: /developers/entity_registry_index.md --- Entity registry 是 Home Assistant 用于跟踪实体的注册表。任何添加到 Home Assistant 且指定了 [`unique_id` 属性](/developers/core/entity.md#generic-properties) 的实体,都会被注册到注册表中。 被注册的好处是,同一个实体始终会获得相同的 entity ID。同时也会阻止其他实体使用该 entity ID。 用户还能够覆盖 entity registry 中实体的名称。当设置时,entity registry 中的名称会优先于设备自身可能给出的名称。 ## Unique ID 重要的是用户不能更改 unique ID,因为系统会丢失与 unique ID 相关的所有设置。 实体在注册表中的查找基于 platform 类型(例如 `light`)、集成名称(domain,例如 hue)和实体的 unique ID 的组合。实体不应在它们的 Unique ID 中包含 `domain`(例如 `your_integration`)和 platform 类型(例如 `light`),因为系统已经考虑了这些标识符。 如果一个设备只有一个 unique id 但提供多个实体,请将 unique id 与实体的唯一标识符组合起来。例如,如果一个设备同时测量温度和湿度,你可以使用 `{unique_id}-{sensor_type}` 来唯一标识这些实体。 ## Unique ID 要求 ### 可接受的 Unique ID 来源示例 * 设备的序列号 * MAC 地址:使用 `homeassistant.helpers.device_registry.format_mac` 格式化;只能从设备 API 或 discovery handler 获取 MAC 地址。依赖读取 arp 缓存或本地网络访问的工具(如 `getmac`)在所有受支持的网络环境中都无法正常工作,因此不被接受。 * 纬度和经度或其他唯一的地理坐标 * 物理印在设备上或烧录在 EEPROM 中的唯一标识符 ### 最后手段的 Unique ID 对于通过 config entry 设置的实体,如果无法获取其他 Unique ID,可以使用 `Config Entry ID` 作为最后手段。 ### 不可接受的 Unique ID 来源 * IP 地址 * 设备名称 * 主机名 * URL * 电子邮件地址 * 用户名 --- url: /developers/frontend.md --- Home Assistant 前端允许用户浏览和控制其房屋的状态,管理自动化并配置集成。 前端被设计为 mobile-first 的体验。它是一个 progressive web application,为用户提供了类似 app 的体验。 Home Assistant 前端需要快速响应。但它也需要在大量老旧设备上工作。为此,我们发布两个版本的前端: * **Latest:** 此构建版本兼容最新两个版本的 evergreen 浏览器,并针对速度进行了优化。 * **ES5:** 此构建版本兼容近 5+ 年来发布的浏览器,并针对兼容性进行了优化。 运行最新技术的设备未必就快。你可以买到运行最新 Android 版本、可访问最新 Firefox 和 Chrome 浏览器,但搭载低功耗芯片组和有限内存的廉价 Android 手机。我们的 latest 构建也需要在这些设备上流畅运行。 若要深入了解我们的前端及其设计选择,请参见[这篇博客](/developers/blog/2019-05-22-internet-of-things-and-the-modern-web.md)。 ![Home Assistant 前端截图](/img/en/frontend/frontend-hero.png) --- url: /developers/frontend/architecture.md --- Home Assistant 前端基于 web components 构建。这是一种现代 web 技术,使我们能够将模板、样式和逻辑封装到一个文件中,并在浏览器中将其暴露为一个 HTML 标签。这些组件是可组合的,为我们应用程序提供了一个非常动态且功能强大的基础。 ## 结构 Home Assistant 前端可以分为 4 个部分: ### 引导 文件:`src/entrypoints/core.ts` 这是一个非常小的脚本,是页面上最先加载的内容。它负责检查认证凭据,并与后端建立 websocket 连接。 该脚本允许我们在下载其余 UI 的同时并行开始下载数据。 ### 应用外壳 文件:`src/entrypoints/app.ts` 此入口点加载 `` 根元素和全局样式。根元素的实现在 `src/layouts/home-assistant.ts` 中。它初始化应用程序状态,处理顶层导航,并渲染 `src/layouts/home-assistant-main.ts`。 主布局渲染侧边栏,并将当前路由传递给面板解析器,由后者加载并显示所请求的面板。 ### 面板 文件夹:`src/panels/` Home Assistant 中的每个页面都是一个 panel。组件可以注册额外的 panel 以展示给用户。panel 的示例包括"states"、"map"、"logbook"和"history"。 ### 对话框 文件夹:`src/dialogs` 某些信息和数据录入以流程的形式呈现给用户。dialog 可在任何页面触发。最常见的是 entity more info dialog,它允许用户深入了解某个实体的状态、历史记录和设置。 ## 数据流 前端利用 [WebSocket API](/developers/api/websocket.md) 和 [REST API](/developers/api/rest.md) 与 Home Assistant 交互。 数据通过 `hass` 属性提供,并向下传递给每个组件。`hass` 属性包含核心状态,并拥有调用 API 的方法。 只需要 Home Assistant 部分状态的组件,应改为使用相关的 [Lit context](/developers/frontend/data.md#context)。 组件可以订阅核心状态中不可用的信息。订阅通过 websocket API 运行,从而保持数据与后端同步。 我们使用单向数据流。当你在后端做出更改时(例如打开一盏灯),`hass` 对象会在应用程序根部更新,并可供每个需要它的组件使用。 ## 路由 前端采用去中心化路由。每个组件只需要了解足够的路由信息,以知道如何处理它负责的部分。进一步的路由则沿组件树向下传递。 例如,`` 主组件会查看 URL 的第一部分,以决定应加载哪个 panel。每个 panel 可以自行定义 URL 与显示内容之间的映射。 --- url: /developers/frontend/custom-ui/creating-custom-panels.md --- Panels 是在 Home Assistant 中展示信息并可能允许对其进行控制的页面。Panels 通过 sidebar 链接,并全屏渲染。它们通过 JavaScript 可实时访问 Home Assistant 对象。应用中的 panels 示例包括 dashboards、Map、Logbook 和 History。 除了 component 注册 panels 之外,用户还可以使用 `panel_custom` component 注册 panels。这使得用户可以快速构建自己的 Home Assistant 自定义界面。 ## 简介 Panels 被定义为 custom element。你可以使用任何你喜欢的框架,只要将其包装为 custom element。要快速开始构建一个 panel,创建新文件 `/www/example-panel.js` 并放入以下内容 ```js import "https://unpkg.com/wired-card@2.1.0/lib/wired-card.js?module"; import { LitElement, html, css, } from "https://unpkg.com/lit-element@2.4.0/lit-element.js?module"; class ExamplePanel extends LitElement { static get properties() { return { hass: { type: Object }, narrow: { type: Boolean }, route: { type: Object }, panel: { type: Object }, }; } render() { return html`

共有 ${Object.keys(this.hass.states).length} 个 entities。

屏幕${this.narrow ? "" : " 不是"}narrow 的。

配置的 panel 参数
${JSON.stringify(this.panel.config, undefined, 2)}
当前 route
${JSON.stringify(this.route, undefined, 2)}
`; } static get styles() { return css` :host { background-color: #fafafa; padding: 16px; display: block; } wired-card { background-color: white; padding: 16px; display: block; font-size: 18px; max-width: 600px; margin: 0 auto; } `; } } customElements.define("example-panel", ExamplePanel); ``` 然后在你的 `configuration.yaml` 中添加: ```yaml panel_custom: - name: example-panel # 每个 panel_custom 配置,url_path 必须唯一 url_path: redirect-server-controls sidebar_title: Example Panel sidebar_icon: mdi:server module_url: /local/example-panel.js config: # 你想让 panel 使用的数据 hello: world ``` ## API 参考 Home Assistant 前端会通过在你的 custom element 上设置 properties 来向你的 panel 传递信息。以下 properties 会被设置: | Property | Type | Description | -------- | ---- | ----------- | hass | object | Home Assistant 当前状态 | narrow | boolean | 指示 panel 是否应以 narrow 模式渲染 | panel | object | Panel 信息。配置可通过 `panel.config` 访问。 ## JavaScript 版本 Home Assistant 用户界面目前以 modern JavaScript 和较旧的 JavaScript(ES5)两种方式向浏览器提供服务。较旧的版本具有更广泛的浏览器兼容性,但代价是更大的体积和更低的性能。 如果你确实需要以 ES5 支持运行,在定义你的 element 之前,需要加载 ES5 custom elements adapter: ```javascript window.loadES5Adapter().then(function() { customElements.define('my-panel', MyCustomPanel) }); ``` --- url: /developers/frontend/custom-ui/custom-badge.md --- [Badges](https://www.home-assistant.io/dashboards/badges/) 是位于 view 顶部、所有卡片上方的小部件。我们提供了一个内置的 badge,即 [entity badge](https://next.home-assistant.io/dashboards/badges/#entity-badge),但你并不局限于这一种。你可以构建并使用自己的 badge! ## 定义你的 badge 定义 badge 的方式与定义 [custom card](/developers/frontend/custom-ui/custom-card.md) 非常相似。 让我们创建一个基本的 badge,在屏幕顶部显示自定义文本。 在你的 Home Assistant config 目录下创建新文件 `/www/text-badge.js`,并放入以下内容: ```js class TextBadge extends HTMLElement { // 每当 state 变更时,会设置一个新的 `hass` 对象。使用它来 // 更新你的内容。 set hass(hass) { this._hass = hass; this.updateContent(); } // 用户提供的配置。如果抛出异常,Home Assistant // 将渲染一个错误 badge。 setConfig(config) { if (!config.entity) { throw new Error("You need to define an entity"); } this.config = config; this.updateContent(); } updateContent() { if (!this.config || !this._hass) return; const entityId = this.config.entity; const state = this._hass.states[entityId]; const stateStr = state ? state.state : "unavailable"; this.innerHTML = `

${stateStr}

`; } } customElements.define("text-badge", TextBadge); ``` ## 引用你的新 badge 在我们的示例 badge 中,我们定义了一个 tag 为 `text-badge` 的 badge(见最后一行),因此我们的 badge type 将是 `custom:text-badge`。由于你把文件创建在 `/www` 目录下,它可以通过 URL `/local/` 在浏览器中访问(如果你最近新增了 www 文件夹,需要重启 Home Assistant 才能识别文件)。 在你的 dashboard 配置中添加一个 resource,URL 为 `/local/text-badge.js`,type 为 `module`([resource 文档](/developers/frontend/custom-ui/registering-resources.md))。 然后你可以在 dashboard 配置中使用你的 badge: ```yaml # 示例 dashboard 配置 views: - name: Example badges: - type: "custom:text-badge" entity: light.bedside_lamp ``` ## API Custom badges 被定义为 [custom element](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements)。如何在你自己的 element 内部渲染 DOM 由你决定。你可以使用 Polymer、Angular、Preact 或任何其他主流框架(React 除外——[此处了解更多关于 React 的信息](https://custom-elements-everywhere.com/#react))。 Home Assistant 会在配置变更时(较少见)调用 `setConfig(config)`。如果配置无效而抛出异常,Home Assistant 会渲染一个错误 badge 来通知用户。 Home Assistant 会在 state 变更时(频繁)设置 [the `hass` property](/developers/frontend/data.md)。每当 state 变更时,该组件都必须更新自身以反映最新的 state。 ## 图形化 badge 配置 你的 badge 可以定义一个 `getConfigElement` 方法,返回一个用于编辑用户配置的 custom element。Home Assistant 会在 dashboard 的 badge 编辑器中显示该 element。 你的 badge 还可以定义一个 `getStubConfig` 方法,返回一个默认的 badge 配置(不含 `type:` 参数),以 json 形式供 dashboard 中的 badge type 选择器使用。 Home Assistant 会在初始化时调用 config element 的 `setConfig` 方法。 state 变更时,Home Assistant 会更新 config element 的 `hass` 属性,以及包含 dashboard 配置信息的 `lovelace` element。 配置的变更通过派发一个 `config-changed` 事件传回 dashboard,新配置包含在该事件的 detail 中。 若要让你的 badge 显示在 dashboard 的 badge 选择对话框中,请将描述它的对象添加到数组 `window.customBadges` 中。该对象的必填属性是 `type` 和 `name`(见下方示例)。 ```js import "./text-badge-editor.js"; class TextBadge extends HTMLElement { ... static getConfigElement() { return document.createElement("text-badge-editor"); } static getStubConfig() { return { entity: "sun.sun" }; } } customElements.define("text-badge", TextBadge); ``` ```js class TextBadgeEditor extends HTMLElement { setConfig(config) { this._config = config; } configChanged(newConfig) { const event = new Event("config-changed", { bubbles: true, composed: true, }); event.detail = { config: newConfig }; this.dispatchEvent(event); } } customElements.define("text-badge-editor", TextBadgeEditor); window.customBadges = window.customBadges || []; window.customBadges.push({ type: "text-badge", name: "Text badge", preview: false, // 可选 - 默认为 false description: "A custom badge made by me!", // 可选 documentationURL: "https://developers.home-assistant.io/docs/frontend/custom-ui/custom-badge", // 在 frontend badge 编辑器中添加帮助链接 }); ``` --- url: /developers/frontend/custom-ui/custom-card-feature.md --- 一些 dashboard 卡片支持 [features](https://www.home-assistant.io/dashboards/features/)。这些 widget 为卡片添加快速控制。我们提供了许多内置的 feature,但你并不局限于我们决定包含在 Home Assistant 中的那些。你可以像定义 [custom cards](/developers/frontend/custom-ui/custom-card.md) 一样构建并使用自己的 feature。 ## 定义你的卡片 feature 以下是针对 [button entity](/developers/core/entity/button.md) 的自定义卡片 feature 示例。 ![Screenshot of the custom card feature example](/img/en/frontend/dashboard-custom-card-feature-screenshot.png) ```js import { LitElement, html, css, } from "https://unpkg.com/lit-element@2.0.1/lit-element.js?module"; const supportsButtonPressCardFeature = (hass, context) => { const stateObj = context.entity_id ? hass.states[context.entity_id] : undefined; if (!stateObj) return false; const domain = stateObj.entity_id.split(".")[0]; return domain === "button"; }; class ButtonPressCardFeature extends LitElement { static get properties() { return { hass: undefined, config: undefined, context: undefined, }; } static getStubConfig() { return { type: "custom:button-press-card-feature", label: "Press", }; } setConfig(config) { if (!config) { throw new Error("Invalid configuration"); } this.config = config; } get _stateObj() { if (!this.hass || !this.context?.entity_id) return undefined; return this.hass.states[this.context.entity_id]; } _press(ev) { ev.stopPropagation(); const stateObj = this._stateObj; if (!stateObj) return; this.hass.callService("button", "press", { entity_id: stateObj.entity_id, }); } render() { if ( !this.config || !this.hass || !this.context || !supportsButtonPressCardFeature(this.hass, this.context) ) { return null; } return html` `; } static get styles() { return css` .button { display: block; height: var(--feature-height, 42px); width: 100%; border-radius: var(--feature-border-radius, 12px); border: none; background-color: #eeeeee; cursor: pointer; transition: background-color 180ms ease-in-out; } .button:hover { background-color: #dddddd; } .button:focus { background-color: #cdcdcd; } `; } } customElements.define("button-press-card-feature", ButtonPressCardFeature); window.customCardFeatures = window.customCardFeatures || []; window.customCardFeatures.push({ type: "button-press-card-feature", name: "Button press", isSupported: supportsButtonPressCardFeature, // 可选 configurable: true, // 可选 - 默认为 false }); ``` ## 上下文 Card feature 在卡片内部渲染,并接收与卡片绑定相同的 context。该 context 既作为 `context` 属性传递给 element,也作为 `isSupported` 函数的第二个参数。 `context` 对象暴露以下内容: * `entity_id` *(optional)*: 来自父卡片的 entity id。 * `area_id` *(optional)*: 来自父卡片的 area id。 如果你希望你的 feature 更好地与 Home Assistant 的默认设计集成,可以使用这些 CSS 变量: * `--feature-height`: 推荐高度(42px)。 * `--feature-border-radius`: 推荐圆角(12px)。用于设置 button 或 slider 的圆角很有用。 * `--feature-button-spacing`: 推荐 button 之间的间距(12px)。如果你的 feature 中有多个 button,这会很有用。 与 custom cards 的主要区别在于图形化配置选项。 若要在卡片编辑器中显示,你必须将描述它的对象添加到数组 `window.customCardFeatures` 中。 该对象的必填属性是 `type` 和 `name`。建议定义 `isSupported` 选项,使用函数 `(hass, context) => boolean`,这样编辑器只有在 feature 与卡片中选定的 entity 兼容时才会推荐它。如果你的 entity 有额外的配置(例如上方示例中的 `label` 选项),请将 `configurable` 设为 `true`。 此外,静态函数 `getConfigElement` 和 `getStubConfig` 的工作原理与普通的 custom cards 相同。 --- url: /developers/frontend/custom-ui/custom-card.md --- [Dashboards](https://www.home-assistant.io/dashboards/) 是我们为你定义 Home Assistant 用户界面的方式。我们提供了许多内置卡片,但你并不仅限于我们决定纳入 Home Assistant 的那些。你可以构建并使用自己的卡片! ## 定义你的卡片 下面是一个展示可能性的基本示例。 在你的 Home Assistant config 目录中创建新文件 `/www/content-card-example.js`,并放入以下内容: ```js class ContentCardExample extends HTMLElement { // card 连接到 DOM connectedCallback() { const event = new CustomEvent('context-request', { bubbles: true, composed: true, cancelable: true, }); event.context = 'states'; // HA 的 user context provider 使用的 key event.subscribe = true; // 订阅此 context 的后续更新,而不只是获取当前值 event.callback = this._updateStates; this.dispatchEvent(event); // 初始渲染 this._render(); } // 接收 states 更新并检查卡片是否需要重新渲染 _updateStates = (states, unsubscribe) => { // 存储 unsubscribe 函数,以便在卡片从 DOM 中移除时调用 this._unsubscribe = unsubscribe; const entityId = this.config.entity; console.log("update states", states, entityId) const state = states[entityId]; const stateString = state ? state.state : "unavailable"; console.log("stateString", stateString, this.stateString) if (this.stateString !== stateString) { console.log("stateString changed, re-rendering") this.stateString = stateString; this._render(); } } // 仅在需要时渲染卡片的 html _render = () => { this.innerHTML = ` ${this.config.entity || "?"} 的状态是 ${this.stateString || "unavailable"}!

`; } // 用户提供的配置。抛出异常,Home Assistant // 将渲染一个 error 卡片。 setConfig(config) { if (!config.entity) { throw new Error("You need to define an entity"); } this.config = config; } // 你的卡片高度。Home Assistant 使用此值在 masonry view 中 // 自动将所有卡片分配到可用的列中 getCardSize() { return 3; } // 在 sections view 的 grid 中确定卡片大小的规则 getGridOptions() { return { rows: 3, columns: 6, min_rows: 3, max_rows: 3, }; } disconnectedCallback() { if (this._unsubscribe) { this._unsubscribe(); this._unsubscribe = undefined; } } } customElements.define("content-card-example", ContentCardExample); ``` ## 引用你的新卡片 在我们的示例卡片中,我们定义了一个带 tag `content-card-example` 的卡片(见最后一行),因此我们的卡片类型将是 `custom:content-card-example`。并且由于你将文件创建在 `/www` 目录中,它将可以通过 `/local/` URL 在你的浏览器中访问(如果你最近才添加 www 文件夹,需要重启 Home Assistant 才能加载文件)。 在你的 dashboard 配置中添加一个 resource,URL 为 `/local/content-card-example.js`,类型为 `module`([resource docs](/developers/frontend/custom-ui/registering-resources.md))。 然后你就可以在 dashboard 配置中使用你的卡片: ```yaml # 示例 dashboard 配置 views: - name: Example cards: - type: "custom:content-card-example" entity: input_boolean.switch_tv ``` ## API Custom cards 被定义为 [custom element](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements)。如何渲染你的 element 内部的 DOM 由你决定。你可以使用 Polymer、Angular、Preact 或其他任何主流框架(React 除外 – [更多信息请看这里](https://custom-elements-everywhere.com/#react))。 ### 配置 Home Assistant 会在配置变更时(很少)调用 `setConfig(config)`。如果配置无效时你抛出异常,Home Assistant 会渲染一个 error 卡片来通知用户。 ### 数据上下文 在示例中,你看到我们使用一个 custom event 来请求 Home Assistant 的 states。这是从 Home Assistant 获取数据并订阅此数据后续更新的推荐方式。详细文档请看[这里](/developers/frontend/data.md#available-contexts)。 ### 在 masonry view 中的 sizing 你的卡片可以定义一个 `getCardSize` 方法,返回一个数字或一个将 resolve 为数字的 promise,代表你卡片的大小。高度为 1 相当于 50 像素。这将帮助 Home Assistant 在 [masonry view](https://www.home-assistant.io/dashboards/masonry/) 中将卡片均匀分配到各列。如果未定义该方法,将假定卡片大小为 `1`。 由于某些 element 可能会被 lazy load,如果你想获取另一个 element 的卡片大小,应首先检查它是否已定义。 ```js return customElements .whenDefined(element.localName) .then(() => element.getCardSize()); ``` ### 在 sections view 中的 sizing 你可以定义一个 `getGridOptions` 方法,返回你卡片在 [sections view](https://www.home-assistant.io/dashboards/sections/) 中使用的 grid 所占的最小、最大和默认单元格数量。每个 section 分为 12 列。如果你不定义此方法,卡片将占用 12 列,并忽略 grid 的 rows。 grid 中一个单元格的尺寸定义如下: * width:section 宽度除以 12(约 `30px`) * height:`56px` * 单元格间距:`8px` 不同的 grid 选项包括: * `rows`:卡片占用的默认行数。如果想让卡片忽略 grid 的 rows,不要定义此值(默认未定义) * `min_rows`:卡片占用的最小行数(默认为 `1`) * `max_rows`:卡片占用的最大行数(默认未定义) * `columns`:卡片占用的默认列数。设为 `full` 以强制卡片为全宽(默认为 `12`) * `min_columns`:卡片占用的最小列数(默认为 `1`) * `max_columns`:卡片占用的最大列数(默认未定义) 关于列数,非常建议使用 3 的倍数作为默认值(`3`、`6`、`9` 或 `12`),这样你的卡片在 dashboard 上默认会更美观。 实现示例: ```js public getGridOptions() { return { rows: 2, columns: 6, min_rows: 2, }; } ``` 在此示例中,卡片默认将占用 6 x 2 个单元格。卡片高度不能小于 2 行。根据单元格尺寸,卡片高度将为 `120px`(`2` \* `56px` + `8px`)。 ## 使用 JS modules 的示例 dashboard 中加载的 resources 是作为 JS module import 导入的。下面是一个使用 JS modules 的 custom card 示例,它实现了所有高级功能。 ![有线卡片截图](/img/en/frontend/dashboard-custom-card-screenshot.png) 在你的 Home Assistant config 目录中创建新文件 `/www/wired-cards.js`,并放入以下内容: ```js import "https://unpkg.com/wired-card@0.8.1/wired-card.js?module"; import "https://unpkg.com/wired-toggle@0.8.0/wired-toggle.js?module"; import { LitElement, html, css, } from "https://unpkg.com/lit-element@2.0.1/lit-element.js?module"; function loadCSS(url) { const link = document.createElement("link"); link.type = "text/css"; link.rel = "stylesheet"; link.href = url; document.head.appendChild(link); } loadCSS("https://fonts.googleapis.com/css?family=Gloria+Hallelujah"); class WiredToggleCard extends LitElement { static get properties() { return { hass: {}, config: {}, }; } render() { return html` ${this.config.entities.map((ent) => { const stateObj = this.hass.states[ent]; return stateObj ? html`
${stateObj.attributes.friendly_name}
` : html`
未找到 Entity ${ent}。
`; })}
`; } setConfig(config) { if (!config.entities) { throw new Error("You need to define entities"); } this.config = config; } // 你的卡片高度。Home Assistant 使用此值自动 // 将所有卡片分配到可用的列中。 getCardSize() { return this.config.entities.length + 1; } _toggle(state) { this.hass.callService("homeassistant", "toggle", { entity_id: state.entity_id, }); } static get styles() { return css` :host { font-family: "Gloria Hallelujah", cursive; } wired-card { background-color: white; padding: 16px; display: block; font-size: 18px; } .state { display: flex; justify-content: space-between; padding: 8px; align-items: center; } .not-found { background-color: yellow; font-family: sans-serif; font-size: 14px; padding: 8px; } wired-toggle { margin-left: 8px; } `; } } customElements.define("wired-toggle-card", WiredToggleCard); ``` 在你的 dashboard 配置中添加一个 URL 为 `/local/wired-cards.js`、类型为 `module` 的 resource。 以及你的配置: ```yaml # 示例 dashboard 配置 views: - name: Example cards: - type: "custom:wired-toggle-card" entities: - input_boolean.switch_ac_kitchen - input_boolean.switch_ac_livingroom - input_boolean.switch_tv ``` ## 图形化卡片配置 你的卡片可以定义一个 `getConfigElement` 方法,返回一个用于编辑用户配置的 custom element。Home Assistant 将把这个 element 显示在 dashboard 的 card editor 中。 你的卡片还可以定义一个 `getStubConfig` 方法,以 json 形式返回一个默认的卡片配置(不含 `type:` 参数),供 dashboard 中的卡片类型选择器使用。 Home Assistant 将在设置时调用 config element 的 `setConfig` 方法。Home Assistant 会在状态变更时更新 config element 的 `hass` 属性,以及包含 dashboard 配置信息的 `lovelace` element。 配置的变更通过派发一个 `config-changed` 事件传回 dashboard,新配置包含在其 detail 中。 要让你的卡片显示在 dashboard 的卡片选择器对话框中,需要向数组 `window.customCards` 添加一个描述它的对象。该对象的必填属性为 `type` 和 `name`(见下面示例)。 ```js class ContentCardExample extends HTMLElement { static getConfigElement() { return document.createElement("content-card-editor"); } static getStubConfig() { return { entity: "sun.sun" } } ... } customElements.define('content-card-example', ContentCardExample); ``` ```js class ContentCardEditor extends LitElement { setConfig(config) { this._config = config; } configChanged(newConfig) { const event = new Event("config-changed", { bubbles: true, composed: true, }); event.detail = { config: newConfig }; this.dispatchEvent(event); } } customElements.define("content-card-editor", ContentCardEditor); window.customCards = window.customCards || []; window.customCards.push({ type: "content-card-example", name: "Content Card", preview: false, // 可选,默认为 false description: "A custom card made by me!", // 可选 documentationURL: "https://developers.home-assistant.io/docs/frontend/custom-ui/custom-card", // 在 frontend 卡片编辑器中添加帮助链接 }); ``` ### 为实体推荐你的卡片 *自 Home Assistant 2026.6 起可用。* 当用户在卡片选择器中选择一个实体时,Home Assistant 会显示适用于该实体的建议卡片列表。你的卡片可以在其 `window.customCards` 条目中定义 `getEntitySuggestion` 函数来加入此列表。建议的 custom cards 会出现在内置建议下方的 **Community** 部分。 ```js window.customCards.push({ type: "content-card-example", name: "Content Card", getEntitySuggestion: (hass, entityId) => { // 如果不支持该实体,返回 null const domain = entityId.split(".")[0]; if (domain !== "light") { return null; } // 返回一个建议 return { config: { type: "custom:content-card-example", entity: entityId }, }; }, }); ``` `getEntitySuggestion(hass, entityId)` 会被传入 `hass` 对象和所选 entity id。它返回: * 如果卡片不支持该实体,返回 `null`。 * 单个建议,或一个建议数组,用于提供多种变体。 仅当你的卡片对该实体确实有意义时才返回建议。使用 `hass` 对象检查其实体的 domain、device class 或 supported features。为每个实体都推荐你的卡片会让选择器过于杂乱,并导致用户选择错误的卡片。 每个建议都是一个对象,包含: * `config` *(必填)*:用户选择该建议时要应用的卡片配置。必须包含你的 `type`(带 `custom:` 前缀)。 * `label` *(可选)*:描述变体的简短标签。选择器会先显示卡片的 `name`,再接这个 label,因此只有返回多个建议时才设置它。 ```js getEntitySuggestion: (hass, entityId) => { if (entityId.split(".")[0] !== "light") { return null; } return [ { label: "Compact", config: { type: "custom:content-card-example", entity: entityId }, }, { label: "Detailed", config: { type: "custom:content-card-example", entity: entityId, details: true, }, }, ]; }, ``` ### 使用内置表单编辑器 为图形编辑器配置的一种方式是为卡片提供一个 custom editor element;对于配置需求相对简单的卡片,另一种选择是使用内置的 frontend 表单编辑器。通过在卡片类中定义一个静态 `getConfigForm` 函数来实现,它返回一个定义配置表单形状的 form schema。 示例: ```js static getConfigForm() { return { schema: [ { name: "label", selector: { label: {} } }, { name: "entity", required: true, selector: { entity: {} } }, { type: "grid", name: "", schema: [ { name: "name", selector: { text: {} } }, { name: "icon", selector: { icon: {}, }, context: { icon_entity: "entity", }, }, { name: "attribute", selector: { attribute: {}, }, context: { filter_entity: "entity", }, }, { name: "unit", selector: { text: {} } }, { name: "theme", selector: { theme: {} } }, { name: "state_color", selector: { boolean: {} } }, ], }, ], computeLabel: (schema) => { if (schema.name === "icon") return "Special Icon"; return undefined; }, computeHelper: (schema) => { switch (schema.name) { case "entity": return "This text describes the function of the entity selector"; case "unit": return "The unit of measurement for this card"; } return undefined; }, assertConfig: (config) => { if (config.other_option) { throw new Error("'other_option' is unexpected."); } }, }; } ``` 从此函数中,应返回一个最多包含 4 个 key 的对象: * `schema` *(必填)*:这是一个 schema 对象列表,每个表单字段对应一个,定义字段的名称、selector 等各种属性。 * `computeLabel` *(可选)*:此回调函数会对每个表单字段调用,允许卡片定义要显示的字段 label。如果为 `undefined`,Home Assistant 可能会为 `entity` 这类通用字段名应用已知的翻译,或者你也可以提供自己的翻译。 * `computeHelper` *(可选)*:此回调函数会对每个表单字段调用,允许你为字段定义更长的 helper 文本,将显示在字段下方。 * `assertConfig` *(可选)*:每次配置更新时,用户的配置都会传递给此回调函数。在此回调中抛出 `Error` 将使可视化编辑器被禁用。这可用于在用户输入不兼容数据时禁用可视化编辑器,比如对期望 string 的 selector 输入了一个 yaml 对象。如果此回调的后续执行未抛出错误,可视化编辑器将被重新启用。 此示例将产生以下配置表单: ![配置表单截图](/img/en/frontend/dashboard-custom-card-config-form.png) #### Form schema 元素 form schema 可以包含独立的控件、grid 或 expansion panel,配置选项如下: Controls: * `name` *(必填)*:控件的名称。 * `selector` *(可选)*:此控件的 selector 配置(可用选项请参见 [selectors](https://www.home-assistant.io/docs/blueprint/selectors/)) * `type` *(可选)*:如果未定义 selector,有 `float` 和 `boolean` 等原生表单类型,但建议使用 selectors。 Grids: * `type` *(必填)*:`grid` * `name` *(必填)*:在 form 数据对象中对应此 grid 的 key(参见 `flatten`) * `schema` *(必填)*:grid 中子控件的列表 * `flatten` *(可选)*:`true`/`false`,指示子控件数据是否应展平到主数据字典中,还是放在以此 grid 命名的子字典下 * `column_min_width` *(可选)*:grid 中单元格最小宽度的 CSS 属性(例如 `200px`) Expansion Panel: * `type` *(必填)*:`expandable` * `name` *(必填)*:在 form 数据对象中对应此 panel 的 key(参见 `flatten`) * `schema` *(必填)*:expansion panel 中子控件的列表 * `title` *(可选)*:panel 上的标题 * `flatten` *(可选)*:`true`/`false`,指示子控件数据是否应展平到主数据字典中,还是放在以此 panel 命名的子字典下 这不是所有选项的完整列表,更多配置选项列于 [ha-form/types.ts](https://github.com/home-assistant/frontend/blob/master/src/components/ha-form/types.ts) --- url: /developers/frontend/custom-ui/custom-strategy.md --- *在 Home Assistant 2021.5 中引入。* Strategies 是生成自定义 dashboards 和/或 views 的 custom elements。你可以在 frontend 仓库中创建新的 strategies,也可以创建作为 dashboard resources 加载的 custom strategies。两者都可以像 [custom cards](/developers/frontend/custom-ui/custom-card.md) 一样访问 Home Assistant API。 一个 strategy 可以生成单个 view,也可以生成包含一个或多个 view 的完整 dashboard。 与 custom cards 一样,custom strategies 需要作为 resources 加载。有关如何将 strategies 作为 resources 包含的更多信息,请参见 [registering resources](/developers/frontend/custom-ui/registering-resources.md)。 如果你已经构建过 custom card,这套流程会让你感到熟悉。Strategies 的加载方式相同,但它们不是直接渲染单个卡片,而是生成 dashboard 内容。当需要时,它们也可以与 custom cards 配合使用。你可以像导入任何其他 resource/element 一样将 custom cards 导入到你的 strategy 中。 ## 仪表盘 dashboard strategy 生成完整的 dashboard 配置。在大多数情况下,它从一个小型的 strategy config 开始,返回完整的 dashboard 结构。可以把它想成一个随后会被渲染成 dashboard 的 json/yaml 配置。内置的 dashboards 就是用 dashboard strategies 构建的。你可以在[这里](https://github.com/home-assistant/frontend/tree/dev/src/panels/lovelace/strategies)阅读内置 dashboards 的源代码。 ### 在新的 dashboard 对话框中展示你的社区 dashboard **在 Home Assistant 2026.5 中引入。** 如果你已经有一个 dashboard strategy,可以通过将其注册到 `window.customStrategies` 中来让人更容易添加。 一旦 resource 加载完毕,Home Assistant 就可以在新的 dashboard 对话框的 **Community dashboards** 部分中显示你的 dashboard。 该对象支持以下 key: | Key | Required | Description | | ------------------ | -------- | ------------------------------------------------------------------------------ | | `type` | Yes | 不带 `custom:` 前缀的 strategy type。 | | `strategyType` | Yes | 设为 `"dashboard"` 以注册一个 dashboard strategy。 | | `name` | No | 在选择器中显示的友好名称。 | | `description` | No | 显示在名称下方的简短文本。 | | `documentationURL` | No | 指向你的文档的链接。目前在 strategy UI 中尚未显示。 | 示例: ```js window.customStrategies = window.customStrategies || []; window.customStrategies.push({ type: "my-demo", strategyType: "dashboard", name: "My demo dashboard", description: "A starter dashboard generated from JavaScript.", documentationURL: "https://example.com/my-demo-dashboard", }); ``` ### 在创建对话框中建议初始值 dashboard strategies 还可以为在用户选择 strategy 后打开的 dashboard 详情表单建议初始值。 为此,在 dashboard strategy element 中添加一个静态 `getCreateSuggestions(hass)` 方法。返回一个包含以下任意可选 key 的对象: | Key | Description | | ------- | ------------------------------------------ | | `title` | 建议的 dashboard 标题。 | | `icon` | 建议的 dashboard 图标,如 `mdi:home`。 | 示例: ```js class MyDemoDashboardStrategy extends HTMLElement { static getCreateSuggestions(_hass) { return { title: "My demo dashboard", icon: "mdi:view-dashboard", }; } static async generate(config, hass) { // ... } } ``` 这些值只是对话框的默认值。用户仍然可以在创建 dashboard 之前更改它们。 ### 示例 一个好的起点是 [home overview](https://github.com/home-assistant/frontend/tree/dev/src/panels/lovelace/strategies/home) dashboard 或 [energy dashboard](https://github.com/home-assistant/frontend/tree/dev/src/panels/lovelace/strategies/energy)。 或者,对于更简单的示例,可以是 [map dashboard strategy](https://github.com/home-assistant/frontend/blob/dev/src/panels/lovelace/strategies/map/map-dashboard-strategy.ts),它导入了 map view strategy。而这反过来使用了 panel view 类型,该类型使用单个 map card。 #### Basic 示例 本示例可复制到 JavaScript 文件中并作为 module resource 加载。它包含了 strategy 注册以及在新的 dashboard 对话框中显示它所需的 metadata。 这是一个好的起点,但我们推荐使用 Lit 的 [ReactiveElement](https://lit.dev/docs/framework/concepts/reactive-element/) 代替 HTMLElement,并使用 TypeScript 或 JSDoc 进行类型标注。完整代码示例请参见 [frontend repo](https://github.com/home-assistant/frontend/tree/dev/src/panels/lovelace/strategies)。 ```js class MyDemoDashboardStrategy extends HTMLElement { static getCreateSuggestions(_hass) { return { title: "My demo dashboard", icon: "mdi:view-dashboard", }; } static async generate(config, hass) { const title = config.title || "My demo dashboard"; const locationName = hass.config.location_name || "Home Assistant"; return { title, views: [ { title: "Home", path: "home", cards: [ { type: "markdown", content: `# ${locationName}\n\n` + "本 dashboard 由一个社区 dashboard strategy 生成。", }, { type: "entities", entities: ["sun.sun"], }, ], }, ], }; } } customElements.define("ll-strategy-dashboard-my-demo", MyDemoDashboardStrategy); window.customStrategies = window.customStrategies || []; window.customStrategies.push({ type: "my-demo", strategyType: "dashboard", name: "My demo dashboard", description: "A small starter dashboard generated from JavaScript.", documentationURL: "https://developers.home-assistant.io/docs/frontend/custom-ui/custom-strategy", }); ``` 使用以下 dashboard 配置来使用此 strategy: ```yaml strategy: type: custom:my-demo ``` ## 图形配置 你的 strategy 可以定义一个静态 `getConfigElement` 方法,返回一个用于编辑 strategy 配置的 custom element。Home Assistant 将把这个 element 显示在 dashboard 设置对话框中。 如果你的 strategy 需要配置才能工作,将 `configRequired` 设为 `true`。这样可以防止 Home Assistant 在首先显示配置编辑器之前就创建使用该 strategy 的 dashboard。 如果你的 strategy 不支持图形化配置,将 `noEditor` 设为 `true`。 ```js class MyDemoDashboardStrategy extends HTMLElement { static getConfigElement() { return document.createElement("my-demo-strategy-editor"); } static configRequired = true; static async generate(config, hass) { return { views: [ { cards: [ { type: "iframe", url: config.url, }, ], }, ], }; } } customElements.define("ll-strategy-dashboard-my-demo", MyDemoDashboardStrategy); ``` ```js class MyDemoStrategyEditor extends HTMLElement { setConfig(config) { this._config = config; } set hass(hass) { this._hass = hass; } configChanged(newConfig) { this.dispatchEvent( new CustomEvent("config-changed", { bubbles: true, composed: true, detail: { config: newConfig }, }) ); } } customElements.define("my-demo-strategy-editor", MyDemoStrategyEditor); ``` Home Assistant 将在设置时调用 config element 的 `setConfig` 方法。状态变更时会更新 `hass` 属性。配置的变更通过派发一个 `config-changed` 事件传回,新配置包含在其 detail 中。 ## 视图 view strategy 生成特定 dashboard view 的配置。如果需要,它们可以在 dashboard strategies 中复用,就像 custom cards 可以在 view strategies 中使用一样。 > 本节讨论的是 view strategies。如果你想构建自定义 view 布局 element,请参见 [custom views](/developers/frontend/custom-ui/custom-view.md)。 使用以下 dashboard 配置来使用此 strategy: ```yaml views: - strategy: type: custom:my-demo title: Generated view ``` ## Full strategy 示例 通常好的做法是让 dashboard strategy 创建 views 列表,然后让 view strategy 为每个 view 生成 cards。这样可以让首次 dashboard 加载量更小,并让 Home Assistant 仅在打开某个 view 时才构建它。 下面的示例为每个 area 创建一个 view。每个生成的 view 都会以 grid 显示该 area 的 entities。 ```js class MyAreaDashboardStrategy extends HTMLElement { static getCreateSuggestions(_hass) { return { title: "Area dashboard", icon: "mdi:floor-plan", }; } static async generate(config, hass) { // 查询所需的所有数据。我们将通过将其存储在 strategy options 中使其对 views 可用。 const [areas, devices, entities] = await Promise.all([ hass.callWS({ type: "config/area_registry/list" }), hass.callWS({ type: "config/device_registry/list" }), hass.callWS({ type: "config/entity_registry/list" }), ]); return { title: config.title || "Area dashboard", views: areas.map((area) => ({ title: area.name, path: area.area_id, strategy: { type: "custom:my-area-dashboard", area: area, devices: devices, entities: entities, }, })), }; } } class MyAreaViewStrategy extends HTMLElement { static async generate(config, hass) { const areaDevices = new Set(); // 找出此 area 中的所有 devices。 for (const device of config.devices) { if (device.area_id === config.area.area_id) { areaDevices.add(device.id); } } const cards = []; // 找出此 area 中或属于此 area 中某个 device 的所有 entities。 for (const entity of config.entities) { if ( entity.area_id === config.area.area_id || (!entity.area_id && areaDevices.has(entity.device_id)) ) { cards.push({ type: "button", entity: entity.entity_id, }); } } return { cards: [ { type: "grid", cards, }, ], }; } } customElements.define( "ll-strategy-dashboard-my-area-dashboard", MyAreaDashboardStrategy, ); customElements.define( "ll-strategy-view-my-area-dashboard", MyAreaViewStrategy, ); window.customStrategies = window.customStrategies || []; window.customStrategies.push({ type: "my-area-dashboard", strategyType: "dashboard", name: "Area dashboard", description: "Build one view per area from the Home Assistant registries.", documentationURL: "https://developers.home-assistant.io/docs/frontend/custom-ui/custom-strategy", }); ``` 使用以下 dashboard 配置来使用此 strategy: ```yaml strategy: type: custom:my-area-dashboard ``` --- url: /developers/frontend/custom-ui/custom-view.md --- 默认情况下,Home Assistant 会尝试以 masonry 布局(类似 Pinterest)显示卡片。Custom view 布局允许开发者覆盖此行为并定义布局机制(如 grid)。 ## API 你将自定义 view 定义为 [custom element](https://developer.mozilla.org/docs/Web/Web_Components/Using_custom_elements)。如何渲染你的 element 内部的 DOM 由你决定。你可以使用 Lit Element、Preact 或其他任何主流框架(React 除外 – [更多信息请看这里](https://custom-elements-everywhere.com/#react))。 Custom Views 会接收以下内容: ```ts interface LovelaceViewElement { hass?: HomeAssistant; lovelace?: Lovelace; index?: number; cards?: Array; badges?: LovelaceBadge[]; setConfig(config: LovelaceViewConfig): void; } ``` Cards 和 Badges 将由核心代码创建和维护,并交给 custom view。Custom views 的目的是加载这些 cards 和 badges,并以自定义布局显示它们。 ## 示例 (注意:此示例不包含所有 properties,但包含展示示例所需的基本内容) ```js import { LitElement, html, } from "https://unpkg.com/@polymer/lit-element@^0.6.1/lit-element.js?module"; class MyNewView extends LitElement { setConfig(_config) {} static get properties() { return { cards: { type: Array, attribute: false }, }; } render() { if (!this.cards) { return html``; } return html`${this.cards.map((card) => html`
${card}
`)}`; } } ``` 你可以在 Custom Element Registry 中像定义 Custom Card 一样定义此 element: ```js customElements.define("my-new-view", MyNewView); ``` 可以在你的 view 定义中添加以下内容来使用 custom view: ```yaml - title: Home View type: custom:my-new-view badges: [...] cards: [...] ``` 默认的 masonry view 就是一个 layout element 的示例。([source](https://github.com/home-assistant/frontend/blob/master/src/panels/lovelace/views/hui-masonry-view.ts))。 ## 存储自定义数据 如果你的 view 需要以卡片级别持久化数据,卡片配置中的 `view_layout` 可用于存储信息。例如:Key、X 和 Y 坐标、宽度和高度等。当你需要为 view 存储卡片的位置或尺寸时,这会很有用。 ```yaml - type: weather-card view_layout: key: 1234 width: 54px entity: weather.my_weather ``` ## 编辑、删除或添加卡片 要调用核心 frontend 的对话框来编辑、删除或添加卡片,只需调用以下三个事件: ``` Event: "ll-delete-card" Detail: { path: [number] | [number, number] } Event: "ll-edit-card" Detail: { path: [number] | [number, number] } Event: "ll-create-card" Detail: none ``` 调用事件的方法: ```js // 删除当前 view 中的第 4 张卡片(this 指向该 card element) this.dispatchEvent( new CustomEvent("ll-edit-card", { detail: { path: [3] }, }), ); ``` --- url: /developers/frontend/custom-ui/registering-resources.md --- 如果你想要用 custom cards、strategies 或 views 扩展 Home Assistant 界面,需要加载外部 resources。 第一步是让这些 resources 对 Home Assistant 前端可访问。这通过在你的 config 文件夹中创建一个名为 `www` 的新目录来实现。创建此目录并重启 Home Assistant。 重启后,你可以将文件放入此目录。每个文件都可以通过 UI 在 `/local` 下无认证访问。 下一步是向 Home Assistant 界面注册这些 resources。方法是按照下面链接导航到 Resources 页面: [![Open your Home Assistant instance and show your resources.](https://my.home-assistant.io/badges/lovelace_resources.svg)](https://my.home-assistant.io/redirect/lovelace_dashboards/)(注意:重定向后,点击右上角的三个点菜单。) 或者,你也可以通过将 resource 添加到配置中 `lovelace` 的 `resources` 部分来注册它: ```yaml resources: - url: /local/.js type: module ``` 如果你正在构建一个社区 dashboard,在 Home Assistant 能在新 dashboard 对话框中显示它之前,必须加载该 resource。添加或更新 resource 后,刷新 Home Assistant 并重新打开对话框。 关于完整的 dashboard strategy 和选择器注册流程,请参见 [custom strategies](/developers/frontend/custom-ui/custom-strategy.md)。 --- url: /developers/frontend/data.md --- 前端传递单个 `hass` 对象。此对象包含最新状态,允许你向后端发送命令,并提供用于格式化实体状态的辅助方法。 只需要这些数据中一部分的组件,应改为使用相关的 [context](#context)。 每当状态发生变化时,都会创建发生变化的对象的新版本。因此,你只需进行一次严格相等性检查,即可轻松判断某项内容是否发生了变化: ```js const changed = newVal !== oldVal; ``` 如需查看 `hass` 对象中可用的数据,请使用你喜欢的浏览器打开 Home Assistant 前端,然后打开浏览器的开发者工具。在 elements 面板中,选择 `` 元素,或者任何带有 `hass` 属性的元素,然后在 console 面板中运行以下命令: ```js $0.hass ``` 读取 `hass` 对象的此方法仅应作为参考。要在代码中与 `hass` 交互,请确保它被正确地传递到你的代码中。 ## 数据 ### 上下文 组件获取 Home Assistant 特定部分数据的方式是消费可用的 Lit context 之一。你也可以创建本地 context,用于在组件树内传递数据。 使用 Lit 的 `@consume` 装饰器向 context provider 注册。provider 会发送初始值,当设置 `subscribe: true` 时,会在值发生变化时发送更新。 #### 可用的 contexts contexts 从 `src/data/context/index.ts` 导出: * `statesContext`:所有实体的 states * `servicesContext`:可用的 service actions * `registriesContext`:entity、device、area 和 floor registries * `entitiesContext`、`devicesContext`、`areasContext` 和 `floorsContext`:单个 registry 数据 * `internationalizationContext`:本地化、locale 设置、translation metadata 和 translation loaders * `apiContext`:HTTP 和 WebSocket API 方法 * `connectionContext`:WebSocket 连接状态 * `uiContext`:themes、panels、sidebar 设置以及其他全局 UI 状态 * `configContext`:Home Assistant 配置、认证和用户数据 * `formattersContext`:实体状态、属性和名称的格式化方法 * `narrowViewportContext`:主 viewport 是否使用窄布局 某些 contexts 仅在组件首次消费时加载。这些包括 `labelsContext`、`fullEntitiesContext`、`configEntriesContext`、`manifestsContext`、`triggerDescriptionsContext` 和 `conditionDescriptionsContext`。它们的后端订阅会在最后一个订阅组件断开后移除。 #### 在 Lit 中消费 context ```ts @consume({ context: labelsContext, subscribe: true }) @state() private _labels?: LabelRegistryEntry[]; ``` ### `hass.states` 一个包含 Home Assistant 中所有实体状态的对象。键为 entity\_id,值为 state object。 ```json { "sun.sun": { "entity_id": "sun.sun", "state": "above_horizon", "attributes": { "next_dawn": "2018-08-18T05:39:19+00:00", "next_dusk": "2018-08-17T18:28:52+00:00", "next_midnight": "2018-08-18T00:03:51+00:00", "next_noon": "2018-08-18T12:03:58+00:00", "next_rising": "2018-08-18T06:00:33+00:00", "next_setting": "2018-08-17T18:07:37+00:00", "elevation": 60.74, "azimuth": 297.69, "friendly_name": "Sun" }, "last_changed": "2018-08-17T13:46:59.083836+00:00", "last_updated": "2018-08-17T13:49:30.378101+00:00", "context": { "id": "74c2b3b429c844f18e59669e4b41ec6f", "user_id": null }, }, "light.ceiling_lights": { "entity_id": "light.ceiling_lights", "state": "on", "attributes": { "min_mireds": 153, "max_mireds": 500, "brightness": 180, "color_temp": 380, "hs_color": [ 56, 86 ], "rgb_color": [ 255, 240, 35 ], "xy_color": [ 0.459, 0.496 ], "white_value": 200, "friendly_name": "Ceiling Lights", "supported_features": 151 }, "last_changed": "2018-08-17T13:46:59.129248+00:00", "last_updated": "2018-08-17T13:46:59.129248+00:00", "context": { "id": "2c6bbbbb66a84a9dae097b6ed6c93383", "user_id": null }, } } ``` ### `hass.user` 当前登录的用户。 ```json { "id": "758186e6a1854ee2896efbd593cb542c", "name": "Paulus", "is_owner": true, "is_admin": true, "credentials": [ { "auth_provider_type": "homeassistant", "auth_provider_id": null } ] } ``` ## 方法 所有以 `call` 开头的方法都是异步方法。这意味着它们将返回一个 `Promise`,该 Promise 会在调用结果产生时 resolve。 ### `hass.callService(domain, service, data)` 在后端调用一个 service action。 ```js hass.callService('light', 'turn_on', { entity_id: 'light.kitchen' }); ``` ### `hass.callWS(message)` 在后端调用一个 WebSocket 命令。 ```js this.hass.callWS({ type: 'config/auth/create', name: 'Paulus', }).then(userResponse => console.log("Created user", userResponse.user.id)); ``` ### `hass.callApi(method, path, data)` 在 Home Assistant 服务器上调用 API。例如,如果你想通过向 `/api/hassio/backups` 发送 GET 请求来获取所有 Home Assistant 备份: ```js hass.callApi('get', 'hassio/backups') .then(backups => console.log('Received backups!', backups)); ``` 如果需要传入数据,请传递第三个参数: ```js hass.callApi('delete', 'notify.html5', { subscription: 'abcdefgh' }); ``` :::info 我们正在逐步远离 API 调用,并将所有内容迁移到 `hass.callWS(message)` 调用。 ::: ## 实体状态格式化 这些方法允许你对实体的状态和属性进行格式化。该值会根据用户个人档案设置(语言、数字格式、日期格式、时区)和计量单位进行本地化。 ### `hass.formatEntityState(stateObj, state)` 格式化实体的状态。你需要传入 entity state object。 ```js hass.formatEntityState(hass.states["light.my_light"]); // "On" ``` 你可以使用第二个可选参数强制指定状态值。 ```js hass.formatEntityState(hass.states["light.my_light"], 'off'); // "Off" ``` ### `hass.formatEntityAttributeValue(stateObj, attribute, value)` 格式化实体的属性值。你需要传入 entity state object 和属性名。 ```js hass.formatEntityAttributeValue(hass.states["climate.thermostat"], "current_temperature"); // "20.5 °C" ``` 你可以使用第三个可选参数强制指定状态值。 ```js hass.formatEntityAttributeValue(hass.states["climate.thermostat"], "current_temperature", 18); // "18 °C" ``` ### `hass.formatEntityAttributeName(stateObj, attribute)` 格式化实体的属性名。你需要传入 entity state object 和属性名。 ```js hass.formatEntityAttributeName(hass.states["climate.thermostat"], "current_temperature"); // "Current temperature" ``` ### `hass.formatEntityName(stateObj, name, options)` *自 Home Assistant 2026.4 起可用。* 根据实体的 registry context(entity、device、area、floor)格式化实体的显示名称。这是内置卡片(tile、entity rows 等)所使用的同一辅助方法,因此自定义卡片可以生成一致的标签。 `name` 参数可以是: * 一个普通的 `string` —— 按原样返回。用于尊重用户提供的自定义值。 * 单个名称项,例如 `{ type: "entity" }`。 * 名称项数组,通过分隔符连接。项可以引用 registry 数据(`entity`、`device`、`area`、`floor`),也可以是字面量 `text`。 * `undefined` —— 回退到实体的 friendly name。 ```ts type EntityNameItem = | { type: "entity" | "device" | "area" | "floor" } | { type: "text"; text: string }; interface EntityNameOptions { separator?: string; // 默认为 " " } ``` 以下示例假设 `sensor.living_room_thermostat_temperature` 是一个 thermostat device 的温度传感器,其中: * entity name: `Temperature` * device name: `Thermostat` * area: `Living room` * floor: `Ground floor` ```js const stateObj = hass.states["sensor.living_room_thermostat_temperature"]; // Friendly name 回退 hass.formatEntityName(stateObj, undefined); // "Thermostat Temperature" // 用户提供的自定义值 hass.formatEntityName(stateObj, "Indoor temperature"); // "Indoor temperature" // 单个 registry 项 hass.formatEntityName(stateObj, { type: "entity" }); // "Temperature" hass.formatEntityName(stateObj, { type: "area" }); // "Living room" // 使用自定义分隔符的组合显示 hass.formatEntityName( stateObj, [{ type: "device" }, { type: "entity" }], { separator: " · " } ); // "Thermostat · Temperature" // 混合使用字面文本和 registry 项 hass.formatEntityName( stateObj, [{ type: "text", text: "Floor:" }, { type: "floor" }] ); // "Floor: Ground floor" ``` #### 在自定义卡片中使用 一种常见模式是在卡片配置中接受 `name` 选项,并将其直接传递给 `formatEntityName`。这样用户既可以提供字符串,也可以使用结构化形式来组合 registry 数据。 ```yaml type: custom:my-card entity: sensor.living_room_thermostat_temperature name: - type: area - type: entity ``` 在卡片类内部: ```js setConfig(config) { if (!config.entity) { throw new Error("You need to define an entity"); } this._config = config; } render() { const stateObj = this.hass.states[this._config.entity]; const name = this.hass.formatEntityName(stateObj, this._config.name); return html`
${name}
`; } ``` #### 在可视化编辑器中编辑 前端自带一个 `entity_name` selector,它生成的值符合 `formatEntityName` 所接受的格式。在使用 [内置表单编辑器](/developers/frontend/custom-ui/custom-card.md#using-the-built-in-form-editor) 的卡片中,通过 `context` 引用 entity 字段,这样 selector 就能知道针对哪个实体来解析 registry context: ```js { name: "name", selector: { entity_name: {}, }, context: { entity: "entity", }, } ``` selector 生成的值与 `formatEntityName` 所接受的格式一致:要么是一个普通字符串(自由格式的自定义名称),要么是一个或多个 `EntityNameItem` 条目(由 registry 数据组合而成)。selector UI 允许用户在两种模式之间切换。 selector 接受两个选项: * `entity_id`:硬编码用于预览名称的 entity(覆盖 `context.entity`)。 * `default_name`:字段为空时显示的值。接受与 `string | EntityNameItem | EntityNameItem[]` 相同的格式。 --- url: /developers/frontend/design.md --- 我们在 维护一个设计门户,提供有关前端各个方面的信息,例如: * 可以复用的 UI 组件。 * 各种配置和状态下的 Dashboard 卡片。 * 在浅色和深色主题之间对比组件和卡片的便捷方式。 * 关于 Home Assistant 中特定措辞的说明。 当向前端添加新组件或新功能时,需要将其添加到设计门户中。此门户页面说明了具体操作方法: :::note 虽然门户在公开命名上称为 "design",但在前端仓库中被称为 "gallery"。因此,源代码位于 `gallery/src`,你可以使用 `yarn dev:gallery` 在本地运行 gallery(它是 `gallery/script/develop_gallery` 的一个包装器)。它通过 http://localhost:8100 提供服务,并接受与其他 dev server 相同的 [background lifecycle flags](/developers/frontend/development.md#managing-the-dev-server-in-the-background)。 ::: --- url: /developers/frontend/development.md --- Home Assistant 前端基于 web components 构建。关于我们的技术选择的更多背景信息,[请参阅这篇博客](https://developers.home-assistant.io/blog/2019/05/22/internet-of-things-and-the-modern-web.html)。 :::caution 不要在生产环境中使用开发模式。Home Assistant 使用激进的缓存来改善移动端体验。在开发期间会禁用该缓存,这样你就不需要在每次更改之间重新启动服务器。 ::: ## 设置环境 首先按照我们的 [devcontainer 开发环境](/developers/setup_devcontainer_environment.md) 指南,设置一个合适的开发环境。 ### 获取代码 第一步是将 [frontend 仓库][hass-frontend] fork 到你的账户,并添加 upstream remote。你可以将 fork 后的仓库放在系统上的任意位置。 ```shell git clone git@github.com:YOUR_GIT_USERNAME/frontend.git cd frontend git remote add upstream https://github.com/home-assistant/frontend.git ``` ### 配置 Home Assistant 你需要先设置好一个 Home Assistant 实例。开发实例请参考我们的 [设置开发环境](/developers/development_environment.md) 指南。 有两种方式可以测试前端:一种是运行开发实例 Home Assistant Core,另一种是配置前端以连接到一个已有的 Home Assistant 实例。第一种方式与其在生产环境中的工作方式一致。第二种方式允许以最小干扰的方式在已有 Home Assistant 上运行开发前端。缺点是无法测试所有功能。例如,登录页面将始终是你 Home Assistant 内置的那个。 import Tabs from '@theme/Tabs' import TabItem from '@theme/TabItem' #### 使用 Visual Studio Code + dev container 进行开发 要配置 Home Assistant 使其前端使用开发模式,请更新 `configuration.yaml` 中的前端配置,并将其设置为上一步中克隆的 frontend 仓库路径: 如果你在使用 Visual Studio Code 配合 dev containers 开发 Home Assistant Core,你需要将 frontend 仓库挂载到 dev container 中。将以下内容添加到 Home Assistant Core 仓库中的 `.devcontainer/devcontainer.json`: ```json "mounts": [ "source=/path/to/hass/frontend,target=/workspaces/frontend,type=bind,consistency=cached" ] ``` 按 Shift+Command+P(Mac)/ Ctrl+Shift+P(Windows/Linux)打开 Command Palette,然后选择 **Dev Containers: Rebuild Container** 命令,以重新构建 dev container。 在 Home Assistant Core 仓库根目录下编辑 `config/configuration.yaml`,添加以下条目: ```yaml frontend: development_repo: /workspaces/frontend ``` :::note 这是 dev container 内部的挂载路径,请参见上面的 `target` 参数。如果 `source` 路径不正确,web 前端将无法工作。 ::: 在 VS Code 中运行 Home Assistant Core: 1. 打开 Command Palette: * Mac: `Shift+Command+P` * Windows/Linux: `Ctrl+Shift+P` 2. 选择 **Tasks: Run Task** 3. 选择 **Run Home Assistant Core** :::caution 对 `.devcontainer/devcontainer.json` 的更改应从任何 PR 中排除,因为它包含你本地 `frontend` 仓库的路径。由于 `.devcontainer/devcontainer.json` 中的设置仅在容器重新构建时处理,因此在重新构建完成后,你可以安全地回滚该更改。 ::: #### 使用手动环境进行开发 如果你是手动为 Home Assistant Core 设置开发环境,请在 `configuration.yaml` 中填写 frontend 仓库路径: ```yaml frontend: # 示例路径: /home/paulus/dev/hass/frontend development_repo: /path/to/hass/frontend ``` :::tip `configuration.yaml` 文件位于 Home Assistant Core 仓库根目录下的 `config` 目录中。如果路径不正确或无法访问,web 前端将无法工作。 ::: 如果你想将开发前端连接到一个已有的 Home Assistant 实例,而不完全替换其 UI,你需要在你将要连接的 Home Assistant 的 `configuration.yaml` 中添加开发前端的主机地址,如下所示: ```yaml http: cors_allowed_origins: - http://localhost:8124 ``` 一旦前端开发环境设置完成(参见 [Development](#development) 部分),你可以使用以下命令替代标准 dev server。它会在 `http://localhost:8124` 上开发和运行前端,并连接到运行在 `http://localhost:8123` 的 Home Assistant。注意,如果你是从 devcontainer 运行此命令,则 URL 应能从容器主机访问。 ```shell yarn dev:serve ``` 你可以通过传递 `-c` 选项来更改前端连接的 Home Assistant URL。这对于已有的生产核心实例同样适用。它不必是托管在本地上的开发版本。但是,如果你更改此选项的值,你需要先退出开发前端,它才会真正切换到新值。例如: ```shell yarn dev:serve -c http://homeassistant.local ``` 你可以通过传递 `-p` 选项来更改前端服务的端口。注意,如果你从 devcontainer 运行,还需要设置端口转发才能从容器主机访问它。例如: ```shell yarn dev:serve -p 8654 ``` :::note 如果你连接到一个生产环境的 Home Assistant 实例并使用 `-p` 更改端口,请确保 `cors_allowed_origins` 中包含带有对应端口的 frontend origin。对于上面的 `yarn dev:serve -p 8654` 示例,应添加 `http://localhost:8654` 而非 `http://localhost:8124`。 ::: :::note 它还接受 [在后台管理 dev server](#managing-the-dev-server-in-the-background) 中描述的 background lifecycle flags。 ::: ### 安装 Node.js(仅手动环境) 构建前端需要 Node.js。安装 node.js 的推荐方式是使用 [nvm](https://github.com/nvm-sh/nvm)。按照 [README](https://github.com/nvm-sh/nvm#install--update-script) 中的说明安装 nvm,然后运行以下命令安装正确的 node.js: ```shell nvm install ``` [Yarn](https://yarnpkg.com/en/) 用作 node modules 的包管理器。[请按照此处说明安装 yarn。](https://yarnpkg.com/getting-started/install) ### 安装开发依赖项 通过安装开发依赖项来引导前端开发环境。 ```shell nvm use script/bootstrap ``` :::note 如果你正在使用开发容器,请在容器内部运行这些命令。 ::: ## 开发 ### 运行开发服务器 运行以下命令以构建前端并运行开发服务器: ```shell nvm use yarn dev --fetch-translations ``` 当构建完成且 Home Assistant Core 已正确设置后,前端将可以通过 `http://localhost:8123` 访问。当你修改源文件时,服务器会自动重新构建前端。 :::note `yarn dev` 是 `script/develop` 脚本的一个包装器。两者仍然都可用,但 `yarn dev` 添加了下面描述的 background lifecycle flags。 ::: ### 在已有的 HA 实例上运行开发前端 运行以下命令以启动开发服务器: ```shell nvm use yarn dev:serve --fetch-translations -c http://homeassistant.local ``` 你可能需要将 `http://homeassistant.local` 替换为你本地的 Home Assistant URL。`http://homeassistant.local` 假设的是使用默认端口 80 的 Home Assistant OS 安装;较旧的安装以及其他安装类型通常使用端口 8123(例如 `http://homeassistant.local:8123`)。 ### 在后台管理 dev server 上述两个 dev server(以及下面的 demo、gallery 和端到端测试应用的 dev server)都接受一组生命周期标志。这让你可以启动服务器、让它保持运行,并在之后管理它,而无需保持终端会话处于附加状态: | Flag | 作用 | | ------------------- | --------------------------------------------------------------------------------------------------------------------------- | | `--background` | 在分离状态下启动服务器,等待其就绪,打印其 URL(如果有)和 pid,然后退出并让其继续运行。 | | `--status` | 报告 dev server 是否在运行。 | | `--logs [--follow]` | 打印 dev server 日志,或使用 `--follow` 进行 tail。 | | `--stop` | 停止正在运行的后台 dev server。 | app、本地托管的 app、demo 和 gallery 命令也接受 `--fetch-translations`。这会在启动服务器前获取最新的翻译,并且在没有保存的 token 时提示进行 GitHub 授权。翻译获取在前台和后台模式下都使用同一个工作流锁。 如果之前的授权已不再有效(例如,你看到 "Bad Credentials" 错误),请删除 `translations/token.json`,然后再次使用 `--fetch-translations` 启动其中一个命令。 例如: ```shell yarn dev:serve --background # 启动并分离 yarn dev:serve --logs --follow # 监视输出 yarn dev:serve --stop # 停止它 ``` 每个 dev server 都有自己的监听端口: | Command | 端口 | 用途 | | ----------------------- | ---- | ------------------------------------------------------------------------ | | `yarn dev` | 8123 | 由运行中的 Home Assistant Core(`development_repo`)提供的 app。 | | `yarn dev:serve` | 8124 | 在已有的 Home Assistant 实例上本地提供的 app。 | | `yarn dev:demo` | 8090 | [Demo](https://demo.home-assistant.io/)。 | | `yarn dev:gallery` | 8100 | [设计图库](/developers/frontend/design.md)。 | | `yarn test:e2e:app:dev` | 8095 | [端到端测试](#end-to-end-tests) 使用的精简版 app。 | 这些受管理的 Yarn 开发工作流,连同 `yarn build` 和 `yarn build --modern`,共享一个工作流锁。再次启动同一个开发工作流会报告正在运行的服务器并成功。在已有工作流处于活动状态时启动另一个受管理工作流会被阻止,并报告带有相关状态、日志或停止命令的活动工作流。 :::note 当检测到 coding agent 时,`yarn dev:*` 会自动在后台运行,以免阻塞 agent 的会话。设置 `HA_DEV_BACKGROUND=0` 可强制 dev server 在前台运行。 冷构建最多等待 180 秒以变为就绪状态;可以通过 `HA_DEV_SERVER_TIMEOUT`(单位为秒)覆盖此值。 后台日志写入到 `node_modules/.cache/ha-dev-server/` 下。 ::: ### 浏览器设置 打开 Google Chrome 的开发者工具,并确保已禁用缓存并设置了正确的选项以避免陈旧内容: :::info 说明适用于基于 Google Chrome 的浏览器,但同样适用于其他浏览器。你应该能在你所选浏览器中找到类似的设置。 ::: 1. 勾选 **Network** > **Disable cache** 中的复选框以禁用缓存

2. 在 **Application** > **Service Workers** > **Bypass for network** 中启用网络绕过

## 测试 在提交 pull request 之前,请运行 linters 和测试。这些命令都从 frontend 仓库中运行。 ### Linting 和格式化 ```shell yarn lint # ESLint, Prettier, TypeScript, and Lit analyzer yarn format # 自动修复 ESLint 和 Prettier 问题 yarn lint:types # 仅运行 TypeScript 编译器 ``` :::warning 始终在不带文件参数的情况下运行 `yarn lint:types`(和 `tsc`)。传递文件名(例如 `yarn lint:types src/file.ts`)会使 `tsc` 忽略 `tsconfig.json`,并在 `src/` 中每个 `.ts` 源文件旁边生成编译后的 `.js` 文件,从而污染源码树。如果发生了这种情况,请使用 `git clean -fd src/` 删除多余的文件。 ::: ### 单元测试 单元测试使用 [Vitest](https://vitest.dev/) 运行: ```shell yarn test # 运行单元测试 yarn test:coverage # 带覆盖率报告地运行 ``` ### 端到端测试 端到端测试使用 [Playwright](https://playwright.dev/) 运行,分为三个套件,每个套件都有各自的 dev server: * **App**:主 app,针对专为端到端测试构建的精简 harness 进行测试。 * **Demo**:[demo](https://demo.home-assistant.io/)。 * **Gallery**:[设计图库](/developers/frontend/design.md)。 | Suite | Dev server | Test command | 运行端口 | | ------- | ----------------------- | ----------------------- | ------------ | | App | `yarn test:e2e:app:dev` | `yarn test:e2e:app` | 8095 | | Demo | `yarn dev:demo` | `yarn test:e2e:demo` | 8090 | | Gallery | `yarn dev:gallery` | `yarn test:e2e:gallery` | 8100 | 先启动套件的 dev server(理想情况下使用 [background lifecycle flags](#managing-the-dev-server-in-the-background)),然后运行该套件。Playwright 会复用已在端口上运行的 dev server,而不是进行缓慢的完整构建,而 watcher 会在保存时重新编译,因此你可以在无需重启任何东西的情况下进行迭代: ```shell # App yarn test:e2e:app:dev --background # 启动 dev server 并分离 yarn test:e2e:app # 运行套件 # Demo yarn dev:demo --background yarn test:e2e:demo # Gallery yarn dev:gallery --background yarn test:e2e:gallery ``` 使用 `-g` 将运行范围缩小到匹配的测试,使用 `--project` 缩小到单个项目: ```shell yarn test:e2e:app -g "more-info" --project=chromium # 桌面版 Chromium(匹配 "more-info") yarn test:e2e:app -g "more-info" --project=mobile-chrome # Pixel 7(匹配 "more-info") ``` `yarn test:e2e` 运行全部三个套件,而 `yarn test:e2e:show-report` 打开合并的 HTML 报告。 ## 创建 pull requests 如果你计划向 Home Assistant 代码库提交 PR,你需要 fork frontend 项目,并将你的 fork 作为 remote 添加到 Home Assistant frontend 仓库中。 ```shell git remote add fork ``` 完成更改并准备好推送后,切换到 frontend 项目的目录,然后推送你的更改 ```bash git add -A git commit -m "Added new feature X" git push -u fork HEAD ``` ## 构建前端 如果你对前端的打包方式进行了更改,可能需要在主仓库中尝试使用一个新的打包好的前端构建(而不是指向 frontend 仓库)。从 frontend 仓库运行完整的生产构建: ```shell yarn build ``` 生产构建也可以作为受管理的后台进程运行: ```shell yarn build --background # 启动完整构建并分离 yarn build --status # 报告是否有构建正在进行 yarn build --logs # 打印后台构建日志 yarn build --logs --follow # 跟踪后台构建日志 yarn build --stop # 停止正在运行的后台构建 ``` 在进行打包、bundle-size 或浏览器性能相关工作时,如果只需要现代的 `frontend_latest` bundle,请使用 `yarn build --modern`。添加 `--background` 可将仅现代构建作为受管理的后台进程运行。 :::caution 受管理的生产构建不能与受管理的开发服务器同时运行。在启动另一个受管理工作流之前,请使用其对应的 `--stop` 命令停止活动工作流。 ::: 要在 Home Assistant 内部进行测试,从主 Home Assistant 仓库运行以下命令: ```shell pip3 install -e /path/to/hass/frontend/ --config-settings editable_mode=compat hass --skip-pip-packages home-assistant-frontend ``` [hass-frontend]: https://github.com/home-assistant/frontend ## 测试已有的 PR 有时你需要在不同的环境中测试前端更改,或者在不设置完整开发环境的情况下进行测试。例如,你可能想在 Home Assistant OS 实例上测试更改,或者在 PR 合并之前验证修复是否在你的特定设置中有效。 `development_pr` 选项允许你通过自动下载并使用来自 GitHub 的 frontend artifact 来轻松测试 frontend PR。 ### 配置 要使用此功能,你需要一个 PR 编号和一个 GitHub token。 #### 创建 GitHub token 1. 转到 [GitHub Settings > Developer Settings > Personal Access Tokens > Fine-grained tokens](https://github.com/settings/personal-access-tokens) 2. 点击 "Generate new token" 3. 给它一个描述性的名称,例如 "Home Assistant Frontend Testing" 4. 设置过期日期(建议:90 天或更短) 5. 在 "Repository access" 下,选择 "Public Repositories (read-only)" 6. 跳过 "Permissions" 部分(保持为空) 7. 点击 "Generate token" 8. 立即复制该 token(之后将无法再次查看) #### 在 Home Assistant 中配置 将以下内容添加到你的 `configuration.yaml`: ```yaml frontend: development_pr: github_token: ``` 例如,要测试 PR #12345: ```yaml frontend: development_pr: 12345 github_token: ghp_your_token_here ``` 添加此配置后,重启 Home Assistant 使更改生效。 :::warning 妥善保管你的 GitHub token。不要将其提交到版本控制或公开分享。 ::: #### 恢复为生产前端 要停止使用 PR 构建并返回到标准的 Home Assistant 前端: 1. 从你的 `configuration.yaml` 中删除 `development_pr` 和 `github_token` 行 2. 重启 Home Assistant Home Assistant 将自动恢复到使用内置的生产前端。 ### 工作原理 当你配置 `development_pr` 时,Home Assistant 会在启动期间从 GitHub 上指定的 PR 下载 frontend build artifact,并使用它来替代生产版本。该 artifact 会在本地缓存,在随后的重启中,Home Assistant 会通过比较 SHA 和来检查该 PR 是否有新的 commit。如果发现了更新版本,它会自动下载更新后的 artifact。 :::info 如果你同时配置了 `development_repo` 和 `development_pr`,`development_repo` 优先。将使用本地开发仓库,而不是 PR 构建。 ::: ### 使用场景 这在以下场景下特别有用: * **在 HAOS 上测试**:在 Home Assistant OS 上测试 PR,而无需开发环境 * **特定环境的测试**:验证修复是否在你的特定硬件、网络或浏览器配置上有效 * **快速验证**:在无需克隆仓库和在本地构建前端的情况下测试修复或功能 ### 限制 * PR 必须在 GitHub 上具有带有可用 artifacts 的成功构建 * Frontend artifacts 仅在 PR 构建完成后的 7 天内可用 * 此功能仅用于测试,不应在生产环境中使用 #### 重新创建 artifact 如果 artifact 已不再可用(例如因为它已经超过了 7 天),或者你想测试 PR 中新的上游更改,这会非常有用。 如果你是 PR 的作者,你可以通过以下方式触发新的 artifact: * 更新你的分支——将其与 `dev` 分支合并,或在最新的 `dev` 分支之上 rebase。这将触发构建管道并创建一个新的 artifact,供 Home Assistant 下载。 * 关闭并重新打开 PR 以触发新的构建。 如果你不是作者,可以要求作者更新其 PR 分支以触发新的构建。 :::info 要使用新的 artifact,你需要重启 Home Assistant core ::: --- url: /developers/frontend/extending/adding-more-info-dialogs.md --- 每当用户点击或选中一张卡片时,都会显示一个 more info 对话框。此对话框的 header 将是 state card,紧接着是过去 24 小时该 entity 的历史记录。在这之下会渲染该 entity 的 more info component。More info component 可以显示更多信息或允许更多的控制方式。 一个 light 的 more info 对话框允许用户控制颜色和亮度。 添加 more info 对话框的说明与添加新的卡片类型非常相似。本示例将为 domain `camera` 添加一个新的 more info component: 1. 在文件 [/common/const.ts](https://github.com/home-assistant/frontend/blob/dev/src/common/const.ts) 中,将 `'camera'` 添加到数组 `DOMAINS_WITH_MORE_INFO`。 2. 在文件夹 [/dialogs/more-info/controls](https://github.com/home-assistant/frontend/tree/dev/src/dialogs/more-info/controls) 中创建文件 `more-info-camera.js`。 3. 在 [/dialogs/more-info/more-info-content.ts](https://github.com/home-assistant/frontend/blob/dev/src/dialogs/more-info/more-info-content.ts) 中添加 `import './more-info-camera.js';` --- url: /developers/frontend/extending/adding-state-card.md --- Home Assistant 的主界面是一个列出当前 entities 及其状态的列表。对于系统中的每个 entity,都会渲染一张 state card。State card 会显示一个图标、entity 的名称、状态上次更改的时间以及当前状态,或一个用于与之交互的控件。 ![Cards in the frontend](/img/en/frontend/frontend-cards1.png) 不同的卡片类型可以在[这里](https://github.com/home-assistant/frontend/tree/dev/src/state-summary)找到。 未分组的 Sensors 会作为所谓的 badge 显示在 state card 的顶部。 ![Badges in the frontend](/img/en/frontend/frontend-badges.png) 不同的 badge 位于文件 [`/src/components/entity/ha-state-label-badge.ts`](https://github.com/home-assistant/frontend/blob/dev/src/components/entity/ha-state-label-badge.ts) 中。 添加自定义卡片类型只需几个简单步骤。在此示例中,我们将为 domain `camera` 添加一个新的 state card: 1. 在文件 [/common/const.ts](https://github.com/home-assistant/frontend/blob/dev/src/common/const.ts) 中,将 `'camera'` 添加到数组 `DOMAINS_WITH_CARD`。 2. 在文件夹 [/state-summary/](https://github.com/home-assistant/frontend/tree/dev/src/state-summary) 中创建文件 `state-card-camera.ts`。 3. 在 [state-card-content.ts](https://github.com/home-assistant/frontend/blob/dev/src/state-summary/state-card-content.ts) 中添加 `import './state-card-camera.ts';`。 --- url: /developers/frontend/extending/websocket-api.md --- 作为 component,你可能有想要让前端可用的信息。例如,media player 会希望将专辑封面提供给前端显示。我们的前端通过 websocket API 与后端通信,该 API 可以扩展自定义命令。 ## 注册命令(Python) 要注册一个命令,你需要一个 message type、一个 message schema 和一个 message handler。你的 component 不必将 websocket API 添加为依赖。注册命令后,如果用户正在使用 websocket API,该命令将变得可用。 ### 定义你的命令 schema Command schema 由一个 message type 和命令被调用时期望的数据类型组成。你在命令 handler 上通过 decorator 定义命令类型和数据 schema。Message handlers 是在 event loop 中运行的回调函数。 ```python from homeassistant.components import websocket_api @websocket_api.websocket_command( { vol.Required("type"): "frontend/get_panels", vol.Optional("preload_panels"): bool, } ) @callback def ws_get_panels( hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict ) -> None: """处理 websocket 命令""" panels = ... connection.send_result(msg["id"], {"panels": panels}) ``` #### 执行 I/O 或发送延迟响应 如果你的命令需要与网络或设备交互,或需要计算信息,你将需要排入一个 job 来完成工作并发送响应。为此,将你的函数设为 async 并使用 `@websocket_api.async_response` 进行装饰。 ```python from homeassistant.components import websocket_api @websocket_api.websocket_command( { vol.Required("type"): "camera/get_thumbnail", vol.Optional("entity_id"): str, } ) @websocket_api.async_response async def ws_handle_thumbnail( hass: HomeAssistant, connection: ActiveConnection, msg: dict ) -> None: """处理获取 media player 封面的命令""" # 使用传入的 entity id 获取 media player。 player = hass.data[DOMAIN].get_entity(msg["entity_id"]) # 如果 player 不存在,发送错误消息。 if player is None: connection.send_error( msg["id"], "entity_not_found", "Entity not found" ) return data, content_type = await player.async_get_media_image() # 没有可用的 media player 缩略图 if data is None: connection.send_error( msg["id"], "thumbnail_fetch_failed", "Failed to fetch thumbnail" ) return connection.send_result( msg["id"], { "content_type": content_type, "content": base64.b64encode(data).decode("utf-8"), }, ) ``` ### 在 WebSocket API 中注册 在定义了所有 component 之后,是时候注册命令了。这在你的 setup 方法内部完成。 ```python from homeassistant.components import websocket_api async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """设置你的 component。""" websocket_api.async_register_command(hass, ws_get_panels) websocket_api.async_register_command(hass, ws_handle_thumbnail) return True ``` ## 从前端调用命令(JavaScript) 定义了命令后,是时候从前端调用它了!这使用 JavaScript 完成。你需要能够访问持有与后端 WebSocket 连接的 `hass` 对象。然后只需调用 `hass.connection.sendMessagePromise`。这将返回一个 promise,命令成功时 resolve,命令失败时 error。 ```js hass.connection.sendMessagePromise({ type: 'media_player/thumbnail', entity_id: 'media_player.living_room_tv', }).then( (resp) => { console.log('Message success!', resp.result); }, (err) => { console.error('Message failed!', err); } ); ``` 如果你的命令不发送响应,可以使用 `hass.connection.sendMessage`。 --- url: /developers/frontend/external-authentication.md --- 默认情况下,前端会自行管理其认证 token。如果未找到 token,它会将用户重定向到登录页面,并负责更新 token。 如果你想在外部应用中嵌入 Home Assistant 前端,你会希望将认证信息存储在应用中,但同时让前端能够访问它。为此,Home Assistant 提供了一个外部认证 API。 要激活此 API,请在 URL 末尾附加 `?external_auth=1` 加载前端。如果传入了此参数,Home Assistant 将期望定义了 `window.externalAppV2`(Android V2,推荐)、`window.externalApp`(Android V1,备选)或 `window.webkit.messageHandlers`(iOS),并包含下面描述的方法。 :::note V2(`window.externalAppV2`)要求 WebView 支持 [`WebViewFeature.WEB_MESSAGE_LISTENER`][web-message-listener]。否则应用应回退到 V1。 ::: ## 获取 access token 当前端加载时,它会向外部认证请求一个 access token。它通过调用以下方法之一来实现。选项中包含要使用响应调用的回调方法,以及一个可选的 `force` 布尔值;无论 access token 是否已过期,如果它应该被刷新,该值设为 `true`。在 Android 上,选项以序列化 JSON 字符串的形式传递,而在 iOS 上,它们以对象的形式传递。 回调名称是稳定的,不会更改。应用应验证回调名称与预期值是否匹配,以确保回调未被伪造。 `force` 布尔值是在 Home Assistant 0.104 中引入的,可能并不总是可用。 ```js // Android V2(推荐) window.externalAppV2.postMessage( JSON.stringify({ type: "getExternalAuth", payload: { callback: "externalAuthSetToken", force: true }, }) ); // Android V1(备选) window.externalApp.getExternalAuth( JSON.stringify({ callback: "externalAuthSetToken", force: true }) ); // iOS window.webkit.messageHandlers.getExternalAuth.postMessage({ callback: "externalAuthSetToken", force: true, }); ``` 响应应包含一个布尔值,表示是否成功,以及一个包含 access token 及其有效秒数的对象。将响应传递给选项对象中定义的函数。 ```js // 由外部应用调用 window.externalAuthSetToken(true, { access_token: "qwere", expires_in: 1800 }); // 如果无法获取新的 access token window.externalAuthSetToken(false); ``` 当页面首次加载时,以及每当前端需要一个有效 token 但之前收到的 token 已过期时,前端都会调用此方法。 ## 撤销 token 当用户在个人资料页面上按下注销按钮时,外部应用必须[撤销 refresh token](auth_api.md#revoking-a-refresh-token),并将用户注销。 回调名称是稳定的,不会更改。应用应验证回调名称与预期值是否匹配,以确保回调未被伪造。 ```js // Android V2(推荐) window.externalAppV2.postMessage( JSON.stringify({ type: "revokeExternalAuth", payload: { callback: "externalAuthRevokeToken" }, }) ); // Android V1(备选) window.externalApp.revokeExternalAuth( JSON.stringify({ callback: "externalAuthRevokeToken" }) ); // iOS window.webkit.messageHandlers.revokeExternalAuth.postMessage({ callback: "externalAuthRevokeToken", }); ``` 完成后,外部应用必须调用选项对象中定义的函数。 ```js // 由外部应用调用 window.externalAuthRevokeToken(true); // 如果无法注销 window.externalAuthRevokeToken(false); ``` [web-message-listener]: https://developer.android.com/reference/androidx/webkit/WebViewCompat.WebMessageListener --- url: /developers/frontend/external-bus.md --- 前端能够与一个嵌入 Home Assistant 前端的外部应用建立一个 message bus。该系统是 [external authentication](frontend/external-authentication.md) 的泛化,使未来更容易添加更多命令,而无需在应用或前端两端进行大量接线工作。 ## 消息交换 与 external auth 类似,消息交换是通过外部应用提供一个 JavaScript 方法来实现的。 消息以序列化 JSON 对象的形式传递给外部应用。将被调用的函数接受单个参数:一个字符串。外部应用必须处理该消息并相应地处理它(或忽略它)。 在 Android 上,实现方式取决于 WebView 的功能: **V2(推荐)**:使用 [`WebViewFeature.WEB_MESSAGE_LISTENER`][web-message-listener] 进行安全的来源验证。前端使用注入的 V2 对象发送消息: ```ts window.externalAppV2.postMessage(message: string) ``` **V1(备选)**:当 WebView 不支持 [`WebViewFeature.WEB_MESSAGE_LISTENER`][web-message-listener] 时使用。你的应用需要定义: ```ts window.externalApp.externalBus(message: string) ``` 在 iOS 上,你的应用需要定义以下方法: ```ts window.webkit.messageHandlers.externalBus.postMessage(message: string); ``` 要将消息发送到前端,请将消息序列化为 JSON,并从外部应用调用以下函数: ```ts window.externalBus(message: string) ``` ## 消息格式 消息描述了一个发送方希望接收方执行或知晓的操作或信息。如果它是一个操作,发送方将期望收到包含该操作结果的响应。对命令的响应可以是成功或失败。 ### Action 和 info 消息格式 包含或提供信息的消息格式是相同的。它包含一个标识符、一个类型和一个可选的 payload(取决于类型)。 结果消息会在响应中重用标识符,以指示该响应对应于哪个操作。 消息的基本格式如下: ```ts { id: number; type: string; payload?: unknown; } ``` 一条示例消息: ```json { "id": 5, "type": "config/get" } ``` ### 结果消息格式 如果该消息是一个操作,发送方将期望收到包含结果的响应。响应要么是成功,要么是失败。 结果的类型取决于它所响应的消息类型。例如,如果它响应的消息类型是 `config/get`,则结果应为一个描述配置的对象。 消息格式: ```ts interface SuccessResult { id: number; type: "result"; success: true; result: unknown; } interface ErrorResult { id: number; type: "result"; success: false; error: { code: string; message: string; }; } ``` ## 支持的消息 消息按方向组织:从 frontend 到 app,以及从 app 到 frontend。 ### 从 frontend 到 app 的消息 这些消息从 Home Assistant 前端发送到外部应用。 #### 期望响应的消息 ##### `config/get` 查询外部应用的外部配置。外部配置用于自定义前端的体验。 Payload:无 期望响应: ```ts { hasSettingsScreen?: boolean; hasSidebar?: boolean; canWriteTag?: boolean; hasExoPlayer?: boolean; canCommissionMatter?: boolean; canImportThreadCredentials?: boolean; canTransferThreadCredentialsToKeychain?: boolean; hasAssist?: boolean; hasBarCodeScanner?: number; canSetupImprov?: boolean; appVersion?: string; hasEntityAddTo?: boolean; hasAssistSettings?: boolean; } ``` * `hasSettingsScreen`:如果外部应用在收到 `config_screen/show` 时会显示配置屏幕,则设为 true * `hasSidebar`:如果外部应用有 sidebar,则设为 true * `canWriteTag`:如果外部应用可以写入 NFC tag(即设备有 NFC 硬件),则设为 true * `hasExoPlayer`:如果应用支持通过 ExoPlayer 进行 HLS 视频播放,则设为 true * `canCommissionMatter`:如果应用可以 commission Matter 设备,则设为 true * `canImportThreadCredentials`:如果应用可以导入 Thread 凭据,则设为 true * `canTransferThreadCredentialsToKeychain`:如果应用可以将 Thread 凭据转移到 keychain(仅限 Apple),则设为 true * `hasAssist`:如果应用有原生的 Assist 界面(取代前端实现),则设为 true * `hasBarCodeScanner`:如果应用有条码扫描能力,则设为 `1`,否则设为 `0` * `canSetupImprov`:如果应用可以设置 Improv Wi-Fi 设备,则设为 true * `appVersion`:原生应用的版本字符串 * `hasEntityAddTo`:如果应用支持将实体添加到平台特定的位置(例如 homescreen widget),则设为 true * `hasAssistSettings`:如果应用有 Assist 设置屏幕,则设为 true ##### `entity/add_to/get_actions` 获取将实体添加到设备(例如 homescreen、watch face)的可用操作。 Payload: ```ts { entity_id: string; } ``` 期望响应: ```ts { actions: Array<{ enabled: boolean; name: string; details?: string; mdi_icon: string; app_payload: string; }>; } ``` * `enabled`:该操作当前是否可用 * `name`:操作的显示名称 * `details`:关于该操作的可选附加信息 * `mdi_icon`:操作的 Material Design Icon 标识符(例如,"mdi:car") * `app_payload`:要发送回 `entity/add_to` 以执行该操作的不透明字符串 #### 不期望响应的消息 ##### `assist/settings` 打开 Assist 设置屏幕。 Payload:无 ##### `assist/show` 显示原生的 Assist 界面。 Payload(可选): ```ts { pipeline_id: "preferred" | "last_used" | string; start_listening: boolean; } ``` * `pipeline_id`:要使用的 pipeline,或 "preferred"/"last\_used" 用于自动选择 * `start_listening`:是否立即开始监听 ##### `bar_code/close` 关闭条码扫描器。 Payload:无 ##### `bar_code/notify` 在条码扫描器中显示通知消息。 Payload: ```ts { message: string; } ``` ##### `bar_code/scan` 开始扫描条码。 Payload: ```ts { title: string; description: string; alternative_option_label?: string; } ``` * `title`:在扫描器 UI 中显示的标题(必填) * `description`:在扫描器 UI 中显示的说明文本(必填) * `alternative_option_label`:替代操作按钮的可选标签;如果未包含,则应隐藏替代操作按钮 ##### `config_screen/show` 显示外部应用的配置屏幕。 Payload:无 ##### `connection-status` 通知外部应用前端是否与 Home Assistant 已连接。 Payload: ```ts { event: "connected" | "auth-invalid" | "disconnected"; } ``` ##### `entity/add_to` 将实体添加到平台特定的位置(例如 homescreen widget)。 Payload: ```ts { entity_id: string; app_payload: string; } ``` * `entity_id`:要添加的实体 * `app_payload`:从 `entity/add_to/get_actions` 接收的不透明字符串 ##### `exoplayer/play_hls` 播放 HLS 视频流。 Payload: ```ts { url: string; muted: boolean; } ``` * `url`:HLS 流 URL * `muted`:是否以静音方式开始播放 ##### `exoplayer/resize` 调整 HLS 视频播放器的大小。 Payload: ```ts { left: number; top: number; right: number; bottom: number; } ``` * `left`:播放器左坐标 * `top`:播放器上坐标 * `right`:播放器右坐标 * `bottom`:播放器下坐标 ##### `exoplayer/stop` 停止 HLS 视频播放。 Payload:无 ##### `focus_element` 聚焦前端中的特定元素。 Payload: ```ts { element_id: string; } ``` * `element_id`:要聚焦元素的 ID ##### `haptic` 通知外部应用触发 haptic 反馈。 Payload: ```ts { hapticType: | "success" | "warning" | "failure" | "light" | "medium" | "heavy" | "selection"; } ``` ##### `improv/configure_device` 配置已发现的 Improv Wi-Fi 设备。 Payload: ```ts { name: string; } ``` * `name`:要配置的设备的名称 ##### `improv/scan` 开始扫描 Improv Wi-Fi 设备。 Payload:无 ##### `matter/commission` 开始 Matter 设备的 commissioning 流程。 Payload(可选): ```ts { mac_extended_address: string | null; extended_pan_id: string | null; border_agent_id: string | null; active_operational_dataset: string | null; } ``` 所有 payload 属性描述的是 commissioning Matter over Thread 设备时应该使用的首选 Thread 网络。 * `mac_extended_address`:MAC extended address * `extended_pan_id`:extended PAN ID * `border_agent_id`:border agent ID * `active_operational_dataset`:active operational dataset(TLV) ##### `sidebar/show` 显示 sidebar。 Payload:无 ##### `tag/write` 通知外部应用打开写入 tag 的 UI。 Payload: ```ts { tag: string; name: string | null; } ``` * `tag`:要写入的 tag ID * `name`:用户输入的 tag 名称,如果未设置名称则为 `null` ##### `theme-update` 通知应用 theme 已被更新。应用应刷新其状态栏和导航栏颜色。 Payload:无 ##### `thread/import_credentials` 从设备导入 Thread 网络凭据。凭据应通过 [WebSocket API](/developers/api/websocket.md) 发送。 Payload:无 ##### `thread/store_in_platform_keychain` 将 Thread 凭据存储到平台 keychain 中。 Payload: ```ts { mac_extended_address: string | null; border_agent_id: string | null; active_operational_dataset: string; extended_pan_id: string; } ``` * `mac_extended_address`:MAC extended address * `border_agent_id`:border agent ID * `active_operational_dataset`:active operational dataset(TLV) * `extended_pan_id`:extended PAN ID ### 从 app 到 frontend 的消息 这些消息从外部应用发送到 Home Assistant 前端。 #### 期望响应的消息 本节中的所有命令都会从前端收到一条结果消息: ```ts { id: number; type: "result"; success: boolean; result: null; error?: { code: string; message: string }; } ``` ##### `automation/editor/show` 打开 automation editor 以创建新的自动化。config 可用于使用特定的 triggers、conditions 和 actions 预填充编辑器。 Payload(可选): ```ts { config?: { alias?: string; description?: string; triggers?: Trigger | Trigger[]; conditions?: Condition | Condition[]; actions?: Action | Action[]; mode?: "single" | "restart" | "queued" | "parallel"; max?: number; }; } ``` * `config.alias`:自动化的预填充名称 * `config.description`:预填充的描述 * `config.triggers`:一个或多个用于预填充的 trigger * `config.conditions`:一个或多个用于预填充的 condition * `config.actions`:一个或多个用于预填充的 action * `config.mode`:自动化的执行模式 * `config.max`:并发运行的最大数量(仅适用于 `queued` 和 `parallel` 模式) ##### `bar_code/aborted` 通知条码扫描已中止。 Payload: ```ts { reason: "canceled" | "alternative_options"; } ``` ##### `bar_code/scan_result` 将条码扫描器结果发送到前端。 Payload: ```ts { rawValue: string; format: | "aztec" | "code_128" | "code_39" | "code_93" | "codabar" | "data_matrix" | "ean_13" | "ean_8" | "itf" | "pdf417" | "qr_code" | "upc_a" | "upc_e" | "unknown"; } ``` * `rawValue`:从 barcode 数据解码出的字符串 * `format`:条码格式,如 [Barcode Detection API](https://developer.mozilla.org/en-US/docs/Web/API/Barcode_Detection_API#supported_barcode_formats) 中所定义 ##### `improv/device_setup_done` 通知 Improv Wi-Fi 设备设置已完成。 Payload:无 ##### `improv/discovered_device` 通知已发现 Improv Wi-Fi 设备。 Payload: ```ts { name: string; } ``` ##### `kiosk_mode/set` 启用或禁用 kiosk mode。 Payload: ```ts { enable: boolean; } ``` ##### `navigate` 导航到前端中的特定路径。 Payload: ```ts { path: string; options?: { replace?: boolean; data?: any; }; } ``` * `path`:要导航到的绝对路径(例如,`/config/voice-assistants/assistants`)。该路径直接传递给 `history.pushState` 或 `history.replaceState`,因此它必须以 `/` 开头 * `options.replace`:如果为 true,则替换当前的浏览器历史记录条目,而不是推入新条目。 * `options.data`:要存储在浏览器历史状态中的可选数据,可通过 `history.state` 访问 ##### `notifications/show` 显示 notifications panel。 Payload:无 ##### `restart` 请求前端重启。 Payload:无 ##### `sidebar/show` 显示 sidebar。如果当前有 dialog 打开,则返回带有 `not_allowed` code 的错误响应。 Payload:无 ##### `sidebar/toggle` 切换 sidebar 的打开/关闭。如果当前有 dialog 打开,则返回带有 `not_allowed` code 的错误响应。 Payload:无 [web-message-listener]: https://developer.android.com/reference/androidx/webkit/WebViewCompat.WebMessageListener --- url: /developers/index.md --- --- url: /developers/instance_url.md --- 在某些情况下,integration 需要知道用户的 Home Assistant 实例的 URL,并且该 URL 必须符合当前用例的要求。例如,设备需要回传数据给 Home Assistant,或者外部服务或设备需要从 Home Assistant 获取数据(例如,生成的图片或声音文件)。 获取 instance URL 可能会比较复杂,因为用户可能有一堆不同的 URL: * 用户配置的 internal home network URL。 * 自动检测到的 internal home network URL。 * 用户配置的、从互联网上可公开访问的 external URL。 * 如果用户有订阅,则可能是 Nabu Casa 提供的 Home Assistant Cloud URL。 URL 可以在非标准端口上提供服务(例如,不是 80 或 443),并且可以带或不带 SSL(`http://` 与 `https://`),这增加了额外的复杂性。 幸运的是,Home Assistant 提供了一个 helper method 来稍微简化这一点。 ## URL helper Home Assistant 提供了一个 network helper method 来获取 instance URL,该 URL 符合 integration 的需求,名为 `get_url`。 该 helper method 的签名: ```py # homeassistant.helpers.network.get_url def get_url( hass: HomeAssistant, *, require_current_request: bool = False, require_ssl: bool = False, require_standard_port: bool = False, allow_internal: bool = True, allow_external: bool = True, allow_cloud: bool = True, allow_ip: bool = True, prefer_external: bool = False, prefer_cloud: bool = False, ) -> str: ``` 该方法的各个参数: * `require_current_request` 要求返回的 URL 与用户浏览器当前正在使用的 URL 匹配。如果没有当前请求,将抛出错误。 * `require_ssl`: 要求返回的 URL 使用 `https` scheme。 * `require_standard_port`: 要求返回的 URL 使用标准 HTTP 端口。也就是说,它要求 `http` scheme 使用端口 80,`https` scheme 使用端口 443。 * `allow_internal`: 允许 URL 是用户在 internal network 上设置的 URL 或检测到的 URL。如果你要求必须使用 external URL,请将此项设置为 `False`。 * `allow_external`: 允许 URL 是用户设置的 external URL 或 Home Assistant Cloud URL。如果你要求必须使用 internal URL,请将此项设置为 `False`。 * `allow_cloud`: 允许返回 Home Assistant Cloud URL,如果你要求不能使用 Cloud URL,请设置为 `False`。 * `allow_ip`: 允许 URL 的 host 部分为 IP 地址,如果这对你的用例不可用,请设置为 `False`。 * `prefer_external`: 默认情况下,我们优先选择 internal URL 而不是 external URL。将此选项设置为 `True` 可以反转这一逻辑,优先选择 external URL 而不是 internal URL。 * `prefer_cloud`: 默认情况下,用户设置的 external URL 是首选,但在极少数情况下,cloud URL 可能更可靠。将此选项设置为 `True` 会优先选择 Home Assistant Cloud URL,而不是用户自定义的 external URL。 ## 默认行为 默认情况下,不传递任何额外参数(`get_url(hass)`),它会尝试: * 获取用户设置的 internal URL,如果不可用,则尝试从 network interface 检测一个(基于 `http` 设置)。 * 如果 internal URL 失败,它会尝试获取 external URL。它优先使用用户设置的 external URL,如果那也失败,则在可用的情况下获取 Home Assistant Cloud URL。 默认目标是:允许任何 URL,但优先使用本地 URL,且没有额外要求。 ## 使用示例 使用该 helper 的最基本示例: ```py from homeassistant.helpers.network import get_url instance_url = get_url(hass) ``` 对上述 helper method 的这次调用将优先返回一个 internal URL,该 URL 要么是用户设置的,要么是检测到的。如果无法提供,它将尝试使用用户的 external URL。最后,如果用户没有设置 external URL,它将尝试使用 Home Assistant Cloud URL。 如果完全没有任何 URL 可用(或没有任何 URL 满足给定要求),将抛出一个异常:`NoURLAvailableError`。 ```py from homeassistant.helpers import network try: external_url = network.get_url( hass, allow_internal=False, allow_ip=False, require_ssl=True, require_standard_port=True, ) except network.NoURLAvailableError: raise MyInvalidValueError("Failed to find suitable URL for my integration") ``` 上面的示例展示了 URL helper 的稍复杂用法。在这种情况下,请求的 URL 不能是 internal 地址,URL 不能包含 IP 地址,需要 SSL,并且必须运行在标准端口上。 如果没有可用的 URL,可以捕获并处理 `NoURLAvailableError` 异常。 --- url: /developers/integration_events.md --- :::info 集成一般被鼓励将 events 作为 [event entities](/developers/core/entity/event.md) 发布,而不是直接在 event bus 上发出 events。这种方法通过让用户更容易浏览和识别所有可用的 events 来提升用户体验。 ::: 一些 integrations 表示具有 events 的 devices 或 services,比如检测到运动或按下短暂按钮时。integration 可以通过在 Home Assistant 中将其作为 events 发出,向用户提供这些 events。 你的 integration 应该发出类型为 `_event` 的 events。例如,ZHA integration 发出 `zha_event` events。 如果该 event 与某个特定的 device/service 相关,应该进行正确的归属。方法是在 event data 中添加一个 `device_id` attribute,其中包含来自 device registry 的 device 标识符。 ``` event_data = { "device_id": "my-device-id", "type": "motion_detected", } hass.bus.async_fire("mydomain_event", event_data) ``` 如果一个 device 或 service 只发出 events,你需要 [手动在 device registry 中注册它](/developers/device_registry_index.md#manual-registration)。 ## 让 events 对用户可用 一个 [Device trigger](/developers/device_automation_trigger.md) 可以根据 payload 附加到特定 event 上,并让该 event 对用户可用。有了 device trigger,用户就能看到该 device 的所有可用 events,并在 automations 中使用它。 ## 不要做的事 与 event 相关的代码不应成为你 integration 的 entity logic 的一部分。你应该从 `__init__.py` 中的 `async_setup_entry` 内部启用将你的 integration events 转换为 Home Assistant events 的 logic。 Entity state 不应代表 events。例如,你不应该在 event 发生时创建一个持续 30 秒处于 `on` 状态的 binary sensor。 --- url: /developers/integration_fetching_data.md --- 你的 integration 需要从 API 获取 data,以便提供给 Home Assistant。这个 API 可能通过 web(本地或云端)、sockets、通过 USB 设备暴露的 serial ports 等方式提供。 ## Push vs poll APIs 有各种形式,但核心上分为两类:push 和 poll。 使用 push 时,我们订阅一个 API,当有新的 data 可用时,API 会通知我们。它把变更推送给我们。Push APIs 非常好,因为它们消耗的资源更少。当发生变更时,我们可以收到变更通知,而不必重新获取所有 data 并找出变更。由于 entities 可以被禁用,你应该确保你的 entity 在 `async_added_to_hass` callback 内部订阅,并在移除时取消订阅。 使用 polling 时,我们会按指定的时间间隔从 API 获取最新的 data。你的 integration 然后将这些数据提供给它的 entity,并写入 Home Assistant。 由于 polling 非常常见,Home Assistant 默认假设你的 entity 是基于 polling 的。如果不是,请从 `Entity.should_poll` property 返回 `False`。当你禁用 polling 时,你的 integration 将负责调用其中一个方法,通知 Home Assistant 是时候将 entity state 写入 Home Assistant: * 如果你在一个 async function 内部执行,且不需要调用你的 entity update method,请调用 `Entity.async_write_ha_state()`。这是一个 async callback,会在不将控制权让出给 event loop 的情况下,将 state 写入 state machine。 * `Entity.schedule_update_ha_state(force_refresh=False)` / `Entity.async_schedule_update_ha_state(force_refresh=False)` 会安排一次 entity 更新。如果将 `force_refresh` 设置为 `True`,Home Assistant 会在写入 state 之前先调用你的 entity update method(`update()` / `async_update()`)。 ## Polling API endpoints 我们将解释几种不同的 API 类型以及集成到 Home Assistant 的最佳方式。注意,有些 integrations 会遇到下面几种类型的组合。 ### 为所有 entities 协调、单次 API poll 获取 data 这个 API 将有一个单一的方法,用于获取你在 Home Assistant 中所有 entities 的 data。在这种情况下,我们希望在该 endpoint 上进行单次周期性 poll,然后尽快让 entities 知道有新的 data 可用。 Home Assistant 提供了一个 `DataUpdateCoordinator` 类来帮助你尽可能高效地管理这一点。 使用 `DataUpdateCoordinator` 时,被 poll 的 data 通常预期保持基本不变。例如,如果你 poll 一个每周只开一次灯的 light,其 data 在绝大多数时间里可能是相同的。默认行为是每当 data 更新时就回调 listeners,即使 data 没有变化。如果从 API 返回的 data 可以通过 Python 的 `__eq__` method 比较变更,请在创建 `DataUpdateCoordinator` 时将 `always_update` 设置为 `False`,以避免不必要的 callbacks 和对 state machine 的写入。 ```python """Example integration using DataUpdateCoordinator.""" import asyncio from datetime import timedelta import logging from homeassistant.components.light import LightEntity from homeassistant.core import callback from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, UpdateFailed, ) _LOGGER = logging.getLogger(__name__) async def async_setup_entry(hass, config_entry, async_add_entities): """Config entry example.""" # assuming API object stored as runtime_data by __init__.py my_api = config_entry.runtime_data coordinator = MyCoordinator(hass, config_entry, my_api) # Fetch initial data so we have data when entities subscribe # # If the refresh fails, async_config_entry_first_refresh will # raise ConfigEntryNotReady and setup will try again later # # If you do not want to retry setup on failure, use # coordinator.async_refresh() instead # await coordinator.async_config_entry_first_refresh() async_add_entities( MyEntity(coordinator, idx) for idx, ent in enumerate(coordinator.data) ) class MyCoordinator(DataUpdateCoordinator): """My custom coordinator.""" def __init__(self, hass, config_entry, my_api): """Initialize my coordinator.""" super().__init__( hass, _LOGGER, # Name of the data. For logging purposes. name="My sensor", config_entry=config_entry, # Polling interval. Will only be polled if there are subscribers. update_interval=timedelta(seconds=30), # Set always_update to `False` if the data returned from the # api can be compared via `__eq__` to avoid duplicate updates # being dispatched to listeners always_update=True ) self.my_api = my_api self._device: MyDevice | None = None async def _async_setup(self): """Set up the coordinator This is the place to set up your coordinator, or to load data, that only needs to be loaded once. This method will be called automatically during coordinator.async_config_entry_first_refresh. """ self._device = await self.my_api.get_device() async def _async_update_data(self): """Fetch data from API endpoint. This is the place to pre-process the data to lookup tables so entities can quickly look up their data. """ try: # Note: asyncio.TimeoutError and aiohttp.ClientError are already # handled by the data update coordinator. async with asyncio.timeout(10): # Grab active context variables to limit data required to be fetched from API # Note: using context is not required if there is no need or ability to limit # data retrieved from API. listening_idx = set(self.async_contexts()) return await self.my_api.fetch_data(listening_idx) except ApiAuthError as err: # Raising ConfigEntryAuthFailed will cancel future updates # and start a config flow with SOURCE_REAUTH (async_step_reauth) raise ConfigEntryAuthFailed from err except ApiError as err: raise UpdateFailed(f"Error communicating with API: {err}") except ApiRateLimited as err: # If the API is providing backoff signals, these can be honored via the retry_after parameter raise UpdateFailed(retry_after=60) class MyEntity(CoordinatorEntity, LightEntity): """An entity using CoordinatorEntity. The CoordinatorEntity class provides: should_poll async_update async_added_to_hass available """ def __init__(self, coordinator, idx): """Pass coordinator to CoordinatorEntity.""" super().__init__(coordinator, context=idx) self.idx = idx @callback def _handle_coordinator_update(self) -> None: """Handle updated data from the coordinator.""" self._attr_is_on = self.coordinator.data[self.idx]["state"] self.async_write_ha_state() async def async_turn_on(self, **kwargs): """Turn the light on. Example method how to request data updates. """ # Do the turning on. # ... # Update the data await self.coordinator.async_request_refresh() ``` ### 每个独立 entity 单独 poll 有些 API 会为每个 device 提供一个 endpoint。有时无法将一个 API device 映射到一个单一的 entity。如果你从一个 API device endpoint 创建了多个 entities,请参阅上一节。 如果你可以将一个 device endpoint 精确映射到一个单一 entity,你可以在 `update()` / `async_update()` method 中获取该 entity 的 data。请确保 polling 设置为 `True`,Home Assistant 会定期调用此 method。 如果你的 entities 在首次写入 Home Assistant 之前需要获取 data,请将 `update_before_add=True` 传递给 `add_entities` method:`add_entities([MyEntity()], update_before_add=True)`。 你可以通过在 platform 中定义一个 `SCAN_INTERVAL` constant 来控制 integration 的 polling interval。注意不要将此值设置得太低。它会占用 Home Assistant 的资源,可能压垮承载 API 的 device,或被 cloud APIs 封禁。允许的最小值是 5 秒。 ```python from datetime import timedelta SCAN_INTERVAL = timedelta(seconds=5) ``` ## Pushing API endpoints 如果你的 API endpoint 是 push data 的,你仍然可以使用 data update coordinator。做法是不要将 polling 参数 `update_method` 和 `update_interval` 传递给构造函数。 当新的 data 到达时,使用 `coordinator.async_set_updated_data(data)` 将 data 传递给 entities。如果在 poll 的 coordinator 上使用此 method,它会重置到下一次 poll data 的时间。 ## Request parallelism :::info Home Assistant 会自动管理 request parallelism;大多数 integrations 无需更改此处描述的任何内容。 ::: Home Assistant 有内置的 logic,确保 integrations 不会 hammer APIs 并耗尽 Home Assistant 的所有可用资源。这个 logic 围绕限制并行请求的数量构建。这个 logic 会在 service action 调用和 entity 更新期间自动使用。 Home Assistant 通过为每个 integration 维护一个 [semaphore](https://docs.python.org/3/library/asyncio-sync.html#asyncio.Semaphore) 来控制并行更新(对 `update()` 的调用)的数量。例如,如果 semaphore 允许 1 个并行连接,那么当有一个正在进行时,updates 和 service action 调用会等待。如果该值为 0,integration 本身负责在必要时限制并行请求的数量。 平台并行请求的默认值由添加的到 Home Assistant 的第一个 entity 决定。如果 entity 定义了 `async_update` method,则为 0,否则为 1。(这是一个遗留决策) Platforms 可以通过在它们的 platform(如 `rflink/light.py`)中定义 `PARALLEL_UPDATES` constant 来覆盖默认值。 --- url: /developers/integration_listen_events.md --- 你的 integration 可能需要对 Home Assistant 内部发生的特定事件采取行动。Home Assistant 提供了 event helpers 来监听特定的 event 类型,并且可以直接访问 event bus。这些 helpers 经过高度优化,以尽量减少回调数量。如果你需要监听的事件已经有对应的 helper,那么优先使用 helper 而不是直接监听 event bus。 ## 可用的 event helpers Event helpers 位于 `homeassistant.helpers.event` 命名空间中。这些函数返回一个用于取消 listener 的 callable。 这些函数中许多也有不带 `async_` 前缀的同步版本。 ### 示例 ```python unsub = async_track_state_change_event(hass, entity_ids, state_automation_listener) unsub() ``` ### 跟踪 entity state 变更 | Function | Use case | ------------------------------------ | -------------------------------------------------------------------------- | `async_track_state_change` | 跟踪特定的 state 变更(已弃用,请使用 `async_track_state_change_event`) | `async_track_state_change_event` | 跟踪以 entity\_id 索引的特定 state 变更 events | `async_track_state_added_domain` | 跟踪当 entity 被添加到 domains 时的 state 变更 events | `async_track_state_removed_domain` | 跟踪当 entity 从 domains 中移除时的 state 变更 events | `async_track_state_change_filtered` | 跟踪带有 TrackStates filter 的 state 变更,该 filter 可以更新 | `async_track_same_state` | 跟踪 entities 的 state 持续一段时间并执行 action ### 跟踪 template 变更 | Function | Use case | ------------------------------------ | -------------------------------------------------------------------------- | `async_track_template` | 添加一个 listener,当 template 求值为 'true' 时触发 | `async_track_template_result` | 添加一个 listener,当 template 的结果发生变化时触发 ### 跟踪 entity registry 变更 | Function | Use case | ------------------------------------------- | -------------------------------------------------------------------------- | `async_track_entity_registry_updated_event` | 跟踪以 entity\_id 索引的特定 entity registry 更新 events ### 跟踪时间变更 | Function | Use case | ------------------------------------------- | -------------------------------------------------------------------------- | `async_track_point_in_time` | 添加一个 listener,在特定时间点之后触发一次 | `async_track_point_in_utc_time` | 添加一个 listener,在特定 UTC 时间点之后触发一次 | `async_call_later` | 添加一个带有延迟调用的 listener | `async_track_time_interval` | 添加一个 listener,在每个 timedelta 间隔重复触发 | `async_track_utc_time_change` | 添加一个 listener,当时间与某模式匹配时触发 | `async_track_time_change` | 添加一个 listener,当本地时间与某模式匹配时触发 ### 跟踪太阳 | Function | Use case | ------------------------------------------- | -------------------------------------------------------------------------- | `async_track_sunrise` | 添加一个 listener,每天在 sunrise 之后指定偏移量触发 | `async_track_sunset` | 添加一个 listener,每天在 sunset 之后指定偏移量触发 ## 直接监听 event bus 有两个函数可用于创建 listeners。这两个函数都返回一个取消 listener 的 callable。 * `async_listen_once` — 监听一次该 event,之后不再触发 * `async_listen` — 持续监听直到被取消 `async_listen` 很少被使用,因为 `EVENT_HOMEASSISTANT_START`、`EVENT_HOMEASSISTANT_STARTED` 和 `EVENT_HOMEASSISTANT_STOP` 每次运行只触发一次。 ### Async context ```python cancel = hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, disconnect_service) cancel() ``` ```python cancel = hass.bus.async_listen(EVENT_STATE_CHANGED, forward_event) cancel() ``` ### Sync context ```python cancel = hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, disconnect_service) cancel() ``` ```python cancel = hass.bus.listen(EVENT_STATE_CHANGED, forward_event) cancel() ``` ### 常见 events 以下 events 通常被直接监听。 | Event Name | Description | --------------------------------- | -------------------------------------------------------------------------- | `EVENT_HOMEASSISTANT_START` | 已完成 setup 并进入 start 阶段 | `EVENT_HOMEASSISTANT_STARTED` | 已完成 start 阶段,且所有 integrations 都获得了加载的机会;主要用于 voice assistants 以及将 states 导出到外部服务的 integrations | `EVENT_HOMEASSISTANT_STOP` | 已进入 stop 阶段 ### 其他 events 这些 events 很少被直接监听,除非该 integration 属于 core。通常会有消耗这些 events 的 helper 可用,此时不应直接监听。 | Event Name | Description | Preferred helper | --------------------------------- | -------------------------------------------- | ---------------------------- | `EVENT_HOMEASSISTANT_FINAL_WRITE` | 最后一次将 data 写入磁盘的机会 | | `EVENT_HOMEASSISTANT_CLOSE` | 拆除(Teardown) | | `EVENT_COMPONENT_LOADED` | 一个 integration 已完成加载 | `homeassistant.helpers.start.async_at_start` | `EVENT_SERVICE_REGISTERED` | 注册了一个新的 service | | `EVENT_SERVICE_REMOVED` | 移除了一个 service | | `EVENT_CALL_SERVICE` | 调用了一个 service | | `EVENT_STATE_CHANGED` | 一个 entity 的 state 发生了变化 | [跟踪 entity state 变更](#tracking-entity-state-changes) | `EVENT_THEMES_UPDATED` | Themes 已更新 | | `EVENT_CORE_CONFIG_UPDATE` | Core configuration 已更新 | | `EVENT_ENTITY_REGISTRY_UPDATED` | Entity registry 已更新 | [跟踪 entity registry 变更](#tracking-entity-registry-changes) --- url: /developers/integration_setup_failures.md --- 你的 integration 可能因为各种原因无法完成设置。最常见的情况是 device 或 service 离线,或者凭据已不再有效。你的 integration 必须重试 setup,这样当 device 或 service 恢复上线时,就能尽快恢复,而无需用户重启 Home Assistant。 ## 处理离线或不可用的 devices 和 services ### 使用 `async_setup_entry` 的 integrations 在 integration 的 `__init__.py` 中的 `async_setup_entry` 里抛出 `ConfigEntryNotReady` 异常,Home Assistant 会自动安排稍后重试设置。为避免混淆,在 platform 的 `async_setup_entry` 中抛出 `ConfigEntryNotReady` 是无效的,因为此时对于 config entry 的设置来说已经太晚了。 #### 示例 ```python async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up the config entry for my device.""" device = MyDevice(entry.data[CONF_HOST]) try: await device.async_setup() except (asyncio.TimeoutError, TimeoutException) as ex: raise ConfigEntryNotReady(f"Timeout while connecting to {device.ipaddr}") from ex ``` 如果你正在使用 [DataUpdateCoordinator](/developers/integration_fetching_data.md#coordinated-single-api-poll-for-data-for-all-entities),调用 `await coordinator.async_config_entry_first_refresh()` 也会在首次刷新失败时自动触发此异常。 如果你的 integration 支持 discovery,Home Assistant 会在你的 device 或 service 被发现时自动重试。 #### 处理重试的 logging 将错误消息作为第一个参数传递给 `ConfigEntryNotReady`。Home Assistant 会以 `debug` 级别记录。错误消息还会传播到 UI,并显示在 integrations 页面上。如果你在抛出 `ConfigEntryNotReady` 时不设置消息,Home Assistant 会尝试从导致 `ConfigEntryNotReady` 的异常中提取原因,前提是该异常是从另一个异常传播而来的。 该 integration 不应记录任何关于重试的非 debug 消息,而应依赖 `ConfigEntryNotReady` 内置的 logic,以避免刷屏日志。 ### 使用 `async_setup_platform` 的 integrations 在 `async_setup_platform` 中抛出 `PlatformNotReady` 异常,Home Assistant 会自动安排稍后重试设置。 #### 示例 ```python async def async_setup_platform( hass: HomeAssistant, config: ConfigType, async_add_entities: AddEntitiesCallback, discovery_info: DiscoveryInfoType | None = None, ) -> None: """Set up the platform.""" device = MyDevice(config[CONF_HOST]) try: await device.async_setup() except ConnectionError as ex: raise PlatformNotReady(f"Connection error while connecting to {device.ipaddr}: {ex}") from ex ``` #### 处理重试的 logging 将错误消息作为第一个参数传递给 `PlatformNotReady`。Home Assistant 会以 `warning` 级别记录一次重试,随后的重试会以 `debug` 级别记录。如果你在抛出 `PlatformNotReady` 时不设置消息,Home Assistant 会尝试从导致 `PlatformNotReady` 的异常中提取原因,前提是该异常是从另一个异常传播而来的。 该 integration 不应记录任何关于重试的非 debug 消息,而应依赖 `PlatformNotReady` 内置的 logic,以避免刷屏日志。 ## 处理过期凭据 抛出 `ConfigEntryAuthFailed` 异常,Home Assistant 会自动将 config entry 置为失败状态并启动一个 reauth flow。该异常必须从 `__init__.py` 中的 `async_setup_entry` 抛出,或从 `DataUpdateCoordinator` 抛出,否则将无法有效触发 reauth flow。如果你的 integration 不使用 `DataUpdateCoordinator`,可以调用 `entry.async_start_reauth()` 作为启动 reauth flow 的替代方案。 `reauth` flow 会使用以下 context 变量启动,这些变量在 `async_step_reauth` step 中可用: * source:始终为 "SOURCE\_REAUTH" * entry\_id:需要重新认证的 config entry 的 entry\_id * unique\_id:需要重新认证的 config entry 的 unique\_id #### 示例 ```python async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up the config entry for my device.""" device = MyDevice(entry.data[CONF_HOST]) try: await device.async_setup() except AuthFailed as ex: raise ConfigEntryAuthFailed(f"Credentials expired for {device.name}") from ex except (asyncio.TimeoutError, TimeoutException) as ex: raise ConfigEntryNotReady(f"Timed out while connecting to {device.ipaddr}") from ex ``` --- url: /developers/intent_builtin.md --- import intents from '!!yaml-loader!../intents/intents.yaml'; 以下 intents 受到**支持**:
  • <> { Object.entries(intents) .filter(([intent, info]) => info["supported"]) .map(([intent, info]) => intent) .join(", ") }
以下 intents 已被**弃用**: * HassOpenCover、HassCloseCover、HassToggle、HassHumidifierSetpoint、HassHumidifierMode、HassShoppingListLastItems **Slots** 对于 *HassTurnOn* 和 *HassTurnOff*,*slots* 是可选的。 可能的 slot 组合如下: | Slot combination | Example | | ----------------------- | ---------------------------------| | 仅 name | 桌灯 | | 仅 area | 厨房 | | area 和 name | 客厅阅读灯 | | area 和 domain | 厨房灯光 | | area 和 device class | 浴室湿度 | | device class 和 domain | 二氧化碳传感器 | ## 支持的意图 <> { Object.entries(intents) .filter((\[intent, info]) => info\["supported"]) .map( (\[intent, info]) => <>

{intent}

{info.description}

{info.slots && (Slots) && (
    {Object.entries(info.slots).map((\[slot, slotInfo]) => (
  • {slot} - {slotInfo.description + (slotInfo.required ? "(必需)" : "")}
  • ))}
)}

\由 {info.domain} 集成提供。

\ ) } \ ## 已弃用的 intents 这些是旧版 intents,不被 template matching sentences 支持,计划将其移除或替换。 ### HassOpenCover *已弃用;请改用 `HassTurnOn`。* 打开一个 cover。 | Slot name | Type | Required | Description | --------- | ---- | -------- | ----------- | name | string | 是 | 要打开的 cover entity 名称。 ### HassCloseCover *已弃用;请改用 `HassTurnOff`。* 关闭一个 cover。 | Slot name | Type | Required | Description | --------- | ---- | -------- | ----------- | name | string | 是 | 要关闭的 cover entity 名称。 ### HassToggle 切换一个 entity 的 state。 | Slot name | Type | Required | Description | --------- | ---- | -------- | ----------- | name | string | 是 | 要切换的 entity 名称。 ### HassHumidifierSetpoint 设置目标湿度。 | Slot name | Type | Required | Description | --------- | ---- | -------- | ----------- | name | string | 是 | 要控制的 entity 名称。 | humidity | integer, 0-100 | 是 | 要设置的目标湿度。 ### HassHumidifierMode 如果 humidifier 支持,设置其 mode。 | Slot name | Type | Required | Description | --------- | ---- | -------- | ----------- | name | string | 是 | 要控制的 entity 名称。 | mode | string | 是 | 要切换到的 mode。 ### HassShoppingListLastItems 列出购物清单上最近 5 个 items。 *此 intent 没有 slots。* [此页面基于 Intents 仓库自动生成。](https://github.com/home-assistant/intents/blob/main/intents.yaml) --- url: /developers/intent_conversation_api.md --- Intents 可以从文本中识别,并通过 [conversation integration](https://www.home-assistant.io/integrations/conversation/) 发出。 有一个 API endpoint 可以接收一个输入句子并产生一个 [conversation response](#conversation-response)。一个 "conversation" 可以通过传递 Home Assistant 生成的 [conversation id](#conversation-id) 在多次输入和响应之间进行跟踪。 该 API 可通过 Rest API 和 Websocket API 访问。 可以将一个句子 POST 到 `/api/conversation/process`,例如: ```json { "text": "turn on the lights in the living room", "language": "en" } ``` 或者通过 WebSocket API 发送,例如: ```json { "type": "conversation/process", "text": "turn on the lights in the living room", "language": "en" } ``` 可用的输入字段如下: | Name | Type | Description | |-------------------|--------|---------------------------------------------------------------------------------------------| | `text` | string | 输入句子。 | | `language` | string | 可选。输入句子的语言(默认为已配置的语言)。 | | `agent_id` | string | 可选。用于处理请求的 conversation agent(默认为 *home\_assistant*)。 | | `conversation_id` | string | 可选。用于 [跟踪 conversation](#conversation-id) 的唯一 id。由 Home Assistant 生成。 | ## 对话响应 `/api/conversation/process` 的 JSON response 包含有关所发出 intent 效果的信息,例如: ```json { "continue_conversation": true, "response": { "response_type": "action_done", "language": "en", "data": { "success": [ { "name": "Living Room", "type": "area", "id": "living_room" }, { "name": "My Light", "type": "entity", "id": "light.my_light" } ], "failed": [] }, "speech": { "plain": { "speech": "Turned Living Room lights on" } } }, "conversation_id": "", } ``` `"response"` object 中可用的属性如下: | Name | Type | Description | | --------------- | ---------- | ----------------------------------------------------------------------------------------- | | `response_type` | string | `action_done`、`query_answer` 或 `error` 之一(见 [response types](#response-types))。 | | `data` | dictionary | 每个 [response type](#response-types) 的相关 data。 | | `language` | string | Intent 和 response 的语言。 | | `speech` | dictionary | 可选。要向用户宣读的 response text(见 [speech](#speech))。 | [Conversation id](#conversation-id) 会与 conversation response 一起返回。 如果 `continue_conversation` 设置为 `true`,conversation agent 期望用户进行后续交互。 ## 响应类型 ### 操作完成 该 intent 在 Home Assistant 中产生了一个 action,例如打开一个 light。Response 的 `data` 属性包含一个 `success` 列表和一个 `failed` 列表。这些列表中的每个条目都是被操作的 target,其格式如下: | Name | Type | Description | |------------|---------|-------------------------------------------------------------------------------------------------| | `name` | string | 受影响 target 的名称。 | | `type` | string | Target 类型。`area`、`floor`、`domain`、`device_class`、`device`、`entity` 或 `custom` 之一。 | | `id` | string | 可选。Target 的 id。 | `success` 列表包含成功操作的 targets(如 areas、floors 和 entities/devices),而 `failed` 列表包含失败的 targets: ```json { "response": { "response_type": "action_done", "data": { "success": [ (targets that succeeded) ], "failed": [ (targets that failed) ] } } } ``` 一个 intent 可以有多个 targets,它们会叠加应用。Targets 必须从一般到具体排序: * `floor` * 一个已注册的 floor,用于对多个 areas 进行分组 * `area` * 一个 [已注册的 area](https://developers.home-assistant.io/docs/area_registry_index/) * `domain` * Home Assistant integration domain,如 "light" * `device_class` * 某个 domain 的 device class,如 "cover" domain 的 "garage\_door" * `device` * 一个 [已注册的 device](https://developers.home-assistant.io/docs/device_registry_index) * `entity` * 一个 [Home Assistant entity](https://developers.home-assistant.io/docs/architecture/devices-and-services) * `custom` * 一个自定义 target 大多数 intents 最终有 0、1 或 2 个 targets。目前只有当 device classes 参与时才会有 3 个 target。Target 组合示例: * "关闭所有灯光" * 1 个 target:`domain:light` * "打开厨房的灯光" * 2 个 targets:`area:kitchen`、`domain:light` * "打开厨房的百叶窗" * 3 个 targets:`area:kitchen`、`domain:cover`、`device_class:blind` ### 查询回答 该 response 是对一个问题的回答,例如 "温度是多少?"。请参见 [speech](#speech) 属性以获取回答文本。 ```json { "response": { "response_type": "query_answer", "language": "en", "speech": { "plain": { "speech": "It is 65 degrees" } }, "data": { "success": [ { "name": "Ecobee", "type": "entity", "id": "climate.ecobee" } ], "failed": [] } }, "conversation_id": "", } ``` ### 错误 在 intent 识别或处理过程中发生了错误。请查看 `data.code` 了解具体的错误类型,并查看 [speech](#speech) 属性以获取错误消息。 ```json { "response": { "response_type": "error", "language": "en", "data": { "code": "no_intent_match" }, "speech": { "plain": { "speech": "Sorry, I didn't understand that" } } } } ``` `data.code` 是一个 string,可以是以下之一: * `no_intent_match` — 输入文本没有匹配到任何 intents。 * `no_valid_targets` — 所指向的 area、device 或 entity 不存在。 * `failed_to_handle` — 在处理 intent 时发生了意外的错误。 * `unknown` — 在 intent 处理范围之外发生了错误。 ## 语音 向用户宣读的 response 在 response 的 `speech` 属性中提供。它既可以是纯文本(默认),也可以是 [SSML](https://www.w3.org/TR/speech-synthesis11/)。 对于纯文本 speech,response 会如下所示: ```json { "response": { "response_type": "...", "speech": { "plain": { "speech": "...", "extra_data": null } } }, "conversation_id": "", } ``` 如果 speech 是 [SSML](https://www.w3.org/TR/speech-synthesis11/),则会变为: ```json { "response": { "response_type": "...", "speech": { "ssml": { "speech": "...", "extra_data": null } } }, "conversation_id": "", } ``` ## 对话 ID 如果回答的 conversation agent 支持,可以使用 Home Assistant 内部生成的唯一 id 来跟踪 conversations。要继续一个 conversation,请从 HTTP API response 中检索 `conversation_id`(与 [conversation response](#conversation-response) 一起返回),并将其添加到下一个输入句子中: 初始输入句子: ```json { "text": "Initial input sentence." } ``` JSON response 包含 conversation id: ```json { "conversation_id": "", "response": { (conversation response) } } ``` 使用下一个输入句子 POST: ```json { "text": "Related input sentence.", "conversation_id": "" } ``` ## 预加载 sentences 可以通过 WebSocket API 预加载某种语言的 sentences: ```json { "type": "conversation/prepare", "language": "en" } ``` 可用的输入字段如下: | Name | Type | Description | |------------|--------|--------------------------------------------------------------------------------| | `language` | string | 可选。要加载的 sentences 的语言(默认为已配置的语言)。 | --- url: /developers/intent_firing.md --- 如果你的代码将用户的语音或文本匹配到 intents,你可以让该 intent 交由 Home Assistant 处理。这既可以在你自己的 integration 内部完成,也可以通过通用的 Intent handle API 来实现。 当你 fire 一个 intent 时,你会收到一个 response,或者抛出一个 error。由你的代码负责将结果返回给用户。 ## HTTP API 当 intent integration 被加载后,会在 `/api/intent/handle` 提供一个 HTTP API endpoint。你可以向它 POST JSON 数据,其中包含 intent name 及其 data: ```json { "name": "HassTurnOn", "data": { "name": "Kitchen Light" } } ``` ## Home Assistant integration 在 Home Assistant 中处理 intent 的示例代码。 ```python from homeassistant.helpers import intent intent_type = "TurnLightOn" slots = {"entity": {"value": "Kitchen"}} try: intent_response = await intent.async_handle( hass, "example_component", intent_type, slots ) except intent.UnknownIntent as err: _LOGGER.warning("Received unknown intent %s", intent_type) except intent.InvalidSlotInfo as err: _LOGGER.error("Received invalid slot data: %s", err) except intent.IntentError: _LOGGER.exception("Error handling request for %s", intent_type) ``` intent response 是 `homeassistant.helpers.intent.IntentResponse` 的一个实例。 | Name | Type | Description | | ---- | ---- | ----------- | | `intent` | Intent | 触发该 response 的 intent 实例。 | | `speech` | Dictionary | Speech responses。每个 key 对应一个类型。允许的类型为 `plain` 和 `ssml`。 | | `reprompt` | Dictionary | Reprompt responses。每个 key 对应一个类型。允许的类型为 `plain` 和 `ssml`。
当需要从用户处获取 response 时,用于保持 session 处于打开状态。在这种情况下,`speech` 通常是一个问题。 | | `card` | Dictionary | Card responses。每个 key 对应一个类型。 | Speech dictionary 的值: | Name | Type | Description | | ---- | ---- | ----------- | | `speech` | String | 要播放的文本 | | `extra_data` | Any | 与该 speech 相关的额外信息。 | Reprompt dictionary 的值: | Name | Type | Description | | ---- | ---- | ----------- | | `reprompt` | String | 当用户花费太长时间未响应时要播放的文本 | | `extra_data` | Any | 与该 speech 相关的额外信息。 | Card dictionary 的值: | Name | Type | Description | | ---- | ---- | ----------- | | `title` | String | 该 card 的标题 | | `content` | Any | 该 card 的内容 | --- url: /developers/intent_handling.md --- 任何 component 都可以注册来处理 intents。这使得单个 component 能够处理来自多个 voice assistants 所 fire 的 intents。 一个 component 需要为它想要处理的每一种类型注册一个 intent handler。Intent handlers 必须继承 `homeassistant.helpers.intent.IntentHandler`。 ```python from homeassistant.core import HomeAssistant from homeassistant.helpers import intent from homeassistant.helpers.typing import ConfigType DATA_KEY = "example_key" async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: hass.data[DATA_KEY] = 0 intent.async_register(hass, CountInvocationIntent()) return True class CountInvocationIntent(intent.IntentHandler): """Handle CountInvocationIntent intents.""" # 要处理的 intent 类型 intent_type = "CountInvocationIntent" description = "Count how often it has been called" # 可选。用于校验 slots 的 schema # slot_schema = { # 'item': cv.string # } async def async_handle(self, intent_obj: intent.Intent) -> intent.IntentResponse: """Handle the intent.""" intent_obj.hass.data[DATA_KEY] += 1 count = intent_obj.hass.data[DATA_KEY] response = intent_obj.create_response() response.async_set_speech( f"This intent has been invoked {count} times" ) return response ``` --- url: /developers/intent_index.md --- 一个 intent 是对用户意图的描述。Intents 由用户的操作生成,例如让 Amazon Echo 打开一盏灯。 Architectural overview of intents in Home Assistant Intents 由接收来自外部源/服务的 intents 的 components fire。Conversation、Alexa、API.ai 和 Snips 目前都在提供 intents。 任何 component 都可以处理 intents。这使得开发者可以轻松地一次性与所有 voice assistants 集成。 Intents 使用 `homeassistant.helpers.intent.Intent` 类实现。它包含以下属性: | Name | Type | Description | |---------------|----------------|-----------------------------------------------------------------------------| | `hass` | Home Assistant | fire 该 intent 的 Home Assistant 实例。 | | `platform` | string | fire 该 intent 的 platform | | `intent_type` | string | 该 intent 的类型(名称) | | `slots` | dictionary | 包含以 slot name 为 key 的 slot 值。 | | `text_input` | string | 可选。发起该 intent 的原始文本输入。 | | `language` | string | 可选。文本输入的语言(默认为配置的语言)。 | Slots dictionary 值的说明。 | Name | Type | Description | |-------|----------|--------------------| | Value | anything | 该 slot 的值。 | --- url: /developers/internationalization.md --- Home Assistant 的国际化项目包括为平台及前端准备本地化环境,以及实际翻译本地化字符串。 某些 components 和 platforms 会包含需要针对该平台专门本地化的字符串。这些字符串在核心的 [home-assistant](https://github.com/home-assistant/core) 仓库中进行管理。Home Assistant 后端会根据运行实例中加载的 components,向客户端提供相应的字符串。 还有一些可本地化的字符串仅存在于前端。这些字符串在 [home-assistant frontend](https://github.com/home-assistant/frontend) 仓库中进行管理。这些字符串与前端一起存储,不依赖于后端配置。 | Type | Location | | ----------------- | -------- | | Entity states | Core | | Config flows | Core | | Options flows | Core | | Device automation | Core | | Text in UI | Frontend | 我们的字符串由社区使用在线翻译工具 [Lokalise](https://lokalise.com/) 进行翻译。 --- url: /developers/internationalization/core.md --- ## 翻译字符串 Platform translation strings 以 JSON 形式存储在 [core](https://github.com/home-assistant/core) 仓库中。这些文件必须与所属的 component/platform 相邻放置。Components 必须有自己独立的目录,文件名在该目录中简单地命名为 `strings.json`。该文件将包含可翻译的不同字符串。 `strings.json` 包含集成提供的、需要翻译的各种内容的翻译。 | Category | Description | | ------------------- | ------------------------------------------------- | | `title` | Title of the integration. | | `common` | Shared strings. | | `conditions` | Conditions of the integration. | | `config` | Translations for the config flow. | | `device` | Translations for devices. | | `device_automation` | Translations for device automations. | | `entity` | Translations for entities. | | `entity_component` | Translations for entity components. | | `exceptions` | Translations for error messages. | | `issues` | Translations for repairs issues. | | `options` | Translations for the options flow. | | `selectors` | Selectors of the integration. | | `services` | Service actions of the integration. | | `triggers` | Triggers of the integration. | ### 标题 此 category 只是一个字符串:集成名称的翻译。该 key 是可选的,如果省略,Home Assistant 将回退到集成名称。仅当该名称不是产品品牌时才包含此条目。 ### 共享字符串 多次使用的字符串不应重复,而应使用引用指向单一的定义。引用可以是任何有效的 translation key。可选地,shared strings 可以放在 `common` section 中。 ```json { "common": { "error_stale_api_key": "This message will be displayed if `stale_api_key` is returned as the abort reason." }, "config": { "error": { "invalid_api_key": "This message will be displayed if `invalid_api_key` is returned as a flow error.", // Reference to the common section "stale_api_key": "[%key:component::new_integration::common::error_stale_api_key%]" }, } "options": { "error": { // Reference to another section in the same file "invalid_api_key": "[%key:component::new_integration::config::error::invalid_api_key%]", // Reference to the common section in the same file "stale_api_key": "[%key:component::new_integration::common::error_stale_api_key%]" }, } } ``` ### 配置 / 选项 / 子条目流 Configuration flow handler、option flow handler 和 config subentry handler 的 translation strings 分别定义在 `config`、`options` 和 `config_subentries` key 下。 请注意,`config_subentries` 是 map of maps,其中 key 是集成支持的 subentry 类型。 下面的示例 strings 文件描述了不同的支持的 key。虽然示例展示的是 configuration flow 的翻译,但 options 和 subentry flow 的翻译格式相同。 ```json { "config": { // Optional. Title to show in list. Only will be rendered if placeholders required "flow_title": "Discovered Device ({host})", // Optional, only needed if the default translations in frontend are misleading "entry_type": "Label explaining what an entry represents", // Optional, only needed if the default translations in frontend are misleading "initiate_flow": { "reconfigure": "Menu or button label for starting a reconfigure flow", "user": "Menu or button label for starting a user flow" }, "step": { "init": { // Optional. Will show the integration name if omitted "title": "The user visible title of the `init` step.", // Optional "description": "Markdown that is shown with the step.", "data": { "api_key": "The label for the `api_key` input field" }, // Only needed if the form has sections "sections": { "auth_options": { "name": "The label for the `auth_options` section" } } } }, "error": { "invalid_api_key": "This message will be displayed if `invalid_api_key` is returned as a flow error." }, "abort": { "stale_api_key": "This message will be displayed if `stale_api_key` is returned as the abort reason. Supports Markdown." }, "progress": { "slow_task": "This message will be displayed if `slow_task` is returned as `progress_action` for `async_show_progress`. Supports Markdown." }, "create_entry": { "default": "This message will be displayed in the success dialog if `async_create_entry` is called with `description=None`. Supports Markdown.", "custom": "This message will be displayed in the success dialog if `async_create_entry` is called with `description='custom'`. Supports Markdown." } }, "options": { // Same format as for config flow }, "config_subentries": { "subentry_type_1": { // Same format as for config flow }, "subentry_type_2": { // Same format as for config flow } } } ``` ### 选择器 Selectors 的翻译定义在 `selector` key 下。它支持 selector `select` 的 option label 翻译。集成应在 selector select 配置上设置 `translation_key`。这允许对 config 和 options flows 中使用的 select selectors 进行翻译。下面的示例 strings 文件描述了不同的支持的 key。 ```json { "config": { "flow_title": "Discovered Device ({host})", "step": { "init": { "title": "The user visible title of the `init` step.", "description": "Markdown that is shown with the step.", "data": { // Config flow selector select with options that support translations "set_ca_cert": "Broker certificate validation" } } } }, // Translations for selector select to be used in option and config flows "selector": { // The key is linked to the `translation_key` that needs to be set // using the SelectSelectorConfig class "set_ca_cert": { // The translations for the selector select option labels "options": { "off": "Off", "auto": "Auto", "custom": "Custom" } } } } ``` Number selector 的 `unit_of_measurement` 也可以使用 translation key 进行翻译: ```json { // Translations for number selector to be used in option and config flows "selector": { // The key is linked to the `translation_key` that needs to be set // using the NumberSelectorConfig class "round_digits": { // The translations for the number selector unit_of_measurement "unit_of_measurement": { "decimals": "decimals" } } } } ``` ### Service 操作 Service actions strings 的翻译定义在 `services` key 下。 它支持翻译每个 action 的 `name` 和 `description`、每个 action 的 `fields` 的 `name` 和 `description`,以及每个可折叠 fields section 的 `name` 和 `description`。 请注意,在可折叠 section 中显示的 fields 的 `name` 和 `description` 的翻译也应在 `fields` key 下。 在[注册 service action](/developers/dev_101_services.md#service-action-description-example)时设置 description placeholders。 ```json { "selector": { "fan_speed": { "options": { "high": "High", "low": "Low", "medium": "Medium", "off": "Off", } } }, "services": { "set_speed": { "name": "Set speed", "description": "Sets fan speed. [Learn more.]({docs_url})", "fields": { "speed": { "name": "Speed", "description": "The speed to set." } }, "sections": { "additional_fields": { "name": "Additional options" } } } } } ``` :::note Service actions 可以在其 `fields` 中使用 selectors。这些 selectors 的翻译可以通过 `services.yaml` 文件中 selector 定义上的 `translation_key` 属性提供。更多信息请参见 [Selectors](#selectors) section 和 [Service action description](/developers/dev_101_services.md#service-action-descriptions) 页面。 ::: ### 设备自动化 Device automations 的 translation strings 定义在 `device_automation` key 下。下面的示例 strings 文件描述了不同的支持的 key。 ```json { "device_automation": { // Translations for supported device actions "action_type": { "open": "Open {entity_name}" } // Translations for supported device conditions "condition_type": { "is_open": "{entity_name} is open" } // Translations for supported device triggers "trigger_type": { "opened": "{entity_name} opened", "remote_button_short_press": "\"{subtype}\" button pressed", } // Translations for device trigger sub types, typically used for names of buttons "trigger_subtype": { "button_1": "First button" } } } ``` ### 触发器 Trigger strings 的翻译定义在 `triggers` key 下。结构与[service actions](#service-actions)相同:每个 trigger 以 trigger key(`async_get_triggers` 返回的 key)为键,支持翻译 trigger 的 `name` 和 `description`、每个 `fields` 的 `name` 和 `description`,以及每个可折叠 `section` 的 `name` 和 `description`。 Trigger 的结构(其 fields、sections 和 selectors)定义在 `triggers.yaml` 文件中。更多信息请参见 [Automations](/developers/automations.md) 文档。 ```json { "triggers": { "occupancy_cleared": { "name": "Occupancy cleared", "description": "Triggers when occupancy is cleared.", "fields": { "for": { "name": "For", "description": "The duration the occupancy must be cleared before triggering." } } } } } ``` :::note Triggers 可以在其 `fields` 中使用 selectors。这些 selectors 的翻译可以通过 `triggers.yaml` 文件中 selector 定义上的 `translation_key` 属性提供。更多信息请参见 [Selectors](#selectors) section。 ::: ### 条件 Condition strings 的翻译定义在 `conditions` key 下。与[triggers](#triggers)一样,结构与[service actions](#service-actions)相同:每个 condition 以 condition key(`async_get_conditions` 返回的 key)为键,支持翻译 condition 的 `name` 和 `description`、每个 `fields` 的 `name` 和 `description`,以及每个可折叠 `section` 的 `name` 和 `description`。 Condition 的结构(其 fields、sections 和 selectors)定义在 `conditions.yaml` 文件中。更多信息请参见 [Automations](/developers/automations.md) 文档。 ```json { "conditions": { "door_state": { "name": "Door state", "description": "Tests if the door has a specific state.", "fields": { "state": { "name": "State", "description": "The state the door must have for the condition to pass." } } } } } ``` :::note Conditions 可以在其 `fields` 中使用 selectors。这些 selectors 的翻译可以通过 `conditions.yaml` 文件中 selector 定义上的 `translation_key` 属性提供。更多信息请参见 [Selectors](#selectors) section。 ::: ### 异常 Localization 支持 `HomeAssistantError` 及其子类。 Exceptions 的 translation strings 定义在 `strings.json` 文件中的 `exception` key 下。下面的示例描述了不同的支持的 key。 ```json { "exceptions": { // Translations for known exceptions "invalid_index": { "message": "Invalid index selected, expected [0,1,2]. Got {index}" } } } ``` 在 service action 调用中抛出带 localization 的异常示例: ```python async def async_select_index(hass: HomeAssistant, index: int) -> None: """Set up the config entry for my device.""" try: check_index(index) except ValueError as exc: raise ServiceValidationError( translation_domain=DOMAIN, translation_key="invalid_index", translation_placeholders={ "index": index, }, ) from exc ``` ### 问题 Repairs issues 的 translation strings 定义在 `issues` key 下。下面的示例 strings 文件描述了不同的支持的 key。 ```json { "issues": { "cold_tea": { // The title of the issue "title": "The tea is cold", // Translations for a fixable issue's repair flow, defined in the same way as translation for a configuration flow. // Exactly one of `fix_flow` or `description`. must be present. "fix_flow": { "abort": { "not_tea_time": "Can not re-heat the tea at this time" } } }, "unfixable_problem": { "title": "This is not a fixable problem", // Description of the issue, exactly one of `fix_flow` or `description`. must be present. "description": "This issue can't be fixed by a flow." } } } ``` ### 设备 #### 设备名称 集成可以提供其设备名称的翻译。为此,提供一个 `device` 对象,该对象包含名称的翻译,并将设备的 `translation_key` 设置为 `device` 对象下某个 domain 对应的键。 如果设备的 `translation_key` 不为 `None`,则在 entity 的 `device_info` 属性中设置或通过 `DeviceRegistry.async_get_or_create` 传递的 `name` 将被忽略。如果 `device` 对象没有为指定的 `translation_key` 提供翻译后的名称,`translation_key` 将被用作设备名称。 翻译中也支持使用占位符。如果在翻译字符串中定义了占位符,则设备的 `translation_placeholders` 必须相应地设置。 以下示例 `strings.json` 适用于 `translation_key` 设置为 `power_strip` 的设备: ```json { "device": { "power_strip": { "name": "Power strip" } } } ``` 以下示例 `strings.json` 适用于 `translation_key` 属性设置为 `n_ch_power_strip` 且包含占位符 `number_of_sockets` 的设备: ```json { "device": { "n_ch_power_strip": { "name": "Power strip with {number_of_sockets} sockets" } } } ``` ### 实体 #### 实体名称 集成可以提供其实体名称的翻译。为此,提供一个 `entity` 对象,该对象包含名称的翻译,并将实体的 `translation_key` 属性设置为 `entity` 对象下某个 domain 对应的键。 如果实体的 `translation_key` 属性不为 `None` 且 `entity` 对象提供了翻译后的名称,`EntityDescription.name` 将被忽略。 实体名称的本地化仅支持将 [`has_entity_name`](/developers/core/entity.md#has_entity_name-true-mandatory-for-new-integrations) 属性设置为 `True` 的实体。 像 `sensor` 这样的 entity components 已经有现成的翻译可供通过引用复用。这包括基于 device class 的通用实体名称翻译。例如,它已经有 "Temperature" 传感器的翻译可供引用。优先使用引用现有翻译,因为它可以避免多次翻译相同内容。 翻译中也支持使用占位符。如果在翻译字符串中定义了占位符,则实体的 `translation_placeholders` 属性必须相应地设置。 以下示例 `strings.json` 适用于 `translation_key` 属性设置为 `thermostat_mode` 的 `sensor` 实体: ```json { "entity": { "sensor": { "thermostat_mode": { "name": "Thermostat mode" } } } } ``` 以下示例 `strings.json` 适用于 `translation_key` 属性设置为 `temperature_sensor` 的 `sensor` 实体,其中使用了由 `sensor` 集成提供的共享翻译: ```json { "entity": { "sensor": { "temperature_sensor": { "name": "[%key:component::sensor::entity_component::temperature::name%]" } } } } ``` 以下示例 `strings.json` 适用于 `translation_key` 属性设置为 `distance` 且包含占位符 `tracked_device` 的 `sensor` 实体: ```json { "entity": { "sensor": { "distance": { "name": "Distance of {tracked_device}" } } } } ``` #### 实体状态 如果基础 entity component 不提供翻译,或者基础 entity component 提供的翻译与集成的实体不匹配,集成可以提供其实体在 sensor 等其他集成下状态的翻译。为此,提供一个 `entity` 对象,该对象包含状态的翻译,并将实体的 `translation_key` 属性设置为 `entity` 对象下某个 domain 对应的键。 请注意,翻译后的 state 必须像所有其他翻译键一样为 `snake_case`。 为了区分实体及其翻译,请提供不同的 translation keys。以下示例 `strings.json` 适用于 Moon domain 下 `translation_key` 属性设置为 `phase` 的 `sensor` 实体: ```json { "entity": { "sensor": { "phase": { "state": { "new_moon": "New moon", "first_quarter": "First quarter", "full_moon": "Full moon", "last_quarter": "Last quarter" } } } } } ``` #### 实体状态属性 如果基础 entity component 不提供翻译,或者基础 entity component 提供的翻译与集成的实体不匹配,集成可以提供其实体在 sensor 等其他集成下状态属性的翻译。为此,提供一个 `entity` 对象,该对象包含实体状态属性的翻译,并将实体的 `translation_key` 属性设置为 `entity` 对象下某个 domain 对应的键。 请注意,翻译后的状态属性必须像所有其他翻译键一样为 `snake_case`。 为了区分实体及其翻译,请提供不同的 translation keys。以下示例 `strings.json` 适用于 `demo` domain 下 `translation_key` 属性设置为 `ubercool` 的 `climate` 实体,它具有自定义的 `fan_mode` 和 `swing_mode` 设置: ```json { "entity": { "climate": { "ubercool": { "state_attributes": { "fan_mode": { "state": { "auto_high": "Auto High", "auto_low": "Auto Low", "on_high": "On High", "on_low": "On Low" } }, "swing_mode": { "state": { "1": "1", "2": "2", "3": "3", "auto": "Auto", "off": "Off" } } } } } } } ``` #### Entity component 状态 如果你的集成在其 domain 下提供实体,你将需要翻译这些状态。通过在 `entity_component` 字典下提供一个 `states` 对象来实现,该对象包含具有不同 device class 的状态的翻译。键 `_` 用于没有 device class 的实体。 ```json { "entity_component": { "problem": { "state": { "off": "OK", "on": "Problem" } }, "safety": { "state": { "off": "Safe", "on": "Unsafe" } }, "_": { "state": { "off": "[%key:common::state::off%]", "on": "[%key:common::state::on%]" } } } } ``` #### Entity component 的实体属性名称和状态 :::info 实体属性名称和状态的翻译还需要前端支持,目前仅适用于 `climate` 实体。 ::: 如果你的集成在其 domain 下提供实体,你将需要翻译实体属性名称以及实体状态属性。通过在 `entity_component` 字典中提供一个 `state_attributes` 对象来实现,该对象包含具有不同 device class 的实体属性的翻译。键 `_` 用于没有 device class 的实体。 ```json { "entity_component": { "_": { "state_attributes": { "aux_heat": { "name": "Aux heat" }, "current_humidity": { "name": "Current humidity" }, "current_temperature": { "name": "Current temperature" }, "fan_mode": { "name": "Fan mode", "state": { "off": "[%key:common::state::off%]", "on": "[%key:common::state::on%]", "auto": "Auto", "low": "Low", "medium": "Medium", "high": "High", "top": "Top", "middle": "Middle", "focus": "Focus", "diffuse": "Diffuse" } } } } } } ``` #### 实体测量单位 集成可以提供其实体测量单位的翻译。为此,提供一个 `entity` 对象,该对象包含单位的翻译,并将实体的 `translation_key` 属性设置为 `entity` 对象下某个 domain 对应的键。 如果实体的 `translation_key` 属性不为 `None` 且 `entity` 对象提供了翻译后的测量单位,则不应定义 `SensorEntityDescription.native_unit_of_measurement` 或 `NumberEntityDescription.native_unit_of_measurement`。 以下示例 `strings.json` 适用于 `translation_key` 属性设置为 `goal` 的 `sensor` 实体: ```json { "entity": { "sensor": { "goal": { "unit_of_measurement": "steps" } } } } ``` ## 测试翻译 要测试翻译文件的更改,翻译字符串必须通过运行以下脚本编译到 Home Assistant 的翻译目录中: ```shell python3 -m script.translations develop ``` 如果翻译不显示,请清除浏览器缓存(MacOS 为 cmd + R,Windows 和 Linux 为 ctrl + F5)。 ## 引入新字符串 要引入新字符串,请将其添加到 `strings.json` 或平台字符串文件中。尽可能多地引用通用字符串。通用字符串存放在 `homeassistant/strings.json` 中。你可以使用引用来引用这些翻译。例如: ```json { "config": { "abort": { "already_configured": "[%key:common::config_flow::abort::already_configured_device%]" } } } ``` 包含字符串文件的 pull request 合并到 `dev` 分支后,字符串将自动上传到 Lokalise,贡献者可以在那里提交翻译。Lokalise 中的翻译字符串将被定期拉取到核心仓库中。 --- url: /developers/internationalization/custom_integration.md --- ## Translation strings 与合并到 `home-assistant` 仓库中的本地化 strings 不同,custom integrations 无法利用 Lokalise 获取用户提交的翻译。然而,custom integration 作者仍然可以在其集成中包含翻译。这些翻译将从集成的源代码相邻的 `translations` 目录中读取。它们在 `translations` 目录中命名为 `.json`,例如,德语翻译为 `de.json`。 该文件将包含 custom integration 提供的、需要翻译的各种内容的可翻译字符串。这些文件的格式与[后端 translation string 文件](internationalization/core.md)相同,但每个已翻译的语言都会有一个副本。 Language codes 遵循 [BCP47](https://tools.ietf.org/html/bcp47) 格式。 为确保翻译文件正确,请使用我们的集成验证工具 Hassfest 进行测试。[设置说明在此。](https://developers.home-assistant.io/blog/2020/04/16/hassfest) :::caution Strings.json vs. Translations **Custom components 不要使用 `strings.json`。** `strings.json` 文件和占位符语法(例如 `[%key:common::config_flow::data::email%]`)是仅由 Home Assistant Core 使用的**build-time features**。 Custom integrations 不会运行内部的 translation build script。你必须手动创建 `translations/en.json` 文件,并为每个 key 包含完整的、扁平的英文文本。如果使用 `strings.json` 或占位符,你的 config flow 将无法加载翻译,并显示原始 key(例如显示 `username` 而非翻译值 `Enter Username`)。 ::: --- url: /developers/misc.md --- 杂项类别。各主题之间相互无关。 --- url: /developers/modbus/introduction.md --- Modbus 是一种基于轮询的通信协议,通过串口和 TCP 进行通信。它广泛用于智能家居,适用于太阳能逆变器、电能表以及其他已经进入我们家庭的工业设备。 ## 编写 Modbus 库 我们要求每个集成都实现一个库,用于处理设备特定的通信。为了帮助构建这些库,我们维护了 [`modbus-connection`](https://home-assistant-libs.github.io/modbus-connection/) 这个 Python 包。 `modbus-connection` 提供: * 基于两个流行的 Modbus 库 [pymodbus](https://github.com/pymodbus-dev/pymodbus) 和 [tmodbus](https://github.com/wlcrs/tmodbus) 之上的通用、与后端无关的接口,因此你可以不修改代码就切换后端。 * 一个设备建模框架,将设备数据映射为带类型的 Python 属性,并以尽可能少的请求次数读取数据([Trovis 示例](https://github.com/Tom-Bom-badil/trovis-modbus/blob/main/src/trovis_modbus/heating_circuit.py))。 * 一个 `pytest` 插件,使库的测试更加便捷。 如需了解该模式的完整示例,请参阅 [trovis-modbus](https://github.com/Tom-Bom-badil/trovis-modbus)(一个基于 `modbus-connection` 构建的设备库)以及 [trovis-modbus-hass](https://github.com/Tom-Bom-badil/trovis-modbus-hass)(使用该库的 Home Assistant 集成)。 --- url: /developers/network_discovery.md --- 某些 integrations 在启用后,可能需要通过 [mDNS/Zeroconf](https://en.wikipedia.org/wiki/Zero-configuration_networking)、[SSDP](https://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol) 或其他方法在网络中自动发现设备。主要的使用场景是查找没有已知固定 IP Address 的设备,或者用于可以动态添加和移除任意数量兼容可发现设备的 integrations。 Home Assistant 内置了支持 mDNS/Zeroconf 和 SSDP 的 helpers。如果你的 integration 使用了其他 discovery method,并且需要确定使用哪些 network interfaces 来广播流量,[Network](https://www.home-assistant.io/integrations/network/) integration 提供了一个 helper API 来访问用户的 interface 偏好设置。 ## mDNS/Zeroconf Home Assistant 使用 [python-zeroconf](https://github.com/python-zeroconf/python-zeroconf) 包来提供 mDNS 支持。由于不建议在单个主机上运行多个 mDNS 实现,Home Assistant 提供了内部 helper APIs 来访问正在运行的 `Zeroconf` 和 `AsyncZeroconf` 实例。 在使用这些 helpers 之前,请确保在你的 integration 的 [`manifest.json`](/developers/creating_integration_manifest.md) 中将 `zeroconf` 添加到 `dependencies` 中。 ### 获取 `AsyncZeroconf` 对象 ```python from homeassistant.components import zeroconf ... aiozc = await zeroconf.async_get_async_instance(hass) ``` ### 获取 `Zeroconf` 对象 ```python from homeassistant.components import zeroconf ... zc = await zeroconf.async_get_instance(hass) ``` ### 使用 `AsyncZeroconf` 和 `Zeroconf` 对象 `python-zeroconf` 提供了关于如何使用这两个对象的示例:[examples](https://github.com/jstasiak/python-zeroconf/tree/master/examples)。 ## SSDP Home Assistant 提供了基于 SSDP 的内置自动发现功能。 在使用这些 helpers 之前,请确保在你的 integration 的 [`manifest.json`](/developers/creating_integration_manifest.md) 中将 `ssdp` 添加到 `dependencies` 中。 ### 获取已发现设备列表 可以通过以下内置 helper APIs 获取已发现的 SSDP 设备列表。SSDP integration 提供了以下 helper APIs 来从缓存中查找现有的 SSDP discoveries:`ssdp.async_get_discovery_info_by_udn_st`、`ssdp.async_get_discovery_info_by_st`、`ssdp.async_get_discovery_info_by_udn` ### 查找特定设备 `ssdp.async_get_discovery_info_by_udn_st` API 在提供 `SSDP`、`UDN` 和 `ST` 时,返回单个 `discovery_info` 或 `None`。 ``` from homeassistant.components import ssdp ... discovery_info = await ssdp.async_get_discovery_info_by_udn_st(hass, udn, st) ``` ### 按 `ST` 查找设备 如果你想查找特定类型的已发现设备,调用 `ssdp.async_get_discovery_info_by_st` 将返回所有与 `SSDP` `ST` 匹配的已发现设备列表。下面的示例返回网络中发现的每个 Sonos player 的 discovery info 列表。 ``` from homeassistant.components import ssdp ... discovery_infos = await ssdp.async_get_discovery_info_by_st(hass, "urn:schemas-upnp-org:device:ZonePlayer:1") for discovery_info in discovery_infos: ... ``` ### 按 `UDN` 查找设备 如果你想查看特定 `UDN` 所提供的服务列表,调用 `ssdp.async_get_discovery_info_by_udn` 将返回所有与 `UPNP` `UDN` 匹配的已发现设备列表。 ``` from homeassistant.components import ssdp ... discovery_infos = await ssdp.async_get_discovery_info_by_udn(hass, udn) for discovery_info in discovery_infos: ... ``` ### 订阅 SSDP 发现 某些 integrations 可能需要立即获知设备被发现的事件。SSDP integration 提供了一个 registration API,当发现的新设备匹配特定 key values 时接收回调。匹配规则使用与 [`manifest.json`](/developers/creating_integration_manifest.md) 中 `ssdp` 相同的格式。 `ssdp.async_register_callback` 函数提供了此功能。该函数返回一个回调,调用该回调即可取消注册。 下面的示例展示了注册以在网络中出现 Sonos player 时接收回调。 ``` from homeassistant.components import ssdp ... entry.async_on_unload( await ssdp.async_register_callback( hass, _async_discovered_player, {"st": "urn:schemas-upnp-org:device:ZonePlayer:1"} ) ) ``` 下面的示例展示了注册以在 `x-rincon-bootseq` header 存在时接收回调。 ``` from homeassistant.components import ssdp from homeassistant.const import MATCH_ALL ... entry.async_on_unload( await ssdp.async_register_callback( hass, _async_discovered_player, {"x-rincon-bootseq": MATCH_ALL} ) ) ``` ## DHCP Home Assistant 提供了基于 DHCP 的内置自动发现功能。 在使用这些 helpers 之前,请确保在你的 integration 的 [`manifest.json`](/developers/creating_integration_manifest.md) 中将 `dhcp` 添加到 `dependencies` 中。 ### 获取已发现设备列表 要访问当前的 DHCP discoveries 列表,请调用 `dhcp.async_discovered_service_info` API。仅返回仍处于 DHCP cache 中的设备。 ```python from homeassistant.components import dhcp ... service_infos = dhcp.async_discovered_service_info(hass) for service_info in service_infos: ... ``` 每个条目都是一个 `DhcpServiceInfo`,包含 `ip`、`hostname` 和 `macaddress` 属性。请注意,`hostname` 始终为小写,`macaddress` 格式化为不带冒号的小写字符串(例如,`AA:BB:CC:12:34:56` 将返回为 `aabbcc123456`)。 ## 网络 对于使用非内置 discovery method 且需要访问用户 network adapter 配置的 integrations,应使用以下 helper API。 ```python from homeassistant.components import network ... adapters = await network.async_get_adapters(hass) ``` ### `async_get_adapters` 数据结构示例 ```python [ { "auto": True, "default": False, "enabled": True, "ipv4": [], "ipv6": [ { "address": "2001:db8::", "network_prefix": 8, "flowinfo": 1, "scope_id": 1, } ], "name": "eth0", }, { "auto": True, "default": False, "enabled": True, "ipv4": [{"address": "192.168.1.5", "network_prefix": 23}], "ipv6": [], "name": "eth1", }, { "auto": False, "default": False, "enabled": False, "ipv4": [{"address": "169.254.3.2", "network_prefix": 16}], "ipv6": [], "name": "vtun0", }, ] ``` ### 从适配器获取 IP 网络 ```python from ipaddress import ip_network from homeassistant.components import network ... adapters = await network.async_get_adapters(hass) for adapter in adapters: for ip_info in adapter["ipv4"]: local_ip = ip_info["address"] network_prefix = ip_info["network_prefix"] ip_net = ip_network(f"{local_ip}/{network_prefix}", False) ``` ## USB USB integration 在启动时、访问 integrations 页面时,以及在底层系统支持 `pyudev` 的情况下插入设备时,会发现新的 USB 设备。 ### 了解何时查找新的兼容 USB 设备 调用 `async_register_scan_request_callback` API 以在可能有新的兼容 USB 设备可用时请求回调。 ```python from homeassistant.components import usb from homeassistant.core import callback ... @callback def _async_check_for_usb() -> None: """Check for new compatible USB adapters.""" entry.async_on_unload( usb.async_register_scan_request_callback(hass, _async_check_for_usb) ) ``` --- url: /developers/operating-system.md --- Home Assistant Operating System 是一个专门设计的操作系统,专为在单板计算机和 x86-64 系统上运行 Home Assistant 而打造。它旨在提供一个健壮且免维护的操作系统来运行 Home Assistant。 Home Assistant Operating System (HAOS) 使用 [Buildroot](https://buildroot.org/) 构建系统。Buildroot 并非传统意义上的 Linux 发行版。它提供用于构建 Linux 发行版的 infrastructure 和构建系统。Buildroot 允许我们为不同的架构进行交叉编译,这在为资源通常较为有限的架构(如基于 Arm 的系统)编译时尤其有用。HAOS 由一组较为常规的 Linux 和 GNU 软件栈组成,使用 Linux、GNU C library、systemd init daemon 以及 Home Assistant Supervisor 所需的 Docker container engine。 ### Components * **Bootloader:** * [GRUB](https://www.gnu.org/software/grub/) 用于支持 UEFI 的设备 * [U-Boot](https://www.denx.de/wiki/U-Boot) 用于不支持 EFI 的设备 * **Operating System:** * [Buildroot](https://buildroot.org/) 构建系统,用于生成 Linux 发行版 * **File Systems:** * [SquashFS](https://www.kernel.org/doc/Documentation/filesystems/squashfs.txt) 用于只读文件系统(使用 LZ4 压缩) * [ZRAM](https://www.kernel.org/doc/Documentation/blockdev/zram.txt) 用于 `/tmp`、`/var` 和 swap(使用 LZ4 压缩) * **Container Platform:** * [Docker Engine](https://docs.docker.com/engine/) 用于在容器中运行 Home Assistant components * **Updates:** * [RAUC](https://rauc.io/) 用于 Over The Air (OTA) 和 USB 更新 * **Security:** * [AppArmor](https://apparmor.net/) Linux kernel security module --- url: /developers/operating-system/board-metadata.md --- 每个受支持的板卡都有一个 Home Assistant Operating System(HAOS)特有的元数据文件,名为 `meta`。这记录了变量和可用的选项。 ## 板卡特定变量 `BOARD_ID`: 板卡标识符。通常为全小写。用于生成文件名,并在 os-release 文件中用作 `VARIANT_ID`。 `BOARD_NAME`: 用户友好的板卡名称。用于 os-release 文件中的 `VERSION` 和 `VARIANT` 变量。 ## 启动相关变量 `BOOT_ENV_SIZE`: bootloader 环境的最大大小(以十六进制表示)。rauc 需要此参数。 `BOOT_SYS`: * efi * hybrid * mbr HAOS 在可能的情况下尽量使用 GPT。要使用 GPT,第二个逻辑块(LBA)必须可用。在某些板卡上,该块被 boot 固件保留或需要。如果是这种情况,则需要使用经典 MBR 方法。 Hybrid 在 GPT 可用的情况下同时使用两种分区表,但底层固件仍需要 MBR。 `BOOT_SPL`: * true * false 启用 SPL(secondary program loader)处理。某些 U-Boot 目标除了主要的 U-Boot 二进制文件外,还会生成一个小的加载器(SPL)。 `BOOTLOADER`: * grub * uboot HAOS 主要使用 [U-Boot](https://www.denx.de/wiki/U-Boot)。对于 UEFI 系统,使用 [GRUB](https://www.gnu.org/software/grub/)。 `DISK_SIZE`: 默认值为 2。最终(未压缩)镜像的大小,单位为 GB。 `KERNEL_FILE`: 内核二进制文件的文件名。aarch64 通常为 `Image`,`armv7` 为 `zImage`,`amd64` 为 `bzImage`。 ## Supervisor 相关变量 `SUPERVISOR_MACHINE`: * generic-x86-64 * khadas-vim3 * odroid-c2 * odroid-c4 * odroid-n2 * odroid-xu * qemuarm * qemuarm-64 * qemux86 * qemux86-64 * raspberrypi * raspberrypi2 * raspberrypi3 * raspberrypi4 * raspberrypi3-64 * raspberrypi4-64 * tinker `SUPERVISOR_ARCH`: * amd64 * i386 * armhf * armv7 * aarch64 --- url: /developers/operating-system/boards/asus.md --- ## 支持的硬件 | 设备 | 发布日期 | 支持状态 | 配置 | |--------------|-------------|----------|--------| | Tinker RK3288 | 2017 年 4 月 | 是 | [tinker](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/tinker_defconfig) | | Tinker S RK3288| 2018 年 1 月 | 是 | [tinker](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/tinker_defconfig) | | Tinker Edge T | 2019 年 11 月 | 否? | | | Tinker Edge R | 2019 年 11 月 | 否? | | ## eMMC eMMC 支持通过相同的镜像提供。只需通过 Micro-USB 将 Tinker Board S 连接到 PC,然后将镜像刷入 eMMC 即可。请参阅 Tinkerboard 文档,了解如何使用 Micro-USB 和 UMS 进行刷写。 Home Assistant OS 提供的 U-Boot 同样支持 UMS, 但需要进行手动操作: 1. 将 Micro-USB 与 HDMI 之间的跳线设置为 maskrom 模式 2. 插入 SD 卡,并通过 Micro-USB 将开发板连接到 PC 3. 持续按 Ctrl+C 以中断启动 4. 将跳线拨回 park 位置 5. 使用以下命令启动 UMS: ``` ums 0 mmc 0 ``` 6. 系统应显示一个 mass storage 设备。将 Home Assistant OS 刷入该设备即可。 ## 串口控制台 要通过串口控制台访问终端,请在 `cmdline.txt` 中添加 `console=ttyS2,115200`。GPIO 引脚为:34 = GND / 32 = UART TXD / 33 = UART RXD。 --- url: /developers/operating-system/boards/generic-aarch64.md --- ## 支持的硬件 此 board 配置旨在支持大多数通过 UEFI 启动的 aarch64 系统。 经测试的硬件如下所示。 ## 已测试的硬件 | 设备 | 发布日期 | 支持状态 | 配置 | |---------------------|----------|----------|-----------| | QEMU | QEMU | 是 | [generic\_aarch64](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/generic_aarch64_defconfig) | ## 要求 * aarch64 支持 * UEFI 启动 ## Wi-Fi WiFi 尚未测试。 ## 蓝牙 Bluetooth 尚未测试。 ## 安装 请确保已在 UEFI BIOS 设置中禁用 secure boot。 目前还没有漂亮的安装方法。检查清单如下: * 使用 PXE 或 USB 将 PC 启动到 live environment * 将 Home Assistant OS 镜像复制或下载到 live environment 中 * 使用 unxz 解压镜像,并通过 dd 写入本地硬盘 * 重启 --- url: /developers/operating-system/boards/generic-x86-64.md --- ## 支持的硬件 此 board 配置旨在支持大多数通过 UEFI 启动的 x86-64 系统。主要目标是支持 Intel NUC 迷你 PC 及类似系统。经测试的硬件如下所示。 ## 已测试的硬件 | 设备 | 发布日期 | 支持状态 | 配置 | |---------------------|----------|----------|-----------| | Intel NUC5CPYH | 2015 Q3 | 是 | [generic\_x86\_64](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/generic_x86_64_defconfig) | | Intel NUC6CAYH | 2016 Q4 | 是 | [generic\_x86\_64](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/generic_x86_64_defconfig) | | Intel NUC6CAYS | 2016 Q4 | 是 | [generic\_x86\_64](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/generic_x86_64_defconfig) | | Intel NUC7i3DNHE | 2017 Q3 | 是 | [generic\_x86\_64](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/generic_x86_64_defconfig) | | Intel NUC10i3FNK2 | 2019 Q4 | 是 | [generic\_x86\_64](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/generic_x86_64_defconfig) | | Gigabyte GB-BPCE-3455 | 2017 | 是\* | [generic\_x86\_64](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/generic_x86_64_defconfig) | \* 如果需要 console,需要在 cmdline.txt 中添加 `nomodeset` ## 要求 * x86-64 支持 * UEFI 启动 * SATA/AHCI 或 eMMC 存储 * 受支持的 NIC: * Intel Gigabit NIC (e1000, igb - via Linux mainline) * Intel PCIe Gigabit NIC (e1000e - via *https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/package/intel-e1000e* 中的 out-of-tree module) * Realtek Gigabit NIC (r8169) * Intel Wireless Wifi 802.11ac (iwlwifi, 见下文) ## Wi-Fi 以下网卡受支持: * Intel Wireless 3160 * Intel Wireless 7260 * Intel Wireless 7265 * Intel Wireless-AC 3165 * Intel Wireless-AC 3168 * Intel Wireless-AC 8260 * Intel Wireless-AC 8265 * Intel Wireless-AC 9260 * Intel Wireless-AC 9461 * Intel Wireless-AC 9462 * Intel Wireless-AC 9560 ## 蓝牙 集成在 Intel Wireless 网卡中的 Bluetooth 工作正常,其他方案尚未测试。 ## 安装 请确保已在 UEFI BIOS 设置中禁用 secure boot。 目前还没有漂亮的安装方法。检查清单如下: * 使用 PXE 或 USB 将 PC 启动到 live environment * 将 Home Assistant OS 镜像复制或下载到 live environment 中 * 使用 unxz 解压镜像,并通过 dd 写入本地硬盘 * 重启 --- url: /developers/operating-system/boards/hardkernel.md --- ## 支持的硬件 | 设备 | 发布日期 | 支持状态 | 配置 | |--------------|-----------|--------------|---------| | ODROID-C2 | 2016 | 是 | [odroid\_c2](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/odroid_c2_defconfig) | | ODROID-C4 | 2020 | 是 | [odroid\_c4](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/odroid_c4_defconfig) | | ODROID-M1 | 2022 | 是 | [odroid\_m1](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/odroid_m1_defconfig) | | ODROID-M1S | 2023 | 是 | [odroid\_m1s](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/odroid_m1s_defconfig)| | ODROID-N2 | 2019 | 是 | [odroid\_n2](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/odroid_n2_defconfig) | | ODROID-XU4 | 2015 | 是 | [odroid\_xu4](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/odroid_xu4_defconfig)| 请参阅各开发板的单独文档。 ## 联网设备 ### Wi-Fi 以下设备已在 Home Assistant OS 5.8 上测试通过: * [Bluetooth Module 2](https://www.hardkernel.com/shop/bluetooth-module-2/) * [WiFi Module 3](https://www.hardkernel.com/shop/wifi-module-3/) [WiFi Module 5A](https://www.hardkernel.com/shop/wifi-module-5a/) 不推荐使用, 因为没有可用的 upstream driver 支持。目前与近期 Linux kernel 版本兼容的 driver 在连接到 5GHz 网络时似乎存在问题。 --- url: /developers/operating-system/boards/odroid-c2.md --- ## eMMC eMMC 支持是透明提供的。只需像刷入 SD 卡一样将镜像刷入 eMMC 板即可。 ## 控制台 默认情况下,控制台访问通过串口 header 和 HDMI 提供。某些启动消息默认仅在串口控制台上显示。若要在 HDMI 控制台上显示这些消息,请交换 boot 分区上 `cmdline.txt` 文件中两个控制台的顺序。如果你不打算使用串口适配器,也可以删除 AML0 控制台。 例如,`console=ttyAML0,115200n8 console=tty0` ## USB 一个长期存在的 kernel 漏洞目前会导致一些异常行为。要使用 USB,必须在硬启动时将设备插入其中一个 USB 端口。如果所有设备都被从 USB 端口移除,USB 将停止工作,直到重启。 ### OTG OTG USB 尚未经过测试。 ## GPIO 请参考 [the odroid wiki](https://wiki.odroid.com/odroid-c2/hardware/expansion_connectors)。 --- url: /developers/operating-system/boards/odroid-c4.md --- ## Experimental ODROID-C4 支持大量基于 Odroid-C2 和 N2 的配置。鉴于 SoC 的相似性,以及 Linux kernel 中相当级别的支持,C4 应该不会有太多意外。然而,Home Assistant 的支持仍应被视为实验性的。 还请参考 [ODROID-C2](/developers/operating-system/boards/odroid-c2.md) 和 [Odroid-N2](/developers/operating-system/boards/odroid-n2.md) 的文档页面,因为其中部分信息同样可能适用于 C4。 已经专门测试并且看起来工作正常的常见 C4 问题: * boot from SD * boot from eMMC * MAC address obtained from eFuse ## GPIO 请参考 [the odroid wiki](https://wiki.odroid.com/odroid-c4/hardware/expansion_connectors)。 --- url: /developers/operating-system/boards/odroid-m1.md --- Home Assistant OS 10 及更高版本支持 ODROID-M1 板。 ## SD-card SD 卡启动通过板载 bootloader(SPL)或 recovery 按钮支持。 ## eMMC 通过板载 bootloader 启动 eMMC 需要更新版本的 Petitboot (spiboot 20230328 或更高版本)。要安装最新版本,请按如下方式从 [linuxfactory.or.kr][1] 下载 SPI boot image: 1. 下载 `spiupdate_odroidm1_20240415.img.xz` 2. 使用 balenaEtcher 或其他工具将更新程序刷入 SD 卡 3. 下载 `spiboot-20240109.img` 4. 将 `spiboot-20240109.img` 文件重命名为 `spiboot.img`。 5. 将 `spiboot.img` 文件粘贴到同一张 SD 卡的 FAT 分区中。 6. 将该 SD 卡插入 ODROID-M1。Petitboot 会自动更新自身,你可以在 HDMI 输出上确认进度。 7. 如果你在左上角看到版本 20240109,则安装成功。\ 如果在左上角看到任何其他版本,则安装失败。 更新 Petitboot 后,即可将 Home Assistant OS 直接刷入 eMMC。 ## NVMe 不支持直接从 NVMe 启动。NVMe 卡可作为数据盘使用。 ## 启动流程技术说明 Home Assistant OS 镜像可由 SoC 直接启动。这意味着无需借助 Hardkernel 提供并预装的 bootloader Petitboot。 然而,ODROID-M1 会自动从内部 SPI 启动。要直接从 SD 卡或 eMMC 启动,你需要按下 recovery 按钮。 通过 SPI 刷入的 U-Boot SPL 会尝试在 SD 卡上搜索 U-Boot 二进制文件 (并在使用 Petitboot 20230328 及更高版本时从 eMMC 搜索)。此机制允许你在不按下 recovery 按钮的情况下启动 Home Assistant OS U-Boot。 ## Console 默认情况下,可在串口 header(CON1)和 HDMI 上获得控制台访问。 串口控制台的波特率默认为 1500000。 systemd 启动消息默认仅在串口控制台上显示。 若要在 HDMI 控制台上显示这些消息,请手动将 console 添加到 boot 分区上的 `cmdline.txt` 文件中(例如,`console=tty0`)。 [1]: http://ppa.linuxfactory.or.kr/images/petitboot/odroidm1/ --- url: /developers/operating-system/boards/odroid-m1s.md --- Home Assistant OS 12 及更高版本支持 ODROID-M1S 板。 ## SD-card ODROID-M1S 可以直接从 SD 卡启动 HAOS,因为 SD 卡的优先级高于 eMMC 上的系统。只需使用你喜欢的工具将镜像刷入 SD 卡,然后将其插入板上的 micro SD 槽即可。即使 eMMC 被清空,或者其中包含出厂默认的 U-Boot SPL 加载器,这也同样有效,因为该加载器仍然能够加载 HAOS 镜像中提供的 U-Boot。但在后一种情况下,如果 SD 卡探测失败(例如,由于硬件故障),则可能会启动 eMMC 上的系统,而非 HAOS。 ## eMMC 可以使用特殊的 boot image 将 HAOS 直接安装到 eMMC 上,步骤如下: 1. 下载 *UMS Utility* 镜像:[`ODROID-M1S_EMMC2UMS.img`][1]。*UMS Utility* 是一种特殊镜像,可将 ODROID-M1S 切换为 USB Mass Storage 设备。 2. 使用 balenaEtcher 或其他工具将 *UMS utility* 刷入 SD 卡。 3. 将该 SD 卡插入 ODROID-M1S 并启动它。将你的 PC 连接到 Micro USB OTG 端口。 4. eMMC 将作为驱动器显示在你的 PC 上,你可以直接使用 balenaEtcher 刷入 HAOS 镜像。 安装 HAOS 会用 HAOS 提供的主线版本替换 eMMC 上的 firmware 和 SPL。因此,无法再使用带有 EMMC2UMS 镜像的 SD 卡,因为主线 SPL 目前(2024 年 2 月)与 EMMC2UMS 镜像中的 U-Boot 不兼容。这对标准使用不会造成任何问题,只是在你想要恢复到 Hardkernel 提供的操作系统时,会变得更复杂一些。 在这种情况下重新刷写 eMMC 的可靠方法是,将 [the binary](https://dn.odroid.com/RK3566/ODROID-M1S/Installer/ODROID-M1S_EMMC2UMS.img) 从 Odroid 下载到运行 ssh server 的 PC 上。 然后,在 Odroid M1S 设备上使用 HA CLI,输入 `login` 命令进入 root shell。 从那里,将二进制文件从你的 PC 复制过来(例如,`ssh user@mypc.local:/path_to/ODROID-M1S_EMMC2UMS.img /tmp` ——将 user 替换为你在 PC 上的用户名,将 mypc.local 替换为你的计算机名或 IP 地址,将 path\_to 替换为你下载的二进制文件的实际路径)。该命令随后会将二进制文件复制到你的 HAOS 的 /tmp/ 中。 接下来,运行 `dd if=/tmp/ORDOID-M1S_EMMC2UMS.img of=/dev/mmcblk0` ——这会将二进制镜像写入 eMMC 的 boot 部分。 **警告:** 由于 odroid.com 页面存在机器人检测,请勿使用 curl 命令,因为它不会下载实际文件;这有使你的设备变砖的风险! 这样,设备在下次启动时(移除 SD 卡后)将以 UMS 模式启动。或者,你也可以直接使用 [Hardkernel installer image][2] 代替 EMMC2UMS 镜像。 ## NVMe 不支持直接从 NVMe 启动。NVMe 卡可作为数据盘使用。 ## 启动流程技术说明 Home Assistant OS 镜像可由 SoC 直接启动。有关从 eMMC 执行启动的哪一部分、从 SD 卡执行哪一部分的详细信息,请参阅 [boot sequence documentation][3]。但上述记录的步骤应涵盖普通用户在使用过程中可能遇到的所有场景。 ## Console 默认情况下,可在串口 header(UART)和 HDMI 上获得控制台访问。 串口控制台的波特率默认为 1500000。 systemd 启动消息默认仅在串口控制台上显示。 若要在 HDMI 控制台上显示这些消息,请手动将 console 添加到 boot 分区上的 `cmdline.txt` 文件中(例如,`console=tty0`)。 ## GPIO Odroid-M1S 引入了一个新的 14pin 扩展 header。请参考 [the ODROID wiki][4]。 目前,Home Assistant OS 使用的上游 kernel 尚不支持所有功能。\ 受支持的模块包括: * UPS * Internal USB * Mini IO board(部分支持) [1]: https://dn.odroid.com/RK3566/ODROID-M1S/Installer/ODROID-M1S_EMMC2UMS.img [2]: https://wiki.odroid.com/odroid-m1s/getting_started/os_installation_guide#user_installer [3]: https://wiki.odroid.com/odroid-m1s/board_support/boot_sequence [4]: https://wiki.odroid.com/odroid-m1s/hardware/expansion_connectors --- url: /developers/operating-system/boards/odroid-n2.md --- ## eMMC eMMC 支持是透明提供的。只需将镜像刷入 eMMC 板,就像刷入 SD 卡一样。 ## 控制台 默认情况下,通过串口 header 和 HDMI 提供控制台访问。某些启动消息默认仅在串口控制台上显示。要在 HDMI 控制台上显示这些消息,请交换 boot 分区上 `cmdline.txt` 文件中两个控制台的顺序。如果你不打算使用串口适配器,也可以删除 AML0 控制台。 例如,`console=ttyAML0,115200n8 console=tty0` ## GPIO 请参考 [odroid wiki](https://wiki.odroid.com/odroid-n2/hardware/expansion_connectors)。 目前,Home Assistant OS 使用的上游内核尚不支持所有功能。 第 11 号引脚上的 GPIO 被用作低电平有效的电源按钮输入。 --- url: /developers/operating-system/boards/odroid-xu4.md --- ## eMMC ODROID XU4 使用 eMMC boot 分区来启动。通常 eMMC 读卡器无法写入该 eMMC boot 分区。有以下几种可能: 1. **可工作** 例如,在刷入 HassOS 之前 eMMC 上已经有一个可工作的镜像: * 它将启动到 U-Boot(但无法继续)。 * 如果你有串口适配器,应该能够在 uboot 提示符下输入 `distro_bootcmd` 以继续启动。 * 如果没有,将 HassOS 镜像刷入 SD 卡并暂时从该卡启动(同时 eMMC 也保持连接)。 * 启动后,在提示符处登录,然后在 linux 提示符下输入 `dd if=/dev/mmcblk0 of=/dev/mmcblk0boot0 bs=512 skip=63 seek=62 count=1440`。 * 使用 eMMC 重启(别忘了将 boot 开关切换到 eMMC) 2. **不可工作** 例如,eMMC boot 分区是干净/已清空/已损坏的: * 你需要按照 [Hardkernel's instructions](https://forum.odroid.com/viewtopic.php?f=53\&t=6173) 来获取一个可工作的 boot sector。然后刷入 HassOS 并遵循上述说明。 * 或者,你可以尝试将 HassOS 同时刷入 SD 卡和 eMMC,然后从 SD 卡启动(同时 eMMC 也保持连接),然后在 Linux 提示符下运行 `dd if=/dev/mmcblk1 of=/dev/mmcblk0boot0 bs=512 skip=1 seek=0 count=16381`。注意,此方法尚未经过测试,但理论上应该可以工作。 如果在使用 dd 命令时遇到权限问题,请尝试禁用 RO: `echo 0 > /sys/block/mmcblk0boot0/force_ro` 运行 dd 后重新启用: `echo 1 > /sys/block/mmcblk0boot0/force_ro` ## Console 默认情况下,控制台访问通过串口 header 和 HDMI 提供。某些启动消息默认仅在串口控制台上显示。若要在 HDMI 控制台上显示这些消息,请交换 boot 分区上 `cmdline.txt` 文件中两个控制台的顺序。如果你不打算使用串口适配器,也可以删除 SAC2 控制台。 例如,`console=tty1 console=ttySAC2,115200` ## GPIO 请参考 [the odroid wiki](https://wiki.odroid.com/odroid-xu4/hardware/expansion_connectors)。 --- url: /developers/operating-system/boards/ova.md --- ## 支持的 Hypervisor | Hypervisor | 厂商 | 支持状态 | 配置 | |---------------------|---------|-----------------|------------------| | HyperV | Microsoft | 是,通过 VMDK | [ova](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/ova_defconfig) | | VirtualBox | Oracle | 是,通过 VMDK | [ova](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/ova_defconfig) | | VMware | VMware | 是,通过 VMDK | [ova](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/ova_defconfig) | 由于之前的 OVA 分发版本存在问题,目前我们只发布 VMDK 虚拟磁盘。我们正在研究恢复 OVA 分发版本的方案,不过,VMDK 适用于上述列出的 hypervisor。 ## 要求 在虚拟机中使用此 VMDK 需要满足以下条件: * 操作系统:Other 4.x 或更高版本的 Linux (64-bit) * 已启用 UEFI 启动支持 * SATA 磁盘控制器 * 至少 1GB RAM * 至少 2 个 vCPU * 已分配的网络 --- url: /developers/operating-system/boards/overview.md --- ## 概览 以下板卡/设备受支持: * Nabu Casa * [Home Assistant Green](https://www.home-assistant.io/green/) * [Home Assistant Yellow](https://www.home-assistant.io/yellow/)(基于自定义载板和 Raspberry Pi 4 Compute Module 驱动) * [Home Assistant Blue](https://www.home-assistant.io/blue/)(基于 ODROID-N2+) * Raspberry Pi * Pi 5([4 GB](https://www.raspberrypi.com/products/raspberry-pi-5/?variant=raspberry-pi-5-4gb) 和 [8 GB](https://www.raspberrypi.com/products/raspberry-pi-5/?variant=raspberry-pi-5-8gb) 型号)64 位 * Pi 4 Model B([1 GB](https://www.raspberrypi.com/products/raspberry-pi-4-model-b/?variant=raspberry-pi-4-model-b-1gb)、[2 GB](https://www.raspberrypi.com/products/raspberry-pi-4-model-b/?variant=raspberry-pi-4-model-b-2gb)、[4 GB](https://www.raspberrypi.com/products/raspberry-pi-4-model-b/?variant=raspberry-pi-4-model-b-4gb) 和 [8 GB](https://www.raspberrypi.com/products/raspberry-pi-4-model-b/?variant=raspberry-pi-4-model-b-8gb) 型号)64 位 * [Pi 3 Model B](https://www.raspberrypi.com/products/raspberry-pi-3-model-b/) 和 [B+](https://www.raspberrypi.com/products/raspberry-pi-3-model-b-plus/) 64 位 * Hardkernel * [ODROID-C2](https://www.hardkernel.com/shop/odroid-c2/)(已停产) * [ODROID-C4](https://www.hardkernel.com/shop/odroid-c4/) * [ODROID-M1](https://www.hardkernel.com/shop/odroid-m1/) * ODROID-M1S [4 GB](https://www.hardkernel.com/shop/odroid-m1s-with-4gbyte-ram/) 或 [8 GB](https://www.hardkernel.com/shop/odroid-m1s-with-8gbyte-ram/) * [ODROID-N2](https://www.hardkernel.com/shop/odroid-n2/)(已停产) * ODROID-N2+ [2 GB](https://www.hardkernel.com/shop/odroid-n2-with-2gbyte-ram-2/) 或 [4 GB](https://www.hardkernel.com/shop/odroid-n2-with-4gbyte-ram-2/) * [ODROID-XU4](https://www.hardkernel.com/shop/odroid-xu4-special-price/) * Asus * [Tinker Board](https://tinker-board.asus.com/product/tinker-board.html) * 通用 x86-64(UEFI,不适用于虚拟化) * [Intel NUC5CPYH](https://www.intel.com/content/www/us/en/products/sku/85254/intel-nuc-kit-nuc5cpyh/specifications.html) * [Intel NUC6CAYH](https://www.intel.com/content/www/us/en/products/sku/95062/intel-nuc-kit-nuc6cayh/specifications.html) * [Intel NUC10I3FNK2](https://www.intel.com/content/www/us/en/products/sku/195503/intel-nuc-10-performance-kit-nuc10i3fnk/specifications.html) * [Gigabyte GB-BPCE-3455](https://www.gigabyte.com/Mini-PcBarebone/GB-BPCE-3455-rev-10/sp#sp) * 支持 x86-64 架构和 UEFI 启动的计算机通常都能工作 * 虚拟设备(x86\_64/UEFI): * VMDK * OVA? * VHDX? * VDI? * QCOW2? 备注: * 关于上面的?:这些当前是否受支持?请参见 ova 文档,其中解释了之前 OVA 分发的问题。 ## 板卡详情 |板卡|构建|配置|文档| |-----|----|------|---------------------------------------| |Green |`make green` |[green](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/green_defconfig)| - | |Yellow |`make yellow` |[yellow](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/yellow_defconfig)| - | |Pi5 64-bit |`make rpi5_64` |[rpi5\_64](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/rpi5_64_defconfig)| [raspberrypi](/developers/operating-system/boards/raspberrypi.md) | |Pi4B 64-bit |`make rpi4_64` |[rpi4\_64](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/rpi4_64_defconfig)| [raspberrypi](/developers/operating-system/boards/raspberrypi.md) | |Pi4B 32-bit |`make rpi4` |[rpi4](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/rpi4_defconfig)| [raspberrypi](/developers/operating-system/boards/raspberrypi.md) | |Pi3B 64-bit |`make rpi3_64` |[rpi3\_64](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/rpi3_64_defconfig)| [raspberrypi](/developers/operating-system/boards/raspberrypi.md) | |Pi3B 32-bit |`make rpi3` |[rpi3](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/rpi3_defconfig)| [raspberrypi](/developers/operating-system/boards/raspberrypi.md) | |Pi2 |`make rpi2` |[rpi2](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/rpi2_defconfig)| [raspberrypi](/developers/operating-system/boards/raspberrypi.md) | |ODROID-C2 |`make odroid_c2` |[odroid\_c2](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/odroid_c2_defconfig)| [hardkernel](/developers/operating-system/boards/hardkernel.md) | |ODROID-C4 |`make odroid_c4` |[odroid\_c4](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/odroid_c4_defconfig)| [hardkernel](/developers/operating-system/boards/hardkernel.md) | |ODROID-M1 |`make odroid_m1` |[odroid\_m1](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/odroid_m1_defconfig)| [hardkernel](/developers/operating-system/boards/hardkernel.md) | |ODROID-M1S |`make odroid_m1s` |[odroid\_m1s](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/odroid_m1s_defconfig)| [hardkernel](/developers/operating-system/boards/hardkernel.md) | |ODROID-N2/N2+ |`make odroid_n2` |[odroid\_n2](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/odroid_n2_defconfig)| [hardkernel](/developers/operating-system/boards/hardkernel.md) | |ODROID-XU4 |`make odroid_xu4` |[odroid\_xu4](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/odroid_xu4_defconfig)| [hardkernel](/developers/operating-system/boards/hardkernel.md) | |Tinker Board |`make tinker` |[tinker](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/tinker_defconfig)| [asus](/developers/operating-system/boards/asus.md) | |Generic x86-64|`make generic_x86_64`|[generic\_x86\_64](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/generic_x86_64_defconfig)| [generic-x86-64](/developers/operating-system/boards/generic-x86-64.md) | |OVA |`make ova` |[ova](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/ova_defconfig)| [ova](/developers/operating-system/boards/ova.md) | --- url: /developers/operating-system/boards/raspberrypi.md --- ## 支持的硬件 | 设备 | 发布日期 | 支持状态 | 配置 | |--------------------|-------------|----------------|--------------------------------------| | Raspberry Pi 3 B/B+ |2016/2018 | 是 | [rpi3\_64](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/rpi3_64_defconfig) | | Raspberry Pi 4 B |2019 | 是 | [rpi4\_64](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/rpi4_64_defconfig) | | Raspberry Pi 5 |2023 | 是(beta) | [rpi5\_64](https://github.com/home-assistant/operating-system/tree/dev/buildroot-external/configs/rpi5_64_defconfig) | ## 串口控制台 要通过串口控制台访问终端,请在 `cmdline.txt` 中添加 `console=ttyAMA0,115200`,并在 `config.txt` 中添加 `enable_uart=1`、`dtoverlay=pi3-disable-bt`。GPIO 引脚为:6 = GND / 8 = UART TXD / 10 = UART RXD。 ## I2C 在 `config.txt` 中添加 `dtparam=i2c1=on` 和 `dtparam=i2c_arm=on`。之后我们通过[config usb stick][config]在主机上创建模块文件,或直接添加到 `/etc/modules-load.d`。 rpi-i2c.conf: ``` i2c-dev i2c-bcm2708 ``` ## USB 启动 Raspberry Pi 4(仅 64 位)、3B、3B+ 和 3A+ 支持 USB 大容量存储启动。 对于 Raspberry Pi 3B 和 3A+,要启用 USB 启动,请在 `config.txt` 中添加 `program_usb_boot_mode=1`。请注意,这会**永久**更改设备的单次可编程内存。 对于 Raspberry Pi 4 * 确保将 bootloader 更新为支持 USB 大容量存储启动的稳定版本(参见 [bcm2711\_bootloader\_config.md](https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711_bootloader_config.md#usbmassstorageboot))。 * 如果不使用 SD 卡,请在 `config.txt` 中的 `dtparam`(逗号分隔)中添加 `sd_poll_once=on`。这将消除 `mmc0: timeout waiting for hardware interrupt` 内核错误。 * 如果安装仍然失败,则你的 SSD 可能需要启用 quirks 才能正常工作(参见 [Finding the VID and PID of your USB SSD](https://www.raspberrypi.org/forums/viewtopic.php?t=245931))。找到适配器 ID 后,在 `cmdline.txt` 中添加 quirks 参数。 更多信息请参见 [RaspberryPi](https://www.raspberrypi.org/documentation/hardware/raspberrypi/bootmodes/msd.md)。 ### 注意事项 * 必须移除所有可启动的 SD 卡。 * USB 启动时启动时间会显著更长。这是因为启动过程首先尝试从 SD 卡启动,失败后才会回退到 USB。 * 许多 USB 驱动器根本无法用于启动。这可能是由于 uboot 中最小的驱动支持所致,且不会修复。如果无法在某个驱动器上启动,请尝试不同的品牌/型号。SanDisk Cruzer 驱动器似乎问题发生率较高。 ## 调整 如果你不需要蓝牙,可以在 `config.txt` 中添加 `dtoverlay=pi3-disable-bt` 来禁用它。 [config]: /developers/operating-system/configuration.md#automatic --- url: /developers/operating-system/configuration.md --- ## 自动 你可以使用带有 HassOS 的 USB 驱动器来配置网络选项、对主机的 SSH 访问以及安装更新。 将一个 USB 驱动器格式化为 FAT32/EXT4/NTFS,并将其命名为 `CONFIG`(全大写)。或者,你也可以在 `boot` 分区内创建一个 `CONFIG` 文件夹。在 USB 驱动器中使用以下目录结构: ```text network/ modules/ modprobe/ udev/ authorized_keys timesyncd.conf hassos-xy.raucb ``` * `network` 文件夹可以包含任何类型的 NetworkManager 连接文件。更多信息请参见 [Network][network.md]。 * `modules` 文件夹用于 modules-load 配置文件。 * `modprobe` 文件夹用于模块配置文件(/etc/modprobe.d) * `udev` 文件夹用于 udev 规则文件。 * `authorized_keys` 文件会在端口 `22222` 上启用 debug SSH 访问。请参见 [Debugging Home Assistant][debug-homeassistant]。 * `timesyncd.conf` 文件允许你设置不同的 NTP 服务器。HassOS 在缺少正确运行的时间服务器时将无法启动! * `hassos-*.raucb` 文件是将被安装的固件 OTA 更新包。这些可以在 [release][hassos-release] 页面中找到。 USB 驱动器上的文本文件必须使用 Unix(LF)换行符。如果你在 Windows 机器上创建 USB 驱动器,请务必使用 Notepad++、Visual Studio Code 或其他支持不同换行符的编辑器。在 Notepad++ 中,可以通过设置 `Edit -> EOL Conversion -> Unix (LF)` 启用 LF EOL。 你可以将这支 USB 驱动器插入设备,它将在启动时被读取,文件也会写入正确的位置。你也可以稍后通过 CLI 中的 `ha os import` 命令,或在 OS shell 上调用 `systemctl restart hassos-config` 来触发此过程。*USB 驱动器只需在此设置过程中插入设备,之后即可移除。* ## 本地 ### Bootargs 你可以在 boot 分区中编辑或创建 `cmdline.txt`。它将被 bootloader 读取。 ### Kernel-Module 内核模块文件夹 `/etc/modules-load.d` 是持久的,你可以在那里添加配置文件。请参见 [Systemd modules load][systemd-modules]。你还可以在 `/etc/modprobe.d` 中添加模块配置文件,它也是持久的。 ### Udev 规则 udev 规则文件夹 `/etc/udev/rules.d` 是持久的,你可以在那里添加配置文件。 ### 网络 你可以手动添加、编辑或删除 `/etc/NetworkManager/system-connections` 中的连接配置。 ### NTP 你可以手动编辑 `/etc/systemd/timesyncd.conf` 上的 systemd timesync 文件。 我们的默认 NTP 配置如下: ``` [Time] NTP=time.cloudflare.com FallbackNTP=0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.org ``` [systemd-modules]: https://www.freedesktop.org/software/systemd/man/modules-load.d.html [network.md]: /developers/operating-system/network.md [hassos-release]: https://github.com/home-assistant/hassos/releases/ [debug-homeassistant]: https://developers.home-assistant.io/docs/operating-system/debugging --- url: /developers/operating-system/debugging.md --- :::info 本节不适用于终端用户。终端用户应使用 \[SSH app(原 add-on)] 通过 SSH 连接 Home Assistant。本节面向 Home Assistant 的**开发者**。如果你正在使用这些选项,请不要寻求支持。 ::: [SSH app]: https://github.com/home-assistant/addons/tree/master/ssh ## 启用对主机的 SSH 访问 :::info 通过 [SSH app] 的 SSH 访问(默认为端口 22)仅提供有限的权限,输入 'login' 命令时你需要输入用户名和密码。按照以下步骤启用一个独立的 SSH 访问端口 22222,它独立于 app 工作,并为你提供对 Home Assistant OS("主机")的直接访问,具有完全权限。 ::: 1. 使用一个包含名为 `CONFIG`(区分大小写)分区的 USB 驱动器,格式化为 FAT、ext4 或 NTFS。创建一个 `authorized_keys` 文本文件(不带文件扩展名),每行一个,包含你的公钥(多个则各占一行),并将其放在 USB 驱动器 `CONFIG` 分区的根目录中。该文件必须使用 POSIX 标准的换行控制字符(LF),而不是 Windows 的(CR LF),并且需要是 ASCII 字符编码(即在注释中不得包含任何特殊字符)。 如果你需要帮助生成密钥,请参见下面的 [生成 SSH 密钥](#generating-ssh-keys) 部分。 2. 将 USB 驱动器连接到 Home Assistant OS 设备,然后通过 `ha os import` 命令明确导入驱动器内容(例如,通过 SSH 连接端口 22 上的 [SSH app]),或者在保留驱动器连接的情况下重启设备,这将自动触发导入。 :::tip 在将公钥复制到 USB 驱动器根目录时,请确保将文件正确命名为 `authorized_keys`,不带 `.pub` 文件扩展名。 ::: 你现在应该能够以 root 身份通过端口 22222 的 SSH 连接到设备。在 Mac/Linux 上使用: ```shell ssh root@homeassistant.local -p 22222 ``` 如果你的安装版本较旧或更改了主机名,可能需要相应调整上述命令。你也可以使用设备的 IP 地址代替主机名。 你将以 root 身份登录,工作目录设置为 `/root`。[Home Assistant OS] 是 Docker 的 hypervisor。请参见 [Supervisor Architecture] 文档了解关于 Supervisor 的信息。Supervisor 提供了一个 API 来管理主机和运行 Docker 容器。Home Assistant 本身以及所有安装的 addons 都在单独的 Docker 容器中运行。 [Home Assistant OS]: https://github.com/home-assistant/operating-system [Supervisor Architecture]: /architecture_index.md ## 禁用对主机的 SSH 访问 1. 使用一个包含名为 `CONFIG`(区分大小写)分区的 USB 驱动器,格式化为 FAT、ext4 或 NTFS。从该分区的根目录中移除任何现有的 `authorized_keys` 文件。 2. 当 Home Assistant OS 设备在插入该驱动器的情况下重启时,任何现有的 SSH 公钥都将被移除,端口 22222 上的 SSH 访问将被禁用。 ## 查看日志 ```shell # Host OS 上 supervisor 服务的日志 journalctl -f -u hassos-supervisor.service # Supervisor 日志 docker logs hassio_supervisor # Home Assistant 日志 docker logs homeassistant ``` ## 访问容器 bash ```shell docker exec -it homeassistant /bin/bash ``` [windows-keys]: https://docs.digitalocean.com/products/droplets/how-to/add-ssh-keys/create-with-putty/ ### 生成 SSH 密钥 关于如何使用 Putty 生成并使用私钥/公钥的 Windows 说明,请参见[这里][windows-keys]。按照上述说明添加公钥(而不是 droplet 说明)。 Mac、Windows 和 Linux 的替代说明请参见[这里](https://docs.github.com/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent)。按照 *Generating a new SSH key* 下的步骤操作(其他部分不适用于 Home Assistant,可以忽略)。 确保复制你刚刚创建的 SSH 密钥对的***公钥***。默认情况下,公钥文件名为 `id_ed25519.pub`(对于 Ed25519 椭圆曲线算法)或 `id_rsa.pub`(对于较旧的 RSA 算法),即它应该带有 `.pub` 文件名后缀。它保存在与私钥相同的文件夹中(私钥默认命名为 `id_ed25519` 或 `id_rsa`)。 --- url: /developers/operating-system/deployment.md --- Home Assistant Operating System 的发布版本从 release 分支构建。GitHub Actions 用于构建所有公开发布版本。没有固定的时间表,构建由 HAOS 维护者按需触发。更改需要先应用到开发分支,并标记 `rel-x` 标签。维护者将在下一次发布前将这些补丁 backport 到 release 分支。 ## 分支 * `dev`:开发分支。在开发过程中承载下一个主要版本。在 release candidate 阶段,release candidate 会在此分支上打标签。 * `rel-X`:发布分支。每个主要版本一个。通常新的发布版本只从最后一个主要版本号构建。每个版本都会打上一个版本号标签。 ## 版本控制 版本的格式为 *MAJOR.BUILD*。每次发布新 release,BUILD 编号都会递增(存储在 `buildroot-external/meta` 中)。MAJOR 编号继承自开发分支,并在创建 release 分支后立即递增。 构建系统默认会自动添加一个 *dev{DATE}* 后缀来标记开发构建。 在新主要版本发布之前,可以在开发分支上构建 release candidate。使用 release candidate 后缀来标记它们,例如 *MAJOR.0.rc1*。 ## 部署类型 HAOS 提供 3 种不同类型的部署。不同部署之间的区别在于它们为 over the air 更新包含了哪些公钥。部署类型显示在 Supervisor web 前端的 System 选项卡中的 Host 卡片上。 * development(dev) * staging(beta) * production(stable) ## 构建流水线 GitHub Actions 用于构建 HAOS 的开发版本和发布版本。存在两个 workflow: * `.github/workflows/dev.yml`:开发构建,手动触发,镜像存储在 [os-builds.home-assistant.io](https://os-builds.home-assistant.io/)。 * `.github/workflows/release.yml`:发布(和 release candidate)构建,在 GitHub release 发布时触发,镜像作为 GitHub release asset 存储。 开发构建流水线也可以从 PR 触发:首先需要设置相应的板卡标签,然后在添加 `run-dev-build` 标签时会为这些板卡触发构建。 --- url: /developers/operating-system/getting-started.md --- ## 准备开发环境 ### 检出源代码 主仓库位于 [github.com/home-assistant/operating-system/](https://github.com/home-assistant/operating-system/),它通过 [br2-external 机制](https://buildroot.org/downloads/manual/manual.html#outside-br-custom) 包含 Buildroot 定制内容,以及辅助脚本和 GitHub Action CI 脚本。主仓库使用 Git Submodule 机制指向 Buildroot 本身。虽然大多数定制可以通过 br2 机制完成,但仍有一些修改直接作用于 Buildroot 本身。出于这个原因,我们还在 [github.com/home-assistant/buildroot/](https://github.com/home-assistant/buildroot/) 下维护一个 Buildroot 的 fork。我们的目标是尽量将基于上游 Buildroot 的补丁数量保持在最低水平。 确保你已经安装了 `git`,并按如下方式克隆 HAOS 主仓库: ```shell git clone https://github.com/home-assistant/operating-system/ cd operating-system/ git submodule update --init ``` 当你更新本地 git 仓库时,务必同时更新 `buildroot` 子模块。这样可以确保在 Buildroot 本身也更新时,你能获取与之匹配的版本。 ```shell git pull git submodule update ``` 要恢复到初始洁净状态,请使用以下两条命令(这会删除所有本地修改!) ```shell git reset --hard git submodule update --init --force ``` ### 安装依赖 HAOS 使用构建容器来运行 Buildroot。安装 Docker 容器引擎,并确保你有一个可用的 `docker` 命令,允许运行 privileged 容器。构建脚本设计为由普通用户运行,但部分命令会使用特权,因此也需要一个可用的 `sudo` 命令。 虽然 Buildroot 可以直接运行在大多数 Linux 发行版上,但强烈建议使用基于 Debian 的构建容器。这样可以获得一个稳定且已知的构建环境,所有依赖均已预装。 :::info 构建容器必须以特权模式启动,因为在构建过程的某个阶段需要在 Docker 容器内挂载一个由 loopback 设备支持的新的文件系统镜像。因此,rootless 容器无法用于构建 HAOS。 ::: ## 使用构建容器构建镜像 脚本 `scripts/enter.sh` 会构建构建容器镜像,并使用该镜像启动一个容器。传递给脚本的参数将在容器内部执行。 HAOS 为每个受支持的目标使用一个配置文件。要为特定目标(板卡)构建,需要将配置文件传递给 `make`。配置文件存放在 `buildroot-external/configs/` 中。注意,后缀 `_defconfig` 会自动追加,并且*绝不能*传递给 `make`。例如,要构建 Raspberry Pi 4 64 位配置 `buildroot-external/configs/rpi4_64_defconfig`,请使用以下命令: ``` $ scripts/enter.sh make rpi4_64 [sudo] password for whoever: [+] Building 32.5s (10/10) FINISHED [...] === Using rpi4_64_defconfig === /usr/bin/make -C /build/buildroot O=/build/output BR2_EXTERNAL=/build/buildroot-external "rpi4_64_defconfig" [...] === Building rpi4_64 === [...] ``` 这会在容器内的源代码仓库根目录中使用 `Makefile` 调用 make。这个 makefile 进而会调用 Buildroot 的 makefile。 根据你的机器速度,构建过程需要 0.5 到 1 小时。构建文件(目标文件、中间二进制文件等)存储在 `output/` 文件夹中。最终的镜像文件存放在 `output/images/` 目录中。 ### 重新构建包 Buildroot 像常规发行版一样使用包。但 Buildroot 包不是简单地下一个预构建的包,而是下载源文件并直接编译二进制文件。Buildroot 会记住哪些包已经构建过。这使得第二次构建快得多,因为只有最终镜像会被重新生成。如果你想强制 Buildroot 重新构建某个特定包,只需从 `output/build/` 目录中删除它: ```shell rm -rf output/build/linux-custom/ ``` :::tip 你可以查看 `output/build/packages-file-list.txt` 来了解最终镜像中的文件分别属于哪个包。这样更容易找到你想要更改的包。 ::: ### 为多个目标构建 要在同一个源代码目录中为多个目标构建,必须使用不同的输出目录。输出目录可以通过 `O=` 参数指定。推荐的做法是直接使用与目标配置文件同名的输出目录: ```shell scripts/enter.sh make O=output_rpi4_64 rpi4_64 ``` ### 交互方式使用构建容器 如果不向 `scripts/enter.sh` 传递任何参数,就会呈现一个 shell。 ```bash $ scripts/enter.sh [...] builder@d3d7577663c9:/build$ ``` 从该 shell 中,可以使用 `make O=output_rpi4_64 rpi4_64` 启动上述相同的构建。 这样可以调用其他 Buildroot 目标,例如,[绘制包之间的依赖关系图](https://buildroot.org/downloads/manual/manual.html#_graphing_the_dependencies_between_packages)。要使用其他 Buildroot 目标,请确保切换到 `buildroot/` 目录并从那里执行命令 ```bash builder@c6dfb4cd4036:/build$ cd buildroot/ builder@c6dfb4cd4036:/build$ make O=../output_rpi4_64 graph-depends Getting dependency tree... dot -Tpdf \ -o /build/output_rpi4/graphs/graph-depends.pdf \ /build/output_rpi4/graphs/graph-depends.dot builder@c6dfb4cd4036:/build$ ``` ## 使用 Qemu 测试镜像 目标 OVA(Open Virtual Appliance)包含适用于各种虚拟机的镜像。其中一种镜像格式是 QCOW2,即 QEMU 的原生镜像格式。它可以用来通过 QEMU 测试新的 HAOS 构建。 由于 HAOS 需要 UEFI 支持,这比基于"经典"/传统 MBR 的镜像稍微复杂一些。在 *Debian* 主机上安装 [ovmf 包](https://packages.debian.org/stable/ovmf),它提供"64 位 x86 虚拟机的 UEFI 固件"。该包将在 `/usr/share/OVMF/OVMF_CODE.fd` 安装一个派生自 **TianoCore** 的 QEMU UEFI 镜像,可用于在 QEMU 中启动生成的 QCOW2 镜像。 ```bash $ scripts/enter.sh make O=output_ova ova [...] $ unxz output_ova/images/haos_ova-7.0.dev20211003.qcow2.xz $ qemu-system-x86_64 -enable-kvm -name haos -smp 2 -m 2G -drive file=output_ova/images/haos_ova-18.0.dev0.qcow2,index=0,media=disk,if=virtio,format=qcow2 -drive file=/usr/share/ovmf/x64/OVMF_CODE.fd,if=pflash,format=raw,readonly=on ``` 这会显示 QEMU 的 SDL 界面,并应启动 Home Assistant Operating System。启动完成并显示 Home Assistant CLI 提示符 `ha > ` 后,你可以使用 `login` 访问 root shell。 ## 创建 pull request 以供审核 当你对自己的修改满意后,创建一个单独的 git 分支并提交。尽量描述你认为这项更改*为什么*重要,以及*为什么*应该应用到 HAOS。例如,"更新内核"从更改本身来看也很明显。维护者更感兴趣的是你为什么认为内核需要更新。这个*为什么*可以非常简单(更新内核以确保我们跟上最新的更改),也可以包含一些有趣的细节(更新内核,因为最新版本修复了 xy 板上的以太网问题)。 fork 上游 [github.com/home-assistant/operating-system](https://github.com/home-assistant/operating-system) 仓库(如果你还没有的话),将你的分支推送到你的 forked GitHub 仓库中。然后打开一个新的 pull request。所有更改都应针对开发分支 `dev` 进行。如果你的更改希望出现在下一个稳定版本中,请添加 `rel-x` 标签,以便将其标记为待 backport。 --- url: /developers/operating-system/network.md --- Home Assistant Operating System 使用 NetworkManager 来控制主机网络。 ## 配置网络 默认情况下,设备将处于 DHCP 状态。 基本网络设置可以通过 Supervisor 前端在 System 选项卡中设置。VLAN 等附加设置也可以通过 `ha network` CLI 命令配置。 要恢复默认配置,也可以使用 `ha network` CLI 命令: ``` ha network update default --ipv4-method auto ``` 对于前端或 CLI 不支持的网络设置,底层 NetworkManager 的连接配置可以放在 USB 驱动器上,并按照 [Configuration][configuration-usb] 中的描述导入到主机。 ## 手动网络配置 如果前端或 `ha network` CLI 无法满足你的用例,仍然可以手动配置底层的 NetworkManager。 你可以阅读 [NetworkManager manual][nm-manual],或者在网上找到许多配置示例。注意,目前不支持对 `NetworkManager.conf` 的更改,仅支持连接 keyfiles。请记住系统是只读的。如果你不希望 IP 地址在每次启动时都发生变化,应该将 UUID 属性修改为通用的 [UUID4][uuid]。在 USB 驱动器或 SD 卡的 `\CONFIG\network\` 目录中,创建一个名为 `my-network` 的文件,并添加以下适当内容: **注意:请确保将此文件以 UNIX 行尾(LF,而不是 Windows 默认的 CRLF)保存。你可以使用 Notepad 来完成!** ### 默认 有线网络的预装连接配置文件默认为活动状态: ```ini [connection] id=Home Assistant OS default uuid=f62bf7c2-e565-49ff-bbfc-a4cf791e6add type=802-3-ethernet llmnr=2 mdns=2 [ipv4] method=auto [ipv6] addr-gen-mode=stable-privacy method=auto ``` ### 有线连接至 LAN ```ini [connection] id=my-network uuid=d55162b4-6152-4310-9312-8f4c54d86afa type=802-3-ethernet llmnr=2 mdns=2 [ipv4] method=auto [ipv6] addr-gen-mode=stable-privacy method=auto ``` ### 无线 LAN WPA/PSK ```ini [connection] id=my-network uuid=72111c67-4a5d-4d5c-925e-f8ee26efb3c3 type=802-11-wireless [802-11-wireless] mode=infrastructure ssid=MY_SSID # 如果你的 SSID 未广播,请取消下方注释 #hidden=true [802-11-wireless-security] auth-alg=open key-mgmt=wpa-psk psk=MY_WLAN_SECRET_KEY [ipv4] method=auto [ipv6] addr-gen-mode=stable-privacy method=auto ``` ### 静态 IP 替换以下配置: ```ini [ipv4] method=manual address=192.168.1.111/24;192.168.1.1 dns=8.8.8.8;8.8.4.4; ``` 对于 `address`,分号前面的值就是 IP 地址和子网前缀长度。第二个值(分号后面)是本地网关的 IP 地址。 ## 提示 ### 重置网络 如果你希望将网络配置重置回使用 DHCP 的默认连接配置文件,请在主机控制台上使用以下命令: ```bash # rm -r /mnt/overlay/etc/NetworkManager/system-connections # reboot ``` Home Assistant OS 将在启动过程中重新创建默认连接配置文件。 ### 启用 Wi-Fi 出于可靠性考虑,不建议使用 Wi-Fi。但如果你仍希望使用 Wi-Fi,可以使用 `ha network` 命令来设置 Wi-Fi(以 Raspberry Pi 4 为例,使用 `ha network info` 检查你的板卡是否支持 Wi-Fi 以及 Wi-Fi 设备的名称): ```bash ha network update wlan0 --ipv4-method auto --wifi-auth wpa-psk --wifi-mode infrastructure --wifi-ssid "MY-SSID" --wifi-psk MY_PASS ``` ### 节能 如果 powersave 出现问题的话,应用以下更改: ```ini [wifi] # Values are 0 (use default), 1 (ignore/don't touch), 2 (disable) or 3 (enable). powersave=0 ``` ## 使用 `nmcli` 设置静态 IPv4 地址 通过控制台登录 Home Assistant OS 基础系统: ```bash Welcome to Home Assistant homeassistant login: ``` * 以 `root` 身份登录(无需密码)。在 `ha >` 提示符下,输入 `login`(按照指示)。 从那里你可以使用 `nmcli` 配置工具。 * `# nmcli con show` 将列出正在使用的"Home Assistant OS default"连接。 * `# nmcli con show "Home Assistant OS default"` 将列出该连接的所有属性。 要开始编辑"Home Assistant OS default"的配置设置: ```bash # nmcli con edit "Home Assistant OS default" ``` 添加你的静态 IP 地址(对 manual method 选择 'yes'): ```bash nmcli> set ipv4.addresses 192.168.100.10/24 Do you also want to set 'ipv4.method' to 'manual'? [yes]: ``` 此外,建议设置 DNS 服务器和本地网关。对于大多数家用路由器,DNS 服务器的 IP 地址与路由器本身相同。如果你使用的是 Pi-Hole 或第三方 DNS 系统,则可以将 DNS 服务器设置为其。 ```bash nmcli> set ipv4.dns 192.168.100.1 nmcli> set ipv4.gateway 192.168.100.1 ``` `nmcli> print ipv4` 将显示此连接的 IPv4 属性。通过 `nmcli> save` 你可以保存更改。 如果你现在查看默认连接 `cat /etc/NetworkManager/system-connections/default`,你应该看到 method 是 manual 且 address 已设置。 执行 `nmcli con reload` 并不总是有效,因此请重启虚拟机或物理系统。 [nm-manual]: https://networkmanager.dev/docs/api/1.40/manpages.html [configuration-usb]: /developers/operating-system/configuration.md [uuid]: https://www.uuidgenerator.net/version4 --- url: /developers/operating-system/partition.md --- Home Assistant Operating System(HAOS)的分区布局与 Linux 系统上通常使用的布局略有不同。 ## 分区表 HAOS 在可能的情况下优先使用 GPT(GUID Partition Table)。某些 SoC 的 Boot ROM 不支持 GPT,在这种情况下,如果可能则使用 hybrid GPT/MBR,否则使用传统 MBR(另请参见 [Metadata](/developers/operating-system/board-metadata.md) 文档)。 ## 分区 ```text ------------------------- | Boot | ------------------------- | Kernel A | ------------------------- | System A | | | ------------------------- | Kernel B | ------------------------- | System B | | | ------------------------- | Bootstate | ------------------------- | Overlay | | | ... ------------------------- | Data | | | | | ------------------------- ``` ### 系统分区 boot 分区通常是 FAT 分区,包含启用启动所需的系统特定内容。在 UEFI 系统上,这是包含 GRUB 二进制文件、配置及其环境文件的 EFI 系统分区。 接下来存储两个版本的 Linux 内核和主操作系统(Kernel A/B 和 System A/B,共 4 个分区)。这允许系统在新版本启动失败时回退到上一个版本(A/B 更新方法)。系统分区仅在更新期间写入,在常规操作下是只读的。 overlay 分区用于存储某些操作系统级别的设置(例如网络设置)。使用文件系统标签 `hassos-overlay` 来查找并挂载此分区。 ### 数据分区 数据分区是主分区,包含所有容器(Supervisor/Core/Plug-Ins 和 apps(原 add-ons))以及用户数据。它的 I/O 操作远远多于其他分区,因此如果在快速存储上挂载(例如通过 data disk 功能)受益最大。它被挂载到 `/mnt/data`,部分子目录被 bind mount 到其他位置(如 `/var/lib/docker`)。使用文件系统标签 `hassos-data` 来查找并挂载此分区。 在新安装中,数据分区包含 Supervisor 及其 Plug-Ins 的最新版本(构建时的版本)。没有预装 Home Assistant Core,而是一个较小的 landing page。Supervisor 会在首次启动时下载 Home Assistant Core 的最新版本。这确保了用户在首次启动 HAOS 后以最新版本的 Home Assistant Core 开始使用。 data disk 功能利用了 HAOS 使用 `hassos-data` 标签这一事实:该功能通过分区磁盘并创建一个标签为 `hassos-data-external` 的文件系统来准备磁盘。重启时,文件系统工具 `dumpe2fs` 被用来将现有 `hassos-data` 分区中的所有数据移动到新的分区。最后,将现有数据分区的文件系统标签更改为 `hassos-data-old`(以避免再次被挂载),并将 data disk 上的新数据分区标签更改为 `hassos-data`。 --- url: /developers/operating-system/update-system.md --- Home Assistant Operating System 使用 [RAUC](https://rauc.io/) 作为更新系统。RAUC 是一个面向嵌入式系统的基于镜像的更新系统。它支持多个 boot slot,因此支持 A/B 样式的更新机制。更新系统集成了诸如 U-Boot 等流行的 bootloader,但也允许通过脚本与自定义启动流程集成。它使用 X.509 密码学来签名和验证更新包。 ## RAUC 与 Home Assistant OS RAUC 可以直接从 Buildroot 获取。HAOS 构建系统会创建更新包(`.raucb` 文件),它们与初始安装所用的磁盘镜像文件一起上传。RAUC 更新包本质上包含内核和系统分区以及 boot 分区,对于某些板卡还包括一个名为 `SPL` 的 boot 镜像。相同的分区镜像用于生成磁盘镜像和更新包。所有板卡都使用从 `buildroot-external/ota/manifest.raucm.gtpl` 处的模板文件生成的类似 RAUC manifest。该 manifest 定义了更新包的确切内容。 RAUC 在 [rauc.readthedocs.io](https://rauc.readthedocs.io/) 上拥有优秀的文档,本指南主要关注 RAUC 的实用方面以及 HAOS 特有的内容。 ## 使用更新包 RAUC 在 HAOS 上作为 systemd 系统服务运行。系统服务暴露了一个 D-Bus API。Supervisor 利用这个 D-Bus API 来发起更新。更新包本身由 Supervisor 下载并传递给 RAUC。从 RAUC 系统服务的角度来看,更新只是一个简单的本地更新安装。 出于开发或测试目的,RAUC 更新包可以通过 shell 上的 `rauc install` 命令安装。例如,手动更新特定板卡可以直接在 HAOS shell 中运行以下命令完成: ```sh # cd /mnt/data/ # curl -L -O https://github.com/home-assistant/operating-system/releases/download/11.5.rc3/haos_rpi5-64-11.5.rc3.raucb # rauc install haos_rpi5-64-11.5.rc3.raucb # systemctl reboot ``` :::note 在 Raspberry Pi 5 上使用 `tryboot` 机制时,务必使用 `systemctl reboot`,因为普通的 `reboot` 不会触发从另一个 slot 启动。或者,需要显式使用 `reboot '0 tryboot'`。 ::: 重启后,系统应运行新安装的 HAOS 版本。 ## 启动槽位 HAOS 有两个 boot slot,分别命名为 A 和 B。新安装总是从单个 boot slot(Slot A)开始部署。更新时,会写入另一个 boot slot,系统随后重启进入另一个 boot slot。因此,新安装系统上的第一次更新将安装到 boot slot B 中。Supervisor 使用 `ha os info` 显示 boot slot,在 OS shell 上可以使用 `rauc status` 命令来查看两个 boot slot 的完整状态。 ```sh # rauc status === System Info === Compatible: haos-rpi5-64 Variant: Booted from: kernel.0 (A) === Bootloader === Activated: kernel.0 (A) === Slot States === [spl.0] (/dev/disk/by-partlabel/hassos-boot, raw, inactive) [boot.0] (/dev/disk/by-partlabel/hassos-boot, vfat, inactive) x [kernel.0] (/dev/disk/by-partlabel/hassos-kernel0, raw, booted) bootname: A boot status: good [rootfs.0] (/dev/disk/by-partlabel/hassos-system0, raw, active) o [kernel.1] (/dev/disk/by-partlabel/hassos-kernel1, raw, inactive) bootname: B boot status: good [rootfs.1] (/dev/disk/by-partlabel/hassos-system1, raw, inactive) ``` 更新后,RAUC 会指示 bootloader 启动到另一个 slot(例如,通过使用 U-Boot 环境变量写入)。如果启动成功,该 slot 将被标记为 good,系统将继续启动到该 boot slot。通常,每个 boot slot 在回退到另一个 boot slot 之前会尝试三次,但具体逻辑取决于 bootloader 的集成方式。 可以使用 `ha os boot-slot` 命令更改 boot slot。在使用 GRUB bootloader 的系统上,也可以使用启动菜单。在这种情况下,所选的 boot slot 将被用于未来的启动,直到再次手动或通过 OS 更新进行更改。 ## 安全 HAOS RAUC 更新包是经过签名的。HAOS 拥有自己的 PKI,包含 development 和 release 的 CA。目前,所有公开发布版本都使用 release CA 进行签名。证书预装在 OS 的 `/etc/rauc/keyring.pem` 中。 在本地构建时,第一次使用构建目录时会生成一个自签名证书。证书及其关联的私钥存储在构建目录的根目录中,分别为 `key.pem` 和 `cert.pem`(另请参见 `buildroot-external/scripts/rauc.sh`)。从那时起,每次构建都使用相同的自签名证书。这个自签名证书也会被自动添加到 HAOS 镜像本身的 keyring 中。这意味着从本地构建的镜像安装的 HAOS 可以处理来自同一构建目录的更新包。 ### 更新到开发构建 将现有的官方安装更新到本地的自签名构建会因签名验证错误而失败: ```sh # rauc install haos_rpi5-64-11.6.dev0.raucb installing 0% Installing 0% Determining slot states 20% Determining slot states done. 20% Checking bundle 20% Verifying signature 40% Verifying signature failed. 40% Checking bundle failed. 100% Installing failed. LastError: signature verification failed: Verify error:self signed certificate Installing `/mnt/data/haos_rpi5-64-11.6.dev0.raucb` failed ``` 然而,Home Assistant Operating System 不是一个锁定平台。它使用默认 keyring 来验证传入的更新。使用 root 访问 OS shell,向 keychain 中添加另一个 keyring(可以是单个自签名证书)是相当简单的,因此可以更新到自签名的 OS 构建: ```sh # cp -r /etc/rauc/ /tmp/rauc # cat /mnt/data/cert.pem >> /tmp/rauc/keyring.pem # mount -o bind /tmp/rauc/ /etc/rauc/ # systemctl restart rauc ``` 有了这个更改,就可以安装本地构建。从本地构建的 OS 安装官方更新仍然是可能的,因为自签名证书被追加到了 keychain 中。这意味着即使是本地构建,官方 release 证书仍然被接受。这允许从本地开发构建更新到官方 release。 --- url: /developers/review-process.md --- Home Assistant 项目由许多较小的子项目组成,分布在多个 GitHub repositories 中,它们共同构成了我们所熟知和喜爱的 Home Assistant。 我们通过 GitHub Pull Requests 收到了大量的贡献,这真是太棒了。我们对此深表感激。本页描述了我们的 review process,以便你在提交 PR 时了解会发生什么。 本页提供了关于创建 pull requests 以及如何处理它们的通用提示和指南。它并非创建 PR 的完整指南;不过,本页中的大多数内容同样适用于向任何开源项目贡献。 ## 谁负责 review PR? Home Assistant 是一个开源项目。我们项目中发生的一切几乎都是志愿者完成的。我们有一个 core team 的开发者,负责 Home Assistant 的整体架构,他们负责合并 PR(同样是志愿者)。不过,他们并不是唯一 review PR 的人。 任何人都可以帮忙 review PR,我们鼓励大家这么做。 因此,当你打开一个 PR 后,请考虑查看是否有可以帮忙处理的 open PR。任何 review 评论、改进建议,甚至只是“我用……测试过,可以工作”,都是非常受欢迎的。此外,查看他人的代码也是学习更多关于 Home Assistant 知识的绝佳方式。 ## 创建 PR 之前 **遵守架构决策。** 所有与 Home Assistant 项目相关的架构决策都记录在 [ADR folder](https://github.com/home-assistant/architecture/tree/master/adr) 中。在创建 PR 之前,请确保遵循这些规则和指南,以避免因 PR 未遵循这些规则而需要后续调整。如有必要,可以在提交 PR 进行 review 之前发起新的 [discussion](https://github.com/home-assistant/architecture/discussions),以做出必要的决策。 ## 创建完美的 PR 不存在完美的 PR,但有些事情可以让你的 PR 更容易被 review。这不仅有助于 reviewers,也作为贡献者可以帮助你更快地合并更改,让最终用户更早地使用上你的改进。 1. **让 PR 尽可能小。** 一个 PR 应该只 refactor 一件事、修复一件事、添加一个功能,或在文档中调整一个主题。如果你想改多件事,请创建多个 PR。更小的 PR 范围更小、需要更少 review 时间、更少发生冲突,并且通常需要的 review 轮次也更少。 2. **一次只改一件事。** 这与前面一点相同,但更具体。你可能很想顺便改进附近你注意到的那一两行代码,但请不要这么做。把它们放到单独的 PR 中。PR 中的无关更改会让人分心,并且常常引发疑问。相反,在一个独立的 PR 中,这会是一个快速而简单的 review 和合并。 3. **在创建 PR 之前先测试你的更改**。 这听起来显而易见,但我们经常看到包含根本无法运行的代码的 PR,或者在生成的页面上看不到的文档更改。当然,这对你和 reviewer 都是一种精力浪费;它增加了一次不必要的 review 轮次。请确保至少运行并物理测试你的更改。确保它们按预期工作(对于文档:按预期呈现)。 4. **确保 PR 基于 dev upstream branch 的最新版本。** 在创建 PR 之前,确保拉取了最新的 upstream 更改。在你编写更改的过程中,upstream 可能已经发生了变化。这可能导致 merge 冲突、测试失败,或你的更改无法按预期工作。 5. **创建 (feature) branch。** 当你创建 PR 时,它基于一个 branch(通常是 dev branch)。你必须为每一个创建的 PR 新建一个 feature branch。这有助于保持 dev branch 与 upstream branch 同步,也便于在 PR 合并后删除该 branch。 6. **遵循 PR template 并添加清晰的 title 和详尽的 description。** 当你打开 PR 时,会提供一个 PR template。使用 template 并尽可能多地填写字段。花时间写一个良好、清晰且简洁的 title,并添加对更改的详尽 description。务必为你的 PR 添加一个 motivation(或使用场景),以便 reviewer 理解你为什么要做这项更改(或为什么做出某些决策)。 7. **在独立 PR 中更新依赖。** 当你需要 bump 一个依赖时,尽量在独立 PR 中完成。PR 中只应包含兼容性代码调整或小型相关的 bug fixes。如果你有依赖新依赖的新功能,可以在后续 PR 中添加。在 review 新功能或较大的 bug fixes 时,这也将使 CI 迭代运行得快得多,因为它将测试限制在单个 integration 上。请确保 PR description 中至少包含以下一项(或多项): * 指向该包版本的 release notes 的链接,以及其间所有版本的链接。 * 指向该包 changelog 的链接。 * 指向从当前版本到 bump 后版本的 Git(Hub) diff/compare 视图的链接。 这使我们能够 review upstream 的更改,这是决定该更改是否按预期工作以及/或者是否可以将其包含在例如 Home Assistant 的 patch release 中所必需的。 ## 接收 review comments 当你的 PR 打开后,总会有人在某个时刻查看你的代码。Reviewer 可能会对你的代码提出一些 comments,甚至提出更改请求。 **请务必牢记,这些 review comments 并非针对个人。** Reviewer 并不是想要侮辱你或让你感觉不好。他们是在帮助你改进 PR,以便其能够被合并。和你一样,他们也是志愿者,并且都在努力让 Home Assistant 变得更好。我们的目标是一样的。 无论你的经验多么丰富,总是可以从他人身上学到东西,所以不要反感,欣然接受。不要害怕提问,或要求澄清。如果你不理解某些内容,尽管问! ## 需要更改时 PR 会被设为 draft 如果你的 PR 收到了更改请求,我们的 bot 会自动将你的 PR 标记为 draft。这意味着该 PR 目前尚不能合并或进一步 review。 Draft PR 会告诉其他查看所有 PR 列表的 reviewers,该 PR 目前正在进行中,暂时不需要他们的关注。 一旦你完成了所请求的更改,可以通过点击 "Ready for review button" 将 PR 重新标记为 ready for review: ![The ready for review button in the bottom of a PR in draft mode](/img/en/blog/2023-02-07-introducing-PR-drafting-in-reviews/ready-for-review.png) 在点击 "Ready for review" 按钮之前,请确保你已经处理了所有请求的更改,并且我们所有的 CI jobs 和 checks 都成功通过。 一旦点击了 "Ready for review" 按钮,PR 将恢复到正常状态,我们的 bot 会自动通知那些提出更改请求的 reviewers,PR 已准备好! ## 加快 review process 1. **Build/CI 失败?将 PR 设为 draft!** 打开了 PR,但 build 失败了?别担心,这种事我们都会遇到。如果你确信失败与你的更改无关,你可以让 PR 保持打开。不过,如果失败与你的更改有关,你应该在解决期间将 PR 标记为 draft。这样可以防止 reviewers 在 PR 准备好之前查看它。 ![Putting a PR in draft is something you can do too](/img/en/blog/2023-02-07-introducing-PR-drafting-in-reviews/convert-to-draft.png) 2. **监控你的 PR 并使其保持最新。** 即使你的 PR 尚未被 review,你也应该主动监控它。确保没有引入 merge 冲突(GitHub 会在发生这种情况时提醒你),并在经过一周不活动后[用最新的 development branch 更新它](/developers/development_catching_up.md)。这确保了在 review process 开始时,你的 PR 已经准备就绪。 3. **添加 tests。** 如果你正在添加新功能,请确保添加 tests。如果你正在修复一个 bug,请确保添加一个能够捕获该 bug 的 test。如果你正在 refactor 代码,请添加 tests 以确保你的 refactor 没有破坏任何东西。Tests 有助于证明你的代码按预期工作,但更重要的是,它确保一切在未来也能持续正常工作。虽然 tests 增加了需要 review 的代码量,但它也帮助 reviewers 以不同的方式理解你所解决的问题。 4. **回顾、调整,并精雕细琢至完美。** 有时,稍后回头看看自己的代码会教会你新的东西,并帮助你自行发现不完美或问题。在等待 review 时,正是确保你的 PR 尽可能好的完美时机。 5. **帮忙 review 队列。** 帮助加快 review process 的最佳方式是参与 review process!你所接手的任何 review 工作都有助于加快所有人的 review process。此外,其他人可能会注意到你的 review,并回报你。 ## 不要做的事 * 不要直接联系 contributors、code owners、core team members 或其他 reviewers 关于某个 PR,或在 PR 中 ping/mention 他们来请求 review。虽然你可能是出于友好,但这可能会被看作是令人烦恼或强人所难。相反,我们的 bots 会处理 ping 正确的人员:请保持一点耐心 :) * 不要在 PR description 中请求 review。这是多余的,因为 PR 本身已经表明了这个意图 😉。如果有需要,我们的 bots 会通知相关人员;请避免自己这么做。 * 不要提交依赖于其他仍处于 open/unmerged 状态的 PR 的新的 pull requests。这会在队列中创建不必要的、无法操作的 PR。 * 不要打开超过 5 个 pull requests。如果你有超过 5 个 open PR,我们会要求你关闭其中一些,直到其他一些被合并。类似于依赖性的 pull requests,请等待一个 PR 被批准后,再将这种方法应用到多个 PR。 * 如果你不打算继续工作,就不要打开 PR。如果你在打开 PR 后无法继续工作,请告诉我们并关闭它。关闭 PR 并不可耻;不过,如果是卡住了,请随时在我们的 [#devs channel in our Discord chat](https://www.home-assistant.io/join-chat) 中寻求帮助。 ## 我的 PR 已经合并了! 恭喜! **最重要的是:非常感谢!❤️** 你刚刚让 Home Assistant 变得更好。你帮助我们改进了代码、文档、tests、用户体验,或社区。你帮助我们让 Home Assistant 对所有人来说都更好。 保持势头!随意打开另一个 PR,或帮忙 review 其他 PR。 如果这是你的第一个 PR,别担心,我们保证,每次经历这个过程都会变得更轻松。 ## 常见问题 1. **如何让我的 PR 被合并?** 不能保证你的 PR 一定会被合并。我们有很多 contributors,我们必须确保不会破坏任何东西。我们会尽快 review 你的 PR,但请保持耐心。如果你想加快流程,请阅读上面关于如何加快 review process 的章节。 2. **我的 PR 已经等待 review 好几天了,什么时候会被 review?** 视 repository 而定,可能需要一段时间你的 PR 才会被 review。这取决于很多因素。例如,修复 bug、改进代码质量、较小或提供 tests 的 PR(以及这些的组合)通常优先于添加新功能的 PR。PR 的规模和复杂度也是一个因素,因为它意味着更少的人愿意或有能力接手你的 PR。你总是可以考虑将 PR 变得更小、更专注,以加快 review process。还有一些 PR 可能需要或需要具有特定知识的人来 review(例如架构更改或需要 code owner 批准的更改),这可能会导致更长的等待时间。 3. **这么多小的 PR 不是超级低效吗?** 这是一个常见的误解。虽然 review 大量小 PR 看起来像是很多工作,但实际上它更高效。小 PR 更容易被更多人 review,这意味着更多人可以加入帮忙 review。它们可以在更短的时间内被快速接手,并且更不容易与其他 PR 冲突。一般来说,review 较小的 PR 会得到更好的 review,并且不太可能引入新的 bug,因为在大型 PR 中更容易忽略某些东西。 4. **Bot 说我的 PR 即将 stale,这是什么意思?** Bot 会在一段时间不活动后自动将 PR 标记为 stale。如果 PR 继续保持不活动,bot 会关闭它。这可能意味着 PR 正在等待你的更改,或者等待我们项目的 review。请确保前一种情况不是事实;如果你是在等待 review,只需留言说明。通过回复 bot,它会知道情况并非 stale,从而不再行动。同时,[用最新的 development branch 更新它](/developers/development_catching_up.md) 是个好主意,以确保你完全同步了最近的更改。 5. **我有一个应该进入 hotfix/patch release 的 PR,该怎么做?** 像平常一样创建 PR,并在 PR description 中非常明确地说明该 PR 是一个需要包含在 patch release 中的 hotfix。Reviewer 随后会进行双重检查,并通过给 PR 打上下一个 patch milestone 标签来确保它被包含在下一次 patch release 中。 ## 仓库特定信息 我们的一些 repositories 有特定的要求或指南,这些是在本通用指南之上的额外要求。 ### Home Assistant 核心 [Home Assistant Core](https://github.com/home-assistant/core) repository 有许多要求和指南,以确保代码质量。在创建对 Core repository 的贡献时,以下 developer documentation 页面可能会有所帮助: * [Development checklist](/developers/development_checklist.md) * [Development checklist for integrations](/developers/creating_component_code_review.md) * [Submitting your work](/developers/development_submitting.md) * [Style guidelines](/developers/development_guidelines.md) * [Testing your code](/developers/development_testing.md) * [Catching up with reality](/developers/development_catching_up.md) * [Tips and Tricks](/developers/development_tips.md) ### Home Assistant 文档 要了解贡献文档的相关信息,请参阅 [Contributing to documentation](/developers/documenting.md)。 ### Home Assistant 前端 [Home Assistant Frontend](https://github.com/home-assistant/frontend) 在 [Frontend development page](/developers/frontend/development.md#creating-pull-requests) 上提供了开发和贡献 frontend 的指引。 ### Home Assistant 意图 构建 voice assistant 是一项复杂的任务。它需要多种不同的技术协同工作,因此有一些指南可以参考: * [Contributing template sentences](/developers/voice/intent-recognition/contributing.md) * [Response Style Guide](/developers/voice/intent-recognition/style-guide.md) ## 帮助?!我还有更多问题! Developer documentation 中有很多信息,甚至更多关于贡献和 pull requests 的信息,因此请务必使用页面右上角的搜索功能来查找你需要的内容。 不过,你可能仍然卡住,或者有一个文档中没有回答的问题。在这种情况下,请随时在我们的 [#devs channel in our Discord chat](https://www.home-assistant.io/join-chat) 中提问。 我们很多人都会在那里,并且总有人愿意帮助你。 --- url: /developers/setup_devcontainer_environment.md --- 开始开发最简单的方法是使用 Visual Studio Code 配合 [devcontainers](https://code.visualstudio.com/docs/devcontainers/containers)。这种方式会创建一个带有必要工具的预配置开发环境,所有 Home Assistant 仓库都已启用。由于基于 Docker 的 devcontainer 概念提供了一层抽象,以下指南在某一点上会汇合。 首先,安装 [Visual Studio Code](https://code.visualstudio.com/),然后根据系统选择以下步骤。 ## Windows 设置 :::tip **快速入门指南** * 安装 [WSL2](https://learn.microsoft.com/en-us/windows/wsl/install) 并启用 [systemd 支持](https://devblogs.microsoft.com/commandline/systemd-support-is-now-available-in-wsl/)。 * 根据你选择的 WSL2 Linux 发行版安装 [Docker engine](https://docs.docker.com/engine/install/)。 * 在 WSL2 内 fork 并 clone 所需的代码仓库。 * [启动 devcontainer](#fork-the-repository-and-start-the-devcontainer)。 ::: ### 安装 WSL2 本节概述了 Windows 10(*2004 版本及以后*)和 Windows 11 的步骤。如果你仍在运行旧版本,请按这些[手动安装步骤](https://learn.microsoft.com/en-us/windows/wsl/install-manual)操作。 1. 在 Windows 终端中运行以下命令,安装运行 WSL 所需的特性并安装默认的 Ubuntu 发行版: ```batch wsl --install ``` 2. 检查 WSL 版本,如果版本已经是 2,跳过"设置 wsl 版本"步骤。 ```batch wsl -l -v ``` 3. 如有必要,将 WSL 版本设置为 2(*将 `` 替换为已安装的发行版名称;参见上面的输出*)。 ```batch wsl --set-version 2 ``` ### 在 WSL2 中启用 systemd 支持 由于 Docker engine 是作为 systemd 服务安装的,我们需要确保 WSL2 已启用 systemd 支持。 1. 在 Windows 终端中仅输入 `wsl` 命令启动 WSL shell。 2. 将以下内容添加到 `/etc/wsl.conf`;你需要以 root 权限打开该文件(*例如,`sudo nano /etc/wsl.conf`*): ```text [boot] systemd=true ``` 3. 在 Windows 终端中运行以下命令关闭 WSL2: ```batch wsl --shutdown ``` 4. 再次启动 WSL shell 并运行以下命令,检查 systemd 是否正在运行: ```shell systemctl list-units ``` ### 按照"Linux 设置"操作 从这里开始,你可以按照下面的[Linux 设置](#setup-on-linux)说明操作,注意所有步骤都必须在 WSL2 shell 内执行。选择安装 docker engine 的正确步骤时,请使用已安装的 WSL2 发行版(*默认为 Ubuntu*)。 ## Linux 设置 :::tip **快速入门指南** * 根据你的 Linux 发行版安装 [Docker engine](https://docs.docker.com/engine/install/)。 * Fork 并 clone 所需的代码仓库。 * [启动 devcontainer](#fork-the-repository-and-start-the-devcontainer)。 ::: ### 安装 Docker Engine 由于这些说明因 Linux 发行版而异,我们仅提供大致概述。详细操作请遵循官方的 [Docker engine](https://docs.docker.com/engine/install/) 安装指南。 1. 更新所有已安装的包。 2. 为你的包管理器(*如 `yum` 或 `apt`*)添加 Docker 仓库。 3. 更新包仓库的索引。 4. 安装 Docker engine 包。 5. 按照 [Docker Engine 的 Linux 安装后步骤](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user) 允许非 root 用户使用 Docker。 ## macOS 设置 :::tip **快速入门指南** * 安装 [Docker Desktop](https://docs.docker.com/desktop/install/mac-install/)。 * Fork 并 clone 所需的代码仓库。 * [启动 devcontainer](#fork-the-repository-and-start-the-devcontainer)。 ::: ### 安装 Docker Desktop 由于安装步骤已有详细记录且可能随时间变化,我们参考官方的 [在 Mac 上安装 Docker Desktop](https://docs.docker.com/desktop/install/mac-install/) 指南。 ## Fork 仓库并启动 devcontainer 由于这在我们不同的代码仓库间略有不同,以下是一份通用指南。 1. 在 GitHub 上打开所需的代码仓库(*例如 [Home Assistant Core 仓库](https://github.com/home-assistant/core)*),点击 "fork"。 2. Fork 创建后,复制你的 fork 的 URL 并将其 clone 到计算机上的本地目录。 ```shell cd $HOME git clone ``` 3. 进入你的 fork 目录并从中启动 Visual Studio Code: ```shell cd code . ``` 4. Visual Studio Code 将自动检测到 devcontainer 并提示 "Reopen in Container"(*右下角*)——点击它。

--- url: /developers/supervisor.md --- Supervisor 允许用户从 Home Assistant 内部管理他们的 Home Assistant 安装。Supervisor 有以下职责: * 运行 Home Assistant Core * 更新 Home Assistant Core。如果更新失败则自动回滚。 * 创建和恢复 backups * 安装和运行 Home Assistant Apps(前身为 Home Assistant add-ons) * 统一的 audio 系统 * 更新 Home Assistant operating system(在 Supervised 安装中禁用) ## 架构 Architecture Overview of Home Assistant * **Home Assistant Core**: 家庭自动化平台 * **Apps(前身为 add-ons)**: 用户希望在其服务器上运行的额外应用程序 * **DNS**: 允许 core 和 apps(前身为 add-ons)相互通信 * **Audio**: 允许 core 和 apps(前身为 add-ons)播放 audio * **mDNS**: 帮助发现网络中的设备和连接服务 * **Supervisor**: 管理系统的所有部分并保持其最新 * **Docker**: 用于运行应用程序的 container 服务。 * **Operating System**: 基于 Linux 的操作系统 * **D-Bus**: 用于控制操作系统部分(如 network manager)的通信系统 --- url: /developers/supervisor/debugging.md --- 以下调试技巧和诀窍适用于正在运行 Home Assistant 镜像并处理基础镜像的开发者。如果你使用的是通用 Linux 安装脚本,你应该可以按照主机的方式访问主机和日志。 ## 调试 Supervisor 在使用 Python debugger 之前,你需要在 Supervisor 中启用 debug 选项: ```shell ha su options --debug=true ha su reload ``` 如果你在远程主机上运行 Supervisor,你将无法直接访问 Supervisor 容器。"Remote ptvsd debugger" add-on(可从 [Development Add-On Repository](https://github.com/home-assistant/addons-development) 获取)会在你的主机 IP 地址上暴露调试端口,从而允许远程调试 Supervisor。 下面是一个 Visual Studio Code 配置示例,用于将 Python debugger 附加到 Home Assistant Supervisor。此配置旨在通过 Run> Start Debugging 或按 F5 作为默认配置使用。你需要将 "IP" 更改为匹配 Supervisor 在 Docker 环境中的 IP(在 Supervisor 容器内使用 `ip addr`),或者如果你远程调试,则使用主机 IP。 `.vscode/launch.json` ```json { "version": "0.2.0", "configurations": [ { "name": "Supervisor remote debug", "type": "python", "request": "attach", "port": 33333, "host": "IP", "pathMappings": [ { "localRoot": "${workspaceFolder}", "remoteRoot": "/usr/src/supervisor" } ] } ] } ``` --- url: /developers/supervisor/development.md --- 这些说明适用于 Supervisor、Supervisor 前端面板和 `hassio` 集成的开发,通过与发展中的或远程的 supervisor 交互进行,这假设你正在使用一台开发机器进行开发。这些说明还将使用 devcontainer 和其他依赖 Docker 的工具,请先按照我们的 [devcontainer 开发环境](/developers/setup_devcontainer_environment.md) 指南设置合适的开发环境。 ## Supervisor 开发 这里的说明适用于 Supervisor 本身的开发。 1. Fork Supervisor 仓库(https://github.com/home-assistant/supervisor)并将其克隆到你的开发机器上。 2. 使用 Visual Studio Code devcontainer 打开该仓库。 3. 在你的 fork 中创建一个分支。 4. 完成你的更改。 5. 按照下面的说明测试你的更改。 6. 提交并推送你的更改,针对 https://github.com/home-assistant/supervisor 的 `main` 分支创建 PR。 ### 本地测试 在 Visual Studio Code 中启动任务"Run Supervisor",这将在 devcontainer 中启动一个 Supervisor 实例,你可以用它来测试你的更改。 初始化完成后,你可以在 `http://localhost:9123` 访问 Home Assistant 前端。 ### 在远程系统上测试 1. 通过 SSH 或直接控制台访问远程系统。 2. 使用 `ha info` 检查机器上的架构,如果是 Home Assistant OS,则直接运行 `info`。 3. 在你的开发机器上,构建你的 Supervisor 镜像并将其推送到容器注册表。以 GitHub Container Registry 为例(调整 `YOUR_GH_USERNAME` 和架构以匹配你在第 2 步中找到的内容): ```bash docker build \ --platform linux/arm64 \ --tag ghcr.io/YOUR_GH_USERNAME/aarch64-hassio-supervisor:latest \ --push \ . ``` :::note 所有示例都包含你需要调整的值。 * 将 `linux/arm64` 和 `aarch64` 调整为你在第 2 步中找到的架构。 * 将 `YOUR_GH_USERNAME` 调整为你的 GitHub 用户名或组织。 * 要像上面的示例那样将镜像推送到 GitHub Container Registry,你需要使用具有适当权限范围的 personal access token 进行身份验证。更多详情请参见 [GitHub Container Registry 文档](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry)。 ::: :::note `--platform` 选项中使用的架构与 Home Assistant 中使用的并不相同。虽然 Home Assistant 中的 `amd64` 对应于 `--platform linux/amd64`,但 Home Assistant 中的 `aarch64` 对应于 Docker 中的 `--platform linux/arm64`。 ::: 4. 在你的远程系统上,使用 `ha supervisor options --channel dev` 将 channel 更改为 `dev`,如果是 Home Assistant OS,则直接运行 `supervisor options --channel dev`。 5. 拉取你的 Supervisor 镜像: ```bash docker pull ghcr.io/YOUR_GH_USERNAME/aarch64-hassio-supervisor:latest ``` :::note 上传到 GHCR 的 Docker 镜像默认是私有的。要下载它们,你需要在远程系统上也使用 personal access token 进行身份验证,或者[更改 GitHub 上包的可见性](https://docs.github.com/en/packages/learn-github-packages/configuring-a-packages-access-control-and-visibility#configuring-visibility-of-packages-for-your-personal-account)。 ::: 6. 将你的 Supervisor 镜像标记为预期的本地名称: ```bash docker tag ghcr.io/YOUR_GH_USERNAME/aarch64-hassio-supervisor:latest ghcr.io/home-assistant/aarch64-hassio-supervisor:latest ``` 7. 使用 `systemctl restart haos-supervisor` 重启 `haos-supervisor` 服务 8. 使用 `journalctl -fu haos-supervisor` 检查问题 ## 集成开发 这里的说明适用于 `hassio` 集成的开发,我们假设你已经设置了 [Home Assistant Core 开发环境](development_environment.mdx),并且你已经设置了 [Supervisor API 访问](#supervisor-api-access)。 要配置 Home Assistant Core 连接到远程 supervisor,在启动 Home Assistant 时设置以下环境变量: * `SUPERVISOR`:设置为运行 Home Assistant 的机器的 IP 和端口 8880(API proxy add-on) * `SUPERVISOR_TOKEN`:设置为你在 [Supervisor API 访问](#supervisor-api-access) 中找到的 token ```shell SUPERVISOR=192.168.1.100:8880 SUPERVISOR_TOKEN=abcdefghj1234 hass ``` 你的本地 Home Assistant 安装现在将连接到远程 Home Assistant 实例。 ## 前端开发 :::info 所有 supervisor 前端面板已被弃用,在 Home Assistant core >= 2026.2 时将不再加载 ::: Home Assistant 前端通过核心代理使用 supervisor。请查看 [Home Assistant 前端开发环境](/developers/frontend/development.md) 了解如何开发前端。 ## Supervisor API 访问 要为 `hassio` 集成和 Supervisor 面板开发,我们需要访问 supervisor 的 API。该 API 由一个 token 保护,我们可以使用一个特殊的 add-on 来提取该 token。这可以在一个运行的系统上完成,或者使用 [devcontainer](#local-testing)。 [![Open your Home Assistant instance and show the add-on repository dialog with a specific repository URL pre-filled.](https://my.home-assistant.io/badges/supervisor_add_addon_repository.svg)](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2Fhome-assistant%2Faddons-development) [![Open your Home Assistant instance and show the dashboard of a Supervisor add-on.](https://my.home-assistant.io/badges/supervisor_addon.svg)](https://my.home-assistant.io/redirect/supervisor_addon/?addon=ae6e943c_remote_api) 1. 添加我们的开发者 Add-on 仓库: 2. 安装 Add-on"Remote API proxy" 3. 点击 Start 4. token 将打印在日志中 该 add-on 需要保持运行状态,以允许 Home Assistant Core 连接。 Remote API proxy token 的权限略低于 Home Assistant Core 在生产环境中的权限。要获取具有完全权限的实际 token,你需要 SSH 到主机系统并运行: ```shell docker inspect homeassistant | grep SUPERVISOR_TOKEN ``` 注意,任何一种 token 在 OS/容器重启或更新后都可能更改。 --- url: /developers/translations.md --- Home Assistant 的翻译通过 [Lokalise](https://lokalise.com/) 进行管理,这是一款在线翻译管理工具。我们的翻译分为四个项目:一个用于平台特定翻译的 backend 项目、一个用于 UI 翻译的 frontend 项目,以及两个用于官方 companion apps 的项目。点击下方链接即可加入对应项目!即使你的语言已经完成全部翻译,额外的 proofreading 也是非常大的帮助!欢迎审阅现有翻译,并为可能更合适的备选译文投票。 * [加入 frontend 翻译团队](https://app.lokalise.com/public/3420425759f6d6d241f598.13594006/) * [加入 backend 翻译团队](https://app.lokalise.com/public/130246255a974bd3b5e8a1.51616605/) * [加入 iOS 翻译团队](https://app.lokalise.com/public/834452985a05254348aee2.46389241/) * [加入 Android 翻译团队](https://app.lokalise.com/public/145814835dd655bc5ab0d0.36753359/) 如需了解有关翻译编辑器和工具的更多信息,请参阅 [Lokalise 翻译与协作文档](https://docs.lokalise.com/en/collections/2909016-translate-and-collaborate)。 每次构建都会从 Lokalise 下载翻译,因此所有 major、minor、beta 版本以及 nightly builds 都将拥有最新的翻译。 ## 翻译占位符 部分翻译字符串包含特殊的占位符,会在运行时被替换。 用方括号 `[]` 定义的占位符(在 Lokalise 中以绿色显示)是 [Lokalise key references](https://docs.lokalise.com/en/articles/1400528-key-referencing)。它们主要用于链接那些将会重复出现的翻译字符串,避免反复定义相同的翻译。在合理的情况下,译文应充分利用这些引用(方括号占位符的值可以通过在 Lokalise 编辑模式下点击 "Source Alt+0" 按钮轻松填入)。不同语言与英语的重复项可能并不一致,欢迎链接那些在英语中未建立关联的重复翻译。 用花括号 `{}` 显示的占位符是 [translation arguments](https://formatjs.github.io/docs/core-concepts/icu-syntax/),会在 Home Assistant 运行时替换为实时值。原始字符串中出现过的任何 translation argument 占位符都必须包含在译文里,且绝不能被翻译!这些占位符可能包含用于定义复数或其他替换规则的特殊语法。上面链接的 format.js 指南说明了添加复数定义及其他规则的语法。 ## 规则 1. 只有母语者才应提交翻译。 2. 遵循 [Material Design 指南](https://material.io/design/communication/writing.html)。 3. 不要翻译或更改 `Home Assistant`、`Supervisor` 或 `Hue` 等专有名词。 4. 对于区域特定翻译,那些应与基础翻译保持一致的 keys,应克隆源字符串。你可以在界面中通过 **Ctrl+Insert** 或选择 **Insert Source** 来完成。这有助于跟踪哪些内容已审阅、哪些尚未审阅,同时也能简化工作流程。 5. `state_badge` 键下的翻译将用于通知徽章显示。这些译文应足够简短,以适配徽章标签而不溢出。你可以在 Home Assistant UI 中测试这一点:要么用浏览器的开发工具编辑标签文本,要么使用 Home Assistant UI 中 Tools 的 States 标签。在 UI 中输入一个新的 entity ID(`device_tracker.test`),并在 state 中输入你想测试的文本。 6. 如果文本会在不同的翻译 key 之间重复出现,请尽可能使用 Lokalise 的 key reference 功能。基础翻译在 `states` 翻译下面提供了相关示例。更多细节请参阅 [Lokalise key referencing](https://docs.lokalise.com/articles/1400528-key-referencing) 文档。 ## 添加新语言 如果你的语言尚未列出,可以在 [GitHub](https://github.com/home-assistant/frontend/discussions/new?category=localization) 上申请添加。请提供你语言的英文名称和本地名称,例如: ```txt English Name: German Native Name: Deutsch ``` :::info 区域特定翻译(`en-US`、`fr-CA`)只有在某个区域的翻译需要与基础语言翻译有所区别时,才会被纳入。 ::: ### 维护者添加新语言的步骤 1. 语言标签必须符合 [BCP 47](https://tools.ietf.org/html/bcp47)。大多数语言标签的列表见:[IANA subtag registry](http://www.iana.org/assignments/language-subtag-registry/language-subtag-registry)。示例:`fr`、`fr-CA`、`zh-Hans`。只有在包含国家特定覆盖且基础语言已被翻译时,才应包含国家代码。 2. 在 `src/translations/translationMetadata.json` 中添加语言标签和本地名称。示例:"Français"、"Français (CA)"。 3. 在 Lokalise 中添加新语言。 注意:有时你需要在 Lokalise 中更改标签(Language -> Language settings -> custom ISO code)。 ## 语言特定指南 大多数语言对一句话都有多种可能的译法。请在这里查看你所负责语言的指南,里面还有一些典型的错误示例供你避免。 各章节使用对应语言撰写,因为这更便于解释语法,同时也因为只有母语者才应提交翻译(参见[规则](#rules))。 ### 德语 * Du/Sie:翻译中使用 "Du",不要使用正式的 "Sie"。 #### 典型错误 * 注意使用正确的祈使句。祈使句是命令形式,例如 "Gib mir das Wasser"。写成 "Gebe mir das Wasser" 则是错误的(参见[祈使句的构成](https://www.duden.de/sprachwissen/sprachratgeber/Bildung-des-Imperativs))。 ### 法语 * *Blueprint*:已决定不翻译该词,将其视为专有名词。这样可以避免与 *map* 和 *template* 的翻译产生混淆,也便于在互联网上搜索要导入的 Blueprint。因此应始终使用带首字母大写的 `Blueprint`。 --- url: /developers/versioning.md --- Home Assistant Core 使用 [calendar versioning](https://calver.org/) (CalVer)。一个版本由三个用点分隔的部分组成: ``` YYYY.MM.PATCH ``` | Part | Meaning | | --- | --- | | `YYYY` | 发布的年份(例如 `2026`)。 | | `MM` | 发布的月份,**不**补零(例如 `5`,而不是 `05`)。 | | `PATCH` | 该月度发布内的 patch 号,从 `0` 开始。 | 例如,`2026.5.0` 是 2026 年 5 月的初始发布,而 `2026.5.1` 和 `2026.5.2` 是同月的后续 patch releases。关于发布计划和渠道,请参阅 [release FAQ](https://www.home-assistant.io/faq/release/)。 ## 预发布版本和开发版本 版本遵循 [PEP 440](https://peps.python.org/pep-0440/),因此 `PATCH` 部分可以带有表示非稳定构建的 suffix: | Kind | Format | Example | | --- | --- | --- | | Stable release | `YYYY.MM.PATCH` | `2026.5.0`, `2026.5.2` | | Beta | `YYYY.MM.PATCH` + `b` | `2026.5.0b0` | | Nightly | `YYYY.MM.PATCH` + `.dev` | `2026.7.0.dev202607241254` | | Development | `YYYY.MM.PATCH` + `.dev` | `2026.7.0.dev0` | ## 版本号的设定方式 版本被硬编码在 [`homeassistant/const.py`](https://github.com/home-assistant/core/blob/dev/homeassistant/const.py) 中,作为 `MAJOR_VERSION`、`MINOR_VERSION` 和 `PATCH_VERSION` 常量。`dev` branch 始终将即将到来的发布作为一个 development version(例如 `2026.7.0.dev0`)。 版本不是自动从 tags 或日期推导出来的;它是通过使用 [`script/version_bump.py`](https://github.com/home-assistant/core/blob/dev/script/version_bump.py) helper 显式 bump 的,该 helper 知道如何推进每种类型的版本(`minor`、`patch`、`dev`、`beta` 和 `nightly`)。例如,发布第一个 beta 会将 `2026.7.0.dev0` 变成 `2026.7.0b0`,而最终发布则去掉 suffix 变为 `2026.7.0`。 :::note 当你需要根据 Home Assistant Core 版本来 gate 行为时,请使用 [AwesomeVersion](https://github.com/ludeeus/awesomeversion) 来比较版本,而不是自己解析字符串,以便 pre-releases、development 和 patch releases 能够正确排序。 ::: --- url: /developers/voice/contributing-your-voice.md --- 你可以帮助我们和更广泛的开放语音社区为你的语言开发**speech-to-text**和**text-to-speech**模型。 ## 语音转文字 当你向计算机说话时,它会将来自你声音的音频\*\*转录(transcribes)\*\*为文本。实现方式有很多种,但它们都依赖于人们说话的录音。 对于 speech-to-text,重要的是要具备: * 许多不同的说话者和口音 * 各种录音设备和质量水平 * 通常是 16Khz 音频,16 位采样 * 多种录音环境,包括不同的房间和噪音水平 我们建议用户为 [Mozilla's Common Voice](https://commonvoice.mozilla.org) 项目做贡献,以用于 speech-to-text。这是一个免费且开放的数据集,通过众包方式从世界各地的人们那里收集口语句子。贡献者还可以通过验证现有录音来提供帮助。 ## 文字转语音 当计算机向你说话时,它会从文本\*\*合成(synthesizes)\*\*音频。这与 speech-to-text 数据集有不同的要求: * 单个说话者,或为所有说话者提供等量的数据 * 高质量的录音设备 * 通常是 48Khz,32 位采样 * 安静、受控的录音环境,例如隔音棚 我们建议用户为 [LibriVox](https://librivox.org/) 项目做贡献,以用于 text-to-speech。这不仅为开放语音社区提供了训练数据,还为所有人提供了免费的有声书。重要的是,所朗读的书籍必须处于公共领域。 --- url: /developers/voice/intent-recognition/contributing.md --- 模板句子需要提交到我们在 [GitHub 上的 Intents 仓库](https://github.com/home-assistant/intents)。句子将由[语言负责人](/developers/voice/language-leaders.md)审核,如果正确则合并。你可以贡献新句子或改进现有句子。 Intent 仓库结构如下: * `sentences//` - 每种语言的模板句子 - [了解更多](/developers/voice/intent-recognition/template-sentence-syntax.md) * `tests//` - 每种语言的测试 - [了解更多](/developers/voice/intent-recognition/test-syntax.md) 我们更倾向于许多小贡献而不是少数大贡献。包含大量更改的贡献很难审核。因此,我们希望每次贡献仅限于单一语言和单一 domain。 句子和测试的文件名格式为 `_.yaml`。因此,如果你为 cover domain 做贡献,你将更新以下文件: * `sentences//cover_HassCoverOpen.yaml` * `sentences//cover_HassCoverClose.yaml` * `tests//cover_HassCoverOpen.yaml` * `tests//cover_HassCoverClose.yaml` ## 如何贡献 所有贡献都通过 GitHub 上的 Pull Request 完成。我们推荐使用 GitHub CodeSpaces。[按照本教程开始。](https://github.com/home-assistant/intents/blob/main/docs/codespace/README.md) 我们的仓库有很多检查,你可以使用它们确保提交的句子有效。你可以在 VS Code 中使用 `terminal -> run task` 在本地运行它们。 当你创建 Pull Request 时,这些检查也会自动运行。如果检查失败,贡献将无法接受。 ## 添加新语言 新语言应基于 `python3 -m script.intentfest add_language ` 的输出,它会生成一个包含新语言所需所有文件的空语言目录。 首次贡献应限于 `_common.yaml` 中错误句子的翻译,以及为 `homeassistant` domain 添加句子和测试。 如果你无法在本地运行 add\_language 脚本,请在 Discord 中请求维护者为你运行。 --- url: /developers/voice/intent-recognition/index.md --- 语音助手的演变围绕 intent recognition(意图识别)展开。Intent recognition 尝试从用户的输入中提取用户的意图。该意图(一种数据格式)随后将由 Home Assistant 执行。 Home Assistant 的 intent recognition 由 [hassil](https://github.com/home-assistant/hassil) 提供支持。Hassil 通过将用户输入与 sentence templates(句子模板)进行匹配来识别 intents。 Sentence template 是一种包含 slots(即数据的占位符)的句子,并支持各种语法,允许单个 template 匹配大量相似的句子。 > `(turn | switch) on [the] {area} lights` 这个示例 sentence template 既能匹配 `turn on kitchen lights`,也能匹配 `switch on the kitchen lights`。在两种情况下,它都会提取额外数据 `area` 并设为 `kitchen`。 在 Home Assistant 中,我们将 sentence templates 收集在 [GitHub](https://github.com/home-assistant/intents) 上。该仓库旨在针对每种语言和 Home Assistant 中的每个 [supported intent](/developers/intent_builtin.md),包含用户可能会说的各种句子。 --- url: /developers/voice/intent-recognition/style-guide.md --- 本文档描述 responses 的 style guide。 ## 简洁明了 Responses 应简洁明了,不应包含不必要的信息。 * 如果命令针对单个设备,不要在 response 中重复 entity 的名称。 * 如果命令针对一个 area,不要在 response 中重复该 area 或其 entities 的名称。 * 如果命令请求列出 entities,数量在 4 个或以下时全部列出;否则列出前 3 个并说 "+ 2 more"。 可读性很重要,因此在需要时使用下方代码来生成 "+ 2 more" 样式的句子。不要自行创建变体。 ```jinja {% if query.matched %} {% set match = query.matched | map(attribute="name") | sort | list %} {% if match | length > 4 %} Yes, {{ match[:3] | join(", ") }} and {{ (match | length - 3) }} more {%- else -%} Yes, {% for name in match -%} {% if not loop.first and not loop.last %}, {% elif loop.last and not loop.first %} and {% endif -%} {{ name }} {%- endfor -%} {% endif %} {% else %} No {% endif %} ``` ## 使用正确的时态 Responses 应使用现在时。例如,使用 "The light is on",而不是 "The light was on"。 ## 使用正确的语态 Responses 应使用主动语态。例如,使用 "The light is on",而不是 "The light is being turned on"。此处的例外是 `cover` domain,因为其操作需要相当长的时间才能完成。 --- url: /developers/voice/intent-recognition/supported-languages.md --- import languages from '!!yaml-loader!../../../intents/languages.yaml'; import intents from '!!yaml-loader!../../../intents/intents.yaml'; 如果你在下方没有看到你的语言,[帮助我们翻译!](/developers/voice/intent-recognition/contributing.md) 有关每种语言的完整进度报告,[点击此处。](https://ohf-voice.github.io/intents/) <> { Object.entries(languages).map( ([language, info]) => ) }
Code Language Leader Links
{language} {info.nativeName} {info.leaders?.length && info.leaders.map((leader, idx) => <> {!!idx && ', '} {leader} )} Sentences
[本页基于 Intents 仓库自动生成。](https://github.com/home-assistant/intents/blob/main/languages.yaml) --- url: /developers/voice/intent-recognition/template-sentence-syntax.md --- Template sentences 在 YAML 文件中使用 [Hassil(我们的 template matcher)](https://github.com/home-assistant/hassil) 的格式来定义。我们的 template sentences 存储在 [GitHub](https://github.com/home-assistant/intents/tree/main/sentences) 上,组织方式为每种语言在 `sentences//` 下有一个文件目录: * `_common.yaml` - 列出了所有 template sentences 共用的 lists、expansion rules 和 skip words。 * `_.yaml` - 针对单个 [intent](/developers/intent_builtin.md) 和 domain 的 template sentences。 除了 `_common.yaml` 中的数据外,template sentences 还可以使用 `name`、`area` 和 `floor` 这些 lists。这些 lists 由 Home Assistant 在 intent recognition 期间提供。 ```yaml # Example light_HassTurnOn.yaml language: "en" intents: HassTurnOn: # Intent name data: - sentences: - " on [all] [the] (light | lights) in [the] {area}" - " on [all] [the] {area} (light | lights)" - " [all] [the] (light | lights) in [the] {area} on" # Optional; used to set fixed slot values when the intent is matched slots: domain: "light" ``` 上述示例会将句子 `turn on all the lights in the living room` 匹配到 intent `HassTurnOn`,并提取出 area `living room`。domain 值被设为 `light`。在 Home Assistant 中,当该 intent 被执行时,它会打开 area `living room` 中所有类型为 `light` 的 entities。 ## 响应 Sentence template 文件可以包含一组句子的 response "key": ```yaml # Example light_HassLightSet.yaml language: "en" intents: HassTurnOn: data: - sentences: - "set {name} brightness to maximum" slots: brightness: 100 response: "brightness" ``` 在上面的示例中,response key "brightness" 指的是文件 `responses/en/HassLightSet.yaml` 内的一个 template: ```yaml language: en responses: intents: HassLightSet: brightness: '{{ slots.name }} brightness set to {{ slots.brightness }}' ``` 如果没有提供 response key,则假定为 `"default"`。 Response templates 使用 [Jinja2 语法](https://jinja.palletsprojects.com/en/latest/templates/),可以引用 `slots` 对象,其属性是匹配到的 intent 的 slot 值。 请参阅所有 [translated responses](https://github.com/home-assistant/intents/tree/main/responses) 以获取更多示例。 ## 句子模板语法 * 替代词、短语或单词的一部分 * `(red | green | blue)` * `turn(ed | ing)` * 可选词、短语或单词的一部分 * `[the]` * `[this | that]` * `light[s]` * Slot Lists * `{list_name}` * `{list_name:slot_name}`(如果 intent slot 名称不同) * list 中的每个值都是一个不同的选项 * 在 YAML 中,`list_name` 应位于 `lists` 下 * 文本列表使用 `values`,数字列表使用 `range` * Expansion Rules * `` * rule 的主体会被 `` 替换 * 在 YAML 中,`rule_name` 应位于 `expansion_rules` 下。如果 `rule_name` 包裹了 slot name,则应与 slot name 匹配。否则应使用本地语言。 * 2 个或更多项的 [Permutations](https://en.wikipedia.org/wiki/Permutation) * `(patience;you must have)` * Permutation 项始终以空格进行填充,以防止生成新词 * 将项数限制在 2-4 个,因为 `n` 项的排列数会随 `n` 迅速增加,该数字为 `n! == 1 * 2 * ... * n` ## 公共文件 Common 文件 `_common.yaml` 包含在所有 intents 和 domain 的 template sentences 中使用的 lists、expansion rules 和 skip words。 ### 列表 Lists 是 slot 的可能值。Slots 是我们希望从句子中提取的数据。例如,我们可以创建一个 `color` list 来匹配可能的颜色。 ```yaml lists: color: values: - "white" - "red" - "orange" ``` Home Assistant 中的 intent handlers 期望 color 以英文定义。为了允许其他语言定义颜色,lists 支持 in-out 格式。这样你就可以用本地语言定义一组值,但 intent handler 接收到的值将是英文。 ```yaml lists: color: values: - in: "rood" out: "red" - in: "oranje" out: "orange" ``` List 也可以是一个数字范围。这对于定义你想要匹配的 brightness 值范围或温度范围很有用。 ```yaml lists: brightness: range: type: "percentage" from: 0 to: 100 ``` List 还可以匹配特定数字,例如从关键词 maximum 返回 100。要在句子中使用该 list 来设置 brightness,请使用以下语法:`{brightness_level:brightness}`。这会从 list 中获取值,但将其放入 brightness 的 slot 中。 ```yaml lists: brightness_level: values: - in: (max | maximum | highest) out: 100 - in: ( minimum | lowest) out: 1 ``` #### 内联数字范围 数字范围 list 也可以在 sentence template 内联定义: ```yaml language: en intents: SetBrightness: data: - sentences: - set brightness to {0..100:brightness} percent ``` 这将匹配从 0 到 100 的数字,并将值放入 `brightness` slot。数字单词同样有效,因此 "set brightness to 50 percent" 和 "set brightness to fifty percent" 都会匹配,并将 `brightness` slot 设为 50。 #### 通配符 Wildcard lists 可以匹配任意文本,例如: ```yaml language: en intents: PlayAlbum: data: - sentences: - play {album} by {artist} lists: artist: wildcard: true album: wildcard: true ``` 它将匹配诸如 "play the white album by the beatles" 这样的句子。`PlayAlbum` intent 会有一个 `album` slot,值为 "the white album "(注意末尾的空格),以及一个 `artist` slot,值为 "the beatles"。 #### 本地列表 有时你不需要一个可供所有 intents 和 sentences 使用的 slot list,因此你可以在本地定义一个,使其仅在其定义的 intent data(如一组 sentences)的上下文中可用。例如: ```yaml language: en intents: AddListItem: data: - sentences: - add {item} to [my] shopping list lists: item: wildcard: true ``` ### 展开规则 很多 template sentences 可以以相似的方式编写。为了避免多次重复相同的匹配结构,我们可以定义 expansion rules。例如,用户可能在 area 名称前面加上 "the",也可能不加。我们可以定义一个 expansion rule 来匹配这两种情况。 Expansion rules 可以包含 slots、lists 以及其他 expansion rules。 ```yaml expansion_rules: name: "[the] {name}" area: "[the] {area}" what_is: "(what's | whats | what is)" brightness: "{brightness} [percent]" turn: "(turn | switch)" ``` #### 本地展开规则 Expansion rules 也可以在 sentences 列表旁边本地定义,并且仅在那些 templates 内可用。这允许你为不同场景编写相似的 templates。例如: ```yaml language: en intents: GetLocked: data: - sentences: - is the door requires_context: domain: binary_sensor expansion_rules: state: "{binary_state}" - sentences: - is the door requires_context: domain: lock expansion_rules: state: "{lock_state}" lists: binary_state: values: - in: "locked" out: "off" - in: "unlocked" out: "on" lock_state: values: - "locked" - "unlocked" ``` 相同的 template `is the door ` 同时用于 binary sensors 和普通 locks,但本地的 `state` expansion rules 指向不同的 lists。 ### 跳过词 Skip words 是 intent recognizer 在识别期间会跳过的单词。对于不是 intent 一部分、但在句子中经常使用的单词很有用。例如,用户可能在句子中使用单词 "please",但它不是 intent 的一部分。 ```yaml skip_words: - "please" - "can you" ``` ### 需要/排除上下文 Hassil 返回它能找到的第一个 intent match,因此如果同一句子可能产生多个匹配,可能需要额外的 **context**。 例如,考虑以下 template: ```yaml language: "en" intents: HassLightSet: data: - sentences: - "set {name} brightness to maximum" - "set {area} brightness to maximum" slots: brightness: 100 ``` 如果你有一个名为 "kitchen light" 的 entity,那么你就可以说 "set kitchen light brightness to maximum"。类似地,如果你有一个名为 "kitchen" 的 area,那么 "set kitchen brightness to maximum" 也会生效。 但如果你有一个名为 "kitchen" 的 media player 呢?同一句子可能匹配 area 或 media player。Hassil 需要更多 context 才能知道该怎么做: ```yaml language: "en" intents: HassLightSet: data: - sentences: - "set {name} brightness to maximum" requires_context: domain: "light" slots: brightness: 100 - sentences: - "set {area} brightness to maximum" slots: brightness: 100 ``` 我们将 sentences 分成了两组。第一组针对单个 entities,现在包含了 `requires_context`,且 `domain` 为 `light`。这确保 Hassil 只有当 `{name}` 中的 entity 具有正确的 domain 时才会产生匹配。由于 areas 没有 domains,我们需要将 `{area}` sentence 移到其自己的组中。 如果希望在同一 intent 内使用不同的 responses,context 也很有用: ```yaml language: "en" intents: HassTurnOn: data: - sentences: - "activate {name}" excludes_context: domain: "cover" response: "default" - sentences: - "activate {name}" requires_context: domain: "cover" response: "cover" ``` 第一组 sentence 使用 `excludes_context` 跳过 `cover` entities,而第二组则专门匹配 `cover` entities,并使用不同的 [response](#responses)。 --- url: /developers/voice/intent-recognition/test-syntax.md --- 为确保 template sentences 按预期工作,我们拥有一个全面的 test suite。该 test suite 基于 YAML 文件,这些文件包含一组输入 sentences 以及预期匹配的 intent 和 slots。 测试存储在 [GitHub](https://github.com/home-assistant/intents/tree/main/tests) 上,组织方式为每种语言在 `tests//` 下有一个文件目录: * `_fixtures.yaml` - 测试期间可引用的伪造 entities 和 areas * `_.yaml` - 针对单个 [intent](/developers/intent_builtin.md) 和 domain 的 sentences。这些文件应仅测试在 [match sentences file](/developers/voice/intent-recognition/template-sentence-syntax.md) 中同名的句子里定义的 sentences。 ```yaml # Example homeassistant_HassTurnOn.yaml language: "en" tests: # You can have multiple blocks of tests, each with different expected match data - sentences: # Multiple sentences can be tested at once - "turn on the ceiling fan" - "turn the ceiling fan on" # Expected match data intent: name: "HassTurnOn" slots: name: "fan.ceiling" ``` ## 测试夹具 当 Home Assistant 匹配 sentences 时,它会提供一份可在句子中引用的 areas 和 entities 列表。对于测试,我们在 `_fixtures.yaml` 中定义这些。 ```yaml # Example _fixtures.yaml for English language: "en" areas: - name: "Kitchen" id: "kitchen" - name: "Living Room" id: "living_room" entities: - name: "Kitchen Switch" id: "switch.kitchen" area: "kitchen" - name: "Curtain Left" id: "cover.curtain_left" area: "living_room" ``` 请确保 fixtures 不要使用 "garage door" 或 "curtains" 这样泛泛的名称。取而代之,使用像 "garage door left" 或 "curtains left" 这样的唯一名称。这对于允许基于泛泛名称定义匹配句子(如 "open the garage door")是必要的。 --- url: /developers/voice/intents/index.md --- 请参阅 Home Assistant Core 文档中的 intents 部分,了解以下内容: * 由 Home Assistant 支持的 [内置 intents](/developers/intent_builtin.md)。 * 使用 [Conversation API](/developers/intent_conversation_api.md) 向 Home Assistant 发送文本命令并接收响应。 * [注册 intent handlers](/developers/intent_handling.md) 以向 Home Assistant 添加新的 intents。 * [触发 intents](/developers/intent_firing.md),如果你有自己句子匹配逻辑并希望 Home Assistant 处理这些 intents。 --- url: /developers/voice/language-leaders.md --- Home Assistant 是一个全球性项目。我们希望能确保每个人都能用自己的母语使用 Home Assistant。因此,我们为每种语言设有 language leader,负责领导维护工作。 Language leader 负责审核其语言下的贡献,并确保语法正确。 Language leader 会自动收到他们所维护语言的任何新贡献通知。审核并接受该贡献是他们的职责。 任何人都可以申请成为 language leader,只要满足以下要求: * 是其所领导语言的母语使用者 * 向 intents 仓库提交 2 个或以上的 pull request * 参与该语言的 pull request 审核工作 如果你想申请成为 language leader,请加入 Discord 上的 `#developers` 频道或[发起一个讨论话题](https://github.com/home-assistant/intents/discussions)。 ## 失去 language leader 身份 Language leader 是一种语言及其质量的把关人。如果他们不活跃,该语言的贡献将不会被处理。如果他们接受低质量的贡献,将无法生成处理所需的正确匹配句子。 如果 language leader 的不活跃成为瓶颈,或者质量不达标,该 language leader 将被移除。如果他们想恢复身份,可以再次申请。 --- url: /developers/voice/overview.md --- 构建一个语音助手是一项复杂的任务。它需要许多不同的技术协同工作。本页将概述 Home Assistant 内部的不同组件以及它们将如何协同工作。 ```mermaid graph TD; U((User)) STT[Speech-to-Text] VA[Assist Pipeline] C[Conversation] I[Intent] TTS[Text-to-Speech] U -->|1\. Speech + Metadata| VA; VA -->|2\. Speech| STT STT -->|3\. Sentence| VA VA -->|4\. Sentence + Metadata| C C -->|5\. Intent| I I -->|6\. Intent Response| C; C -->|7\. Intent Response| VA; VA -->|8\. Intent Response| TTS TTS -->|9\. Response Audio| VA VA -->|10\. Response Audio| U ``` * **Assist Pipeline** 集成负责将用户的语音转换为文本,对其进行处理,并将响应转换为语音。 * **Conversation** 集成负责处理用户的文本。内置的 conversation agent 通过将其匹配到 intent 来完成此操作。集成可以提供[自定义 conversation agent](/developers/core/entity/conversation.md)。 * **Intent** 集成负责执行 intent 并返回响应。 * **Text-to-Speech** 集成负责将文本转换为语音。集成可以提供[自定义 text-to-speech agent](/developers/core/entity/tts.md)。 * **Speech-to-Text** 集成负责将语音转换为文本。集成可以提供[自定义 speech-to-text agent](/developers/core/entity/stt.md)。 ## 捕获用户的语音 上述图表没有描述的内容是如何捕获用户的语音。实现方式会有很多种。 最终目标是打造**Voice Satellites(语音卫星设备)**。这些设备可以放置在房屋的任何位置。一旦检测到唤醒词,它就会捕获用户的语音,将其发送到 Home Assistant,并向用户播放响应。 --- url: /developers/voice/pipelines/index.md --- [Assist 流水线](https://www.home-assistant.io/integrations/assist_pipeline) 集成执行语音助手的常见步骤: 1. 唤醒词检测 2. 语音转文字 3. 意图识别 4. 文字转语音 流水线通过 WebSocket API 运行: ```json { "type": "assist_pipeline/run", "start_stage": "stt", "end_stage": "tts", "input": { "sample_rate": 16000, } } ``` [示例代码](https://github.com/OHF-Voice/websocket-voice-assistant) 以下输入字段可用: | 名称 | 类型 | 描述 | |-------------------|--------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `start_stage` | enum | 必填。第一个要运行的 stage。可选值为 `wake_word`、`stt`、`intent`、`tts`。 | | `end_stage` | enum | 必填。最后一个要运行的 stage。可选值为 `stt`、`intent`、`tts`。 | | `input` | dict | 取决于 `start_stage`:
  • 仅 `wake_word`:
    • `timeout` - 唤醒词检测超时前的秒数(int,默认:3)
    • `noise_suppression_level` - 噪音抑制量(int,0 = 禁用,4 = 最大)
    • `auto_gain_dbfs` - 自动增益(int,0 = 禁用,31 = 最大)
    • `volume_multiplier` - 固定音量放大(float,1.0 = 不变,2.0 = 两倍)
  • `wake_word` 和 `stt`:
    • `sample_rate` - 传入音频的采样率(int,赫兹)
    • `wake_word_phrase` - 检测到的唤醒词(例如 "okay nabu"),用于避免多个设备被唤醒
  • `intent` 和 `tts`:
    • `text` - 输入文本(string)
| | `pipeline` | string | 可选。流水线的 ID(使用 `assist_pipeline/pipeline/list` 获取名称)。 | | `conversation_id` | string | 可选。[对话的唯一 ID](/developers/intent_conversation_api.md#conversation-id)。 | | `device_id` | string | 可选。从 Home Assistant 设备注册表中获取的设备 ID,表示启动流水线的设备。 | | `timeout` | number | 可选。流水线超时前的秒数(默认:300)。 | ## 事件 流水线运行过程中,会通过 WebSocket 连接发出事件。 可能发出的事件如下: | 名称 | 描述 | 发出时机 | 属性 | |----------------|------------------------------|------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `run-start` | 流水线运行开始 | 总是 | `pipeline` - 流水线 ID
`language` - 流水线使用的语言
`runner_data` - 额外 WebSocket 数据:
  • `stt_binary_handler_id` 是发送语音数据的前缀。
  • `timeout` 是整个流水线的最大运行时间。

`tts_output` - TTS 输出数据
  • `token` - 生成音频的 Token
  • `url` - 生成音频的 URL
  • `mime_type` - 生成音频的 MIME 类型
  • `stream_response` - TTS 在生成响应时是否可流式传输。
| | `run-end` | 流水线运行结束 | 总是 | | | `wake_word-start` | 唤醒词检测开始 | 仅音频 | `engine`: 使用的唤醒引擎
`metadata`: 传入音频
`timeout`: 唤醒词超时前的秒数 | | `wake_word-end` | 唤醒词检测结束 | 仅音频 | `wake_word_output` - 检测结果数据:
  • `wake_word_id` 是检测到的唤醒词 ID
  • `timestamp` 是相对于音频流开始的检测时间(毫秒,可选)
| | `stt-start` | 语音转文字开始 | 仅音频 | `engine`: 使用的 STT 引擎
`metadata`: 传入音频元数据 | | `stt-vad-start` | 语音指令开始 | 仅音频 | `timestamp`: 相对于音频流开始的时间(毫秒) | `stt-vad-end` | 语音指令结束 | 仅音频 | `timestamp`: 相对于音频流开始的时间(毫秒) | `stt-end` | 语音转文字结束 | 仅音频 | `stt_output` - 包含检测到的文本 `text` 的对象。 | | `intent-start` | 意图识别开始 | 总是 | `engine` - [代理](/developers/intent_conversation_api.md) 引擎
`language`: 处理语言。
`intent_input` - 输入到代理的文本 | | `intent-progress` | 意图识别的中间更新 | 取决于对话代理 | `chat_log_delta` - 可选,来自[聊天日志](/developers/core/entity/conversation.md#chat-log)的 delta 对象
`tts_start_streaming` - 可选,如果 TTS 流式传输已开始则为 True | | `intent-end` | 意图识别结束 | 总是 | `intent_output` - [对话响应](/developers/intent_conversation_api.md#conversation-response) | | `tts-start` | 文字转语音开始 | 仅音频 | `engine` - 使用的 TTS 引擎
`language`: 输出语言。
`voice`: 输出语音。
`tts_input`: 要朗读的文本。 | | `tts-end` | 文字转语音结束 | 仅音频 | `token` - 生成音频的 Token
`url` - 生成音频的 URL
`mime_type` - 生成音频的 MIME 类型
| | `error` | 流水线错误 | 出错时 | `code` - 错误代码([见下文](#error-codes))
`message` - 错误消息 | ## 错误代码 流水线 `error` 事件返回以下代码: * `wake-engine-missing` - 未安装唤醒词引擎 * `wake-provider-missing` - 配置的唤醒词 provider 不可用 * `wake-stream-failed` - 唤醒词检测期间出现意外错误 * `wake-word-timeout` - 超时前未检测到唤醒词 * `stt-provider-missing` - 配置的语音转文字 provider 不可用 * `stt-provider-unsupported-metadata` - 语音转文字 provider 不支持音频格式(采样率等) * `stt-stream-failed` - 语音转文字期间出现意外错误 * `stt-no-text-recognized` - 语音转文字未返回转录文本 * `intent-not-supported` - 配置的对话代理不可用 * `intent-failed` - 意图识别期间出现意外错误 * `tts-not-supported` - 配置的文字转语音 provider 不可用或不支持选项 * `tts-failed` - 文字转语音期间出现意外错误 ## 发送语音数据 以 `stt` 作为第一个 stage 启动流水线并收到 `stt-start` 事件后,可以通过 WebSocket 连接以二进制数据发送语音数据。音频应尽快发送,每个数据块前面带一个字节作为 `stt_binary_handler_id` 前缀。 例如,如果 `stt_binary_handler_id` 为 `1` 且音频块为 `a1b2c3`,消息为(十六进制): ``` stt_binary_handler_id || 01a1b2c3 |||||| audio ``` 要指示语音数据发送结束,发送一个包含单个字节的二进制消息,该字节为 `stt_binary_handler_id`。 ## 唤醒词检测 当 `start_stage` 设置为 `wake_word` 时,流水线将不会运行,直到检测到唤醒词。客户端应避免不必要的音频流传输,使用本地语音活动检测器(VAD)仅在检测到人类语音时才开始流传输。 对于 `wake_word`,`input` 对象应包含一个 `timeout` 浮点值。这是流水线在唤醒词检测期间超时的静默秒数(错误代码 `wake-word-timeout`)。 如果 Home Assistant 的内部 VAD 检测到足够多的语音,超时将持续重置。 ### 音频增强 当 `start_stage` 设置为 `wake_word` 时,以下设置作为 `input` 对象的一部分可用: * `noise_suppression_level` - 噪音抑制级别(0 = 禁用,4 = 最大) * `auto_gain_dbfs` - 自动增益控制(0 = 禁用,31 = 最大) * `volume_multiplier` - 音频样本乘以常数(1.0 = 不变,2.0 = 两倍响) 如果你的设备麦克风音量较小,推荐设置如下: * `noise_suppression_level` - 2 * `auto_gain_dbfs` - 31 * `volume_multiplier` - 2.0 增加 `noise_suppression_level` 或 `volume_multiplier` 可能导致音频失真。 --- url: /download.md --- # Home Assistant 相关资源下载 :::danger China Only 请使用`中国大陆的网络`下载以下内容,否则可能导致速度不佳,文件损坏或者下载中断 ::: ## 安卓客户端下载 :::info 加速链接采用第三方公开平台 `https://gh-proxy.org` ::: | 版本 | 类型 | 版本号 | 下载链接 | 版本 | 类型 | 版本号 | 下载链接 | | ------ | ---------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------- | ------ | ---------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------- | | 稳定版 | 原生安卓系统 | 2026.6.5 | [国内加速](https://gh-proxy.org/https://github.com/home-assistant/android/releases/download/2026.6.5/app-full-release.apk) | 测试版 | 原生安卓系统 | 2026.8.4 | [国内加速](https://gh-proxy.org/https://github.com/home-assistant/android/releases/download/2026.8.4/app-full-release.apk) | | 稳定版 | 国内安卓系统 | 2026.6.5 | [国内加速](https://gh-proxy.org/https://github.com/home-assistant/android/releases/download/2026.6.5/app-minimal-release.apk) | 测试版 | 国内安卓系统 | 2026.8.4 | [国内加速](https://gh-proxy.org/https://github.com/home-assistant/android/releases/download/2026.8.4/app-minimal-release.apk) | | 稳定版 | 原生安卓车机系统 | 2026.6.5 | [国内加速](https://gh-proxy.org/https://github.com/home-assistant/android/releases/download/2026.6.5/automotive-full-release.apk) | 测试版 | 原生安卓车机系统 | 2026.8.4 | [国内加速](https://gh-proxy.org/https://github.com/home-assistant/android/releases/download/2026.8.4/automotive-full-release.apk) | | 稳定版 | 国内安卓车机系统 | 2026.6.5 | [国内加速](https://gh-proxy.org/https://github.com/home-assistant/android/releases/download/2026.6.5/automotive-minimal-release.apk) | 测试版 | 国内安卓车机系统 | 2026.8.4 | [国内加速](https://gh-proxy.org/https://github.com/home-assistant/android/releases/download/2026.8.4/automotive-minimal-release.apk) | | 稳定版 | Wear OS 穿戴设备 | 2026.6.5 | [国内加速](https://gh-proxy.org/https://github.com/home-assistant/android/releases/download/2026.6.5/wear-release.apk) | 测试版 | Wear OS 穿戴设备 | 2026.8.4 | [国内加速](https://gh-proxy.org/https://github.com/home-assistant/android/releases/download/2026.8.4/wear-release.apk) | :::tip 新手建议使用稳定版,虽然版本功能更新没这么快,但是不容易出现异常情况。 ::: ## Windows 客户端下载 :::info 加速链接采用第三方公开平台 `https://gh-proxy.org` ::: | 版本 | 类型 | 版本号 | 下载链接 | | ------ | ------ | ------ | ----------------------------------------------------------------------------------------------------------------------- | | 稳定版 | 安装包 | v0.5.2 | [国内加速](https://gh-proxy.org/https://github.com/ha-china/ha-windows/releases/download/v0.5.2/HomeAssistantWindows.exe) | :::tip 提示 国内用户无法访问GitHub的用户建议选择"国内加速"链接以获得更快的下载速度,国际用户可直接使用原始。 ::: ## `Home Assistant OS 极速版`系统镜像下载 :::info 国内链接与OTA服务器由[深圳酷宅科技有限公司](https://www.coolkit.cn/)(以下简称`酷宅科技`)提供赞助`(仅限中国地区IP地址可以访问)` 原始加速采用`https://gh-proxy.org`加速 (`建议使用`),`酷宅科技`下载点已经**禁用手机**下载,手机下载仅限`ghfast加速` 后台扫描的太多了,加了WAF防火墙,如果请求次数太多无法下载,请采用`原始加速`链接,原始已经做了国内优化,普通网络也可以下载 请使用`中国大陆的网络`安装系统,否则可能导致安装不上,安装失败,无法初始化 在线式:跟官方标准版一样,安装之后需要初始化,并下载依赖镜像(时间根据服务器负载波动) 完整包(**公测**):安装完成后即可直接进入系统配置,无需等待依赖镜像下载;检测到更新会提示,更新再慢也不影响您配置。建议体验,如果有任何安装后不能进入系统的问题,欢迎随时反馈 ::: | 文件名 | 下载链接(完整包) | 下载链接(在线式) | 备注(刷机方式) | | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | | aarch64-18.3.img.xz | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_generic-aarch64-18.3-full.img.xz) | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_generic-aarch64-18.3.img.xz) | [酷宅科技](https://ota.hasscn.top/18.3/haos_generic-aarch64-18.3.img.xz) | Mac Mini, arm 64 | | aarch64-18.3.qcow2.xz | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_generic-aarch64-18.3-full.qcow2.xz) | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_generic-aarch64-18.3.qcow2.xz) | [酷宅科技](https://ota.hasscn.top/18.3/haos_generic-aarch64-18.3.qcow2.xz) | arm pve, [UTM](/installations/utm.md) | | aarch64-18.3.vdi.zip | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_generic-aarch64-18.3-full.vdi.zip) | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_generic-aarch64-18.3.vdi.zip) | [酷宅科技](https://ota.hasscn.top/18.3/haos_generic-aarch64-18.3.vdi.zip) | | | aarch64-18.3.vmdk.zip | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_generic-aarch64-18.3-full.vmdk.zip) | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_generic-aarch64-18.3.vmdk.zip) | [酷宅科技](https://ota.hasscn.top/18.3/haos_generic-aarch64-18.3.vmdk.zip) | arm vmware, esxi | | x86-64-18.3.img.xz | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_generic-x86-64-18.3-full.img.xz) | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_generic-x86-64-18.3.img.xz) | [酷宅科技](https://ota.hasscn.top/18.3/haos_generic-x86-64-18.3.img.xz) | [x86物理机直装](/installations/x86.md) | | x86-64-18.3.qcow2.xz | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_generic-x86-64-18.3-full.qcow2.xz) | | x86 [pve](/installations/proxmox.md) | | x86-64-18.3.vdi.zip | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_generic-x86-64-18.3-full.vdi.zip) | | | | x86-64-18.3.vmdk.zip | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_generic-x86-64-18.3-full.vmdk.zip) | | x86 vmware, [esxi](/installations/esxi.md) | | green-18.3.img.xz | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_green-18.3-full.img.xz) | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_green-18.3.img.xz) | [酷宅科技](https://ota.hasscn.top/18.3/haos_green-18.3.img.xz) | HA Green | | ihost-17.1.img.xz | | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/17.0/haos_ihost-17.0.img.xz) | [酷宅科技](https://ota.hasscn.top/17.0/haos_ihost-17.0.img.xz) | [Sonoff iHost](/installations/ihost.md) | | OPI-cm4-18.3.img.xz | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_orangepi-cm4-18.3-full.img.xz) | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_orangepi-cm4-18.3.img.xz) | [酷宅科技](https://ota.hasscn.top/18.3/haos_orangepi-cm4-18.3.img.xz) | [OPI CM4](/installations/orangepi.md) | | ova-18.3.img.xz | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_ova-18.3-full.img.xz) | | 通用离线镜像 | | ova-18.3.ova | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_ova-18.3-full.ova) | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_ova-18.3.ova) | [酷宅科技](https://ota.hasscn.top/18.3/haos_ova-18.3.ova) | vmware, [esxi](/installations/esxi.md), [威联通](/installations/qnap.md) | | ova-18.3.qcow2.xz | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_ova-18.3-full.qcow2.xz) | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_ova-18.3.qcow2.xz) | [酷宅科技](https://ota.hasscn.top/18.3/haos_ova-18.3.qcow2.xz) | [pve](/installations/proxmox.md), [飞牛](/installations/fnos.md) | | ova-18.3.vdi.zip | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_ova-18.3-full.vdi.zip) | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_ova-18.3.vdi.zip) | [酷宅科技](https://ota.hasscn.top/18.3/haos_ova-18.3.vdi.zip) | Hyper-V 老版本 | | ova-18.3.vhdx.zip | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_ova-18.3-full.vhdx.zip) | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_ova-18.3.vhdx.zip) | [酷宅科技](https://ota.hasscn.top/18.3/haos_ova-18.3.vhdx.zip) | Hyper-V | | ova-18.3.vmdk.zip | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_ova-18.3-full.vmdk.zip) | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_ova-18.3.vmdk.zip) | [酷宅科技](https://ota.hasscn.top/18.3/haos_ova-18.3.vmdk.zip) | vmware, [esxi](/installations/esxi.md) | | panther-x2-18.3.img.xz | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_panther-x2-18.3-full.img.xz) | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_panther-x2-18.3.img.xz) | [酷宅科技](https://ota.hasscn.top/18.3/haos_panther-x2-18.3.img.xz) | 黑豹 x2 | | rpi3-64-18.3.img.xz | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_rpi3-64-18.3-full.img.xz) | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_rpi3-64-18.3.img.xz) | [酷宅科技](https://ota.hasscn.top/18.3/haos_rpi3-64-18.3.img.xz) | [树莓派3](/installations/raspberrypi.md)| | rpi4-64-18.3.img.xz | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_rpi4-64-18.3-full.img.xz) | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_rpi4-64-18.3.img.xz) | [酷宅科技](https://ota.hasscn.top/18.3/haos_rpi4-64-18.3.img.xz) | [树莓派4](/installations/raspberrypi.md)| | rpi5-64-18.3.img.xz | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/17.3/haos_rpi5-64-17.3-full.img.xz) | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_rpi5-64-18.3.img.xz) | [酷宅科技](https://ota.hasscn.top/18.3/haos_rpi5-64-18.3.img.xz) | [树莓派5](/installations/raspberrypi.md)| | yellow-18.3.img.xz | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_yellow-18.3-full.img.xz) | [gh-proxy](https://gh-proxy.org/github.com/ha-china/HAOS-CN/releases/download/18.3/haos_yellow-18.3.img.xz) | [酷宅科技](https://ota.hasscn.top/18.3/haos_yellow-18.3.img.xz) | HA Yellow | ## 刷机程序 :::info 所有的刷机程序固件均为`Home Assistant OS 极速版`,更适合中国环境下使用。 ::: | 文件名 | 下载链接 | 备注(刷机方式) | 文件HASH (SHA256) | | ----------------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------- | ---------------------------------------------------------------- | | green\_factory\_CN.img.xz | [酷宅科技](https://ota.hasscn.top/green_factory_CN.img.xz) | [Home Assistant Green](https://mp.weixin.qq.com/s/QZKFLsyAbJ9zgqu9EIKXKw) | 1a5299d0189d0fcce59ad488e08476180cf87bcb71176b8a887c2bdd29257de1 | | haos-installer-amd64.iso | [酷宅科技](https://ota.hasscn.top/haos-installer-amd64.iso) | [x86物理机直装](/installations/x86.md),专门为 x86 物理机直装使用 | | ## 加入群聊沟通 :::info 因为有不同的群提供,如果你在使用上有任何问题,可以点击页面右上角微信图标进入群聊,直接贴群聊二维码有7天有效期的问题,所以采用申请表的方式也解决有效期的问题 ::: --- url: /evaluation/index.md --- # 测评清单 :::tip 说明 (仅Home Assistant相关的使用情况) 测评仅为参考,请结合自身情况进行选择,测评产品默认可以直接跟Home Assistant局域网对接 根据不同的协议您可能会需要购买不同的配件,但都是本地直连,非本地直连的,会在文章内容中指出。 ::: ## 硬件 ### **Seeed Studio (矽递科技)** #### reTerminal E1001/E1002 #### reSpeaker XVF 3800 (with XIAO ESP32S3) #### reCamera HQ POE ### **AIKS 埃克思科技** #### Home Assistant 智能遥控器 (AIKS X9 Vela Edition) *** ## 软件 ### 普格睿明信息科技 (PGRM) #### WebTunnel --- url: /hacscn.md --- # 🏠 HACS 极速版 [![stars](https://img.shields.io/github/stars/hacs-china/integration)](https://github.com/hacs-china/integration/stargazers) :::info 版权 版本修改作者:[Alone](https://anlo.ng/),如果你已经是`Home Assistant OS 极速版`则无需重复安装,已内置 ::: [HACS](https://hacs.xyz)是一款优秀的 [Home Assistant](https://www.home-assistant.io) 集成商店,然而国人想要使用它下载插件或前端卡片却困难重重,主要原因就是国内的网络环境。 本项目使用了[gitmirror.com](https://gitmirror.com)和[fastgit.org](https://fastgit.org)等提供的Github代理服务,可以让大家更快的下载商店里的插件。 :::tip 我们需要你的帮助 HACS极速版是依赖于有github帐号的玩家共享token来实现免帐号使用的,如果您愿意共享您的token,请[点此](https://tokenhub.hacs.vip/)来帮助有需要的人 ::: ## 安装/更新 :::tip 本项目是HACS官方集成的修改版,安装本项目会覆盖官方的集成,但是无需重新配置集成(共用一套配置),因此你可以放心安装。如果想切换到官方版本,使用官方的shell命令再安装即可。 ::: :::warning 以下几种方法任选其一! ::: ### 方法1️⃣: 使用命令安装 ```shell wget -O - https://get.hacs.vip | bash - # 或 curl -fsSL get.hacs.vip | bash ``` * 如果是haos/hassio/supervised版本的HA,可直接在宿主机或`Terminal & SSH`加载项中执行上面的命令 * 如果是core/docker版本的HA,需要ssh登陆宿主机后,并cd进入到HA配置目录再执行安装命令 ### 方法2️⃣: [`加载项安装器: https://hacs.vip/get-addon`](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgitee.com%2Fhacs-china%2Faddons) > 需要HAOS或Supervised版本的HA 1. 添加加载项仓库 [`https://gitee.com/hacs-china/addons`](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgitee.com%2Fhacs-china%2Faddons) 2. 找到`HACS极速版安装器`并安装加载项 3. 启动加载项并观察日志 4. 重启HA ### 方法3️⃣: [`upgrade`](https://my.home-assistant.io/redirect/developer_call_service/?service=hacs.upgrade)服务 > 需要已安装HACS极速版v1.33.0.3版本及以上 1. 在开发者工具中执行服务 [`service: hacs.upgrade`](https://my.home-assistant.io/redirect/developer_call_service/?service=hacs.upgrade) 2. 重启HA使更新后的HACS生效 ### 方法4️⃣: [`shell_command`](https://my.home-assistant.io/redirect/developer_call_service/?service=shell_command.update_hacs_china)服务 1. 复制代码到HA配置文件 `configuration.yaml` ```yaml shell_command: update_hacs_china: |- wget -O - https://get.hacs.vip | bash - ``` 2. 重启HA使配置生效 3. 在开发者工具中执行动作 [`action: shell_command.update_hacs_china`](https://my.home-assistant.io/redirect/developer_call_service/?service=shell_command.update_hacs_china) 4. 再次重启HA使更新后的HACS生效 ### 方法5️⃣: [`Docker安装`](https://hub.docker.com/r/hacn/hacn) > 仅针对未安装HACS的**Docker**版本的HA 1. 使用命令方式安装 ```bash docker run -d \ --name homeassistant \ --privileged \ --restart=unless-stopped \ -e TZ=Asia/Shanghai \ -v /PATH_TO_YOUR_CONFIG:/config \ -v /run/dbus:/run/dbus:ro \ --network=host \ hacn/hacn:stable ``` 2. 使用Compose安装 ```yaml services: homeassistant: container_name: homeassistant image: hacn/hacn:stable volumes: - /PATH_TO_YOUR_CONFIG:/config - /etc/localtime:/etc/localtime:ro - /run/dbus:/run/dbus:ro restart: unless-stopped privileged: true network_mode: host ``` 3. 启动后[添加HACS集成](https://my.home-assistant.io/redirect/config_flow_start/?domain=hacs) ### 方法6️⃣: 手动安装 * [点击这里下载](https://github.com/hacs-china/integration/releases/latest/download/hacs.zip)安装包并解压 (如果下载不了请点[这里](https://ghproxy.com/github.com/hacs-china/integration/releases/latest/download/hacs.zip)或[这里](https://hub.fastgit.xyz/hacs-china/integration/releases/latest/download/hacs.zip)) * 通过samba/ftp进入HA配置目录,通常为以下目录: * `/usr/share/hassio/homeassistant` haos/hassio宿主机 * `/config` haos/hassio的`Samba`或`Terminal & SSH`加载项 * `$HOME/.homeassistant` 以core方式安装的HA默认配置目录 * docker安装的HA为`-v`参数后面映射的目录 * 在HA配置目录下创建`custom_components`文件夹 (如果已有请忽略) * 在`custom_components`目录下创建`hacs`文件夹 (如果已有请删除重新创建) * 將解压出来的文件复制到刚创建的`hacs`文件夹 * 重启HA * [添加HACS集成](https://my.home-assistant.io/redirect/config_flow_start/?domain=hacs) (仅首次安装) --- url: /haoscn.md --- import BilibiliVideo from './BilibiliVideo'; # 🏠 Home Assistant OS 极速版 · 极致体验为你而来 **作者:老王杂谈说** ## 🌟 极速版简介 :::info | `Home Assistant OS 极速版` | [![haoscn](https://camo.githubusercontent.com/812fc8ae4e90824fc4661a2e97644f969c68cec0a96e0a1b14f7755d43a08464/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f486f6d65253230417373697374616e742532304f532d2545362539452538312545392538302539462545372538392538382d3431424446353f7374796c653d666f722d7468652d6261646765266c6f676f3d686f6d652d617373697374616e74266c6f676f436f6c6f723d7768697465)](https://github.com/ha-china/HAOS-CN/) | |----|----| |仅对最终用户提供稳定版通道|不提供 `dev`版| | `如果你打的开Github,点个Star吧` | [![stars](https://img.shields.io/github/stars/ha-china/HAOS-CN)](https://github.com/ha-china/HAOS-CN/) | ::: ## 🌟 极速版核心亮点 ### 🚀 网络加速优化 * 🕵️‍♂️ `版本检测服务`优化至国内`自架`腾讯BGP节点 - `[赞助]` * 🛡️ `系统网络检查`优化至国内`自架`腾讯BGP节点 - `[赞助]` * ⏰ `时间同步服务器`优化至国内 - `[公共]` * 🏫 `镜像拉取服务`优化至国内`自架`腾讯BGP节点 - `[赞助]` * 🏢 `核心镜像拉取`优化至国内`自架`腾讯BGP节点 - `[赞助]` * 🔄 `OTA升级服务`优化至国内`自架`腾讯BGP节点 - `[赞助]` * ⚡ `系统源下载地址`优化至国内`自架`腾讯BGP节点 - `[赞助]` * 🐳 添加国内 `docker.io` 镜像地址至系统 - `[公共]` * 🔗 `系统错误日志上报`优化至国内`自架`腾讯BGP节点 - `[赞助]` *** ### 🛠️ 原汁原味的官方体验 * 🟢 100% 保留官方源代码 * 🚀 所有的优化`仅`为加速系统在中国的`使用以及合规性` * ⏱️ 系统初始化时间`大幅`优化:界面显示20分钟,实际仅需`5分钟`左右即可完成(相比原版可能耗时数小时) * ⚡ **完整版本固件**无需等待,可直接跳过初始化依赖下载,安装好后零等待即可直接使用 *** ### ⚙️ 系统配置优化 * 🕰️ 默认时区设置为 `Asia/Shanghai` * 📅 默认系统更新频率调整为`每月28日`定期更新,Beta通道为每日同步一次官方稳定版 * 📢 终端页面添加`服务器赞助信息`声明 *** ### 📦 海量应用支持 :::info | `点个Star吧` | [![star](https://img.shields.io/github/stars/ha-china/hassio-addons)](https://github.com/ha-china/hassio-addons) | |----|----| ::: * 📦 内置 400+ 中国版应用 * 🖱️ 一键安装,丝滑升级 * ✅ 彻底解决: * 🌐 网络问题导致的安装失败 * 🗑️ 系统误删应用 * 🔧 网络异常导致的系统错误,自动修复功能失效 * 🔗 访问地址:[`应用仓库`](https://gitcode.com/ha-china/ha-apps) * ❌ 移除不稳定的 `官方应用源`、`官方社区源`、`Music Assistant 源`、`ESP Home 源` * ✅ 添加经过全面优化与汉化的`默认应用源`(上述移除内容均已包含在内) *** ### 📅 智能更新策略 * 🗓️ 每月 `28 日`统一更新版本 * 🛡️ `避免`月初更新导致的集成问题 * ⏳ 比官方版本延迟约 `1 个月`,确保稳定性 * 📝 支持根据用户反馈`调整`更新频率 *** ### 💻 极速在线升级 * ⚡ 初始化与在线升级`全面优化` * 🕒 `告别`漫长等待,升级体验大幅提升 *** ### ⚡ `完全开源`透明 * 🔓 所有修改`公开`透明 * 🔍 支持`代码审查` * 🔒 无任何后门,确保系统`安全` *** ### 🔧 新设备适配计划 * 📈 持续扩展设备支持范围 * 💡 欢迎用户提交设备适配需求 * 🤝 共同完善生态建设 *** ### 🎬 速度演示 *** ### 📥 [系统镜像下载](/download.md#中国优化版系统镜像下载) :::info 💡 **Home Assistant OS 极速版 让 Home Assistant 更懂中国用户,体验前所未有的丝滑与便捷!** ::: --- url: /hello.md --- # Hello world! ## Start Write something to build your own docs! 🎁 --- url: /home-assistant/blog/2014-12-18-website-launched.md --- # 网站上线! 我终于抽时间搭建了一个简单的网站,帮助大家快速上手 Home Assistant。整个过程非常顺利,这要感谢优秀的工具 [Jekyll](http://jekyllrb.com) 和 [Octopress](http://octopress.org),以及出色的服务 [GitHub Pages](https://pages.github.com) 和 [CloudFlare](https://cloudflare.com)。 --- url: /home-assistant/blog/2014-12-26-home-control-home-automation-and-the-smart-home.md --- # 家居控制、家庭自动化与智能家居 过去一年里,互联网一直在热议家庭自动化。你会看到很多相关术语,比如物联网(Internet of Things)、家庭自动化和智能家居。 这篇文章会尝试解释它们之间的关系。 首先要介绍的是 **物联网**(IoT)。它指的是新一代设备:这些设备不仅能让人通过按钮或遥控器控制,还能提供接口与其他设备和应用通信。比如,一台支持 IoT 的咖啡机可以接收指令制作不同种类的咖啡,并广播水箱剩余水量。 目前还没有被广泛采用的智能设备通信开放标准,这导致许多设备无法互通。即使能互通,大多数设备也不是为管理其他设备而设计的。为了解决这个问题,我们需要一个能与所有已连接设备通信并进行管理的设备,这个设备叫做 **中枢(hub)**。 作为最基本能力,中枢必须跟踪每个设备的状态,并在可能的情况下控制它们。比如,它要知道哪些灯开着、哪些关着,并提供控制灯光的方法。对于传感器,它只需要知道其数值。具备这些能力的中枢,就提供了 **家居控制**。

Hub 仪表盘 example 中枢仪表盘示例:显示 2 个人员、4 盏灯和太阳的状态。

在家居控制之上更进一步,就是让用户根据家居控制层的信息设置触发器来发送命令。比如,当有人回家时自动打开灯光。具备这些能力的中枢,就是 **家庭自动化**。 如今市面上的大多数中枢都在不同程度上提供了这类能力。某些 IoT 设备也提供类似功能,但通常只能控制自身,而且多半局限于基于位置和时间的事件。 最后一个类别,也是目前仍偏未来形态的,是 **智能家居**:一个能够自学习和自适应的系统,它会自行决定哪些事件应影响其他设备。 一个智能家居的实际例子是:系统观察到 A 回家时,客厅和厨房的灯会打开;而 B 回家时,客厅和书房的灯会打开。下一次 A 或 B 回家时,智能家居会在用户无需配置的情况下自动打开其偏好的灯光。 如今能让我们一窥未来的产品之一是 [Nest 恒温器](https://nest.com/)。它足够智能,能够学习你的作息并据此自动调节温度。 综上,家庭自动化大致可归纳为下图:

Home 自动化 landscape 家庭自动化版图概览。

### Challenges 你可能会想:听起来并不复杂,为什么我还没有自己的智能家居?因为我们目前还面临一些挑战,阻碍了我们走向这个未来。 #### 需要更多支持物联网的设备 现在大多数 IoT 产品仍集中在灯光、开关和在场检测上。仅靠这些,还不足以让家真正“聪明”起来。我们需要电视、冰箱、烤箱等更多设备加入,扩大可控设备数量。 #### 需要更多数据 大多数第一代 IoT 设备只暴露控制所需的信息。为了让智能家居学习“设备交互如何影响其他事物”,我们需要能追踪与每个设备的全部交互。比如,需要知道冲了多少杯咖啡、冰箱开门频率等。这会显著增加信息流,并打开大量新可能性。例如,当咖啡快喝完时,智能家居可以自动下单补货。 #### 需要易用、开放且可信的软件 要提高普及率,首先得让人们信任自己的智能家居系统。要说服大家升级所有设备,并把所有交互上传到云端,是非常困难的。这些数据可能暴露他们生活的方方面面,包括不想示人的习惯。因此,这类系统应当简单且开源,让人们能验证“家里产生的数据留在家里”。 另一个推动普及的重要因素是:软件必须让普通用户也能轻松安装和使用。很多人还没尝试家庭自动化,仅仅是因为担心配置过程太复杂。 Home Assistant 正在努力成为这样的软件。虽然还未完全实现,但我们一直在持续推进。设备发现以及家庭自动化配置界面,是我们希望在 2015 年重点攻克的问题,同时不牺牲模块化和易用性。 新年快乐! --- url: /home-assistant/blog/2015-01-04-hey-pushbullet-nice-talking-to-you.md --- # 你好 PushBullet,很高兴和你对话 Home Assistant 过去一直缺少一个与用户沟通的方式。比如家里没人时灯却被打开了,若能及时收到消息不是很好吗?由于 Home Assistant 前端在手机上是以 Web 应用形式运行,我们无法主动把自己切到前台。这正是新通知组件发挥作用的地方,而它由 PushBullet 驱动。 新的通知组件会接收消息并发送给用户。当前由非常棒的 [PushBullet](https://www.pushbullet.com/) 提供支持,但也可以很容易扩展到其他消息平台。

由 simple_alarm 组件触发的消息,通过 PushBullet 显示在 Moto360 上。

继续阅读,了解如何启用通知组件并与其他组件集成。 ### 启用通知组件 要启用新的通知组件,请在 `home-assistant.conf` 中添加以下内容: ```text [notify] platform=pushbullet api_key=ABCDEFGHJKLMNOPQRSTUVXYZ ``` 你可以在 [PushBullet 账户页面](https://www.pushbullet.com/#settings/account) 获取 API key。 ### 从你的组件发送消息 要发送消息,通知组件必须先成功加载并初始化。 ```python import homeassistant.loader as loader def setup(hass, config): notify = loader.get_component('notify') notify.send_message(hass, "Hello from my component!") ``` --- url: /home-assistant/blog/2015-01-11-bootstrapping-your-setup-with-discovery.md --- # 使用 Discovery 快速启动你的配置 大多数人都不喜欢手动配置。大家希望开箱即用。我们即将介绍的新 discovery 组件,目标正是实现这一点。 discovery 组件会定期扫描 WiFi 网络中的 zeroconf/mDNS 和 uPnP 设备。首个版本主要先把整体架构搭好,并支持发现网络中的 Belkin WeMo 开关和 Google Chromecast。发现后,它会加载并通知对应组件,几秒内即可使用。 大多数设备在被发现后,仍需要用户进行某种交互——可能是按下按钮,也可能是完成认证。这是我们未来会继续解决的挑战。 要启用 discovery 组件,请在 `home-assistant.conf` 中添加: ```text [discovery] ``` 我们已在“Adding a new platform”页面新增 [discovery 小节](/home-assistant/developers/add_new_platform/#discovery),说明如何让你的平台支持被发现。 --- url: /home-assistant/blog/2015-01-13-nest-in-da-house.md --- # Nest 来到家中! 在过去的大部分时间里,Home Assistant 主要专注于在场检测、灯光和开关。但现在不一样了,我们正在扩展支持设备。今天,我们很高兴发布由 [Stefano Fiorini](https://github.com/sfiorini) 贡献的 Nest Thermostat 集成!

这个新集成由两部分组成:通用恒温器组件和 Nest 平台实现。首个版本提供了一个只读卡片以及用于控制的服务。后续计划是在恒温器卡片中加入温度和离家模式控制,并增加更多信息对话框。底层通信使用的是 [jkoelker 的 python-nest](https://github.com/jkoelker/python-nest) Python 包。 如果你有 Nest 恒温器,请在 `home-assistant.conf` 中添加以下内容: ```text [thermostat] platform=nest username=YOUR_USERNAME password=YOUR_PASSWORD ``` --- url: /home-assistant/blog/2015-01-24-release-notes.md --- # 2015 年 1 月 24 日发布说明 我刚刚把开发分支的最新版本合并到了 master。以下是本次发布的一些亮点: **通过前端完成配置**
Philips Hue 现在可以被自动发现,并会使用新的 `configurator` 组件与用户交互来完成设置流程。 **Wink Hub 支持**
感谢 John McLaughlin 和 Geoff Norton 的工作,我们现在支持连接到 Wink Hub 的灯光、开关和传感器。 **入门指南与组件页面已重组**
入门说明现已拆分为“每个组件单独页面”加“总览页面”。目标是让每个组件页面都包含: * 它的作用 * 如何配置 * 维护哪些状态 * 提供哪些服务 * 额外的开发提示 **更合理的错误提示**
如果你的 Python 3 版本不正确、忘记克隆 git submodule,或未安装依赖,Home Assistant 现在会给出更清晰的错误提示和解决建议。 **首次启动流程更顺畅**
Home Assistant 现在支持 `--open-ui` 和 `--demo-mode` 命令行参数,可自动打开浏览器并展示可用内容。现在也支持无密码运行,使界面启动后可以自动登录。 --- url: /home-assistant/blog/2015-02-07-looking-at-the-past.md --- # 回望过去 自 Home Assistant 发布以来,你一直可以追踪家中的状态。但过去只能看到“当前状态”,无法看到“曾经状态”。今天我们将通过两个全新组件改变这一点: * Recorder 组件:把每个事件记录到 SQLite 数据库 * History 组件:查询并聚合这些历史事件 通过增加“过去视角”,我们为家庭状态增加了一个新的维度,也为未来功能带来了更多可能。本次发布重点是先让你开始记录并积累数据。为展示记录内容,我们新增了一个视图,用于显示过去 24 小时的家庭状态。未来我们会继续提供更强大的历史探索工具。 把历史功能加入 UI 本身就是个挑战,因为旧 UI 不利于导航。借这次发布,Home Assistant 的界面也一并焕新了。 新用户默认启用 history 组件。现有用户请运行 `scripts/update` 升级到最新版本,并在 `home-assistant.conf` 中添加 `[history]`。

:::note 事件会保存在本地数据库中。图表由 Google Graphs 绘制,绘制过程 100% 在浏览器内完成,任何时候都不会把数据传给他人。 ::: 历史追踪是 Home Assistant 令人兴奋的下一步,也将驱动下一代功能。下面是一些现在已经可以实现的方向: * Time Machine:查看家中任意过去时刻的状态 * Smart Home:分析行为模式并用于家庭自动化 * 汇总家中不同组件的使用情况 --- url: /home-assistant/blog/2015-02-24-streaming-updates.md --- # 流式更新 Home Assistant 学会了一个从服务端获取最新信息的新方式:流式更新。前端不再每 30 秒轮询一次,而是保持连接常开,在变更发生时立即接收推送。 侧边栏新增了一个开关,可启用或关闭流式更新。这个偏好会通过 local storage 按浏览器保存。若建立流连接时发生错误,开关也会显示状态,并自动回退到轮询模式。

流式更新基于 HTML5 `EventSource` 实现。实现过程很直接,因为重连逻辑由 `EventSource` 自身处理。[服务端代码](https://github.com/home-assistant/home-assistant/blob/master/homeassistant/integrations/api/__init__.py) 约 50 行,客户端代码约 80 行。 现在,服务端发生的所有事件都会发送到浏览器。这让任何正在运行 UI 的浏览器都成为 Home Assistant 的一个完整[从属实例](/home-assistant/developers/architecture/#multiple-connected-instances)。这也为完全运行在客户端的组件打开了新的可能性。 实现 EventSource 也并非没有挑战。我们解决了以下问题: 在 Chrome 中,连接可能会“悄悄失效”而不触发任何事件处理器。这通常发生在设备进入待机时。电脑上较少见,但手机上很常见。我们通过服务端定期发送 ping 解决了这个问题:当前端一段时间没收到通信时,会认为连接已失效。发送 ping 也有助于服务端发现并清理断开的连接。 我遇到的另一个问题是,Safari 和 Firefox 不会在连接建立时触发 `open` 事件,而是在收到第一条消息后才触发。为此,服务端现在会在连接建立后立即发送一次 ping。 --- url: /home-assistant/blog/2015-02-28-home-assistant-migrating-to-yaml.md --- # Home Assistant 正在迁移到 YAML Home Assistant 现在使用 [YAML](http://yaml.org/) 作为配置文件格式。YAML 支持列表结构,这会让配置文件更灵活、更实用。新的配置格式向后兼容现有组件,因此组件开发者无需更新自己的组件。 新文件名为 `configuration.yaml`。如果在你的配置目录中找不到该文件,Home Assistant 会继续尝试查找旧配置文件 `home-assistant.conf`。 `home-assistant.conf.example` 现已替换为更新后的 `configuration.yaml.example`。 建议 Home Assistant 用户尽快迁移,因为旧配置格式已被弃用。 --- url: /home-assistant/blog/2015-03-08-new-logo.md --- # Home Assistant 全新 Logo 大家常说,人通常要么是好程序员,要么是好设计师,两者兼备很少见。所以我自己做出来的 Logo 表现平平,也就不让人意外了。幸运的是,[Jeremy Geltman](http://jeremygeltman.com/) 前来救场,为 Home Assistant 贡献了全新的 Logo。 新 Logo 遵循 Google 的 Material Design 规范,采用了 Home Assistant 界面中的蓝色,并提供两个版本:高细节版本(用于主屏图标等)和简化版本(用于 favicon 等)。

旧 Logo、新版高细节 Logo 与新版简化 Logo。

--- url: /home-assistant/blog/2015-03-11-release-notes.md --- # 2015 年 3 月 11 日发布说明 距离 Theodor 为 Home Assistant 引入 YAML 支持才刚过一周多,但已经发生了很多变化,是时候总结一下近期更新了。在介绍亮点之前,先感谢 [andythigpen](https://github.com/andythigpen)、[jamespcole](https://github.com/jamespcole) 和 [theolind](https://github.com/theolind) 提交了大量 bug 修复、功能增强和新贡献! **监控本地资源**
Theodor 贡献了一个新的传感器平台,可用于监控磁盘占用、内存占用、CPU 占用和运行进程。该平台已取代 process 组件,后者现已被视为弃用。 ```yaml # Example configuration.yaml entry sensor: - platform: systemmonitor resources: - type: disk_use_percent arg: /home - type: memory_free - type: process arg: kodi ``` **实验性 Z-Wave 支持**
现在已提供通过 Z-Wave USB 棒连接 Z-Wave 网络的实验性支持。目前仅集成 Z-Wave 传感器到 Home Assistant。我们的目标是在更多人测试后,再逐步加入其他 Z-Wave 设备支持。 新组件构建在 [python-openzwave](https://code.google.com/p/python-openzwave/) 之上。该包目前未在 PyPI 发布,因此我们新增了脚本 `scripts/build_python_openzwave`,用于在你的机器上安装。你也可以直接使用开箱即用的 Docker 镜像。 开发测试使用的是 AEON Z-Wave USB 棒和 AEON Z-Wave MultiSensor。 ```yaml # Example configuration.yaml entry zwave: usb_path: /dev/ttyUSB0 ``` **语音控制**
Home Assistant 的语音控制首个版本已上线。当前实现分为两个部分。 第一部分是名为 `conversation` 的组件,暴露服务 `conversation/process`。该服务可以处理文本并将其转换为设备命令。当前仅支持 `Turn ` 格式的指令。 第二部分是对前端的升级:利用 Chrome 的语音转文本能力,让用户可以直接说出命令。如果你使用 Chrome,可以在 [demo](/home-assistant/demo/) 中体验。 ```yaml # Example configuration.yaml entry conversation: ``` --- url: /home-assistant/blog/2015-03-22-release-notes.md --- # 2015 年 3 月 22 日发布说明 Home Assistant 刚刚推送了一个新版本。这个版本包含了 [jamespcole](https://github.com/jamespcole)、[andythigpen](https://github.com/andythigpen)、[trainman419](https://github.com/trainman419) 和 [我](https://github.com/balloob) 贡献的错误修复,也带来了不少很棒的新功能: **脚本** Andythigpen 贡献了脚本组件。它允许你创建由服务调用和延时组成的顺序流程。你可以通过服务 `script/turn_on` 启动脚本,并通过服务 `script/turn_off` 中断脚本。前端也新增了一个独立页面,用来查看脚本状态。 ```yaml # Example configuration.yaml entry script: # Turns on the bedroom lights and then the living room lights 1 minute later wakeup: alias: "Wake Up" sequence: - alias: "Bedroom lights on" execute_service: light.turn_on service_data: entity_id: group.bedroom - delay: # supports seconds, milliseconds, minutes, hours, etc. minutes: 1 - alias: "Living room lights on" execute_service: light.turn_on service_data: entity_id: group.living_room ``` **场景** 我(Paulus)贡献了场景组件。你可以创建场景,定义某些实体应处于的状态。比如,一个场景可以设置灯 A 打开、灯 B 为亮红色。停用场景时,系统会恢复到场景激活前的状态。和脚本一样,场景也有独立页面来查看哪些场景处于开启状态。 ```yaml # Example configuration.yaml entry scene: - name: Romantic entities: light.tv_back_light: on light.ceiling: state: on color: [0.33, 0.66] brightness: 200 ``` **SABnzbd** James Cole 贡献了 SABnzbd 集成支持。这样你就可以在 Home Assistant 中监控下载,并基于这些信息设置自动化。 ```yaml # Example configuration.yaml entry sensor: - platform: sabnzbd name: SAB api_key: YOUR_API_KEY # Example: http://192.168.1.32:8124/ base_url: YOUR_SABNZBD_BASE_URL monitored_variables: - type: 'current_status' - type: 'speed' - type: 'queue_size' - type: 'queue_remaining' - type: 'disk_size' - type: 'disk_free' ``` **Pushover** James Cole 还贡献了对 Pushover 服务 的支持,可作为通知组件的平台。这让各组件能够通过 Pushover 向你发送消息。 ```yaml # Example configuration.yaml entry notify: platform: pushover # Get this by registering a new application on https://pushover.net api_key: ABCDEFGHJKLMNOPQRSTUVXYZ # Get this by logging into your account on https://pushover.net user_key: ABCDEFGHJKLMNOPQRSTUVXYZ ``` --- url: /home-assistant/blog/2015-04-25-release-notes.md --- # 2015 年 4 月 25 日发布说明 距离上次更新已经过去一个月,这段时间又发生了很多变化。下面快速概述一下这次的新内容。 **折线图** [James](https://github.com/jamespcole) 升级了前端中的历史视图,现已支持折线图。任何带有计量单位的实体都会显示折线图,实体的“更多信息”卡片中也会显示折线图。[查看在线演示示例。](/home-assistant/demo/)

**ISY994 hub 支持** [Ryan](https://github.com/rmkraus) 贡献了 Universal Devices ISY994 hub 的集成支持。你可以借此接入 X10/Insteon 传感器、开关和灯光。 他还编写了一份完整的入门指南,可在 [ISY994 组件页面](/home-assistant/integrations/isy994/index.md) 查看。 ```yaml # Example configuration.yaml entry isy994: ``` **日志簿** 我(Paulus)新增了日志簿组件。日志簿会按时间顺序展示家中发生的所有变化,让你用另一种视角查看家庭历史。[查看在线演示示例。](/home-assistant/demo/) ```yaml # Example configuration.yaml entry logbook: ``` **Transmission 支持** James 还贡献了 Transmission 集成支持。 ```yaml # Example configuration.yaml entry sensor: platform: transmission name: Transmission host: 192.168.1.26 port: 9091 username: YOUR_USERNAME password: YOUR_PASSWORD monitored_variables: - type: 'current_status' - type: 'download_speed' - type: 'upload_speed' ``` **Modbus 支持** [Kixam](https://github.com/kixam) 贡献了 Modbus 支持。Modbus 是一种用于控制 PLC 的串行通信协议。目前它支持可通过串口、TCP 和 UDP 连接控制的传感器与开关。 ```yaml # Example configuration.yaml entry modbus: type: serial method: rtu port: /dev/ttyUSB0 baudrate: 9600 stopbits: 1 bytesize: 8 parity: N sensor: platform: modbus slave: 1 registers: 16: name: My integer sensor unit: C 24: bits: 0: name: My boolean sensor 2: name: My other boolean sensor switch: platform: modbus slave: 1 registers: 24: bits: 0: name: My switch 2: name: My other switch ``` --- url: /home-assistant/blog/2015-05-09-utc-time-zone-awareness.md --- # UTC 与时区感知 我最近合并了一次重构,将 Home Assistant 内部时间全面改为仅使用 UTC。这是一次非常必要的调整。我还为时间敏感部分补充了更多测试覆盖,以确保稳定性。这些代码已经在 dev 分支运行了 9 天,很快就会发布到 master 分支。 从现在开始,所有内部通信都将使用 UTC:比如时间变化事件、状态的 datetime 属性等。要获取当前 UTC 时间,你可以调用 `homeassistant.util.dt.utcnow()`。它会返回一个带时区信息的 UTC datetime 对象。[`homeassistant.util.dt`](https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/util/dt.py) 是一个新的日期工具包。 当然也有“本地时间”。本地时间基于你在 `configuration.yaml` 中设置的时区。本地时间只应用于面向用户的信息,比如日志、前端界面,以及 `configuration.yaml` 里的自动化设置。 ### 设置时区 时区需要在 `configuration.yaml` 中设置。如果你没有配置时区,系统会使用现有的检测代码通过 [freegeoip.net](https://freegeoip.net) 自动探测。你可以在 [Wikipedia](http://en.wikipedia.org/wiki/List_of_tz_database_time_zones) 上查看兼容的时区列表。 ```yaml homeassistant: time_zone: America/Los_Angeles ``` ### 兼容性 这次代码变更在大多数情况下向后兼容。旧方法 `hass.track_time_change` 和 `hass.track_point_in_time` 现在内部会调用两个新方法:`hass.track_utc_time_change` 和 `hass.track_point_in_utc_time`。旧方法的使用方式没有变化,按理应保持向后兼容。 这次重构还新增了一次数据库迁移,为事件和状态表添加了 `utc_offset` 列。该信息目前还未使用,但未来分析历史数据时可能会很有帮助。 ### 向后不兼容的内容 所有内置组件都已升级。下面这份列表仅适用于运行自定义组件的用户: * `hass.track_time_change` 和 `hass.track_point_in_time` 现在会返回带时区信息的 datetime 对象。Python 不允许比较 naive datetime 和 aware datetime。 * 日出和日落相关的 sun 属性现在都是 UTC。`sun.next_rising(hass)` 和 `sun.next_setting(hass)` 方法保持向后兼容,但如果你以前直接读取原始属性,需要注意。 * API 现在会以 UTC 发送所有时间。如果你使用前端以外的方式与 Home Assistant 通信,请确认它能正确处理这一变化。 --- url: /home-assistant/blog/2015-05-14-release-notes.md --- # 2015 年 5 月 14 日发布说明 距离上次发布已经过去将近忙碌的三周。我们终于完成了内部日期时间格式统一为 UTC 的重构。过程中我们新增了大量测试覆盖,以确保迁移平稳完成。关于向后不兼容的变更,请查看[UTC 重构博文](/home-assistant/blog/2015/05/09/utc-time-zone-awareness/#backwards-incompatible-stuff)。 这次发布还包含前端启动速度的显著提升,并修复了 Wemo 在其最新固件升级后的发现问题。 我还要特别感谢我们的新贡献者 [fabaff](https://github.com/fabaff),他投入了很多时间改进文档。 :::note 要更新到最新版本,请运行 脚本/更新。如果遇到问题,请在 GitHub 提交反馈。 ::: **覆盖实体属性** 在介绍新支持的设备和服务之前,我想先重点提一下 [rmkraus](https://github.com/rmkraus) 带来的一项很棒的配置增强:覆盖实体属性。 这些新的配置选项允许你覆盖实体的状态属性。其主要用途是覆盖那些会影响实体在界面中显示方式的属性。 ```yaml # Example configuration.yaml entry homeassistant: customize: light.bowl: # hides this entity from the interface hidden: true light.ceiling: # Replaces the state badge with given picture entity_picture: http://graph.facebook.com/schoutsen/picture ``` **MySensors** [Andythigpen](https://github.com/andythigpen) 和 [Theolind](https://github.com/theolind) 为 Home Assistant 增加了 [MySensors 平台](http://www.mysensors.org) 支持。 ```yaml # Example configuration.yaml entry sensor: platform: mysensors port: /dev/ttyACM0 ``` **OpenWeatherMap** [Fabaff](https://github.com/fabaff) 贡献了 [OpenWeatherMap](http://openweathermap.org) 支持。这让你可以把本地天气数据集成到 Home Assistant 中。 ```yaml # Example configuration.yaml entry sensor: platform: openweathermap api_key: YOUR_API_KEY monitored_variables: - type: 'weather' - type: 'temperature' - type: 'wind_speed' - type: 'humidity' - type: 'pressure' - type: 'clouds' - type: 'rain' - type: 'snow' ``` **InstaPush** [Fabaff](https://github.com/fabaff) 贡献了 InstaPush 支持。你可以通过它把消息从 Home Assistant 发送到 iOS 和 Android 设备。 ```yaml # Example configuration.yaml entry notify: platform: instapush # Get those by creating a new application, event and tracker api_key: ABCDEFGHJKLMNOPQRSTUVXYZ app_secret: ABCDEFGHJKLMNOPQRSTUVXYZ event: ABCDEFGHJKLMNOPQRSTUVXYZ tracker: ABCDEFGHJKLMNOPQRSTUVXYZ ``` **XMPP** [Fabaff](https://github.com/fabaff) 贡献了 Jabber/XMPP 支持。你可以通过 Home Assistant 向任何 Jabber/XMPP 用户发送消息。 ```yaml # Example configuration.yaml entry notify: platform: xmpp sender: YOUR_JID password: YOUR_JABBER_ACCOUNT_PASSWORD recipient: YOUR_RECIPIENT ``` **Notify My Android** [Fabaff](https://github.com/fabaff) 贡献了 [Notify My Android](http://www.notifymyandroid.com/) 支持。你可以借此通过 Home Assistant 向 Android 设备发送消息。 ```yaml # Example configuration.yaml entry notify: platform: nma # Get this by registering a new application on http://www.notifymyandroid.com/ api_key: ABCDEFGHJKLMNOPQRSTUVXYZ ``` **时间与日期传感器** [Fabaff](https://github.com/fabaff) 贡献了时间与日期传感器。你可以用它在仪表盘上显示当前时间和日期。 ```yaml # Example configuration.yaml entry sensor: platform: time_date monitored_variables: - type: 'time' - type: 'date' - type: 'date_time' - type: 'time_date' ``` --- url: /home-assistant/blog/2015-06-10-release-notes.md --- # 2015 年 6 月 10 日发布说明 哇,距离上次发布几乎过去了一个月,而这次发布内容非常丰富。你最可能不会直接注意到的一项重大变化是:前端已从 Polymer 0.5 升级到全新发布的 Polymer 1.0。Polymer 已被 Google 宣布为稳定版本,这让我们能够继续扩展此前一直在等待这一时刻的功能。 这次发布还刷新了参与人数纪录:8 位!感谢 [Andythigpen](https://github.com/Andythigpen)、[Jamespcole](https://github.com/Jamespcole)、[Azelphur](https://github.com/Azelphur)、[Fabaff](https://github.com/Fabaff)、[Dutchy-](https://github.com/Dutchy-)、[Fbradyirl](https://github.com/Fbradyirl)、wind-rider 和 [ettisan](https://github.com/ettisan) 的贡献! wind-rider 为本次发布带来了一个重要改进。他花时间恢复了 Chromecast 支持,并开始持续完善媒体播放器集成。这也带动了更多人加入,最终带来了焕然一新的媒体播放器体验,以及对 Music Player Daemon 的支持。

新媒体播放器卡片示例

:::note 要更新到最新版本,请运行 脚本/更新。如果遇到问题,请在 GitHub 提交反馈。 ::: 在介绍新支持的平台之前,先看看这次发布带来的其他改进: * 前端由 @balloob 升级到 Polymer 1.0 * 通过 `!include` 关键字支持在 YAML 中包含其他文件(@andythigpen) * Vera 平台新增开关支持并修复多个问题(@jamespcole) * HTTP 组件增加 HTTP session 支持(@jamespcole) * 设备追踪器问题修复(@Dutchy-) * 设备追踪器平台问题修复(@fbradyirl) * 修复 Chromecast 支持(@wind-rider) * 媒体播放器改进(@balloob 与 @wind-rider) * Nest 恒温器问题修复(@balloob) * 修复设备追踪器死锁问题(@balloob) * 更新文档(@fabaff) **Music Player Daemon** Fabaff 贡献了 Music Player Daemon 支持。mpd 平台让你可以在 Home Assistant 中控制 [Music Player Daemon](http://www.musicpd.org/)。目前支持播放控制,不支持播放列表管理。 ```yaml # Example configuration.yaml entry media_player: platform: mpd server: 127.0.0.1 port: 6600 location: bedroom ``` **命令行开关** 这是一个开关平台,在打开和关闭时会分别执行指定命令。它很可能会成为最受欢迎的平台之一,因为它让你可以把任何可通过命令行控制的开关类型集成进 Home Assistant,甚至包括调用其他脚本! ```yaml # Example configuration.yaml entry switch: platform: command_switch switches: - kitchen_light: oncmd: switch_command on kitchen offcmd: switch_command off kitchen ``` **LimitlessLED** 这个新平台可以让你在 Home Assistant 中控制 LimitlessLED 灯光。这些灯光也被称为 EasyBulb、AppLight、AppLamp、MiLight、LEDme、dekolight 或 iLight。 ```yaml # Example configuration.yaml entry light: platform: limitlessled host: 192.168.1.10 group_1_name: Living Room group_2_name: Bedroom group_3_name: Office group_4_name: Kitchen ``` **比特币传感器** Bitcoin 平台会显示 [Bitcoin](https://bitcoin.org) 网络的多项信息。如果你使用 [Blockchain.info](https://blockchain.info/) 在线钱包,该传感器还可以显示当前余额。 ```yaml # Example configuration.yaml entry sensor: platform: bitcoin wallet: "YOUR WALLET_ID" password: YOUR_ACCOUNT_PASSWORD currency: YOUR CURRENCY display_options: - exchangerate - trade_volume_btc - miners_revenue_usd - btc_mined - trade_volume_usd - difficulty - minutes_between_blocks - number_of_transactions - hash_rate - timestamp - mined_blocks - blocks_size - total_fees_btc - total_btc_sent - estimated_btc_sent - total_btc - total_blocks - next_retarget - estimated_transaction_volume_usd - miners_revenue_btc - market_price_usd ``` **SMTP 通知平台** SMTP 平台允许你把 Home Assistant 的通知发送到电子邮件收件人。 ```yaml # Example configuration.yaml entry notify: platform: mail server: MAIL_SERVER port: YOUR_SMTP_PORT sender: SENDER_EMAIL_ADDRESS starttls: 1 or 0 username: YOUR_SMTP_USERNAME password: YOUR_SMTP_PASSWORD recipient: YOUR_RECIPIENT ``` **Syslog 通知平台** Syslog 平台允许你把 Home Assistant 的通知发送到本地 syslog。 ```yaml # Example configuration.yaml entry notify: platform: syslog ``` **瑞士公共交通传感器** 瑞士公共交通传感器会提供瑞士境内指定起点到终点的后两班发车时间。查看[组件页面](/home-assistant/integrations/swiss_public_transport.md)了解更多设置方法。 **Transmission 海龟模式开关** Transmission 平台允许你在 Home Assistant 中控制 [Transmission](http://www.transmissionbt.com/) 客户端。该平台可让你开关其“备用速度限制”(也叫“海龟模式”)。 ```yaml # Example configuration.yaml entry switch: platform: transmission name: Transmission host: 192.168.1.26 port: 9091 username: YOUR_USERNAME password: YOUR_PASSWORD ``` **Hikvision 摄像头运动检测支持** 这个开关平台允许你控制 Hikvision 摄像头的运动检测设置。 ```yaml # Example configuration.yaml entry switch: platform: hikvisioncam name: Hikvision Cam 1 Motion Detection host: 192.168.1.26 username: YOUR_USERNAME password: YOUR_PASSWORD ``` --- url: /home-assistant/blog/2015-07-11-ip-cameras-arduino-kodi-efergy-support.md --- # 现已支持 IP 摄像头、Arduino、Kodi 和 Efergy 能耗监测器 又过了一个月,Home Assistant 迎来了一批很棒的新功能。本月发布由 [balloob](https://github.com/balloob)、[ettisan](https://github.com/ettisan)、[fabaff](https://github.com/fabaff)、[gyran](https://github.com/gyran)、[jamespcole](https://github.com/jamespcole)、[michaelarnauts](https://github.com/michaelarnauts)、[miniconfig](https://github.com/miniconfig) 和 [rmkraus](https://github.com/rmkraus) 共同实现。 这次发布还包含了我做的一些架构调整。首先,前端现在基于 [NuclearJS](http://optimizely.github.io/nuclear-js/) JavaScript 后端,这极大地改善了前端代码的组织和优化。另一个变化是,Home Assistant 现在会按需安装依赖,而不是一次性为所有受支持设备安装全部依赖。 **IP 摄像头支持** James 付出了大量努力,为 Home Assistant 增加了 IP 摄像头支持,并已包含在本次发布中。首个版本聚焦于通用 IP 摄像头支持,这意味着只要摄像头能通过 URL 提供 JPEG 图像,就可以集成。 Home Assistant 会通过服务器转发到摄像头的请求,让你可以在 Home Assistant 应用中访问内网里的 IP 摄像头。 ```yaml # Example configuration.yaml entry camera: platform: generic name: my sample camera username: MY_USERNAME password: MY_PASSWORD still_image_url: http://194.218.96.92/jpg/image.jpg ``` :::note 要更新到最新版本,请运行 script/update。如遇到问题,请在 GitHub 上反馈。 ::: **Arduino** Fabian 贡献了 Arduino 接口支持。你现在可以通过 USB 连接 Arduino,将引脚作为传感器数据暴露出来,并通过开关写入引脚状态。可查看[文档](/home-assistant/integrations/arduino/)了解详细入门指南。 ```yaml # Example configuration.yaml entry switch: platform: arduino pins: 11: name: Fan Office type: digital 12: name: Light Desk type: digital sensor: platform: arduino pins: 1: name: Door switch type: analog 0: name: Brightness type: analog ``` **Kodi (XBMC)** Ettisan 为媒体播放器组件贡献了 Kodi(XBMC)平台。这让你可以跟踪正在播放的媒体并进行控制。 ```yaml # Example configuration.yaml entry media_player: platform: kodi name: Kodi url: http://192.168.0.123/jsonrpc user: kodi password: my_secure_password ``` **TP-Link** Michael 为设备追踪器添加了 TP-Link 支持。如果你使用 TP-Link 路由器,现在可以进行在家状态检测。 ```yaml # Example configuration.yaml entry device_tracker: platform: tplink host: YOUR_ROUTER_IP username: YOUR_ADMIN_USERNAME password: YOUR_ADMIN_PASSWORD ``` **Efergy 能耗监测器** Miniconfig 贡献了对 [Efergy 电表](https://efergy.com)的支持。要获取应用令牌,请登录 Efergy 账户,进入设置页面,选择 App tokens,然后点击“Add token”。 ```yaml # Example configuration.yaml entry sensor: platform: efergy app_token: APP_TOKEN utc_offset: UTC_OFFSET monitored_variables: - type: instant_readings - type: budget - type: cost period: day currency: $ ``` **Forecast.io** Fabian 增加了 [Forecast.io](https://forecast.io/) 支持,用于在 Home Assistant 中获取天气预报。你需要一个 API 密钥,免费但需要先[注册](https://developer.forecast.io/register)。要将 Forecast.io 添加到你的安装中,请在 `configuration.yaml` 中加入以下内容: ```yaml # Example configuration.yaml entry sensor: platform: forecast api_key: YOUR_APP_KEY monitored_conditions: - summary - precip_type - precip_intensity - temperature - dew_point - wind_speed - wind_bearing - cloud_cover - humidity - pressure - visibility - ozone ``` --- url: /home-assistant/blog/2015-08-09-mqtt-raspberry-pi-squeezebox-asuswrt-support.md --- # 现已支持 MQTT、Raspberry Pi、Logitech Squeezebox 和 ASUSWRT 路由器 八月发布来了,这次有不少重磅内容。感谢 [@balloob](https://github.com/balloob) 对 Home Assistant 核心进行了一轮深入清理,并提升了测试覆盖率。如果你是开发者,请务必阅读[弃用公告](https://github.com/home-assistant/home-assistant/pull/251)。[@fabaff](https://github.com/fabaff) 也再次完善了各类组件文档。 **MQTT 支持** 本次发布最重要的新功能是 MQTT 协议支持,由 [@fabaff](https://github.com/fabaff) 贡献,并得到 [@balloob](https://github.com/balloob) 协助。现在,任何通过 MQTT 通信的 IoT 设备都可以集成。首个版本支持将 Home Assistant 连接到 Broker(暂不支持 TLS)。组件现可订阅和发布 MQTT 主题,自动化组件也已新增相关支持[MQTT-自动化]。更多信息请参见 [MQTT 组件页面][MQTT-component]。 [MQTT-自动化]: /getting-started/自动化-触发器/#MQTT-触发器 [MQTT-component]: /integrations/MQTT/ ```yaml # Example configuration.yaml entry mqtt: broker: IP_ADDRESS_BROKER # All the other options are optional: port: 1883 keepalive: 60 qos: 0 username: your_username password: your_secret_password ``` **Raspberry Pi GPIO 支持** [@gbarba](https://github.com/gbarba) 贡献了 Raspberry Pi 通用输入输出(GPIO)支持,你可以在 Home Assistant 中把这些引脚当作开关使用。 ```yaml # Example configuration.yaml entry switch: platform: rpi_gpio ports: 11: Fan Office 12: Light Desk ``` **基于 ASUSWRT 的路由器** [@persandstrom](https://github.com/persandstrom) 贡献了基于 ASUSWRT 路由器的在家状态检测支持。 ```yaml # Example configuration.yaml entry device_tracker: platform: asuswrt host: YOUR_ROUTER_IP username: YOUR_ADMIN_USERNAME password: YOUR_ADMIN_PASSWORD ``` **Logitech Squeezebox 媒体播放器支持** [@persandstrom](https://github.com/persandstrom) 还贡献了 Logitech Squeezebox 媒体播放器支持,让你可以直接在 Home Assistant 中控制它。 ```yaml # Example configuration.yaml entry media_player: platform: squeezebox host: 192.168.1.21 port: 9090 username: user password: password ``` **Slack 通知支持** [@jamespcole](https://github.com/jamespcole) 为通知平台贡献了 Slack 支持,你可以将消息发送到任意频道。 ```yaml # Example configuration.yaml entry notify: platform: slack api_key: ABCDEFGHJKLMNOPQRSTUVXYZ default_channel: "#general" ``` **Edimax 智能开关支持** [@rkabadi](https://github.com/rkabadi) 贡献了 Edimax 智能开关集成支持。 ```yaml # Example configuration.yaml entry switch: platform: edimax host: 192.168.1.32 username: YOUR_USERNAME password: YOUR_PASSWORD name: Edimax Smart Plug ``` **RFXtrx 传感器支持** [@danielhiversen](https://github.com/danielhiversen) 贡献了 RFXtrx 传感器支持。该平台支持在 433.92 MHz 频段通信的传感器。 ```yaml # Example configuration.yaml entry sensor: - platform: rfxtrx device: PATH_TO_DEVICE ``` 这里填写你的设备路径,例如 `/dev/serial/by-id/usb-RFXCOM_RFXtrx433_A1Y0NJGR-if00-port0` **TEMPer 温度传感器支持** [@rkabadi](https://github.com/rkabadi) 贡献了 TEMPer 温度传感器支持。 ```yaml # Example configuration.yaml entry sensor: platform: temper ``` --- url: /home-assistant/blog/2015-08-17-verisure-and-modern-tp-link-router-support.md --- --- url: /home-assistant/blog/2015-08-26-laundry-automation-with-moteino-mqtt-and-home-assistant.md --- # Laundry 自动化: insight and 通知 *这是 Home Assistant 用户和贡献者 [Nolan Gilley](https://github.com/nkgilley) 撰写的一篇客座文章。* 在我们家,洗衣这件事已经困扰我们很久了。我们的洗衣机和烘干机都没有蜂鸣提醒,经常会忘记衣服,最后变得有异味还得重洗。于是我决定用一些便宜的电子元件自己监测洗衣机和烘干机,做一个解决方案。 作为 Home Assistant 的重度用户,我觉得它非常适合用来管理界面和通知系统。接下来我只需要一种方法来监测洗衣机和烘干机。我试过用声音传感器,但可靠性不够。最后我选择把加速度计固定在每台设备背面。我还在洗衣机和烘干机门上加了磁簧开关,用来检测门是开还是关。我把加速度计和磁簧开关连接到 [Moteino](https://lowpowerlab.com/moteino/)(一款带 RF 收发器的 Arduino 克隆板)上。Moteino 可以执行逻辑判断设备当前处于什么状态,并把数据无线发送给另一块通过串口连接到树莓派的 Moteino。树莓派读取串口数据后,再通过 MQTT 转发给 Home Assistant 使用。这样非常好,因为我不需要在树莓派上运行 Home Assistant。我可以把 Home Assistant 跑在更快的机器上,再把 [MQTT component](/home-assistant/integrations/MQTT/) 指向我的树莓派。 在每台设备运行时采集了一些加速度计样本数据后,我决定把数据画成图,以便确定设备运行和停止时的合适阈值。我必须这样做,才能得到足够精确的范围,避免烘干机传感器被洗衣机触发,反之亦然。下图展示了连接在洗衣机上的加速度计在 x 方向上的加速度。可以很直观地看出洗衣机何时在运行。我对烘干机的加速度计也用了同样的方法。

显示加速度计数据的图表

接下来就是把所有东西接入 Home Assistant。我可以使用 [MQTT component](/home-assistant/integrations/MQTT/) 读取来自 Moteino 的洗衣机和烘干机状态,并在 Home Assistant 中显示出来。

Home Assistant 中的烘干机和洗衣机状态

然后我写了几个[脚本](/home-assistant/integrations/script/index.md),在洗衣机或烘干机完成一轮后自动运行。这些脚本由 [automation component](/home-assistant/getting-started/automation/index.md) 触发。当洗衣完成时,我会让家里的灯光变红,并通过 [notify me via PushBullet](/home-assistant/integrations/pushbullet.md) 收到通知。等衣物处理完后,另一个脚本会把灯光恢复正常。到目前为止,这套方案非常有帮助,也非常可靠。

左上:磁簧开关。左下:Moteino。右侧:加速度计。

使用的材料: * [Moteino](https://lowpowerlab.com/moteino/) * [2 x Accelerometers](https://www.amazon.com/dp/B008BOPN40) * [2 x Reed 开关](https://www.amazon.com/dp/B01IU7NWMM) * [Home Assistant](/index.md) [Sketch for the Moteino is available here.](https://codebender.cc/sketch:144743) Home Assistant 配置: :::note 这里的自动化和脚本语法使用的是已弃用且不再受支持的格式。 ::: ```yaml mqtt: broker: 192.168.1.100 port: 1883 keepalive: 60 qos: 0 sensor: platform: mqtt name: "Dryer Status" state_topic: "sensor/dryer" unit_of_measurement: "" sensor 2: platform: mqtt name: "Washer Status" state_topic: "sensor/washer" unit_of_measurement: "" automation: alias: "Dryer complete" platform: state state_entity_id: sensor.dryer_status state_from: "Running" state_to: "Complete" execute_service: script.turn_on service_entity_id: script.dryer_complete automation 2: alias: "Dryer emptied" platform: state state_entity_id: sensor.dryer_status state_from: "Complete" state_to: "Empty" execute_service: script.turn_on service_entity_id: script.dryer_cleared script: dryer_complete: alias: "Dryer Complete Script" sequence: - alias: "Pushbullet Notification" execute_service: notify.notify service_data: message: "The dryer has finished its cycle, please empty it!" - alias: "Living Room Lights Red" execute_service: scene.turn_on service_data: entity_id: scene.red - delay: seconds: 1 - alias: "Living Room Lights Off" execute_service: light.turn_off service_data: entity_id: group.living_room - delay: seconds: 1 - alias: "Living Room Lights Red" execute_service: scene.turn_on service_data: entity_id: scene.red dryer_cleared: alias: "Dryer Cleared Script" sequence: - alias: "Living Room Lights Off" execute_service: light.turn_off service_data: entity_id: group.living_room - delay: seconds: 1 - alias: "Living Room Lights Normal" execute_service: scene.turn_on service_data: entity_id: scene.normal ``` 参考资源: * [Inspiration and Help with Arduino code](http://www.instructables.com/id/Uber-Home-automation-w-Arduino-Pi/step13/Washer-Dryer-Smartifier-Water-Leak-传感器/) * [Moteino Code](https://github.com/LowPowerLab/RFM69/) --- url: /home-assistant/blog/2015-08-31-version-7-revamped-ui-and-improved-distribution.md --- # 0.7: Better UI and improved distribution 随着 Home Assistant 用户越来越多,我们开始明显感受到缺少正式发布机制带来的问题。过去我们没有版本号,用户必须通过 Git 检出源码才能开始使用。此外,随着支持设备数量持续增长,所需依赖也越来越多。因此我们决定调整发布方式。从现在开始: * 每次发布都会有版本号,从版本 0.7 开始。这个版本号的选择,表示我们已经发展了一段时间,但还不认为自己已经完全稳定。 * 每次发布都会上传到 PyPi。这将成为唯一受支持的分发方式。 * 安装后,Home Assistant 可通过命令行工具 `hass` 使用。 * 默认配置位置已从当前工作目录下的 `config` 移动到 `~/.homeassistant`(Windows 上是 `%APPDATA%/.homeassistant`)。 * 组件和平台依赖不再安装到当前 Python 环境(无论是否为虚拟环境),而是安装到 `/lib`。 特别感谢 [Ryan Kraus](https://github.com/rmkraus) 促成了这一切。请务必阅读 [the full 博客 post][self],了解如何迁移你现有设置的详细步骤。 [self]: /博客/2015/08/31/版本-7-revamped-ui-and-improved-distribution/#read-more 在 Ryan 处理分发机制的同时,我也一直在努力给 Home Assistant 的界面做一次焕新。我们原来的界面已经不错,但对于拥有大量设备的用户来说,组织方式还不够理想。新界面不再是每个实体一张卡片,而是改为按分组和域来展示卡片。[The demo](/home-assistant/demo/) 也已更新,欢迎体验。

新界面截图

## 迁移到版本 0.7 在这个示例中,假设你有一套旧版 Home Assistant 安装,路径为 `/home/paulus/home-assistant`。 如果你想把现有配置迁移为默认配置: ```bash cp -r /home/paulus/home-assistant ~/.homeassistant ``` 如果你希望把配置放在其他位置,例如 `/home/paulus/home-assistant-config`,则需要在启动时将 Home Assistant 指向该配置文件夹: ```bash hass --config /home/paulus/home-assistant-config ``` ## 新平台 最后同样重要的是:新平台支持! **MQTT 传感器和开关** [@sfam](https://github.com/sfam) 为我们带来了另外两个 MQTT 平台,进一步扩展了我们与 MQTT 的集成:[传感器][MQTT-传感器] 和 [开关][MQTT-开关]。这两个平台都要求 MQTT 组件先连接到 Broker。 [MQTT-传感器]: /integrations/传感器.MQTT/ [MQTT-开关]: /integrations/开关.MQTT/ ```yaml # Example configuration.yaml entry sensor: platform: mqtt name: "MQTT Sensor" state_topic: "home/bedroom/temperature" unit_of_measurement: "°C" switch: platform: mqtt name: "Bedroom Switch" state_topic: "home/bedroom/switch1" command_topic: "home/bedroom/switch1/set" payload_on: "ON" payload_off: "OFF" optimistic: false ``` **Actiontec MI424WR Verizon FIOS 无线路由器** [Nolan](https://github.com/nkgilley) 贡献了对 Actiontec 无线路由器的支持。 ```yaml # Example configuration.yaml entry device_tracker: platform: actiontec host: YOUR_ROUTER_IP username: YOUR_ADMIN_USERNAME password: YOUR_ADMIN_PASSWORD ``` **DHT 温湿度传感器** @MakeMeASandwich 贡献了 DHT 温湿度传感器支持。你可以从 DHT11、DHT22 或 AM2302 设备读取当前温度和湿度。 ```yaml # Example configuration.yaml entry sensor: platform: dht sensor: DHT22 pin: 23 monitored_conditions: - temperature - humidity ``` **Aruba 设备追踪器** [Michael Arnauts](https://github.com/michaelarnauts) 贡献了对 Aruba 无线路由器的支持,用于在家状态检测。 ```yaml # Example configuration.yaml entry device_tracker: platform: aruba host: YOUR_ACCESS_POINT_IP username: YOUR_ADMIN_USERNAME password: YOUR_ADMIN_PASSWORD ``` --- url: /home-assistant/blog/2015-09-11-different-ways-to-use-mqtt-with-home-assistant.md --- # Using MQTT with Home Assistant {::options coderay\_line\_numbers="table" /} 最近 Home Assistant 新增了 [MQTT](https://en.wikipedia.org/wiki/MQTT) 支持。[MQTT component](/home-assistant/integrations/MQTT/) 可以让你实现很多功能。最常见的用法是和你的设备通信。但只要支持 MQTT,Home Assistant 并不关心数据来源,也不局限于真实硬件。这意味着数据无论来自人、网络服务,还是设备,都可以使用。 一个很好的例子是本博客中的 [Laundry automation](/home-assistant/blog/2015/08/26/laundry-automation-with-moteino-MQTT-and-home-assistant/) 文章。 这篇文章会简要介绍一些在 Home Assistant 中使用 MQTT 的其他方式。 ## 手动使用 作为人工交互 Home Assistant 传感器,最简单但不算酷的方法就是手动执行命令。我们来创建一个“心情”传感器。为简化演示,Home Assistant 和 MQTT broker 都运行在同一台主机上。需要添加到 `configuration.yaml` 的配置片段分为两部分:一部分用于 broker,另一部分用于传感器。 ```yaml mqtt: broker: 127.0.0.1 sensor: - platform: mqtt name: "Fabian's Mood" state_topic: "home-assistant/fabian/mood" ``` 重启 Home Assistant 后,“心情”传感器就会出现在前端。有关 MQTT 本身和传感器配置的更多细节,请参考 [MQTT component](/home-assistant/integrations/MQTT/) 或 [MQTT sensor](/home-assistant/integrations/sensor.MQTT/) 文档。 现在我们可以设置心情了。这里使用 `mosquitto` 自带的命令行工具 `mosquitto_pub` 来发送 MQTT 消息。 ```bash mosquitto_pub -h 127.0.0.1 -t "home-assistant/fabian/mood" -m "bad" ```

心情传感器

这是一个很差的示例。实际使用中不要这样做,因为你无法绘制历史数据图表。更好的做法是使用数值。 ## Python MQTT 绑定 上一节确实有点无聊,我知道。桌上有电脑时,没人想手工发 MQTT 消息。如果你买彩票,这一节很适合你;如果不买也可以继续看,因为彩票只是示例 :-)。 这个示例使用 [Paho MQTT Python binding](https://eclipse.org/paho/clients/python/),因为运行 Home Assistant 的主机上通常可以直接使用它。如果你想在另一台机器上运行这个示例,请先确认已安装该绑定(`pip3 install paho-mqtt`)。 第一步是在 `configuration.yaml` 中新增一个 MQTT 传感器。这个传感器命名为“Lottery”,计量单位为“No.”。 ```yaml - platform: mqtt name: "Lottery" state_topic: "home-assistant/lottery/number" unit_of_measurement: "No." ``` 别忘了重启 Home Assistant 以使配置生效。 要“选号”,我们需要 1 到 49 的数字,并在 Home Assistant 前端显示随机结果。下面这段 Python 脚本是另一个从命令行发送 MQTT 消息的简单示例,这次通过循环持续发送。更多信息和示例请查看 [Paho MQTT](https://eclipse.org/paho/clients/python/docs/) 文档。 ```python #!/usr/bin/python3 # import time import random import paho.mqtt.client as mqtt import paho.mqtt.publish as publish broker = '127.0.0.1' state_topic = 'home-assistant/lottery/number' delay = 5 # Send a single message to set the mood publish.single('home-assistant/fabian/mood', 'good', hostname=broker) # Send messages in a loop client = mqtt.Client("ha-client") client.connect(broker) client.loop_start() while True: client.publish(state_topic, random.randrange(0, 50, 1)) time.sleep(delay) ``` 每 5 秒会向 broker 发送一条新数字消息,随后由 Home Assistant 接收。顺便说一句,我现在心情好多了。

彩票传感器

只需几行 Python 和一个 MQTT broker,你就可以创建自己的“智能设备”,或者把你想到的任意信息发送给 Home Assistant。当然这不限于 Python。只要有可用的 MQTT 库,这个设备就可以和 Home Assistant 配合使用。 ## Arduino 如果你想从可发送 MQTT 消息的真实硬件入手,Arduino 平台是一个低成本选择。本节使用 Arduino UNO、以太网扩展板和一个光敏电阻。光敏电阻连接到模拟引脚 0(A0),输出范围为 0 到 1024。

带以太网扩展板和光敏电阻的 Arduino UNO

你需要先在 Arduino IDE 中安装可用的 [MQTT client](http://knolleary.github.io/pubsubclient/)。下面这段 sketch 可以作为起点。请按需修改 IP 地址、MAC 地址和引脚,然后将 sketch 上传到你的 Arduino。 ```c /* This sketch is based on the basic MQTT example by http://knolleary.github.io/pubsubclient/ */ #include #include #include #define DEBUG 1 // Debug output to serial console // Device settings IPAddress deviceIp(192, 168, 0, 43); byte deviceMac[] = { 0xAB, 0xCD, 0xFE, 0xFE, 0xFE, 0xFE }; char* deviceId = "sensor01"; // Name of the sensor char* stateTopic = "home-assistant/sensor01/brightness"; // MQTT topic where values are published int sensorPin = A0; // Pin to which the sensor is connected to char buf[4]; // Buffer to store the sensor value int updateInterval = 1000; // Interval in milliseconds // MQTT server settings IPAddress mqttServer(192, 168, 0, 12); int mqttPort = 1883; EthernetClient ethClient; PubSubClient client(ethClient); void reconnect() { while (!client.connected()) { #if DEBUG Serial.print("Attempting MQTT connection..."); #endif if (client.connect(deviceId)) { #if DEBUG Serial.println("connected"); #endif } else { #if DEBUG Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); #endif delay(5000); } } } void setup() { Serial.begin(57600); client.setServer(mqttServer, mqttPort); Ethernet.begin(deviceMac, deviceIp); delay(1500); } void loop() { if (!client.connected()) { reconnect(); } client.loop(); int sensorValue = analogRead(sensorPin); #if DEBUG Serial.print("Sensor value: "); Serial.println(sensorValue); #endif client.publish(stateTopic, itoa(sensorValue, buf, 10)); delay(updateInterval); } ``` Arduino 会每秒发送一次传感器值。要在 Home Assistant 中使用这些数据,请在 `configuration.yaml` 中再添加一个 MQTT 传感器。 ```yaml - platform: mqtt name: "Brightness" state_topic: "home-assistant/sensor01/brightness" unit_of_measurement: "cd" ``` 重启 Home Assistant 后,就可以看到来自 Arduino 的数值。

亮度传感器

希望这篇文章能给你一些关于 Home Assistant 与 MQTT 结合使用的灵感。如果你正在做包含 Home Assistant 的有趣项目,欢迎告诉我们。 --- url: /home-assistant/blog/2015-09-13-home-assistant-meets-ifttt.md --- # Home Assistant meets IFTTT 今天我们发布 Home Assistant v0.7.2,其中包含由 [@sfam][github-sfam] 带来的全新 [IFTTT][ifttt] 集成支持。IFTTT 的全称是 If This, Then That,它是一个几乎能连接所有网络服务的 Web 服务。把 Home Assistant 加入这个生态后,Home Assistant 就能通过 IFTTT 与这些服务互联。 现在你可以在明天预报多云时禁用灌溉系统,或者在烟雾报警触发时自动发推。 [github-sfam]: https://github.com/sfam [ifttt]: https://ifttt.com

前往 [设置说明](/home-assistant/integrations/ifttt/index.md) 即可开始使用 IFTTT。点击“阅读更多”按钮可查看一些示例配方。 在下面每个示例中,请将 URL 里的 XXX 替换为你正确的主机地址和 API 密码。 ## 不需要时关闭灌溉系统

Maker channel 设置: | Field | Value | | ----- | ----- | | URL | `http://xxx.xxx.xxx.xxx:8123/api/services/switch/turn_off?api_password=xxxxxxxx` | METHOD | POST | CONTENT TYPE | application/json | BODY | { "entity\_id": "开关.irrigation" } ## 重要事件发生时发推

当收到表示烟雾报警已触发的 MQTT 消息时,这个配方会发出一条推文。请将 Maker channel 的事件名设置为 `HA_FIRE_ALARM`,并让 Twitter channel 发出 `value1` 中的消息。 ```yaml # Configuration.yaml entry automation: - alias: "Post a tweet when fire alarm is triggered" trigger: platform: mqtt mqtt_topic: home/alarm/fire mqtt_payload: "on" action: service: ifttt.trigger data: {"event":"HA_FIRE_ALARM", "value1":"The fire alarm just triggered!"} ``` ## 我回家时打开灯光

Maker channel 设置: | Field | Value | | ----- | ----- | | URL | `http://xxx.xxx.xxx.xxx:8123/api/services/light/turn_on?api_password=xxxxxxxx` | METHOD | POST | CONTENT TYPE | application/json | BODY | { "entity\_id": "灯光.kitchen" } ## Home Assistant 有新 PR 时闪烁灯光

Maker channel 设置: | Field | Value | | ----- | ----- | | URL | `http://xxx.xxx.xxx.xxx:8123/api/services/light/turn_on?api_password=xxxxxxxx` | METHOD | POST | CONTENT TYPE | application/json | BODY | { "entity\_id": "group.all\_lights", "flash":"yes" } ## 按下 DO 按钮时触发事件

Maker channel 设置: | Field | Value | | ----- | ----- | | URL | http://xxx.xxx.xxx.xxx:8123/api/events/do\_button\_pressed?api\_password=xxxxxxxx | METHOD | POST | CONTENT TYPE | application/json --- url: /home-assistant/blog/2015-09-18-monitoring-with-glances-and-home-assistant.md --- # 遥控器 Monitoring with Glances 受到一个 [feature requests](https://github.com/home-assistant/home-assistant/issues/310) 的启发,我开始研究可用于监控远程主机的方案。这个功能请求希望能像 [systemmonitor](/home-assistant/integrations/systemmonitor) 传感器监控本地系统那样显示系统信息。后来我觉得,这对没有完整系统监控方案的小型家庭网络会是一个很好的补充。 最基础的问题是如何从远程主机获取数据。从 systemmonitor 传感器使用的 [psutil](https://pypi.python.org/pypi/psutil) 出发,一个现成可用的方案就是 [Glances](https://github.com/nicolargo/glances)。Glances 提供了不错的 curses 界面和一个 [RESTful API](https://github.com/nicolargo/glances/wiki/The-Glances-RESTFULL-JSON-API)。 [Glances 传感器](/home-assistant/integrations/glances.md) 就是通过这个 API 获取所需数据。 在这篇文章中,被监控主机使用的是默认安装的 Fedora 22 Workstation。实际上,只要系统里可用 Glances,不论是本机还是远程主机都可以。稍作调整后,它也能在你的系统上工作,差异主要在软件包和防火墙管理工具上。 首先,除了 Glances 之外还需要一些额外软件包,尤其是 [bottle](http://bottlepy.org/docs/dev/index.html) Web 服务器。我猜你的发行版里也有 Glances;如果没有,请按照这些 [instructions](https://github.com/nicolargo/glances#安装) 安装。 ```bash sudo dnf -y install glances python-bottle ``` Fedora 的防火墙设置比较严格。我们先开放 61208 端口,允许其他主机连接。如果你只监控本机,则不需要这一步。 ```bash sudo firewall-cmd --permanent --add-port=61208/tcp sudo firewall-cmd --reload ``` 启动 `glances`,并观察输出。 ```bash $ glances -w Glances web server started on http://0.0.0.0:61208/ ``` 然后访问 http://IP\_ADRRESS:61208/,你应该能看到 Glances 的 Web 界面。

Glances Web 界面

还可以再检查一次:访问位于 http://IP\_ADRRESS:61208/api/2/mem/used 的 API,并确认它会返回包含内存使用详情的 JSON 响应。如果没问题,就可以继续了。 ```bash $ curl -X GET http://IP_ADDRESS:61208/api/2/mem/used {"used": 203943936} ``` 把 [glances 传感器](/home-assistant/integrations/glances.md) 配置项添加到 `configuration.yaml`,然后重启 Home Assistant。 ```yaml # Example configuration.yaml entry - platform: glances name: NAS host: IP_ADDRESS resources: - 'disk_use_percent' - 'disk_use' - 'disk_free' ``` 如果日志里没有错误,你就会看到新传感器。

Glances 传感器

[Glances](https://github.com/nicolargo/glances) 还有一些可选依赖,可以扩展可提供的信息范围。这意味着你可以获取 RAID 系统、硬盘温度、IP 地址、传感器等更多细节。如果你做了扩展,欢迎提交 [Pull request](https://github.com/home-assistant/home-assistant/pulls);如果你希望在 Home Assistant 前端看到更多信息,也可以提交 [Feature request](https://github.com/home-assistant/home-assistant/issues/new)。 --- url: /home-assistant/blog/2015-09-19-alarm-sonos-and-itunes-support.md --- # Alarms, Sonos and iTunes now supported 这次就像有人把一整罐硬核开发者倒进了我们的 [chat channel](https://discord.gg/c5DvZ4e),于是讨论和贡献都迎来了大爆发。0.7.3 版本亮点包括:Sonos、iTunes、报警组件,以及自动化升级。 更详细的发布说明请查看 [GitHub](https://github.com/home-assistant/home-assistant/releases/tag/0.7.3)。 *迁移说明:`scheduler` 组件已移除,改为使用 `automation` 组件。* **Sonos 支持** Sonos 支持由 [@rhooper](https://github.com/rhooper) 和 [@SEJeff](https://github.com/SEJeff) 添加。Home Assistant 现在可以自动发现你网络中的 Sonos 设备并完成设置。你可以控制 Sonos 播放内容并调整音量。 **iTunes 与 AirPlay 音箱** [@maddox](https://github.com/maddox) 贡献了对 iTunes 和 AirPlay 音箱的控制支持。要使用此功能,你需要在 Mac 上运行 [itunes-api](https://github.com/maddox/itunes-api) 作为中间层。 ```yaml # Example configuration.yaml entry media_player: platform: itunes name: iTunes host: http://192.168.1.50 port: 8181 ``` **自动化** 自动化在这个版本里得到了大量改进。它现在支持条件、多个触发器,以及新的触发器类型。想快速上手,最好的方式是查看新的 [自动化入门](/home-assistant/getting-started/automation/index.md) 页面。 ```yaml # Example of entry in configuration.yaml automation: alias: "Light on in the evening" trigger: - platform: sun event: sunset offset: "-01:00:00" - platform: state entity_id: all state: home condition: - platform: state entity_id: all state: home - platform: time after: "16:00:00" before: "23:00:00" action: service: homeassistant.turn_on target: entity_id: group.living_room ``` **Verisure 报警** 感谢 [@persandstrom](https://github.com/persandstrom) 的支持,我们现在可以在 Home Assistant 中对 Verisure 报警进行布防和撤防。 --- url: /home-assistant/blog/2015-10-05-home-assistant-goes-geo-with-owntracks.md --- # Home Assistant goes geo with OwnTracks 几周过去了,又到了发布新版本的时候:版本 0.7.4。我们非常高兴地宣布,这次带来了全新的 OwnTracks 集成,可在地图上追踪人员位置。地理位置支持包含三个部分: * [OwnTracks platform for the 设备 tracker][platform-owntracks],用于获取设备位置 * 全新的[区域 component][component-区域],用于定义位置区域并支持[触发器 自动化][区域-自动化] * UI 中新增地图来展示这些信息([see it in 动作 in the demo](/home-assistant/demo/)) 我们还新增了一个[入门 section][start-在场],帮助你快速开始。 [platform-owntracks]: /integrations/owntracks [component-区域]: /integrations/区域/ [区域-自动化]: /getting-started/自动化-触发器/#区域-触发器 [start-在场]: /getting-started/在场-detection/

Home Assistant 中的地图,显示两个人和三个区域(home、school、work)

当然,过去三周还有很多其他变化。这里不再写成长文,改为简要列出重点更新: * 传感器: [rest platform](/home-assistant/integrations/rest.md) added ([@fabaff](https://github.com/fabaff)) * 报警 Control 面板: [MQTT platform](/home-assistant/integrations/alarm_control_panel.MQTT/) added ([@sfam](https://github.com/sfam)) * Media Player: [Plex platform](/home-assistant/integrations/plex.md#media-player) added (\[@miniconfig]\(https://github.com/miniconfig, [@adrienbrault](https://github.com/adrienbrault)) * Dev Tools: 服务 can now show description of fields ([@balloob](https://github.com/balloob)) * MQTT: Support for certificates and improved 错误 reporting ([@balloob](https://github.com/balloob)) * 灯光: [limitlessled platform](/home-assistant/integrations/limitlessled.md) extended with white 灯光 support ([@auchter](https://github.com/auchter)) * Fuzzy matching for 场景 ([@pavoni](https://github.com/pavoni)) * 场景 support for media player ([@maddox](https://github.com/maddox)) --- url: /home-assistant/blog/2015-10-11-measure-temperature-with-esp8266-and-report-to-mqtt.md --- # Report the temperature with ESP8266 to MQTT {::options coderay\_line\_numbers="table" /} 我最近接触了 ESP8266,这是一颗仅需 5 美元、内置 WiFi 且兼容 Arduino 的芯片。这意味着你现在可以用更低成本完成各种 DIY 项目。 在这篇教程中,我会带你一步步上手 ESP8266,读取温度和湿度数据,并上报到 MQTT,让 Home Assistant 可以接收这些数据。

最终搭建效果图(额外加了 2 个 LED 做装饰)

Home Assistant 会记录历史数值,并允许你将其用于自动化。

### Components 我这次使用的是 Adafruit 的配件: * [Adafruit HUZZAH ESP8266 Breakout](http://www.adafruit.com/product/2471) ([assembly instructions](https://learn.adafruit.com/adafruit-huzzah-esp8266-breakout/assembly)) * [Adafruit HDC1008 Temperature & Humidity 传感器 Breakout Board](http://www.adafruit.com/product/2635) ([assembly instructions](https://learn.adafruit.com/adafruit-hdc1008-temperature-and-humidity-sensor-breakout/assembly)) * [MQTT server](/home-assistant/integrations/MQTT/#picking-a-broker) *除此之外,你还需要常见的硬件原型工具:面包板、若干导线、电烙铁和焊锡丝、串口 USB 线。* ### Alternatives 这篇文章发布后,HDC1008 已停产。你可以使用下面这些替代方案以及更新后的示例代码: * [DHT22 传感器](https://www.adafruit.com/product/385) and [updated sketch](https://gist.github.com/balloob/1176b6d87c2816bd07919ce6e29a19e9). * [BME280 传感器](https://www.adafruit.com/product/2652) and [updated sketch](https://gist.github.com/mtl010957/9ee85fb404f65e15c440b08c659c0419). ### Connections 在面包板上,将 ESP8266 与 HDC1008 按如下方式连接: | ESP8266 | HDC1008 | | ------- | ------- | | GND | GND | 3V | Vin | 14 | SCL | #2 | SDA *我这里使用的是 `#2` 和 `14`,你也可以在示例代码中自行配置。* ### Preparing your IDE 按照[这些说明](https://github.com/esp8266/Arduino#installing-with-boards-manager)安装并准备 Arduino IDE,以便进行 ESP8266 开发。 安装完成后,打开 Arduino IDE,在菜单中选择 `sketch` -> `include library` -> `manage libraries`,安装以下库: * PubSubClient by Nick 'O Leary * Adafruit HDC1000 ### Sketch 完成上面的步骤后,你就可以开始了。 * 打开 Arduino IDE 并新建一个 sketch(`File` -> `New`) * 将下面的 sketch 复制粘贴到 Arduino IDE * 调整第 6 到 14 行的参数,使其符合你的设置 * 可选:如果你要连接不需要用户名或密码的 MQTT 服务器,请调整第 62 行 * 为了让 ESP8266 接收新 sketch,需要进入上传模式。在 ESP8266 设备上按住 GPIO0 按钮,同时按下 reset 按钮。红色 LED 会半亮,表示已进入上传模式 * 在 Arduino IDE 中按下上传按钮 * 打开串口监视器(`Tools` -> `Serial Monitor`)查看设备输出 这个 sketch 会连接到你的 WiFi 网络和 MQTT broker。它每秒读取一次传感器的温度与湿度数据;当与上次上报值的差值大于 1 时,就会发送到 MQTT 服务器。发送到 MQTT broker 的消息会将 retain 设为 `True`,这意味着任何订阅该 MQTT 主题的客户端都会自动收到最近一次上报的数据。 ```cpp #include #include #include #include #define wifi_ssid "YOUR WIFI SSID" #define wifi_password "WIFI PASSWORD" #define mqtt_server "YOUR_MQTT_SERVER_HOST" #define mqtt_user "your_username" #define mqtt_password "your_password" #define humidity_topic "sensor/humidity" #define temperature_topic "sensor/temperature" WiFiClient espClient; PubSubClient client(espClient); Adafruit_HDC1000 hdc = Adafruit_HDC1000(); void setup() { Serial.begin(115200); setup_wifi(); client.setServer(mqtt_server, 1883); // Set SDA and SDL ports Wire.begin(2, 14); // Start sensor if (!hdc.begin()) { Serial.println("Couldn't find sensor!"); while (1); } } void setup_wifi() { delay(10); // We start by connecting to a WiFi network Serial.println(); Serial.print("Connecting to "); Serial.println(wifi_ssid); WiFi.begin(wifi_ssid, wifi_password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } void reconnect() { // Loop until we're reconnected while (!client.connected()) { Serial.print("Attempting MQTT connection..."); // Attempt to connect // If you do not want to use a username and password, change next line to // if (client.connect("ESP8266Client")) { if (client.connect("ESP8266Client", mqtt_user, mqtt_password)) { Serial.println("connected"); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); // Wait 5 seconds before retrying delay(5000); } } } bool checkBound(float newValue, float prevValue, float maxDiff) { return !isnan(newValue) && (newValue < prevValue - maxDiff || newValue > prevValue + maxDiff); } long lastMsg = 0; float temp = 0.0; float hum = 0.0; float diff = 1.0; void loop() { if (!client.connected()) { reconnect(); } client.loop(); long now = millis(); if (now - lastMsg > 1000) { lastMsg = now; float newTemp = hdc.readTemperature(); float newHum = hdc.readHumidity(); if (checkBound(newTemp, temp, diff)) { temp = newTemp; Serial.print("New temperature:"); Serial.println(String(temp).c_str()); client.publish(temperature_topic, String(temp).c_str(), true); } if (checkBound(newHum, hum, diff)) { hum = newHum; Serial.print("New humidity:"); Serial.println(String(hum).c_str()); client.publish(humidity_topic, String(hum).c_str(), true); } } } ``` ### Configuring Home Assistant 最后一步是把传感器数值接入 Home Assistant。你只需要让 Home Assistant 连接到 MQTT broker,并订阅对应的传感器主题。 ```yaml mqtt: broker: YOUR_MQTT_SERVER_HOST username: your_username password: your_password sensor: platform: mqtt name: "Temperature" state_topic: "sensor/temperature" qos: 0 unit_of_measurement: "ºC" sensor 2: platform: mqtt name: "Humidity" state_topic: "sensor/humidity" qos: 0 unit_of_measurement: "%" ``` --- url: /home-assistant/blog/2015-10-11-rfxtrx-blinkstick-and-snmp-support.md --- # 0.7.5: Blinkstick, SNMP, Telegram 我们发现了两个足够烦人的问题,因此决定发布 0.7.5: * Home Assistant 安装包中未包含 CloudMQTT 证书 * 核心中的一个 bug 会在某些平台被重复加载时引发问题 这次发布也包含了一些新平台支持(因为新集成真的一直在来!): * 灯光: [blinkstick platform](/home-assistant/integrations/blinksticklight.md) added ([@alanbowman](https://github.com/alanbowman)) * 设备 Tracker: [SNMP platform](/home-assistant/integrations/snmp.md) added ([@tomduijf](https://github.com/tomduijf)) * 灯光: [rfxtrx platform](/home-assistant/integrations/rfxtrx.md#灯光) added ([@badele](https://github.com/badele)) * 开关: [rfxtrx platform](/home-assistant/integrations/rfxtrx.md#开关) added ([@badele](https://github.com/badele)) * 通知: [telegram platform](/home-assistant/integrations/telegram.md) added ([@fabaff](https://github.com/fabaff)) 此外,[@maddox](https://github.com/maddox) 扩展了媒体播放器功能,支持 `play media` 命令,该功能已在 [iTunes platform](/home-assistant/integrations/itunes.md) 中实现。 --- url: /home-assistant/blog/2015-10-26-firetv-and-radiotherm-now-supported.md --- # 0.7.6: Amazon FireTV, Radiotherm thermostats 经过两周的努力,我很高兴宣布 Home Assistant v0.7.6 正式发布。本次发布主要聚焦于 bug、测试覆盖率和文档,而且这三方面都超出预期。我们修复了大量问题,[测试覆盖率提升到 85%](https://coveralls.io/builds/3946399),同时也感谢 [@fabaff](https://github.com/fabaff) 和我一起完成了网站[组件版块](/home-assistant/integrations/index.md)的全面改版。 #### Changes * 设备 tracker: Newer [TP-Link routers](/home-assistant/integrations/tplink.md) now supported ([@mKeRix](https://github.com/mKeRix)) * 报警 Control 面板: [Manual 报警](/home-assistant/integrations/manual.md) added ([@sfam](https://github.com/sfam)) * Thermostat: [Radiotherm](/home-assistant/integrations/radiotherm/index.md) now supported ([@toddeye](https://github.com/toddeye)) * Media Player: [Amazon FireTV](/home-assistant/integrations/androidtv.md) now supported ([@happyleavesaoc](https://github.com/happyleavesaoc)) * 设备 Tracker: [Geofancy](/home-assistant/integrations/locative.md) now supported (@wind-rider) * New component [Shell Command](/home-assistant/integrations/shell_command/index.md) can expose shell commands as 服务 ([@balloob](https://github.com/balloob)) * [脚本](/home-assistant/integrations/script/index.md) can now be customized using `customize` key in `configuration.yaml` ([@balloob](https://github.com/balloob)) * 灯光: [Hyperion](/home-assistant/integrations/hyperion.md) now supported (@MakeMeASandwich) * 传感器: [aRest](/home-assistant/integrations/arest.md#sensor) can now also read out pins ([@balloob](https://github.com/balloob)) * 传感器: [Forecast.io](/home-assistant/integrations/darksky) now supports specifying units in `configuration.yaml` ([@balloob](https://github.com/balloob)) * Thermostat: Heat Control has been completely rewritten ([@balloob](https://github.com/balloob)) * 开关: [Rest](/home-assistant/integrations/switch.rest/index.md) now supported ([@bachp](https://github.com/bachp)) * Media Player: [Plex](/home-assistant/integrations/plex.md#media-player) can now be auto discovered and 配置 itself ([@tomduijf](https://github.com/tomduijf)) * [Downloader](/home-assistant/integrations/downloader/index.md) will now treat relative paths based on config dir ([@tomduijf](https://github.com/tomduijf)) * Line Charts will use interpolation for 传感器 data and show current and target temperature for thermostats ([@balloob](https://github.com/balloob)) * 设备 Tracker: [OpenWRT via ubus](/home-assistant/integrations/ubus.md) now supported ([@krzynio](https://github.com/krzynio)) #### Backward-incompatible changes As part of this 发布 we did some cleanup which introduced backwards incompatible changes: **Heat Control thermostat no longer includes scheduling features.** This feature has been removed completely. Use the [automation component](/home-assistant/getting-started/automation/index.md) instead to control target temperature. **Config changed for calling a 服务 from a 脚本.** `execute_service:` has been replaced with `service:`. See [component page](/home-assistant/integrations/script/index.md) for example. The old method will continue working for some time. **场景 can no longer be turned off.** It is no longer possible to turn a 场景 off after it has been activated. The way it worked was unpredictable and causes a lot of confusion. **Downloader treats relative paths now relative to the config dir instead of the current working dir.** This makes more sense as most people run Home Assistant as a daemon --- url: /home-assistant/blog/2015-11-16-zwave-switches-lights-and-honeywell-thermostats-now-supported.md --- # 0.8: Honeywell Thermostats, Orvibo 开关 and Z-Wave 开关 and 灯光 我们一直在努力准备这个最新发布。本次发布的一大亮点,是在前端引入了一套扩展图标集(感谢 [@happyleavesaoc] 提供创意和原型)。要开始自定义,请从 [Material Design Icons] 中选择任意图标,在名称前加上 `mdi:`,然后将其放入 `configuration.yaml` 中的 `customize` 部分: ```yaml homeassistant: customize: switch.ac: icon: "mdi:air-conditioner" ``` #### Backward-incompatible changes * Any existing 区域 icon will have to be replaced with one from [Material Design Icons]. * LimitlessLED 灯光 服务 require colors to be specified in RGB instead of XY. #### Changes * Thermostat: [Honeywell](/home-assistant/integrations/honeywell/index.md) now supported ([@sander76]) * 开关: [Orvibo](/home-assistant/integrations/orvibo.md) now supported ([@happyleavesaoc]) * 摄像头: [mjpeg 摄像头's](/home-assistant/integrations/mjpeg.md) now supported ([@ryanturner]) * 通知: Pushetta now supported ([@fabaff]) * 灯光: [MQTT](/home-assistant/integrations/light.mqtt/index.md) now supported ([@hexxter]) * 灯光: [Z-Wave](/home-assistant/integrations/zwave/) now supported ([@leoc]) * 开关: [Z-Wave](/home-assistant/integrations/zwave/) now supported ([@leoc]) * New component [logger](/home-assistant/integrations/logger/index.md) allows filtering logged data ([@badele]) * New component [updater](/home-assistant/integrations/updater/) will 通知 用户 if an 更新 for Home Assistant is available ([@rmkraus]) * 通知: [PushBullet](/home-assistant/integrations/pushbullet.md) now allows targeting contacts/channels/specific 设备 ([@tomduijf]) * 灯光: Allow controlling color temperature ([@tomduijf]) * 前端: about page added ([@balloob]) * 开关 RGB as the color unit used in 灯光 component ([@balloob]) * Re-安装 platform and component dependencies after a Home Assistant 版本 升级 ([@balloob]) [Material Design Icons]: https://pictogrammers.com/library/mdi/ [@sander76]: https://github.com/sander76 [@happyleavesaoc]: https://github.com/happyleavesaoc [@ryanturner]: https://github.com/ryanturner [@fabaff]: https://github.com/fabaff [@hexxter]: https://github.com/hexxter [@leoc]: https://github.com/leoc [@badele]: https://github.com/badele [@rmkraus]: https://github.com/rmkraus [@tomduijf]: https://github.com/tomduijf [@balloob]: https://github.com/balloob --- url: /home-assistant/blog/2015-11-22-survey-november-2015.md --- # 2015 年 11 月调查 大约一周前,我们发起了第一次调查。现在已经有 30 人参与。若你也参与了,非常感谢。我们认为这个时间点已经足以得到一些“仅具部分代表性”的数据。很难准确判断目前有多少 Home Assistant 用户。当前我们的 [Discord 聊天服务器](https://discord.gg/c5DvZ4e) 有 215 名成员,而上周 [PyPI](https://pypi.python.org/pypi/homeassistant/) 统计到 5063 次下载。 这次调查的目标,是匿名收集一些关于 Home Assistant 各部分使用情况的数据,以及少量运行环境信息。 得益于 Python,用户可以在最主流的 Linux 发行版上运行 Home Assistant,也可以在 OS X 和 Microsoft Windows 等其他操作系统上运行。有四分之一的操作系统信息未知,这让我们推测,Home Assistant 今天应该可以在大多数常见操作系统上运行。我们也希望 \*BSD 用户同样玩得开心。硬件平台方面,x86\_64 和 ARM 看起来是最常见的选择。 当然,大多数用户都在使用 [自动化](/home-assistant/getting-started/automation/index.md) 组件,否则使用 Home Assistant 的意义就不大了。[sun](/home-assistant/integrations/sun/index.md) 组件的使用率也很高。我们希望这不是因为它默认就会启用。 [报警控制面板](/home-assistant/integrations/alarm_control_panel/index.md) 和 [摄像头组件](/home-assistant/integrations/camera/index.md) 大约都被三分之一的调查参与者使用。可以说它们目前仍偏小众,但随着更多人发现可以用 Home Assistant 搭建报警系统,它们会越来越受欢迎。 [Philips Hue](/home-assistant/integrations/hue.md) 是灯光类别的“赢家”,紧随其后的是 [MQTT 灯光](/home-assistant/integrations/light.mqtt/index.md)。[Google Cast](/home-assistant/integrations/cast.md) 和 [Plex](/home-assistant/integrations/plex.md#media-player) 是最受欢迎的媒体播放器平台。[Pushbullet](/home-assistant/integrations/pushbullet.md) 则远远领先,成为使用最多的 [通知平台](/home-assistant/integrations/notify/index.md)。如果你有关注最近对该平台的改进,这个结果并不意外。 有意思的是,大多数传感器、开关和恒温器平台都有人在使用。很多人似乎对 [天气预报传感器](/home-assistant/integrations/darksky) 提供的天气数据很感兴趣。MQTT 传感器和开关几乎部署在 50% 的 Home Assistant 安装中。

Home Assistant 发布版本

操作系统

硬件平台

组件

报警控制面板和摄像头

设备追踪器

灯光

媒体播放器

通知

传感器

开关

恒温器

结论是,[MQTT](http://MQTT.org/) 在几乎每个类别里都很流行,从报警控制面板、通过 [owntracks](http://owntracks.org/) 进行在场检测,到传感器和开关,现在甚至在灯光领域也是如此。 至于这些数据该如何解读,就留给你自己判断了。再次感谢你参与这次调查。 --- url: /home-assistant/blog/2015-12-06-community-highlights.md --- # Community Highlights 我们会不时发现一些值得和 Home Assistant 社区伙伴分享的内容。以下是上周的一些有趣内容: 首先是 [Let's Encrypt](https://letsencrypt.org/) 的公开测试版。Let's Encrypt 是一个全新的证书颁发机构,免费、自动化且开源。这意味着你现在可以非常轻松地在外出时保护与 Home Assistant 的连接安全。W1ll1am23 还写了一篇[入门指南](https://community.home-assistant.io/t/homeassistant-nginx-ssl-proxy-设置/53)。 接下来是一个展示大家如何用 Home Assistant 玩出花样的例子:这是 miniconfig 通过 Amazon Echo 与 Home Assistant 对话!
最后但同样重要的是,Midwestern Mac 做了一份面向树莓派的 [microSD 卡性能对比](http://www.midwesternmac.com/blogs/jeff-geerling/raspberry-pi-microsd-卡片)。如果你在使用 Pi,一定值得看看! --- url: /home-assistant/blog/2015-12-06-locks-rollershutters-binary-sensors-and-influxdb-support.md --- # 0.9: Rollershutters, 门锁, binary 传感器 and InfluxDB 过去几周里,我们成功打磨出了一个不错的 Home Assistant 新版本带给大家! * New [门锁 component] including [Wink][门锁.wink] support ([@miniconfig]) * New [二元sensor component] including [aRest][binary_sensor.arest] and [MQTT][binary_sensor.MQTT] support ([@fabaff]) * New rollershutter component including MQTT support ([@sfam]) * New [InfluxDB component] to store data in InfluxDB ([@fabaff]) * Thermostat: [Ecobee] now supported ([@nkgilley]) * Thermostat: [Homematic] now supported ([@goir]) * Support for [parsing JSON values] received over MQTT ([@mcdeck]) * Bunch of bug fixes and optimizations 要更新,请运行 `pip3 install --upgrade homeassistant`。 [门锁 component]: /integrations/门锁/ [门锁.wink]: /integrations/wink#门锁 [二元sensor component]: /integrations/binary_sensor/ [binary_sensor.arest]: /integrations/arest#binary-传感器 [binary_sensor.MQTT]: /integrations/binary_sensor.MQTT/ [InfluxDB component]: /integrations/influxdb/ [Ecobee]: /integrations/ecobee/#thermostat [Homematic]: /integrations/homematic/ [parsing JSON values]: /integrations/MQTT/#processing-json [@miniconfig]: https://github.com/miniconfig [@fabaff]: https://github.com/fabaff [@sfam]: https://github.com/sfam [@fabaff]: https://github.com/fabaff [@nkgilley]: https://github.com/nkgilley [@mcdeck]: https://github.com/mcdeck [@goir]: https://github.com/goir

--- url: /home-assistant/blog/2015-12-07-influxdb-and-grafana.md --- # InfluxDB and Grafana [InfluxDB](https://influxdb.com/) 数据库是一种所谓的时间序列数据库,主要用于存储传感器数据和实时分析数据。 `influxdb` 组件可以将 Home Assistant 中所有状态变化传输到外部 [InfluxDB](https://influxdb.com/) 数据库。 第一步是安装 InfluxDB 软件包。如果你不是在 Fedora 上运行,请查看[安装](https://influxdb.com/docs/v0.9/introduction/安装.html)章节了解更多细节。 ```bash sudo dnf -y install http://influxdb.s3.amazonaws.com/influxdb-0.9.5.1-1.x86_64.rpm ``` 启动 InfluxDB 服务。 ```bash sudo systemctl start influxdb ``` 如果一切顺利,你应该可以通过 `http://localhost:8083/` 访问数据库的 Web 界面。通过 Web 界面或命令行工具 `influx` 创建一个名为 `home_assistant` 的数据库,供 Home Assistant 使用。

InfluxDB Web 前端

```bash $ influx Visit https://enterprise.influxdata.com to register for updates, InfluxDB server management, and monitoring. Connected to http://localhost:8086 version 0.9.5.1 InfluxDB shell 0.9.5.1 > CREATE DATABASE home_assistant ``` 可选步骤是创建一个用户。如果你要这样做,请记得在下一步中调整配置(添加 `username` 和 `password`)。 ```bash > CREATE USER "home-assistant" WITH PASSWORD 'password' ``` 要在你的安装中使用 `influxdb` 组件,请在 `configuration.yaml` 文件中添加以下内容: ```yaml influxdb: host: 127.0.0.1 ``` 重启 Home Assistant 后,你应该会看到 InfluxDB 数据库开始写入数据。用于查询数据库的[语法](https://influxdb.com/docs/v0.9/query_language/index.html)与 SQL 类似。 ```bash $ influx [...] > USE home_assistant Using database home_assistant > SELECT * FROM binary_sensor name: binary_sensor ------------------- time domain entity_id value 1449496577000000000 binary_sensor bathroom_door 0 1449496577000000000 binary_sensor bathroom_window 0 1449496577000000000 binary_sensor basement_door 0 1449496577000000000 binary_sensor basement_window 0 1449496684000000000 binary_sensor bathroom_window 1 [...] ``` [Grafana](http://grafana.org/) 是一个仪表盘工具,可以从包括 InfluxDB 在内的不同数据源创建图表。安装过程很简单,针对不同配置的详细步骤可以在 [Grafana 安装](http://docs.grafana.org/installation/)页面找到。对于较新的 Fedora 系统: ```bash sudo dnf -y install https://grafanarel.s3.amazonaws.com/builds/grafana-2.5.0-1.x86_64.rpm ``` 启动 Grafana 服务器。 ```bash sudo systemctl daemon-reload sudo systemctl start grafana-server sudo systemctl status grafana-server ``` 访问 `http://localhost:3000/login`,使用用户名 `admin` 和密码 `admin` 登录。然后按照 [InfluxDB 设置说明](http://docs.grafana.org/datasources/influxdb/) 继续操作。 现在你就可以开始创建仪表盘和图表了。图表的数据获取方式有多种选择。下面的图像展示的是温度传感器的设置截图。

Grafana 设置

如果图表没有显示在仪表盘中,你需要调整右上角的时间范围。图表是根据 Home Assistant 记录的所有状态变化生成的。

Grafana 温度图表

--- url: /home-assistant/blog/2015-12-10-activating-tasker-tasks-from-home-assistant-using-command-line-switches.md --- # Activating Tasker tasks from Home Assistant using command line 开关 在这篇教程中,我会说明如何通过 Home Assistant 的命令行开关触发 Tasker 任务。我们会设置一个开关,当你切换它时,你的 Android 设备会说出 "On" 或 "Off"。 你也可以改用自动化组件来实现,比如当你把家切换到睡眠模式时,让 Android 设备自动打开 Google Play Books 或 Kindle 应用并调暗灯光,不过这篇教程重点讲的是开关方式。 ### AutoRemote URL 首先,你需要在 Android 设备上安装 [Tasker](https://play.google.com/store/apps/details?id=net.dinglisch.android.taskerm) 和 [AutoRemote](https://play.google.com/store/apps/details?id=com.joaomgcd.autoremote),然后启动 AutoRemote。你会在二维码上方看到一个 URL,用浏览器打开后会看到一个类似下面的页面。

现在在 `Message` 输入框中填入 `SayOn`,右侧会出现一个包含 URL 的框,这就是我们稍后在 Python 脚本中要用到的内容,先保存下来。再重复一次这一步,但把 `SayOn` 改成 `SayOff`。接着选择 `Send message now!` 按钮来测试命令是否能发送到 Android 设备;如果成功,你会在屏幕底部看到类似下面的 toast 消息。

### Tasker 设置 打开 Tasker,确认你在 `PROFILES` 标签页,然后选择加号图标创建一个新的 profile。依次选择 `Event` -> `Plugin` -> `AutoRemote` -> `AutoRemote`,再选择铅笔图标来配置 AutoRemote 事件。选择 `Message Filter` 并输入 `SayOn`,然后返回,直到系统提示你选择任务。选择 `New task`,下一个字段保持为空,再选择勾选图标。 接下来配置任务:选择加号图标添加动作。选择 `Alert` -> `Say` 添加 Say 动作。在文本框中输入 `On`,然后返回测试任务。确认媒体音量已开启后选择播放图标,你应该会听到设备说出 "On"。

现在你可以回到 Tasker 主界面再创建一个 profile,这次把 `SayOn` 改成 `SayOff`,并把 `On` 改成 `Off`。完成后回到主界面,选择顶部菜单按钮,然后依次选择 `Exit` 和 `Save first`,确保所有内容都正确保存。 ### Python 脚本 现在来设置脚本:新建一个 Python 脚本,命名为 `On.py`,然后输入以下代码: ```python import requests requests.get('[URL]') ``` 填入你的 "On" URL 并保存。再创建另一个脚本,这次命名为 `Off.py`,并填入你的 "Off" URL。 ### Home Assistant 配置 在 Home Assistant 配置中添加一个命令行开关: ```yaml switch: platform: command_switch switches: tasker_say: oncmd: python "[LocationOfOnScript]" offcmd: python "[LocationOfOffScript]" ``` 现在启动 Home Assistant,当你切换刚创建的开关时,Android 设备就会回应 "On" 或 "Off"。:-) --- url: /home-assistant/blog/2015-12-12-philips-hue-blocks-3rd-party-bulbs.md --- # \[Update: decision reversed!] Philips Hue blocks 3rd party 灯光 **更新 Dec 16**:好消息!Philips 已决定[撤回该决定][philips-reverse],并正在开发软件更新,以再次支持第三方灯泡。

Philips Hue 常见问题中关于撤回该决定的条目。

*原文如下:* Philips Hue 是最早让智能灯泡进入主流市场的品牌之一。它们基于 Zigbee 的网关非常稳定,几乎不会崩溃,API 也很出色,还能兼容其他 Zigbee 灯泡。虽然价格偏高,但在此之前,这个平台一直物有所值。 昨天,[/r/homeautomation][reddit-hue] 上的一则帖子提到,Philips Hue 现在会屏蔽除自家灯泡和 "friends of Hue" 灯泡外的所有产品。我已在 Philips Hue 常见问题中确认了这一点(更新 Dec 14:他们已删除这些条目 - [镜像在此][philips-hue-常见问题-mirror]):

Philips Hue 常见问题中关于第三方灯泡的条目。

这意味着在你将 Hue 网关更新到最新版本后: * 目前你仍可以继续使用已配对的第三方灯泡 * 你无法再配对新的第三方灯泡 * 如果你因某些原因需要重新配对现有第三方灯泡,就会遇到问题 * 重置网关会强制你重新配对所有灯泡 如果你拥有 Philips Hue 网关并在使用第三方灯泡,而你又希望未来还能配对新的第三方灯泡,请务必不要升级网关。但也要意识到,这只是暂时规避问题。 我看到有人提到重置网关会强制进行软件升级,但我尚未证实这一点,所以你也要对此保持警惕。 我将不再建议别人购买 Philips Hue 生态产品。 [philips-reverse]: http://www.开发者.meethue.com/docs/friends-hue-更新 [reddit-hue]: https://www.reddit.com/r/homeautomation/comments/3wet8h/fyi_the_hue_hub_is_now_blocking_third_party/ [philips-hue-常见问题-mirror]: /images/blog/2015-12-philips-hue-3rd-party/mirror.png --- url: /home-assistant/blog/2015-12-13-setup-encryption-using-lets-encrypt.md --- # Set up encryption using Let's Encrypt :::note 这篇博客文章中的说明已过时。请查看新说明。 ::: 将 Home Assistant 实例暴露到外网一直都不容易。你需要在路由器上设置端口转发,并且通常还要添加动态 DNS 服务,以应对运营商变更你的公网 IP。完成这些后,你就可以在任意地点使用 Home Assistant,但这里有一个重大隐患:没有加密。 本教程将带你一步步为 IP 设置动态 DNS,并通过 [DuckDNS] 和 [Let's Encrypt] 免费建立受信任的加密连接。

**更新于 2016-06-18** ### Requirements 本教程中 DuckDNS 部分没有特殊要求,但运行 Let's Encrypt 客户端目前需要满足以下条件。 * 可直接连接互联网,或具备路由器管理权限以设置端口转发 * 一台运行类 Unix 系统并包含 Python 2.6 或 2.7 的设备(也可使用 Docker) * Root 权限,用于写入默认配置、日志和库目录,并绑定 80 端口 ### DuckDNS 第一步是设置 [DuckDNS]。这是一个免费的动态 DNS 服务,你可以用它申请一个指向家庭网络的 DuckDNS.org 子域名。动态 DNS 服务的工作方式是让家里的计算机每 5 分钟向 DuckDNS.org 报告一次当前 IP,这样 DuckDNS 就能确保你的域名始终指向正确地址。 在本示例中,我们假设域名是 hass-example.duckdns.org。 首先需要申请并设置域名。访问 [DuckDNS],使用任意受支持的登录方式登录后添加域名。然后查看它们的[安装说明][duckdns-安装]来完成 DuckDNS 安装。如果你使用的是树莓派,请在 "Operating Systems" 分类中查看 "Pi"。 ### Let's Encrypt [Let's Encrypt] 是一个免费、自动化、开放的证书颁发机构(CA)。我们将使用它获取证书,以加密与 Home Assistant 的连接。 如果通过域名验证挑战,Let's Encrypt 会为你签发一个免费的 90 天证书。域名验证是通过让 Let's Encrypt 能够访问你域名下的特定数据来完成的([官方解释更详细][letsencrypt-technology])。 假设你的家庭网络位于路由器后方,首先要做的是将路由器端口转发到运行 Let's Encrypt 的计算机。对于 Let's Encrypt 设置,我们需要将外部端口 `80` 转发到内部端口 `80`(HTTP 连接)。你可以在路由器管理界面中完成此设置([按路由器型号提供端口转发说明的网站][port-forward])。每次向 Let's Encrypt 申请新证书时都必须启用该端口转发,通常每三个月一次。如果你平时没有应用监听 `80` 端口,一般可以长期保持该端口开放,这样续期会更方便。 现在你已经可以安装并运行向 Let's Encrypt 申请证书的客户端。下面示例将使用跨平台脚本安装并运行 Let's Encrypt 的 [certbot][certbot] 客户端。如果你的操作系统有 certbot 软件包,建议优先安装软件包,而不是使用跨平台脚本。更多信息请阅读 [docs][certbot]。此外,还有其他客户端可提供更多自定义选项,可查看 Let's Encrypt 的[客户端选项页面][letsencrypt-clients]。 ```bash $ mkdir certbot $ cd certbot/ $ wget https://dl.eff.org/certbot-auto $ chmod a+x certbot-auto $ ./certbot-auto certonly --standalone \ --standalone-supported-challenges http-01 \ --email your@email.address \ -d hass-example.duckdns.org ``` 如果你使用 Docker,请运行以下命令生成所需密钥: ```bash sudo mkdir /etc/letsencrypt /var/lib/letsencrypt sudo docker run -it --rm -p 80:80 --name certbot \ -v "/etc/letsencrypt:/etc/letsencrypt" \ -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \ quay.io/letsencrypt/letsencrypt:latest certonly \ --standalone --standalone-supported-challenges http-01 \ --email your@email.address -d hass-example.duckdns.org ``` 无论使用哪种方法,证书都会生成并放在目录 `/etc/letsencrypt/live/hass-example.duckdns.org` 中。由于有效期只有 90 天,你需要每 90 天重复一次。可以使用一条专门命令来简化证书续期: ```bash ./certbot-auto renew --quiet --no-self-upgrade --standalone \ --standalone-supported-challenges http-01 ``` ### Home Assistant 在更新 Home Assistant 配置之前,我们需要把端口 `443`(HTTPS 连接)转发到运行 Home Assistant 的计算机上的端口 `8123`。和之前设置端口 `80` 一样,在路由器配置中完成即可。 最后一步是让 Home Assistant 使用已生成的证书。在此之前,请确保运行 Home Assistant 的用户对证书所在文件夹有读取权限。 ```yaml http: api_password: YOUR_SECRET_PASSWORD ssl_certificate: /etc/letsencrypt/live/hass-example.duckdns.org/fullchain.pem ssl_key: /etc/letsencrypt/live/hass-example.duckdns.org/privkey.pem ``` 现在你可以访问 `https://hass-example.duckdns.org`,享受加密连接了! *特别感谢 Fabian Affolter 在本文中提供的帮助和反馈。* [DuckDNS]: https://duckdns.org [duckdns-安装]: https://www.duckdns.org/安装.jsp [Let's Encrypt]: https://letsencrypt.org [letsencrypt-technology]: https://letsencrypt.org/how-it-works/ [letsencrypt-clients]: https://letsencrypt.org/docs/client-options/ [port-forward]: http://portforward.com [certbot]: https://certbot.eff.org/ --- url: /home-assistant/blog/2015-12-20-amazon-echo-icloud-and-templates.md --- # 0.10: Amazon Echo, iCloud, Dweet.io, Twitch and templating support! 好了,Home Assistant 0.10 来了。这次有很多令人兴奋的变化,不过遗憾的是,我们也引入了不少向后不兼容的改动。特别感谢 Philip Lundrigan ([@philipbl]),他在推动迁移、让更多平台转向使用模板方面投入了大量精力。
* 设备 tracker: [iCloud] platform added ([@xorso], [@kevinpanaro]) * 前端: Improved caching using 服务 workers if served over SSL ([@balloob]) * 传感器: [Twitch] platform added ([@happyleavesaoc]) * [模板] support ([@balloob], [@philipbl], [@fabaff]) * Thermostat: [Heatmiser] platform added ([@andylockran]) * 传感器: [Dweet.io] platform added ([@fabaff]) * [Alexa/Amazon echo] component added ([@balloob]) * 设备 Tracker: [FritzBox] platform added ([@deisi], [@caiuspb]) * 传感器: [Wink] now supports the Egg minders ([@w1ll1am23]) * 传感器: [ELIQ Online] platform added ([@molobrakos]) * 二元sensor: [REST] platform added ([@fabaff]) * 传感器: [Torque (OBD2)] platform added ([@happyleavesaoc]) [iCloud]: /integrations/icloud [Twitch]: /integrations/twitch [模板]: /topics/templating/ [Heatmiser]: /integrations/heatmiser/ [Dweet.io]: /integrations/dweet#传感器 [Alexa/Amazon echo]: /integrations/alexa/ [FritzBox]: /integrations/fritz [Wink]: /integrations/wink#传感器 [ELIQ Online]: /integrations/eliqonline [REST]: /integrations/binary_sensor.rest/ [Torque (OBD2)]: /integrations/torque [@andylockran]: https://github.com/andylockran [@balloob]: https://github.com/balloob [@caiuspb]: https://github.com/caiuspb [@deisi]: https://github.com/deisi [@fabaff]: https://github.com/fabaff [@happyleavesaoc]: https://github.com/happyleavesaoc [@kevinpanaro]: https://github.com/kevinpanaro [@molobrakos]: https://github.com/molobrakos [@philipbl]: https://github.com/philipbl [@w1ll1am23]: https://github.com/w1ll1am23 [@xorso]: https://github.com/xorso ### 模板 这个发布引入了模板功能。你可以在数据被处理前先解析它,或者基于 Home Assistant 内部数据动态生成通知消息。通知组件和新的 Alexa/Amazon Echo 组件都使用了新的模板功能来渲染响应。我们还在应用的开发者工具区域新增了模板编辑器,这样你可以即时验证模板是否正常工作。 ```text The temperature at home is . ``` 更多信息和示例可以在[模板文档][模板]中找到。 ### Backward-incompatible changes 模板 will now be the only way to extract data from 'raw' sources like REST, CommandSensor or MQTT. This will replace any specific option that used to do this before. This means that `precision`, `factor`, `attribute` or `json_path` etc will no longer work. Affected components and platforms: * 传感器: [arest][传感器.arest] * 传感器: [command\_sensor][传感器.command] * 传感器: [rest][传感器.rest] * 传感器: [MQTT][传感器.MQTT] * 开关: [MQTT][开关.MQTT] * rollershutter: MQTT * 灯光: [MQTT][灯光.MQTT] * binary\_sensor: [MQTT][binary_sensor.MQTT] * 自动化: [numeric\_state][自动化-numeric-状态] [传感器.arest]: /integrations/arest#传感器 [传感器.command]: /integrations/传感器.command_line/ [传感器.rest]: /integrations/rest [传感器.MQTT]: /integrations/传感器.MQTT/ [开关.MQTT]: /integrations/开关.MQTT/ [灯光.MQTT]: /integrations/灯光.MQTT/ [binary_sensor.MQTT]: /integrations/binary_sensor.MQTT/ [自动化-numeric-状态]: /getting-started/自动化-触发器/#numeric-状态-触发器 --- url: /home-assistant/blog/2016-01-17-extended-support-for-diy-solutions.md --- --- url: /home-assistant/blog/2016-01-19-perfect-home-automation.md --- # Perfect Home 自动化 人们经常问我对 Home Assistant 的愿景。在解释我想把 Home Assistant 带到哪里之前,我得先谈谈:在我的理想世界里,完美的家庭自动化应该是什么样子。这正是这篇文章想讨论的内容。我不会把重点放在协议、网络或某个特定中枢上,那些都只是实现细节。相反,我想聚焦于最重要的部分:技术与家中成员之间的互动方式。 ### 你不应该去适应技术 当人们开始接触家庭自动化时,最先体验到的往往是“家居控制”:用手机或电脑以新的方式控制设备。他们会觉得未来已经到来,手机 App 会成为生活中的万能遥控器。可他们只看到了“得到什么”,却没意识到“失去了什么”。你装上几只智能灯泡,然后突然发现原来的灯光开关不好用了。晚上回到家,你得掏出手机、打开 App、等待连接,最后才能把灯打开——而原本这件事,只需要按一下开关。 当然,你也许会说可以用在场检测来解决这个问题。但如果手机没电了怎么办?你最后还是得重新依赖传统开关。 如果新设备让你觉得家里反而更难用了,那家庭自动化就已经失败了。灯光应该既能在房间入口处通过开关或按钮控制,也能结合在场检测自动工作。说实话,除了拿来展示“很酷”之外,几乎没有多少场景真的适合用手机来控制灯光。 ### 你不是家里唯一的用户 人们很容易忘记,自己并不是家里唯一的成员。作为系统的搭建者,你会因为热爱它而忽略许多缺点。但家里的其他人很可能兴趣完全不同,他们只希望事情顺手、稳定,别来打扰。 这意味着你设计的所有自动化都必须尽可能可靠。如果某个自动化 90% 的时间能正常响应,那剩下 10% 的失败体验往往会被无限放大。一个典型例子是:当你开始在客厅看电影或电视剧时,灯光会自动渐暗。这个自动化只有在每次都能正确判断“大家确实在看电视”时才成立。 ### 限制假阳性和假阴性的影响 每做一个自动化,你都应该先问自己:如果它失效了,后果会是什么?家庭自动化由许多厂商、许多协议、许多系统拼接而成,出错是必然的。你的职责,是让这些错误即使发生,影响也尽可能小。理想情况下,设备在失效时应该退回到“智能化之前”的体验。比如 Philips Hue 灯泡,在使用普通开关控制、或者没有连接到中枢时,至少还应该像一只普通白灯那样正常工作。如果你的系统一出问题,家里的使用体验就变得更糟,那用户迟早会反感。Nest 恒温器就是个很好的例子:它在[一月初曾出现一个 bug][nest-bug],导致房子完全停止供暖,这可太糟糕了。 [nest-bug]: http://www.nytimes.com/2016/01/14/fashion/nest-thermostat-glitch-battery-dies-software-freeze.html ### 完美的 App,往往不是 App 家庭自动化应该融入你原本的生活流程,而不是取而代之。对于大多数设备来说,你今天已经在使用的控制方式,往往就是最快的方式。很多时候,最好的 App 就是没有 App。真正可能更方便、而且也适合家中各年龄层访客使用的交互方式,其实是语音界面。整个行业也意识到了这一点,所以越来越多大公司开始押注语音交互。比如 Apple,控制 HomeKit 设备的主要方式就是 Siri;而 Amazon 更进一步,推出了 Amazon Echo,把一个始终在线监听的扬声器和麦克风放进客厅。我相信 2016 年会有更多公司加入这个领域。 语音界面也不完美。发出命令的速度很慢,因为您必须等待响应。在命令的可发现性、口音识别和处理语音时对云的依赖性方面也存在问题。我相信,除了第一个问题之外,所有的问题最终都会得到解决。 然而,这并不代表 App 毫无用处。它们当然有存在价值:比如你外出时查看家中状态、回顾状态变化,或者在有孩子来访时用来演示一些很酷的灯光效果。 ### 你的系统应该运行在家里,而不是云端 云服务听起来很美好:世界某处的服务器收集你家中产生的数据,根据自动化规则进行判断,并在需要时下发命令。随着时间推移,这些云端服务还会不断更新、持续改进,似乎能越来越好地服务你。直到某一天,它不能了。你和云之间的连接可能因为很多原因中断:互联网故障、更新出错,或者运行云服务的服务器本身宕机。 在这种情况下,你的家依然应该能继续运作。云应该被视为智能家居的延伸,而不是核心运行环境。只有这样,你才能避免遇到像 Amazon AWS 宕机,或者 Echo 服务异常时那种尴尬局面。 [echo-crash]: http://www.zdnet.com/article/the-night-alexa-lost-her-mind/ **理想的家庭自动化从不惹人烦,但一旦失效,人们就会立刻想念它。** *感谢 Chris LaRose 提供的反馈与建议。* --- url: /home-assistant/blog/2016-01-29-insteon-lifx-twitter-and-zigbee.md --- --- url: /home-assistant/blog/2016-02-09-Smarter-Smart-Things-with-MQTT-and-Home-Assistant.md --- # 通过 MQTT 和 Home Assistant 让 SmartThings 更聪明 *这是一篇由 Home Assistant 用户 [Jeremiah Wuenschel](https://github.com/jer) 和 [St. John Johnson](https://github.com/stjohnjohnson) 撰写的客座文章。* 如果你拥有一个 [SmartThings][smartthings] Hub,你很可能是在刚接触家庭自动化爱好时买下它的,因为它几乎什么都能配合使用,而且还能让你自动化 *任何事情*。不过,拥有它一周之后,你可能发现,构建仪表板和编写自动化所需要写的 Groovy 代码比你预想的要多得多。后来有一天,你在浏览 [reddit][r/homeautomation] 时发现了强大的 Home Assistant!它提供了仪表板、图表、可用的 Nest 支持,以及真正容易上手的自动化功能。 你花了整个周末把一切都配置好,也向另一半展示了一番,但最后还是卡在了如何把已有的 SmartThings 设备接入进来。现在该怎么办?要不要再买一个 Hub?还是干脆买一个 Z-Wave 棒? 这正是我们介入的原因。我们想要一个方案,把 Home Assistant 的强大体验,与几乎兼容一切的 SmartThings Hub 连接起来。 @ @ PH0 @ @ @ @ PH0 @ @ @ @ PH0 @ @ @ @ PH0 @ @ ## 术语表 这会是一篇相当详细的教程,介绍如何搭建我们的 SmartThings 桥接方案。不过其中有几个关键术语,你可能还不太熟悉: * [MQTT][MQTT]:一种轻量级消息协议,用于监听和发布事件。许多家庭自动化平台都内置了对它的支持,[Home Assistant 尤其如此][MQTT-ha]。 * [Docker][Docker]:一种运行自包含应用程序的工具。你无需安装一堆依赖,也不用担心冲突问题。它在 Linux 和 macOS 上都很容易安装。 ## 设置桥接 ### MQTT 假设你已经运行好了 Home Assistant 和 SmartThings,第一步就是让一个 MQTT broker 跑起来。开源世界里有不少 [MQTT][mosquitto] [broker][emqttd] 可供选择。我们选择 [Mosca][mosca],因为它足够简单。 要让 Mosca 运行起来,几乎不需要做太多事。最简单的方法是使用 [Docker][Docker],然后运行下面这样的命令: ```bash $ docker run \ -d \ --name="mqtt" \ -v /opt/mosca:/db \ -p 1883:1883 \ matteocollina/mosca ``` 这样会在 Docker 容器中启动 Mosca,同时把 Mosca 的持久化存储保存在 `/opt/mosca`。默认配置已经足够让我们把它运行起来。 如果你不想折腾 Docker,而且安装 node.js 也没有问题,那么按照 [standalone][mosca-standalone] 的说明操作就够了。 ### MQTT Bridge 这就是连接 MQTT 和 SmartThings 的那一小块魔法。它是一个 node.js 应用,和 Mosca 一样,最简单的安装方式大概也是 Docker: ```bash $ docker run \ -d \ --name="mqtt-bridge" \ -v /opt/mqtt-bridge:/config \ -p 8080:8080 \ stjohnjohnson/smartthings-mqtt-bridge ``` 如果你想独立启动它,这个桥接的代码也已经[放在 GitHub 上][MQTT-bridge]。 MQTT Bridge 只需要知道你的 MQTT broker 在哪里。如果你直接照搬上面的 Docker 命令,请把 `/opt/mqtt-bridge/config.yml` 改成下面这样: ```yaml --- mqtt: host: ``` 重启桥接之后,就可以继续了: ```bash docker restart mqtt-bridge ``` ### SmartThings 设备 下一步是设置设备类型,这一步也许最容易让人困惑。前往 [Smart Things Device IDE][ide-dt],选择 `Create New Device Handler`。选择 `From Code`,然后把 [MQTT Bridge Device Code][devicetype] 粘贴进去。接着选择 `Save`、`Publish`,然后选择 `For Me`。 现在来安装你新的设备 Handler。回到 IDE 中的 `My Devices`,然后选择 `New Device`。输入一个名称,并为设备 Network Id 随便填写一串字符(之后它会自动更新)。在 Type 中,滚动到列表底部,找到你刚刚创建的 `MQTT Bridge`。其余字段可以按你的喜好填写。 再回到 `My Devices`,然后在列表中选择你刚创建的设备。这会打开一个页面,你可以在这里编辑设备的 Preferences。选择 `edit`,然后填写它要求的 3 项信息。 * MQTT Bridge IP Address: \ * MQTT Bridge Port: <8080 if you have changed nothing in the previous commands> * MQTT Bridge MAC Address: \ 这样就建立起了 SmartThings 与 MQTT Bridge 之间的连接。 ### SmartThings App 最后一步是设置 SmartApp。完成后,所有已注册的设备都会开始把它们的事件发送到 MQTT。 前往 [Smart App IDE][ide-app]。选择 `New SmartApp`,然后选择 `From Code`。把 [MQTT Bridge SmartApp code][smartapp] 粘贴进去,然后选择 `Save`。接着选择 `Publish`,再选择 `For Me`。在 SmartThings 手机应用中,添加这个新的 SmartApp,并用你的设备以及 MQTT Bridge 设备对它进行配置。选择 `done` 之后,SmartThings 就会订阅你的 MQTT broker,并开始双向传播事件。 ### 配置 Home Assistant 如果要通过 MQTT 将 SmartThings 设备添加到 Home Assistant,首先要在 Home Assistant 中启用 MQTT: ```yaml mqtt: broker: localhost ``` 把 `localhost` 替换成 MQTT broker 实际运行的位置。来自 MQTT Bridge 的设备会发布到路径 `smartthings//`。 例如,我的调光 Z-Wave 灯在 SmartThings 中叫做 “Fireplace 灯光”。下面这些主题会被发布出来: | Topic | 描述 | | ----- | ----------- | | smartthings/Fireplace 灯光/level | 亮度 (0-99) | | smartthings/Fireplace 灯光/开关 | 开关状态 (on/off) | 下面是一个 Home Assistant 配置示例: ```yaml switch: platform: mqtt name: "Fireplace Lights" state_topic: "smartthings/Fireplace Lights/switch" command_topic: "smartthings/Fireplace Lights/switch" brightness_state_topic: "smartthings/Fireplace Lights/level" brightness_command_topic: "smartthings/Fireplace Lights/level" payload_on: "on" payload_off: "off" retain: true ``` 我们建议每个 MQTT 设备都设置 `retain: true`,这样当连接中断又恢复时,状态仍然能保持同步。 接下来,你可以深入看看 Home Assistant 中的 [MQTT 组件][MQTT-ha],找到哪些组件适合映射这些新发布到 MQTT 的事件。 ### 使用 Docker-Compose 配置 我们个人最喜欢的启动整套软件的方式,是使用一个统一的 Docker-Compose 文件。你只需要创建一个名为 `docker-compose.yml` 的文件,内容如下: ```yaml mqtt: image: matteocollina/mosca ports: - 1883:1883 mqttbridge: image: stjohnjohnson/smartthings-mqtt-bridge volumes: - ./mqtt-bridge:/config ports: - 8080:8080 links: - mqtt homeassistant: image: homeassistant/home-assistant:latest ports: - 80:80 volumes: - ./home-assistant:/config - /etc/localtime:/etc/localtime:ro links: - mqtt ``` 这样会按照依赖顺序启动 home-assistant、MQTT,以及 Bridge。所有配置都可以直接引用 Docker 容器名称,而不用填写 IP 地址(例如,在 Home Assistant 中把 broker 主机直接写成 `mqtt`)。 ### 工作原理 **HTTP Endpoint**:我们能找到的与 SmartThings Hub 通信的方法,其实只有两种。最简单的方法,是创建一个基于 OAuth 认证的 RESTful SmartApp,通过 HTTP 直接提供状态变化。这种方式实现起来相当直接,但它需要与 SmartThings 的云服务通信,无法完全在你的局域网内部完成。我们希望把所有通信都留在内网,于是想到了第二种方式。 **自定义设备类型**:SmartThings 的自定义设备类型允许开发者为 SmartThings Hub 在本地网络中直接接收到的 HTTP 事件定义处理器。接收到的消息会通过 MAC 地址进行认证,并且负载中可以包含任意字符串。由于一个设备类型只能绑定到一个设备,我们还需要配合一个 SmartApp,来在各个单独设备与我们这个特殊的 Home Assistant Bridge 设备之间翻译事件。到目前为止,结构如下: ```text Z-Wave Switch | Zigbee motion sensor |<---> Bridge App <---> Bridge Device Type <---> Z-Wave light bulb | ``` 在 Home Assistant 这一侧,有一个基于 MQTT 轻量消息总线协议的强大平台可用。从灯光、开关,到温度传感器,都可以在 Home Assistant 中定义为 MQTT 组件,因此它是一个非常方便的集成点。这需要一个 MQTT broker 来处理消息总线,还需要最后一个组件来负责在 SmartThings 支持的 HTTP 与 MQTT 之间进行转换。 最终的事件流转顺序如下: @ @ PH0 @ @ @ @ PH0 @ @ @ @ PH0 @ @ @ @ PH0 @ @ SmartThings Bridge Sequence @ @ PH0 @ @ 这些事件在途中要经过不少节点,但每一层都只是一个简单的翻译层,用来在各个系统之间转送事件。 ### 后续改进 * **树莓派**:很多人都希望让这套方案跑在树莓派上。它只需要为 ARM 编译的二进制文件,所以我们计划在未来某个时间点提供兼容 ARM 的容器版本。 * **MQTT 认证**:目前 MQTT bridge 还不知道如何向 MQTT 执行认证,因此现在只支持不带认证的 MQTT。如果你使用了我们的 Docker Compose 配置,这个问题会在一定程度上被缓解,因为 MQTT 的端口实际上并不会公开暴露出去。 * **MQTT Bridge 认证**:目前 bridge 默认认为任何订阅者都是 SmartThings Hub。这部分还需要更完善的认证机制。 [mosquitto]: http://mosquitto.org/ [emqttd]: https://github.com/emqtt/emqttd [mosca]: http://www.mosca.io/ [Docker]: https://www.Docker.com/ [mosca-standalone]: https://github.com/mcollina/mosca#standalone [MQTT-bridge]: https://github.com/stjohnjohnson/smartthings-MQTT-bridge [ide-dt]: https://graph.api.smartthings.com/ide/devices [devicetype]: https://github.com/stjohnjohnson/smartthings-MQTT-bridge/blob/master/devicetypes/stj/MQTT-bridge.src/MQTT-bridge.groovy [ide-app]: https://graph.api.smartthings.com/ide/apps [smartapp]: https://github.com/stjohnjohnson/smartthings-MQTT-bridge/blob/master/smartapps/stj/MQTT-bridge.src/MQTT-bridge.groovy [MQTT-ha]: /integrations/MQTT/ [smartthings]: http://smartthings.com [r/homeautomation]: https://www.reddit.com/r/homeautomation [MQTT]: https://en.wikipedia.org/wiki/MQTT --- url: /home-assistant/blog/2016-02-11-classifying-the-internet-of-things.md --- # 物联网分类 家庭自动化的核心,在于知道当前发生了什么。我们越快知道状态发生了变化,就越能更好地为你服务。比如,如果你希望回家时灯光自动打开,那么要是系统只能在你已经开门、甚至还得手动把灯打开之后才知道你到家了,那显然没有帮助。 每个智能设备都由两部分组成:一部分是“普通”的设备本体,另一部分是让它变“智能”的连接能力。设备的连接能力可能包含控制、状态,或两者兼有。 状态描述的是设备当前正在做什么。比如,一盏灯可能处于开启状态,颜色是红色,亮度为中等。 控制指的是通过 API 发送命令来操控智能设备。这些命令可能包括配置设备的工作方式,或者模拟用户与设备交互的方式。媒体播放器可能支持切换到下一首曲目,而传感器则可能允许你配置其灵敏度或轮询间隔。 Home Assistant 的 API 已尽量设计得足够方便。不过,网络系统的强弱总取决于最薄弱的一环。对我们来说,这一环就是各个集成。以一盏不会上报状态的灯为例,在发送命令之后,Home Assistant 唯一能报告的就只是“假定状态”:也就是如果命令执行成功,我们预计这盏灯会处于什么状态。 我们希望你能获得尽可能好的家庭自动化体验,而这要从确保设备能与 Home Assistant 良好配合开始。因此,我们将开始为各个集成应用以下分类标记:
分类标记 说明
假定状态 我们无法获取设备的状态。我们能做的最好情况,就是根据最后一次发送的命令来假定设备当前的状态。
云端轮询 此设备通过云端进行集成,并且需要可用的互联网连接。由于是轮询状态,因此系统可能会较晚才注意到更新。
云端推送 此设备通过云端进行集成,并且需要可用的互联网连接。一旦有新的状态可用,Home Assistant 就会立即收到通知。
本地轮询 提供与设备的直接通信能力。由于是轮询状态,因此系统可能会较晚才注意到更新。
本地推送 提供与设备的直接通信能力。一旦有新的状态可用,Home Assistant 就会立即收到通知。
至于我们为什么会整理出这些分类标记,你可以在下文中继续了解。 ## 状态 状态的传递方式可以分成 5 类。这些分类并不是互斥的,同一个设备的状态可能同时通过云端和本地连接获得。 ### 没有可用状态 这类设备没有能力公开自己的状态。它们只能被控制。比如使用红外遥控器控制的设备,像电视和空调。你可以按下遥控器上的开机按钮,但你只能假定你的命令已经被设备接收并成功执行。设备可能根本没有通电,或者有东西挡住了红外接收器。 家庭自动化面对这类设备时,只能基于“命令会被正确接收”的假设来工作,也就是采用乐观更新。意思是,发送命令之后,系统会把设备状态更新为“仿佛命令已经成功执行”的结果。 优点: * 无 缺点: * 如果命令没有被正确接收,或者设备通过家庭自动化系统之外的其他方式被控制,家庭自动化就会假定出错误的状态。 ### 轮询云端 这类设备只会把状态上报给自己的云端后端。云端后端允许你读取状态,但不会在有新状态到来时主动通知。这意味着家庭自动化系统必须频繁检查状态是否发生了变化。 优点: * 无论你在家还是外出,都可以控制设备。 * 云端可以利用更强的计算能力分析设备数据,并向你提供优化建议。 缺点: * 一旦互联网中断,或者厂商停止支持,这套方案就无法工作。 * 你将不再完全掌控谁可以访问你的数据。 ### 云端推送新状态 前一节的内容同样适用于这里。除此之外,云端现在还会在有新状态到来时通知家庭自动化系统。这意味着云端一知道,家庭自动化系统也就立刻知道。 优点: * 新状态一旦在云端可用,系统就能立即获知。 ### 轮询本地设备 这类设备会提供一个可在本地访问的 API。家庭自动化系统需要频繁检查状态是否发生了变化。 优点: * 不依赖互联网。 缺点: * 若要支持轮询,设备就必须始终在线,这意味着它需要持续接入电源。 ### 本地设备推送新状态 这是最理想的情况。这类设备在进入新状态时会主动发出通知。它们通常会使用某种家庭自动化协议,把消息传递给一个 Hub,再由 Hub 负责管理并通知订阅者。 优点: * 新状态几乎可以瞬时送达。 * 设备可以在两次状态更新之间进入深度休眠,从而获得更长的电池续航。 缺点: * 如果它同时不支持轮询,那么在家庭自动化系统启动之后,只有等状态真正变化时,系统才会知道当前状态。 * 如果设备通过 Wi-Fi 并采用深度休眠,那么它在唤醒时会产生延迟,因为连接 Wi-Fi 和获取 IP 地址都需要时间。 ## 控制 和状态一样,控制设备也可以通过云端和/或本地连接来完成。但控制中更重要的一点,是知道你的命令是否执行成功,以及设备的新状态是什么。 ### 没有可用控制 这类设备无法被控制。它们只能提供状态。 ### 发送命令后轮询状态 这类设备需要在发送命令后,再去轮询状态,才能知道命令是否执行成功。 优点: * 命令发送后,系统可以很快尝试确认状态。 缺点: * 状态更新可能需要时间。我们该多久轮询一次,又该等待多久才认定命令失败?此外,状态也可能由于其他因素而变化,因此很难判断更新后的状态究竟是不是由我们的命令引起的。 ### 设备主动推送状态更新 这类设备不会把新状态作为命令的直接返回值,而是会立刻主动推送一个新的状态。这个方案的缺点是,我们只能假定:如果某个状态更新在发送命令后的一段时间内到达,那它就与这次命令有关。 ### 命令直接返回新状态 这是最好的情况。这类设备会在执行命令之后,直接以响应的形式返回新的状态。 ## Home Assistant 的分类 Home Assistant 会尽量通过自己的 API 提供最好的使用体验。与 Home Assistant 交互的方式有多种,但它们全部都是本地的。 * 可以通过 REST API 轮询状态。 * 还提供了一个流式 API,会在有新状态到达时立即推送给订阅者。这也是前端始终能够保持同步的原因。 * 调用 Home Assistant 中的某个服务时,返回结果会包含该服务执行期间发生变化的所有状态。遗憾的是,这并不总能包含那些通过主动推送来上报新状态的设备的最终状态,因为这些状态有可能会在服务执行结束之后才到达。 --- url: /home-assistant/blog/2016-02-13-speedtest-bloomsky-splunk-and-garage-doors.md --- # 0.13: Speedtest.net, Bloomsky, Splunk and Garage Doors 0.13 的重点是测试覆盖率,特别感谢 [@rmkraus] 在这方面付出的努力。很高兴宣布,我们在核心和重要组件上达到了 90% 的测试覆盖率。这是项目的一个重要里程碑。

新增的 [input_select] 和 weblink 组件示例。

我们不仅大幅提升了测试覆盖率,还吸引了许多新开发者贡献了各种组件和平台: * 核心: 新增可重启 Home Assistant 的服务 ([@rmkraus]) * 核心: 允许设备上报为不可用状态 ([@MartinHjelmare]) * 核心: 允许在平台内和配置中覆盖轮询间隔 ([@balloob]) * 前端: 新增 [default view] 支持,用于替代显示全部视图 ([@balloob]) * 组件: 新增 [apcupsd] 组件 ([@flyte]) * 组件: 新增将日志数据发送到 [Splunk] 的组件 ([@miniconfig]) * 组件: 新增 [garage door] 组件,包含 [Wink] 支持 ([@xrolfex]) * 组件: 新增 [input\_select][input_select] 组件 ([@balloob]) * 组件: 新增 [proximity] 组件,用于追踪离某个位置最近的人 ([@nickwaring], [@Bart274] ) * 组件: 新增 [Bloomsky 天气 Station] 支持 ([@haraldnagel]) * 组件: 新增将统计数据推送到 [graphite] 的支持 ([@kk7ds]) * 组件: 新增 [SCSGate] 设备支持 ([@flavio]) * 组件: 新增 weblink 组件,可链接到其他页面 ([@MagnusKnutas]) * 组件: 新增对 Ubiquiti mFI [传感器][mfi.传感器] 和 [switchable 设备][mfi.开关] 的支持 ([@kk7ds]) * 报警控制面板: 新增 [Caddx/GE/Interlogix NetworX][nx584] 支持 ([@kk7ds]) * 摄像头: [MJPEG] 摄像头现在显示真实视频流,而非 2fps 流 ([@stjohnjohnson]) * 摄像头: 新增 [Unifi video 摄像头][unifi] 支持 ([@kk7ds]) * 设备 Tracker: [Aruba] 平台现改用 SSH,而非 telnet ([@carlosmgr]) * 历史: 为温控器显示正确的图表 ([@sdague]) * 灯光: 新增 [MySensors] 支持 ([@MartinHjelmare]) * 门锁: 新增 [Verisure] 支持 ([@turbokongen]) * 媒体播放器: 新增 [Samsung TV] 支持 ([@stefan-jonasson]) * 媒体播放器: 新增 [Snapcast] 支持 ([@happyleavesaoc]) * MQTT: 允许在 [publish 服务][MQTT-publish] 中使用模板 ([@flyte]) * 通知: 新增 [REST] 支持 ([@Theb-1]) * 传感器: 新增 [Speedtest.net] 支持 ([@nkgilley]) * 开关: 新增 [模板] 平台 ([@pavoni]) * 温控器: 新增对美国地区 [Honeywell] 的支持 ([@kk7ds]) * Z-Wave: 允许 [configuring polling][zwave-polling] 并 [support 场景][zwave-场景] ([@lukas-hetzenecker]) * 由 [@persandstrom]、[@fabaff]、[@balloob]、[@pavoni]、[@philipbl]、[@MartinHjelmare]、[@rmkraus]、[@molobrakos]、[@lukas-hetzenecker]、[@TangoAlpha]、[@deisi]、[@Danielhiversen]、[@roqeer]、[@jaharkes] 带来多项 Bug 修复与改进 [@rmkraus]: https://github.com/rmkraus/ [@MartinHjelmare]: https://github.com/MartinHjelmare/ [@balloob]: https://github.com/balloob/ [@flyte]: https://github.com/flyte/ [@miniconfig]: https://github.com/miniconfig/ [@xrolfex]: https://github.com/xrolfex/ [@nickwaring]: https://github.com/nickwaring/ [@Bart274]: https://github.com/Bart274/ [@haraldnagel]: https://github.com/haraldnagel/ [@kk7ds]: https://github.com/kk7ds/ [@flavio]: https://github.com/flavio/ [@MagnusKnutas]: https://github.com/MagnusKnutas/ [@stjohnjohnson]: https://github.com/stjohnjohnson/ [@carlosmgr]: https://github.com/carlosmgr/ [@sdague]: https://github.com/sdague/ [@turbokongen]: https://github.com/turbokongen/ [@stefan-jonasson]: https://github.com/stefan-jonasson/ [@happyleavesaoc]: https://github.com/happyleavesaoc/ [@Theb-1]: https://github.com/Theb-1/ [@nkgilley]: https://github.com/nkgilley/ [@pavoni]: https://github.com/pavoni/ [@lukas-hetzenecker]: https://github.com/lukas-hetzenecker/ [@persandstrom]: https://github.com/persandstrom/ [@fabaff]: https://github.com/fabaff/ [@philipbl]: https://github.com/philipbl/ [@molobrakos]: https://github.com/molobrakos/ [@TangoAlpha]: https://github.com/TangoAlpha/ [@deisi]: https://github.com/deisi/ [@Danielhiversen]: https://github.com/Danielhiversen/ [@roqeer]: https://github.com/roqeer/ [@jaharkes]: https://github.com/jaharkes/ [default view]: /integrations/group/ [apcupsd]: /integrations/apcupsd/ [Splunk]: /integrations/splunk/ [garage door]: /integrations/遮盖/ [Wink]: /integrations/wink/#遮盖 [input_select]: /integrations/input_select/ [proximity]: /integrations/proximity/ [Bloomsky 天气 Station]: /integrations/bloomsky/ [graphite]: /integrations/graphite/ [SCSGate]: /integrations/scsgate/ [mfi.开关]: /integrations/mfi#开关 [mfi.传感器]: /integrations/mfi#传感器 [nx584]: /integrations/nx584 [MJPEG]: /integrations/mjpeg [unifi]: /integrations/uvc [Aruba]: /integrations/aruba [History]: /integrations/history/ [MySensors]: /integrations/灯光.mysensors/ [Verisure]: /integrations/verisure [Speedtest.net]: /integrations/speedtestdotnet [Samsung TV]: /integrations/samsungtv [Snapcast]: /integrations/snapcast [MQTT-publish]: /integrations/MQTT/#publish-服务 [REST]: /integrations/通知.rest/ [模板]: /integrations/模板/#开关 [Honeywell]: /integrations/honeywell/ [zwave-polling]: /integrations/zwave/#配置 [zwave-场景]: /integrations/zwave/#events --- url: /home-assistant/blog/2016-02-18-multi-room-audio-with-snapcast.md --- # Multi-房间 audio with Snapcast, Mopidy, and Home Assistant 你是否想在家里的每个房间听音乐,并且由一个音源统一控制?那多房间音频就是你要找的方案。 多房间音频可以通过在每个房间放置一台连接扬声器的电脑来实现。每台电脑上运行用于播放和控制音频的服务。采用这种 DIY 方案时,电脑和扬声器类型都可以自由选择。你可以使用连接有源音箱的桌面电脑、接入电视和功放的 HTPC、带功放或 DAC 的树莓派,甚至 Android 设备。 除了 Home Assistant 外,你还需要两个关键软件包。第一个是 [Mopidy](https://www.mopidy.com/),这是一个音乐服务器,可以播放本地文件,也可以连接 Spotify 这类流媒体音乐服务。第二个是 [Snapcast](https://github.com/badaix/snapcast/),它可以让网络中的音频流保持同步播放。两者都可以集成到 Home Assistant 中。每个房间的音频设备会运行一个 Snapcast 客户端实例,并可选运行一个 Mopidy 实例。你的服务器则运行一个专门用于 Snapcast 的 Mopidy 实例以及 Snapcast 服务器。 最后,你还需要一个播放器来控制 Mopidy。任何兼容 MPD 的播放器都可以使用,另外也有多个 [Mopidy-only web-based options](https://docs.mopidy.com/en/latest/ext/web/#ext-web)。在 Android 上,[Remotedy](https://play.google.com/store/apps/details?id=se.anil.remotedy) 尤其好用,因为你可以在一个界面里访问多个 Mopidy 实例。 Home Assistant 会提供每个房间设备的状态和音量控制。如果你想在所有房间(所有客户端)播放音乐,就访问服务器上的 Mopidy 实例。如果你只想在某个房间播放,就访问该房间对应的 Mopidy 实例。如果你使用 Mopidy 的网页界面,还可以通过 weblink 组件把各实例链接加入 Home Assistant。

## 准备工作 * [安装](https://www.mopidy.com/) Mopidy (2.0.0 or greater) * [Download](https://github.com/badaix/snapcast/releases/) and [安装](https://github.com/badaix/snapcast/tree/v0.5.0-beta-1#安装) Snapcast (0.5.0 or greater) ## 配置 Mopidy Mopidy 可以通过多个配置文件运行,每个配置文件都在前一个文件的基础上扩展。当你需要运行多个功能不同的实例时,这种方式非常有用。 ### 核心.conf 这个基础配置会被所有实例共享: ```text [mpd] hostname = :: [http] hostname = :: [audio] output = alsasink [spotify] username = password = ``` ### local.conf 在有本地媒体文件的电脑上,增加本地配置: ```text [local] media_dir = ``` ### snapcast.conf 最后,与 Snapcast 连接的 Mopidy 实例需要特殊配置。如果你的电脑上还运行了第二个 Mopidy 实例,请使用不同端口以避免冲突。音频输出会发送到一个命名管道,Snapcast 会从这里读取。请注意,你可能需要根据系统和音频源调整音频输出参数。 ```text [mpd] hostname = :: port = 6601 [http] hostname = :: port = 6681 [audio] output = audioresample ! audio/x-raw,rate=48000,channels=2,format=S16LE ! audioconvert ! wavenc ! filesink location=/tmp/snapfifo ``` ## 运行 Mopidy 运行某个房间专用实例: ```bash mopidy --config $CONF_DIR/core.conf ``` 运行带本地媒体的房间专用实例: ```bash mopidy --config $CONF_DIR/core.conf:$CONF_DIR/local.conf ``` 运行连接 Snapcast 的专用实例(含本地媒体): ```bash mopidy --config $CONF_DIR/core.conf:$CONF_DIR/local.conf:$CONF_DIR/snapcast.conf ``` ## 运行 Snapcast 在运行 Snapcast 配置版 Mopidy 的同一台服务器上启动 `snapserver`。 ```bash snapserver # or use systemd ``` 在负责播放音频的电脑上启动 `snapclient`。 ```bash snapclient # or use systemd, add -h if necessary ``` ## 配置 Snapcast Snapcast 有很多配置项,但与 Home Assistant 相关性最高的是客户端名称。你可以在 snapserver 的配置文件中设置,默认路径是 `~/.config/Snapcast/settings.json`。请只在 `snapserver` 未运行时编辑该文件。修改其中 JSON 的 `name` 值后,客户端就会在 Home Assistant 里以这个名称显示。 ## 配置 Home Assistant 使用 [mpd] 和 [snapcast] 组件。你也可以选择使用 \[weblink],以便快速访问 Mopidy 的网页界面。 ```yaml media_player: - platform: snapcast host: xxxxx - platform: mpd server: xxxx location: Multi-Room Controller - platform: mpd server: xxx location: Room 1 weblink: entities: - name: Multi-Room Player url: xxxx ``` [snapcast]: /integrations/snapcast [mpd]: /integrations/mpd --- url: /home-assistant/blog/2016-02-20-community-highlights.md --- # Community Highlights Home Assistant 社区最近非常活跃,很多人都做出了很棒的项目。 ### Part of the Thing 的家庭自动化演示
### Haaska - Home Assistant 的 Alexa Skill 适配器 Haaska 允许你通过 Amazon Echo 控制 Home Assistant 实例中暴露的灯光、开关和场景。这与我们自己的 [Alexa](/home-assistant/integrations/alexa/index.md) 组件不同,因为它会直接让 Amazon Echo 识别这些设备,而不是让 Echo 经由 Home Assistant 转发。它不支持自定义句式,但你在发出命令时可以跳过“Ask Home Assistant”这一步: * "Alexa,将 kitchen 调到百分之二十" * "Alexa,打开 evening 场景" * "Alexa,关闭 bedroom 灯光" [Haaska GitHub 页面](https://github.com/auchter/haaska) ### 将 Home Assistant 集成到 HomeKit 贡献者 Maddox 为 HomeBridge(一个开源 HomeKit 桥接项目)创建了一个插件。借助它,你可以在 Apple 设备上通过 Siri 控制你的家。由于 HomeBridge 最近进行了结构调整,你需要通过 `homebridge-homeassistant` 这个 npm 包单独安装该插件。 用于加载 Home Assistant 的 `config.json` 示例条目: ```json "platforms": [ { "platform": "HomeAssistant", "name": "HomeAssistant", "host": "http://192.168.1.50:8123", "password": "xxx", "supported_types": ["light", "switch", "media_player", "scene"] } ] ``` [HomeBridge GitHub 页面](https://github.com/nfarina/homebridge) [HomeBridge Home Assistant 插件](https://github.com/maddox/homebridge-homeassistant) ### 使用 Home Assistant 构建自定义报警系统 用户 thaijames 在论坛帖子([Home Assistant forums 讨论帖](https://community.home-assistant.io/t/controlling-house-报警-from-ha/67))中介绍了他如何使用 Home Assistant、DIY 组件和加菲猫玩偶,搭建一个基于 NFC 的自定义报警系统。

把你的 NFC 标签贴到加菲猫肚子上即可解除报警。

--- url: /home-assistant/blog/2016-02-28-steam-d-link-smart-plugs-and-neurio-energy-sensors.md --- # 0.14: Steam, D-Link smart plugs and Neurio Energy 传感器 又过去了两周,也就意味着 0.14 发布时间到了! * 通知: 新增 [Command line platform][通知.command_line] ([@stefan-jonasson]) * 传感器: 新增对 [Verisure] 鼠标探测器的支持 ([@turbokongen]) * 核心: 实体现在可以声明其状态表示是否被认为是准确的 ([@balloob]) * 传感器: 新增 [TCP][传感器.tcp] 平台 ([@flyte]) * 二元传感器: 新增 [TCP][binary_sensor.tcp] 平台 ([@flyte]) * 传感器: 新增 [Neurio energy 传感器] 支持 ([@infamy]) * 二元传感器: 新增 [nx584] 支持 ([@kk7ds]) * 改进并澄清了 CI 测试流程 ([@sdague]) * 自动化: 状态 [触发器] 和 [条件] 现在支持可选 `for` 参数,仅在状态持续一段时间未变化时触发 ([@pavoni], [@stefan-jonasson]) * 传感器: 新增 [Nest] 天气数据 ([@w1ll1am23]) * 设备 Tracker: 新增 [Ubiquiti Unifi] 支持 ([@kk7ds]) * 二元传感器: 新增 [MySensors] 支持 ([@MartinHjelmare]) * 二元传感器: 新增 [Bloomsky] 支持 ([@balloob]) * 二元传感器: 新增 [Z-Wave] 支持 ([@tpatja]) * 开关: 新增 [D-Link smart plugs] 支持 ([@LinuxChristian]) * 脚本: 新增切换支持 ([@Andythigpen]) * 灯光: 新增 [Wemo] 支持 ([@jaharkes]) * 卷帘门: 新增 Command line 平台 ([@t30]) * 传感器: 新增 [Steam] 支持 ([@GreenTurtwig]) * 二元传感器: 新增 [Wink] 支持 ([@w1ll1am23]) * 演示示例已更新 ([@kfgoode]) * 前端: 为摄像头新增 UI ([@balloob])

摄像头画面现在直接嵌入在前端中。

### 向后不兼容的变更 * 组件: Simple 报警已移除,但仍可在 cookbook 中使用。 * 脚本: 对已开启的 [脚本] 再次执行开启操作时,现在不会执行任何操作,不再跳过当前延迟。 * Wemo 开关现在必须通过主 [Wemo component] 进行设置。 * [开关][开关.cmd]、[传感器][传感器.cmd] 和 [binary\_sensor][binary_sensor.cmd] 的 Command line 平台已重命名为 `command_line`。 * rfxtrx 传感器实体 ID 将发生一次性调整,以迁移到稳定格式。详情请参见 [the docs][传感器.rfxtrx]。 [传感器.rfxtrx]: /integrations/rfxtrx#传感器 [通知.command_line]: /integrations/通知.command_line/ [Verisure]: /integrations/verisure [binary_sensor.tcp]: /integrations/tcp#binary-传感器 [传感器.tcp]: /integrations/tcp#传感器 [Neurio energy 传感器]: /integrations/neurio_energy [nx584]: /integrations/nx584#binary-传感器 [触发器]: /getting-started/自动化-触发器/#状态-触发器 [条件]: /getting-started/自动化-条件/#状态-条件 [Nest]: /integrations/nest#传感器 [Ubiquiti Unifi]: /integrations/unifi [MySensors]: /integrations/binary_sensor.mysensors/ [Bloomsky]: /integrations/bloomsky#binary-传感器 [Z-Wave]: /integrations/zwave [D-Link smart plugs]: /integrations/dlink [Wemo]: /integrations/wemo [Steam]: /integrations/steam_online [Wink]: /integrations/wink#binary-传感器 [脚本]: /integrations/脚本/ [Wemo component]: /integrations/wemo/ [开关.cmd]: /integrations/开关.command_line/ [传感器.cmd]: /integrations/传感器.command_line/ [binary_sensor.cmd]: /integrations/command_line [@stefan-jonasson]: https://github.com/stefan-jonasson [@turbokongen]: https://github.com/turbokongen [@balloob]: https://github.com/balloob [@flyte]: https://github.com/flyte [@infamy]: https://github.com/infamy [@kk7ds]: https://github.com/kk7ds [@sdague]: https://github.com/sdague [@pavoni]: https://github.com/pavoni [@w1ll1am23]: https://github.com/w1ll1am23 [@MartinHjelmare]: https://github.com/MartinHjelmare [@tpatja]: https://github.com/tpatja [@LinuxChristian]: https://github.com/LinuxChristian [@Andythigpen]: https://github.com/Andythigpen [@jaharkes]: https://github.com/jaharkes [@t30]: https://github.com/t30 [@GreenTurtwig]: https://github.com/GreenTurtwig [@kfgoode]: https://github.com/kfgoode --- url: /home-assistant/blog/2016-03-12-z-wave-pep257-templated-service-calls.md --- # 0.15: Unforked Open Z-Wave, templated 服务 calls, extended 场景 support 两周过去了,0.15 来了!我们这段时间非常专注于质量,确保系统更加稳定、可靠。我通常会在发布说明里重点介绍一项很酷的更新,但这次发布有 4 条令人兴奋的公告! * [@fabaff] has upgraded the codebase to follow the PEP257 文档 standard. * [@partofthething] has migrated us to use the main Python Open Z-Wave library instead of our forked 版本. * To make our 自动化 more powerful, [@persandstrom] added the option to use 模板 to dynamically create 服务 calls. This works for 自动化, Alexa, universal media player, 模板 开关. [Learn more.][服务] * [@MartinHjelmare] has upgraded our 场景 support to now support all built-in 服务 and components. 除错误修复外,这次发布还带来了: * 场景: Converted to a platform based component ([@sander76]) * 场景: [Hunter Douglas Powerview] now supported ([@sander76]) * 门锁: [MQTT] platform added ([@fabaff]) * 设备 Tracker: [OwnTracks] will allow filtering inaccurate GPS locations ([@HydrelioxGitHub]) * 二元sensor: Wemo Motion now supported ([@pavoni], [@ryanlaux]) ```yaml # Example using templates for service and data in service call. # Works for automation, Alexa, universal media player, template switch. automation: - trigger: - platform: state entity_id: switch.bathroom action: service: > switch.turn_on switch.turn_off target: entity_id: switch. ``` ### Backward-incompatible changes * Media Player: 属性 to call 服务 play\_media has been renamed to `media_content_type` and `media_content_id`, to match the corresponding media player 状态 属性. This change affects 自动化, 脚本 and 场景. [服务]: /docs/脚本/服务-calls/#use-模板-to-decide-which-服务-to-call [Hunter Douglas Powerview]: /integrations/hunterdouglas_powerview [MQTT]: /integrations/门锁.MQTT/ [OwnTracks]: /integrations/owntracks [Wemo Motion]: /integrations/wemo [@fabaff]: https://github.com/fabaff [@partofthething]: https://github.com/partofthething [@persandstrom]: https://github.com/persandstrom [@fabaff]: https://github.com/fabaff [@persandstrom]: https://github.com/persandstrom [@PartOfTheThing]: https://github.com/PartOfTheThing [@sander76]: https://github.com/sander76 [@sander76]: https://github.com/sander76 [@fabaff]: https://github.com/fabaff [@HydrelioxGitHub]: https://github.com/HydrelioxGitHub [@MartinHjelmare]: https://github.com/MartinHjelmare [@pavoni]: https://github.com/pavoni [@ryanlaux]: https://github.com/ryanlaux --- url: /home-assistant/blog/2016-03-26-embedded-mqtt-broker-uber-yamaha-growl.md --- # 0.16: Embedded MQTT broker, Uber, Yamaha receivers and Growl 各位派对玩家,0.16 来了!这次发布最大的亮点是,我们通过可启动内置 MQTT 服务器 [hbMQTT],彻底降低了 MQTT 的上手门槛。只要在配置中加入 `mqtt:`,代理服务就会启动并连接到 Home Assistant。 此外,这次发布还包含了大量很酷的新功能、错误修复,以及 Vera 和 Tellstick 组件的重写(详见文末“不向后兼容的更改”部分)。 尽情享受吧。 * 设备 Tracker - [OwnTracks]: Allow entry into passive 区域 using iBeacons ([@pavoni]) * Tellstick: rewrite to [component][Tellstick] to address concurrency issues ([@stefan-jonasson]) * Z-Wave: add [服务][Z-Wave] to heal and soft reset network ([@srcLurker]) * New component [input\_slider][input_slider] added ([@persandstrom]) * 灯光 - [Hue]: Option added to ignore unreachable property ([@maddox]) * 通知: [MessageBird] support added ([@florianholzapfel]) * HTTP: Failed login attempts are now logged ([@fabaff]) * Vera: rewrite to [component][Vera] to simplify code and organize for reusability ([@pavoni]) * Discovery: support for Squeezebox (Logitech media) server added ([@jaharkes]) * Discovery: fix uPNP discovery crashing some routers ([@jaharkes]) * 开关: [Wake on LAN] platform added ([@joopert]) * 服务 for thermostats, 通知 and media player will now validate passed in parameters ([@MartinHjelmare]) * 开关 - [Arduino]: support for default 状态 and negate port functionality (@tilutza) * 开关: [PulseAudio loopback] now supported ([@Cinntax]) * 传感器: Uber now supported ([@robbiet480]) * 通知: [Growl (GNTP)] now supported ([@robbiet480]) * Media Player: [Yamaha receivers] now supported ([@aoakeson]) [hbMQTT]: https://github.com/beerfactory/hbmqtt [@aoakeson]: https://github.com/aoakeson [@balloob]: https://github.com/balloob [@Cinntax]: https://github.com/Cinntax [@fabaff]: https://github.com/fabaff [@florianholzapfel]: https://github.com/florianholzapfel [@jaharkes]: https://github.com/jaharkes [@joopert]: https://github.com/joopert [@maddox]: https://github.com/maddox [@MartinHjelmare]: https://github.com/MartinHjelmare [@pavoni]: https://github.com/pavoni [@persandstrom]: https://github.com/persandstrom [@robbiet480]: https://github.com/robbiet480 [@srcLurker]: https://github.com/srcLurker [@stefan-jonasson]: https://github.com/stefan-jonasson [Arduino]: /integrations/arduino#开关 [Discovery]: /integrations/discovery/ [Growl (GNTP)]: /integrations/gntp [Hue]: /integrations/hue [input_slider]: /integrations/input_number [MessageBird]: /integrations/message_bird [OwnTracks]: /integrations/owntracks [PulseAudio loopback]: /integrations/pulseaudio_loopback [Tellstick]: /integrations/tellstick/ [Vera]: /integrations/vera/ [Wake on LAN]: /integrations/wake_on_lan#开关 [Z-Wave]: /integrations/zwave/#服务 [Yamaha receivers]: /integrations/yamaha ### Backward-incompatible changes * 自动化: support for old deprecated config has been removed * Tellstick 配置 has changed ```yaml tellstick: signal_repetitions: X ``` * Vera 配置 has changed ```yaml vera: vera_controller_url: http://192.168.1.161:3480/ # Optional to exclude devices - this is a list of vera device ids exclude: [ 13, 14, 16, 20, 23, 72, 73, 74, 75, 76, 77, 78, 88, 89, 99] # Optional to import switches as lights - this is a list of vera device ids lights: [15, 17, 19, 21, 22, 24, 26, 43, 64, 70, 87] ``` --- url: /home-assistant/blog/2016-04-04-your-hub-should-be-local-and-open.md --- # Your hub should be local and open 今天有消息传出,Google 将会[关闭 Revolv 中枢][medium-revolv]。这里的“关闭”并不是停止销售或停止支持——不是的,他们会向每一台中枢推送更新,把你原本完全可用的家庭自动化中枢变成一块没用的塑料。Google 竟然觉得这是个好主意,这让我非常震惊。无论如何,他们都应该像 ninjasphere 一样:把一切开放出来,让人们自己决定他们 *自己的* 中枢命运。 我[之前][perfect-cloud]说过这句话,但我还要再说一次:
云应该被视为智能家居的扩展,而不是由它来运行你的智能家居。
当你的网络中断,或者卖给你中枢的公司倒闭时,你的中枢不应该受到影响。它应该能够在本地运行,这样即使厂商倒闭,或者决定终止产品,它也依然可以继续工作。最好你的中枢还是开放的,这样在厂商不再投入之后,社区可以接手继续开发。 除非你能承受时不时损失一个产品,否则在购买那些依赖云服务、且来自尚不成熟公司的 IoT 产品时要格外谨慎。它们很可能会破产,或者被收购后被关闭。不过这话说起来容易做起来难,因为 [Gartner] 预测,到 2017 年,50% 的 IoT 解决方案将来自成立不到三年的初创公司。 [medium-revolv]: https://medium.com/@arlogilbert/the-time-that-tony-fadell-sold-me-a-容器-of-hummus-cb0941c762c1#.rmppks86a [perfect-cloud]: /博客/2016/01/19/perfect-home-自动化/#your-system-should-run-at-home-not-in-the-cloud [Gartner]: http://www.gartner.com/newsroom/id/2869521 --- url: /home-assistant/blog/2016-04-07-static-website.md --- # Static website Home Assistant 的前端借助本地 Web 服务器提供服务。如果你已经[自定义](/home-assistant/getting-started/devices/#customizing-devices-and-服务)过安装,那你其实已经在使用这个功能了。位于 Home Assistant 配置目录(`.homeassistant`)中的 `www` 文件夹内容,会通过 `/local` 对外提供(例如 `index.html` 文件对应 `https://localhost:8123/local/index.html`)。 但你还能做得更多!你不仅可以在这里托管用于自定义的图像,还可以托管 HTML 文件,甚至包含 CSS 和 Javascript 的 Web 应用。

过去,“Smart mirror” 这个热词在我们的[聊天室](https://discord.gg/c5DvZ4e)里被提到过好几次,甚至还出现在了 [issue tracker](https://github.com/home-assistant/home-assistant/issues/1392) 中。如果你家里或公寓里已经在某处运行了 Home Assistant,那么现有方案([Smart mirror](https://docs.smart-mirror.io/)、[MagicMirror](https://michaelteeuw.nl/tagged/magicmirror) 和 [HomeMirror](https://github.com/HannahMitt/HomeMirror))看起来就有点“杀鸡用牛刀”了。为什么不直接在平板上显示由 Home Assistant 提供的网页呢?不需要 app,也不需要在后台运行树莓派。 实现这个目标的方法有很多,比如 [RESTful API](/home-assistant/developers/rest_api/)、~~Python API~~,或者任一 [history components](/home-assistant/integrations/index.md#history)。如果要做成网页,我使用的是 [MQTT Eventstream component](/home-assistant/integrations/mqtt_eventstream/index.md) 和 [Eclipse Paho JavaScript Client](https://www.eclipse.org/paho/clients/js/)。 [HBMQTT](https://pypi.org/pypi/hbmqtt) 代理为 MQTT 提供了 websockets 支持,而网页中引入的 mqttws31.js 让你可以访问 MQTT 消息。整个过程只需几分钟。好吧,实际上我花的时间更久一点,因为我并不是 Javascript 老手,要写出展示你环境细节的软件部分并不轻松。源码在 ,上面的截图就是最终效果。我猜任何熟悉 Javascript 的人都能把代码进一步精简,并让它更灵活。不过,这本来就只是一个原型和展示,用来在这篇博客里放一张图像。 希望这篇小文章能给你一些灵感,用一种不那么传统的方式扩展 Home Assistant。 --- url: /home-assistant/blog/2016-04-09-onkyo-panasonic-gtfs-and-config-validation.md --- # 0.17: Onkyo, Panasonic, GTFS and config validation Another awesome 发布 ready to hit your homes. YAML can be hard for beginners and more experienced automators. So to help catch those pesky 错误 that sneak into your files we've been hard at work to introduce config validation! Especially huge thanks to [@jaharkes] for his hard work on this. Config validation is still in its early stages. More common platforms and components have been added but we didn't do everything yet. When we encounter an invalid config we will now write a 警告 to your 日志. You can see those in the 前端 by clicking on the last developer tool. We're looking into options to make it more clear - it is a work in progress. Another big thing is the addition of GTFS support. You probably don't know it, but GTFS is the standard that public transit companies all over the world use to distribute their schedule. This means that you can now have the time of the next bus/train/etc right in your 前端. * Config validation ([@balloob], [@jaharkes]) * 传感器: [GTFS] support (public transit open standard) ([@robbiet480]) * 摄像头: [树莓派] support added ([@LucaSoldi]) * Z-Wave: improved startup reliability ([@srcLurker]) * Media Player: [Onkyo receiver] now supported ([@danieljkemp]) * 传感器: [Loop Energy] now supported ([@pavoni]) * Thermostat: [Z-Wave] now supported ([@coteyr], [@turbokongen], [@luxus]) * 传感器: [NZBGet] now supported ([@justyns]) * Media Player: [Panasonic Viera TV] now supported ([@florianholzapfel]) * Thermostats: Use whole degrees if 用户 uses Fahrenheit ([@JshWright]) * 前端: more material love ([@balloob]) [@balloob]: https://github.com/balloob/ [@coteyr]: https://github.com/coteyr/ [@danieljkemp]: https://github.com/danieljkemp/ [@florianholzapfel]: https://github.com/florianholzapfel/ [@jaharkes]: https://github.com/jaharkes/ [@JshWright]: https://github.com/JshWright/ [@justyns]: https://github.com/justyns/ [@LucaSoldi]: https://github.com/LucaSoldi/ [@luxus]: https://github.com/luxus/ [@pavoni]: https://github.com/pavoni/ [@robbiet480]: https://github.com/robbiet480/ [@srcLurker]: https://github.com/srcLurker/ [@turbokongen]: https://github.com/turbokongen/ [GTFS]: /integrations/gtfs [Loop Energy]: /integrations/loopenergy [NZBGet]: /integrations/nzbget [Onkyo receiver]: /integrations/onkyo [Panasonic Viera TV]: /integrations/panasonic_viera [树莓派]: /integrations/rpi_camera [Z-Wave]: /integrations/zwave/#温控 ### Backward-incompatible changes As of now we are not aware of any backward-incompatible changes. However, it might be that Home Assistant will not start for you because of an invalid 配置. A common mistake that people are making is that they are still referring to `execute_service` in their 脚本 configs. This should be `service`. --- url: /home-assistant/blog/2016-04-17-updated-documentation.md --- # Updated documentation One of the main complaints that we receive is something along the lines "I read that X is possible yet I am unable to find it on the website.". This post is to announce that we have taken the first steps to improve it by revamping the [入门] and [开发者] sections. It's still a work in progress but we now have a solid foundation to build on for the future 👍. Our 文档 has been going through various phases. Initially it was just the README in our GitHub repository. I discovered Jekyll and GitHub pages in December 2014 and 创建 home-assistant.io. I more or less broke the README in 5 pages and [called it a website]. Back then we had a whopping 11 components! As Home Assistant grew, so did our 文档. [Fabian Affolter](https://github.com/fabaff) does an amazing job in making sure there is at least a 文档 stub for each new feature that lands. And that's quite a feat given our [frequent releases](/home-assistant/blog/categories/发布-notes/)! But despite all the efforts, the 文档 outgrew our existing 文档 organization. Today it has been almost 1.5 years since we started the website. We now have [264 components and platforms] under our belt and have been honored with 1.5 million page views ✨. And hopefully we now also have 文档 that our community deserves. [入门]: /getting-started/ [开发者]: https://开发者.home-assistant.io/ [called it a website]: /博客/2014/12/18/website-launched/ [264 components and platforms]: /integrations/index.md Finally, if you see some content that could use more clarifcation or is outdated, don't hesitate to use the 'Edit in GitHub' link that is present on each page. --- url: /home-assistant/blog/2016-04-19-to-infinity-and-beyond.md --- # To Infinity and Beyond 🚀 After 2.5 years I think we can proudly say: Home Assistant is a success. I write *we* because Home Assistant is no longer a one-person side project. It has become the side project of many people who spend countless hours on making Home Assistant the best home 自动化 software out there. To acknowledge this we migrated the repositories from being under my name to be under our own [organization on GitHub][gh-ha]. On our journey we've reached many noteworthy milestones: * \#1 on HackerNews * Featured on ProductHunt * Trending repository on GitHub * 3000 stars on GitHub * 1.5 million page views on our website * Speaker at OpenIoT Summit 2016 All these accomplishments are a nice pat on the back but our journey is far from over. There are a lot of challenges ahead if we want to become the go to solution for home 自动化 *for everyone*. Until now the focus has been on making a platform that 开发者 love to use. A platform that is simple but customizable. A platform that is both powerful and reliable. But most important: a platform that is local and open. Home Assistant does a great job at all these things. There will be some major challenges ahead of us to target groups other than 开发者. Easy 安装 and easy 配置 being the #1. I'm sure that we'll be able to eventually achieve these goals. I can't say yet how or when. As with everything Home Assistant, we'll take tiny steps, gathering feedback along the way to make sure we're solving the right problems. I am confident that we will get there because we are set up for success: we have a robust architecture, high test coverage and an active community of world class 开发者 and 用户. On top of that, we use Python which allows us to move fast and tackle complex problems in elegant ways. It is so easy to learn that it allows any programmer, experienced or not, to contribute support for 设备 and 服务. It's as simple as [filling in the blanks]. I would like to put out a big thank you to all our contributors who make Home Assistant what it is today. It doesn't Matter if it is form of code, 文档 or giving support in our [chat 房间] or [forums]. You. all. rock. Cheers to the future! Paulus [gh-ha]: https://github.com/home-assistant/ [filling in the blanks]: /developers/platform_example_sensor/#code [chat 房间]: https://discord.gg/c5DvZ4e [forums]: https://community.home-assistant.io/ --- url: /home-assistant/blog/2016-04-21-bluetooth-lg-webos-tvs-and-roombas.md --- # 0.18: Bluetooth, LG WebOS TVs and Roombas. It's time for 0.18. This 发布 cycle is 2 days shorter than usual as I'll be traveling to Europe. This also means that it can take some more time before you get feedback on PRs. Since the last 发布 we have moved all Home Assistant source code etc into its own [organization on GitHub](https://github.com/home-assistant). We're growing up! This sadly did cause us to have to move all Docker 图像. Check the backward-incompatible changes section for more info.
* Media Player: redesign in the UI! ([@DesignFirst], [@balloob]) * New component: [Zeroconf] for Home Assistant discovery ([@robbiet480]) * Garage door: [MQTT] now supported ([@joelash]) * Thermostat: [Homematic platform] now supports Max! 设备 ([@bimbar]) * New component Thinkingcleaner ([开关][开关.thinkingcleaner]/[传感器][传感器.thinkingcleaner]) to integrate your Roomba into Home Assistant ([@TheRealLink]) * New component: [upnp] to automatically open a upnp port on your router for Home Assistant ([@robbiet480]) * Thermostat: [EQ3 蓝牙 Smart Thermostats] now supported ([@bimbar]) * New component [Feedreader] will track RSS feeds ([@shaftoe]) * 设备 Tracker: [蓝牙 tracking platform] added ([@vmulpuru]) * Media Player: [LG WebOS TVs][媒体播放器.lg] now supported ([@TheRealLink]) * 通知: [LG WebOS TVs][通知.lg] now supported ([@TheRealLink]) * HTTP: Use constant time comparison for auth ([@JshWright]) * Config and 服务 validations ([@jaharkes], [@Danielhiversen]) * MySensors: 实体 IDs will more clearly differentiate between node ID and child ID ([@oeysteinhansen]) * MySensors: Add support for [ethernet gateway][mysensors] ([@MartinHjelmare]) * Media player: [Plex] will now monitor the server and add clients as they pop up ([@infamy]) * 核心: We now use iso8601 for datetimes ([@balloob]). * Media Player: [MPD] now supports 服务 to play playlists ([@Cinntax]) * Z-Wave should be a little bit more stable ([@Turbokongen]) * Media Player: [Sonos] will now only add visible 设备 ([@jpmossin]) * 灯光: [Wink] will now allow controlling the colors ([@bradsk88]) [@balloob]: https://github.com/balloob/ [@bimbar]: https://github.com/bimbar/ [@bradsk88]: https://github.com/bradsk88/ [@Cinntax]: https://github.com/Cinntax/ [@Danielhiversen]: https://github.com/Danielhiversen/ [@DesignFirst]: https://github.com/DesignFirst/ [@infamy]: https://github.com/infamy/ [@jaharkes]: https://github.com/jaharkes/ [@joelash]: https://github.com/joelash/ [@jpmossin]: https://github.com/jpmossin/ [@JshWright]: https://github.com/JshWright/ [@MartinHjelmare]: https://github.com/MartinHjelmare/ [@oeysteinhansen]: https://github.com/oeysteinhansen/ [@robbiet480]: https://github.com/robbiet480/ [@shaftoe]: https://github.com/shaftoe/ [@TheRealLink]: https://github.com/TheRealLink/ [@Turbokongen]: https://github.com/Turbokongen/ [@vmulpuru]: https://github.com/vmulpuru/ [蓝牙 tracking platform]: /integrations/bluetooth_tracker [EQ3 蓝牙 Smart Thermostats]: /integrations/eq3btsmart/ [mysensors]: /integrations/mysensors/ [Feedreader]: /integrations/feedreader/ [Homematic platform]: /integrations/homematic/ [媒体播放器.lg]: /integrations/webostv#media-player [通知.lg]: /integrations/webostv [MPD]: /integrations/mpd [MQTT]: /integrations/遮盖.MQTT/ [Plex]: /integrations/plex#media-player [Sonos]: /integrations/sonos [传感器.Thinkingcleaner]: /integrations/thinkingcleaner#传感器 [开关.Thinkingcleaner]: /integrations/thinkingcleaner#开关 [upnp]: /integrations/upnp/ [Wink]: /integrations/wink#灯光 [Zeroconf]: /integrations/zeroconf/ ### Backward-incompatible changes * We have migrated our datetime format to be iso8601. This will only impact you if you are consuming the date times from the API directly. You can ignore this if you are just using Home Assistant via 配置 and the 前端. * The constant `TEMP_CELCIUS` is now correctly called `TEMP_CELSIUS`. Old one is deprecated and will eventually be removed. * The location of the Docker 图像 has changed. There was no possibility for us to keep maintaining the old 图像 (as it was bound to the GitHub repo under my name) or to make a redirect. So if you are using the Home Assistant Docker 图像, change it to run `homeassistant/home-assistant:latest` for the latest 发布 and `homeassistant/home-assistant:dev` for the latest dev 版本. * MySensors received two big changes that will cause you to 更新 your configs. See [component page][mysensors] for new example config. 1. All MySensors 实体 IDs are different! There was an 错误 in the naming that caused MySensors to append node ID and child ID instead of separating them with an underscore. This has been fixed but will cause all your MySensors 实体 IDs to change. This is a one time breaking change. 2. The second change is that we now support the TCP ethernet gateway. This is causing a slight change to the config format: you have to change `port:` under `gateways` to `device:`. --- url: /home-assistant/blog/2016-04-30-ibeacons-part-1-making-presence-detection-work-better.md --- # iBeacons: Making 在场 detection work better (part I) *本文由 Home Assistant 贡献者 [Greg Dowling](https://github.com/pavoni) 撰写。* 2013 年,Apple 推出了 iBeacon:这是一类低功耗蓝牙(LE)设备,会向附近的设备(包括大多数智能手机)广播自己的标识符。乍看之下,你可能很难想象它有什么用。在这篇分为两部分的博客里,我会尽量解释它为什么有用,以及你如何在 Home Assistant 中使用它。 我开始使用 iBeacon 的原因,是为了提升 presence detection(我想大多数人也是这个原因),所以这会是 *part 1* 的重点。在 *part 2* 里,我会讲如何用 iBeacon 跟踪那些无法自行上报位置的设备。 ### 使用 beacon 改善 OwnTracks 位置数据 当你在 OwnTracks 中使用标准的 *major move* 模式时(这个模式更省手机电量),它有时不会在你希望的时候更新。以我自己为例:我经常在回家路上收到一次位置更新,但到家后反而不更新。结果就是 Home Assistant 以为我还在离家 500 米的地方,需要过很久才意识到我已经回家了。这也让“我回家时自动开灯”的自动化效果很差!甚至有几次,我手机在凌晨 2 点更新位置,直接把灯打开了。好在我太太非常有耐心。 好在 OwnTracks 支持 iBeacon,所以我可以用它来让 presence detection 更可靠。只要 OwnTracks 看到它识别的 beacon,就会发送一次更新。这意味着:如果你把一个 beacon 放在前门,你回家后几秒内 OwnTracks 就能看到它,并发送“已检测到该 iBeacon”的更新。 ### 开始之前 要做到这一点,你首先需要在 Home Assistant 里配置好 [MQTT] 和 [OwnTracks],并确认 HA 已经可以跟踪你的手机。 [MQTT]: /integrations/MQTT/#picking-a-broker [OwnTracks]: /integrations/owntracks 接下来你需要做两件事: * A) 告诉 Home Assistant beacon 在哪里 * B) 告诉 OwnTracks 识别这个 beacon #### A. 告诉 Home Assistant beacon 在哪里 你可以通过创建一个包含 beacon 经纬度的区域,来告诉 Home Assistant 这个固定位置在哪里。你还需要给该区域命名,这个名字稍后在 OwnTracks 里也会用到。下面这个示例区域表示我家车道的位置。 **`configuration.yaml` 示例条目** ```yaml zone: - name: 'Drive' latitude: XXX longitude: YYY radius: 100 ``` `radius` 不会被 beacon 逻辑使用,但会被 GPS 定位逻辑使用。稍后我会再讲这一点。现在你可以先填 50 或 100。 创建好 zone 后,你需要重启 HA。下一步是: #### B. 告诉 OwnTracks 跟踪你的 beacon 1. 打开手机上的 OwnTracks 应用 2. 点按屏幕底部的 `Regions` 菜单 3. 点按右上角的 `+` 按钮 4. 给 beacon 起个名字,例如 `-drive`(名称以 `-` 开头,原因见下文) 5. 将 Share 设置为 `On` 6. 跳过 `Circular Region` 部分 7. 输入你的 beacon 的 `UUID`。这个值可能印在 beacon 本体上,也可以从 iBeacon 配套管理 app 里复制。它通常很长,能复制就尽量复制。 8. 输入 iBeacon 的 `Minor` 和 `Major` 数值,或者都保留为 0(这样会匹配该 `UUID` 下的所有 beacon)

添加 iBeacon 后,你应该能在 OwnTracks 的 region 页面看到它。如果手机能接收到该 beacon 的广播包,OwnTracks 会把对应 Region 标成红色。

当 OwnTracks 看到 beacon(并把 region 变红)时,它也会向 HA 发送一条 MQTT 消息,表示你已经进入该区域。 按上面的配置,当你的手机看到 beacon 时,`device.phone` 的位置会被设置为 `Drive`(GPS 位置设置为 XXX,YYY)。 按这些步骤做完后,你就能提高手机跟踪的可靠性,并及时把更新发给 HA。我在自己家这样配置后,步行回家时灯会在我走到门口前亮起;开车回家时,通常到家几秒内就会亮灯,快到我还没走到前门。 我也很高兴地说,现在不会再在凌晨 2 点收到一次“到家”事件把灯误打开了。希望我已经说服你:iBeacon 值得一试! ### 混合使用 beacon 与 GPS 定位 你很可能会用 beacon 来提升“进入现有 GPS 区域”的可靠性。默认情况下,beacon 或 GPS 位置都可以触发你进入某个 zone。HA 也有一套逻辑来让两者协同工作(当你在 iBeacon Zone 内时,会忽略 GPS 更新)。 不过,beacon 还可以用于 GPS 效果不佳的场景。 比如两个区域挨得太近,甚至上下重叠。 举个例子:我太太在隔壁上班。因为 GPS 精度不够,我没法准确判断她是在家还是在办公室。但用两个 beacon 就可以做到。 要实现这种 presence detection,你需要把 Home Assistant 中某个 zone 设为 `passive`,也就是关闭这个 zone 的 GPS 进入判断。这很重要,否则 HA 会在数据不足的情况下尝试在两个很近的 zone 之间做判断,效果通常不好。 被动 zone 只能通过 iBeacon 进入,因此 GPS 更新总会落到另一个 zone。 我的做法是把 Home zone 设为普通区域,把 Office zone 设为 passive。这样 Home zone 仍可像平常一样通过 GPS 或 beacon 进入。 **`configuration.yaml` 示例条目** ```yaml zone: - name: 'Office' latitude: XXX longitude: YYY radius: 3 passive: true ``` 你也可以用这个技巧尝试判断一个人在哪个房间。即便客厅和卧室是上下楼关系,也可能区分出来(当然,beacon 信号会穿过墙壁和楼板)。 要达到理想效果,你大概率需要调试 beacon 的发射功率,让信号覆盖范围更贴合你要跟踪的位置。如果你成功做到了,欢迎告诉我(我家是开放式格局,所以这个方法对我不太适用)。 ### 结论 Presence tracking 听起来很简单,但它是家庭自动化里非常关键、也非常容易踩坑的一环。真正做起来你会发现,要把 presence detection 做准并不容易。对我来说,iBeacon 显著提升了位置判断的可靠性和及时性,也希望这篇文章能鼓励你试试看。 ### 提示 关于 OwnTracks 和 beacon 的配置,你可以在 [here](http://owntracks.org/booklet/features/beacons/) 了解更多。 关于在 Home Assistant 中使用 beacon 的配置说明,见 [here](/home-assistant/integrations/owntracks.md)。 #### 连接与断连 在 OwnTracks 里,region 名称如果以 `-` 开头,会被当作一个提示:不要因为丢失单个数据包就断开连接。这有助于保持与 beacon 的持续连接。 不过,即使启用了这个特性,我也发现仍然可能断连(而且不同 beacon 厂商和型号差异明显,我会在 *part 2* 展开说)。所以在 HA 里最好预先考虑到“误触发进入/离开事件”的可能性。你可以通过提高 beacon 的广播频率、增强发射功率来改善这个问题(但两者都会更快耗电)。这些参数通常可以在 iBeacon 厂商提供的 app 中调整。你也可以选择一些高功率 beacon(对我来说效果不错)。 在自动化里,你可以使用 `for:` 来避免短暂断连时触发,也可以用带延时的脚本。*part 2* 里我会给出示例。 #### 在同一个 Zone 中使用多个 beacon iBeacon 包含一个 `UUID`(同一厂商的 beacon 往往相同),以及 `minor` 和 `major` 编号。如果你把两个 beacon 设置成完全相同的参数,OwnTracks 会认为它们位于同一位置。 这意味着你可以在家里布置多个 beacon;只要连上其中任意一个,OwnTracks 和 HA 都会把它判定为 `home`。这样能减少断连影响。 你也可以用同一个 `UUID`,但让 `major` / `minor` 不同;再把 OwnTracks 中该 region 的 `major` / `minor` 设为 0,这样也能达到相同效果。 *也别忘了看 [part II](/home-assistant/blog/2016/05/26/ibeacons-how-to-track-things-that-cant-track-themselves-part-ii/),我会在那里介绍如何用 iBeacon 跟踪任意物品。* --- url: /home-assistant/blog/2016-05-06-open-iot-summit-talk.md --- # 演讲:使用 Home Assistant 自动化您的家庭 (OpenIoT Summit) 四月初,我在圣地亚哥的 OpenIoT Summit 上发表了关于 Home Assistant 的演讲。我介绍了 Home Assistant 的架构,并解释了如何开始集成您的设备。非常感谢我的雇主 AppFolio([我们正在招聘!])让我参加此次活动。[幻灯片。]
[幻灯片。]: https://docs.google.com/presentation/d/1P2WsmwGSSni4gAriY5IA0-m-FUGO1kno3gIkRYz20Kw/edit#slide=id.p [我们正在招聘!]: http://www.appfolioinc.com/jobs-openings --- url: /home-assistant/blog/2016-05-07-empowering-scripts-and-alexa.md --- # 0.19: Empowering 脚本 and Alexa 这次发布很重磅。到目前为止,我们的自动化和脚本一直比较静态。从今天开始,它们会变得更动态一些。 **脚本** 现在可用于自动化,也可用于响应 Alexa/Amazon Echo。这两个组件现在都会暴露可在脚本模板中使用的数据(包括 `from_state`!)。你还可以通过向脚本服务传递数据,把变量传给脚本实体。 ```yaml automation: trigger: platform: mqtt topic: some/notify/topic action: service: notify.notify data: message: automation 2: trigger: platform: state entity_id: light.hue action: service: notify.notify data: message: is now ``` **实体命名空间(Entity namespaces)** 允许你控制特定平台生成的实体 ID。例如,你可以通过下面的配置把 `light.living_room` 变成 `light.holiday_home_living_room`: ```yaml light: platform: hue entity_namespace: holiday_home ``` * 自动化: allow [脚本 syntax] for 动作 ([@balloob]) * 自动化: expose [`trigger` variable][触发器-variable] to 脚本 模板 ([@balloob]) * 脚本: allow passing variables for 脚本 模板 in the [脚本 服务 calls] ([@balloob]) * Alexa/Amazon Echo: allow [脚本 syntax] for 动作 ([@balloob]) * Alexa/Amazon Echo: [expose intent variables] to 脚本 模板 ([@balloob]) * 脚本 syntax: [条件 now supported] to interrupt execution ([@balloob]) * 自动化: use [new 条件 syntax] ([@balloob]) * 脚本 syntax: two new 条件 [`and`][con-and] and [`or`][con-or] to combine 条件 ([@balloob]) * Any platform: Allow setting [实体 namespace] to prefix entity\_ids. ([@balloob]) * 开关: [树莓派 generic 433 Mhz GPIO adapters][rpi-rf] now supported ([@milaq]) * Z-Wave: use more sane defaults ([@danieljkemp]) * Media Player: [Snapcast] now supports picking a source ([@happyleavesaoc]) * MySensors: major cleanup ([@MartinHjelmare]) * 二元sensor: [Command line 传感器] now supports classes ([@fabaff]) * MQTT: [allow client key 认证] ([@timharton]) * 传感器: [Forecast.io] now supports minutely, hourly and daily summaries ([@aceat64]) * Media Player: [Pioneer AVR] now supported ([@kylehendricks]) * 开关: [Acer Projectors] now supported ([@deisi]) * New [HVAC component] added with Z-Wave support ([@turbokongen]) * Support added for [OctoPrint] ([@w1ll1am23]) * 配置.yaml can now refer to environment variables using `!env_var` ([@bah2830]) * 门锁: [Z-Wave][门锁.zwave] now supported ([@devdelay]) * New [Dweet component] to export data ([@fabaff]) * Media Player now supports stop command + initial kodi support ([@hmronline]) * Zigbee: push updates now supported ([@flyte]) * Wink 设备 with battery level will now show these ([@w1ll1am23]) * 模板: new [`as_timestamp`] method now available ([@srcLurker]) * API: Add \[`/api/discovery_info`] with basic instance info ([@robbiet480]) * 传感器: [Google Maps travel time] added ([@Danielhiversen]) * HTTP: Allow adding [CORS headers] ([@robbiet480]) * 传感器: [Fitbit] support added ([@robbiet480]) * Bug fixes and tweaks by [@turbokongen], [@danieljkemp], [@Danielhiversen], [@TheRealLink], [@persandstrom], [@sander76], [@fabaff], [@ishults], [@Bart274], [@robbiet480], [@Cinntax], [@blackdog70], [@gwendalg], [@JshWright], [@kylehendricks], [@bradsk88], [@shaftoe], [@molobrakos], [@bah2830], [@nkgilley] [脚本 syntax]: /getting-started/脚本/ [触发器-variable]: /getting-started/自动化-templating/#available-触发器-data [脚本 服务 calls]: /integrations/脚本/#passing-parameters-in-服务-calls [expose intent variables]: /integrations/alexa/#configuring-home-assistant [条件 now supported]: /getting-started/脚本-条件/ [new 条件 syntax]: /getting-started/脚本-条件/ [con-and]: /getting-started/脚本-条件/#and-条件 [con-or]: /getting-started/脚本-条件/#or-条件 [实体 namespace]: /topics/platform_options/#实体-namespace [rpi-rf]: /integrations/rpi_rf [Forecast.io]: /integrations/darksky [Snapcast]: /integrations/snapcast [Command line 传感器]: /integrations/传感器.command_line/ [allow client key 认证]: /integrations/MQTT/ [Pioneer AVR]: /integrations/pioneer [Acer Projectors]: /integrations/acer_projector [HVAC component]: /integrations/温控/ [OctoPrint]: /integrations/octoprint/ [Z-Wave]: /integrations/zwave/ [门锁]: /integrations/门锁/ [门锁.zwave]: /integrations/zwave#门锁 [Dweet component]: /integrations/dweet/ [`as_timestamp`]: /topics/templating/#home-assistant-模板-extensions [Google Maps travel time]: /integrations/google_travel_time [CORS headers]: /integrations/http/ [Fitbit]: /integrations/fitbit [@balloob]: https://github.com/balloob/ [@milaq]: https://github.com/milaq/ [@danieljkemp]: https://github.com/danieljkemp/ [@happyleavesaoc]: https://github.com/happyleavesaoc/ [@MartinHjelmare]: https://github.com/MartinHjelmare/ [@fabaff]: https://github.com/fabaff/ [@timharton]: https://github.com/timharton/ [@aceat64]: https://github.com/aceat64/ [@kylehendricks]: https://github.com/kylehendricks/ [@deisi]: https://github.com/deisi/ [@turbokongen]: https://github.com/turbokongen/ [@w1ll1am23]: https://github.com/w1ll1am23/ [@bah2830]: https://github.com/bah2830/ [@devdelay]: https://github.com/devdelay/ [@hmronline]: https://github.com/hmronline/ [@flyte]: https://github.com/flyte/ [@srcLurker]: https://github.com/srcLurker/ [@robbiet480]: https://github.com/robbiet480/ [@Danielhiversen]: https://github.com/Danielhiversen/ [@TheRealLink]: https://github.com/TheRealLink/ [@persandstrom]: https://github.com/persandstrom/ [@sander76]: https://github.com/sander76/ [@ishults]: https://github.com/ishults/ [@Bart274]: https://github.com/Bart274/ [@Cinntax]: https://github.com/Cinntax/ [@blackdog70]: https://github.com/blackdog70/ [@gwendalg]: https://github.com/gwendalg/ [@JshWright]: https://github.com/JshWright/ [@bradsk88]: https://github.com/bradsk88/ [@shaftoe]: https://github.com/shaftoe/ [@molobrakos]: https://github.com/molobrakos/ [@nkgilley]: https://github.com/nkgilley/ ### Deprecations * 条件 in 自动化 should now specify which 条件 to use with `condition:` instead of `platform:`. For example `condition: state`. * RFXtrx has a new config format. Old RFXtrx config format: ```yaml devices: 123efab1: name: My DI.0 light device packetid: 1b2200000890efab1213f60 ``` New RFXtrx config format: ```yaml devices: 1b2200000890efab1213f60: name: My DI.0 light device ``` --- url: /home-assistant/blog/2016-05-12-video-configuring-home-assistant.md --- # 视频:如何配置 Home Assistant 来自 [BRUH automation](http://www.bruhautomation.com) 的 Ben 制作了许多很棒的视频,介绍他如何使用 Home Assistant 以及您如何也能开始使用它。下面的视频将引导您完成 Home Assistant 的配置。请欣赏! 请务必订阅 [他的 YouTube 频道](https://www.youtube.com/channel/UCLecVrux63S6aYiErxdiy4w) 以获取更多 Home Assistant 视频。
--- url: /home-assistant/blog/2016-05-18-why-we-use-polymer.md --- # Why we use web components and Polymer 我一直想写这篇文章,因为我们经常被问到类似的问题:*“为什么 Home Assistant 要用 Polymer?为什么不用 React、Redux 之类的?”* 这很容易理解。Polymer 在 Web 框架世界里确实属于“冷门选手”。有大公司背书并不等于一定流行,也不等于社区一定活跃,这一点从使用 Polymer 的项目数量上就能看出来。 不过,[我们确实在用 Polymer,而且它很棒][demo]。为了说明原因,我会经常拿 React 的工作流来对比,因为它在很多方面做得很好,同时也会说明这些事情在 Polymer 里是如何实现的。 Polymer 和 React 一样,都是做组件化 Web 开发,但 Polymer 依托的是 Web 标准:[web components]、[CSS variables]。这些标准目前还没有被所有浏览器完整原生支持,但主流浏览器都在实现它们,这就是未来。现在我们通过 polyfill 也能很好地运行;未来 Home Assistant 的 Web 应用可以直接在浏览器原生运行,速度会更快。 Polymer 在开发者体验上还没有 React 加 [React Dev Tools] 那么成熟,但这只是时间问题。各家浏览器的开发者工具近几年进步很快,而每一次改进都在帮助 Web Components 获得更好的支持。 Polymer 对 Home Assistant 的另一个重要优势是我们可以[免费获得 Material Design][material design for free]。Polymer 自带的 Material Design 组件质量很高。Google 自己也在使用这些组件,并确保它们在性能以及屏幕阅读器/键盘可访问性方面表现优秀。作为一个开源项目,我们能“外包”出去的基础能力越多越好,这样贡献者就能把精力集中在核心产品上:家庭自动化。 那 Flux、数据管理,以及组件之间交互怎么办?其实和 React 或其他组件化框架很像。类 Flux 架构在 Polymer 里和在 React 里一样成立:当数据变化时,会更新组件属性,并继续向子组件传递。在 Home Assistant 中,我们使用 [NuclearJS],配合我们[自定义的 Polymer 绑定][own Polymer bindings]。在子组件向父组件传递数据时,Polymer 的模式是用 DOM 事件而不是回调,但最终效果一致。它们相似到什么程度?我只花了两个小时,就基于核心逻辑做出了一个 [React Native 前端][ha-rn]。 那 Babel 和 ES2015 呢?这部分也有方案。每个 Web Component 都由一个 HTML 模板和一个 JavaScript 类组成。你可以把 HTML 模板理解为 React 里的 render 方法。在 Home Assistant 里,我们让 HTML 模板彼此导入,同时为每个组件背后的 JavaScript 类走独立的构建链。这使我们可以在 JavaScript 部分使用 Babel 和 NPM 模块([more info here][tools-js])。 当然,这也带来了与其他 JS 框架类似的缺点:浏览器在解析 JavaScript 时会阻塞页面绘制,而不是渐进式渲染页面。不过这在当前前端世界里几乎是默认前提,我们也期待模块打包工具最终能更好地解决这个问题。Tree shaking 在这方面就是一个很有前景的改进方向。 这篇博客的大部分内容都在把 Polymer 和 React 做比较。Polymer 在很多方面和 React 很像,但演进成熟度还没到同一水平。我喜欢 React,但我不认为它会永远是主流。参考过去热门 JS 框架的发展趋势,React 很可能也会被下一个更好的框架替代。 但 Web Components 不一样。它是 HTML 标准的一部分,会长期存在。这让我们在 Home Assistant 的“虚拟总部”里更安心:我们不需要担心为了追热点而被迫重写整个前端,也不用担心将来没人愿意为了一个“遗留系统”再引入一整套额外依赖。 以上,就是我们选择 Polymer 的原因。 [web components]: https://www.w3.org/standards/techs/components#w3c_all [CSS variables]: https://www.w3.org/TR/css-variables/ [React Dev Tools]: https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en [NuclearJS]: https://optimizely.github.io/nuclear-js/ [own Polymer bindings]: http://paulusschoutsen.nl/博客/2015/07/using-polymer-with-flux-and-a-global-app-状态/ [ha-rn]: https://github.com/balloob/home-assistant-react-native-ios [tools-js]: https://github.com/home-assistant/home-assistant-polymer#building-the-app [material design for free]: https://elements.polymer-project.org/browse?package=paper-elements [demo]: /demo --- url: /home-assistant/blog/2016-05-21-release-020.md --- # 0.20: Roku, Last.fm, AWS, Twilio 0.20 带来了大量新的支持内容。 * 现在支持无需 forking 的重启 ([@jaharkes]) * 为 recorder 组件添加了 [purge days option] ([@justyns], [@infamy]) * 为实体组件提供通用的 load\_platform 机制 ([@kellerza]) * 模板:新增 [`relative_time`] 函数,可渲染如 `7 seconds ago` 这样的文本 ([@robbiet480]) * 传感器:[supervisord] 现已支持 ([@happyleavesaoc]) * Docker:不再出现 requests 的 SSL 错误 ([@lwis]) * 媒体播放器:[Google Play Music Desktop Player] 现已支持 ([@GreenTurtwig]) * 通知:新增 [Twilio SMS] 平台 ([@robbiet480]) * 设备追踪器:[Asus WRT] 现在默认使用 SSH(但仍可选择 telnet) ([@froz]) * 支持 [Nest Protect] 烟雾报警器 ([@khabi]) * Configurator:允许向用户提供链接 ([@mnestor]) * 媒体播放器:[Roku] 现已支持 ([@bah2830]) * 传感器:[Last.fm] 现已支持 ([@darookee], [@GreenTurtwig]) * 通知:现已支持 Amazon Lambda、SNS、SQS ([@robbiet480]) * 灯光:允许在 turn\_on 命令中使用人类可读颜色名称 ([@robbiet480]) * YAML:新增 include dir 选项 [`!include_dir_merge_list`] 和 [`!include_dir_merge_named`] ([@happyleavesaoc]) * 媒体播放器:[LG Netcast TVs] 现已支持 ([@wokar]) * 媒体播放器:允许在 Sonos 上将媒体加入队列 ([@shaftoe]) * 通知:[Ecobee thermostats] 现已支持 ([@nkgilley]) * 传感器:新增 [Mold indicator] ([@xifle]) * 新增导出到 [Logentries] 的支持 ([@omgapuppy]) * Group 的更多信息对话框在可用时允许控制 group 域 (@fignuts) ### 不向后兼容的变更 * Asus WRT 现在默认使用 SSH,Telnet 作为可选项 ```yaml device_tracker: platform: asuswrt protocol: telnet ``` [@bah2830]: https://github.com/bah2830 [@darookee]: https://github.com/darookee [@froz]: https://github.com/froz [@GreenTurtwig]: https://github.com/GreenTurtwig [@happyleavesaoc]: https://github.com/happyleavesaoc [@infamy]: https://github.com/infamy [@jaharkes]: https://github.com/jaharkes [@justyns]: https://github.com/justyns [@kellerza]: https://github.com/kellerza [@khabi]: https://github.com/khabi [@lwis]: https://github.com/lwis [@mnestor]: https://github.com/mnestor [@nkgilley]: https://github.com/nkgilley [@omgapuppy]: https://github.com/omgapuppy [@robbiet480]: https://github.com/robbiet480 [@shaftoe]: https://github.com/shaftoe [@wokar]: https://github.com/wokar [@xifle]: https://github.com/xifle [`!include_dir_merge_list`]: /topics/splitting_configuration/#advanced-usage [`!include_dir_merge_named`]: /topics/splitting_configuration/#advanced-usage [`relative_time`]: /topics/templating/#home-assistant-模板-extensions [Asus WRT]: /integrations/asuswrt [Ecobee thermostats]: /integrations/ecobee [Google Play Music Desktop Player]: /integrations/gpmdp [LG Netcast TVs]: /integrations/lg_netcast [Logentries]: /integrations/logentries/ [mold indicator]: /integrations/mold_indicator/ [Nest Protect]: /integrations/nest#传感器 [purge days option]: /integrations/recorder/ [Roku]: /integrations/roku#media-player [supervisord]: /integrations/supervisord [Twilio SMS]: /integrations/twilio_sms [Last.fm]: /integrations/lastfm --- url: /home-assistant/blog/2016-05-22-get-started-with-all-in-one-installer.md --- # Raspberry Pi all-in-one installer 我们在虚拟的 Home Assistant 总部一直努力工作,让你能更轻松地开始使用 Home Assistant。这就是为什么 [@patchedsoul] 最近推出了一体化安装器。你只需要在运行 Raspbian Jessie 的树莓派中输入一行代码,就可以快速部署一套完整的 Home Assistant 设置: ```bash wget -Nnv https://raw.githubusercontent.com/home-assistant/fabric-home-assistant/master/hass_rpi_installer.sh && bash hass_rpi_installer.sh; ``` 这个功能如果没有 Ben(来自 [BRUH automation](http://www.bruhautomation.com))的新视频就不算完整。视频演示了如何在树莓派上安装 Raspbian Jessie,并使用新的安装脚本来搭建并运行完整的 Home Assistant 系统。
[@patchedsoul]: https://github.com/patchedsoul --- url: /home-assistant/blog/2016-05-26-ibeacons-how-to-track-things-that-cant-track-themselves-part-ii.md --- # iBeacons: How to track things that can’t track themselves (part II) *本文由 Home Assistant 贡献者 [Greg Dowling](https://github.com/pavoni) 撰写。* 在 [Part 1](/home-assistant/blog/2016/04/30/ibeacons-part-1-making-presence-detection-work-better) 中,我介绍了如何使用 iBeacons 改善在场追踪。在第 2 部分里,我会讲如何用 iBeacons 追踪像钥匙这种无法自我追踪的物品。 ### 使用 iBeacons 追踪物品 在第一部分中我提到,iBeacons 只会发送 *I’m here* 数据包,我们利用这一点在你的手机靠近固定 beacon 时触发一次更新。 但 beacon 不一定非要固定。 你的手机大致知道自己所在位置(基于移动基站、Wi-Fi 网络或 GPS)。如果手机看到了 *I’m here* 消息,它就知道 beacon 在附近。 如果你的手机能够记住(或告知服务器)它上次看到 iBeacon 时的位置,那么它也就知道 beacon 当时在哪里。因此,即使 iBeacon 本身不具备追踪技术,你依然可以追踪它的位置。 所以如果你把 iBeacon 放在钥匙上或车里,就可以追踪它们。

这是我的钥匙,上面粘了一个 Estimote Nearable iBeacon。虽然不太好看,但很有效!

相比我在 Part 1 里讲的固定 beacon,让 OwnTracks 和 HA 追踪移动 beacon 更容易,因为你只需要在 OwnTracks 中配置 iBeacon,完全不需要配置 HA。 :::警告 OwnTracks 目前仅在 iOS 上支持移动 beacon。 ::: 你可以按照 part 1 中的相同方式设置 beacon。唯一的区别是,region 不再使用位置名称(例如 -drive),而是使用你想追踪的设备名称(例如 -keys)。记得保留前导的 `-`,这样连接会更可靠。

添加 iBeacon 后,你应该能在 OwnTracks 的 region 页面看到它。如果手机能够接收到该 beacon 的数据包,OwnTracks 会把对应的 Region 标成红色。 由于你为该 region 打开了 *Share*,当 OwnTracks 看到 beacon 时会向 HA 发送一条消息。如果 HA 之前没见过这个 beacon,就会把它添加为一个被追踪的设备。因此你会在 HA 中看到一个名为 `device_tracker.beacon_[name]` 的新设备,它的位置就是你的手机上次看到该 beacon 时认为的所在地。

如果你的手机在仍处于 beacon 范围内时移动并向 HA 发送新位置,HA 就会更新 beacon 的位置。所以当你开车出行时,你会看到手机和 *device\_tracker.beacon\_car* 一起移动。 如果你把车停好去购物,*device\_tracker.beacon\_car* 就会停止移动。 当基础追踪可用后,你可以使用自动化来实现例如“车辆回家时打开大门”这类功能。 ```yaml automation: - alias: "Open gate" trigger: - platform: state entity_id: device_tracker.beacon_car from: "not_home" to: "home" condition: - condition: state entity_id: switch.gate state: "off" action: service: switch.turn_on target: entity_id: switch.gate ``` 或者在你把钥匙落下时提醒你。 ```yaml automation: - alias: "Forgotten keys" trigger: platform: template value_template: '' condition: condition: template value_template: '' action: service: script.turn_on target: entity_id: script.send_key_alert - alias: "Forgotten keys - cancel" trigger: platform: template value_template: '' condition: - condition: state entity_id: script.send_key_alert state: "on" action: service: script.turn_off target: entity_id: script.send_key_alert ``` ```yaml script: send_key_alert: sequence: - delay: minutes: 2 - service: notify.notify data: message: "You forgot your keys" target: "device/gregs_iphone" ``` (需要延迟有两个原因: 1. HA 更新 beacon 和手机位置的时间点会略有差异,所以你不希望自动化在两次更新之间的空档被触发 2. 我发现 beacon(尤其是低功耗的 Estimote Nearables)有时会断连几秒,因此最好先等一两分钟再判断你是否真的把钥匙落下了) ### 同时使用两种 iBeacon 当然,你也可以同时使用固定和移动 beacon。我希望开车到家时大门自动打开,所以我在车里放了一个 iBeacon 来追踪车辆,在车道上放了另一个 iBeacon 来在我到达时触发位置更新。我还尝试过把高功率 beacon 放进车道上的防水盒里,效果看起来不错,能很好地识别我何时回家。 ### 购买 Beacon 这不是一篇购买指南,但我想简单提一下我正在使用的 iBeacon。我认为你基本可以把任何 iBeacon 与 HA 和 OwnTracks 搭配使用。通常你无法在本地电子商店买到 beacon,所以我简要介绍一下我目前用过的两家供应商。 我从一家叫 Blue Sense Networks 的公司买了不少 iBeacon。我在英国科技创业行业工作,选择他们部分是因为他们是本地初创公司,值得支持。他们的产品、支持和软件看起来都不错。我用了他们多个型号的 beacon,从简单的 USB dongle 到长距离 beacon 都有。它们的产品都可以更换电池(外接电源的 USB 设备则不需要电池),而且可以通过他们的软件配置你想要的各种参数。我曾遇到过一次软件问题,技术支持周末就回复了我(!),并且两天后通过软件发布解决了问题。 这些 beacon 总体表现都不错,而且长距离型号的有效范围确实比我其他 beacon 更远。 我还从一家美国/波兰的初创公司 [Estimote](http://estimote.com/) 买过一些 beacon,他们可能更有名。我买的是他们的 10 个 *nearables* 开发包,这些设备除了是 iBeacon 之外,还会通过自有协议发送其他数据(方向和运动)。如果你在开发自己的应用,这很有意思;但对 OwnTracks 和 HA 来说,它们就是普通 beacon。它们体积小且自带粘性,可以贴在物品上(比如钥匙)。这些设备并不能调整全部参数(UUID/Major/Minor 固定),而且电池不能更换。我还“用坏”过一个 Estimote beacon(我猜是电池没电了),因为我带着它跑了几个月,还摔了很多次!不过它们价格不错、体积小而且防水。 我主要把这些用作“要追踪的设备”,而不是“位置 beacon”。Estimote 也有卖稍大一点、可更换电池的 iBeacon。之前我搞不清如何编辑它们 beacon 参数时,Estimote 支持回复很快,也很愿意帮助(虽然最终答案是“目前还不行”)。 更大一些的 Blue Sense Network beacon 在保持连接方面看起来比 Estimote 更好,不过这也可能是因为 Estimote 的电池不可更换,我不太愿意把功率开到最大并缩短发包间隔。 ### 结论 正如我在 [part 1](/home-assistant/blog/2016/04/30/ibeacons-part-1-making-presence-detection-work-better) 里提到的,我发现 iBeacons 是提升在场检测效果的好方法。我也用它们来追踪像汽车、钥匙这类无法自我追踪的设备。 我还在继续尝试,希望能用 iBeacons 做更多事情。也希望这篇文章能鼓励你一起尝试;如果你实践了,欢迎分享你的经验。 ### 备注 有关文档信息,请查看 [notes at the end of Part 1](/home-assistant/blog/2016/04/30/ibeacons-part-1-making-presence-detection-work-better/#tips)。 --- url: /home-assistant/blog/2016-06-01-community-highlights.md --- # Community Highlights 我们的社区非常乐于助人且充满创造力。如果你还没来过,记得来我们的 [聊天室] 逛逛,一起交流。在这篇博客文章中,我想重点介绍一些社区最近很棒的项目和视频。 ### SceneGen - 用于创建场景的命令行工具 SceneGen 是由 [Andrew Cockburn] 开发的新命令行工具,可帮助创建 Home Assistant 的场景配置。使用时,你先把家里的设备调整到想要的状态,然后运行 SceneGen,它会输出当前状态对应的场景配置。 ### 视频 [Nick Touran] 一直在做 IR 遥控器与 Home Assistant 的集成。他已经把它做成了组件,预计会在几天后的下一个发布中提供。与此同时,他写了一篇[博客文章],并发布了一个展示新集成的视频,非常酷!
来自 [BRUH 自动化] 的 Ben 又发布了一支很棒的视频,讲解如何在 Home Assistant 中使用 MQTT 和 OwnTracks 开始进行位置追踪。
Muhammed Kilic 制作了一支视频,介绍如何使用免费的动态 DNS 服务 DuckDNS,让你的 Home Assistant 实例可以从互联网访问。
[聊天室]: https://discord.gg/c5DvZ4e [Andrew Cockburn]: https://github.com/acockburn [BRUH 自动化]: http://www.bruhautomation.com/ [Nick Touran]: https://partofthething.com [博客文章]: https://partofthething.com/thoughts/?p=1010 --- url: /home-assistant/blog/2016-06-08-super-fast-web-enocean-lirc.md --- # 0.21: Improved Web and support for EnOcean, LIRC and Osram Lightify 现在到了发布 0.21 的时候了,这个版本包含了大量核心改进:我们用标准化的 WSGI 栈替换了自研的 HTTP 栈。这将提升性能、速度与安全性,也会让未来开发高级 HTTP 功能变得更加轻松。 这项工作由非常出色的 Josh Wright 主导。自从他开始参与以来,他的专业知识、严格标准以及对安全的坚持,持续推动 Home Assistant 显著进步。让我们为 Josh 喝彩! 好了,来看本次更新内容: * New HTTP stack based on WSGI ([@JshWright], [@balloob]) * 前端: lots of performance improvements ([@balloob]) * Initial support for EnOcean [灯光][en-灯光], [传感器][en-传感器] and [开关][en-开关] added ([@rubund]) * 灯光: [Osram Lightify] is now supported ([@olimpiurob]) * 灯光: [Insteon Hub] now supports brightness ([@wkonkel]) * Add support for adding HA as Windows 10 tile ([@fabaff]) * 条件: [time 条件] can now cross midnight ([@jaharkes]) * 模板 based 传感器 should now throw less 警告 ([@Bart274]) * New [LIRC component] allows receiving IR commands ([@partofthething]) * The [Feedreader] component will now persist data to disk to prevent duplicate events ([@shaftoe]) * Sun: azimuth 属性 added ([@fabaff]) * New [Flux like 开关 platform] to change 灯光 intensity in the evening ([@nkgilley]) * We no longer crash if you live in a part of the world where the sun never sets ([@balloob]) * Rollershutter: [RFXTRX] now supported ([@jacobtomlinson]) * 开关: [模板 开关] can now execute 脚本 ([@kellerza]) * Z-Wave: automatically heal the network at midnight ([@infamy]) * 传感器: [DTE Energy Bridge] now supported ([@kylehendricks]) * Media Player: [Kodi] now supports different 关闭 commands ([@armills]) ### Backward-incompatible changes * Our work in the WSGI stack is not fully done yet. We still have a minor issues where retrieving the 错误 日志 in the about screen can raise an encoding 错误 * The API used to incorrectly accept a JSON body with form-url-encoded headers. Our cURL examples on the website used to be wrong and have [been updated]. * Make sure your 配置.yaml file contains `frontend:` to serve the 前端 ### Hotfixes 0.21.1 and 0.21.2 We released two hotfixes to address some issues that couldn't wait till the next 发布. ##### 0.21.1 - June 12 * Add eventlet to base requirements to resolve some 安装 issues ([@balloob]) * GTFS will filter out routes in the wrong direction ([@imrehg]) * Recover from rare 错误 条件 from LIRC ([@partofthething]) * Z-Wave autoheal will no longer raise exception ([@balloob]) * Alexa will now execute the 脚本 before making reply ([@balloob]) * Fix MJPEG 摄像头 streaming ([@stjohnjohnson]) * Fix 前端 in older browsers ([@balloob]) * Fix history in more info dialog being cut off ([@balloob]) ##### 0.21.2 - June 15 * Fix input\_select calling the set\_option 服务 again when changed ([@persandstrom]) * Fix more info dialog not being able to open on Safari ([@balloob]) * Add support for OPTIONS HTTP command to get CORS working ([@JshWright]) [@stjohnjohnson]: https://github.com/stjohnjohnson [@imrehg]: https://github.com/imrehg [@persandstrom]: https://github.com/persandstrom [@armills]: https://github.com/armills [@balloob]: https://github.com/balloob [@Bart274]: https://github.com/Bart274 [@fabaff]: https://github.com/fabaff [@infamy]: https://github.com/infamy [@jacobtomlinson]: https://github.com/jacobtomlinson [@jaharkes]: https://github.com/jaharkes [@JshWright]: https://github.com/JshWright [@kellerza]: https://github.com/kellerza [@kylehendricks]: https://github.com/kylehendricks [@nkgilley]: https://github.com/nkgilley [@olimpiurob]: https://github.com/olimpiurob [@partofthething]: https://github.com/partofthething [@rubund]: https://github.com/rubund [@shaftoe]: https://github.com/shaftoe [@wkonkel]: https://github.com/wkonkel [DTE Energy Bridge]: /integrations/dte_energy_bridge [en-灯光]: /integrations/enocean#灯光 [en-传感器]: /integrations/enocean#传感器 [en-开关]: /integrations/enocean#开关 [Feedreader]: /integrations/feedreader/ [Flux like 开关 platform]: /integrations/flux [Insteon Hub]: /integrations/insteon/ [Kodi]: /integrations/kodi [LIRC component]: /integrations/lirc/ [Osram Lightify]: /integrations/osramlightify [RFXTRX]: /integrations/rfxtrx/ [模板 开关]: /integrations/开关.模板/ [time 条件]: /getting-started/脚本-条件/#time-条件 [been updated]: /developers/rest_api/ --- url: /home-assistant/blog/2016-06-13-home-assistant-at-pycon-2016.md --- # Home Assistant at PyCon 2016 距离几位 Home Assistant 开发者前往波特兰参加 [PyCon 2016](一场关于 Python 的大会)已经快两周了。我们此行既是为了学习各种让代码更好的技巧,更重要的是为了交流 Home 自动化。

Home Assistant 开发者 几位 Home Assistant 开发者。从左到右分别是:[Paulus (@balloob)]、[Alex (@infamy)]、[Ryan (@rmkraus)]。

周一时,我(Paulus)面向 400 多位听众做了一场关于 Home Assistant 的演讲!一开始确实有点紧张,但几分钟后就顺利起来了,之后的提问环节也非常精彩。演示文稿可以在[这里][slides]查看,演讲视频就嵌在下方:
最让我印象深刻的一件事,是有很多人主动来告诉我们:他们有多喜欢 Home Assistant,它如何取代了他们之前的方案,他们多么享受为 Home Assistant 做贡献,以及我们的社区有多么乐于助人。这让我为 Home Assistant,尤其是我们的社区,感到无比自豪。 PyCon 有几个我在其他大会上很少见到的优秀形式:开放交流(open spaces)和开发冲刺(sprints)。开放交流让任何人都有机会申请一个房间,组织一场一小时、主题不限的讨论。开发冲刺则在 PyCon 主会程结束后进行,连续四天都有房间供参与者一起协作,动手开发自己喜欢的开源项目。 我的演讲留给问答的时间有限,所以开放交流正好提供了一个很好的机会,既能回答所有未尽问题,也能和社区更深入地建立联系。第一天结束后大家反响很热烈,于是我们第二天又加开了一场开放交流。 我们的开放交流获得了非常积极的反馈,以至于 [Jonathan Baginski][@patchedsoul] 决定在线上再办一次。本月晚些时候我们将举办一场免费的线上研讨会 [Home Assistant Support 101 - Getting around in Home Assistant][webinar],记得提前报名。 PyCon 会议部分结束后,我们又额外花了一天组织 Home Assistant 冲刺活动。这让我们可以帮助大家上手参与 Home Assistant 开发,也因此产出了一些非常棒的贡献。

Home Assistant sprint group photo Home Assistant 冲刺活动合影。

我在 PyCon 度过了一段非常美好的时光。能和大家线下见面真的太棒了,希望明年还能见到你们中的很多人! [PyCon 2016]: https://us.pycon.org/2016/ [Paulus (@balloob)]: https://github.com/balloob/ [Alex (@infamy)]: https://github.com/infamy/ [Ryan (@rmkraus)]: https://github.com/rmkraus/ [@patchedsoul]: https://github.com/patchedsoul/ [slides]: https://docs.google.com/presentation/d/1F1pGOoSf0dD79Dl5dgys0ll7xiuIA4XiQeNeJ-xlqMg/edit [webinar]: https://www.eventbrite.com/e/home-assistant-support-101-getting-around-in-home-assistant-tickets-25943868810 --- url: /home-assistant/blog/2016-06-18-pandora-bt-home-hub-5-and-local-file-camera.md --- # 0.22: Pandora, BT Home Hub 5 and local file 摄像头. 现在到了 0.22 发布的时间。这个发布周期相当艰难,我们不得不为核心改进连续推出两个热修复。不过现在看起来一切都稳定下来了,很多人反馈他们的安装体验比以往更快,偶发的小问题也不再出现。 我们知道新的 Web 栈在 ARM 平台上安装 Home Assistant 时带来了一些问题,很遗憾这包括树莓派和群晖 NAS 系统。我们正在努力提供更好的解决方案。对于树莓派,All-in-One 安装器会帮你处理好所有细节。我们也在更新[独立树莓派安装指南][standalone 树莓派 安装 guide]。 这次发布里有两项很酷的内容值得特别提一下。第一项是对 Pandora 的支持,它基于名为 pianobar 的命令行播放器。这意味着运行 Home Assistant 的机器可以直接连接音箱,为你的家播放音乐。

另一项很棒的新增功能是本地文件摄像头。它看起来很基础,但可以让你用喜欢的第三方绘图工具生成图像,并直接显示在 Home Assistant 仪表盘中。我们很期待看到你用它做出什么! * Media Player: [Pandora] media player now supported ([@partofthething]) * 设备 Tracker: [BT Home Hub 5] now supported ([@lwis]) * 摄像头: New [local file] platform shows any 图像 as 摄像头 ([@Landrash]) * Add [Sonos] snapshot and 恢复 服务 ([@dansullivan86]) * 设备 Tracker: [AsusWRT] in Access Point mode now supported ([@linjef]) * 设备 Tracker: [AsusWRT] login using public key now supported ([@mtreinish]) * 设备 Tracker: [AsusWRT] protocol to use is now auto detected ([@persandstrom]) * 摄像头: [Netatmo] now supported ([@jabesq]) * API 文档 added in [Swagger.yaml format] ([@wind-rider]) * Media Player: [Cast] 设备 can now be stopped ([@michaelarnauts]) * MySensors: [IR 开关 设备] and 服务 now supported ([@MartinHjelmare]) * Bloomsky: [Voltage 传感器] now supported ([@arsaboo]) * 传感器: New [Plex 传感器] monitors friends streaming from your Plex server ([@nkgilley]) * Component [shell command] can now use 模板 to render arguments ([@partofthething]) * Rollershutter: [Wink] is now supported ([@philk]) * Alexa: Updated [文档][alexa] to show how to call 脚本 and 场景 (@acockburn) * 传感器: [SNMP] is now supported ([@fabaff]) * 传感器: Support for Swiss hydrological data ([@fabaff]) ### Breaking change * The new Netatmo support caused us to change how Netatmo are configured. It's now done via its own component. ```yaml netatmo: api_key: API_KEY secret_key: SECRET_KEY username: username password: password ``` ### Hotfix 0.22.1 - June 20 * Insteon Hub 灯光 will load again [@acockburn]: https://github.com/acockburn/ [@arsaboo]: https://github.com/arsaboo/ [@dansullivan86]: https://github.com/dansullivan86/ [@jabesq]: https://github.com/jabesq/ [@Landrash]: https://github.com/Landrash/ [@linjef]: https://github.com/linjef/ [@lwis]: https://github.com/lwis/ [@MartinHjelmare]: https://github.com/MartinHjelmare/ [@michaelarnauts]: https://github.com/michaelarnauts/ [@mtreinish]: https://github.com/mtreinish/ [@nkgilley]: https://github.com/nkgilley/ [@partofthething]: https://github.com/partofthething/ [@persandstrom]: https://github.com/persandstrom/ [@philk]: https://github.com/philk/ [@wind-rider]: https://github.com/wind/ [@fabaff]: https://github.com/fabaff/ [AsusWRT]: /integrations/asuswrt [BT Home Hub 5]: /integrations/bt_home_hub_5 [Cast]: /integrations/cast [IR 开关 设备]: /integrations/mysensors/ [local file]: /integrations/local_file [Netatmo]: /integrations/netatmo/ [Pandora]: /integrations/pandora [shell command]: /integrations/shell_command/ [Sonos]: /integrations/sonos [Wink]: /integrations/wink/#遮盖 [alexa]: /integrations/alexa/#working-with-场景 [Plex 传感器]: /integrations/plex#传感器 [Swagger.yaml format]: https://github.com/home-assistant/home-assistant/blob/dev/docs/swagger.yaml [standalone 树莓派 安装 guide]: /getting-started/安装-raspberry-pi/ [Voltage 传感器]: /integrations/bloomsky/#传感器 [SNMP]: /integrations/snmp#传感器 --- url: /home-assistant/blog/2016-06-23-usb-webcams-and-home-assistant.md --- # Using USB webcams with Home Assistant 过去一个月里,我一直在思考如何再次把 USB 摄像头集成到 Home Assistant 中。主要原因是这能让这些设备重获新生,也能以很低的成本实现视频监控。虽然有一些可用方案,比如 [pygame](http://www.pygame.org/hifi.html) 或 [SimpleCV](http://www.simplecv.org/),但我一直没有真正完成。现在借助 [Landrash](https://github.com/Landrash) 提供的 [Local File 摄像头平台](/home-assistant/integrations/local_file) 和 [motion](http://lavrsen.dk/foswiki/bin/view/Motion/WebHome),只需几个简单步骤就能接入本地 USB 摄像头。 在这篇博客中,我使用的是安装了 Home Assistant 0.22.1 的 Fedora 24(大概率也适用于其他发行版)环境,运行设备为 Foxconn nT-330i,连接了一台旧的 [Logitech QuickCam Orbit AF](http://support.logitech.com/en_us/product/quickcam-sphere-af) 和一台 [Logitech HD Webcam C270](http://support.logitech.com/en_us/product/hd-webcam-c270)。作为开始,我们先只使用 QuickCam,暂时不做多摄像头设置。 先检查你的操作系统是否已经识别到摄像头。 ```bash $ lsusb [...] Bus 002 Device 016: ID 046d:08cc Logitech, Inc. Mic (PTZ) [...] ``` 我们要用的摄像头位于 `/dev/video1`,而 C270 对应的是 `/dev/video0`。 ```bash $ ls -al /dev/video* crw-rw----+ 1 root video 81, 0 Jun 23 08:05 /dev/video0 crw-rw----+ 1 root video 81, 1 Jun 23 08:36 /dev/video1 ``` 我们还需要一个额外的软件来处理摄像头。[motion](http://lavrsen.dk/foswiki/bin/view/Motion/WebHome) 可以监控来自 USB 和网络摄像头的视频信号,进行运动检测,以及执行很多实用功能,比如保存图像、叠加文字,或做一些基础图像处理。请确保你已经启用了 [RPM Fusion 软件源](http://rpmfusion.org/)。 ```bash sudo dnf -y install motion ``` 针对我们的设置,需要修改 `/etc/motion/motion.conf` 文件。目前最关键的参数是 `videodevice`、`snapshot_interval` 和 `target_dir`。其他设置可以先保持默认。我们将使用 `/dev/video1` 这个设备,截图间隔设为 30 秒,路径设为 `/tmp`。 ```bash [...] ########################################################### # Capture device options ############################################################ # Videodevice to be used for capturing (default /dev/video0) # for FreeBSD default is /dev/bktr0 videodevice /dev/video1 [..] ############################################################ # Snapshots (Traditional Periodic Webcam File Output) ############################################################ # Make automated snapshot every N seconds (default: 0 = disabled) snapshot_interval 30 [...] ############################################################ # Target Directories and filenames For Images And Films # For the options snapshot_, picture_, movie_ and timelapse_filename # you can use conversion specifiers # %Y = year, %m = month, %d = date, # %H = hour, %M = minute, %S = second, # %v = event, %q = frame number, %t = thread (camera) number, # %D = changed pixels, %N = noise level, # %i and %J = width and height of motion area, # %K and %L = X and Y coordinates of motion center # %C = value defined by text_event # Quotation marks round string are allowed. ############################################################ # Target base directory for pictures and films # Recommended to use absolute path. (Default: current working directory) target_dir /tmp [...] ``` 建议你至少调整 `width` 和 `height`,这样可以从摄像头获得更大的图像。设置完成后,启动 `motion`。 ```bash $ sudo motion [0] [NTC] [ALL] conf_load: Processing thread 0 - config file /etc/motion/motion.conf [0] [ALR] [ALL] conf_cmdparse: Unknown config option "sdl_threadnr" [0] [NTC] [ALL] motion_startup: Motion 3.3.0 Started [0] [NTC] [ALL] motion_startup: Logging to file (/var/log/motion.log) ``` 你的 `target_dir` 目录会开始不断出现摄像头生成的图像。`motion` 会创建一个名为 `lastsnap.jpg` 的符号链接,它始终指向最新快照。接下来我们会把 [Local File 摄像头平台](/home-assistant/integrations/local_file.md) 设置为读取这个文件。 ```yaml camera: - platform: local_file name: Cranberry cam file_path: /tmp/lastsnap.jpg ```

"Cranberry cam" 运行中的画面

连接了 USB 摄像头的这台机器也会变成一个摄像头服务器,因为 `motion` 内置的 HTTP 服务器默认就是开启的。这意味着你可以把 USB 摄像头接到局域网中的另一台机器上,在那台机器运行 `motion`、调整防火墙规则,然后在 Home Assistant 中显示视频流。只要访问 `http://[IP of your webcam host]:8081/` 就能看到画面。当然,与快照模式相比,这需要更强的硬件性能。 在这种场景下,你需要在 `configuration.yaml` 里配置 [Generic MJPEG IP 摄像头](/home-assistant/integrations/mjpeg.md)。 ```yaml camera: - platform: mjpeg mjpeg_url: http://[IP of your webcam host]:8081 name: Cranberry Live cam ``` [motion](http://lavrsen.dk/foswiki/bin/view/Motion/WebHome) 是一个功能强大的工具,而这篇博客只展示了两个非常基础的用法。可以查看 `motion` 的[文档](http://www.lavrsen.dk/foswiki/bin/view/Motion/MotionGuide),进一步挖掘它的潜力。 --- url: /home-assistant/blog/2016-07-01-envisalink-homematic-hdmi-cec-and-sony-bravia-tv.md --- # 0.23: Envisalink, Homematic, HDMI-CEC and Sony Bravia TV It's time for Home Assistant 0.23 and it's full of goodies. It's also the 发布 that bumps us over a 1000 tests and to 94% test coverage! Also our 安装 issues on the 树莓派 and Synology have been resolved. This 发布 brings support for two new ecosystems: [Envisalink] and [Homematic]. We can now also control your TV via HDMI using [HDMI-CEC] (which works on the Pi!) and another cool feature is the [persistent 通知] which allow you to add a 通知 to the 前端 till dismissed. [Wink] support has been dramatically improved by migrating to the PubNub API. This allows Wink to push changes from their system to Home Assistant. This change came just in time as somehow our Wink 集成 was causing a lot of requests to their servers. Thanks to Wink for letting us know so we could solve it instead of blocking us. On the config side, you can now [store your passwords][secrets] in your OS keyring or just in a standalone file. We also got a new 服务 to 重载 the 核心 config so no reboots needed anymore after changing customize 设置! * Support for [Envisalink] added ([报警 control 面板][envi-报警], [二元sensor][envi-binary-传感器], [传感器][envi-传感器]) ([@cinntax]) * Support for [Homematic] added ([二元sensor][hm-binary-传感器], [灯光][hm-灯光], [rollershutter][hm-rollershutter], [传感器][hm-传感器], [开关][hm-开关]) ([@pvizeli], [@danielperna84]) * New [HDMI-CEC] component ([@happyleavesaoc], [@lukas-hetzenecker]) * Major rewrite of [Wink] which now pushes changes to Home Assistant ([@w1ll1am23]) * 核心: new add [重载 核心 config 服务] ([@balloob]) * Support for [persistent 通知] added ([@fabaff], [@balloob]) * Garage door: [Z-Wave][zwave-garage-door] support added ([@turbokongen]) * Rollershutter: [Z-Wave][zwave-rollershutter] support added ([@turbokongen]) * Media Player: [Sony Bravia TV] now supported ([@aparraga]) * 传感器: [Fixer.io] now supported ([@fabaff]) * Garage door: Control any garage door using [树莓派 GPIO pins] ([@kellerza]) * 传感器: [OpenExchangeRates] support added ([@arsaboo]) * 通知: [Pushover] now supports target 设备, sound, URL and priority ([@dale3h]) * 传感器: [Netatmo] now supports wind, battery and radio signals ([@Jypy]) * 日志 successful and failed login attemps ([@fabaff]) * Config: allow [extracting account info][secrets] into OS keyring or separate YAML file ([@kellerza]) * 核心: add option to not filter out duplicate 状态 per 实体 ([@philipbl]) * HTTP: Follow Mozilla SSL recommendations ([@danieljkemp], [@AlucardZero]) * 灯光: [Z-Wave colorbulb][zwave-灯光] support added ([@armills]) * 核心: new elevation config option added ([@balloob]) * 传感器: [OneWire] support extended with support for DS18S20, DS1822, DS1825 and DS28EA00 temperature 传感器 + support for bus masters which use fuse to mount 设备 tree. ([@Ardetus]) * 门锁: [Vera] now supported ([@rhooper]) * HTTP: Migrate to CherryPy WSGI server to fix 安装 and runtime problems ([@balloob]) ### Backward-incompatible changes * Homematic thermostat 配置 has changed and now depends on the new [Homematic] component. ### Hotfix 0.23.1 - July 2 * Bump PyVera to 0.2.13 to fix traceback and pyvera Thread dying related to bug ([@rhooper]) * HTTP - SSL: Check for OP\_NO\_COMPRESSION support before trying to use it ([@AlucardZero]) * Wink: Downgraded pubnub to work around pycryptodome conflicts ([@w1ll1am23]) ### 常见问题 * `elevation: ` was introduced to the 配置 for 天气/sunrise data. For existing [配置][elevation] add the value shown in the 警告 `[homeassistant.config] Incomplete core config. Auto detected elevation: 665` to your `configuration.yaml` file. [@AlucardZero]: https://github.com/AlucardZero/ [@aparraga]: https://github.com/aparraga/ [@Ardetus]: https://github.com/Ardetus/ [@armills]: https://github.com/armills/ [@arsaboo]: https://github.com/arsaboo/ [@balloob]: https://github.com/balloob/ [@cinntax]: https://github.com/cinntax/ [@dale3h]: https://github.com/dale3h/ [@danieljkemp]: https://github.com/danieljkemp/ [@danielperna84]: https://github.com/danielperna84/ [@fabaff]: https://github.com/fabaff/ [@happyleavesaoc]: https://github.com/happyleavesaoc/ [@Jypy]: https://github.com/Jypy/ [@kellerza]: https://github.com/kellerza/ [@lukas-hetzenecker]: https://github.com/lukas-hetzenecker/ [@philipbl]: https://github.com/philipbl/ [@pvizeli]: https://github.com/pvizeli/ [@rhooper]: https://github.com/rhooper/ [@turbokongen]: https://github.com/turbokongen/ [@w1ll1am23]: https://github.com/w1ll1am23/ [envi-报警]: /integrations/envisalink [envi-binary-传感器]: /integrations/envisalink [envi-传感器]: /integrations/envisalink [Envisalink]: /integrations/envisalink/ [HDMI-CEC]: /integrations/hdmi_cec/ [hm-binary-传感器]: /integrations/homematic [hm-灯光]: /integrations/homematic [hm-rollershutter]: /integrations/homematic/ [hm-传感器]: /integrations/homematic [hm-开关]: /integrations/homematic [Homematic]: /integrations/homematic/ [Netatmo]: /integrations/netatmo#传感器 [OneWire]: /integrations/onewire [OpenExchangeRates]: /integrations/openexchangerates [Pushover]: /integrations/pushover [secrets]: /topics/secrets/ [Vera]: /integrations/vera [Wink]: /integrations/wink/ [zwave-garage-door]: /integrations/zwave/#遮盖 [zwave-灯光]: /integrations/zwave [zwave-rollershutter]: /integrations/zwave/#遮盖 [Fixer.io]: /integrations/fixer [persistent 通知]: /integrations/persistent_notification/ [重载 核心 config 服务]: /getting-started/customizing-设备/#reloading-customize [Sony Bravia TV]: /integrations/braviatv [树莓派 GPIO pins]: /integrations/rpi_gpio/#遥控器-raspberry-pi-遮盖 [elevation]: /getting-started/basic/ --- url: /home-assistant/blog/2016-07-06-pocketchip-running-home-assistant.md --- # 在 PocketCHIP 上运行 Home Assistant 一年多前,我参加了 [Next Thing Co.](https://www.nextthing.co/) 发起的 [Kickstarter 众筹](https://www.kickstarter.com/projects/1598272670/chip-the-worlds-first-9-computer/description)——“CHIP:世界上第一台 9 美元电脑”。我选择 PocketCHIP 正是因为它的设计理念:有显示屏、内置存储(因此不需要 SD 卡)、电池供电、还有键盘,这些特性都很吸引人。上周它终于到货了…… 多亏了 [Next Thing Co.](https://www.nextthing.co/) 和他们那块真的只要 9 美元的 CHIP,单板电脑的体积门槛又被拉低了。没有以太网和 HDMI 输出也有助于缩小体积。不过我猜下一个开发周期,我们可能就能把带有有线网络和 SATA 接口的板子塞进火柴盒里。

Cubieboard、OrangePi One 和 CHIP 的体积对比。

如果你开始用 PocketCHIP,绝对会有种在用 Blackberry 或 Game Boy 的感觉。打字基本靠两只拇指 :-) 先做几项基础调整,比如配置 `sudo`、升级现有系统、修改密码、启用 ssh、删掉一些碍事的默认内容,然后再安装 Home Assistant。整体没太多可说的,非常直接。下面把我做过的步骤完整记一下。 系统默认提供 Debian 安装环境。这意味着 Home Assistant 的部分依赖并不齐全。我还没确认 PocketCHIP 的新镜像是否已经包含这些依赖。因此先执行 `$ sudo apt-get update`,再安装依赖,整个过程大概一两分钟。 ```bash sudo apt-get install python3-dev python3-pip python3-venv ``` 和往常一样,我会在 [venv](https://docs.python.org/3/library/venv.html) 中运行 Python 应用。 ```bash pvenv ha ``` 接下来激活刚创建的环境。 ```bash cd ha source bin/activate ``` 如果你还没见过接下来的两条命令,那你该去看看我们的[首页](/index.md)。 ```bash pip3 install homeassistant hass --open-ui ``` 在低分辨率屏幕上使用 `surf` 浏览网页,体验并不理想。现在大多数智能手机(哪怕很便宜的)都有更高分辨率的触摸屏。没关系,[`midori`](https://twitter.com/fabaff/status/748852317047418880) 也没好到哪去。

运行 Home Assistant 前端的 PocketCHIP

总之,借助 PocketCHIP 和 Home Assistant,你可以在一台 49 美元、带触摸屏、集成 USB 和键盘的设备上运行家庭自动化。显示屏上方还提供 GPIO 接口,甚至可以把 PocketCHIP 直接连接到传感器和执行器。 --- url: /home-assistant/blog/2016-07-16-sqlalchemy-knx-join-simplisafe.md --- # 0.24: SQLAlchemy, KNX, Join by Joaoapps, and SimpliSafe. It's time for Home Assistant 0.24 and it's full of new 集成 for your Home. It contains some structural changes to our history which requires 动作 from your end, so please keep reading. [MapQuest] discontinued their free and direct tile access by Monday, July 11, 2016. With [CARTO] we found a very cool and suitable solution. They allow us to use their tile for the map. Thank you, [CARTO]. [Roy Hooper][@rhooper] did an amazing job migrating the history support from being tied to SQLite to use the ORM SQLAlchemy instead. This means that you can now use **any** SQL 后端 for the history. So besides SQLite you can now databases like MySQL or PostgreSQL. However, this does require that you 安装 [SQLAlchemy] and run a command to migrate your existing history over. We tried to make the process as seamless as possible by introducing a new command line 脚本: ```bash pip3 install SQLAlchemy hass --script db_migrator --config /path/to/config ``` You can omit the `--config` option if you use the default 配置 directory. Run the 脚本 with `--help` to get more options. * Config: Improved support for storing [secrets][secrets] ([@kellerza]) * 传感器: Support for Yahoo! 天气 ([@pvizeli]) * Add 脚本 to command line to expose advanced options ([@balloob]) * 报警: [SimpliSafe][simplisafe] is now supported ([@w1ll1am23]) * 核心: 开关 to SQLAlchemy for the Recorder component ([@rhooper]) * Support for [Join by Joaoapps][join-joaoapps] added incl. [Join 通知][join-通知] ([@nkgilley]) * Media Player: [Plex] will no longer spam the 日志 if server goes offline ([@dale3h]) * 传感器: [APCUPSd 传感器][apcupsd-传感器] now supports names, icons and units ([@dale3h]) * 门锁: [Verisure] 实体 will now use name instead of serial number for 实体 id ([@turbokongen]) * [StatsD] can now also export 属性 ([@bah2830]) * Support for [KNX] added ([@usul27]) * 开关: [TPLink] HS100/HS110 now supported ([@GadgetReactor]) * Stability fixes for [RFXtrx] ([@Danielhiversen]) * Tweaks to [Z-Wave] ([@turbokongen]) * 灯光: [Brightness] now clamped to 0-255 ([@keatontaylor]) * Thermostat: [Radiotherm] HVAC mode now supported ([@danieljkemp]) * 传感器: [Google Travel] times can now use dynamic locations for start/end ([@bah2830]) * 通知: Allow sending photos to [Telegram] ([@pvizeli]) * 前端: Improve loading times ([@balloob]) * 前端: Fix stream not reconnecting after standby ([@balloob]) * 前端: Wait up to two seconds for new 状态 before resetting 切换 after toggling 状态 ([@balloob]) ### Hotfix 0.24.1 - July 21 Quick hot fix after we found a bug in the migrator where it wouldn't work with a database in a non-standard location. Thanks to [@n8henrie] and [@AlucardZero]. ### Backward-incompatible changes * Migrating existing databases (see above). * The [APCUPSd 传感器][apcupsd-传感器] was updated. This will need that you modify your `configuration.yaml` file. * 实体 IDs of Verisure 门锁 will change. This is a one time change but should improve readability. [@bah2830]: https://github.com/bah2830/ [@balloob]: https://github.com/balloob/ [@dale3h]: https://github.com/dale3h/ [@danieljkemp]: https://github.com/danieljkemp [@GadgetReactor]: https://github.com/GadgetReactor [@keatontaylor]: https://github.com/keatontaylor [@kellerza]: https://github.com/kellerza/ [@nkgilley]: https://github.com/nkgilley [@pvizeli]: https://github.com/pvizeli/ [@rhooper]: https://github.com/rhooper/ [@turbokongen]: https://github.com/turbokongen/ [@usul27]: https://github.com/usul27 [@w1ll1am23]: https://github.com/w1ll1am23/ [@n8henrie]: https://github.com/n8henrie/ [@AlucardZero]: https://github.com/AlucardZero/ [@Danielhiversen]: https://github.com/danielhiversen [apcupsd-传感器]: /integrations/apcupsd#传感器 [Brightness]: /integrations/灯光/ [CARTO]: https://carto.com/ [Google Travel]: /integrations/google_travel_time [imap-传感器]: /component/传感器.imap/ [join-joaoapps]: /integrations/joaoapps_join/ [join-通知]: /integrations/joaoapps_join [KNX]: /integrations/knx/ [MapQuest]: https://www.mapquest.com/ [Plex]: /integrations/plex#media-player [Radiotherm]: /integrations/radiotherm/ [recorder]: /integrations/recorder/ [secrets]: /topics/secrets/ [simplisafe]: /integrations/simplisafe [SQLAlchemy]: http://www.sqlalchemy.org/ [StatsD]: /integrations/statsd/ [Telegram]: /integrations/telegram [TPLink]: /integrations/tplink [Verisure]: /integrations/verisure [Z-Wave]: /integrations/zwave/ [RFXtrx]: /integrations/rfxtrx/ --- url: /home-assistant/blog/2016-07-19-visualizing-your-iot-data.md --- # 可视化你的 IoT 数据 [history 组件](/home-assistant/integrations/history/index.md) 会跟踪 Home Assistant 中发生的一切。这意味着,你可以访问家中所有已存储的信息。我们的历史记录功能并不是一个完整的图形处理和可视化组件,不像你在系统监控或网络监控工具中看到的那些那样全面。目前的限制是,你只能选择一天来查看信息的可视化结果,而不能选择一个时间段。另外,也无法深入查看某个特定实体。 这篇博客文章将向你展示几种导出数据的方法,用于报表、可视化,或者对自动化规则进行进一步分析。 在这篇博客文章中,我会以我住处附近 [Aare 河](https://en.wikipedia.org/wiki/Aare) 的温度为例。这些温度数据由 [Swiss Hydrological Data 传感器](/home-assistant/integrations/swiss_hydrological_data.md) 记录,传感器的名称是 `sensor.aare`。 数据库以 [SQLite 数据库](https://www.sqlite.org/index.html) 的形式存储在 `/.homeassistant/home-assistant_v2.db`。在下面所有示例中,我们都会使用这个路径:`/home/ha/.homeassistant/home-assistant_v2.db` 如果你只是想看看数据库里存了什么,可以使用 `sqlite3` 命令行工具,或者像 [DB Browser for SQLite](https://sqlitebrowser.org/) 这样的图形化工具。 用于保存状态的表名为 `states`。`events` 表则负责存储发生过的事件。因此,我们先来检查一下 `states` 表中有多少条记录。`sqlite3` 需要知道数据库文件所在的位置。要操作你的数据库,请确保 Home Assistant 没有在运行,或者先复制一份现有数据库。建议使用副本进行操作。 ```bash $ sqlite3 /home/ha/.homeassistant/home-assistant_v2.db SQLite version 3.11.0 2016-02-15 17:29:24 sqlite> SELECT count(*) FROM states; 24659 ``` 我们来看一个 [SQL](https://en.wikipedia.org/wiki/SQL) 查询示例。这个查询会显示传感器 `sensor.aare` 在某一时间段内的所有状态。 ```sql SELECT state, last_changed FROM states WHERE entity_id = 'sensor.aare' AND last_changed BETWEEN '2016-07-05 00:00:00.000000' AND '2016-07-07 00:00:00.000000'; ``` 你可以按照自己的需要来编写 SQL 语句。这意味着,你可以用任何想要的方式处理这些数据,以便进一步使用。很多时候,去除某些条目,比如 `Unknown` 或异常峰值,会更有意义。 如果你在 DB Browser for SQLite 中执行上面的查询,就可以把这个传感器的图表保存为 png。

使用 DB Browser for SQLite 进行可视化

你可能会问:为什么不直接用 LibreOffice Calc 或其他电子表格应用来做?由于大多数电子表格应用无法直接处理 SQLite 数据库,我们接下来会把数据从数据库导出为 [CSV](https://en.wikipedia.org/wiki/Comma-separated_values)。 ```bash sqlite3 -header -csv /home/ha/.homeassistant/home-assistant_v2.db "SELECT last_changed, state FROM states WHERE entity_id = 'sensor.aare' AND last_changed BETWEEN '2016-07-05 00:00:00.000000' AND '2016-07-07 00:00:00.000000';" > sensor.csv ``` 为了让时间戳排在前面、状态排在后面,我们调整了 `SELECT` 的字段顺序。现在,我们就可以把 CSV 文件导入你选择的应用中,这里使用的是 LibreOffice Calc。

导入 CSV 文件

导入之后,就可以基于现有数据创建图表了。

LibreOffice 中的图表

你也可以使用 [matplotlib](https://matplotlib.org/) 来生成图表,作为电子表格应用的替代方案。这是一个功能强大的 Python 2D 绘图库。借助 Python 内置的 SQLite 支持,只需要几行代码就能把你的数据可视化。 ```python import sqlite3 from matplotlib import dates import matplotlib.pyplot as plt import homeassistant.util.dt as dt values = [] timestamps = [] conn = sqlite3.connect('/home/ha/.homeassistant/home-assistant_v2.db') data = conn.execute("SELECT state, last_changed FROM states WHERE " "entity_id = 'sensor.aare' AND last_changed BETWEEN " "'2016-07-05 00:00:00.000000' AND " "'2016-07-07 00:00:00.000000'") for x in data: timestamps.append(dates.date2num(dt.parse_datetime(x[1]))) values.append(float(x[0])) plt.plot_date(x=timestamps, y=values, fmt="r-") plt.ylabel('Temperature') plt.xlabel('Time line') plt.savefig('sensor.png') ``` 创建数据库连接并执行查询,与前面展示的方法类似。查询返回的值会被拆分到两个列表中。时间戳必须转换成 matplotlib 可接受的数值格式,然后就可以生成图表并保存为图像。

使用 matplotlib 生成的传感器图表

大多数图表看起来都挺朴素的,所以你可能还需要进一步美化。如果你已经做出了包含出色图表的漂亮报表,Home Assistant 社区会非常感谢你在我们的[论坛](https://community.home-assistant.io/)中分享。 --- url: /home-assistant/blog/2016-07-23-internet-of-things-data-exploration-with-jupyter-notebooks.md --- # 使用 Jupyter Notebooks 探索 IoT 数据 *这是 Anton Kireyeu 的第一篇博客文章。他是 Home Assistant 的新贡献者,接下来会专注于 Home Assistant 数据的探索与可视化。* 正如我们在 Fabian 最近的[博客文章][博客 post by Fabian]中了解到的那样,你的 Home Assistant 应用运行数据都存储在本地,并且可以被进一步探索。我们的第一步通常是用 [DB Browser for SQLite] 查询数据,把结果导出为 CSV,再在 LibreOffice 里画图。但这些数据还能做什么?又有哪些工具可以用? 这篇文章会帮你配置几款常用数据科学工具,让你在本地处理自己的数据: *  [Pandas]:Python 开源数据分析工具 *  [matplotlib]:Python 绘图库 *  [Jupyter notebook]:可创建和分享文档的应用,文档中可包含可执行代码、可视化图表和说明文字

本教程中生成的一张图表。

*TL;DR:直接使用[这个 Jupyter Notebook][nb-prev] 来可视化你的数据。* [博客 post by Fabian]: /博客/2016/07/19/visualizing-your-iot-data/ [DB Browser for SQLite]: https://sqlitebrowser.org/ [Pandas]: https://pandas.pydata.org/ [matplotlib]: https://matplotlib.org/ [Jupyter notebook]: https://jupyter.org/ [nb-prev]: https://nbviewer.org/github/home-assistant/home-assistant-notebooks/blob/master/other/DataExploration-1/DataExploration-1.ipynb ### 依赖项 要运行本文提供的 Jupyter notebook,请先确认你的电脑已安装以下应用/库: * Pandas * NumPy * Matplotlib * SQLAlchemy * Jupyter 作为 Windows 用户,我觉得安装这些依赖最简单、最快、最省事的方法是使用 [WinPython]。这个免费的开源便携发行版包含了本 notebook 所需的全部依赖,以及未来进行数据探索时可能会用到的一些常用 Python 库。 [WinPython]: https://winpython.github.io/ #### 为什么用 Jupyter? 虽然不同 Home Assistant 部署的配置、组件和脚本各不相同,但底层数据结构是标准化且定义清晰的。这让我们可以编写与环境无关的 Python 代码。把这些内容放进 Jupyter notebook,可以把代码、图表和步骤说明组织得更易读、更完整。Jupyter 最强大的特点之一,就是你可以边运行边改代码,实时定制输出和可视化结果! #### 从哪里开始? 本教程基于我们制作的一份带有大量注释的 Jupyter Notebook。要开始,请先打开它: * [下载教程 Jupyter Notebook][nb-prev](链接会打开预览页,然后点击右上角 download) * 启动 Jupyter Notebook 应用 * 点击“upload”按钮,将下载的 notebook 添加到 Jupyter * 调整 notebook 开头的 `DB_URL`,指向你的 Home Assistant 数据库 * 在顶部菜单中选择:Cell -> Run All 就这么简单!附带代码会带你完成:导入所需库、对本地数据库执行原始 SQL、从 states 表绘制基础数据图,最后还会输出系统中每个实体的变化图,以及过去 20 天的日均值图表。 完成以上步骤后,你会看到如下格式良好的可视化结果:

本教程中生成的一张图表。

#### 下一步做什么? 借助 Jupyter 的强大能力,所有代码都可按需定制:想只展示某个实体的数据?完全可以!想调整图表样式参数?也没问题! 在你学习和探索 IoT 数据的同时,我们也会继续提供更多开箱即用的 Jupyter Notebooks。欢迎随时提问或提出建议。你是否想看到某种特定可视化?是否对某个数据维度特别感兴趣?一起来交流,一起深入数据世界! --- url: /home-assistant/blog/2016-07-28-esp8266-and-micropython-part1.md --- # ESP8266 and MicroPython - Part 1 The first 发布 of Micropython for ESP8266 was delivered a couple of weeks ago. The [文档](http://docs.micropython.org/en/latest/) 遮盖 a lot of ground. This post is providing only a little summary which should get you started. Until a couple of weeks ago, the pre-built MicroPython binary for the ESP8266 was only available to backers of the Kickstarter campaign. This has changed now and it is available to the public for [download](https://micropython.org/download/#esp8266). The easiest way is to use [esptool.py](https://github.com/espressif/esptool) for firmware handling tasks. First erase the flash: ```bash $ sudo python esptool.py --port /dev/ttyUSB0 erase_flash esptool.py v1.0.2-dev Connecting... Erasing flash (this may take a while)... ``` and then load the firmware. You may adjust the file name of the firmware binary. ```bash $ sudo python esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=8m 0 esp8266-2016-07-10-v1.8.2.bin esptool.py v1.2-dev Connecting... Running Cesanta flasher stub... Flash params set to 0x0020 Writing 540672 @ 0x0... 540672 (100 %) Wrote 540672 bytes at 0x0 in 13.1 seconds (330.8 kbit/s)... Leaving... ``` Now reset the 设备. You should then be able to use the [REPL (Read Evaluate Print Loop)](http://docs.micropython.org/en/latest/esp8266/esp8266/教程/repl.html#getting-a-micropython-repl-prompt). On Linux there is `minicom` or `picocom`, on a Mac you can use `screen` (eg. `screen /dev/tty.SLAB_USBtoUART 115200`), and on Windows there is Putty to open a serial connection and get the REPL prompt. The [WebREPL](http://docs.micropython.org/en/latest/esp8266/esp8266/教程/repl.html#webrepl-a-prompt-over-WiFi) work over a wireless connection and allows easy access to a prompt in your browser. An instance of the WebREPL client is hosted at . Alternatively, you can create a local clone of their [GitHub repository](https://github.com/micropython/webrepl). This is necessary if your want to use the command-line tool `webrepl_cli.py` which is mentionend later in this post. ```bash $ sudo minicom -D /dev/ttyUSB0 #4 ets_task(4020e374, 29, 3fff70e8, 10) WebREPL daemon started on ws://192.168.4.1:8266 Started webrepl in setup mode could not open file 'main.py' for reading #5 ets_task(4010035c, 3, 3fff6360, 4) MicroPython v1.8.2-9-g805c2b9 on 2016-07-10; ESP module with ESP8266 Type "help()" for more information. >>> ``` :::note The public build of the firmware may be different than the firmware distributed to the backers of the Kickstarter campaign. Especially in regard of the [available modules](http://docs.micropython.org/en/latest/esp8266/quickref.html), turned on 调试 messages, and alike. Also, the WebREPL may not be started by default. ::: Connect a LED to pin 5 (or another pin of your choosing) to check if the ESP8266 is working as expected. ```python >>> import machine >>> pin = machine.Pin(5, machine.Pin.OUT) >>> pin.high() ``` You can toogle the LED by changing its 状态 with `pin.high()` and `pin.low()`. Various ESP8266 development board are shipped with an onboard photocell or a 灯光 dependent resistors (LDR) connected to the analog pin of your ESP8266 check if you are able to obtain a value. ```python >>> import machine >>> brightness = machine.ADC(0) >>> brightness.read() ``` Make sure that you are familiar with REPL and WebREPL because this will be needed soon. Keep in mind the 密码 for the WebREPL access. Read the [instructions](http://docs.micropython.org/en/latest/esp8266/esp8266/教程/network_basics.html) about how to 设置 your wireless connection. Basically you need to upload a `boot.py` file to the microcontroller and this file is taking care of the connection 设置. Below you find a sample which is more or less the same as shown in the [文档](http://docs.micropython.org/en/latest/esp8266/esp8266/教程/network_basics.html#configuration-of-the-WiFi). ```python def do_connect(): import network SSID = 'SSID' PASSWORD = 'PASSWORD' sta_if = network.WLAN(network.STA_IF) ap_if = network.WLAN(network.AP_IF) if ap_if.active(): ap_if.active(False) if not sta_if.isconnected(): print('connecting to network...') sta_if.active(True) sta_if.connect(SSID, PASSWORD) while not sta_if.isconnected(): pass print('Network configuration:', sta_if.ifconfig()) ``` Upload this file with `webrepl_cli.py` or the WebREPL: ```bash python webrepl_cli.py boot.py 192.168.4.1:/boot.py ``` If you reboot, you should see your current IP address in the terminal. ```bash >>> Network configuration: ('192.168.0.10', '255.255.255.0', '192.168.0.1', '192.168.0.1') ``` First let's create a little consumer for Home Assistant 传感器's 状态. The code to place in `main.py` is a mixture of code from above and the [RESTful API](https://开发者.home-assistant.io/docs/api/rest/) of Home Assistant. If the temperature in the kitchen is higher than 20 °C then the LED connected to pin 5 is switched on. :::警告 If a module is missing then you need to download it from the [MicroPython Library 概述](https://github.com/micropython/micropython-lib) and upload it to the ESP8266 with `webrepl_cli.py` manually. ::: ```python # Sample code to request the state of a Home Assistant entity. API_PASSWORD = 'YOUR_PASSWORD' URL = 'http://192.168.0.5:8123/api/states/' ENTITY = 'sensor.kitchen_temperature' TIMEOUT = 30 PIN = 5 def get_data(): import urequests url = '{}{}'.format(URL, ENTITY) headers = {'x-ha-access': API_PASSWORD, 'content-type': 'application/json'} resp = urequests.get(URL, headers=headers) return resp.json()['state'] def main(): import machine import time pin = machine.Pin(PIN, machine.Pin.OUT) while True: try: if int(get_data()) >= 20: pin.high() else: pin.low() except TypeError: pass time.sleep(TIMEOUT) if __name__ == '__main__': print('Get the state of {}'.format(ENTITY)) main() ``` Upload `main.py` the same way as `boot.py`. After a reboot (`>>> import machine` and `>>> machine.reboot()`) or power-cycling your physical notifier is ready. If you run into trouble, press "Ctrl+c" in the REPL to stop the execution of the code, enter `>>> import webrepl` and `>>> webrepl.start()`, and upload your fixed file. --- url: /home-assistant/blog/2016-07-30-custom-frontend-panels--jupyter-notebooks--directv.md --- # 0.25: Custom 前端 面板, Jupyter notebooks, DirecTV. When Home Assistant started the focus has always been on making a great developer experience. Allowing anyone to add support for their favorite 设备 to Home Assistant easily. This focus has been a great success since we now have 339 components and platforms! Starting with this 发布, we are extending our extensibility to the 前端. Starting this 发布, any component can [add its own page to the 前端][custom-面板]. Examples of this today are the map, logbook and history. We are looking forward to all the crazy 面板 you'll come up with! We have also seen an exciting trend of people starting to visualize their Internet of Things data using [Jupyter] Notebooks, which are a great way to create and share documents that contain code, visualizations, and explanatory text. In case you missed it, the [博客] post by [@kireyeu] shows an advanced usecase while our [Notebooks][jupyter-notebooks] in the [Home Assistant Notebooks repository][jupyter-repo] 遮盖 the basics. This 发布 also includes a bunch of new 集成, among others three new media player platforms. This means that today Home Assistant can talk to 26 different media players! The brand-new [iFrame 面板 component][iframe_panel] allows you to add other websites as pages in the Home Assistant 前端. They will show up in the 侧边栏 and can be used the same way as you open the 前端 in your browser but all within one view. I would like to do a shoutout to [@fabianhjr]. He has started adding [typing] data ([PEP484]) to the Home Assistant 核心. This will help us identify issues before they are released. * 前端: Support for [iFrame 面板][iframe_panel] to adding other sites to 侧边栏 ([@balloob]) * Allow components to register [custom 前端 面板][custom-面板] ([@balloob]) * Add example custom\_component react\_panel showing custom 面板 ([@balloob]) * 灯光: [MagicLight/Flux WiFi Color LED 灯光][flux] support ([@Danielhiversen]) * 脚本: Specify a delay [using 模板][脚本] ([@Teagan42]) * Media player: [Russound RNET][Russound] 集成 ([@laf]) * 遥控器: Option specifying custom timeout when calling Home Assistant API ([@n8henrie]) * Thermostat: 集成 of [KNX] thermostats ([@open-homeautomation]) * Thermostat: Support for HVAC mode of [Nest] 设备 ([@vladonemo]) * InfluxDB: Option to specify additional [tags] ([@open-homeautomation]) * Input slider: Support for float value ([@ngraziano]) * 模板: New [filters] (`timestamp_local` and `timestamp_utc`) ([@fabaff]) * 二元sensor - Wink: Water leak 传感器 support added ([@w1ll1am23]) * 传感器 - Tellduslive: Support for luminance of Fibaro Motion 传感器 ([@PetitCircuitLab]) * 开关 - RPi GPIO: Fix when inverted logic (@zeroDenial) * Z-Wave: Rollershutter 更新 ([@turbokongen]) * RFXtrx: Fire events when receiving signals from 传感器 and tests added ([@Danielhiversen]) * 核心: Add [type][typing] checking using mypy to the 核心 ([@fabianhjr]) * 遥控器: Support for getting the [配置] through the Python API ([@fabaff]) * Media player: Support for [DirecTV] ([@cbulock]) * Use browser timezone for 前端 logbook and history dates ([@armills]) * 灯光: New support for [X10] 灯光 ([@fotoetienne]) * 传感器: Support for observing [IMAP] accounts ([@danieljkemp]) * Media Player: 集成 for [MPC-HC] (Media Player Classic - Home Cinema) mediaplayer ([@abcminiuser]) * 通知: `location` extension for [Telegram] and photo bug fixed ([@keatontaylor] and [@pvizeli]) * Groups: 门锁 状态 will now be properly grouped ([@jwl17330536]) * Media Player: Added tests for Sonos to improve code quality ([@americanwookie]) * 设备 Tracker: iCloud stability fixes ([@kellerza]) * 传感器: Speedtest with improved 错误 handling and 状态 restoring ([@nkgilley]) * Recorder: Stability fixes ([@kellerza]) * Qwikswitch: Stability fixes ([@kellerza]) * 灯光: [Hyperion] keeps now track of active color ([@schneefux]) ### Hotfix 0.25.1 - August 1 * 灯光 - Z-Wave: Bring back delayed value 更新 behavior ([@jnewland]) * Recorder: Properly close session after execute ([@kellerza]) * Media Player - Kodi: No longer block startup if connecting to wrong port ([@shoekstra]) * Downgrade voluptuous to 0.8.9 as it blocked the 升级 for some ([@balloob]) ### Hotfix 0.25.2 - August 2 * Hotfix to make sure Z-Wave 门锁 work again. Thanks to @tobiebooth for the quick fix. ### Backward-incompatible changes * Google Voice SMS 通知 support was removed. [@nkgilley]: https://github.com/nkgilley [@abcminiuser]: https://github.com/abcminiuser [@americanwookie]: https://github.com/americanwookie [@armills]: https://github.com/armills [@balloob]: https://github.com/balloob [@cbulock]: https://github.com/cbulock [@Danielhiversen]: https://github.com/Danielhiversen [@danieljkemp]: https://github.com/danieljkemp [@fabaff]: https://github.com/fabaff [@fabianhjr]: https://github.com/fabianhjr [@fotoetienne]: https://github.com/fotoetienne [@jwl17330536]: https://github.com/jwl17330536 [@keatontaylor]: https://github.com/keatontaylor [@kellerza]: https://github.com/kellerza [@kireyeu]: https://github.com/kireyeu [@laf]: https://github.com/laf [@n8henrie]: https://github.com/n8henrie [@ngraziano]: https://github.com/ngraziano [@open-homeautomation]: https://github.com/open-homeautomation [@PetitCircuitLab]: https://github.com/PetitCircuitLab [@pvizeli]: https://github.com/pvizeli [@schneefux]: https://github.com/schneefux [@Teagan42]: https://github.com/Teagan42 [@turbokongen]: https://github.com/turbokongen [@usul27]: https://github.com/usul27 [@vladonemo]: https://github.com/vladonemo [@w1ll1am23]: https://github.com/w1ll1am23 [@jnewland]: https://github.com/jnewland [@shoekstra]: https://github.com/shoekstra [custom-面板]: /developers/frontend_creating_custom_panels/ [iframe_panel]: /integrations/panel_iframe/ [flux]: /integrations/flux_led [脚本]: /getting-started/脚本/#delay [Russound]: /integrations/russound_rnet [tags]: /integrations/influxdb/ [filter]: /topics/templating/ [jupyter-notebooks]: /cookbook/#jupyter-notebooks [jupyter-repo]: https://github.com/home-assistant/home-assistant-notebooks [Jupyter]: http://jupyter.org/ [博客]: /博客/2016/07/23/internet-of-things-data-exploration-with-jupyter-notebooks/ [DirecTV]: /integrations/directv [配置]: /developers/python_api/#get-配置 [X10]: /integrations/x10 [IMAP]: /integrations/imap [typing]: https://docs.python.org/3/library/typing.html [PEP484]: https://www.python.org/dev/peps/pep-0484/ [MPC-HC]: /integrations/mpchc [Telegram]: /integrations/telegram [KNX]: /integrations/温控.knx/ [Nest]: /integrations/nest/#温控 [filters]: /topics/templating/#home-assistant-模板-extensions [Hyperion]: /integrations/hyperion --- url: /home-assistant/blog/2016-08-03-laundry-automation-update.md --- # Laundry 传感器 with NodeMCU and Home Assistant *This is a guest post by Home Assistant 用户 and contributor [Nolan Gilley](https://github.com/nkgilley).* Today I'll show you how I used Home Assistant, a NodeMCU (ESP8266), and a couple of accelerometers to automate our laundry 房间. This is a rewrite of an [old post](/home-assistant/blog/2015/08/26/laundry-automation-with-moteino-MQTT-and-home-assistant/) where I did the same thing using a Moteino & 树莓派. This 版本 only requires a NodeMCU. We have an older washer and dryer which doesn't have any form of 通知 when cycles complete. Home Assistant was the obvious solution, I just needed to create 传感器 for the washer and dryer. I tried using sound 传感器 but found them unreliable. I ended up using an accelerometer attached to the back of each appliance. I also added magnetic reed 开关 on the doors of the washer and dryer to detect whether they're open or closed. I connected the accelerometers and reed 开关 to an NodeMCU which will relay the data to my MQTT broker.

Block diagram of schematic

After taking some sample data from the accelerometers while each appliance was in operation, I decided to plot the data to help determine the proper thresholds of when the 设备 were running or off. I had to do this in order to get precise ranges so the dryer 传感器 wouldn't get tripped by the washer or vice versa. In the plot below you can see the acceleration in each direction for the accelerometer connected to the dryer. It's easy to see when the dryer is in operation here. I used the same technique for the washer's accelerometer.

Graph showing the accelerometer data

Next it was just a Matter of integrating everything with Home Assistant. I was able to use the [MQTT component](/home-assistant/integrations/MQTT/) to read the washer and dryer 状态 from the Moteino and display it in Home Assistant.

Status of the dryer and washer in Home Assistant

Next I wrote [脚本](/home-assistant/integrations/script/index.md) that are run whenever the washer or dryer completes a load. This is triggered by the [automation component](/home-assistant/getting-started/automation/index.md). When the laundry is complete I have the 灯光 in the house turn red and [notify me via Join](/home-assistant/integrations/joaoapps_join.md). Once the door is opened and laundry emptied another 脚本 runs that sets the 灯光 back to normal. So far it has been very helpful and very reliable.

NodeMCU connected to MPU-6050 accelerometer.

Materials used: * [NodeMCU](https://www.amazon.com/dp/B010O1G1ES) * [2 x Accelerometers](https://www.amazon.com/dp/B008BOPN40) * [2 x Reed 开关](https://www.amazon.com/dp/B01IU7NWMM) [Sketch for the NodeMCU is available here.](https://github.com/nkgilley/nodemcu-laundry/blob/master/nodemcu-laundry.ino) Home Assistant 配置: ```yaml mqtt: broker: 192.168.1.100 port: 1883 keepalive: 60 qos: 0 sensor: - platform: mqtt name: "Dryer Status" state_topic: "sensor/dryer" unit_of_measurement: "" - platform: mqtt name: "Washer Status" state_topic: "sensor/washer" unit_of_measurement: "" automation: - alias: "Washer complete" trigger: platform: state entity_id: sensor.washer_status from: "Running" to: "Complete" action: service: script.turn_on target: entity_id: script.washer_complete - alias: "Washer emptied" trigger: platform: state entity_id: sensor.washer_status from: "Complete" to: "Empty" action: service: scene.turn_on target: entity_id: scene.normal script: washer_complete: alias: "Washer Complete" sequence: - alias: "Join Notification" service: notify.join data: message: "The washing machine has finished its cycle, please empty it!" - alias: "Living Room Lights Blue" service: scene.turn_on target: entity_id: scene.blue ``` Resources used: * [Inspiration and Help with Arduino code](http://www.instructables.com/id/Uber-Home-automation-w-Arduino-Pi/step13/Washer-Dryer-Smartifier-Water-Leak-传感器/) --- url: /home-assistant/blog/2016-08-07-optimizing-the-home-assistant-mobile-web-app.md --- *这篇博客会详细介绍最近为 Home Assistant 前端进行的一系列性能优化。如果你还不熟悉这个应用,可以先看看[演示][demo]和[源码][hap]。* 一句话总结:不要硬改框架,拆分职责,少发一些代码,使用服务工作线程,并拥抱(未来的)Web 标准。 今年在 Google I/O 上,我看了 Polymer 团队的 Monica 分享关于 Web Components 和性能的演讲。她在演讲中提到,他们团队为了让东西更快,有一句信条:**少做事,并且保持懒惰**。 少做事,并且保持懒惰。听起来实在太显而易见了,而我花了一些时间才真正领会这句话。我觉得自己写的大多数代码本来就挺快的,但我并不常停下来,更认真地审视它在真实环境中是如何、又是在什么时候运行的。我们到底什么时候需要结果?它能不能再晚一点? 于是,我开始认真审视 Home Assistant 应用是如何工作的,以及怎样让它变得更快。下面就是我为提升速度所做的各种事情。 我希望这份清单也能对其他人有帮助,成为大家优化自己应用、或者在构建新应用时避开陷阱的一份参考。 第一步永远是测量。Home Assistant 前端是一个移动网页应用,所以我们不应该在一台 8 核、几 GB 内存的机器上做测量,而应该在你预期它会运行的设备上测量:手机。下面是分别在 Home Assistant 0.18.2(优化前)和 Google Chrome 53 下记录的两条时间线。**在我的 Mac 上,应用启动需要 1400 毫秒,而在我的 Nexus 5x 上则需要大约 6500 毫秒(慢了约 4.5 倍!)。**

Home Assistant 0.18.2 中前端加载时间线

虽然这个应用在我手机上要花 6500 毫秒才能加载完成,但在那之后它的表现其实不错。尽管如此,这样的初始加载时间仍然不可接受。你期待在手机上打开一个应用时,它能很快就可用。应用完下面描述的所有改动之后,我把启动时间缩短到了 Mac 上的 900 毫秒(-35%),以及 Nexus 5x 上的 2400 毫秒(-63%)。[点这里查看演示。][demo]

并排展示新旧加载时间的图表 Home Assistant 0.26 中前端加载时间线

## 技术背景 Home Assistant 前端由两部分组成。其一是 [Home Assistant JS][hajs],负责所有数据以及 JavaScript 与服务器之间的交互。它采用基于 Flux 的架构,并使用了 [NuclearJS] 和 [ImmutableJS]。其二是用 [Home Assistant Polymer][hap] 实现的 UI,基于 [Polymer] 和 Web Components。 # 不要硬改框架 我当时自以为很聪明。我把所有 Web Components 里的 JavaScript 部分拆出来,并用 Webpack 单独打包,这样就能通过 BabelJS 使用 ES2015(参见[架构][es2015-arch])。但这并不是 Polymer 组件的标准写法,这意味着我既无法使用社区中已有的工具链,也很难轻松拆分 bundle(后面还会提到这一点)。 于是我把所有 Web Components 又从闪亮漂亮的 ES6 回退成了 ES5。结果你知道吗?其实也没那么糟。没错,不能使用简洁的对象写法和箭头函数,确实会让代码更啰嗦一些。但最终在浏览器里运行的,本来就是同样的代码。 让每个 Web Component 都保留自己的 ` [pc-init]: https://www.podcastinit.com/ --- url: /home-assistant/blog/2017-05-06-zigbee-opencv-dlib.md --- # Home Assistant 0.44:Zigbee、OpenCV 和 DLib 这次发布带来了一些很棒的新集成。其中最大的一项,是由 [Russell Cloran][@rcloran] 带来的[原生 Zigbee 集成][zha docs]。这让 Home Assistant 可以原生控制 Philips Hue 灯光,而不再需要额外的网关!不过 IKEA Tradfri 灯光暂时还不支持,因为它实现的是不同的配置文件。 另一个很棒的新功能是由 [Teagan Glenn][@teagan42] 带来的 [OpenCV][opencv docs]。现在,你可以直接在 Home Assistant 中使用 OpenCV 的强大能力。如果 OpenCV 不是你的菜,也可以试试本次发布中由 [Pascal Vizeli][@pvizeli] 新增的 [DLib 集成][image_processing.dlib_face_identify docs]。 本次发布还包含了一个[新集成][rss_feed_template docs],可以基于模板动态生成 RSS feed。这意味着你手机、平板或电脑上的任何 RSS 小组件,现在都可以用来展示 Home Assistant 的数据! 最后,对于在界面中使用配置面板的用户,我们修复了分组编辑器的问题。 祝你用得开心! ## 如果你需要帮助 欢迎使用我们非常活跃的 [论坛][forum],或者加入聊天频道 [discord][discord]。发布说明虽然也开放评论,但我们更推荐你使用前面的沟通渠道。谢谢。 ## 反馈问题 如果你遇到了这次发布引入的问题,请到我们的 [问题追踪器][issue] 提交反馈,并确保填写问题模板中的所有字段。 ## 新集成 * Pushbullet 通知 传感器 ([@jotunacorn] - [#7182]) ([传感器.pushbullet docs]) * 新增 HTTPS 证书到期传感器 ([@fabfurnari] - [#7272]) ([传感器.cert\_expiry docs][传感器.cert_expiry docs]) * RSS feed 模板 ([@micw] - [#7032]) ([rss\_feed\_template docs][rss_feed_template docs]) * 新增 Zigbee Home Automation 支持 ([@rcloran] - [#6263]) ([zha docs]) ([binary\_sensor.zha docs][binary_sensor.zha docs]) ([灯光.zha docs]) ([传感器.zha docs]) ([开关.zha docs]) * 新增树莓派上的 Blinkt! 灯光支持 ([@imrehg] - [#7377]) ([灯光.blinkt docs]) * Plant 自动化 ([@ChristianKuehnel] - [#7131]) ([plant docs]) * 新增 Eight Sleep 组件 ([@mezz64] - [#7275]) ([eight\_sleep docs][eight_sleep docs]) ([binary\_sensor.eight\_sleep docs][binary_sensor.eight_sleep docs]) ([传感器.eight\_sleep docs][传感器.eight_sleep docs]) * OpenGarage support ([@swbradshaw] - [#7338]) ([遮盖.opengarage docs]) * Add Sensibo 温控 platform ([@andrey-git] - [#7379]) ([温控 docs]) * Pilight 二元sensor components ([@zeltom] - [#6774]) ([binary\_sensor.pilight docs][binary_sensor.pilight docs]) * Opencv ([@Teagan42] - [#7261]) ([opencv docs]) ([image\_processing.opencv docs][image_processing.opencv docs]) * Enviro pHAT ([@imrehg] - [#7427]) ([传感器.envirophat docs]) * 新增基于 dlib 的人脸识别支持 ([@pvizeli] - [#7421]) ([image\_processing.dlib\_face\_detect docs][image_processing.dlib_face_detect docs]) ([image\_processing.dlib\_face\_identify docs][image_processing.dlib_face_identify docs]) ## 发布 0.44.2 - May 8 * Fix opening 插件 in Hass.io store that are not 已安装 ([@balloob]) ## 发布 0.44.1 - May 7 * Fix opening 插件 in Hass.io store that are not 已安装 ([@balloob]) * 传感器.envirophat: add missing requirement ([@imrehg] - [#7451]) ([传感器.envirophat docs]) * Forecasts for 天气 underground ([@pezinek] - [#7062]) ([传感器.wunderground docs]) * 升级 pymysensors to 0.10.0 ([@MartinHjelmare] - [#7469]) * Fix plant MIN\_TEMPERATURE, MAX\_TEMPERATURE validation ([@frog32] - [#7476]) ([plant docs]) * 更新 to pyunifi 2.12 ([@finish06] - [#7468]) ([device\_tracker.unifi docs][device_tracker.unifi docs]) * MQTT 遮盖: Fixed status reporting for range with non-zero base ([@cribbstechnologies]) ## 不向后兼容的变更 * Python Open Z-Wave 发布了一个修复字符串处理问题的新版本,但这项修复并不向后兼容。我们已经同步更新代码,因此你需要在使用本次发布时升级到最新版 Python Open Z-Wave。你也可以再等一个版本,因为下个版本我们将加入 Python Open Z-Wave 的自动安装功能。 ([@keatontaylor] - [#7266]) ([温控.zwave docs]) (breaking change) * InfluxDB 中用于屏蔽域的配置方式已更新,以支持更多功能。 ([@janLo] - [#7264]) (breaking change) ```yaml # New format influxdb: exclude: entities: - entity.id1 - entity.id2 domains: - automation include: entities: - entity.id3 - entity.id4 ``` * Automatic 设备追踪器已从轮询改为 WebSocket 推送。这需要你在 Automatic 账户中进行调整,具体请参阅文档说明。 ([@armills] - [#7404]) (breaking change) * LimitlessLED 的色温范围已反转,以便与其他灯光平台保持一致。若要维持之前的颜色效果,你需要把 `light.turn_on` 调用中的 `color_temp` 改为 `654 - 原值`,例如 280 需要改为 374。 ([@amelchio] - [#7359]) (breaking change) * Joao apps 现在要求所有命令都必须设置 API 密钥。 ([@nkgilley] - [#7443]) ([joaoapps\_join docs][joaoapps_join docs]) ([通知.joaoapps\_join docs][通知.joaoapps_join docs]) (breaking change) ## All changes * LIFX 灯光 effects ([@amelchio] - [#7145]) ([灯光.lifx docs]) * HassIO API v2 ([@pvizeli] - [#7201]) * Capture and 日志 pip 安装 错误 output ([@postlund] - [#7200]) * Support xy\_color with LIFX 灯光 ([@amelchio] - [#7208]) ([灯光.lifx docs]) * 更新 ios.py ([@biacz] - [#7160]) * Fix arwn platform to 更新 hass 状态 when events are received ([@sdague] - [#7202]) * Issue 6749 updated pylgtv to 0.1.6 to fix Thread leak in asyncio loop ([@hmn] - [#7199]) ([媒体播放器.webostv docs]) ([通知.webostv docs]) * tradfri: Improve color temp support detection ([@balloob] - [#7211]) * Fix tradfri 灯光 ([@MartinHjelmare] - [#7212]) * Bump 版本 to 0.44.0.dev0 ([@fabaff] - [#7217]) * Pushbullet 通知 传感器 ([@jotunacorn] - [#7182]) ([传感器.pushbullet docs]) (new-platform) * Zwave 遮盖 workaround for graber shades. ([@turbokongen] - [#7204]) ([遮盖.zwave docs]) * Fixed typo and clarified details for Lifx effects ([@arsaboo] - [#7226]) * Remove superfluous comments and 更新 ordering ([@fabaff] - [#7227]) ([maxcube docs]) ([binary\_sensor.maxcube docs][binary_sensor.maxcube docs]) ([温控.maxcube docs]) * lyft 传感器: re-enable Prime Time rate 属性 ([@drkp] - [#6982]) ([传感器.lyft docs]) * Bump a couple of dependencies ([@mjg59] - [#7231]) ([灯光.avion docs]) ([灯光.decora docs]) * Refactor lyft 传感器 更新 ([@armills] - [#7233]) ([传感器.lyft docs]) * LIFX: avoid "Unable to remove unknown listener" 警告 ([@amelchio] - [#7235]) ([灯光.lifx docs]) * 升级 pygatt to 3.1.1 ([@fabaff] - [#7220]) * 升级 mutagen to 1.37.0 ([@fabaff] - [#7216]) * 升级 speedtest-cli to 1.0.5 ([@fabaff] - [#7215]) * 升级 paho-MQTT to 1.2.3 ([@fabaff] - [#7214]) * 升级 aiohttp\_cors to 0.5.3 ([@fabaff] - [#7213]) * Use consts and string formatting ([@fabaff] - [#7243]) (通知.instapush docs) * Pushed to 版本 0.4.0 of denonavr which also includes experimental support for Marantz receivers ([@scarface-4711] - [#7250]) * Add notice regarding submission of analytics ([@craftyguy] - [#7263]) * Iterating the dictionary directly ([@fabaff] - [#7251]) * Don't use len(SEQUENCE) as 条件 value ([@fabaff] - [#7249]) * Workround for wemo subscription bug. ([@pavoni] - [#7245]) ([wemo docs]) ([开关.wemo docs]) * Fix telegram webhooks ([@MartinHjelmare] - [#7236]) ([telegram\_bot docs][telegram_bot docs]) ([telegram\_bot.webhooks docs][telegram_bot.webhooks docs]) * Work around bad content-type in Hook api response ([@KlaasH] - [#7267]) * Rfxtrx 升级 lib 0.18 ([@danielhiversen] - [#7273]) ([rfxtrx docs]) * WIP: HassIO allow to access to 容器 日志. ([@pvizeli] - [#7271]) * 更新 aiolifx ([@amelchio] - [#7279]) ([灯光.lifx docs]) * Refactor matrix 通知 服务 ([@Cadair] - [#7122]) ([通知.matrix docs]) * Add support for Ukrainian Language in Google TTS ([@LvivEchoes] - [#7278]) * Add https certificate expiry 传感器 ([@fabfurnari] - [#7272]) ([传感器.cert\_expiry docs][传感器.cert_expiry docs]) (new-platform) * Fix telegram\_polling no first\_name or last\_name ([@darookee] - [#7281]) ([telegram\_bot docs][telegram_bot docs]) * Add 脚本 to import 状态 events to InfluxDB ([@janLo] - [#7254]) * Fix HassIO bug with supervisor 更新 & 日志 ([@pvizeli] - [#7282]) * Updating ping 二元sensor with Windows support ([@patrickeasters] - [#7253]) ([binary\_sensor.ping docs][binary_sensor.ping docs]) * Fixes utf-8 encoding no longer required by python-openzwave0.3.3 ([@keatontaylor] - [#7266]) ([温控.zwave docs]) (breaking change) * Recorder: Check for ENTITY\_ID key that contains None value ([@balloob] - [#7287]) ([recorder docs]) * 升级 pytradfri to 1.1 ([@balloob] - [#7290]) * Adding group control to tradfri 灯光 component ([@cyberjunky] - [#7248]) ([灯光.tradfri docs]) * Feature/rss feed 模板 ([@micw] - [#7032]) ([rss\_feed\_template docs][rss_feed_template docs]) (new-platform) * Add support for Zigbee Home 自动化 ([@rcloran] - [#6263]) ([zha docs]) ([binary\_sensor.zha docs][binary_sensor.zha docs]) ([灯光.zha docs]) ([传感器.zha docs]) ([开关.zha docs]) (new-platform) * Added 场景 controller support to the vera component, along with proper polling when a vera 设备 needs it ([@alanfischer] - [#7234]) ([vera docs]) ([传感器.vera docs]) * Don't stack up 错误 messages, fix link, and ordering ([@fabaff] - [#7291]) ([传感器.cert\_expiry docs][传感器.cert_expiry docs]) * Fix breaking SSL in test HTML5 ([@balloob] - [#7310]) ([通知.html5 docs]) * 升级 pyhomematic, extend 设备 support ([@danielperna84] - [#7303]) * Issue 7218 更新 pylgtv to 0.1.7 ([@hmn] - [#7302]) ([媒体播放器.webostv docs]) ([通知.webostv docs]) * 版本 bump of aioautomatic ([@armills] - [#7300]) * 升级 python-telegram-bot to 5.3.1 ([@fabaff] - [#7311]) ([通知.telegram docs]) ([telegram\_bot.polling docs][telegram_bot.polling docs]) ([telegram\_bot.webhooks docs][telegram_bot.webhooks docs]) * Disable Open Z-Wave in Docker ([@balloob] - [#7315]) * LIFX: use white 灯光 when setting a specific temperature ([@amelchio] - [#7256]) ([灯光.lifx docs]) * Allow InfluxDB to blacklist domains ([@janLo] - [#7264]) (breaking change) * Hassio api v3 ([@balloob] - [#7323]) * 更新 前端 ([@balloob] - [#7324]) * Reduce color\_xy\_brightness\_to\_hsv to color\_xy\_to\_hs ([@amelchio] - [#7320]) ([灯光.hue docs]) ([灯光.lifx docs]) * Fix broken Docker build ([@turbokongen] - [#7316]) * Re-enable Open Z-Wave in Dockerfile ([@balloob] - [#7325]) * 版本 bump for automatic ([@armills] - [#7329]) * Right fix for Python Open Z-Wave in Docker ([@balloob] - [#7337]) * Use four-digits year ([@fabaff] - [#7336]) * Allow multiple recipients for SMTP 通知 ([@amelchio] - [#7319]) ([通知.smtp docs]) * Add auxheat to ecobee 温控 ([@titilambert] - [#6562]) ([温控.ecobee docs]) * Properly return self.\_unit\_of\_measurement in the unit\_of\_measurement function ([@robbiet480] - [#7341]) ([传感器.ios docs]) * Multiple changes (typo, ordering, docstrings, timeouts) ([@fabaff] - [#7343]) ([遮盖.garadget docs]) * 升级 Flux led lb to 0.19 ([@danielhiversen] - [#7352]) ([灯光.flux\_led docs][灯光.flux_led docs]) * Add 调试 logging to pyvera events. ([@pavoni] - [#7364]) ([vera docs]) * 升级 xmltodict to 0.11.0 ([@fabaff] - [#7355]) * 升级 speedtest-cli to 1.0.6 ([@fabaff] - [#7354]) ([传感器.speedtest docs]) * Remove global limit on white 灯光 temperature ([@amelchio] - [#7206]) ([灯光 docs]) ([灯光.hue docs]) ([灯光.zwave docs]) ([开关.flux docs]) * Remove 状态 property from alarmdecoder 二元sensor ([@balloob] - [#7370]) ([binary\_sensor.alarmdecoder docs][binary_sensor.alarmdecoder docs]) * Remove 二元sensor platforms implementing 状态 property ([@balloob] - [#7371]) ([binary\_sensor.octoprint docs][binary_sensor.octoprint docs]) ([binary\_sensor.workday docs][binary_sensor.workday docs]) * Feature/add mikrotik 设备 tracker ([@LvivEchoes] - [#7366]) * Netdisco now returns a dictionary while it used to be a tuple, fixed ([@JasonCarter80] - [#7350]) * Create knx.py ([@onsmam] - [#7356]) * 灯光.sensehat: plugin to control the 8x8 LED matrix on a Sense hat ([@imrehg] - [#7365]) * 更新 docstrings ([@fabaff] - [#7361]) ([ecobee docs]) ([enocean docs]) ([zha docs]) * Flux 开关: avoid updates when off ([@amelchio] - [#7363]) ([开关.flux docs]) * Zoneminder: Fixed undefined index 错误 ([@bah2830] - [#7340]) * optimize 遥控器 calls and apps on webostv 媒体播放器 ([@hmn] - [#7191]) ([媒体播放器.webostv docs]) * binary\_sensor.workday: fix handling of 状态 vs provinces ([@drkp] - [#7162]) ([binary\_sensor.workday docs][binary_sensor.workday docs]) * 升级 voluptuous to 0.10.5 ([@fabaff] - [#7107]) * Remove ordered\_dict validator ([@balloob] - [#7375]) * 灯光.blinkt: add support for Blinkt! 灯光 on 树莓派 ([@imrehg] - [#7377]) ([灯光.blinkt docs]) (new-platform) * improve handling of flux\_led 灯光 in RGBW mode ([@wuub] - [#7221]) * Plant (replacement for MiGardener) ([@ChristianKuehnel] - [#7131]) ([plant docs]) (new-platform) * Add support for shuffle toggling on Spotify component. ([@abmantis] - [#7339]) ([媒体播放器 docs]) ([媒体播放器.spotify docs]) * 升级 Ring to 0.1.4 ([@tchellomello] - [#7386]) * Updated docstrings ([@arsaboo] - [#7383]) ([摄像头.netatmo docs]) * Fix impulse events, added 错误 event for Homegear ([@danielperna84] - [#7349]) ([homematic docs]) * Fix YAML dump ([@balloob] - [#7388]) * Migrate updater to aiohttp ([@balloob] - [#7387]) ([updater docs]) * Remove path whitelisting for hassio ([@balloob] - [#7399]) * Add Eight sleep component ([@mezz64] - [#7275]) ([eight\_sleep docs][eight_sleep docs]) ([binary\_sensor.eight\_sleep docs][binary_sensor.eight_sleep docs]) ([传感器.eight\_sleep docs][传感器.eight_sleep docs]) (new-platform) * OpenGarage support ([@swbradshaw] - [#7338]) ([遮盖.opengarage docs]) (new-platform) * Clean up requirements ([@andrey-git] - [#7391]) ([传感器.dht docs]) ([传感器.thinkingcleaner docs]) ([开关.thinkingcleaner docs]) * correct MQTT subscription filter ([@amigian74] - [#7269]) ([MQTT docs]) * 更新 docstrings ([@fabaff] - [#7374]) * 灯光.blinkt: 更新 brightness control logic ([@imrehg] - [#7389]) * 更新 docstrings ([@fabaff] - [#7405]) * 更新 LIFX default color for breathe/pulse effects ([@amelchio] - [#7407]) * LIFX: Add transition option to colorloop effect ([@amelchio] - [#7410]) * 灯光.sensehat: brightness control logic 更新 ([@imrehg] - [#7409]) ([灯光.sensehat docs]) * Add Sensibo 温控 platform ([@andrey-git] - [#7379]) ([温控 docs]) (new-platform) * Pilight 二元sensor components ([@zeltom] - [#6774]) ([binary\_sensor.pilight docs][binary_sensor.pilight docs]) (new-platform) * applx suggested fix from issue #6573 ([@wokar] - [#7390]) ([传感器.zamg docs]) * remove charset if set in content type header ([@hmn] - [#7411]) ([媒体播放器 docs]) * Convert automatic 设备 tracker to push updates ([@armills] - [#7404]) (breaking change) * 灯光.piglow 更新 ([@imrehg] - [#7408]) ([灯光.piglow docs]) * Opencv ([@Teagan42] - [#7261]) ([opencv docs]) ([image\_processing.opencv docs][image_processing.opencv docs]) (new-platform) * Fixed extra R in variable name. ([@cyberplant] - [#7418]) * 更新 docstrings ([@fabaff] - [#7420]) * ps - fix opencv ([@balloob] - [#7419]) * Comment out opencv-python that is not installable on arm ([@andrey-git] - [#7426]) * Reverse limitlessled color\_temp range ([@amelchio] - [#7359]) (breaking change) * Guard against no content type ([@balloob] - [#7432]) ([媒体播放器 docs]) * wsock.send\_json is a coroutine ([@balloob] - [#7433]) * ps - fix websocket yielding pt2 ([@balloob] - [#7434]) * 升级 temperusb to 1.5.3 ([@fabaff] - [#7428]) * 更新 for pypi ([@nkgilley] - [#7430]) * Add new 传感器: Enviro pHAT ([@imrehg] - [#7427]) ([传感器.envirophat docs]) (new-platform) * Added osramlightify groups. ([@deisi] - [#7376]) ([灯光.osramlightify docs]) * Add support for face recognition with dlib ([@pvizeli] - [#7421]) ([image\_processing.dlib\_face\_detect docs][image_processing.dlib_face_detect docs]) ([image\_processing.dlib\_face\_identify docs][image_processing.dlib_face_identify docs]) ([image\_processing.microsoft\_face\_detect docs][image_processing.microsoft_face_detect docs]) (new-platform) * Replace pymailgun with pymailgunner ([@pschmitt] - [#7436]) ([通知.mailgun docs]) * Suppress 日志 when octorpint goes offline ([@w1ll1am23] - [#7441]) ([octoprint docs]) * 更新 join ([@nkgilley] - [#7443]) ([joaoapps\_join docs][joaoapps_join docs]) ([通知.joaoapps\_join docs][通知.joaoapps_join docs]) (breaking change) * Bump pyvera 版本 - handle malformed json replies in poll Thread. ([@pavoni] - [#7440]) ([vera docs]) * Fix for broken virtual keys ([@danielperna84] - [#7439]) ([homematic docs]) * Get new token to keep pubnub updates working ([@w1ll1am23] - [#7437]) ([wink docs]) * Add hass to rfxtrx object ([@danielhiversen] - [#6844]) * 传感器.envirophat: add missing requirement ([@imrehg] - [#7451]) ([传感器.envirophat docs]) [#6263]: https://github.com/home-assistant/home-assistant/pull/6263 [#6562]: https://github.com/home-assistant/home-assistant/pull/6562 [#6774]: https://github.com/home-assistant/home-assistant/pull/6774 [#6844]: https://github.com/home-assistant/home-assistant/pull/6844 [#6982]: https://github.com/home-assistant/home-assistant/pull/6982 [#7032]: https://github.com/home-assistant/home-assistant/pull/7032 [#7107]: https://github.com/home-assistant/home-assistant/pull/7107 [#7122]: https://github.com/home-assistant/home-assistant/pull/7122 [#7131]: https://github.com/home-assistant/home-assistant/pull/7131 [#7145]: https://github.com/home-assistant/home-assistant/pull/7145 [#7160]: https://github.com/home-assistant/home-assistant/pull/7160 [#7162]: https://github.com/home-assistant/home-assistant/pull/7162 [#7182]: https://github.com/home-assistant/home-assistant/pull/7182 [#7191]: https://github.com/home-assistant/home-assistant/pull/7191 [#7199]: https://github.com/home-assistant/home-assistant/pull/7199 [#7200]: https://github.com/home-assistant/home-assistant/pull/7200 [#7201]: https://github.com/home-assistant/home-assistant/pull/7201 [#7202]: https://github.com/home-assistant/home-assistant/pull/7202 [#7204]: https://github.com/home-assistant/home-assistant/pull/7204 [#7206]: https://github.com/home-assistant/home-assistant/pull/7206 [#7208]: https://github.com/home-assistant/home-assistant/pull/7208 [#7211]: https://github.com/home-assistant/home-assistant/pull/7211 [#7212]: https://github.com/home-assistant/home-assistant/pull/7212 [#7213]: https://github.com/home-assistant/home-assistant/pull/7213 [#7214]: https://github.com/home-assistant/home-assistant/pull/7214 [#7215]: https://github.com/home-assistant/home-assistant/pull/7215 [#7216]: https://github.com/home-assistant/home-assistant/pull/7216 [#7217]: https://github.com/home-assistant/home-assistant/pull/7217 [#7220]: https://github.com/home-assistant/home-assistant/pull/7220 [#7221]: https://github.com/home-assistant/home-assistant/pull/7221 [#7226]: https://github.com/home-assistant/home-assistant/pull/7226 [#7227]: https://github.com/home-assistant/home-assistant/pull/7227 [#7231]: https://github.com/home-assistant/home-assistant/pull/7231 [#7233]: https://github.com/home-assistant/home-assistant/pull/7233 [#7234]: https://github.com/home-assistant/home-assistant/pull/7234 [#7235]: https://github.com/home-assistant/home-assistant/pull/7235 [#7236]: https://github.com/home-assistant/home-assistant/pull/7236 [#7243]: https://github.com/home-assistant/home-assistant/pull/7243 [#7245]: https://github.com/home-assistant/home-assistant/pull/7245 [#7248]: https://github.com/home-assistant/home-assistant/pull/7248 [#7249]: https://github.com/home-assistant/home-assistant/pull/7249 [#7250]: https://github.com/home-assistant/home-assistant/pull/7250 [#7251]: https://github.com/home-assistant/home-assistant/pull/7251 [#7253]: https://github.com/home-assistant/home-assistant/pull/7253 [#7254]: https://github.com/home-assistant/home-assistant/pull/7254 [#7256]: https://github.com/home-assistant/home-assistant/pull/7256 [#7261]: https://github.com/home-assistant/home-assistant/pull/7261 [#7263]: https://github.com/home-assistant/home-assistant/pull/7263 [#7264]: https://github.com/home-assistant/home-assistant/pull/7264 [#7266]: https://github.com/home-assistant/home-assistant/pull/7266 [#7267]: https://github.com/home-assistant/home-assistant/pull/7267 [#7269]: https://github.com/home-assistant/home-assistant/pull/7269 [#7271]: https://github.com/home-assistant/home-assistant/pull/7271 [#7272]: https://github.com/home-assistant/home-assistant/pull/7272 [#7273]: https://github.com/home-assistant/home-assistant/pull/7273 [#7275]: https://github.com/home-assistant/home-assistant/pull/7275 [#7278]: https://github.com/home-assistant/home-assistant/pull/7278 [#7279]: https://github.com/home-assistant/home-assistant/pull/7279 [#7281]: https://github.com/home-assistant/home-assistant/pull/7281 [#7282]: https://github.com/home-assistant/home-assistant/pull/7282 [#7287]: https://github.com/home-assistant/home-assistant/pull/7287 [#7290]: https://github.com/home-assistant/home-assistant/pull/7290 [#7291]: https://github.com/home-assistant/home-assistant/pull/7291 [#7300]: https://github.com/home-assistant/home-assistant/pull/7300 [#7302]: https://github.com/home-assistant/home-assistant/pull/7302 [#7303]: https://github.com/home-assistant/home-assistant/pull/7303 [#7310]: https://github.com/home-assistant/home-assistant/pull/7310 [#7311]: https://github.com/home-assistant/home-assistant/pull/7311 [#7315]: https://github.com/home-assistant/home-assistant/pull/7315 [#7316]: https://github.com/home-assistant/home-assistant/pull/7316 [#7319]: https://github.com/home-assistant/home-assistant/pull/7319 [#7320]: https://github.com/home-assistant/home-assistant/pull/7320 [#7323]: https://github.com/home-assistant/home-assistant/pull/7323 [#7324]: https://github.com/home-assistant/home-assistant/pull/7324 [#7325]: https://github.com/home-assistant/home-assistant/pull/7325 [#7329]: https://github.com/home-assistant/home-assistant/pull/7329 [#7336]: https://github.com/home-assistant/home-assistant/pull/7336 [#7337]: https://github.com/home-assistant/home-assistant/pull/7337 [#7338]: https://github.com/home-assistant/home-assistant/pull/7338 [#7339]: https://github.com/home-assistant/home-assistant/pull/7339 [#7340]: https://github.com/home-assistant/home-assistant/pull/7340 [#7341]: https://github.com/home-assistant/home-assistant/pull/7341 [#7343]: https://github.com/home-assistant/home-assistant/pull/7343 [#7349]: https://github.com/home-assistant/home-assistant/pull/7349 [#7350]: https://github.com/home-assistant/home-assistant/pull/7350 [#7352]: https://github.com/home-assistant/home-assistant/pull/7352 [#7354]: https://github.com/home-assistant/home-assistant/pull/7354 [#7355]: https://github.com/home-assistant/home-assistant/pull/7355 [#7356]: https://github.com/home-assistant/home-assistant/pull/7356 [#7359]: https://github.com/home-assistant/home-assistant/pull/7359 [#7361]: https://github.com/home-assistant/home-assistant/pull/7361 [#7363]: https://github.com/home-assistant/home-assistant/pull/7363 [#7364]: https://github.com/home-assistant/home-assistant/pull/7364 [#7365]: https://github.com/home-assistant/home-assistant/pull/7365 [#7366]: https://github.com/home-assistant/home-assistant/pull/7366 [#7370]: https://github.com/home-assistant/home-assistant/pull/7370 [#7371]: https://github.com/home-assistant/home-assistant/pull/7371 [#7374]: https://github.com/home-assistant/home-assistant/pull/7374 [#7375]: https://github.com/home-assistant/home-assistant/pull/7375 [#7376]: https://github.com/home-assistant/home-assistant/pull/7376 [#7377]: https://github.com/home-assistant/home-assistant/pull/7377 [#7379]: https://github.com/home-assistant/home-assistant/pull/7379 [#7383]: https://github.com/home-assistant/home-assistant/pull/7383 [#7386]: https://github.com/home-assistant/home-assistant/pull/7386 [#7387]: https://github.com/home-assistant/home-assistant/pull/7387 [#7388]: https://github.com/home-assistant/home-assistant/pull/7388 [#7389]: https://github.com/home-assistant/home-assistant/pull/7389 [#7390]: https://github.com/home-assistant/home-assistant/pull/7390 [#7391]: https://github.com/home-assistant/home-assistant/pull/7391 [#7399]: https://github.com/home-assistant/home-assistant/pull/7399 [#7404]: https://github.com/home-assistant/home-assistant/pull/7404 [#7405]: https://github.com/home-assistant/home-assistant/pull/7405 [#7407]: https://github.com/home-assistant/home-assistant/pull/7407 [#7408]: https://github.com/home-assistant/home-assistant/pull/7408 [#7409]: https://github.com/home-assistant/home-assistant/pull/7409 [#7410]: https://github.com/home-assistant/home-assistant/pull/7410 [#7411]: https://github.com/home-assistant/home-assistant/pull/7411 [#7418]: https://github.com/home-assistant/home-assistant/pull/7418 [#7419]: https://github.com/home-assistant/home-assistant/pull/7419 [#7420]: https://github.com/home-assistant/home-assistant/pull/7420 [#7421]: https://github.com/home-assistant/home-assistant/pull/7421 [#7426]: https://github.com/home-assistant/home-assistant/pull/7426 [#7427]: https://github.com/home-assistant/home-assistant/pull/7427 [#7428]: https://github.com/home-assistant/home-assistant/pull/7428 [#7430]: https://github.com/home-assistant/home-assistant/pull/7430 [#7432]: https://github.com/home-assistant/home-assistant/pull/7432 [#7433]: https://github.com/home-assistant/home-assistant/pull/7433 [#7434]: https://github.com/home-assistant/home-assistant/pull/7434 [#7436]: https://github.com/home-assistant/home-assistant/pull/7436 [#7437]: https://github.com/home-assistant/home-assistant/pull/7437 [#7439]: https://github.com/home-assistant/home-assistant/pull/7439 [#7440]: https://github.com/home-assistant/home-assistant/pull/7440 [#7441]: https://github.com/home-assistant/home-assistant/pull/7441 [#7443]: https://github.com/home-assistant/home-assistant/pull/7443 [#7451]: https://github.com/home-assistant/home-assistant/pull/7451 [@Cadair]: https://github.com/Cadair [@ChristianKuehnel]: https://github.com/ChristianKuehnel [@JasonCarter80]: https://github.com/JasonCarter80 [@JshWright]: https://github.com/JshWright [@KlaasH]: https://github.com/KlaasH [@LvivEchoes]: https://github.com/LvivEchoes [@MartinHjelmare]: https://github.com/MartinHjelmare [@Teagan42]: https://github.com/Teagan42 [@abmantis]: https://github.com/abmantis [@alanfischer]: https://github.com/alanfischer [@amelchio]: https://github.com/amelchio [@amigian74]: https://github.com/amigian74 [@andrey-git]: https://github.com/andrey-git [@armills]: https://github.com/armills [@arsaboo]: https://github.com/arsaboo [@bah2830]: https://github.com/bah2830 [@balloob]: https://github.com/balloob [@biacz]: https://github.com/biacz [@craftyguy]: https://github.com/craftyguy [@cribbstechnologies]: https://github.com/cribbstechnologies [@cyberjunky]: https://github.com/cyberjunky [@cyberplant]: https://github.com/cyberplant [@danielhiversen]: https://github.com/danielhiversen [@danielperna84]: https://github.com/danielperna84 [@darookee]: https://github.com/darookee [@deisi]: https://github.com/deisi [@drkp]: https://github.com/drkp [@fabaff]: https://github.com/fabaff [@fabfurnari]: https://github.com/fabfurnari [@hmn]: https://github.com/hmn [@imrehg]: https://github.com/imrehg [@janLo]: https://github.com/janLo [@jotunacorn]: https://github.com/jotunacorn [@keatontaylor]: https://github.com/keatontaylor [@mezz64]: https://github.com/mezz64 [@micw]: https://github.com/micw [@mjg59]: https://github.com/mjg59 [@nkgilley]: https://github.com/nkgilley [@onsmam]: https://github.com/onsmam [@patrickeasters]: https://github.com/patrickeasters [@pavoni]: https://github.com/pavoni [@postlund]: https://github.com/postlund [@pschmitt]: https://github.com/pschmitt [@pvizeli]: https://github.com/pvizeli [@rcloran]: https://github.com/rcloran [@robbiet480]: https://github.com/robbiet480 [@scarface-4711]: https://github.com/scarface-4711 [@sdague]: https://github.com/sdague [@swbradshaw]: https://github.com/swbradshaw [@tchellomello]: https://github.com/tchellomello [@titilambert]: https://github.com/titilambert [@turbokongen]: https://github.com/turbokongen [@w1ll1am23]: https://github.com/w1ll1am23 [@wokar]: https://github.com/wokar [@wuub]: https://github.com/wuub [@zeltom]: https://github.com/zeltom [binary_sensor.alarmdecoder docs]: /integrations/alarmdecoder [binary_sensor.eight_sleep docs]: /integrations/eight_sleep [binary_sensor.maxcube docs]: /integrations/maxcube [binary_sensor.octoprint docs]: /integrations/octoprint#binary-传感器 [binary_sensor.pilight docs]: /integrations/pilight#binary-传感器 [binary_sensor.ping docs]: /integrations/ping#binary-传感器 [binary_sensor.workday docs]: /integrations/workday [binary_sensor.zha docs]: /integrations/zha [摄像头.netatmo docs]: /integrations/netatmo#摄像头 [温控 docs]: /integrations/温控/ [温控.ecobee docs]: /integrations/ecobee [温控.maxcube docs]: /integrations/maxcube [温控.zwave docs]: /integrations/zwave#温控 [遮盖.garadget docs]: /integrations/garadget [遮盖.opengarage docs]: /integrations/opengarage [遮盖.zwave docs]: /integrations/zwave#遮盖 [device_tracker.zha docs]: /integrations/device_tracker.zha/ [ecobee docs]: /integrations/ecobee/ [eight_sleep docs]: /integrations/eight_sleep/ [enocean docs]: /integrations/enocean/ [homematic docs]: /integrations/homematic/ [image_processing.dlib_face_detect docs]: /integrations/dlib_face_detect [image_processing.dlib_face_identify docs]: /integrations/dlib_face_identify [image_processing.microsoft_face_detect docs]: /integrations/microsoft_face_detect [image_processing.opencv docs]: /integrations/opencv [joaoapps_join docs]: /integrations/joaoapps_join/ [灯光 docs]: /integrations/灯光/ [灯光.avion docs]: /integrations/avion [灯光.blinkt docs]: /integrations/blinkt [灯光.decora docs]: /integrations/decora [灯光.flux_led docs]: /integrations/flux_led [灯光.hue docs]: /integrations/hue [灯光.lifx docs]: /integrations/lifx [灯光.osramlightify docs]: /integrations/osramlightify [灯光.piglow docs]: /integrations/piglow [灯光.sensehat docs]: /integrations/sensehat#灯光 [灯光.tradfri docs]: /integrations/tradfri [灯光.zha docs]: /integrations/zha [灯光.zwave docs]: /integrations/zwave [maxcube docs]: /integrations/maxcube/ [媒体播放器 docs]: /integrations/媒体播放器/ [媒体播放器.spotify docs]: /integrations/spotify [媒体播放器.webostv docs]: /integrations/webostv#media-player [MQTT docs]: /integrations/MQTT/ [通知.html5 docs]: /integrations/html5 [通知.joaoapps_join docs]: /integrations/joaoapps_join [通知.mailgun docs]: /integrations/mailgun [通知.matrix docs]: /integrations/matrix/#通知 [通知.smtp docs]: /integrations/smtp [通知.telegram docs]: /integrations/telegram [通知.webostv docs]: /integrations/webostv [octoprint docs]: /integrations/octoprint/ [opencv docs]: /integrations/opencv/ [plant docs]: /integrations/plant/ [recorder docs]: /integrations/recorder/ [rfxtrx docs]: /integrations/rfxtrx/ [rss_feed_template docs]: /integrations/rss_feed_template/ [传感器.cert_expiry docs]: /integrations/cert_expiry [传感器.dht docs]: /integrations/dht [传感器.eight_sleep docs]: /integrations/eight_sleep [传感器.envirophat docs]: /integrations/envirophat [传感器.ios docs]: /integrations/传感器.ios/ [传感器.lyft docs]: /integrations/lyft [传感器.pushbullet docs]: /integrations/pushbullet#传感器 [传感器.speedtest docs]: /integrations/speedtestdotnet [传感器.thinkingcleaner docs]: /integrations/thinkingcleaner#传感器 [传感器.vera docs]: /integrations/vera#传感器 [传感器.zamg docs]: /integrations/zamg#传感器 [传感器.zha docs]: /integrations/zha [开关.flux docs]: /integrations/flux [开关.thinkingcleaner docs]: /integrations/thinkingcleaner#开关 [开关.wemo docs]: /integrations/wemo [开关.zha docs]: /integrations/zha [telegram_bot docs]: /integrations/telegram_bot/ [telegram_bot.polling docs]: /integrations/telegram_polling [telegram_bot.webhooks docs]: /integrations/telegram_webhooks [updater docs]: /integrations/updater/ [vera docs]: /integrations/vera/ [wemo docs]: /integrations/wemo/ [wink docs]: /integrations/wink/ [zha docs]: /integrations/zha/ [forum]: https://community.home-assistant.io/ [issue]: https://github.com/home-assistant/home-assistant/issues [#7062]: https://github.com/home-assistant/home-assistant/pull/7062 [#7468]: https://github.com/home-assistant/home-assistant/pull/7468 [#7469]: https://github.com/home-assistant/home-assistant/pull/7469 [#7476]: https://github.com/home-assistant/home-assistant/pull/7476 [@finish06]: https://github.com/finish06 [@frog32]: https://github.com/frog32 [@pezinek]: https://github.com/pezinek [device_tracker.unifi docs]: /integrations/unifi [传感器.wunderground docs]: /integrations/wunderground [discord]: https://discord.gg/c5DvZ4e --- url: /home-assistant/blog/2017-05-07-grazer-linuxtage-2017-talk-python-everywhere.md --- # Grazer Linuxtage 2017: Python Everywhere I like Python. It is a clean, easy-to-read, easy-to-learn language. Yet when you use it for some time, you still find more features that improve your coding. What I probably like most about Python is the community and the great libraries that already exist. Often, solving a problem means including an existing library and writing some glue code. That makes it quick to get things up and running. I just gave a talk on how you can run Python to automate your home, yes, with Home Assistant, but also with [MicroPython]. MicroPython allows you to run Python on your DIY sensors and switches around your home. Python everywhere, even on the chips that give Home Assistant the data that makes it awesome.
[MicroPython]: https://micropython.org --- url: /home-assistant/blog/2017-05-13-home-assistant-on-orange-pi-zero.md --- # Home Assistant on an Orange Pi Zero This blog post is about setting up Home Assistant on an [Orange Pi Zero](http://www.orangepi.org/orangepizero/). Like the setup on a [Raspberry Pi Zero](/home-assistant/blog/2017/05/01/home-assistant-on-raspberry-pi-zero-in-30-minutes/), it will only take a couple of minutes to get a fully functional, super-cheap Home Assistant hub for less than 18 euros, including a case and power supply. Reasons to use an Orange Pi Zero, besides the price, are the built-in Ethernet port and its availability.

Download [Armbian](https://www.armbian.com/orange-pi-zero/) and create the SD card with [balenaEtcher](https://www.balena.io/etcher). There is no way to connect a display to the Orange Pi Zero. This means you need a wired network setup with a DHCP server. After your Orange Pi Zero is running, give it some time, and look for its IP address. The hostname is `orangepizero`. After you find the IP address, use your SSH client to connect to the Orange Pi Zero. The default password is `1234`. ```bash $ ssh root@192.168.0.151 [...] root@192.168.0.151's password: You are required to change your password immediately (root enforced) ___ ____ _ _____ / _ \ _ __ __ _ _ __ __ _ ___ | _ \(_) |__ /___ _ __ ___ | | | | '__/ _` | '_ \ / _` |/ _ \ | |_) | | / // _ \ '__/ _ \ | |_| | | | (_| | | | | (_| | __/ | __/| | / /| __/ | | (_) | \___/|_| \__,_|_| |_|\__, |\___| |_| |_| /____\___|_| \___/ |___/ Welcome to ARMBIAN 5.27.170514 nightly Ubuntu 16.04.2 LTS 4.11.0-sun8i System load: 0.86 0.35 0.13 Up time: 9 min Memory usage: 5 % of 496MB IP: 192.168.0.151 CPU temp: 39°C Usage of /: 16% of 7.1G [ General system configuration: armbian-config ] New to Armbian? Check the documentation first: https://docs.armbian.com Changing password for root. (current) UNIX password: Enter new UNIX password: Retype new UNIX password: You are using Armbian nightly build. It is provided AS IS with NO WARRANTY and NO END USER SUPPORT. Creating a new user account. Press to abort Please provide a username (eg. your forename): ha Trying to add user ha perl: warning: Setting locale failed. perl: warning: Please check that your locale settings: LANGUAGE = "en_US.UTF-8", LC_ALL = (unset), LC_PAPER = "de_CH.UTF-8", LC_MONETARY = "de_CH.UTF-8", LC_NUMERIC = "de_CH.UTF-8", LC_MESSAGES = "en_US.UTF-8", LC_MEASUREMENT = "de_CH.UTF-8", LC_TIME = "de_CH.UTF-8", LANG = "en_US.UTF-8" are supported and installed on your system. perl: warning: Falling back to a fallback locale ("en_US.UTF-8"). Adding user `ha' ... Adding new group `ha' (1000) ... Adding new user `ha' (1000) with group `ha' ... Creating home directory `/home/ha' ... Copying files from `/etc/skel' ... Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully Changing the user information for ha Enter the new value, or press ENTER for the default Full Name []: homeassistant Room Number []: Work Phone []: Home Phone []: Other []: Is the information correct? [Y/n] y Dear homeassistant, your account ha has been created and is sudo enabled. Please use this account for your daily work from now on. root@orangepizero:~# ``` Get the latest details about the packages. ```bash root@orangepizero:~# apt-get update Hit:1 http://ports.ubuntu.com xenial InRelease Get:2 http://ports.ubuntu.com xenial-security InRelease [102 kB] Hit:3 http://beta.armbian.com xenial InRelease Get:4 http://ports.ubuntu.com xenial-updates InRelease [102 kB] Get:5 http://ports.ubuntu.com xenial-backports InRelease [102 kB] Get:6 http://ports.ubuntu.com xenial-updates/main armhf Packages [479 kB] Get:7 http://ports.ubuntu.com xenial-updates/universe armhf Packages [419 kB] Fetched 1205 kB in 7s (158 kB/s) Reading package lists... Done ``` Let's run an upgrade to make sure all available packages are up to date. ```bash root@orangepizero:~# apt-get upgrade ``` Now, we are installing the requirements for Home Assistant. ```bash root@orangepizero:~# apt-get install python3-dev python3-pip python3-venv ``` These steps to install Home Assistant are also described in the [documentation](/home-assistant/docs/installation/armbian/) and the guide for [`venv`](/home-assistant/docs/installation/virtualenv/). Switch to the newly created user `ha` and perform the remaining installation steps, which are reduced to the minimum below: ```bash ha@orangepizero:~$ pyvenv-3.5 homeassistant ha@orangepizero:~$ cd homeassistant && source bin/activate (homeassistant) ha@orangepizero:~/homeassistant$ pip3 install --upgrade pip (homeassistant) ha@orangepizero:~/homeassistant$ pip3 install homeassistant (homeassistant) ha@orangepizero:~/homeassistant$ hass ```

--- url: /home-assistant/blog/2017-05-19-home-assistant-at-pycon-us-2017.md --- # Home Assistant 亮相 PyCon US 2017 再过 12 个小时,PyCon US 2017 就要开幕了。这场大会很令人期待,因为会有很多 Home Assistant 的开发者和用户到场,终于可以线下见面。 和去年一样,我们会举办一场 [Home Assistant Open Space](https://us.pycon.org/2017/events/open-spaces/)。欢迎你过来,向现场的开发者提出任何问题。~~我们还没有预订时段,但会在明天完成。等我们确认时间和地点后,会更新这篇文章,并在社交媒体上公布。~~ **第一场 open space 将于周五下午 4 点在 B112 房间举行。** 我们还会在周一到周三参加[开发冲刺](https://us.pycon.org/2017/community/sprints/)。你只需要带上一台笔记本电脑。我们会帮你搭建开发环境,让你很快就能开始为 Home Assistant 编写代码。~~会议中心内的具体地点稍后公布。~~ **我们在 A108 房间。** 最后想说,Home Assistant 社区真的非常活跃,所以如果我们没记住你的名字、你提交的问题,或者你的贡献,请不要介意。 --- url: /home-assistant/blog/2017-05-20-automation-editor-zwave-panel-ocr.md --- # Home Assistant 0.45: Automation editor, Z-Wave panel, OCR 欢迎来到 Home Assistant 又一次精彩发布!虽然一些贡献者和用户此时正齐聚 PyCon US 2017,我们仍然带来了一次相当出色的版本更新。 本次发布的第一个亮点,是许多人一直在期待的功能:自动化编辑器。它目前仍处于实验阶段,很多内容还在持续完善中,但已经可以使用。你现在可以创建新的自动化,也可以编辑现有自动化。如果你是从全新配置开始,那已经可以直接使用;否则,请先查看[这些说明](/home-assistant/docs/automation/editor/index.md),让你的自动化做好在 UI 中编辑的准备。

想看看新版本的实际效果,可以观看来自 [BRUHautomation](http://www.bruhautomation.com/) 的 [Ben](https://twitter.com/BRUHautomation) 制作的这个[视频](https://youtu.be/0j_hWdCTip4)。
由于编辑器仍是实验功能,目前还有一些限制。现在仅支持 Chrome 和 Chromium,并不是所有触发器和动作都已支持,条件也暂时还不支持。不过基础已经搭好了,所以如果你想参与贡献,非常欢迎加入。 在 Z-Wave 方面,这次也有很多进展。最大的更新来自 [@turbokongen] 对 Z-Wave 面板的大幅扩展。你现在可以直接修改配置参数并管理自己的设备。

感谢 Python Open Z-Wave 团队的努力,我们现在可以按需直接从 PyPI 安装它,不再需要你自己预先编译。这也有助于确保系统使用的 Python Open Z-Wave 版本与代码预期一致。 :::warning 如果你在 Open Z-Wave 的 `options.xml` 中设置了安全密钥,请把 `options.xml` 复制到 Home Assistant 配置目录中。只有保存在这里的选项才会被持久化。 ::: 此外,[@armills] 还主导了相关工作,为 Z-Wave 实现了完整的测试覆盖。感谢所有辛苦付出。 本次发布还带来了两个能让非智能设备稍微“聪明”一些的集成:[`file` 传感器][传感器.file docs] 和 [`seven_segments` OCR 图像处理平台][image_processing.seven_segments docs]。前者可以直接读取由日志程序或类似工具生成的纯文本文件;后者则能从包含七段数码管显示的截图中提取数值。

最后,我们的 Docker 镜像现在已经基于 Python 3.6。这个版本比 Python 3.5 更快,占用内存也更少,确实很棒。 如果你正在使用我们的[实验性 Hass.io 镜像][hass.io],那么这次在面板服务方式上有一项破坏性变更。如果你已经有现有安装,请务必先把 supervisor 更新到最新版本,再升级 Home Assistant。如果你打算重新刷入新的 Hass.io 镜像,请确保只使用[安装页面][hass.io-安装]中提供的全新 0.8 镜像。 [hass.io]: https://community.home-assistant.io/t/introducing-hass-io/17296 [hass.io-安装]: /hassio/installation/ ## 新集成 * 新增 raspihats 组件 ([@florincosta] - [#7392]) ([raspihats docs]) (new-platform) * 新增 Datadog 组件 ([@nunofgs] - [#7158]) ([datadog docs]) (new-platform) * 新增自动化配置面板支持 ([@balloob] - [#7509]) ([config.自动化 docs]) (new-platform) * 新增 Z-Wave 面板 API ([@turbokongen] - [#7456]) ([zwave docs]) ([zwave.api docs]) (new-platform) * 新增 myStrom 按钮支持 ([@fabaff] - [#7099]) ([binary\_sensor.mystrom docs][binary_sensor.mystrom docs]) (new-platform) * 新增 PiFace Digital I/O 模块支持 ([@basschipper] - [#7494]) ([rpi\_pfio docs][rpi_pfio docs]) ([binary\_sensor.rpi\_pfio docs][binary_sensor.rpi_pfio docs]) ([开关.rpi\_pfio docs][开关.rpi_pfio docs]) (new-platform) * 新增 raspihats 二元传感器 ([@florincosta] - [#7508]) ([binary\_sensor.raspihats docs][binary_sensor.raspihats docs]) (new-platform) * 新增 Lutron Serena 窗帘支持 ([@gurumitts] - [#7565]) ([lutron\_caseta docs][lutron_caseta docs]) ([遮盖.lutron\_caseta docs][遮盖.lutron_caseta docs]) (new-platform) * 在传感器和遥控器平台新增 Kira 组件 ([@stu-gott] - [#7479]) ([kira docs]) ([遥控器.kira docs]) ([传感器.kira docs]) (new-platform) * 新增 File 传感器 ([@fabaff] - [#7569]) ([传感器.file docs]) (new-platform) * 新增 Seven segments OCR 图像处理平台 ([@fabaff] - [#7632]) ([image\_processing.seven\_segments docs][image_processing.seven_segments docs]) (new-platform) * 新增 Axis 组件 ([@Kane610] - [#7381]) ([axis docs]) (new-platform) ## 发布 0.45.1 - May 22 * Fix telegram chats ([@azogue] - [#7689]) ([通知.telegram docs]) ([telegram\_bot docs][telegram_bot docs]) * Fix playback control of web streams ([@cgtobi] - [#7683]) ([媒体播放器.volumio docs]) * device\_tracker.ubus: Handle empty results ([@tobygray] - [#7673]) ([device\_tracker.ubus docs][device_tracker.ubus docs]) * Allow fetching hass.io 面板 without auth ([@balloob] - [#7714]) ([hassio docs]) ## 如果你需要帮助 欢迎使用我们非常活跃的 [论坛][forum],或者加入聊天频道 [discord][discord]。发布说明虽然也开放评论,但我们更推荐你使用前面的沟通渠道。谢谢。 ## 反馈问题 如果你遇到了这次发布引入的问题,请到我们的 [问题追踪器][issue] 提交反馈,并确保填写问题模板中的所有字段。 ## 不向后兼容的变更 * PyPI Openzwave ([@JshWright] - [#7415]) ([zwave docs]) (breaking change) * Remove listening to `homeassistant_start` with event 自动化 ([@balloob] - [#7474]) ([自动化.event docs]) (breaking change) ## All changes * Add hass to rfxtrx object ([@danielhiversen] - [#6844]) * Add new raspihats component ([@florincosta] - [#7392]) ([raspihats docs]) (new-platform) * 传感器.envirophat: add missing requirement ([@imrehg] - [#7451]) ([传感器.envirophat docs]) * PyPI Openzwave ([@JshWright] - [#7415]) ([zwave docs]) (breaking change) * Add datadog component ([@nunofgs] - [#7158]) * Add tests for deprecation 助手 ([@armills] - [#7452]) * Forecasts for 天气 underground ([@pezinek] - [#7062]) ([传感器.wunderground docs]) * 传感器.envirophat: add missing requirement ([@imrehg] - [#7451]) ([传感器.envirophat docs]) * 开关 russound, pymysensors, and pocketcasts to pypi ([@andrey-git] - [#7449]) * 升级 pymysensors to 0.10.0 ([@MartinHjelmare] - [#7469]) * 升级 Dockerfile to Python 3.6 ([@balloob] - [#7471]) * Test only dependencies ([@balloob] - [#7472]) * 更新 to pyunifi 2.12 ([@finish06] - [#7468]) ([device\_tracker.unifi docs][device_tracker.unifi docs]) * Remove listening to homeassistant\_start with event 自动化 ([@balloob] - [#7474]) ([自动化.event docs]) (breaking change) * Fix plant MIN\_TEMPERATURE, MAX\_TEMPERATURE validation ([@frog32] - [#7476]) ([plant docs]) * Forecasts for 天气 underground ([@pezinek] - [#7062]) ([传感器.wunderground docs]) * 升级 pymysensors to 0.10.0 ([@MartinHjelmare] - [#7469]) * Fix plant MIN\_TEMPERATURE, MAX\_TEMPERATURE validation ([@frog32] - [#7476]) ([plant docs]) * 更新 to pyunifi 2.12 ([@finish06] - [#7468]) ([device\_tracker.unifi docs][device_tracker.unifi docs]) * Uses pypi for deps ([@gurumitts] - [#7485]) ([lutron\_caseta docs][lutron_caseta docs]) * 0.44.2 ([@balloob] - [#7488]) * LIFX: avoid out-of-bounds hue aborting the colorloop effect ([@amelchio] - [#7495]) * 升级 async\_timeout to 1.2.1 ([@fabaff] - [#7490]) * Prevent printing of packets. ([@aequitas] - [#7492]) ([rflink docs]) * 升级 beautifulsoup4 to 4.6.0 ([@fabaff] - [#7491]) ([传感器.scrape docs]) * 开关 onkyo to pypi ([@andrey-git] - [#7497]) ([媒体播放器.onkyo docs]) * Fixed potential AttributeError when checking for deleted sources ([@scarface-4711] - [#7502]) ([媒体播放器.denonavr docs]) * Refactor sun component for correctness ([@armills] - [#7295]) * new source only forces "play" if the current 状态 is "playing" ([@abmantis] - [#7506]) ([媒体播放器.spotify docs]) * Correct retrieval of spotify shuffle 状态 ([@andersonshatch] - [#7505]) ([媒体播放器.spotify docs]) * Fix sonos sleep timer ([@frog32] - [#7503]) ([媒体播放器.sonos docs]) * Add support for 自动化 config 面板 ([@balloob] - [#7509]) (\[自动化 docs]) ([config.自动化 docs]) ([config docs]) (new-platform) * Zwave 面板 api ([@turbokongen] - [#7456]) ([zwave docs]) ([zwave.api docs]) (new-platform) * 更新 Docker dev environment to python3.6 ([@frog32] - [#7520]) * 开关 basicmodem and python-roku to pypi ([@andrey-git] - [#7514]) ([媒体播放器.roku docs]) ([传感器.modem\_callerid docs][传感器.modem_callerid docs]) * 传感器.envirophat: do not set up platform if hardware is not attached ([@imrehg] - [#7438]) ([传感器.envirophat docs]) * Telegram Bot enhancements with callback queries and new 通知 服务 ([@azogue] - [#7454]) ([telegram\_bot docs][telegram_bot docs]) ([通知.telegram docs]) ([telegram\_bot.polling docs][telegram_bot.polling docs]) ([telegram\_bot.服务.yaml docs][telegram_bot.服务.yaml docs]) ([telegram\_bot.webhooks docs][telegram_bot.webhooks docs]) * Add 密码 parameter to uvc component ([@nunofgs] - [#7499]) ([摄像头.uvc docs]) * Don't interact with hass directly ([@fabaff] - [#7099]) ([binary\_sensor.mystrom docs][binary_sensor.mystrom docs]) (new-platform) * Support for the PiFace Digital I/O module ([@basschipper] - [#7494]) ([rpi\_pfio docs][rpi_pfio docs]) ([binary\_sensor.rpi\_pfio docs][binary_sensor.rpi_pfio docs]) ([开关.rpi\_pfio docs][开关.rpi_pfio docs]) (new-platform) * 升级 limitlessled to 1.0.7 ([@corneyl] - [#7525]) ([灯光.limitlessled docs]) * 更新 docstrings and 日志 messages ([@fabaff] - [#7526]) ([灯光.blinksticklight docs]) ([灯光.enocean docs]) ([灯光.flux\_led docs][灯光.flux_led docs]) ([灯光.insteon\_local docs][灯光.insteon_local docs]) ([灯光.insteon\_plm docs][灯光.insteon_plm docs]) ([灯光.isy994 docs]) ([灯光.limitlessled docs]) ([灯光.mystrom docs]) * Try to request current\_location Automatic scope ([@armills] - [#7447]) * Add myStrom 二元sensor ([@fabaff] - [#7530]) * Add not-context-manager ([@fabaff] - [#7523]) * Threadsafe configurator ([@Kane610] - [#7536]) ([configurator docs]) * Fix for #7459 ([@deftdawg] - [#7544]) ([alexa docs]) * 升级 sendgrid to 4.1.0 ([@fabaff] - [#7538]) ([通知.sendgrid docs]) * Automatic 版本 bump ([@armills] - [#7555]) * 升级 dweepy to 0.3.0 ([@fabaff] - [#7550]) ([dweet docs]) ([传感器.dweet docs]) * Add SSL support to NZBGet 传感器 ([@tboyce021] - [#7553]) ([传感器.nzbget docs]) * Do not 安装 all dependencies in dev mode ([@balloob] - [#7548]) * Hide proximity updates in logbook ([@armills] - [#7549]) ([logbook docs]) * Only 安装 tox in dev mode ([@balloob] - [#7557]) * Support adding different server locations for Microsoft face component ([@tsvi] - [#7532]) ([microsoft\_face docs][microsoft_face docs]) * Treat swing and 风扇 level as optional in Sensibo 温控. ([@andrey-git] - [#7560]) ([温控.sensibo docs]) * LIFX: add lifx\_set\_state 服务 call ([@amelchio] - [#7552]) ([灯光.lifx docs]) * Add raspihats 二元sensor ([@florincosta] - [#7508]) ([binary\_sensor.raspihats docs][binary_sensor.raspihats docs]) (new-platform) * 更新 pywebpush to 1.0.0 ([@perosb] - [#7561]) ([通知.html5 docs]) * Initialize sun with correct values. ([@aequitas] - [#7559]) ([sun docs]) * Comment RasPi specific requirements ([@Juggels] - [#7562]) ([传感器.envirophat docs]) * 更新 netdisco ([@balloob] - [#7563]) * Support lutron serena shades ([@gurumitts] - [#7565]) ([lutron\_caseta docs][lutron_caseta docs]) ([遮盖.lutron\_caseta docs][遮盖.lutron_caseta docs]) (new-platform) * Tests for zwave discovery logic ([@armills] - [#7566]) * Tests for zwave 设置 features ([@armills] - [#7570]) * Blink 版本 bump ([@fronzbot] - [#7571]) ([blink docs]) ([传感器.blink docs]) * Fix systematic 警告 in influxdb 传感器 ([@bestlibre] - [#7541]) ([传感器.influxdb docs]) * Fix Kodi specific 服务 registry and add descriptions ([@azogue] - [#7551]) ([媒体播放器.kodi docs]) * Add Kira component to 传感器 and 遥控器 platforms ([@stu-gott] - [#7479]) ([kira docs]) ([遥控器.kira docs]) ([传感器.kira docs]) (new-platform) * Add tests for zwave network events ([@armills] - [#7573]) * Additional Wink 门锁 features ([@w1ll1am23] - [#7445]) * Websocket\_api: avoid parallel drain ([@balloob] - [#7576]) ([websocket\_api docs][websocket_api docs]) * Remove more test requirements ([@balloob] - [#7574]) * 摄像头.zoneminder: Handle old versions of zoneminder ([@mnoorenberghe] - [#7589]) ([摄像头.zoneminder docs]) * Pass additional arguments to tox in test\_docker ([@frog32] - [#7591]) * Fix websocket api reaching queue ([@balloob] - [#7590]) ([websocket\_api docs][websocket_api docs]) * SMTP 通知 enhancements: full HTML emails and custom `product_name` in email headers ([@azogue] - [#7533]) ([通知.smtp docs]) * 自动化 状态 Change For timer 属性 fix ([@armills] - [#7584]) ([自动化.状态 docs]) * Add posibility to specify snmp protocol 版本 ([@jhemzal] - [#7564]) ([传感器.snmp docs]) * Add sonos 报警 clock 更新 服务 ([@frog32] - [#7521]) ([媒体播放器.sonos docs]) * Fix handling of single 用户 ([@mezz64] - [#7587]) ([eight\_sleep docs][eight_sleep docs]) * File 传感器 ([@fabaff] - [#7569]) ([传感器.file docs]) (new-platform) * Make miflora monitored\_conditions parameter optional ([@frog32] - [#7598]) ([传感器.miflora docs]) * Force 自动化 ids to always be a string ([@balloob] - [#7612]) (\[自动化 docs]) * 更新 Docker base 图像 to python 3.6 ([@pschmitt] - [#7613]) * Add Content-type: 图像/jpeg for 摄像头 proxy ([@olekenneth] - [#7581]) ([摄像头 docs]) * Fix typo and 更新 style to match the other platforms ([@fabaff] - [#7621]) ([image\_processing.opencv docs][image_processing.opencv docs]) * Bump pyvera - fixes issue with % in brightness levels. ([@pavoni] - [#7622]) ([vera docs]) * Add kelvin/brightness\_pct alternatives to 灯光.turn\_on ([@amelchio] - [#7596]) ([灯光.lifx docs]) ([灯光 docs]) * Add support for disabling tradfri groups ([@cnrd] - [#7593]) ([tradfri docs]) ([灯光.tradfri docs]) * 更新 docstrings and comments ([@fabaff] - [#7626]) ([image\_processing.openalpr\_cloud docs][image_processing.openalpr_cloud docs]) ([image\_processing.openalpr\_local docs][image_processing.openalpr_local docs]) * 升级 Sphinx to 1.6.1 ([@fabaff] - [#7624]) * 更新 docstrings ([@fabaff] - [#7630]) ([image\_processing docs][image_processing docs]) ([image\_processing.dlib\_face\_detect docs][image_processing.dlib_face_detect docs]) ([image\_processing.dlib\_face\_identify docs][image_processing.dlib_face_identify docs]) ([image\_processing.microsoft\_face\_detect docs][image_processing.microsoft_face_detect docs]) ([image\_processing.microsoft\_face\_identify docs][image_processing.microsoft_face_identify docs]) ([image\_processing.opencv docs][image_processing.opencv docs]) * Kodi specific 服务 to call Kodi API methods ([@azogue] - [#7603]) ([媒体播放器.kodi docs]) * Updated limitlessled requirement to v1.0.8 ([@corneyl] - [#7629]) * Osram lightify Removed wrong assignment ([@commento] - [#7615]) ([灯光.osramlightify docs]) * Updated dependency ([@danielperna84] - [#7638]) ([homematic docs]) * Seven segments OCR 图像 processing ([@fabaff] - [#7632]) ([image\_processing.seven\_segments docs][image_processing.seven_segments docs]) ([image\_processing docs][image_processing docs]) (new-platform) * Abort tests when instances leaked ([@balloob] - [#7623]) * Coerce color\_temp to int even when passed in as kelvin ([@amelchio] - [#7640]) ([灯光 docs]) * Fix 自动化 failing to 设置 if no 自动化 specified ([@balloob] - [#7647]) (\[自动化 docs]) [#6844]: https://github.com/home-assistant/home-assistant/pull/6844 [#7062]: https://github.com/home-assistant/home-assistant/pull/7062 [#7099]: https://github.com/home-assistant/home-assistant/pull/7099 [#7158]: https://github.com/home-assistant/home-assistant/pull/7158 [#7295]: https://github.com/home-assistant/home-assistant/pull/7295 [#7381]: https://github.com/home-assistant/home-assistant/pull/7381 [#7392]: https://github.com/home-assistant/home-assistant/pull/7392 [#7415]: https://github.com/home-assistant/home-assistant/pull/7415 [#7438]: https://github.com/home-assistant/home-assistant/pull/7438 [#7445]: https://github.com/home-assistant/home-assistant/pull/7445 [#7447]: https://github.com/home-assistant/home-assistant/pull/7447 [#7449]: https://github.com/home-assistant/home-assistant/pull/7449 [#7451]: https://github.com/home-assistant/home-assistant/pull/7451 [#7452]: https://github.com/home-assistant/home-assistant/pull/7452 [#7454]: https://github.com/home-assistant/home-assistant/pull/7454 [#7456]: https://github.com/home-assistant/home-assistant/pull/7456 [#7468]: https://github.com/home-assistant/home-assistant/pull/7468 [#7469]: https://github.com/home-assistant/home-assistant/pull/7469 [#7471]: https://github.com/home-assistant/home-assistant/pull/7471 [#7472]: https://github.com/home-assistant/home-assistant/pull/7472 [#7474]: https://github.com/home-assistant/home-assistant/pull/7474 [#7476]: https://github.com/home-assistant/home-assistant/pull/7476 [#7479]: https://github.com/home-assistant/home-assistant/pull/7479 [#7485]: https://github.com/home-assistant/home-assistant/pull/7485 [#7488]: https://github.com/home-assistant/home-assistant/pull/7488 [#7490]: https://github.com/home-assistant/home-assistant/pull/7490 [#7491]: https://github.com/home-assistant/home-assistant/pull/7491 [#7492]: https://github.com/home-assistant/home-assistant/pull/7492 [#7494]: https://github.com/home-assistant/home-assistant/pull/7494 [#7495]: https://github.com/home-assistant/home-assistant/pull/7495 [#7497]: https://github.com/home-assistant/home-assistant/pull/7497 [#7499]: https://github.com/home-assistant/home-assistant/pull/7499 [#7502]: https://github.com/home-assistant/home-assistant/pull/7502 [#7503]: https://github.com/home-assistant/home-assistant/pull/7503 [#7505]: https://github.com/home-assistant/home-assistant/pull/7505 [#7506]: https://github.com/home-assistant/home-assistant/pull/7506 [#7508]: https://github.com/home-assistant/home-assistant/pull/7508 [#7509]: https://github.com/home-assistant/home-assistant/pull/7509 [#7514]: https://github.com/home-assistant/home-assistant/pull/7514 [#7520]: https://github.com/home-assistant/home-assistant/pull/7520 [#7521]: https://github.com/home-assistant/home-assistant/pull/7521 [#7523]: https://github.com/home-assistant/home-assistant/pull/7523 [#7525]: https://github.com/home-assistant/home-assistant/pull/7525 [#7526]: https://github.com/home-assistant/home-assistant/pull/7526 [#7530]: https://github.com/home-assistant/home-assistant/pull/7530 [#7532]: https://github.com/home-assistant/home-assistant/pull/7532 [#7533]: https://github.com/home-assistant/home-assistant/pull/7533 [#7536]: https://github.com/home-assistant/home-assistant/pull/7536 [#7538]: https://github.com/home-assistant/home-assistant/pull/7538 [#7541]: https://github.com/home-assistant/home-assistant/pull/7541 [#7544]: https://github.com/home-assistant/home-assistant/pull/7544 [#7548]: https://github.com/home-assistant/home-assistant/pull/7548 [#7549]: https://github.com/home-assistant/home-assistant/pull/7549 [#7550]: https://github.com/home-assistant/home-assistant/pull/7550 [#7551]: https://github.com/home-assistant/home-assistant/pull/7551 [#7552]: https://github.com/home-assistant/home-assistant/pull/7552 [#7553]: https://github.com/home-assistant/home-assistant/pull/7553 [#7555]: https://github.com/home-assistant/home-assistant/pull/7555 [#7557]: https://github.com/home-assistant/home-assistant/pull/7557 [#7559]: https://github.com/home-assistant/home-assistant/pull/7559 [#7560]: https://github.com/home-assistant/home-assistant/pull/7560 [#7561]: https://github.com/home-assistant/home-assistant/pull/7561 [#7562]: https://github.com/home-assistant/home-assistant/pull/7562 [#7563]: https://github.com/home-assistant/home-assistant/pull/7563 [#7564]: https://github.com/home-assistant/home-assistant/pull/7564 [#7565]: https://github.com/home-assistant/home-assistant/pull/7565 [#7566]: https://github.com/home-assistant/home-assistant/pull/7566 [#7569]: https://github.com/home-assistant/home-assistant/pull/7569 [#7570]: https://github.com/home-assistant/home-assistant/pull/7570 [#7571]: https://github.com/home-assistant/home-assistant/pull/7571 [#7573]: https://github.com/home-assistant/home-assistant/pull/7573 [#7574]: https://github.com/home-assistant/home-assistant/pull/7574 [#7576]: https://github.com/home-assistant/home-assistant/pull/7576 [#7581]: https://github.com/home-assistant/home-assistant/pull/7581 [#7584]: https://github.com/home-assistant/home-assistant/pull/7584 [#7587]: https://github.com/home-assistant/home-assistant/pull/7587 [#7589]: https://github.com/home-assistant/home-assistant/pull/7589 [#7590]: https://github.com/home-assistant/home-assistant/pull/7590 [#7591]: https://github.com/home-assistant/home-assistant/pull/7591 [#7593]: https://github.com/home-assistant/home-assistant/pull/7593 [#7596]: https://github.com/home-assistant/home-assistant/pull/7596 [#7598]: https://github.com/home-assistant/home-assistant/pull/7598 [#7603]: https://github.com/home-assistant/home-assistant/pull/7603 [#7612]: https://github.com/home-assistant/home-assistant/pull/7612 [#7613]: https://github.com/home-assistant/home-assistant/pull/7613 [#7615]: https://github.com/home-assistant/home-assistant/pull/7615 [#7621]: https://github.com/home-assistant/home-assistant/pull/7621 [#7622]: https://github.com/home-assistant/home-assistant/pull/7622 [#7623]: https://github.com/home-assistant/home-assistant/pull/7623 [#7624]: https://github.com/home-assistant/home-assistant/pull/7624 [#7626]: https://github.com/home-assistant/home-assistant/pull/7626 [#7629]: https://github.com/home-assistant/home-assistant/pull/7629 [#7630]: https://github.com/home-assistant/home-assistant/pull/7630 [#7632]: https://github.com/home-assistant/home-assistant/pull/7632 [#7638]: https://github.com/home-assistant/home-assistant/pull/7638 [#7640]: https://github.com/home-assistant/home-assistant/pull/7640 [#7647]: https://github.com/home-assistant/home-assistant/pull/7647 [@JshWright]: https://github.com/JshWright [@Juggels]: https://github.com/Juggels [@Kane610]: https://github.com/Kane610 [@MartinHjelmare]: https://github.com/MartinHjelmare [@abmantis]: https://github.com/abmantis [@aequitas]: https://github.com/aequitas [@amelchio]: https://github.com/amelchio [@andersonshatch]: https://github.com/andersonshatch [@andrey-git]: https://github.com/andrey-git [@armills]: https://github.com/armills [@azogue]: https://github.com/azogue [@balloob]: https://github.com/balloob [@basschipper]: https://github.com/basschipper [@bestlibre]: https://github.com/bestlibre [@cnrd]: https://github.com/cnrd [@commento]: https://github.com/commento [@corneyl]: https://github.com/corneyl [@cribbstechnologies]: https://github.com/cribbstechnologies [@danielhiversen]: https://github.com/danielhiversen [@danielperna84]: https://github.com/danielperna84 [@fabaff]: https://github.com/fabaff [@finish06]: https://github.com/finish06 [@florincosta]: https://github.com/florincosta [@frog32]: https://github.com/frog32 [@fronzbot]: https://github.com/fronzbot [@gurumitts]: https://github.com/gurumitts [@imrehg]: https://github.com/imrehg [@jhemzal]: https://github.com/jhemzal [@jminardi]: https://github.com/jminardi [@deftdawg]: https://github.com/deftdawg [@mezz64]: https://github.com/mezz64 [@mnoorenberghe]: https://github.com/mnoorenberghe [@nunofgs]: https://github.com/nunofgs [@olekenneth]: https://github.com/olekenneth [@pavoni]: https://github.com/pavoni [@perosb]: https://github.com/perosb [@pezinek]: https://github.com/pezinek [@pschmitt]: https://github.com/pschmitt [@robbiet480]: https://github.com/robbiet480 [@scarface-4711]: https://github.com/scarface-4711 [@stu-gott]: https://github.com/stu-gott [@tboyce021]: https://github.com/tboyce021 [@tsvi]: https://github.com/tsvi [@turbokongen]: https://github.com/turbokongen [@w1ll1am23]: https://github.com/w1ll1am23 [alexa docs]: /integrations/alexa/ [axis docs]: /integrations/axis/ [config.自动化 docs]: /docs/自动化/editor/ [自动化.event docs]: /docs/配置/events/ [自动化.状态 docs]: /docs/配置/state_object/ [binary_sensor.mystrom docs]: /integrations/mystrom#binary-传感器 [binary_sensor.raspihats docs]: /integrations/raspihats#binary-传感器 [binary_sensor.rpi_pfio docs]: /integrations/rpi_pfio#binary-传感器 [blink docs]: /integrations/blink/ [摄像头 docs]: /integrations/摄像头 [摄像头.uvc docs]: /integrations/uvc [摄像头.zoneminder docs]: /integrations/zoneminder#摄像头 [温控.sensibo docs]: /integrations/sensibo [config docs]: /integrations/config [configurator docs]: /integrations/configurator/ [遮盖.lutron_caseta docs]: /integrations/lutron_caseta/ [datadog docs]: /integrations/datadog/ [device_tracker.unifi docs]: /integrations/unifi [dweet docs]: /integrations/dweet/ [eight_sleep docs]: /integrations/eight_sleep/ [homematic docs]: /integrations/homematic/ [image_processing docs]: /integrations/image_processing [image_processing.dlib_face_detect docs]: /integrations/dlib_face_detect [image_processing.dlib_face_identify docs]: /integrations/dlib_face_identify [image_processing.microsoft_face_detect docs]: /integrations/microsoft_face_detect [image_processing.microsoft_face_identify docs]: /integrations/microsoft_face_identify [image_processing.openalpr_cloud docs]: /integrations/openalpr_cloud [image_processing.openalpr_local docs]: /integrations/openalpr_local [image_processing.opencv docs]: /integrations/opencv [image_processing.seven_segments docs]: /integrations/seven_segments [kira docs]: /integrations/kira/ [灯光 docs]: /integrations/灯光 [灯光.blinksticklight docs]: /integrations/blinksticklight [灯光.enocean docs]: /integrations/enocean#灯光 [灯光.flux_led docs]: /integrations/flux_led [灯光.insteon_local docs]: /integrations/insteon/ [灯光.insteon_plm docs]: /integrations/insteon/ [灯光.isy994 docs]: /integrations/isy994 [灯光.lifx docs]: /integrations/lifx [灯光.limitlessled docs]: /integrations/limitlessled [灯光.mystrom docs]: /integrations/mystrom#灯光 [灯光.osramlightify docs]: /integrations/osramlightify [灯光.tradfri docs]: /integrations/tradfri [logbook docs]: /integrations/logbook/ [lutron_caseta docs]: /integrations/lutron_caseta/ [媒体播放器.denonavr docs]: /integrations/denonavr/ [媒体播放器.kodi docs]: /integrations/kodi [媒体播放器.onkyo docs]: /integrations/onkyo [媒体播放器.roku docs]: /integrations/roku#media-player [媒体播放器.sonos docs]: /integrations/sonos [媒体播放器.spotify docs]: /integrations/spotify [microsoft_face docs]: /integrations/microsoft_face/ [通知.html5 docs]: /integrations/html5 [通知.sendgrid docs]: /integrations/sendgrid [通知.smtp docs]: /integrations/smtp [通知.telegram docs]: /integrations/telegram [plant docs]: /integrations/plant/ [raspihats docs]: /integrations/raspihats/ [遥控器.kira docs]: /integrations/kira [rflink docs]: /integrations/rflink/ [rpi_pfio docs]: /integrations/rpi_pfio/ [传感器.blink docs]: /integrations/blink [传感器.dweet docs]: /integrations/dweet#传感器 [传感器.envirophat docs]: /integrations/envirophat [传感器.file docs]: /integrations/file#传感器 [传感器.influxdb docs]: /integrations/influxdb#传感器 [传感器.kira docs]: /integrations/kira [传感器.miflora docs]: /integrations/miflora [传感器.modem_callerid docs]: /integrations/modem_callerid [传感器.nzbget docs]: /integrations/nzbget [传感器.scrape docs]: /integrations/scrape [传感器.snmp docs]: /integrations/snmp#传感器 [传感器.wunderground docs]: /integrations/wunderground [sun docs]: /integrations/sun/ [开关.rpi_pfio docs]: /integrations/rpi_pfio#开关 [telegram_bot docs]: /integrations/telegram_bot/ [telegram_bot.polling docs]: /integrations/telegram_polling [telegram_bot.服务.yaml docs]: /integrations/telegram_bot/#通知-服务 [telegram_bot.webhooks docs]: /integrations/telegram_webhooks [tradfri docs]: /integrations/tradfri/ [vera docs]: /integrations/vera/ [websocket_api docs]: /integrations/websocket_api/ [zwave docs]: /integrations/zwave/ [zwave.api docs]: /integrations/zwave/ [forum]: https://community.home-assistant.io/ [issue]: https://github.com/home-assistant/home-assistant/issues [#7673]: https://github.com/home-assistant/home-assistant/pull/7673 [#7683]: https://github.com/home-assistant/home-assistant/pull/7683 [#7689]: https://github.com/home-assistant/home-assistant/pull/7689 [#7714]: https://github.com/home-assistant/home-assistant/pull/7714 [@cgtobi]: https://github.com/cgtobi [@tobygray]: https://github.com/tobygray [device_tracker.ubus docs]: /integrations/ubus [hassio docs]: /integrations/hassio/ [媒体播放器.volumio docs]: /integrations/volumio [telegram_bot docs]: /integrations/telegram_bot/ [discord]: https://discord.gg/c5DvZ4e --- url: /home-assistant/blog/2017-06-02-home-assistant-podcast-1.md --- # Home Assistant 播客第 1 期 由 [Home Assistant Podcast](https://hasspodcast.io) 制作的第一期节目包含播客介绍,并回顾了 Home Assistant [0.45](/home-assistant/blog/2017/05/20/automation-editor-zwave-面板-ocr/) 的发布。 * 在线收听: * 下载: --- url: /home-assistant/blog/2017-06-04-release-46.md --- # 0.46:Rachio 喷灌、Netgear Arlo 摄像头与 Z-Wave 风扇 0.46 来了!这个版本没有加入太多新的集成,而是将重点放在错误修复上。 ## New platforms * 模板 灯光 ([@cribbstechnologies] - [#7657]) ([灯光.模板 docs]) (new-platform) * Support for GE Zwave 风扇 controller ([@armills] - [#7767]) ([zwave docs]) ([风扇.zwave docs]) (new-platform) * Rachio (Sprinklers) ([@Klikini] - [#7600]) ([开关.rachio docs]) (new-platform) * Introduced support to Netgear Arlo 摄像头 ([@tchellomello] - [#7826]) ([arlo docs]) ([摄像头.arlo docs]) ([传感器.arlo docs]) (new-platform) ## 发布 0.46.1 - June 9 * Support for renaming ZWave values ([@armills] - [#7780]) ([zwave docs]) * Dsmr5 revert ([@aequitas] - [#7900]) ([传感器.dsmr docs]) * Fix typos in Wunderground component (Percipitation -> Precipitation) ([@mje-nz] - [#7901]) ([传感器.wunderground docs]) * MQTT 遮盖: Making command topic optional and add ability to set up/down position including ability to 模板 the value ([@cribbstechnologies] - [#7841]) ([遮盖.MQTT docs]) * Media Player - OpenHome: Fixed metadata issue ([@bazwilliams] - [#7932]) ([媒体播放器.openhome docs]) * 传感器 - MetOffice: Fix 最后更新 date ([@cyberjacob] - [#7965]) ([metoffice docs]) * Prevent Roku doing I/O in event loop ([@balloob] - [#7969]) ([媒体播放器.roku docs]) ## Backward-incompatible changes * The USPS 传感器 实体 names have changed as there are now two. One for packages and one for mail. Config will now also use `scan_interval` instead of `update_interval` ([@happyleavesaoc] - [#7655]) (breaking change) * 自动化 状态 触发器: From/to checks will now ignore 状态 changes that are just 属性 changess ([@amelchio] - [#7651]) ([自动化.状态 docs]) (breaking change) * Redesign monitored variables for hp\_ilo 传感器. `monitored_variables` is now a list of `name` and `sensor_type` values ([@Juggels] - [#7534]) ([传感器.hp\_ilo docs][传感器.hp_ilo docs]) (breaking change) ```yaml sensor: - platform: hp_ilo host: IP_ADDRESS or HOSTNAME username: USERNAME password: PASSWORD monitored_variables: - name: SENSOR NAME sensor_type: SENSOR TYPE ``` * 自动化 - time: The `after` keyword for time 触发器 (not 条件) has been deprecated in favor of the `at` keyword. This resembles better what it does (old one still works, gives a 警告) ([@armills] - [#7846]) ([自动化.time docs]) (breaking change) * 自动化 - numeric\_state: `above` and `below` will no longer 触发器 if it is equal. ([@armills] - [#7857]) (breaking change) * Broadlink 开关: 实体 ids will change for 开关 that don't have a default name set. In this case the object\_id is now used. ([@abmantis] - [#7845]) ([开关.broadlink docs]) (breaking change) * Disallow ambiguous color descriptors in the 灯光.turn\_on schema. This means that you can no longer specify both `xy_color` and `rgb_color`. ([@amelchio] - [#7765]) (breaking change) ## 如果你需要帮助…… ……欢迎随时使用我们非常活跃的[论坛][forum],或者加入我们的[聊天频道][discord]。虽然发布说明开放了评论,但我们仍更推荐你使用前面的沟通渠道。谢谢。 ## 反馈问题 如果你遇到了这个版本引入的问题,请在我们的 [issue tracker][issue] 中反馈。请确保填写问题模板中的所有字段。 ## All changes * Align with OpenALPR platform for naming conf variables ([@fabaff] - [#7650]) ([image\_processing.seven\_segments docs][image_processing.seven_segments docs]) * Added support to Amcrest 摄像头 to feed using RTSP via ffmpeg ([@tchellomello] - [#7646]) ([摄像头.amcrest docs]) ([传感器.amcrest docs]) * bump fedex 版本 ([@happyleavesaoc] - [#7653]) * bump ups 版本 ([@happyleavesaoc] - [#7654]) * 更新 usps ([@happyleavesaoc] - [#7655]) (breaking change) * Final tweaks for Zwave 面板 ([@turbokongen] - [#7652]) ([zwave docs]) * Add network\_key as a config option ([@robbiet480] - [#7637]) ([zwave docs]) * Bugfix #7586 ([@turbokongen] - [#7661]) ([门锁.zwave docs]) * Fix tests ([@balloob] - [#7659]) * Change line endings to LN ([@fabaff] - [#7660]) ([日历.demo docs]) ([日历.google docs]) ([摄像头.synology docs]) ([温控.tado docs]) ([遥控器.harmony docs]) ([传感器.synologydsm docs]) * Point pylutron to pypi ([@thecynic] - [#7664]) ([lutron docs]) * 升级 Openhome library ([@bazwilliams] - [#7671]) ([媒体播放器.openhome docs]) * Ignore 属性 changes in 自动化 触发器 from/to ([@amelchio] - [#7651]) ([自动化.状态 docs]) (breaking change) * 开关 pymodbus to pypi ([@andrey-git] - [#7677]) ([modbus docs]) * zoneminder: fix incorrect use of logging.exception. ([@tobygray] - [#7675]) ([zoneminder docs]) * Zwave: Apply refresh\_node workaround on 1st instance only ([@andrey-git] - [#7579]) ([zwave docs]) * Guard against new and removed 状态 change events ([@balloob] - [#7687]) ([自动化.状态 docs]) * ZWave: Add reset 服务 to meters ([@turbokongen] - [#7676]) ([zwave docs]) * Remove defunct INSTALL\_OPENZWAVE from Dockerfile ([@armills] - [#7697]) * Fix telegram chats ([@azogue] - [#7689]) ([通知.telegram docs]) * Fix playback control of web streams ([@cgtobi] - [#7683]) ([媒体播放器.volumio docs]) * Sort 实体 in default groups by name ([@amelchio] - [#7681]) * Continue tracking 设备 over dhcp lease table if wireless adapter not 已安装 ([@LvivEchoes] - [#7690]) ([device\_tracker.mikrotik docs][device_tracker.mikrotik docs]) * device\_tracker.ubus: Handle empty results ([@tobygray] - [#7673]) ([device\_tracker.ubus docs][device_tracker.ubus docs]) * Bump pyEight 版本 ([@mezz64] - [#7701]) ([eight\_sleep docs][eight_sleep docs]) * 升级 python-telegram-bot to 6.0.1 ([@fabaff] - [#7704]) * Make 'sender' as requirement for the config (fixes #7698) ([@fabaff] - [#7706]) ([通知.smtp docs]) * Allow fetching hass.io 面板 without auth ([@balloob] - [#7714]) ([hassio docs]) * 更新 apcacccess used in apcupsd to 0.0.10, which fixes random file drop from apcaccess ([@infamy] - [#7722]) ([apcupsd docs]) * Constrain requests to a 版本 ([@balloob] - [#7725]) * Asuswrt continuous ssh ([@aronsky] - [#7728]) * Ensure https base\_url in telegram bot ([@bzillins] - [#7726]) ([telegram\_bot.webhooks docs][telegram_bot.webhooks docs]) * Prevent the random 模板 filter from caching its output. Fixes #5678 ([@antsar] - [#7716]) * Don't initialize MQTT components which have already been discovered ([@nordeep] - [#7625]) ([MQTT.discovery docs]) * LIFX: disable color features for white-only bulbs ([@amelchio] - [#7742]) ([灯光.lifx docs]) * Don't block startup more than 60 seconds while waiting for components. ([@antsar] - [#7739]) * Always return rgb color of bulbs ([@w1ll1am23] - [#7743]) ([灯光.wink docs]) * Redesign monitored variables for hp\_ilo 传感器 ([@Juggels] - [#7534]) ([传感器.hp\_ilo docs][传感器.hp_ilo docs]) (breaking change) * Fix time\_date 传感器 to 更新 at predictable intervals ([@stu-gott] - [#7644]) ([传感器.time\_date docs][传感器.time_date docs]) * Added new commands and functionality to the harmony 遥控器 component. ([@everix1992] - [#7113]) ([遥控器 docs]) ([遥控器.harmony docs]) (遥控器.服务.yaml docs) * 模板 灯光 ([@cribbstechnologies] - [#7657]) ([灯光.模板 docs]) (new-platform) * Exclude filter for event types ([@amigian74] - [#7627]) * Change 设置 脚本 to use pip 安装 instead of 设置.py develop ([@hoh] - [#7756]) * Add icons to 设备 tracker. ([@antsar] - [#7759]) * Rename of the zwave hass.data constants ([@armills] - [#7768]) ([zwave docs]) ([遮盖.zwave docs]) ([门锁.zwave docs]) * Get rid of mock http component app ([@balloob] - [#7775]) * Remove usage of event\_loop fixture ([@balloob] - [#7776]) * assertEquals is deprecated ([@balloob] - [#7777]) * Support for GE Zwave 风扇 controller ([@armills] - [#7767]) ([zwave docs]) ([风扇.zwave docs]) (new-platform) * Replace executor with async\_add\_job ([@balloob] - [#7658]) * Fix Telegram Bot send file to multiple targets, snapshots of HA 摄像头, variable templating, digest auth ([@azogue] - [#7771]) * Fix more deprecation 警告 ([@balloob] - [#7778]) * Powerview to async ([@sander76] - [#7682]) ([场景.hunterdouglas\_powerview docs][场景.hunterdouglas_powerview docs]) * Fix home/stay in concord232 ([@CTLS] - [#7789]) ([alarm\_control\_panel.concord232 docs][alarm_control_panel.concord232 docs]) * Add Marantz SSDP discovery / Detect 错误 string in AppCommand.xml body ([@scarface-4711] - [#7779]) ([媒体播放器.denonavr docs]) * 升级 Sphinx to 1.6.2 ([@fabaff] - [#7805]) * 升级 slacker to 0.9.50 ([@fabaff] - [#7797]) ([通知.slack docs]) * Bump pyenvisalink to 版本 2.1 ([@Cinntax] - [#7803]) ([envisalink docs]) * 升级 pysnmp to 4.3.6 ([@fabaff] - [#7806]) ([device\_tracker.snmp docs][device_tracker.snmp docs]) ([传感器.snmp docs]) * Rachio (Sprinklers) ([@Klikini] - [#7600]) ([开关.rachio docs]) (new-platform) * Rest 通知 data ([@Teagan42] - [#7757]) ([通知.rest docs]) * Added handling of an AssertionError from pxssh failed login ([@aronsky] - [#7750]) ([device\_tracker.asuswrt docs][device_tracker.asuswrt docs]) * 升级 sqlalchemy to 1.1.10 ([@fabaff] - [#7807]) * 升级 mypy to 0.511 ([@fabaff] - [#7809]) * Allow configuring DSMR5 protocol. ([@aequitas] - [#7535]) ([传感器.dsmr docs]) * Telegram send 图像: fix mimetype detection ([@azogue] - [#7802]) * Bump aiohttp to 2.1.0 ([@mezz64] - [#7825]) * Cleanup telegram / Add url to Webhook ([@pvizeli] - [#7824]) ([telegram\_bot.polling docs][telegram_bot.polling docs]) ([telegram\_bot.webhooks docs][telegram_bot.webhooks docs]) (breaking change) * 升级 pysnmp to 4.3.7 ([@fabaff] - [#7828]) ([device\_tracker.snmp docs][device_tracker.snmp docs]) ([传感器.snmp docs]) * Flux led fix ([@danielhiversen] - [#7829]) ([灯光.flux\_led docs][灯光.flux_led docs]) * 更新 snapcast media player ([@happyleavesaoc] - [#7079]) ([媒体播放器.服务.yaml docs]) ([媒体播放器.snapcast docs]) * 更新 docstrings and 日志 messages ([@fabaff] - [#7709]) * 升级 PyMVGLive to 1.1.4 ([@fabaff] - [#7832]) ([传感器.mvglive docs]) * Added persistent 错误 message if 遮盖.myq fails to load ([@tchellomello] - [#7700]) ([遮盖.myq docs]) * Add initial benchmark framework ([@balloob] - [#7827]) * Downgrade Docker to Python 3.5 to solve Segmentation Faults ([@philhawthorne] - [#7799]) * Introduced support to Netgear Arlo 摄像头 ([@tchellomello] - [#7826]) ([arlo docs]) ([摄像头.arlo docs]) ([传感器.arlo docs]) (new-platform) * Allow 'base\_url' (fixes #7784) ([@fabaff] - [#7796]) ([upnp docs]) * Expose the node name on the zwave node 实体 ([@armills] - [#7787]) ([zwave docs]) * Bumped pyhomematic 版本 ([@danielperna84] - [#7861]) ([homematic docs]) * Rename time 触发器 'after' to 'at' ([@armills] - [#7846]) ([自动化.time docs]) (breaking change) * Use expected behvaior for above/below ([@armills] - [#7857]) (breaking change) * 日志 time delay of domain 设置 in info level ([@azogue] - [#7808]) * Optimize history\_stats efficiency and database usage ([@bokub] - [#7858]) ([传感器.history\_stats docs][传感器.history_stats docs]) * don't use default for 开关 name, so that the object id is used ([@abmantis] - [#7845]) ([开关.broadlink docs]) (breaking change) * Disallow ambiguous color descriptors in the 灯光.turn\_on schema ([@amelchio] - [#7765]) (breaking change) * Make monkey patch work in Python 3.6 ([@balloob] - [#7848]) * fix permissions issue for Insteon Local #6558 ([@craigjmidwinter] - [#7860]) ([insteon\_local docs][insteon_local docs]) * Start of migration framework, to allow moving of files in the config … ([@infamy] - [#7740]) ([ios docs]) ([通知.ios docs]) (breaking change) * Spotify aliases ([@Teagan42] - [#7702]) ([媒体播放器.spotify docs]) * Query in InfluxDB 传感器 is now templatable ([@titilambert] - [#7634]) ([传感器.influxdb docs]) * fix for https://github.com/home-assistant/home-assistant/issues/7019 ([@molobrakos] - [#7618]) ([tellduslive docs]) * Check if media commands are actually applicable ([@Juggels] - [#7595]) ([媒体播放器.sonos docs]) * Quickfix Bug #7384 ([@DavidLP] - [#7582]) ([媒体播放器.spotify docs]) * Align 开关 group handling with 灯光. ([@aequitas] - [#7577]) ([开关.rflink docs]) * 更新 netdisco ([@balloob] - [#7865]) * Fix telegram\_bot ([@balloob] - [#7877]) ([telegram\_bot.polling docs][telegram_bot.polling docs]) ([telegram\_bot.webhooks docs][telegram_bot.webhooks docs]) * \[灯光.lifx] 更新 aiolifx ([@amelchio] - [#7882]) ([灯光.lifx docs]) * Fix MQTT 摄像头 test ([@balloob] - [#7878]) [#7079]: https://github.com/home-assistant/home-assistant/pull/7079 [#7113]: https://github.com/home-assistant/home-assistant/pull/7113 [#7534]: https://github.com/home-assistant/home-assistant/pull/7534 [#7535]: https://github.com/home-assistant/home-assistant/pull/7535 [#7577]: https://github.com/home-assistant/home-assistant/pull/7577 [#7579]: https://github.com/home-assistant/home-assistant/pull/7579 [#7582]: https://github.com/home-assistant/home-assistant/pull/7582 [#7595]: https://github.com/home-assistant/home-assistant/pull/7595 [#7600]: https://github.com/home-assistant/home-assistant/pull/7600 [#7618]: https://github.com/home-assistant/home-assistant/pull/7618 [#7625]: https://github.com/home-assistant/home-assistant/pull/7625 [#7627]: https://github.com/home-assistant/home-assistant/pull/7627 [#7634]: https://github.com/home-assistant/home-assistant/pull/7634 [#7637]: https://github.com/home-assistant/home-assistant/pull/7637 [#7644]: https://github.com/home-assistant/home-assistant/pull/7644 [#7646]: https://github.com/home-assistant/home-assistant/pull/7646 [#7650]: https://github.com/home-assistant/home-assistant/pull/7650 [#7651]: https://github.com/home-assistant/home-assistant/pull/7651 [#7652]: https://github.com/home-assistant/home-assistant/pull/7652 [#7653]: https://github.com/home-assistant/home-assistant/pull/7653 [#7654]: https://github.com/home-assistant/home-assistant/pull/7654 [#7655]: https://github.com/home-assistant/home-assistant/pull/7655 [#7657]: https://github.com/home-assistant/home-assistant/pull/7657 [#7658]: https://github.com/home-assistant/home-assistant/pull/7658 [#7659]: https://github.com/home-assistant/home-assistant/pull/7659 [#7660]: https://github.com/home-assistant/home-assistant/pull/7660 [#7661]: https://github.com/home-assistant/home-assistant/pull/7661 [#7664]: https://github.com/home-assistant/home-assistant/pull/7664 [#7671]: https://github.com/home-assistant/home-assistant/pull/7671 [#7673]: https://github.com/home-assistant/home-assistant/pull/7673 [#7675]: https://github.com/home-assistant/home-assistant/pull/7675 [#7676]: https://github.com/home-assistant/home-assistant/pull/7676 [#7677]: https://github.com/home-assistant/home-assistant/pull/7677 [#7681]: https://github.com/home-assistant/home-assistant/pull/7681 [#7682]: https://github.com/home-assistant/home-assistant/pull/7682 [#7683]: https://github.com/home-assistant/home-assistant/pull/7683 [#7687]: https://github.com/home-assistant/home-assistant/pull/7687 [#7689]: https://github.com/home-assistant/home-assistant/pull/7689 [#7690]: https://github.com/home-assistant/home-assistant/pull/7690 [#7697]: https://github.com/home-assistant/home-assistant/pull/7697 [#7700]: https://github.com/home-assistant/home-assistant/pull/7700 [#7701]: https://github.com/home-assistant/home-assistant/pull/7701 [#7702]: https://github.com/home-assistant/home-assistant/pull/7702 [#7704]: https://github.com/home-assistant/home-assistant/pull/7704 [#7706]: https://github.com/home-assistant/home-assistant/pull/7706 [#7709]: https://github.com/home-assistant/home-assistant/pull/7709 [#7714]: https://github.com/home-assistant/home-assistant/pull/7714 [#7716]: https://github.com/home-assistant/home-assistant/pull/7716 [#7722]: https://github.com/home-assistant/home-assistant/pull/7722 [#7725]: https://github.com/home-assistant/home-assistant/pull/7725 [#7726]: https://github.com/home-assistant/home-assistant/pull/7726 [#7728]: https://github.com/home-assistant/home-assistant/pull/7728 [#7739]: https://github.com/home-assistant/home-assistant/pull/7739 [#7740]: https://github.com/home-assistant/home-assistant/pull/7740 [#7742]: https://github.com/home-assistant/home-assistant/pull/7742 [#7743]: https://github.com/home-assistant/home-assistant/pull/7743 [#7750]: https://github.com/home-assistant/home-assistant/pull/7750 [#7756]: https://github.com/home-assistant/home-assistant/pull/7756 [#7757]: https://github.com/home-assistant/home-assistant/pull/7757 [#7759]: https://github.com/home-assistant/home-assistant/pull/7759 [#7765]: https://github.com/home-assistant/home-assistant/pull/7765 [#7767]: https://github.com/home-assistant/home-assistant/pull/7767 [#7768]: https://github.com/home-assistant/home-assistant/pull/7768 [#7771]: https://github.com/home-assistant/home-assistant/pull/7771 [#7775]: https://github.com/home-assistant/home-assistant/pull/7775 [#7776]: https://github.com/home-assistant/home-assistant/pull/7776 [#7777]: https://github.com/home-assistant/home-assistant/pull/7777 [#7778]: https://github.com/home-assistant/home-assistant/pull/7778 [#7779]: https://github.com/home-assistant/home-assistant/pull/7779 [#7787]: https://github.com/home-assistant/home-assistant/pull/7787 [#7789]: https://github.com/home-assistant/home-assistant/pull/7789 [#7796]: https://github.com/home-assistant/home-assistant/pull/7796 [#7797]: https://github.com/home-assistant/home-assistant/pull/7797 [#7799]: https://github.com/home-assistant/home-assistant/pull/7799 [#7802]: https://github.com/home-assistant/home-assistant/pull/7802 [#7803]: https://github.com/home-assistant/home-assistant/pull/7803 [#7805]: https://github.com/home-assistant/home-assistant/pull/7805 [#7806]: https://github.com/home-assistant/home-assistant/pull/7806 [#7807]: https://github.com/home-assistant/home-assistant/pull/7807 [#7808]: https://github.com/home-assistant/home-assistant/pull/7808 [#7809]: https://github.com/home-assistant/home-assistant/pull/7809 [#7824]: https://github.com/home-assistant/home-assistant/pull/7824 [#7825]: https://github.com/home-assistant/home-assistant/pull/7825 [#7826]: https://github.com/home-assistant/home-assistant/pull/7826 [#7827]: https://github.com/home-assistant/home-assistant/pull/7827 [#7828]: https://github.com/home-assistant/home-assistant/pull/7828 [#7829]: https://github.com/home-assistant/home-assistant/pull/7829 [#7832]: https://github.com/home-assistant/home-assistant/pull/7832 [#7845]: https://github.com/home-assistant/home-assistant/pull/7845 [#7846]: https://github.com/home-assistant/home-assistant/pull/7846 [#7848]: https://github.com/home-assistant/home-assistant/pull/7848 [#7857]: https://github.com/home-assistant/home-assistant/pull/7857 [#7858]: https://github.com/home-assistant/home-assistant/pull/7858 [#7860]: https://github.com/home-assistant/home-assistant/pull/7860 [#7861]: https://github.com/home-assistant/home-assistant/pull/7861 [#7865]: https://github.com/home-assistant/home-assistant/pull/7865 [#7877]: https://github.com/home-assistant/home-assistant/pull/7877 [#7878]: https://github.com/home-assistant/home-assistant/pull/7878 [#7882]: https://github.com/home-assistant/home-assistant/pull/7882 [@CTLS]: https://github.com/CTLS [@Cinntax]: https://github.com/Cinntax [@DavidLP]: https://github.com/DavidLP [@Juggels]: https://github.com/Juggels [@Klikini]: https://github.com/Klikini [@LvivEchoes]: https://github.com/LvivEchoes [@Teagan42]: https://github.com/Teagan42 [@abmantis]: https://github.com/abmantis [@aequitas]: https://github.com/aequitas [@amelchio]: https://github.com/amelchio [@amigian74]: https://github.com/amigian74 [@andrey-git]: https://github.com/andrey-git [@antsar]: https://github.com/antsar [@armills]: https://github.com/armills [@aronsky]: https://github.com/aronsky [@azogue]: https://github.com/azogue [@balloob]: https://github.com/balloob [@bazwilliams]: https://github.com/bazwilliams [@bokub]: https://github.com/bokub [@bzillins]: https://github.com/bzillins [@cgtobi]: https://github.com/cgtobi [@cribbstechnologies]: https://github.com/cribbstechnologies [@danielhiversen]: https://github.com/danielhiversen [@danielperna84]: https://github.com/danielperna84 [@everix1992]: https://github.com/everix1992 [@fabaff]: https://github.com/fabaff [@happyleavesaoc]: https://github.com/happyleavesaoc [@hoh]: https://github.com/hoh [@infamy]: https://github.com/infamy [@mezz64]: https://github.com/mezz64 [@molobrakos]: https://github.com/molobrakos [@nordeep]: https://github.com/nordeep [@philhawthorne]: https://github.com/philhawthorne [@pvizeli]: https://github.com/pvizeli [@robbiet480]: https://github.com/robbiet480 [@sander76]: https://github.com/sander76 [@scarface-4711]: https://github.com/scarface-4711 [@stu-gott]: https://github.com/stu-gott [@tchellomello]: https://github.com/tchellomello [@thecynic]: https://github.com/thecynic [@titilambert]: https://github.com/titilambert [@tobygray]: https://github.com/tobygray [@turbokongen]: https://github.com/turbokongen [@w1ll1am23]: https://github.com/w1ll1am23 [@craigjmidwinter]: https://github.com/craigjmidwinter [alarm_control_panel.concord232 docs]: /integrations/concord232#报警-control-面板 [apcupsd docs]: /integrations/apcupsd/ [arlo docs]: /integrations/arlo/ [自动化.状态 docs]: /docs/自动化/触发器/#状态-触发器 [自动化.time docs]: /docs/自动化/触发器/#time-触发器 [日历.demo docs]: /integrations/日历/ [日历.google docs]: /integrations/日历.google/ [摄像头.amcrest docs]: /integrations/amcrest [摄像头.arlo docs]: /integrations/arlo#摄像头 [摄像头.synology docs]: /integrations/synology [温控.tado docs]: /integrations/tado [遮盖.myq docs]: /integrations/myq [遮盖.zwave docs]: /integrations/zwave#遮盖 [device_tracker.__init__ docs]: /integrations/device_tracker.__init__/ [device_tracker.asuswrt docs]: /integrations/asuswrt [device_tracker.mikrotik docs]: /integrations/mikrotik [device_tracker.snmp docs]: /integrations/snmp [device_tracker.ubus docs]: /integrations/ubus [eight_sleep docs]: /integrations/eight_sleep/ [envisalink docs]: /integrations/envisalink/ [风扇.zwave docs]: /integrations/zwave [hassio docs]: /integrations/hassio/ [homematic docs]: /integrations/homematic/ [image_processing.seven_segments docs]: /integrations/seven_segments [insteon_local docs]: /integrations/insteon/ [ios docs]: /integrations/ios/ [灯光.__init__ docs]: /integrations/灯光.__init__/ [灯光.flux_led docs]: /integrations/flux_led [灯光.lifx docs]: /integrations/lifx [灯光.模板 docs]: /integrations/灯光.模板/ [灯光.wink docs]: /integrations/wink#灯光 [门锁.zwave docs]: /integrations/zwave#门锁 [lutron docs]: /integrations/lutron/ [媒体播放器.denonavr docs]: /integrations/denonavr/ [媒体播放器.openhome docs]: /integrations/openhome [媒体播放器.服务.yaml docs]: /integrations/媒体播放器/#服务 [媒体播放器.snapcast docs]: /integrations/snapcast [媒体播放器.sonos docs]: /integrations/sonos [媒体播放器.spotify docs]: /integrations/spotify [媒体播放器.volumio docs]: /integrations/volumio [metoffice docs]: /integrations/metoffice/ [modbus docs]: /integrations/modbus/ [MQTT.discovery docs]: /docs/MQTT/discovery/ [通知.ios docs]: /docs/ecosystem/ios/通知/basic/ [通知.rest docs]: /integrations/通知.rest/ [通知.slack docs]: /integrations/slack [通知.smtp docs]: /integrations/smtp [通知.telegram docs]: /integrations/telegram [recorder.__init__ docs]: /integrations/recorder.__init__/ [遥控器 docs]: /integrations/遥控器/ [遥控器.harmony docs]: /integrations/harmony [场景.hunterdouglas_powerview docs]: /integrations/hunterdouglas_powerview [传感器.amcrest docs]: /integrations/amcrest [传感器.arlo docs]: /integrations/arlo#传感器 [传感器.dsmr docs]: /integrations/dsmr [传感器.history_stats docs]: /integrations/history_stats [传感器.hp_ilo docs]: /integrations/hp_ilo [传感器.influxdb docs]: /integrations/influxdb#传感器 [传感器.mvglive docs]: /integrations/mvglive [传感器.snmp docs]: /integrations/snmp#传感器 [传感器.synologydsm docs]: /integrations/synologydsm [传感器.time_date docs]: /integrations/time_date [开关.broadlink docs]: /integrations/broadlink#开关 [开关.rachio docs]: /integrations/rachio#开关 [开关.rflink docs]: /integrations/开关.rflink/ [telegram_bot.__init__ docs]: /integrations/telegram_bot/ [telegram_bot.polling docs]: /integrations/telegram_polling [telegram_bot.webhooks docs]: /integrations/telegram_webhooks [tellduslive docs]: /integrations/tellduslive/ [upnp docs]: /integrations/upnp/ [zoneminder docs]: /integrations/zoneminder/ [zwave docs]: /integrations/zwave/ [forum]: https://community.home-assistant.io/ [issue]: https://github.com/home-assistant/home-assistant/issues [#7780]: https://github.com/home-assistant/home-assistant/pull/7780 [#7841]: https://github.com/home-assistant/home-assistant/pull/7841 [#7900]: https://github.com/home-assistant/home-assistant/pull/7900 [#7901]: https://github.com/home-assistant/home-assistant/pull/7901 [#7932]: https://github.com/home-assistant/home-assistant/pull/7932 [#7965]: https://github.com/home-assistant/home-assistant/pull/7965 [#7969]: https://github.com/home-assistant/home-assistant/pull/7969 [@cyberjacob]: https://github.com/cyberjacob [@mje-nz]: https://github.com/mje-nz [遮盖.MQTT docs]: /integrations/遮盖.MQTT/ [传感器.wunderground docs]: /integrations/wunderground [媒体播放器.roku docs]: /integrations/roku#media-player [discord]: https://discord.gg/c5DvZ4e --- url: /home-assistant/blog/2017-06-10-interview-with-jupiter-broadcasting.md --- # Linux 动作 Show special about Home Assistant Our founder Paulus Schoutsen is interviewed by Chris Fisher for a Linux 动作 Show special about home 自动化, [Hass.io] and the new [Home Assistant podcast].
[Hass.io]: https://community.home-assistant.io/t/introducing-hass-io/17296/48 [Home Assistant podcast]: https://hasspodcast.io/ --- url: /home-assistant/blog/2017-06-15-zwave-entity-ids.md --- # ZWave 实体 IDs ZWave entity\_ids have long been a source of frustration in Home Assistant. The first problem we faced was that depending on the order of node discovery, entity\_ids could be discovered with different names on each run. To solve this we added the node id as a suffix to the entity\_id. This ensured that entity\_ids were generated deterministically on each run, but additional suffixes had to be added to handle edge cases where there would otherwise be a conflict. The resulting entity\_ids worked, but have been difficult to work with and makes ZWave a strange exception among other Home Assistant components. Thanks to the awesome work of [@turbokongen], a growing number of ZWave 配置 options are now available from the new ZWave 面板 in the Home Assistant 前端. Among these new features is support for renaming of ZWave nodes and their underlying values. (These renames are persisted in zwcfg\_\*.xml) This is important, because these items are combined to form the Home Assistant 实体 name, which is used to generate the entity\_id. Now that these options are available, ZWave 用户 can rename nodes and values, influencing the entity\_ids that are generated by Home Assistant. Now that 用户 are able to control these names, we will be making changes to how the entity\_ids are generated for ZWave 实体. The ZWave entity\_ids are going to 开关 back to using the standard entity\_id generation from Home Assistant 核心, based on the 实体 names. Moving forward, if there is a conflict when generating entity\_ids, a suffix will be added, and it will be the responsibility of the 用户 to rename their nodes and values to avoid the conflict. This is the same as any other platform in Home Assistant where two 设备 are discovered with the same name. With the 发布 of 0.47, this feature will be opt-in. Setting `new_entity_ids: true` under `zwave:` in your 配置.yaml will enable the new generation. After 0.48 this feature will become opt-out. From 0.48 onward, unless you’ve declared `new_entity_ids: false` you will 开关 to the new entity\_id generation. At an undecided point in the future, the old entity\_id generation will be removed completely. I’m sure all ZWave 用户 understand that the current entity\_ids aren’t easy to use. They’re annoying to type in 配置.yaml, and break if a node needs to be re-included to the network. We know that backward-incompatible changes are painful, and so we’re doing what we can to roll this change out as smoothly as possible. The end result should be a dramatic simplification of most ZWave 配置. We hope that this change will ultimately make ZWave much easier to work with, and bring ZWave 配置 just a little closer to the rest of the Home Assistant platforms. [@turbokongen]: https://github.com/turbokongen --- url: /home-assistant/blog/2017-06-17-release-47.md --- --- url: /home-assistant/blog/2017-06-20-things-you-should-know-about-senic-covi.md --- # \[Update: fixed] A frank and serious warning about X **更新 June 21:** Senic has removed our name from their materials and have [issued an apology][apology]. We wish them best of luck with the launch of COVI. **更新 June 28:** Removed the brand name from the title to reduce the search ranking. *Original post:* :::note TL;DR: We are not affiliated with Senic or their COVI product. We will not support their 用户 and you will get a subpar Home Assistant experience by using their product. **Furthermore, we cannot guarantee stability or security if you use Senic products.** ::: Recently Home Assistant has been made aware of a product by [Senic] that will be launching later today on [Kickstarter][kickstarter] ([screenshot][ks-备份]). Senic is not new in the IoT business, we have had support for their first product (Nuimo) since last September. Their new product, COVI, uses Home Assistant as its 核心 home 自动化 codebase. This is great, that is what 开源 is all about. However, they also use our name and logo in their Kickstarter, with the press and in their [developer 文档] ([screenshot][docs-备份]) to give the appearance of being affiliated with Home Assistant, against our wishes. Which is not great, at all. Take some of the following quotes from their Kickstarter campaign: > COVI is built on an 开源 platform. The Senic team, along with outside 开发者, contributes to this platform to create the 集成 for COVI. > With COVI, we have built upon an open platform called Home Assistant that anyone can contribute to alongside our engineers and the Home Assistant community. Although those quotes are technically correct, they are very misleading. The Senic team contributes only to their own platform, they have not contributed to Home Assistant, its 集成 or related projects. We did receive [1 contribution][netdisco-contrib] from them for [Netdisco], our network discovery package. It included a memory leak and required us to publish [a hotfix 发布][hotfix] for the 0.39 series. Their contribution has since been reverted. A third party contributor had contributed support for their Nuimo controller. Here is a quote that their CEO Tobias Eichenwald gave [to Forbes]: > Unlike many larger companies who build closed 自动化 platforms, COVI is built on an 开源 platform called Home Assistant that includes 500+ contributors. This allows COVI to be integrated into any ecosystem or platform with an open API. They reached out to us on April 7 ([screenshot][email-备份]). We replied on April 11 and told them they should not use our name as we do not want to be affiliated with them because we do not want to support their 用户. After that one e-mail we had never heard from them again until Forbes accidentally published an article about it before the Kickstarter launched. We did not get any chance to give feedback on their Kickstarter campaign content and they went ahead and used our name and logo without authorization or permission. If you want an 开源 and constantly evolving product, get yourself a $35 树莓派, 安装 our hub [Hass.io] for free and buy yourself some cheap and reliable [IKEA Trådfri 灯光][tradfri] to get yourself a basic home 自动化 设置. If you want a $250 talking lamp, go buy the COVI. Just know that we are not affiliated with Senic, we will not support their 用户 and you will get a subpar Home Assistant experience by using their product. **Furthermore, we cannot guarantee stability or security if you use Senic products.** Senic, we know that this is probably not what you wanted to wake up to on the first day of your Kickstarter but you left us no choice. Please reach out to us to help make this right. **We will always do everything in our power to protect the best interests of the Home Assistant community, our 500+ contributors and 250,000+ 用户.** If we don't hear from you by Wednesday, June 21st, we will be forced to consider further 动作. Sincerely, **Paulus Schoutsen**
Founder, Home Assistant **Robbie Trencheny**
核心 Developer, Home Assistant [Senic]: https://www.senic.com/ [kickstarter]: https://www.kickstarter.com/projects/802159142/1793705123?token=03dc08b4# [ks-备份]: /images/blog/2017-06-senic-covi/covi-kickstarter-screenshot.png [email-备份]: /images/blog/2017-06-senic-covi/email-senic.png [docs-备份]: /images/blog/2017-06-senic-covi/senic-docs-screenshot.png [Netdisco]: https://github.com/home-assistant/netdisco [netdisco-contrib]: https://github.com/home-assistant/netdisco/pull/94 [hotfix]: /博客/2017/02/25/config-面板-and-状态-restoration/#发布-0392---march-1 [Hass.io]: /hassio/ [to Forbes]: https://www.forbes.com/sites/paularmstrongtech/2017/06/20/covi-is-about-to-make-some-general-electric-execs-very-unhappy/ [tradfri]: /博客/2017/04/17/ikea-tradfri-internet-of-things-done-right/ [developer 文档]: http://博客.senic.com/posts/the-senic-hub-a-brief-software-概述 [apology]: https://medium.com/@senic/an-open-letter-to-home-assistant-5ccb53ccf722 --- url: /home-assistant/blog/2017-07-02-release-48.md --- --- url: /home-assistant/blog/2017-07-03-home-assistant-is-moving-to-discord.md --- # Home Assistant 正在迁移到 Discord 社区会成长,事物也会改变。我们理解有些人不喜欢变化,这也是为什么我们会尽力让聊天平台从 Gitter 迁移到 [Discord][discord] 的过程,对每个人来说都尽可能顺畅。现在就通过[一次点击][discord]加入我们吧! 点击 `继续阅读 →` 了解我们为什么要迁移。 ### 易于加入 Discord 是一个非常容易加入的平台。新用户甚至无需先创建账号,就可以立刻参与对话。只要填写你的名字,就可以加入! 这对我们来说非常有价值,也会让 Home Assistant 比以往更易于使用。 ### 出色的应用 我们最不喜欢 Gitter 的一点,就是它为 iOS 和 Android 设备提供的应用质量。相比之下,Discord 拥有我们试过的移动应用里速度最快、功能最丰富的体验!如果你喜欢直接从手机把图片发到聊天室里……现在就可以了。而且这还不止于此;他们还为 Windows、macOS,甚至 Linux 提供了打磨精良的客户端。如果你更喜欢基于浏览器的聊天客户端,他们的网页客户端也会非常适合你。 ### 管理工具 到目前为止,我们很幸运,聊天室里还没有太多不当行为,比如垃圾信息、捣乱者之类。不过,随着社区继续壮大,这类常见问题未来可能会出现。Discord 提供了能帮助我们在问题失控前及时处理这些行为的功能。 ### 强大的多服务器支持 你已经有 Discord 账号了吗?太好了!你现在就可以用这个账号[加入讨论][discord]。一个 Discord 账号适用于所有 Discord 服务器。在不同服务器之间切换或加入新服务器都非常容易。Discord 的私信也可以跨服务器使用,所以你的个人对话不会被限制在某一个服务器中。 ### 托管服务 我们一直都很喜欢自托管应用和服务,但大家都知道,要让它们平稳运行,需要投入相当多的维护和精力。Discord 运行在他们自己的服务器上,因此由他们来维护这项服务更合适,而我们则可以专注于持续改进 Home Assistant,为你带来更多令人兴奋的新功能! ### 丰富的功能 语法高亮、语音聊天、搜索聊天室、私信,甚至自定义表情!Discord 提供了一套非常棒的功能,足以让我们在未来很长一段时间里都用得开心。(悄悄告诉你……加入我们的服务器后,记得看看 `:ponder:` 表情!) ## 加入我们! 你已经被说服,准备好完成这次迁移了吗?加入我们吧,我们只差[一次点击][discord]! 如果你还没有被说服,请花一点时间在下方评论中告诉我们你对这次变更的看法,这样我们就能帮助你,也帮助其他人,让这次迁移更轻松。 ## 细则说明…… 在切换聊天平台的过程中,我们决定为聊天社区制定一套我们认为非常公平的规则。随着社区持续成长,这些规则将来可能会调整。同时,也请查看 [#welcome-rules][discord] 频道,那里会提供我们聊天服务器最新的规则说明。 ### 规则如下…… #### 规则: 在参与讨论之前,请务必认真阅读这些规则。 1. **欢迎新成员!** 请先阅读[常见问题]。也欢迎你做个自我介绍,我们在这里都是朋友! 2. 如果你有问题,请先查看[常见问题]和[相关文档][docs],再发帖提问。 3. 不要侮辱、贬低或辱骂其他社区成员。任何关于辱骂行为的举报都不会被轻视,并且**会导致封禁。** 4. 我们的版主自愿抽出时间来帮助维持这个社区的良好氛围。任何针对他们、或关于他们的不当或缺乏建设性的评论,**都将导致封禁。** 5. [#devs][discord-devs] 仅用于**开发相关讨论**。[#general][discord-general] 用于日常讨论、支持问题,以及帮助他人。请根据讨论内容使用合适的频道。 6. 不容忍垃圾信息,包括但不限于:自我推广、刷屏、代码墙(超过 15 行)以及未经批准的机器人。 这些规则并不是让你按自己喜欢的方式去解读的,也不存在所谓的“漏洞”。如果有人声称自己没有违反规则,只因为“规则里没写”,也会受到相应后果。如果你不确定某件事是否合适,请直接询问我(@dale3h)或社区成员。 如果你对服务器上的任何事情或任何人有问题,请私信我(@dale3h),并附上相关细节。**如果我不知道发生了什么,我就无法帮助任何人。** #### 违规与封禁: 对于严重违规行为,或多次轻微违规后仍不理会警告的情况,\*\*将会直接封禁。\*\*这一点不作协商。 此致, **Dale Higgs**
社区负责人,Home Assistant [discord]: https://discord.gg/c5DvZ4e [discord-devs]: https://discord.gg/8X8DTH4 [discord-general]: https://discord.gg/pywKZRT [常见问题]: /faq/ [docs]: /docs/ --- url: /home-assistant/blog/2017-07-05-hasspodcast-ep-3.md --- # Home Assistant Podcast #3 The third episode of the Home Assistant Podcast is out. Paulus joins to talk about some stats and the 发布 of 0.47 and Petar tells all about his Floorplan project for Home Assistant. [Listen online][episode] [episode]: https://hasspodcast.io/ha003/ --- url: /home-assistant/blog/2017-07-16-release-49.md --- # 我们有主题啦 🎨👩‍🎨 多亏了 [@andrey-git],我们原本就很出色的前端现在变得更强大了。借助新的主题支持,你可以控制主色、强调色以及更多样式细节。 你可以通过前端下新增的配置选项来定义主题。 ```yaml frontend: themes: green: primary-color: "#6CA518" ``` 定义好主题后,使用新的前端服务 `frontend.set_theme` 即可启用它。更多信息请参阅[文档][前端 docs]。

Screenshot of a green 仪表盘 绿色仪表盘截图

目前还不是所有界面部分都支持主题化,后续版本会继续完善。 ## Kiosk 模式 前端的另一项重大改进是加入了 kiosk 模式。当以前端 kiosk 模式查看时,标签栏会被隐藏。 要启用 kiosk 模式,请访问 `https://hass.example.com:8123/kiosk/group.living_room_view`。需要注意的是,如果是 `default_view`,地址只需使用 `https://hass.example.com:8123/kiosk`。 这项功能同样由 [@Andrey-git] 带来!非常感谢他持续不断地推动 Home Assistant 更进一步。 ## 新平台 * Add london\_underground ([@robmarkcole] - [#8272]) ([传感器.london\_underground docs][传感器.london_underground docs]) (new-platform) * Add citybikes platform ([@aronsky] - [#8202]) ([传感器.citybikes docs]) (new-platform) * Add One-Time 密码 传感器 (OTP) ([@postlund] - [#8332]) ([传感器.otp docs]) (new-platform) * Add component for xiaomi robot 吸尘器 (开关.xiaomi\_vacuum) ([@rytilahti] - [#7913]) ([开关.xiaomi\_vacuum docs][开关.xiaomi_vacuum docs]) (new-platform) * LaMetric platform and 通知 module ([@open-homeautomation] - [#8230]) ([lametric docs]) ([通知.lametric docs]) (new-platform) * New component to connect to VELUX KLF 200 Interface ([@Julius2342] - [#8203]) ([velux docs]) ([场景.velux docs]) (new-platform) * New 服务 `send_magic_packet` with new component `wake_on_lan` ([@azogue] - [#8397]) ([wake\_on\_lan docs][wake_on_lan docs]) (new-platform) * Add support for Prometheus ([@rcloran] - [#8211]) ([prometheus docs]) (new-platform) * Refactored Amcrest to use central hub component ([@tchellomello] - [#8184]) ([amcrest docs]) ([摄像头.amcrest docs]) ([传感器.amcrest docs]) (breaking change) (new-platform) * Added media\_extractor 服务 ([@minchik] - [#8369]) ([media\_extractor docs][media_extractor docs]) (new-platform) * Vizio SmartCast support ([@vkorn] - [#8260]) ([媒体播放器.vizio docs]) (new-platform) ## 发布 0.49.1 - July 24 * Fix TP-Link 设备 tracker regression since 0.49 ([@maikelwever] - [#8497]) ([device\_tracker.tplink docs][device_tracker.tplink docs]) * prometheus: Convert fahrenheit to celsius ([@rcloran] - [#8511]) ([prometheus docs]) * 更新 dlib\_face\_detect.py ([@pvizeli] - [#8516]) ([image\_processing.dlib\_face\_detect docs][image_processing.dlib_face_detect docs]) * Realfix for dlib ([@pvizeli] - [#8517]) ([image\_processing.dlib\_face\_detect docs][image_processing.dlib_face_detect docs]) * Attach the `chat_id` for a callback query from a chat group (fixes #8461) ([@azogue] - [#8523]) ([telegram\_bot docs][telegram_bot docs]) * Fix support for multiple Apple TVs ([@postlund] - [#8539]) * LIFX: assume default features for unknown products ([@amelchio] - [#8553]) ([灯光.lifx docs]) * Fix broken status 更新 for lighting4 设备 ([@ypollart] - [#8543]) ([rfxtrx docs]) ([binary\_sensor.rfxtrx docs][binary_sensor.rfxtrx docs]) * zha: 更新 to bellows 0.3.4 ([@rcloran] - [#8594]) ([zha docs]) * Fix STATION\_SCHEMA validation on longitude ([@clkao] - [#8610]) ([传感器.citybikes docs]) * Bumped Amcrest 版本 ([@tchellomello] - [#8624]) ([amcrest docs]) * Check if /dev/input/by-id exists ([@schaal] - [#8601]) ([keyboard\_remote docs][keyboard_remote docs]) * Tado Fix #8606 ([@filcole] - [#8621]) ([温控.tado docs]) * prometheus: Fix zwave battery level ([@rcloran] - [#8615]) ([prometheus docs]) * ubus: Make multiple instances work again ([@glance-] - [#8571]) ([device\_tracker.ubus docs][device_tracker.ubus docs]) * Properly slugify 开关.flux 更新 服务 name ([@jawilson] - [#8545]) ([开关.flux docs]) ## 如果你需要帮助…… 欢迎使用我们非常活跃的 [论坛][forum],或加入 [聊天频道][discord] 与我们交流。虽然发布说明也开放评论,但我们更推荐使用前面的沟通渠道。谢谢。 ## 反馈问题 如果你遇到了这个版本引入的问题,请前往我们的 [issue tracker][issue] 提交反馈,并确保填写 issue 模板中的所有字段。 ## 不向后兼容的变更 * UPC Connect component no longer needs a 密码 passed into the 配置. ([@Flavien] - [#8335]) ([device\_tracker.upc\_connect docs][device_tracker.upc_connect docs]) (breaking change) * The Apple TV platform has been upgraded to a component and a 遥控器 platform has been added. This requires your Apple TV 配置 to be moved to the new `apple_tv` component. ([@postlund] - [#8122]) ([媒体播放器.apple\_tv docs][媒体播放器.apple_tv docs]) (breaking change) ```yaml apple_tv: - name: Apple TV host: 10.0.10.20 login_id: 00000000-1234-5678-9012-345678901234 start_off: true credentials: 8660DEA5154FB46B:20B94847926112B3F46F85DB3A7311830463BF65570C22C3786E27F38C3326CF ``` * Refactored Amcrest to use central hub component to prepare for future 集成. This requires your Amcrest 配置 to be moved to the new `amcrest` component. ([@tchellomello] - [#8184]) ([amcrest docs]) ([摄像头.amcrest docs]) ([传感器.amcrest docs]) (breaking change) (new-platform) ```yaml amcrest: - host: !secret amcrest_living name: "Living Room" username: !secret amcrest_living_username password: !secret amcrest_living_password resolution: low stream_source: snapshot sensors: - motion_detector - ptz_preset ``` ## 全部变更 * 版本 bump to 0.49.0.dev0 ([@fabaff] - [#8266]) * 升级 pyowm to 2.7.1 ([@fabaff] - [#8274]) ([传感器.openweathermap docs]) ([天气.openweathermap docs]) * Don't call 更新() in constructor ([@fabaff] - [#8276]) ([传感器.openweathermap docs]) * 更新 apcaccess to 0.0.13. Add "Percent Load Capacity" to INFERRED\_UNITS. ([@michaelarnauts] - [#8277]) ([apcupsd docs]) ([传感器.apcupsd docs]) * 更新 knxip to 0.4 (better handling of reconnects) ([@open-homeautomation] - [#8289]) ([knx docs]) * Add london\_underground ([@robmarkcole] - [#8272]) ([传感器.london\_underground docs][传感器.london_underground docs]) (new-platform) * pytado moved to pypi ([@wmalgadey] - [#8298]) ([tado docs]) ([温控.tado docs]) * Fix doc link in header ([@robmarkcole] - [#8305]) ([传感器.london\_underground docs][传感器.london_underground docs]) * 升级 discord.py to 0.16.8 ([@fabaff] - [#8304]) ([通知.discord docs]) * zha: Strip whitespace from 设备 names ([@rcloran] - [#8306]) ([zha docs]) * 升级 chardet to 3.0.4 ([@fabaff] - [#8313]) * 升级 aiohttp to 2.2.2 ([@fabaff] - [#8314]) * Fix pylint issue ([@fabaff] - [#8325]) ([snips docs]) * vsure 1.3.7 ([@persandstrom] - [#8321]) ([verisure docs]) * 更新 pyEmby to fix media 图像 ([@mezz64] - [#8331]) ([媒体播放器.emby docs]) * Partially revert #7931 ([@fabaff] - [#8326]) * Only allow 'tls\_insecure\_set()' if cert is present (fixes #8329) ([@fabaff] - [#8337]) ([MQTT docs]) * Fix issue #8285 ([@Sabesto] - [#8340]) ([modbus docs]) ([binary\_sensor.modbus docs][binary_sensor.modbus docs]) ([温控.flexit docs]) ([传感器.modbus docs]) ([开关.modbus docs]) * Bump dlib face\_recognition to 0.2.0 ([@pvizeli] - [#8345]) ([image\_processing.dlib\_face\_detect docs][image_processing.dlib_face_detect docs]) ([image\_processing.dlib\_face\_identify docs][image_processing.dlib_face_identify docs]) * 更新 Avion and Decora 开关 to match upstream changes ([@mjg59] - [#7903]) ([灯光.avion docs]) ([灯光.decora docs]) * Fix the "302" 错误 in the UPC Connect component and remove the need to specify the router 密码 ([@Flavien] - [#8335]) ([device\_tracker.upc\_connect docs][device_tracker.upc_connect docs]) (breaking change) * Add new feature to Apple TV platform ([@postlund] - [#8122]) ([媒体播放器.apple\_tv docs][媒体播放器.apple_tv docs]) (breaking change) * Add citybikes platform ([@aronsky] - [#8202]) ([传感器.citybikes docs]) (new-platform) * Fix some issues for PyLint 1.7.2 ([@balloob] - [#8356]) * Fix pylint 1.7.2 no-else-return issues ([@balloob] - [#8361]) * 升级 aiohttp to 2.2.3 ([@fabaff] - [#8363]) * Remove some more usage of run\_in\_executor ([@balloob] - [#8352]) * Correct spelling of aliases, deprecate old config options. ([@aequitas] - [#8348]) ([rflink docs]) ([灯光.rflink docs]) ([传感器.rflink docs]) ([开关.rflink docs]) * Allow Pilight 二元sensor to control reset\_delay\_sec through 配置 ([@clarkewd] - [#8358]) ([binary\_sensor.pilight docs][binary_sensor.pilight docs]) * MQTT client\_id fix for #8315 ([@heinemml] - [#8366]) ([MQTT docs]) * Allow all 面板 urls ([@balloob] - [#8368]) * 更新 pyHik to catch XML 错误 ([@mezz64] - [#8384]) ([binary\_sensor.hikvision docs][binary_sensor.hikvision docs]) * 更新 版本 ([@craigjmidwinter] - [#8380]) ([alarm\_control\_panel.totalconnect docs][alarm_control_panel.totalconnect docs]) * Add One-Time 密码 传感器 (OTP) ([@postlund] - [#8332]) ([传感器.otp docs]) (new-platform) * buienradar==0.7, fix winddirection/azimuth, logging ([@mjj4791] - [#8281]) ([传感器.buienradar docs]) ([天气.buienradar docs]) * Add component for xiaomi robot 吸尘器 (开关.xiaomi\_vacuum) ([@rytilahti] - [#7913]) ([开关.xiaomi\_vacuum docs][开关.xiaomi_vacuum docs]) (new-platform) * Try catch around database updates in recorder. Resolves 6919 ([@mitchese] - [#8349]) ([recorder docs]) * Fix Amazon Polly with non english voices. #8377 ([@CharlesBlonde] - [#8378]) ([tts.amazon\_polly docs][tts.amazon_polly docs]) * Fix TTS options. #8375 ([@CharlesBlonde] - [#8376]) ([tts docs]) * Add address-specific KNX listeners that fire events on the HASS bus ([@open-homeautomation] - [#8374]) ([knx docs]) * GTFS: check start/end date on 服务 ([@Kernald] - [#8373]) ([传感器.gtfs docs]) * Implement KNX dimming functionality ([@open-homeautomation] - [#8371]) ([灯光.knx docs]) * Add Soundtouch support for playing an HTTP url ([@CharlesBlonde] - [#8370]) ([媒体播放器.soundtouch docs]) * Modbus fixes to work with pymodbus 1.3.1 ([@Sabesto] - [#8365]) ([modbus docs]) ([binary\_sensor.modbus docs][binary_sensor.modbus docs]) ([传感器.modbus docs]) ([开关.modbus docs]) * Cleanup the asuswrt component ([@mattsch] - [#8359]) ([device\_tracker.asuswrt docs][device_tracker.asuswrt docs]) * cover\_template:i open/close/stop 动作 no longer required. Improve tests ([@PhracturedBlue] - [#8344]) ([遮盖.模板 docs]) * Prevent 错误 on Octoprint 传感器 and binary\_sensors when Octoprint and/or Printer are off ([@w1ll1am23] - [#8343]) ([octoprint docs]) ([binary\_sensor.octoprint docs][binary_sensor.octoprint docs]) ([传感器.octoprint docs]) * 在场 detection for tp link eap225 ([@alexrockt] - [#8322]) ([device\_tracker.tplink docs][device_tracker.tplink docs]) * zha 灯光: Refresh at startup ([@rcloran] - [#8310]) ([灯光.zha docs]) * zha: Try multiple reads to get manufacturer/model ([@rcloran] - [#8308]) ([zha docs]) * Upnp mapping 通知 ([@dgomes] - [#8303]) ([upnp docs]) * Use 用户-set 设备 names for Linksys Smart Wi-Fi routers (3) ([@Klikini] - [#8300]) ([device\_tracker.linksys\_smart docs][device_tracker.linksys_smart docs]) * Added support for upload of 遥控器 or local files to slack ([@simaosimao] - [#8278]) ([通知.slack docs]) * 更新 avion.py ([@pvizeli] - [#8364]) ([灯光.avion docs]) * LaMetric platform and 通知 module ([@open-homeautomation] - [#8230]) ([lametric docs]) ([通知.lametric docs]) (new-platform) * Sets spotify media\_type to music ([@Tommatheussen] - [#8387]) ([媒体播放器.spotify docs]) * 更新 waqi 传感器 ([@andrey-git] - [#8385]) ([传感器.waqi docs]) * 更新 aiolifx ([@amelchio] - [#8396]) ([灯光.lifx docs]) * Code owners ([@balloob] - [#8393]) * Add new Dyson 传感器 ([@CharlesBlonde] - [#8199]) ([dyson docs]) ([风扇.dyson docs]) ([传感器.dyson docs]) * Fix CODEOWNERS Z-Wave team name ([@armills] - [#8400]) * 升级 Sphinx to 1.6.3 ([@fabaff] - [#8405]) * Use upstream RachioPy, fix manual run 开关 ([@Klikini] - [#8286]) ([开关.rachio docs]) * Marrantz SR5006 & SR5006 treated as AVR-X 设备 | Fixed Mapping of Media Player and AUX input functions ([@scarface-4711] - [#8409]) ([媒体播放器.denonavr docs]) * New component to connect to VELUX KLF 200 Interface ([@Julius2342] - [#8203]) ([velux docs]) ([场景.velux docs]) (new-platform) * Properly handle the case when a group includes itself. ([@andrey-git] - [#8398]) ([group docs]) * Add set\_operation\_mode support to generic\_thermostat ([@mtreinish] - [#8392]) ([温控.generic\_thermostat docs][温控.generic_thermostat docs]) * Make gzips reproducible by excluding timestamp ([@armills] - [#8420]) * Do not overwrite a custom hyperion 灯光 name with the hostname of the server. ([@doctorjames] - [#8391]) ([灯光.hyperion docs]) * Fixed link to 文档 ([@Julius2342] - [#8424]) ([velux docs]) ([场景.velux docs]) * Fix KeyError (fixes #3721, fixes #7241) ([@fabaff] - [#8428]) (传感器.uber docs) * Use HA lat/long for the start (fixes #3971) ([@fabaff] - [#8429]) (传感器.uber docs) * bump python-mirobo requirement to support newer firmwares and more ([@rytilahti] - [#8431]) ([开关.xiaomi\_vacuum docs][开关.xiaomi_vacuum docs]) * New 服务 `send_magic_packet` with new component `wake_on_lan` ([@azogue] - [#8397]) ([wake\_on\_lan docs][wake_on_lan docs]) (new-platform) * Integrate utility functions into restricted Python environment ([@open-homeautomation] - [#8427]) ([python\_script docs][python_script docs]) * Allow Twitter 通知 to include media ([@MikeChristianson] - [#8282]) ([通知 docs]) ([通知.twitter docs]) * Fix typo (sending USERNAME instead of 密码) introduced in #7963 ([@thecynic] - [#8433]) ([lutron docs]) * zha: Handle both input and output clusters ([@rcloran] - [#8410]) ([zha docs]) ([binary\_sensor.zha docs][binary_sensor.zha docs]) ([灯光.zha docs]) ([传感器.zha docs]) * Add support for Prometheus ([@rcloran] - [#8211]) ([prometheus docs]) (new-platform) * Refactored Amcrest to use central hub component ([@tchellomello] - [#8184]) ([amcrest docs]) ([摄像头.amcrest docs]) ([传感器.amcrest docs]) (breaking change) (new-platform) * Fix radiothermostat -1 value issue ([@aneisch] - [#8395]) ([温控.radiotherm docs]) * Added media\_extractor 服务 ([@minchik] - [#8369]) ([media\_extractor docs][media_extractor docs]) (new-platform) * Updated pyvera ([@alanfischer] - [#8437]) ([vera docs]) * 升级 phue to 1.0 (fixes #7749) ([@fabaff] - [#8444]) ([灯光.hue docs]) * Add effects ([@fabaff] - [#8442]) ([灯光.mystrom docs]) * Exclude 'TAXI' product (fixes #8401) ([@fabaff] - [#8438]) (传感器.uber docs) * 开关 pyW215 to pypi ([@andrey-git] - [#8445]) ([开关.dlink docs]) * Vizio SmartCast support ([@vkorn] - [#8260]) ([媒体播放器.vizio docs]) (new-platform) * DHT support for humidity and temperature offset ([@gitmopp] - [#8238]) ([传感器.dht docs]) * Add support for rain and moisture 传感器 ([@sdague] - [#8440]) ([传感器.arwn docs]) * Hass.io: Disable timeout when updating OS/supervisor/hass ([@balloob] - [#8447]) ([hassio docs]) * Fix Arlo Q not working with 0.48.1 ([@viswa-swami] - [#8446]) ([摄像头.arlo docs]) * Support for Plex servers with enforced SSL ([@nmaggioni] - [#8341]) ([媒体播放器.plex docs]) * 升级 youtube\_dl to 2017.7.9 ([@fabaff] - [#8450]) ([media\_extractor docs][media_extractor docs]) * Implement a bridge between HASS event bus and KNX bus to send events ([@open-homeautomation] - [#8449]) ([knx docs]) * LIFX: improve 灯光 availability ([@amelchio] - [#8451]) ([灯光.lifx docs]) * LIFX: make broadcast address configurable ([@amelchio] - [#8453]) ([灯光.lifx docs]) * 后端 support for themes ([@andrey-git] - [#8419]) * 升级 broadlink ([@danielhiversen] - [#8462]) ([传感器.broadlink docs]) ([开关.broadlink docs]) * 升级 rfxtrx lib ([@danielhiversen] - [#8463]) ([rfxtrx docs]) * Plex: Add exception handler when connection fails ([@abmantis] - [#8179]) ([媒体播放器.plex docs]) * HomeMatic dependency 升级 + IP Wall Thermostat support ([@danielperna84] - [#8465]) ([homematic docs]) * Add kiosk-mode 面板 ([@andrey-git] - [#8457]) [#7903]: https://github.com/home-assistant/home-assistant/pull/7903 [#7913]: https://github.com/home-assistant/home-assistant/pull/7913 [#8122]: https://github.com/home-assistant/home-assistant/pull/8122 [#8179]: https://github.com/home-assistant/home-assistant/pull/8179 [#8184]: https://github.com/home-assistant/home-assistant/pull/8184 [#8199]: https://github.com/home-assistant/home-assistant/pull/8199 [#8202]: https://github.com/home-assistant/home-assistant/pull/8202 [#8203]: https://github.com/home-assistant/home-assistant/pull/8203 [#8211]: https://github.com/home-assistant/home-assistant/pull/8211 [#8230]: https://github.com/home-assistant/home-assistant/pull/8230 [#8238]: https://github.com/home-assistant/home-assistant/pull/8238 [#8260]: https://github.com/home-assistant/home-assistant/pull/8260 [#8266]: https://github.com/home-assistant/home-assistant/pull/8266 [#8272]: https://github.com/home-assistant/home-assistant/pull/8272 [#8274]: https://github.com/home-assistant/home-assistant/pull/8274 [#8276]: https://github.com/home-assistant/home-assistant/pull/8276 [#8277]: https://github.com/home-assistant/home-assistant/pull/8277 [#8278]: https://github.com/home-assistant/home-assistant/pull/8278 [#8281]: https://github.com/home-assistant/home-assistant/pull/8281 [#8282]: https://github.com/home-assistant/home-assistant/pull/8282 [#8286]: https://github.com/home-assistant/home-assistant/pull/8286 [#8289]: https://github.com/home-assistant/home-assistant/pull/8289 [#8298]: https://github.com/home-assistant/home-assistant/pull/8298 [#8300]: https://github.com/home-assistant/home-assistant/pull/8300 [#8303]: https://github.com/home-assistant/home-assistant/pull/8303 [#8304]: https://github.com/home-assistant/home-assistant/pull/8304 [#8305]: https://github.com/home-assistant/home-assistant/pull/8305 [#8306]: https://github.com/home-assistant/home-assistant/pull/8306 [#8308]: https://github.com/home-assistant/home-assistant/pull/8308 [#8310]: https://github.com/home-assistant/home-assistant/pull/8310 [#8313]: https://github.com/home-assistant/home-assistant/pull/8313 [#8314]: https://github.com/home-assistant/home-assistant/pull/8314 [#8321]: https://github.com/home-assistant/home-assistant/pull/8321 [#8322]: https://github.com/home-assistant/home-assistant/pull/8322 [#8325]: https://github.com/home-assistant/home-assistant/pull/8325 [#8326]: https://github.com/home-assistant/home-assistant/pull/8326 [#8331]: https://github.com/home-assistant/home-assistant/pull/8331 [#8332]: https://github.com/home-assistant/home-assistant/pull/8332 [#8335]: https://github.com/home-assistant/home-assistant/pull/8335 [#8337]: https://github.com/home-assistant/home-assistant/pull/8337 [#8340]: https://github.com/home-assistant/home-assistant/pull/8340 [#8341]: https://github.com/home-assistant/home-assistant/pull/8341 [#8343]: https://github.com/home-assistant/home-assistant/pull/8343 [#8344]: https://github.com/home-assistant/home-assistant/pull/8344 [#8345]: https://github.com/home-assistant/home-assistant/pull/8345 [#8348]: https://github.com/home-assistant/home-assistant/pull/8348 [#8349]: https://github.com/home-assistant/home-assistant/pull/8349 [#8352]: https://github.com/home-assistant/home-assistant/pull/8352 [#8356]: https://github.com/home-assistant/home-assistant/pull/8356 [#8358]: https://github.com/home-assistant/home-assistant/pull/8358 [#8359]: https://github.com/home-assistant/home-assistant/pull/8359 [#8361]: https://github.com/home-assistant/home-assistant/pull/8361 [#8363]: https://github.com/home-assistant/home-assistant/pull/8363 [#8364]: https://github.com/home-assistant/home-assistant/pull/8364 [#8365]: https://github.com/home-assistant/home-assistant/pull/8365 [#8366]: https://github.com/home-assistant/home-assistant/pull/8366 [#8368]: https://github.com/home-assistant/home-assistant/pull/8368 [#8369]: https://github.com/home-assistant/home-assistant/pull/8369 [#8370]: https://github.com/home-assistant/home-assistant/pull/8370 [#8371]: https://github.com/home-assistant/home-assistant/pull/8371 [#8373]: https://github.com/home-assistant/home-assistant/pull/8373 [#8374]: https://github.com/home-assistant/home-assistant/pull/8374 [#8376]: https://github.com/home-assistant/home-assistant/pull/8376 [#8378]: https://github.com/home-assistant/home-assistant/pull/8378 [#8380]: https://github.com/home-assistant/home-assistant/pull/8380 [#8384]: https://github.com/home-assistant/home-assistant/pull/8384 [#8385]: https://github.com/home-assistant/home-assistant/pull/8385 [#8387]: https://github.com/home-assistant/home-assistant/pull/8387 [#8391]: https://github.com/home-assistant/home-assistant/pull/8391 [#8392]: https://github.com/home-assistant/home-assistant/pull/8392 [#8393]: https://github.com/home-assistant/home-assistant/pull/8393 [#8395]: https://github.com/home-assistant/home-assistant/pull/8395 [#8396]: https://github.com/home-assistant/home-assistant/pull/8396 [#8397]: https://github.com/home-assistant/home-assistant/pull/8397 [#8398]: https://github.com/home-assistant/home-assistant/pull/8398 [#8400]: https://github.com/home-assistant/home-assistant/pull/8400 [#8405]: https://github.com/home-assistant/home-assistant/pull/8405 [#8409]: https://github.com/home-assistant/home-assistant/pull/8409 [#8410]: https://github.com/home-assistant/home-assistant/pull/8410 [#8419]: https://github.com/home-assistant/home-assistant/pull/8419 [#8420]: https://github.com/home-assistant/home-assistant/pull/8420 [#8424]: https://github.com/home-assistant/home-assistant/pull/8424 [#8427]: https://github.com/home-assistant/home-assistant/pull/8427 [#8428]: https://github.com/home-assistant/home-assistant/pull/8428 [#8429]: https://github.com/home-assistant/home-assistant/pull/8429 [#8431]: https://github.com/home-assistant/home-assistant/pull/8431 [#8433]: https://github.com/home-assistant/home-assistant/pull/8433 [#8437]: https://github.com/home-assistant/home-assistant/pull/8437 [#8438]: https://github.com/home-assistant/home-assistant/pull/8438 [#8440]: https://github.com/home-assistant/home-assistant/pull/8440 [#8442]: https://github.com/home-assistant/home-assistant/pull/8442 [#8444]: https://github.com/home-assistant/home-assistant/pull/8444 [#8445]: https://github.com/home-assistant/home-assistant/pull/8445 [#8446]: https://github.com/home-assistant/home-assistant/pull/8446 [#8447]: https://github.com/home-assistant/home-assistant/pull/8447 [#8449]: https://github.com/home-assistant/home-assistant/pull/8449 [#8450]: https://github.com/home-assistant/home-assistant/pull/8450 [#8451]: https://github.com/home-assistant/home-assistant/pull/8451 [#8453]: https://github.com/home-assistant/home-assistant/pull/8453 [#8457]: https://github.com/home-assistant/home-assistant/pull/8457 [#8462]: https://github.com/home-assistant/home-assistant/pull/8462 [#8463]: https://github.com/home-assistant/home-assistant/pull/8463 [#8465]: https://github.com/home-assistant/home-assistant/pull/8465 [@CharlesBlonde]: https://github.com/CharlesBlonde [@Flavien]: https://github.com/Flavien [@Julius2342]: https://github.com/Julius2342 [@Kernald]: https://github.com/Kernald [@Klikini]: https://github.com/Klikini [@MikeChristianson]: https://github.com/MikeChristianson [@PhracturedBlue]: https://github.com/PhracturedBlue [@Sabesto]: https://github.com/Sabesto [@Tommatheussen]: https://github.com/Tommatheussen [@abmantis]: https://github.com/abmantis [@aequitas]: https://github.com/aequitas [@alanfischer]: https://github.com/alanfischer [@alexrockt]: https://github.com/alexrockt [@amelchio]: https://github.com/amelchio [@andrey-git]: https://github.com/andrey-git [@aneisch]: https://github.com/aneisch [@armills]: https://github.com/armills [@aronsky]: https://github.com/aronsky [@azogue]: https://github.com/azogue [@balloob]: https://github.com/balloob [@clarkewd]: https://github.com/clarkewd [@danielhiversen]: https://github.com/danielhiversen [@danielperna84]: https://github.com/danielperna84 [@dgomes]: https://github.com/dgomes [@doctorjames]: https://github.com/doctorjames [@fabaff]: https://github.com/fabaff [@gitmopp]: https://github.com/gitmopp [@heinemml]: https://github.com/heinemml [@mattsch]: https://github.com/mattsch [@mezz64]: https://github.com/mezz64 [@michaelarnauts]: https://github.com/michaelarnauts [@minchik]: https://github.com/minchik [@mitchese]: https://github.com/mitchese [@mjg59]: https://github.com/mjg59 [@mjj4791]: https://github.com/mjj4791 [@mtreinish]: https://github.com/mtreinish [@nmaggioni]: https://github.com/nmaggioni [@open-homeautomation]: https://github.com/open-homeautomation [@persandstrom]: https://github.com/persandstrom [@postlund]: https://github.com/postlund [@pvizeli]: https://github.com/pvizeli [@rcloran]: https://github.com/rcloran [@robmarkcole]: https://github.com/robmarkcole [@rytilahti]: https://github.com/rytilahti [@scarface-4711]: https://github.com/scarface-4711 [@sdague]: https://github.com/sdague [@simaosimao]: https://github.com/simaosimao [@tchellomello]: https://github.com/tchellomello [@thecynic]: https://github.com/thecynic [@viswa-swami]: https://github.com/viswa-swami [@vkorn]: https://github.com/vkorn [@w1ll1am23]: https://github.com/w1ll1am23 [@craigjmidwinter]: https://github.com/craigjmidwinter [@wmalgadey]: https://github.com/wmalgadey [alarm_control_panel.totalconnect docs]: /integrations/totalconnect [amcrest docs]: /integrations/amcrest/ [apcupsd docs]: /integrations/apcupsd/ [binary_sensor.hikvision docs]: /integrations/hikvision [binary_sensor.modbus docs]: /integrations/binary_sensor.modbus/ [binary_sensor.octoprint docs]: /integrations/octoprint#binary-传感器 [binary_sensor.pilight docs]: /integrations/pilight#binary-传感器 [binary_sensor.zha docs]: /integrations/zha [摄像头.amcrest docs]: /integrations/amcrest [摄像头.arlo docs]: /integrations/arlo#摄像头 [温控.flexit docs]: /integrations/flexit [温控.generic_thermostat docs]: /integrations/generic_thermostat [温控.radiotherm docs]: /integrations/radiotherm [温控.tado docs]: /integrations/tado [遮盖.模板 docs]: /integrations/遮盖.模板/ [device_tracker.asuswrt docs]: /integrations/asuswrt [device_tracker.linksys_smart docs]: /integrations/linksys_smart [device_tracker.tplink docs]: /integrations/tplink [device_tracker.upc_connect docs]: /integrations/upc_connect [dyson docs]: /integrations/dyson/ [风扇.dyson docs]: /integrations/dyson#风扇 [group docs]: /integrations/group/ [hassio docs]: /hassio/ [homematic docs]: /integrations/homematic/ [image_processing.dlib_face_detect docs]: /integrations/dlib_face_detect [image_processing.dlib_face_identify docs]: /integrations/dlib_face_identify [knx docs]: /integrations/knx/ [lametric docs]: /integrations/lametric/ [灯光.avion docs]: /integrations/avion [灯光.decora docs]: /integrations/decora [灯光.hue docs]: /integrations/hue [灯光.hyperion docs]: /integrations/hyperion [灯光.knx docs]: /integrations/灯光.knx/ [灯光.lifx docs]: /integrations/lifx [灯光.mystrom docs]: /integrations/mystrom#灯光 [灯光.rflink docs]: /integrations/灯光.rflink/ [灯光.zha docs]: /integrations/zha [lutron docs]: /integrations/lutron/ [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.apple_tv docs]: /integrations/apple_tv [媒体播放器.denonavr docs]: /integrations/denonavr/ [媒体播放器.emby docs]: /integrations/emby [媒体播放器.plex docs]: /integrations/plex#media-player [媒体播放器.soundtouch docs]: /integrations/soundtouch [媒体播放器.spotify docs]: /integrations/spotify [媒体播放器.vizio docs]: /integrations/vizio [modbus docs]: /integrations/modbus/ [MQTT docs]: /integrations/MQTT/ [通知 docs]: /integrations/通知/ [通知.discord docs]: /integrations/discord [通知.lametric docs]: /integrations/lametric [通知.slack docs]: /integrations/slack [通知.twitter docs]: /integrations/twitter [octoprint docs]: /integrations/octoprint/ [prometheus docs]: /integrations/prometheus/ [python_script docs]: /integrations/python_script/ [recorder docs]: /integrations/recorder/ [rflink docs]: /integrations/rflink/ [rfxtrx docs]: /integrations/rfxtrx/ [场景.velux docs]: /integrations/velux [传感器.amcrest docs]: /integrations/amcrest [传感器.apcupsd docs]: /integrations/apcupsd#传感器 [传感器.arwn docs]: /integrations/arwn [传感器.broadlink docs]: /integrations/broadlink#传感器 [传感器.buienradar docs]: /integrations/传感器.buienradar/ [传感器.citybikes docs]: /integrations/citybikes [传感器.dht docs]: /integrations/dht [传感器.dyson docs]: /integrations/dyson#传感器 [传感器.gtfs docs]: /integrations/gtfs [传感器.london_underground docs]: /integrations/london_underground [传感器.modbus docs]: /integrations/传感器.modbus/ [传感器.octoprint docs]: /integrations/octoprint#传感器 [传感器.openweathermap docs]: /integrations/openweathermap#传感器 [传感器.otp docs]: /integrations/otp [传感器.rflink docs]: /integrations/传感器.rflink/ [传感器.waqi docs]: /integrations/waqi [传感器.zha docs]: /integrations/zha [snips docs]: /integrations/snips/ [开关.broadlink docs]: /integrations/broadlink#开关 [开关.dlink docs]: /integrations/dlink [开关.modbus docs]: /integrations/开关.modbus/ [开关.rachio docs]: /integrations/rachio#开关 [开关.rflink docs]: /integrations/开关.rflink/ [开关.xiaomi_vacuum docs]: /integrations/吸尘器.xiaomi_miio/ [tado docs]: /integrations/tado/ [tts docs]: /integrations/tts/ [tts.amazon_polly docs]: /integrations/amazon_polly [upnp docs]: /integrations/upnp/ [velux docs]: /integrations/velux/ [前端 docs]: /integrations/frontend/ [vera docs]: /integrations/vera/ [verisure docs]: /integrations/verisure/ [wake_on_lan docs]: /integrations/wake_on_lan/ [天气.buienradar docs]: /integrations/buienradar [天气.openweathermap docs]: /integrations/openweathermap#天气 [zha docs]: /integrations/zha/ [zha.const docs]: /integrations/zha.const/ [forum]: https://community.home-assistant.io/ [issue]: https://github.com/home-assistant/home-assistant/issues [discord]: https://discord.gg/c5DvZ4e [#8497]: https://github.com/home-assistant/home-assistant/pull/8497 [#8511]: https://github.com/home-assistant/home-assistant/pull/8511 [#8516]: https://github.com/home-assistant/home-assistant/pull/8516 [#8517]: https://github.com/home-assistant/home-assistant/pull/8517 [#8523]: https://github.com/home-assistant/home-assistant/pull/8523 [#8539]: https://github.com/home-assistant/home-assistant/pull/8539 [#8543]: https://github.com/home-assistant/home-assistant/pull/8543 [#8553]: https://github.com/home-assistant/home-assistant/pull/8553 [#8594]: https://github.com/home-assistant/home-assistant/pull/8594 [#8610]: https://github.com/home-assistant/home-assistant/pull/8610 [@clkao]: https://github.com/clkao [@maikelwever]: https://github.com/maikelwever [@ypollart]: https://github.com/ypollart [binary_sensor.rfxtrx docs]: /integrations/rfxtrx#binary-传感器 [telegram_bot docs]: /integrations/telegram_bot/ [#8545]: https://github.com/home-assistant/home-assistant/pull/8545 [#8571]: https://github.com/home-assistant/home-assistant/pull/8571 [#8601]: https://github.com/home-assistant/home-assistant/pull/8601 [#8615]: https://github.com/home-assistant/home-assistant/pull/8615 [#8621]: https://github.com/home-assistant/home-assistant/pull/8621 [#8624]: https://github.com/home-assistant/home-assistant/pull/8624 [@filcole]: https://github.com/filcole [@glance-]: https://github.com/glance- [@jawilson]: https://github.com/jawilson [@schaal]: https://github.com/schaal [device_tracker.ubus docs]: /integrations/ubus [keyboard_remote docs]: /integrations/keyboard_remote/ [开关.flux docs]: /integrations/flux --- url: /home-assistant/blog/2017-07-17-hasspodcast-ep-4.md --- # Home Assistant Podcast #4 We quickly 遮盖 off a few community items including the move to Discord and Carlo talks with Phil about his use of Floorplan. [Listen online][episode] [episode]: https://hasspodcast.io/ha004/ --- url: /home-assistant/blog/2017-07-25-introducing-hassio.md --- # Introducing Hass.io **TL;DR:** Today we're introducing [Hass.io]. Hass.io is an operating system that will take care of installing and updating Home Assistant, is managed from the Home Assistant UI, allows creating/restoring snapshots of your 配置 and can easily be extended using [Hass.io 插件][插件] including [Google Assistant] and [Let's Encrypt]. *** Home Assistant is 2 months away from being 4 years old. In that time the Internet of Things has really taken off and we've seen many new 设备 and 服务. We saw the introduction of voice assistants like Google Home and new standards like Apple HomeKit. Some things have been supported natively in Home Assistant, others have been integrated into Home Assistant via third party applications. All these moving parts caused our 用户 to spend a lot of time maintaining their systems and applications instead of automating their homes. So we decided to take a step back from day-to-day Home Assistant development and see if we could offer a solution that makes updating a breeze for our 用户. A solution that you can flash to your 树莓派 and no longer worry about. A solution that would still be local first and respect the 用户's privacy. And this is how [Pascal Vizeli] came up with Hass.io, an operating system based on [ResinOS] and [Docker]. Hass.io will take care of installing and updating Home Assistant, is managed from the Home Assistant UI, allows taking/restoring snapshots of your 配置 and can easily be extended using [Hass.io 插件][插件].

Hass.io 仪表盘

To 安装 插件, a 用户 can browse the built-in 插件 store and 安装, 配置 and 更新 any available application. Want to turn your 设备 into a Google Assistant or make your 配置 accessible via Samba/Windows networking? Both are a couple of clicks away! ([Video demo - 38s, no audio][安装-demo]) At launch we have included a couple of [built-in 插件][插件] like [Google Assistant], [Let's Encrypt] and [Duck DNS]. Besides our internal 插件, it is also possible to create and share your own 插件 repositories. During our beta period we've already seen some great 插件 being shared: [Homebridge][olivierg], [InfluxDB][bestlibre], [HASS Configurator][danielperna] and [AppDaemon][vkorn]. As we strongly believe in the openness of technology, we are releasing Hass.io as [开源] under the Apache 2.0 license. That way any 用户 can make sure that the code that runs in their homes is secure and safe. * [Learn more about Hass.io][Hass.io] * [安装 Hass.io][安装] * [Available 插件][插件] *Some frequently asked questions are answered below in the read more section.*
Hass.io has been built by [Pascal Vizeli], the UI has been made by [Paulus Schoutsen] and [BRUHAutomation] made the introduction video. Big thanks to [Resin.io] for building ResinOS and helping us get started with it. Also a big thanks to the community for early feedback, helping out with the 文档 and 插件 development ❤️ #### Will Hass.io be the only way to run Home Assistant? Hass.io is and will always be optional. You can still run Home Assistant wherever you can run Python. #### Which 设备 are supported at launch? Initially we support the 树莓派 1, 2, 3 and Intel NUC. Advanced 用户 can also [安装 Hass.io on a Linux server][advanced-安装]. #### Can I 安装 packages or 脚本 on the machine? No, this is not possible as we're using stateless Docker 容器. To 安装 a package you'll have to write a local 插件 that interacts with Home Assistant. See \[our 教程]\[run-local]. #### Can I 恢复 a snapshot on a different 设备? Yes, any Hass.io snapshot can be restored on any 设备. #### The Hass.io 配置 面板 contains powerful tools. Why is there no extra security besides the Home Assistant login? This is in the works. We have already implemented [the 后端](https://github.com/home-assistant/hassio/pull/41) and plan to 发布 the UI soon. #### Is there a roadmap? We use [Pivotal Tracker] to track things that are in progress and what we might work on. [Hass.io]: /hassio [安装]: /hassio/安装 [Homebridge]: https://github.com/nfarina/homebridge [hb-hass]: https://github.com/home-assistant/homebridge-homeassistant [Pascal Vizeli]: https://github.com/pvizeli/ [Paulus Schoutsen]: https://github.com/balloob/ [ResinOS]: https://resinos.io/ [Docker]: https://www.Docker.com/ [插件]: /apps/ [bestlibre]: https://community.home-assistant.io/t/repository-bestlibre-addons-repository/18037 [danielperna]: https://community.home-assistant.io/t/repository-hass-configurator/17838 [olivierg]: https://community.home-assistant.io/t/repository-homebridge-add-on/18569 [vkorn]: https://community.home-assistant.io/t/repository-few-addons/20659 [安装-demo]: https://youtu.be/NfyavpAg4as [BRUHAutomation]: https://www.youtube.com/channel/UCLecVrux63S6aYiErxdiy4w [开源]: https://github.com/home-assistant/hassio [Google Assistant]: /插件/google_assistant/ [Let's Encrypt]: /插件/lets_encrypt/ [Duck DNS]: /插件/duckdns/ [advanced-安装]: /hassio/installation/#alternative-安装-on-generic-linux-server [Pivotal Tracker]: https://www.pivotaltracker.com/n/projects/2020851 [Resin.io]: https://resin.io --- url: /home-assistant/blog/2017-07-27-talk-python-podcast.md --- --- url: /home-assistant/blog/2017-07-29-release-50.md --- # 0.50: 语音控制、History 改进与 Xiaomi 上周三,我们发布了 [Hass.io](/home-assistant/hassio/),这是一个用于处理家庭自动化环境中各种更新烦恼的操作系统,而且它还远不止于此。这是 Home Assistant 的一个重要里程碑,因为它是我们朝着“自备硬件、完整集成方案”迈出的第一步。 这次发布非常成功。BRUHAutomation 制作的[20 分钟介绍视频][hassio-intro] 在短短 4 天内就获得了 1.25 万次观看和超过 150 条评论。 Hass.io 将会成为更大、更完善集成功能的坚实基础,敬请期待。 ### 为集成加入语音能力 不过先聊到这里,别忘了 Home Assistant 本身。这次发布彻底改造了我们处理语音集成的方式。我们把 Home Assistant 变成了一个可编写语音应用的平台,无论语音处理发生在何处都适用。它可以由 Alexa、Google Assistant,或 Home Assistant 用户界面来完成。 我们对这项新功能非常兴奋,也希望它能催生一类构建在 Home Assistant 之上的全新应用和系统。这个版本加入了购物清单来展示新能力。作为用户,你可以通过语音把任意物品加入购物清单,也可以直接询问购物清单里有什么。 ```yaml # Example configuration.yaml entry shopping_list: ``` 为了让这些应用更容易测试,我们更新了 conversation 组件。现在你可以配置句子,让它们直接接入新的语音功能。配合全新的界面,这会带来很多很棒的交互方式!更多信息请查看[开发者文档][intent docs]。
### History 改进 最近 [@OverloadUT] 花了很多时间优化历史记录数据库查询。这次发布包含了 PR [#8632],这是他正在推进的一系列改进中的第一项。这个 PR 通过针对单个实体使用优化查询,显著提升了这类请求的性能。 在他的一些测试中,这项改动大约快了 300 倍(从 30 秒缩短到 0.1 秒!)。(由于多实体查询会随着当前 recorder 运行时间变长而变得更慢,因此理论上没有固定的性能上限。) [hassio-intro]: https://www.youtube.com/watch?v=XWPluWcYRMI&feature=youtu.be ### Xiaomi 集成 Yes, it has happened! After being in beta for a while, the Xiaomi support is now available to all. [@danielhiversen] did an amazing job and we now support 传感器, 开关, 灯光 and 遮盖. ### Velbus 集成 另一个很棒的集成是由 [@thomasdelaet] 贡献的 Velbus 家庭自动化系统。它集成了他们的传感器、遮盖、风扇、灯光和开关。 ### 通过 MQTT 控制的手动报警 多亏了 [@colinodell],手动报警组件现在推出了支持完整 MQTT 控制的新版本。借助它,你可以构建自己的控制面板来远程布防/撤防报警。例如,可以使用[树莓派打造一个报警控制面板](https://www.hackster.io/colinodell/diy-报警-control-面板-for-home-assistant-ac1813)。 ## 新平台 * Initial support for Google WiFi/OnHub ([@fronzbot] - [#8485]) ([传感器.google\_wifi docs][传感器.google_wifi docs]) (new-platform) * Xiaomi gw support ([@danielhiversen] - [#8555]) ([xiaomi docs]) ([binary\_sensor.xiaomi docs][binary_sensor.xiaomi docs]) ([遮盖.xiaomi docs]) ([灯光.xiaomi docs]) ([传感器.xiaomi docs]) ([开关.xiaomi docs]) (new-platform) * Add Intent component ([@balloob] - [#8434]) ([alexa docs]) ([intent\_script docs][intent_script docs]) ([shopping\_list docs][shopping_list docs]) ([snips docs]) (breaking change) (new-platform) * Manual 报警 with MQTT control ([@colinodell] - [#8257]) ([alarm\_control\_panel.manual\_mqtt docs][alarm_control_panel.manual_mqtt docs]) (new-platform) * Add component 灯光 TPLink ([@gollo] - [#8643]) ([灯光.tplink docs]) (new-platform) * Velbus ([@thomasdelaet] - [#8076]) ([velbus docs]) ([binary\_sensor.velbus docs][binary_sensor.velbus docs]) ([灯光.velbus docs]) (new-platform) * Add uk\_transport component. ([@robmarkcole] - [#8600]) ([传感器.uk\_transport docs][传感器.uk_transport docs]) (new-platform) ## 发布 0.50.2 - July 31 直接来到 0.50.2。由于上传到 PyPi 时出现错误,我们将 0.50 版本以 0.50.1 的形式发布了。 * Fix TP-Link 灯光 brightness issue #8744. ([@gollo] - [#8755]) * Fix typo in 脚本 错误 ([@n8henrie] - [#8754]) * Fix tradfri 错误 spam ([@MartinHjelmare] - [#8738]) ([灯光.tradfri docs]) * Media Player - Pioneer: Suppress exception if host is not available (fixes #8684) ([@fabaff] - [#8732]) ([媒体播放器.pioneer docs]) * Telegram Bot: Retry set\_webhook up to three times, reduce timeout to 5s again ([@azogue] - [#8716]) ([telegram\_bot.webhooks docs][telegram_bot.webhooks docs]) * Fixed 传感器 issue with Google WiFi routers in bridge mode ([@fronzbot] - [#8710]) ([传感器.google\_wifi docs][传感器.google_wifi docs]) * Fix alexa 卡片 ([@balloob] - [#8708]) ([alexa docs]) * Fix Kodi reconnection after websocket disconnect ([@armills] - [#8704]) ([媒体播放器.kodi docs]) * Move I/O outside of properties for 灯光/tplink platform ([@gollo] - [#8699]) ([灯光.tplink docs]) (new-platform) * Correctly discover GE 风扇 Controllers ([@armills] - [#8682]) ([zwave docs]) * Fix Z-Wave barrier discovery for new API ([@armills] - [#8706]) ([zwave docs]) ([遮盖.zwave docs]) ## 如果你需要帮助…… 欢迎使用我们非常活跃的 [论坛][forum],或加入 [聊天频道][discord] 与我们交流。虽然发布说明也开放评论,但我们更推荐使用前面的沟通渠道。谢谢。 ## 反馈问题 如果你遇到了这个版本引入的问题,请前往我们的 [issue tracker][issue] 提交反馈,并确保填写 issue 模板中的所有字段。 ## 不向后兼容的变更 * 自动化: The 状态 触发器 keyword `state` and the time 触发器 keyword `after` were deprecated in 0.46. They have now been removed. Use `to` and `at` instead. ([@amelchio] - [#8510]) ([自动化.状态 docs]) ([自动化.time docs]) (breaking change) * Wink: the component is no longer supporting the `access_token` in the config. Use the new OAuth 认证 or add your username and 密码 to the config. ([@w1ll1am23] - [#8208]) ([wink docs]) (breaking change) * Alexa/API.AI/Snips.ai/Conversation: configuring responses to intents/sentences has been moved to a new component called `intent_script`. Conversation now allows configuring sentences to map to intents. ([@balloob] - [#8434]) ([alexa docs]) ([intent docs]) ([intent\_script docs][intent_script docs]) ([shopping\_list docs][shopping_list docs]) ([snips docs]) (breaking change) (new-platform) ```yaml alexa: snips: apiai: intent_script: LightKitchen: speech: type: plain text: I did the work, yay. card: type: simple title: Lights Card content: I have turned on the lights. action: service: light.turn_on target: entity_id: light.kitchen conversation: intents: LightKitchen: - The kitchen is magic ``` * 开关 fritzdect: 属性 have been renamed to use underscores and no capital letters ([@thomasklingbeil] - [#8436]) (breaking change) * Yahoo 天气: no longer allow configuring forecasts but include all instead. ([@fanthos] - [#8626]) (breaking change) * The Home Assistant Z-Wave 遮盖 implementation has been updated to support the latest development 版本 of OpenZWave. If you are currently applying a workaround to your OpenZWave 安装 to support the barrier command class, you'll need to make sure you 更新 your workaround to the latest development 版本 of OpenZWave. ([@firstof9] - [#8574]) ([遮盖 docs]) ([遮盖.zwave docs]) (breaking change) ## 全部变更 * Make deps directory persistent over upgrades ([@MartinHjelmare] - [#7801]) * Fix check for running inside venv ([@MartinHjelmare] - [#8481]) * Bump to KNXIP 0.5 ([@open-homeautomation] - [#8492]) ([knx docs]) * Expose all components on hass \[Concept] ([@balloob] - [#8490]) ([灯光 docs]) * Add bind\_hass to components ([@balloob] - [#8502]) * Persistent 通知 import ([@balloob] - [#8507]) * Added additional 属性 to OwnTracks device\_tracker ([@binarybucks] - [#8503]) ([device\_tracker.owntracks docs][device_tracker.owntracks docs]) * Added 传感器 状态 rounding ([@fronzbot] - [#8499]) ([传感器.pi\_hole docs][传感器.pi_hole docs]) * fix for a bug introduced with media support in #8282 ([@MikeChristianson] - [#8513]) ([通知.twitter docs]) * handle timeout 错误 without logging.exception when updating hue 灯光; double quotes in 日志 msgs ([@azogue] - [#8524]) ([灯光.hue docs]) * Remove deprecated 自动化 keywords ([@amelchio] - [#8510]) ([自动化.状态 docs]) ([自动化.time docs]) (breaking change) * Citybikes: Allow None as result for empty slots ([@janLo] - [#8528]) ([传感器.citybikes docs]) * Return a 0 temperature value when none is found ([@phil-lavin] - [#8518]) ([温控.maxcube docs]) * Fix #6469 and #6828 ([@titilambert] - [#8537]) * 更新 docstrings ([@fabaff] - [#8536]) * 升级 TwitterAPI to 2.4.6 ([@fabaff] - [#8535]) ([通知.twitter docs]) * Decora: Fix set brightness and improve reconnection ([@titilambert] - [#8522]) ([灯光.decora docs]) * Initial support for Google WiFi/OnHub ([@fronzbot] - [#8485]) ([传感器.google\_wifi docs][传感器.google_wifi docs]) (new-platform) * Fix exception dlib\_face\_identify when 图像 is not recognized by face\_recognition module ([@tchellomello] - [#8552]) ([image\_processing.dlib\_face\_identify docs][image_processing.dlib_face_identify docs]) * \[media\_extractor] Add support for custom stream queries for media\_extractor ([@minchik] - [#8538]) ([media\_extractor docs][media_extractor docs]) * Report Harmony 遥控器 off if 状态 is unknown ([@jawilson] - [#8547]) ([遥控器.harmony docs]) * 升级 the alarmdecoder dependency library from 0.12.1 to 0.12.3. ([@viswa-swami] - [#8542]) ([alarmdecoder docs]) * turn\_on\_action and turn\_off\_action with 脚本 syntax ([@azogue] - [#8558]) ([媒体播放器.kodi docs]) * Extends Pi-hole 传感器 to support the new 传感器: ([@tchellomello] - [#8549]) ([传感器.pi\_hole docs][传感器.pi_hole docs]) * Support for Wink 开关 and 灯光 groups also fix 风扇 speed selection ([@w1ll1am23] - [#8501]) ([wink docs]) ([风扇.wink docs]) ([灯光.wink docs]) ([开关.wink docs]) * Added a 服务 to write to KNX group addressed including 文档 ([@open-homeautomation] - [#8491]) ([knx docs]) * Handle manual edits to emulated\_hue\_ids.json ([@jawilson] - [#8560]) ([emulated\_hue docs][emulated_hue docs]) * Enhance python\_script to support "*getitem*" ([@sdague] - [#8541]) ([python\_script docs][python_script docs]) * 更新 persistent deps dir 版本 in config.py ([@balloob] - [#8479]) * Xiaomi gw support ([@danielhiversen] - [#8555]) ([xiaomi docs]) ([binary\_sensor.xiaomi docs][binary_sensor.xiaomi docs]) ([遮盖.xiaomi docs]) ([灯光.xiaomi docs]) ([传感器.xiaomi docs]) ([开关.xiaomi docs]) (new-platform) * fix #8263 corrected Adafruit DHT library 版本 from 1.3.0 to 1.3.2 ([@namadori] - [#8562]) ([传感器.dht docs]) * xiaomi bug fix ([@danielhiversen] - [#8576]) ([binary\_sensor.xiaomi docs][binary_sensor.xiaomi docs]) * Bumped python-simplisafe 版本 ([@bachya] - [#8578]) ([alarm\_control\_panel.simplisafe docs][alarm_control_panel.simplisafe docs]) * Added Time Remaining and Time Elapsed 传感器 for octoprint ([@w1ll1am23] - [#8581]) ([传感器.octoprint docs]) * upgade xiaomi lib to 0.2 ([@danielhiversen] - [#8584]) ([xiaomi docs]) * 设备 support for different new 传感器 of the xiaomi aqara gateway ([@syssi] - [#8577]) ([xiaomi docs]) ([binary\_sensor.xiaomi docs][binary_sensor.xiaomi docs]) ([传感器.xiaomi docs]) ([开关.xiaomi docs]) * Extends Fitbit 传感器 to track the 设备 battery level ([@tchellomello] - [#8583]) ([传感器.fitbit docs]) * xiaomi 二元sensor bug fix ([@danielhiversen] - [#8586]) ([binary\_sensor.xiaomi docs][binary_sensor.xiaomi docs]) * 升级 pywebpush and PyJWT ([@perosb] - [#8588]) ([通知.html5 docs]) * Support for Wink oauth application authorization ([@w1ll1am23] - [#8208]) ([wink docs]) (breaking change) * Add Intent component ([@balloob] - [#8434]) ([alexa docs]) ([intent docs]) ([intent\_script docs][intent_script docs]) ([shopping\_list docs][shopping_list docs]) ([snips docs]) (breaking change) (new-platform) * Remove code in wink.py overwriting hass.data configurator ([@w1ll1am23] - [#8595]) ([wink docs]) * bump python-mirobo 版本 for more robust protocol handling, make the platform to 更新 on startup ([@rytilahti] - [#8602]) ([开关.xiaomi\_vacuum docs][开关.xiaomi_vacuum docs]) * 二元sensor ping fixed for hassio ([@gollo] - [#8573]) ([binary\_sensor.ping docs][binary_sensor.ping docs]) * Simplified percent conversion, better logging ([@open-homeautomation] - [#8568]) ([传感器.knx docs]) * make 属性 in the fritzdect module easier to process ([@thomasklingbeil] - [#8436]) (breaking change) * Allow set\_cover\_position in 场景 ([@peckham] - [#8613]) * better but still not great ([@cribbstechnologies] - [#8618]) * 升级 youtube\_dl to 2017.7.23 ([@fabaff] - [#8617]) ([media\_extractor docs][media_extractor docs]) * 升级 mypy to 0.520 ([@fabaff] - [#8616]) * REST 二元sensor value\_template optional ([@philhawthorne] - [#8596]) ([binary\_sensor.rest docs][binary_sensor.rest docs]) * added onvif 摄像头 fix for non-virtual env 安装 ([@matt2005] - [#8592]) ([摄像头.onvif docs]) * Cleanup old device\_tracker stuff ([@pvizeli] - [#8627]) * Add support for using credstash as a secret store ([@justin8] - [#8494]) * Added support for default value when environment variable is missing ([@devspacenine] - [#8484]) * Manual 报警 with MQTT control ([@colinodell] - [#8257]) ([alarm\_control\_panel.manual\_mqtt docs][alarm_control_panel.manual_mqtt docs]) (new-platform) * Catch and 日志 Lyft API 错误 ([@armills] - [#8635]) ([传感器.lyft docs]) * Tweak conversation/intent/shopping list ([@balloob] - [#8636]) ([conversation docs]) ([shopping\_list docs][shopping_list docs]) * 更新 dependencies cast + discovery ([@balloob] - [#8646]) ([媒体播放器.cast docs]) * Add component 灯光 TPLink ([@gollo] - [#8643]) ([灯光.tplink docs]) (new-platform) * Fixes Fitbit 传感器 to report battery level with the expected 设备 ([@tchellomello] - [#8647]) ([传感器.fitbit docs]) * 升级 aiolifx ([@amelchio] - [#8648]) ([灯光.lifx docs]) * Velbus ([@thomasdelaet] - [#8076]) ([velbus docs]) ([binary\_sensor.velbus docs][binary_sensor.velbus docs]) ([灯光.velbus docs]) (new-platform) * Yahoo 天气 更新, supports forecast for more days ([@fanthos] - [#8626]) (breaking change) * History performance improvements for single-实体 requests ([@OverloadUT] - [#8632]) ([history docs]) * Add transition support to 灯光.zha ([@jawilson] - [#8548]) ([灯光.zha docs]) * Add uk\_transport component. ([@robmarkcole] - [#8600]) ([传感器.uk\_transport docs][传感器.uk_transport docs]) (new-platform) * Added support for SerenaHoneycombShades to Lutron Caseta ([@kfcook] - [#8662]) ([遮盖.lutron\_caseta docs][遮盖.lutron_caseta docs]) * MQTT 开关: add availability\_topic for online/offline status ([@abmantis] - [#8593]) ([MQTT docs]) ([开关.MQTT docs]) * Adding support for mapping keys to value in statsd ([@Khabi] - [#8665]) ([statsd docs]) * 升级 fuzzywuzzy to 0.15.1 ([@fabaff] - [#8671]) ([conversation docs]) * 升级 libnacl to 1.5.2 ([@fabaff] - [#8670]) ([device\_tracker.owntracks docs][device_tracker.owntracks docs]) * 升级 sqlalchemy to 1.1.12 ([@fabaff] - [#8669]) ([recorder docs]) * 升级 pyhomematic to 0.1.30 ([@danielperna84] - [#8673]) ([homematic docs]) * Hass.io: logo support / timeout handling ([@pvizeli] - [#8668]) ([hassio docs]) * Updated pysnmp to 4.3.9 ([@bgehrich] - [#8675]) ([device\_tracker.snmp docs][device_tracker.snmp docs]) ([传感器.snmp docs]) * Fix COMMAND\_CLASS\_BARRIER\_OPERATOR for dev branch of OpenZwave ([@firstof9] - [#8574]) ([遮盖 docs]) ([遮盖.zwave docs]) (breaking change) * Shopping List: edit name / complete status ([@balloob] - [#8666]) ([shopping\_list docs][shopping_list docs]) * Support for Wink 本地控制 ([@w1ll1am23] - [#8607]) ([wink docs]) * Persist shopping list + clear completed ([@balloob] - [#8697]) ([shopping\_list docs][shopping_list docs]) [#7801]: https://github.com/home-assistant/home-assistant/pull/7801 [#8076]: https://github.com/home-assistant/home-assistant/pull/8076 [#8208]: https://github.com/home-assistant/home-assistant/pull/8208 [#8257]: https://github.com/home-assistant/home-assistant/pull/8257 [#8434]: https://github.com/home-assistant/home-assistant/pull/8434 [#8436]: https://github.com/home-assistant/home-assistant/pull/8436 [#8479]: https://github.com/home-assistant/home-assistant/pull/8479 [#8481]: https://github.com/home-assistant/home-assistant/pull/8481 [#8484]: https://github.com/home-assistant/home-assistant/pull/8484 [#8485]: https://github.com/home-assistant/home-assistant/pull/8485 [#8490]: https://github.com/home-assistant/home-assistant/pull/8490 [#8491]: https://github.com/home-assistant/home-assistant/pull/8491 [#8492]: https://github.com/home-assistant/home-assistant/pull/8492 [#8494]: https://github.com/home-assistant/home-assistant/pull/8494 [#8499]: https://github.com/home-assistant/home-assistant/pull/8499 [#8501]: https://github.com/home-assistant/home-assistant/pull/8501 [#8502]: https://github.com/home-assistant/home-assistant/pull/8502 [#8503]: https://github.com/home-assistant/home-assistant/pull/8503 [#8507]: https://github.com/home-assistant/home-assistant/pull/8507 [#8510]: https://github.com/home-assistant/home-assistant/pull/8510 [#8513]: https://github.com/home-assistant/home-assistant/pull/8513 [#8518]: https://github.com/home-assistant/home-assistant/pull/8518 [#8522]: https://github.com/home-assistant/home-assistant/pull/8522 [#8524]: https://github.com/home-assistant/home-assistant/pull/8524 [#8528]: https://github.com/home-assistant/home-assistant/pull/8528 [#8535]: https://github.com/home-assistant/home-assistant/pull/8535 [#8536]: https://github.com/home-assistant/home-assistant/pull/8536 [#8537]: https://github.com/home-assistant/home-assistant/pull/8537 [#8538]: https://github.com/home-assistant/home-assistant/pull/8538 [#8541]: https://github.com/home-assistant/home-assistant/pull/8541 [#8542]: https://github.com/home-assistant/home-assistant/pull/8542 [#8547]: https://github.com/home-assistant/home-assistant/pull/8547 [#8548]: https://github.com/home-assistant/home-assistant/pull/8548 [#8549]: https://github.com/home-assistant/home-assistant/pull/8549 [#8552]: https://github.com/home-assistant/home-assistant/pull/8552 [#8555]: https://github.com/home-assistant/home-assistant/pull/8555 [#8558]: https://github.com/home-assistant/home-assistant/pull/8558 [#8560]: https://github.com/home-assistant/home-assistant/pull/8560 [#8562]: https://github.com/home-assistant/home-assistant/pull/8562 [#8568]: https://github.com/home-assistant/home-assistant/pull/8568 [#8573]: https://github.com/home-assistant/home-assistant/pull/8573 [#8574]: https://github.com/home-assistant/home-assistant/pull/8574 [#8576]: https://github.com/home-assistant/home-assistant/pull/8576 [#8577]: https://github.com/home-assistant/home-assistant/pull/8577 [#8578]: https://github.com/home-assistant/home-assistant/pull/8578 [#8581]: https://github.com/home-assistant/home-assistant/pull/8581 [#8583]: https://github.com/home-assistant/home-assistant/pull/8583 [#8584]: https://github.com/home-assistant/home-assistant/pull/8584 [#8586]: https://github.com/home-assistant/home-assistant/pull/8586 [#8588]: https://github.com/home-assistant/home-assistant/pull/8588 [#8592]: https://github.com/home-assistant/home-assistant/pull/8592 [#8593]: https://github.com/home-assistant/home-assistant/pull/8593 [#8595]: https://github.com/home-assistant/home-assistant/pull/8595 [#8596]: https://github.com/home-assistant/home-assistant/pull/8596 [#8600]: https://github.com/home-assistant/home-assistant/pull/8600 [#8602]: https://github.com/home-assistant/home-assistant/pull/8602 [#8607]: https://github.com/home-assistant/home-assistant/pull/8607 [#8613]: https://github.com/home-assistant/home-assistant/pull/8613 [#8616]: https://github.com/home-assistant/home-assistant/pull/8616 [#8617]: https://github.com/home-assistant/home-assistant/pull/8617 [#8618]: https://github.com/home-assistant/home-assistant/pull/8618 [#8626]: https://github.com/home-assistant/home-assistant/pull/8626 [#8627]: https://github.com/home-assistant/home-assistant/pull/8627 [#8632]: https://github.com/home-assistant/home-assistant/pull/8632 [#8635]: https://github.com/home-assistant/home-assistant/pull/8635 [#8636]: https://github.com/home-assistant/home-assistant/pull/8636 [#8643]: https://github.com/home-assistant/home-assistant/pull/8643 [#8646]: https://github.com/home-assistant/home-assistant/pull/8646 [#8647]: https://github.com/home-assistant/home-assistant/pull/8647 [#8648]: https://github.com/home-assistant/home-assistant/pull/8648 [#8662]: https://github.com/home-assistant/home-assistant/pull/8662 [#8665]: https://github.com/home-assistant/home-assistant/pull/8665 [#8666]: https://github.com/home-assistant/home-assistant/pull/8666 [#8668]: https://github.com/home-assistant/home-assistant/pull/8668 [#8669]: https://github.com/home-assistant/home-assistant/pull/8669 [#8670]: https://github.com/home-assistant/home-assistant/pull/8670 [#8671]: https://github.com/home-assistant/home-assistant/pull/8671 [#8673]: https://github.com/home-assistant/home-assistant/pull/8673 [#8675]: https://github.com/home-assistant/home-assistant/pull/8675 [#8697]: https://github.com/home-assistant/home-assistant/pull/8697 [@kfcook]: https://github.com/kfcook [@Khabi]: https://github.com/Khabi [@MartinHjelmare]: https://github.com/MartinHjelmare [@MikeChristianson]: https://github.com/MikeChristianson [@OverloadUT]: https://github.com/OverloadUT [@abmantis]: https://github.com/abmantis [@amelchio]: https://github.com/amelchio [@armills]: https://github.com/armills [@azogue]: https://github.com/azogue [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@bgehrich]: https://github.com/bgehrich [@binarybucks]: https://github.com/binarybucks [@colinodell]: https://github.com/colinodell [@cribbstechnologies]: https://github.com/cribbstechnologies [@danielhiversen]: https://github.com/danielhiversen [@danielperna84]: https://github.com/danielperna84 [@devspacenine]: https://github.com/devspacenine [@fabaff]: https://github.com/fabaff [@fanthos]: https://github.com/fanthos [@firstof9]: https://github.com/firstof9 [@fronzbot]: https://github.com/fronzbot [@gollo]: https://github.com/gollo [@janLo]: https://github.com/janLo [@jawilson]: https://github.com/jawilson [@justin8]: https://github.com/justin8 [@matt2005]: https://github.com/matt2005 [@minchik]: https://github.com/minchik [@namadori]: https://github.com/namadori [@open-homeautomation]: https://github.com/open-homeautomation [@peckham]: https://github.com/peckham [@perosb]: https://github.com/perosb [@phil-lavin]: https://github.com/phil-lavin [@philhawthorne]: https://github.com/philhawthorne [@pvizeli]: https://github.com/pvizeli [@robmarkcole]: https://github.com/robmarkcole [@rytilahti]: https://github.com/rytilahti [@sdague]: https://github.com/sdague [@syssi]: https://github.com/syssi [@tchellomello]: https://github.com/tchellomello [@thomasdelaet]: https://github.com/thomasdelaet [@thomasklingbeil]: https://github.com/thomasklingbeil [@titilambert]: https://github.com/titilambert [@viswa-swami]: https://github.com/viswa-swami [@w1ll1am23]: https://github.com/w1ll1am23 [alarm_control_panel.manual_mqtt docs]: /integrations/manual_mqtt/ [alarm_control_panel.simplisafe docs]: /integrations/simplisafe [alarmdecoder docs]: /integrations/alarmdecoder/ [alexa docs]: /integrations/alexa/ [自动化.状态 docs]: /docs/自动化/触发器/#状态-触发器 [自动化.time docs]: /docs/自动化/触发器/#time-触发器 [binary_sensor.ping docs]: /integrations/ping#binary-传感器 [binary_sensor.rest docs]: /integrations/binary_sensor.rest/ [binary_sensor.velbus docs]: /integrations/velbus [binary_sensor.xiaomi docs]: /integrations/binary_sensor.xiaomi_aqara/ [摄像头.onvif docs]: /integrations/onvif [温控.maxcube docs]: /integrations/maxcube [conversation docs]: /integrations/conversation/ [遮盖 docs]: /integrations/遮盖/ [遮盖.lutron_caseta docs]: /integrations/lutron_caseta/ [遮盖.xiaomi docs]: /integrations/遮盖.xiaomi_aqara/ [遮盖.zwave docs]: /integrations/zwave#遮盖 [device_tracker.owntracks docs]: /integrations/owntracks [device_tracker.snmp docs]: /integrations/snmp [emulated_hue docs]: /integrations/emulated_hue/ [风扇.wink docs]: /integrations/wink#风扇 [hassio docs]: /hassio/ [history docs]: /integrations/history/ [homematic docs]: /integrations/homematic/ [image_processing.dlib_face_identify docs]: /integrations/dlib_face_identify [intent docs]: /developers/intent/ [intent_script docs]: /integrations/intent_script/ [knx docs]: /integrations/knx/ [灯光 docs]: /integrations/灯光/ [灯光.decora docs]: /integrations/decora [灯光.hue docs]: /integrations/hue [灯光.lifx docs]: /integrations/lifx [灯光.tplink docs]: /integrations/tplink [灯光.velbus docs]: /integrations/velbus/ [灯光.wink docs]: /integrations/wink#灯光 [灯光.xiaomi docs]: /integrations/灯光.xiaomi_aqara/ [灯光.zha docs]: /integrations/zha [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.cast docs]: /integrations/cast [媒体播放器.kodi docs]: /integrations/kodi [MQTT docs]: /integrations/MQTT/ [通知.html5 docs]: /integrations/html5 [通知.twitter docs]: /integrations/twitter [python_script docs]: /integrations/python_script/ [recorder docs]: /integrations/recorder/ [遥控器.harmony docs]: /integrations/harmony [传感器.citybikes docs]: /integrations/citybikes [传感器.dht docs]: /integrations/dht [传感器.fitbit docs]: /integrations/fitbit [传感器.google_wifi docs]: /integrations/google_wifi [传感器.knx docs]: /integrations/传感器.knx/ [传感器.lyft docs]: /integrations/lyft [传感器.octoprint docs]: /integrations/octoprint#传感器 [传感器.pi_hole docs]: /integrations/pi_hole [传感器.snmp docs]: /integrations/snmp#传感器 [传感器.uk_transport docs]: /integrations/uk_transport [传感器.xiaomi docs]: /integrations/传感器.xiaomi_aqara/ [shopping_list docs]: /integrations/shopping_list/ [snips docs]: /integrations/snips/ [statsd docs]: /integrations/statsd/ [开关.MQTT docs]: /integrations/开关.MQTT/ [开关.wink docs]: /integrations/wink#开关 [开关.xiaomi docs]: /integrations/开关.xiaomi_aqara/ [开关.xiaomi_vacuum docs]: /integrations/吸尘器.xiaomi_miio/ [velbus docs]: /integrations/velbus/ [wink docs]: /integrations/wink/ [xiaomi docs]: /integrations/xiaomi_aqara [forum]: https://community.home-assistant.io/ [issue]: https://github.com/home-assistant/home-assistant/issues [discord]: https://discord.gg/c5DvZ4e [#8682]: https://github.com/home-assistant/home-assistant/pull/8682 [#8699]: https://github.com/home-assistant/home-assistant/pull/8699 [#8704]: https://github.com/home-assistant/home-assistant/pull/8704 [#8706]: https://github.com/home-assistant/home-assistant/pull/8706 [#8708]: https://github.com/home-assistant/home-assistant/pull/8708 [#8710]: https://github.com/home-assistant/home-assistant/pull/8710 [#8716]: https://github.com/home-assistant/home-assistant/pull/8716 [#8732]: https://github.com/home-assistant/home-assistant/pull/8732 [#8738]: https://github.com/home-assistant/home-assistant/pull/8738 [#8754]: https://github.com/home-assistant/home-assistant/pull/8754 [#8755]: https://github.com/home-assistant/home-assistant/pull/8755 [@n8henrie]: https://github.com/n8henrie [灯光.tradfri docs]: /integrations/tradfri [媒体播放器.pioneer docs]: /integrations/pioneer [telegram_bot.webhooks docs]: /integrations/telegram_webhooks [zwave docs]: /integrations/zwave/ --- url: /home-assistant/blog/2017-08-01-hasspodcast-ep-5.md --- # Home Assistant Podcast #5 We 遮盖 off AppDaemon/HADashboard and all the fun stuff introduced in 0.49 and 0.50. Show notes available on the [Home Assistant Podcast Website](https://hasspodcast.io/ha005/) [Listen online][episode] [episode]: https://hasspodcast.io/ha005/ --- url: /home-assistant/blog/2017-08-12-release-51.md --- # 0.51: History 大幅提速、自动化编辑器完成、官方吸尘器支持 :::important 这个版本需要执行一次性数据库迁移,对于大型数据库可能会耗费较长时间(约 20 分钟)。在此期间前端将无法使用。迁移过程中请不要停止 Home Assistant。 ::: 0.51 版本已经到来,其中包含不少非常棒的更新。 ## 数据库提速 首先是 [@OverloadUT] 在 [#8748] 中带来的惊人数据库优化。所有经过测试的查询都能在 1 秒内完成,即使是在使用 MySQL、拥有 600 万行数据和约 300 个实体的树莓派上也是如此。哪怕你查询的是一个大得不太现实的时间范围,也依旧如此! 启动 Home Assistant 时,数据库升级会花费一些时间。在此期间,Home Assistant 前端将无法访问。请耐心等待其完成,不要关闭 Home Assistant。 ## 前端更新 我们已经完成了前端迁移,现在它由 Polymer 2 驱动。这不仅让 Safari/iOS 设备上的速度大幅提升,也修复了大量问题。 我们也完成了自动化编辑器。现在所有触发器与动作都已实现,大多数条件也已支持(目前还缺少 `and`、`or`)。此外,自动化编辑器不再只支持 Chrome,现在在 Safari 中也可以使用。 前端的另一个变化是我们重新组织了面板。Z-Wave 与自动化配置面板已经合并进统一的配置面板中。
## 吸尘器 随着越来越多的吸尘器加入 Home Assistant,是时候为它们建立一个官方组件了。因此 [@azogue] 在 [#8623] 中引入了新的吸尘器组件。这让吸尘器在 Home Assistant 中拥有了一等公民级别的集成支持。开箱即可支持 Dyson、Xiamo 和 Roomba 平台。 ## 新平台 * Added Lutron Caseta 场景 Support ([@kfcook] - [#8690]) ([lutron\_caseta docs][lutron_caseta docs]) ([场景.lutron\_caseta docs][场景.lutron_caseta docs]) (new-platform) * New 媒体播放器 platform for Russound 设备 using the RIO protocol ([@wickerwaka] - [#8448]) ([媒体播放器.russound\_rio docs][媒体播放器.russound_rio docs]) (new-platform) * New component: bluesound ([@thrawnarn] - [#7192]) ([媒体播放器.bluesound docs]) (new-platform) * Add mochad 灯光 component ([@mtreinish] - [#8476]) ([灯光.mochad docs]) (new-platform) * geizhals 传感器 component ([@JulianKahnert] - [#8458]) ([传感器.geizhals docs]) (new-platform) * Xiaomi 吸尘器 as platform of new `vacuum` component derived from ToggleEntity, and 服务 ([@azogue] - [#8623]) (breaking change) (new-platform) * Wi-Fi enabled Roomba support ([@pschmitt] - [#8825]) ([吸尘器.roomba docs]) (new-platform) * Add support to Dyson 360 Eye robot 吸尘器 using new 吸尘器 platform ([@CharlesBlonde] - [#8852]) ([dyson docs]) ([吸尘器 docs]) ([风扇.dyson docs]) ([传感器.dyson docs]) ([吸尘器.dyson docs]) (new-platform) * Add Initial Mailbox 面板 and 传感器 ([@PhracturedBlue] - [#8233]) ([asterisk\_mbox docs][asterisk_mbox docs]) (new-platform) * Add Leviton Decora Smart WiFi 设备 Platform ([@tlyakhov] - [#8529]) ([灯光.decora\_wifi docs][灯光.decora_wifi docs]) (new-platform) * Add RainMachine 开关 platform ([@bachya] - [#8827]) ([开关.rainmachine docs]) (new-platform) * Add new 设备 tracker for Huawei Routers. ([@abmantis] - [#8488]) ([device\_tracker.huawei\_router docs][device_tracker.huawei_router docs]) (new-platform) * Add Shodan 传感器 ([@fabaff] - [#8902]) ([传感器.shodan docs]) (new-platform) ## 发布 0.51.1 - August 12 * Fixed a bug in the 自动化 editor that would break if no 条件 available in the config file. ([@balloob]) ## 发布 0.51.2 - August 14 * Fix zwave power\_consumption 属性 ([@andrey-git] - [#8968]) ([zwave docs]) * Turn foscam verbose mode off ([@andrey-git] - [#8967]) ([摄像头.foscam docs]) * fix stack trace in pushbullet ([@Danielhiversen] - [#8965]) ([通知.pushbullet docs]) * Harmoney 遥控器: Fix call to ha\_send\_commands ([@MartinHjelmare] - [#8956]) ([遥控器.harmony docs]) * fix DeviceException handling when updating xiaomi 吸尘器 ([@azogue] - [#8954]) ([吸尘器.xiaomi docs]) * Sabnzbd: do not assume discovery info is a dict ([@balloob] - [#8951]) ([传感器.sabnzbd docs]) * Fix login 按钮 ([@balloob]) * Add workaround for broken toggles in Safari ([@balloob]) * Fix weblink opening twice ([@azogue]) ## 如果你需要帮助…… 欢迎使用我们非常活跃的 [论坛][forum],或加入 [聊天频道][discord] 与我们交流。虽然发布说明也开放评论,但我们更推荐使用前面的沟通渠道。谢谢。 ## 反馈问题 如果你遇到了这个版本引入的问题,请前往我们的 [issue tracker][issue] 提交反馈,并确保填写 issue 模板中的所有字段。 ## 不向后兼容的变更 * Efergy 传感器: change units from KW to W ([@emlt] - [#8761]) ([传感器.efergy docs]) (breaking change) * Xiaomi 吸尘器 is now a platform of new `vacuum` component derived from ToggleEntity, and 服务 ([@azogue] - [#8623]) (breaking change) (new-platform) ```yaml vacuum: - platform: xiaomi name: Vacuum cleaner host: !secret xiaomi_vacuum_robot_ip token: !secret xiaomi_vacuum_robot_token ``` ## 全部变更 * 升级 pushbullet.py to 0.11.0 ([@fabaff] - [#8691]) ([通知.pushbullet docs]) * 升级 mypy to 0.521 ([@fabaff] - [#8692]) * Added Lutron Caseta 场景 Support ([@kfcook] - [#8690]) ([lutron\_caseta docs][lutron_caseta docs]) ([场景.lutron\_caseta docs][场景.lutron_caseta docs]) (new-platform) * Remove deprecated host and ssl logic from Kodi ([@armills] - [#8700]) ([媒体播放器.kodi docs]) * Remove deprecated substitute interfaces ([@armills] - [#8701]) ([binary\_sensor docs][binary_sensor docs]) ([媒体播放器 docs]) * Remove deprecated sensor\_class config options ([@armills] - [#8702]) * directv: add 配置 glue for Genie slaves ([@sielicki] - [#8713]) ([媒体播放器.directv docs]) * bump python-telegram-bot to 7.0.1 for fully support Bot API 3.2 ([@azogue] - [#8715]) ([telegram\_bot docs][telegram_bot docs]) * Add proxy support for telegram\_bot ([@azogue] - [#8717]) ([telegram\_bot docs][telegram_bot docs]) * python-insteonplm module 版本 bump ([@nugget] - [#8736]) ([insteon\_plm docs][insteon_plm docs]) * New 媒体播放器 platform for Russound 设备 using the RIO protocol ([@wickerwaka] - [#8448]) ([媒体播放器.russound\_rio docs][媒体播放器.russound_rio docs]) (new-platform) * Add 切换 to 遥控器 ([@alanfischer] - [#8483]) ([遥控器 docs]) ([遥控器.apple\_tv docs][遥控器.apple_tv docs]) ([遥控器.harmony docs]) ([遥控器.itach docs]) * added invert\_state optional parameter ([@gwhiteCL] - [#8695]) ([遮盖.rpi\_gpio docs][遮盖.rpi_gpio docs]) * buienradar dates tz-aware ([@mjj4791] - [#8767]) ([传感器.buienradar docs]) ([天气.buienradar docs]) * Change units from KW to W ([@emlt] - [#8761]) ([传感器.efergy docs]) (breaking change) * Clean up 遥控器 component ([@MartinHjelmare] - [#8728]) ([遥控器 docs]) ([遥控器.apple\_tv docs][遥控器.apple_tv docs]) ([遥控器.harmony docs]) ([遥控器.itach docs]) ([遥控器.kira docs]) * Wink discovery ([@w1ll1am23] - [#8739]) ([wink docs]) * Enable/Disable Motion detection for Foscam 摄像头 ([@viswa-swami] - [#8582]) ([摄像头.foscam docs]) * Allow sonos to select playlists as a source ([@mcolyer] - [#8258]) ([媒体播放器.sonos docs]) * mpd improvements ([@StevenLooman] - [#8655]) ([媒体播放器.mpd docs]) * Add support for file attachments in pushbullet ([@tsvi] - [#8763]) ([通知.pushbullet docs]) * Honeywell fixes and improvements ([@dansarginson] - [#8756]) ([温控.honeywell docs]) * Catch exception (fixes #8724) ([@fabaff] - [#8731]) ([传感器.google\_wifi docs][传感器.google_wifi docs]) * use updated osram lightify 1.0.6 component, including bugfix allowing more than 27 设备 ([@tfriedel] - [#8774]) ([灯光.osramlightify docs]) * flux\_led: support for property "available" ([@pezinek] - [#8764]) ([灯光.flux\_led docs][灯光.flux_led docs]) * New component: bluesound ([@thrawnarn] - [#7192]) ([媒体播放器.bluesound docs]) (new-platform) * Add 'forecast' ability to yr 天气 传感器 ([@tinloaf] - [#8650]) * Feature alexa launch request ([@steverhoades] - [#8730]) ([alexa docs]) * Fixes UnboundLocalError: local variable 'setting' referenced before assignment ([@syssi] - [#8782]) ([温控.tado docs]) * 升级 pyasn1 to 0.3.1 and pyasn1-modules to 0.0.10 ([@fabaff] - [#8787]) ([通知.xmpp docs]) * 升级 sphinx-autodoc-typehints to 1.2.1 ([@fabaff] - [#8783]) * Improvements (配置 and validation) ([@fabaff] - [#8785]) * Fix referencing unset variable in tado 温控 component (causes 更新 to fail when tado 区域 is in manual mode) ([@luukd] - [#8723]) ([温控.tado docs]) * MQTT 开关: add voluptuous for availability topic ([@abmantis] - [#8797]) ([开关.MQTT docs]) * Add mochad 灯光 component ([@mtreinish] - [#8476]) ([灯光.mochad docs]) (new-platform) * 更新 numpy 1.13.1 ([@pvizeli] - [#8806]) ([image\_processing.opencv docs][image_processing.opencv docs]) * 升级 aiohttp to 2.2.4 ([@fabaff] - [#8805]) * Catch divide by zero 错误 when a sleep type is 0 ([@mezz64] - [#8809]) ([传感器.eight\_sleep docs][传感器.eight_sleep docs]) * InfluxDB component improvements ([@haimgel] - [#8633]) ([influxdb docs]) * When Sonos gets a tts source - dont't show an 图像 ([@andrey-git] - [#8777]) ([媒体播放器.sonos docs]) * Polymer 2 ([@balloob] - [#8815]) ([group docs]) * geizhals 传感器 component ([@JulianKahnert] - [#8458]) ([传感器.geizhals docs]) (new-platform) * Xiaomi 吸尘器 as platform of new `vacuum` component derived from ToggleEntity, and 服务 ([@azogue] - [#8623]) (breaking change) (new-platform) * 更新 yweather.py ([@fanthos] - [#8820]) * Make HA discover sabnzbd and add it to the Configurator ([@Hellowlol] - [#8634]) ([传感器.sabnzbd docs]) * Fix Dyson 传感器 if 设备 are configured without standby monitoring. Fixes #8569 ([@CharlesBlonde] - [#8826]) ([dyson docs]) ([风扇.dyson docs]) ([传感器.dyson docs]) * Block dependencies that depend on enum34 ([@balloob] - [#8698]) * 升级 aiohttp to 2.2.5 ([@fabaff] - [#8828]) * History query and schema optimizations for huge performance boost ([@OverloadUT] - [#8748]) ([history docs]) (breaking change) * 更新 xiaomi 吸尘器 tests and include in coverage ([@azogue] - [#8845]) ([吸尘器 docs]) ([吸尘器.xiaomi docs]) * Egardia ([@jeroenterheerdt] - [#8389]) * Do not call 更新() in constructor. ([@fabaff] - [#8837]) ([传感器.systemmonitor docs]) * 升级 sendgrid to 4.2.1 ([@fabaff] - [#8839]) * Do not call 更新() in constructor ([@fabaff] - [#8840]) ([传感器.vasttrafik docs]) * Make 'monitored\_conditions' optional ([@fabaff] - [#8843]) ([传感器.radarr docs]) * Do not call 更新() in constructor ([@fabaff] - [#8849]) ([传感器.synologydsm docs]) * Make 'monitored\_conditions' optional ([@fabaff] - [#8848]) ([传感器.sonarr docs]) * Do not call 更新() in constructor ([@fabaff] - [#8847]) ([传感器.pocketcasts docs]) * Catch ConnectionRefusedError ([@fabaff] - [#8844]) ([传感器.supervisord docs]) * 升级 sqlalchemy to 1.1.13 ([@fabaff] - [#8850]) ([recorder docs]) * 升级 pylast to 1.9.0 ([@fabaff] - [#8854]) ([传感器.lastfm docs]) * Wi-Fi enabled Roomba support ([@pschmitt] - [#8825]) ([吸尘器.roomba docs]) (new-platform) * Add support to Dyson 360 Eye robot 吸尘器 using new 吸尘器 platform ([@CharlesBlonde] - [#8852]) ([dyson docs]) ([吸尘器 docs]) ([风扇.dyson docs]) ([传感器.dyson docs]) ([吸尘器.dyson docs]) (new-platform) * 升级 pyasn1 to 0.3.2 and pyasn1-modules to 0.0.11 ([@fabaff] - [#8856]) ([通知.xmpp docs]) * Allow to set coordinates ([@fabaff] - [#8858]) ([传感器.zamg docs]) ([天气.zamg docs]) * Added rounding to Google WiFi ([@fronzbot] - [#8866]) ([传感器.google\_wifi docs][传感器.google_wifi docs]) * Fix off\_delay for zwave 触发器 传感器 ([@turbokongen] - [#8864]) ([zwave docs]) ([binary\_sensor.zwave docs][binary_sensor.zwave docs]) * Do not use pychromecast.Chromecast for Cast Groups ([@foxel] - [#8786]) ([媒体播放器.cast docs]) * Allow get local ip to work without internet ([@balloob] - [#8855]) * Do not call 更新() in constructor ([@fabaff] - [#8859]) * Add new 服务 `clean_spot` to 吸尘器 ([@azogue] - [#8862]) ([吸尘器 docs]) ([吸尘器.xiaomi docs]) * Warn instead of raise on duplicate YAML key ([@balloob] - [#8834]) * Add Initial Mailbox 面板 and 传感器 ([@PhracturedBlue] - [#8233]) ([asterisk\_mbox docs][asterisk_mbox docs]) (new-platform) * Add Leviton Decora Smart WiFi 设备 Platform ([@tlyakhov] - [#8529]) ([灯光.decora\_wifi docs][灯光.decora_wifi docs]) (new-platform) * Consolidate config 面板 ([@balloob] - [#8857]) ([自动化 docs]) ([zwave docs]) * Fix spelling 错误 and 更新 link ([@Klikini] - [#8869]) * Implement Roomba 风扇 speed ([@pschmitt] - [#8863]) ([吸尘器.roomba docs]) * Add nuki 门锁'n'go and unlatch 服务 and add 属性 ([@pschmitt] - [#8687]) ([门锁.nuki docs]) * RFLink: Add send\_command 服务 ([@leppa] - [#8876]) ([rflink docs]) * Do not call 更新() in constructor ([@fabaff] - [#8881]) ([binary\_sensor.rest docs][binary_sensor.rest docs]) ([传感器.rest docs]) * Add RainMachine 开关 platform ([@bachya] - [#8827]) ([开关.rainmachine docs]) (new-platform) * Allow usage of colorlog 3.0.1 ([@fabaff] - [#8885]) * Change level ([@fabaff] - [#8883]) ([传感器.statistics docs]) * 升级 youtube\_dl to 2017.8.6 ([@fabaff] - [#8880]) ([media\_extractor docs][media_extractor docs]) * Fix media\_extractor for some sites ([@AlexxIT] - [#8887]) ([media\_extractor docs][media_extractor docs]) * Do not call 更新() in constructor ([@fabaff] - [#8878]) * Do not call 更新() in constructor ([@fabaff] - [#8892]) ([binary\_sensor.command\_line docs][binary_sensor.command_line docs]) ([传感器.command\_line docs][传感器.command_line docs]) ([开关.command\_line docs][开关.command_line docs]) * Changed Pi-hole graphs from stacked bar to line ([@bachya] - [#8896]) ([传感器.pi\_hole docs][传感器.pi_hole docs]) * Add longer text strings to mailbox demo to test string truncation ([@PhracturedBlue] - [#8893]) ([mailbox.demo docs]) ([mailbox.demo.txt docs]) * added support for setting/getting position of lutron caseta 遮盖 ([@kfcook] - [#8898]) ([遮盖.lutron\_caseta docs][遮盖.lutron_caseta docs]) * Fix for Neato D3 Connected 状态 obtaining ([@karlkar] - [#8817]) ([传感器.neato docs]) ([开关.neato docs]) * 更新 simplisafe-python 版本 ([@w1ll1am23] - [#8908]) ([alarm\_control\_panel.simplisafe docs][alarm_control_panel.simplisafe docs]) * LIFX: improve performance of multi-灯光 transitions ([@amelchio] - [#8873]) ([灯光.lifx docs]) * Support media position and media duration (will display progressbar in ui) ([@molobrakos] - [#8904]) ([媒体播放器.squeezebox docs]) * Add new 设备 tracker for Huawei Routers. ([@abmantis] - [#8488]) ([device\_tracker.huawei\_router docs][device_tracker.huawei_router docs]) (new-platform) * Add Shodan 传感器 ([@fabaff] - [#8902]) ([传感器.shodan docs]) (new-platform) * Added possibilities to use 模板 in the command\_line 传感器 ([@mar-schmidt] - [#8505]) ([传感器.command\_line docs][传感器.command_line docs]) * Honor PEP8 naming convention ([@fabaff] - [#8909]) ([updater docs]) * Remove not needed call to 更新 ([@MartinHjelmare] - [#8930]) ([开关.rachio docs]) * fixing emulated hue issue and testing it ([@cribbstechnologies] - [#8928]) ([emulated\_hue docs][emulated_hue docs]) * 更新 roombapy to 1.3.1 to avoid installing all the mapping dependencies ([@pschmitt] - [#8925]) ([吸尘器.roomba docs]) * 更新 python-wink 版本 to fix Dome water valve bug. ([@w1ll1am23] - [#8923]) ([wink docs]) ([开关.wink docs]) * Fix SET\_TEMPERATURE\_SCHEMA in 温控 component ([@MartinHjelmare] - [#8879]) ([温控 docs]) [#7192]: https://github.com/home-assistant/home-assistant/pull/7192 [#8233]: https://github.com/home-assistant/home-assistant/pull/8233 [#8258]: https://github.com/home-assistant/home-assistant/pull/8258 [#8389]: https://github.com/home-assistant/home-assistant/pull/8389 [#8448]: https://github.com/home-assistant/home-assistant/pull/8448 [#8458]: https://github.com/home-assistant/home-assistant/pull/8458 [#8476]: https://github.com/home-assistant/home-assistant/pull/8476 [#8483]: https://github.com/home-assistant/home-assistant/pull/8483 [#8488]: https://github.com/home-assistant/home-assistant/pull/8488 [#8505]: https://github.com/home-assistant/home-assistant/pull/8505 [#8529]: https://github.com/home-assistant/home-assistant/pull/8529 [#8582]: https://github.com/home-assistant/home-assistant/pull/8582 [#8623]: https://github.com/home-assistant/home-assistant/pull/8623 [#8633]: https://github.com/home-assistant/home-assistant/pull/8633 [#8634]: https://github.com/home-assistant/home-assistant/pull/8634 [#8650]: https://github.com/home-assistant/home-assistant/pull/8650 [#8655]: https://github.com/home-assistant/home-assistant/pull/8655 [#8687]: https://github.com/home-assistant/home-assistant/pull/8687 [#8690]: https://github.com/home-assistant/home-assistant/pull/8690 [#8691]: https://github.com/home-assistant/home-assistant/pull/8691 [#8692]: https://github.com/home-assistant/home-assistant/pull/8692 [#8695]: https://github.com/home-assistant/home-assistant/pull/8695 [#8698]: https://github.com/home-assistant/home-assistant/pull/8698 [#8700]: https://github.com/home-assistant/home-assistant/pull/8700 [#8701]: https://github.com/home-assistant/home-assistant/pull/8701 [#8702]: https://github.com/home-assistant/home-assistant/pull/8702 [#8713]: https://github.com/home-assistant/home-assistant/pull/8713 [#8715]: https://github.com/home-assistant/home-assistant/pull/8715 [#8717]: https://github.com/home-assistant/home-assistant/pull/8717 [#8723]: https://github.com/home-assistant/home-assistant/pull/8723 [#8728]: https://github.com/home-assistant/home-assistant/pull/8728 [#8730]: https://github.com/home-assistant/home-assistant/pull/8730 [#8731]: https://github.com/home-assistant/home-assistant/pull/8731 [#8736]: https://github.com/home-assistant/home-assistant/pull/8736 [#8739]: https://github.com/home-assistant/home-assistant/pull/8739 [#8748]: https://github.com/home-assistant/home-assistant/pull/8748 [#8756]: https://github.com/home-assistant/home-assistant/pull/8756 [#8761]: https://github.com/home-assistant/home-assistant/pull/8761 [#8763]: https://github.com/home-assistant/home-assistant/pull/8763 [#8764]: https://github.com/home-assistant/home-assistant/pull/8764 [#8767]: https://github.com/home-assistant/home-assistant/pull/8767 [#8774]: https://github.com/home-assistant/home-assistant/pull/8774 [#8777]: https://github.com/home-assistant/home-assistant/pull/8777 [#8782]: https://github.com/home-assistant/home-assistant/pull/8782 [#8783]: https://github.com/home-assistant/home-assistant/pull/8783 [#8785]: https://github.com/home-assistant/home-assistant/pull/8785 [#8786]: https://github.com/home-assistant/home-assistant/pull/8786 [#8787]: https://github.com/home-assistant/home-assistant/pull/8787 [#8797]: https://github.com/home-assistant/home-assistant/pull/8797 [#8805]: https://github.com/home-assistant/home-assistant/pull/8805 [#8806]: https://github.com/home-assistant/home-assistant/pull/8806 [#8809]: https://github.com/home-assistant/home-assistant/pull/8809 [#8815]: https://github.com/home-assistant/home-assistant/pull/8815 [#8817]: https://github.com/home-assistant/home-assistant/pull/8817 [#8820]: https://github.com/home-assistant/home-assistant/pull/8820 [#8825]: https://github.com/home-assistant/home-assistant/pull/8825 [#8826]: https://github.com/home-assistant/home-assistant/pull/8826 [#8827]: https://github.com/home-assistant/home-assistant/pull/8827 [#8828]: https://github.com/home-assistant/home-assistant/pull/8828 [#8834]: https://github.com/home-assistant/home-assistant/pull/8834 [#8837]: https://github.com/home-assistant/home-assistant/pull/8837 [#8839]: https://github.com/home-assistant/home-assistant/pull/8839 [#8840]: https://github.com/home-assistant/home-assistant/pull/8840 [#8843]: https://github.com/home-assistant/home-assistant/pull/8843 [#8844]: https://github.com/home-assistant/home-assistant/pull/8844 [#8845]: https://github.com/home-assistant/home-assistant/pull/8845 [#8847]: https://github.com/home-assistant/home-assistant/pull/8847 [#8848]: https://github.com/home-assistant/home-assistant/pull/8848 [#8849]: https://github.com/home-assistant/home-assistant/pull/8849 [#8850]: https://github.com/home-assistant/home-assistant/pull/8850 [#8852]: https://github.com/home-assistant/home-assistant/pull/8852 [#8854]: https://github.com/home-assistant/home-assistant/pull/8854 [#8855]: https://github.com/home-assistant/home-assistant/pull/8855 [#8856]: https://github.com/home-assistant/home-assistant/pull/8856 [#8857]: https://github.com/home-assistant/home-assistant/pull/8857 [#8858]: https://github.com/home-assistant/home-assistant/pull/8858 [#8859]: https://github.com/home-assistant/home-assistant/pull/8859 [#8862]: https://github.com/home-assistant/home-assistant/pull/8862 [#8863]: https://github.com/home-assistant/home-assistant/pull/8863 [#8864]: https://github.com/home-assistant/home-assistant/pull/8864 [#8866]: https://github.com/home-assistant/home-assistant/pull/8866 [#8869]: https://github.com/home-assistant/home-assistant/pull/8869 [#8873]: https://github.com/home-assistant/home-assistant/pull/8873 [#8876]: https://github.com/home-assistant/home-assistant/pull/8876 [#8878]: https://github.com/home-assistant/home-assistant/pull/8878 [#8879]: https://github.com/home-assistant/home-assistant/pull/8879 [#8880]: https://github.com/home-assistant/home-assistant/pull/8880 [#8881]: https://github.com/home-assistant/home-assistant/pull/8881 [#8883]: https://github.com/home-assistant/home-assistant/pull/8883 [#8885]: https://github.com/home-assistant/home-assistant/pull/8885 [#8887]: https://github.com/home-assistant/home-assistant/pull/8887 [#8892]: https://github.com/home-assistant/home-assistant/pull/8892 [#8893]: https://github.com/home-assistant/home-assistant/pull/8893 [#8896]: https://github.com/home-assistant/home-assistant/pull/8896 [#8898]: https://github.com/home-assistant/home-assistant/pull/8898 [#8902]: https://github.com/home-assistant/home-assistant/pull/8902 [#8904]: https://github.com/home-assistant/home-assistant/pull/8904 [#8908]: https://github.com/home-assistant/home-assistant/pull/8908 [#8909]: https://github.com/home-assistant/home-assistant/pull/8909 [#8923]: https://github.com/home-assistant/home-assistant/pull/8923 [#8925]: https://github.com/home-assistant/home-assistant/pull/8925 [#8928]: https://github.com/home-assistant/home-assistant/pull/8928 [#8930]: https://github.com/home-assistant/home-assistant/pull/8930 [@kfcook]: https://github.com/kfcook [@CharlesBlonde]: https://github.com/CharlesBlonde [@Hellowlol]: https://github.com/Hellowlol [@JulianKahnert]: https://github.com/JulianKahnert [@Klikini]: https://github.com/Klikini [@MartinHjelmare]: https://github.com/MartinHjelmare [@OverloadUT]: https://github.com/OverloadUT [@PhracturedBlue]: https://github.com/PhracturedBlue [@AlexxIT]: https://github.com/AlexxIT [@StevenLooman]: https://github.com/StevenLooman [@abmantis]: https://github.com/abmantis [@alanfischer]: https://github.com/alanfischer [@amelchio]: https://github.com/amelchio [@andrey-git]: https://github.com/andrey-git [@armills]: https://github.com/armills [@azogue]: https://github.com/azogue [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@cribbstechnologies]: https://github.com/cribbstechnologies [@dansarginson]: https://github.com/dansarginson [@emlt]: https://github.com/emlt [@fabaff]: https://github.com/fabaff [@fanthos]: https://github.com/fanthos [@foxel]: https://github.com/foxel [@fronzbot]: https://github.com/fronzbot [@gwhiteCL]: https://github.com/gwhiteCL [@haimgel]: https://github.com/haimgel [@jeroenterheerdt]: https://github.com/jeroenterheerdt [@karlkar]: https://github.com/karlkar [@leppa]: https://github.com/leppa [@luukd]: https://github.com/luukd [@mar-schmidt]: https://github.com/mar-schmidt [@mcolyer]: https://github.com/mcolyer [@mezz64]: https://github.com/mezz64 [@mjj4791]: https://github.com/mjj4791 [@molobrakos]: https://github.com/molobrakos [@mtreinish]: https://github.com/mtreinish [@nugget]: https://github.com/nugget [@pezinek]: https://github.com/pezinek [@pschmitt]: https://github.com/pschmitt [@pvizeli]: https://github.com/pvizeli [@sielicki]: https://github.com/sielicki [@steverhoades]: https://github.com/steverhoades [@syssi]: https://github.com/syssi [@tfriedel]: https://github.com/tfriedel [@thrawnarn]: https://github.com/thrawnarn [@tinloaf]: https://github.com/tinloaf [@tlyakhov]: https://github.com/tlyakhov [@tsvi]: https://github.com/tsvi [@turbokongen]: https://github.com/turbokongen [@viswa-swami]: https://github.com/viswa-swami [@w1ll1am23]: https://github.com/w1ll1am23 [@wickerwaka]: https://github.com/wickerwaka [alarm_control_panel.simplisafe docs]: /integrations/simplisafe [alexa docs]: /integrations/alexa/ [asterisk_mbox docs]: /integrations/asterisk_mbox/ [自动化 docs]: /integrations/自动化/ [binary_sensor docs]: /integrations/binary_sensor/ [binary_sensor.command_line docs]: /integrations/command_line [binary_sensor.rest docs]: /integrations/binary_sensor.rest/ [binary_sensor.zwave docs]: /integrations/zwave [摄像头.foscam docs]: /integrations/foscam [温控 docs]: /integrations/温控/ [温控.honeywell docs]: /integrations/honeywell [温控.tado docs]: /integrations/tado [config.zwave docs]: /integrations/config.zwave/ [遮盖.lutron_caseta docs]: /integrations/lutron_caseta/ [遮盖.rpi_gpio docs]: /integrations/rpi_gpio#遮盖 [device_tracker.huawei_router docs]: /integrations/huawei_router [dyson docs]: /integrations/dyson/ [emulated_hue docs]: /integrations/emulated_hue/ [风扇.dyson docs]: /integrations/dyson#风扇 [group docs]: /integrations/group/ [history docs]: /integrations/history/ [image_processing.opencv docs]: /integrations/opencv [influxdb docs]: /integrations/influxdb/ [insteon_plm docs]: /integrations/insteon/ [灯光.decora_wifi docs]: /integrations/decora_wifi/ [灯光.flux_led docs]: /integrations/flux_led [灯光.lifx docs]: /integrations/lifx [灯光.mochad docs]: /integrations/mochad#灯光 [灯光.osramlightify docs]: /integrations/osramlightify [门锁.nuki docs]: /integrations/nuki [lutron_caseta docs]: /integrations/lutron_caseta/ [mailbox.demo docs]: /integrations/demo/ [mailbox.demo.txt docs]: /integrations/demo/ [media_extractor docs]: /integrations/media_extractor/ [媒体播放器 docs]: /integrations/媒体播放器/ [媒体播放器.bluesound docs]: /integrations/bluesound [媒体播放器.cast docs]: /integrations/cast [媒体播放器.directv docs]: /integrations/directv [媒体播放器.kodi docs]: /integrations/kodi [媒体播放器.mpd docs]: /integrations/mpd [媒体播放器.russound_rio docs]: /integrations/russound_rio [媒体播放器.sonos docs]: /integrations/sonos [媒体播放器.squeezebox docs]: /integrations/squeezebox [通知.pushbullet docs]: /integrations/pushbullet [通知.xmpp docs]: /integrations/xmpp [recorder docs]: /integrations/recorder/ [recorder.migration docs]: /integrations/recorder.migration/ [recorder.models docs]: /integrations/recorder.models/ [recorder.purge docs]: /integrations/recorder.purge/ [recorder.util docs]: /integrations/recorder.util/ [遥控器 docs]: /integrations/遥控器/ [遥控器.apple_tv docs]: /integrations/apple_tv#遥控器 [遥控器.demo docs]: /integrations/遥控器.demo/ [遥控器.harmony docs]: /integrations/harmony [遥控器.itach docs]: /integrations/itach [遥控器.kira docs]: /integrations/kira [rflink docs]: /integrations/rflink/ [场景.lutron_caseta docs]: /integrations/lutron#scene_caseta/ [传感器.asterisk_mbox docs]: /integrations/传感器.asterisk_mbox/ [传感器.buienradar docs]: /integrations/传感器.buienradar/ [传感器.command_line docs]: /integrations/传感器.command_line/ [传感器.dyson docs]: /integrations/dyson#传感器 [传感器.efergy docs]: /integrations/efergy [传感器.eight_sleep docs]: /integrations/eight_sleep [传感器.geizhals docs]: /integrations/geizhals [传感器.google_wifi docs]: /integrations/google_wifi [传感器.lastfm docs]: /integrations/lastfm [传感器.neato docs]: /integrations/neato/ [传感器.pi_hole docs]: /integrations/pi_hole [传感器.pocketcasts docs]: /integrations/pocketcasts [传感器.radarr docs]: /integrations/radarr [传感器.rest docs]: /integrations/rest [传感器.sabnzbd docs]: /integrations/sabnzbd [传感器.shodan docs]: /integrations/shodan [传感器.sonarr docs]: /integrations/sonarr [传感器.statistics docs]: /integrations/statistics [传感器.supervisord docs]: /integrations/supervisord [传感器.synologydsm docs]: /integrations/synologydsm [传感器.systemmonitor docs]: /integrations/systemmonitor [传感器.vasttrafik docs]: /integrations/vasttrafik [传感器.zamg docs]: /integrations/zamg#传感器 [开关.command_line docs]: /integrations/开关.command_line/ [开关.MQTT docs]: /integrations/开关.MQTT/ [开关.neato docs]: /integrations/neato#开关 [开关.rachio docs]: /integrations/rachio#开关 [开关.rainmachine docs]: /integrations/rainmachine#开关 [开关.wink docs]: /integrations/wink#开关 [开关.xiaomi_vacuum docs]: /integrations/吸尘器.xiaomi_miio/ [telegram_bot docs]: /integrations/telegram_bot/ [updater docs]: /integrations/updater/ [吸尘器 docs]: /integrations/吸尘器/ [吸尘器.demo docs]: /integrations/吸尘器.demo/ [吸尘器.dyson docs]: /integrations/dyson#吸尘器 [吸尘器.roomba docs]: /integrations/roomba [吸尘器.xiaomi docs]: /integrations/吸尘器.xiaomi_miio/ [天气.buienradar docs]: /integrations/buienradar [天气.zamg docs]: /integrations/zamg#天气 [wink docs]: /integrations/wink/ [zwave docs]: /integrations/zwave/ [forum]: https://community.home-assistant.io/ [issue]: https://github.com/home-assistant/home-assistant/issues [discord]: https://discord.gg/c5DvZ4e [#8951]: https://github.com/home-assistant/home-assistant/pull/8951 [#8954]: https://github.com/home-assistant/home-assistant/pull/8954 [#8956]: https://github.com/home-assistant/home-assistant/pull/8956 [#8965]: https://github.com/home-assistant/home-assistant/pull/8965 [#8967]: https://github.com/home-assistant/home-assistant/pull/8967 [#8968]: https://github.com/home-assistant/home-assistant/pull/8968 [@Danielhiversen]: https://github.com/Danielhiversen --- url: /home-assistant/blog/2017-08-26-release-0-52.md --- # 0.52: 脚本 editor, Nello.io 门锁, HipChat and Abode Home Security Although the summer is in full progress, the development hasn't stalled. This 发布 brings bug fixes, clean ups and another 8 new 集成. On top of that we are also introducing a new [脚本 editor](/home-assistant/docs/scripts/editor/)! To use the 脚本 editor, create a new file in your config directory named `scripts.yaml` and copy your existing 脚本 over: ```yaml # scripts.yaml turn_on_some_lights: alias: "Turn on the lights" sequence: - data: {} service: light.turn_on ``` Than 更新 your `configuration.yaml` to look like this: ```yaml # Configuration.yaml example script: !include scripts.yaml ```
## New Platforms * Add 版本 传感器 ([@fabaff] - [#8912]) ([传感器.版本 docs]) (new-platform) * Nello.io 门锁 support ([@pschmitt] - [#8957]) ([门锁.nello docs]) (new-platform) * Add HipChat 通知 服务. ([@BioSehnsucht] - [#8918]) (new-platform) * Refactor USPS into component with 传感器+摄像头 ([@mezz64] - [#8679]) (breaking change) (new-platform) * Adds London\_air component ([@robmarkcole] - [#9020]) ([传感器.london\_air docs][传感器.london_air docs]) (new-platform) * Add Abode home security component ([@arsaboo] - [#9030]) ([abode docs]) ([alarm\_control\_panel.abode docs][alarm_control_panel.abode docs]) ([binary\_sensor.abode docs][binary_sensor.abode docs]) (new-platform) * Add support for Prowl 通知. ([@mbrrg] - [#9028]) ([通知.prowl docs]) (new-platform) * Add worldtidesinfo 传感器 component ([@aetolus] - [#8860]) ([传感器.worldtidesinfo docs]) (new-platform) ## 发布 0.52.1 - August 28 * Close stream request once we end up with proxy ([@foxel] - [#9110]) * Fix issue #9116 in pushbullet ([@danielhiversen] - [#9128]) ([通知.pushbullet docs]) * bug fix pushbullet ([@danielhiversen] - [#9139]) ([通知.pushbullet docs]) * Fix import for foscam ([@sdague] - [#9140]) ([摄像头.foscam docs]) * Bump aioautomatic to prevent leaking exceptions ([@armills] - [#9148]) * Wrap 状态 when iterating a domain in 模板 ([@balloob] - [#9157]) * Prevent iCloud exceptions in logfile ([@mjj4791] - [#9179]) ([device\_tracker.icloud docs][device_tracker.icloud docs]) * bump ecobee 版本 to fix issue 9190 ([@nkgilley] - [#9191]) ([ecobee docs]) ([温控.ecobee docs]) ## If you need help... ...don't hesitate to use our very active [forums][forum] or join us for a little [chat][discord]. The 发布 notes have comments enabled but it's preferred if you use the former communication channels. Thanks. ## Reporting Issues Experiencing issues introduced by this 发布? Please report them in our [issue tracker][issue]. Make sure to fill in all fields of the issue 模板. ## Backward-incompatible changes * Remove spaces from Xiami 开关 属性 ([@syssi] - [#8952]) ([开关.xiaomi docs]) (breaking change) * MQTT 开关: command and availability payload are now no longer linked. Command and availability payload default to ON/OFF and must be configured individually if custom values are required. ([@timstanley1985] - [#8934]) ([开关.MQTT docs]) (breaking change) ```yaml - platform: mqtt name: "Kitchen" state_topic: "stat/sonoff_1/POWER" command_topic: "cmnd/sonoff_1/POWER" availability_topic: "tele/sonoff_1/LWT" payload_available: "Online" payload_not_available: "Offline" retain: true ``` * Refactor USPS into component with 传感器+摄像头 ([@mezz64] - [#8679]) (breaking change) (new-platform) ```yaml usps: username: user password: pass name: optional ``` * eliqonline: The optional channel\_id 配置 variable of the Eliqonline 传感器 needs to be a positive integer. ([@molobrakos] - [#9072]) ([传感器.eliqonline docs]) (breaking change) * MySensors: Not a breaking change per se but 用户 that have not been following the mysensors [serial API](https://www.mysensors.org/download/serial_api_20) could face dropped messages after this change. Messages are now validated according to the API before being passed along from/to 设备. See [0.11 发布 notes](https://github.com/theolind/pymysensors/releases/tag/0.11) for more info. ([@MartinHjelmare] - [#9069]) ([mysensors docs]) ([binary\_sensor.mysensors docs][binary_sensor.mysensors docs]) ([温控.mysensors docs]) ([遮盖.mysensors docs]) ([device\_tracker.mysensors docs][device_tracker.mysensors docs]) ([灯光.mysensors docs]) ([通知.mysensors docs]) ([传感器.mysensors docs]) ([开关.mysensors docs]) (breaking change) * Automatic has disabled 密码 认证 on their API. Home Assistant will now use OAuth2 to authenticate accounts. The following steps must be taken to transition your 设置: 1. 日志 in to your Automatic developer account. In the Automatic Developer Apps Manager, specify the OAuth Redirect URL in the developer page. This should be configured to `/api/automatic/callback`. (Example: `http://homeassistant.local:8123/api/automatic/callback`) Note that this URL only needs to be accessible from the browser you use to perform the 认证. 2. Remove username/密码 from your automatic 设备 tracker 配置 in 配置.yaml. 3. If you have authorized your account for `scope:current_location`, add `current_location: true` to your automatic 设备 tracker 配置 in 配置.yaml. 4. When you 重启 Home Assistant, click on the Automatic 配置 link in the Configurator 卡片, and follow the instructions to 授权 Home Assistant.

NOTE: Automatic's API is currently not correctly authorizing with refresh tokens, so Step 4 currently needs to be performed after every 重启. ([@armills] - [#8962] [#9002]) ([configurator docs]) (breaking change) ## All changes * Add 版本 传感器 ([@fabaff] - [#8912]) ([传感器.版本 docs]) (new-platform) * Fix hue 灯光 for Philips and non-philips 灯光 ([@groth-its] - [#8905]) ([灯光.hue docs]) * Fixed cert\_expiry 传感器 to delay firing on HA startup ([@arsaboo] - [#8920]) ([传感器.cert\_expiry docs][传感器.cert_expiry docs]) * Remove spaces from Xiami 开关 属性 ([@syssi] - [#8952]) ([开关.xiaomi docs]) (breaking change) * Add 服务 to 报警 control 面板 for night mode arming ([@schmittx] - [#8614]) ([alarm\_control\_panel docs][alarm_control_panel docs]) ([alarm\_control\_panel.totalconnect docs][alarm_control_panel.totalconnect docs]) * Add support for Automatic OAuth2 认证 ([@armills] - [#8962]) ([configurator docs]) (breaking change) * Nello.io 门锁 support ([@pschmitt] - [#8957]) ([门锁.nello docs]) (new-platform) * Added continue-on-错误, added value 模板 ([@iamjackg] - [#8971]) ([传感器.snmp docs]) * Is\_allowed\_path raise for None path ([@danielhiversen] - [#8953]) * Fix #8960 - Decora Wi-Fi 开关 unable to set brightness ([@tlyakhov] - [#8989]) ([灯光.decora\_wifi docs][灯光.decora_wifi docs]) * Adds port/SSL config options for RainMachine ([@bachya] - [#8986]) ([开关.rainmachine docs]) * Automatic 设备 tracker remove 密码 ([@armills] - [#9002]) (breaking change) * Add 脚本 editor 后端 ([@balloob] - [#8993]) ([config docs]) ([脚本 docs]) (new-platform) * MQTT 开关 - Add configurable availability payload ([@timstanley1985] - [#8934]) ([开关.MQTT docs]) (breaking change) * Buienradar newconditions ([@mjj4791] - [#8897]) ([传感器.buienradar docs]) ([天气.buienradar docs]) * Pushbullet, fix multiple messages sent when url param is set ([@karlkar] - [#9006]) ([通知.pushbullet docs]) * 更新 to pyenvisalink 2.2, and remove range validation on zonedump i… ([@Cinntax] - [#8981]) ([envisalink docs]) * Fix #9010 - Swiss Public Transportation shows departure time in the past ([@hertg] - [#9011]) ([传感器.swiss\_public\_transport docs][传感器.swiss_public_transport docs]) * Add HipChat 通知 服务. ([@BioSehnsucht] - [#8918]) (new-platform) * 更新 onkyo-eiscp to 1.2.3 ([@danieljkemp] - [#9019]) ([媒体播放器.onkyo docs]) * Check if album 图像(s) exist in spotify ([@Tommatheussen] - [#9024]) ([媒体播放器.spotify docs]) * 更新 ffmpeg to 1.7 to fix severals problems ([@pvizeli] - [#9029]) * Add state\_with\_unit property to 状态 objects in 模板 ([@balloob] - [#9014]) * Fix Geizhals index issue when not 4 prices available ([@celeroll] - [#9035]) ([传感器.geizhals docs]) * Refactor USPS into component with 传感器+摄像头 ([@mezz64] - [#8679]) (breaking change) (new-platform) * Set 密码 after connecting. Fixes #8983 ([@StevenLooman] - [#9039]) ([媒体播放器.mpd docs]) * 更新 iOS 传感器 (battery icon fix and format updates) ([@schmittx] - [#9032]) * Adds London\_air component ([@robmarkcole] - [#9020]) ([传感器.london\_air docs][传感器.london_air docs]) (new-platform) * 更新 pwmled to 1.2.1. ([@soldag] - [#9040]) ([灯光.rpi\_gpio\_pwm docs][灯光.rpi_gpio_pwm docs]) * Configurable timeout for webostv. ([@soldag] - [#9042]) ([媒体播放器.webostv docs]) * 更新 ios.py ([@schmittx] - [#9041]) ([传感器.ios docs]) * Support Windows in UPNP discovery ([@kabongsteve] - [#8936]) * 升级 python-pushover to 0.3 ([@fanaticDavid] - [#9045]) ([通知.pushover docs]) * Add speeds to 风扇 dropdown in ISY 风扇 component ([@boojew] - [#9004]) ([风扇.isy994 docs]) * 更新 Fitbit 传感器 (icons, formatting, client 更新) ([@schmittx] - [#9031]) ([传感器.fitbit docs]) * Add Abode home security component ([@arsaboo] - [#9030]) ([abode docs]) ([alarm\_control\_panel.abode docs][alarm_control_panel.abode docs]) ([binary\_sensor.abode docs][binary_sensor.abode docs]) (new-platform) * LIFX: avoid rare NoneType 错误 ([@amelchio] - [#9054]) ([灯光.lifx docs]) * Bump dlib face\_recognition to 0.2.2 ([@arsaboo] - [#9060]) ([image\_processing.dlib\_face\_detect docs][image_processing.dlib_face_detect docs]) ([image\_processing.dlib\_face\_identify docs][image_processing.dlib_face_identify docs]) * 更新 fitbit.py ([@schmittx] - [#9064]) ([传感器.fitbit docs]) * 升级 sendgrid to 5.0.0 ([@fabaff] - [#9062]) ([通知.sendgrid docs]) * 升级 slacker to 0.9.60 ([@fabaff] - [#9065]) ([通知.slack docs]) * Add support for Prowl 通知. ([@mbrrg] - [#9028]) ([通知.prowl docs]) (new-platform) * 升级 onkyo-eiscp to 1.2.4 (fixes #8995) ([@fabaff] - [#9068]) ([媒体播放器.onkyo docs]) * Workday 传感器 offset ([@LaStrada] - [#8824]) ([binary\_sensor.workday docs][binary_sensor.workday docs]) * eliqonline: channel id is an integer ([@molobrakos] - [#9072]) ([传感器.eliqonline docs]) (breaking change) * Use builtin constants for Abode alarm\_control\_panel ([@arsaboo] - [#9059]) ([alarm\_control\_panel.abode docs][alarm_control_panel.abode docs]) * bump python-ecobee-api 版本 to 0.0.8 ([@nkgilley] - [#9074]) ([ecobee docs]) * Bump abodepy to 0.7.1 ([@arsaboo] - [#9077]) ([abode docs]) * async\_query returns False if connection to server failed, handle this properly ([@molobrakos] - [#9070]) ([媒体播放器.squeezebox docs]) * Added insteonplm device\_override multiple capabilities ([@teharris1] - [#9078]) ([insteon\_plm docs][insteon_plm docs]) * 升级 uber\_rides to 0.5.1 ([@fabaff] - [#9080]) (传感器.uber docs) * 升级 discord.py to 0.16.10 ([@fabaff] - [#9082]) ([通知.discord docs]) * Fix `device` 属性 in fritz\_callmonitor.py (fixes #9055) ([@max-te] - [#9081]) ([传感器.fritzbox\_callmonitor docs][传感器.fritzbox_callmonitor docs]) * 升级 youtube\_dl to 2017.8.18 ([@fabaff] - [#9079]) ([media\_extractor docs][media_extractor docs]) * Remove dash ([@fabaff] - [#9089]) * 升级 credstash to 1.13.3 ([@fabaff] - [#9088]) * 9043 Fixed 错误 while running dev Docker ([@MungoRae] - [#9044]) * Don't redefine consts ([@fabaff] - [#9086]) * Fix octoprint 错误 when printer is off/disconnected ([@w1ll1am23] - [#8988]) ([octoprint docs]) ([传感器.octoprint docs]) * Pilight 开关: 恢复 last 状态 after 重启 ([@janLo] - [#8580]) ([开关.pilight docs]) * Fix netdata system\_load and add disk\_free. ([@michaelarnauts] - [#9091]) ([传感器.netdata docs]) * Add worldtidesinfo 传感器 component ([@aetolus] - [#8860]) ([传感器.worldtidesinfo docs]) (new-platform) * Support changing the bulb color for tplink smartbulbs, fixes #8766 ([@rytilahti] - [#8780]) ([灯光.tplink docs]) * bump snapcast 版本 ([@happyleavesaoc] - [#9100]) ([媒体播放器.snapcast docs]) * bump fedex 版本 ([@happyleavesaoc] - [#9099]) * Yeelight fix updates on hsv mode ([@rytilahti] - [#9093]) ([灯光.yeelight docs]) * Catch exceptions ([@fabaff] - [#9085]) ([通知.discord docs]) * Fix issue 8894 with uk\_transport component if no next\_buses or next\_trains ([@robmarkcole] - [#9046]) ([传感器.uk\_transport docs][传感器.uk_transport docs]) * 升级 Xiaomi Gateway lib to 0.3 ([@danielhiversen] - [#9101]) ([xiaomi docs]) * pythonegardia package requirement to .18 ([@jeroenterheerdt] - [#9104]) ([alarm\_control\_panel.egardia docs][alarm_control_panel.egardia docs]) * Simplisafe unknown status fix ([@lekobob] - [#9111]) ([alarm\_control\_panel.simplisafe docs][alarm_control_panel.simplisafe docs]) * 更新 flux\_led.py ([@danielhiversen] - [#9122]) ([灯光.flux\_led docs][灯光.flux_led docs]) * Xiaomi ([@danielhiversen] - [#9126]) ([xiaomi docs]) * refactor pushbullet ([@danielhiversen] - [#9125]) ([通知.pushbullet docs]) * optimistic mode for 模板 遮盖 (w/o timed movement) ([@PhracturedBlue] - [#8402]) ([遮盖.模板 docs]) * Use const ([@fabaff] - [#9127]) ([prometheus docs]) * Refactor mysensors callback and add validation ([@MartinHjelmare] - [#9069]) ([mysensors docs]) ([binary\_sensor.mysensors docs][binary_sensor.mysensors docs]) ([温控.mysensors docs]) ([遮盖.mysensors docs]) ([device\_tracker.mysensors docs][device_tracker.mysensors docs]) ([灯光.mysensors docs]) ([通知.mysensors docs]) ([传感器.mysensors docs]) ([开关.mysensors docs]) (breaking change) [#8402]: https://github.com/home-assistant/home-assistant/pull/8402 [#8580]: https://github.com/home-assistant/home-assistant/pull/8580 [#8614]: https://github.com/home-assistant/home-assistant/pull/8614 [#8679]: https://github.com/home-assistant/home-assistant/pull/8679 [#8780]: https://github.com/home-assistant/home-assistant/pull/8780 [#8824]: https://github.com/home-assistant/home-assistant/pull/8824 [#8860]: https://github.com/home-assistant/home-assistant/pull/8860 [#8897]: https://github.com/home-assistant/home-assistant/pull/8897 [#8905]: https://github.com/home-assistant/home-assistant/pull/8905 [#8912]: https://github.com/home-assistant/home-assistant/pull/8912 [#8918]: https://github.com/home-assistant/home-assistant/pull/8918 [#8920]: https://github.com/home-assistant/home-assistant/pull/8920 [#8934]: https://github.com/home-assistant/home-assistant/pull/8934 [#8936]: https://github.com/home-assistant/home-assistant/pull/8936 [#8952]: https://github.com/home-assistant/home-assistant/pull/8952 [#8953]: https://github.com/home-assistant/home-assistant/pull/8953 [#8957]: https://github.com/home-assistant/home-assistant/pull/8957 [#8962]: https://github.com/home-assistant/home-assistant/pull/8962 [#8971]: https://github.com/home-assistant/home-assistant/pull/8971 [#8981]: https://github.com/home-assistant/home-assistant/pull/8981 [#8986]: https://github.com/home-assistant/home-assistant/pull/8986 [#8988]: https://github.com/home-assistant/home-assistant/pull/8988 [#8989]: https://github.com/home-assistant/home-assistant/pull/8989 [#8993]: https://github.com/home-assistant/home-assistant/pull/8993 [#9002]: https://github.com/home-assistant/home-assistant/pull/9002 [#9004]: https://github.com/home-assistant/home-assistant/pull/9004 [#9006]: https://github.com/home-assistant/home-assistant/pull/9006 [#9011]: https://github.com/home-assistant/home-assistant/pull/9011 [#9014]: https://github.com/home-assistant/home-assistant/pull/9014 [#9019]: https://github.com/home-assistant/home-assistant/pull/9019 [#9020]: https://github.com/home-assistant/home-assistant/pull/9020 [#9024]: https://github.com/home-assistant/home-assistant/pull/9024 [#9028]: https://github.com/home-assistant/home-assistant/pull/9028 [#9029]: https://github.com/home-assistant/home-assistant/pull/9029 [#9030]: https://github.com/home-assistant/home-assistant/pull/9030 [#9031]: https://github.com/home-assistant/home-assistant/pull/9031 [#9032]: https://github.com/home-assistant/home-assistant/pull/9032 [#9035]: https://github.com/home-assistant/home-assistant/pull/9035 [#9039]: https://github.com/home-assistant/home-assistant/pull/9039 [#9040]: https://github.com/home-assistant/home-assistant/pull/9040 [#9041]: https://github.com/home-assistant/home-assistant/pull/9041 [#9042]: https://github.com/home-assistant/home-assistant/pull/9042 [#9044]: https://github.com/home-assistant/home-assistant/pull/9044 [#9045]: https://github.com/home-assistant/home-assistant/pull/9045 [#9046]: https://github.com/home-assistant/home-assistant/pull/9046 [#9054]: https://github.com/home-assistant/home-assistant/pull/9054 [#9059]: https://github.com/home-assistant/home-assistant/pull/9059 [#9060]: https://github.com/home-assistant/home-assistant/pull/9060 [#9062]: https://github.com/home-assistant/home-assistant/pull/9062 [#9064]: https://github.com/home-assistant/home-assistant/pull/9064 [#9065]: https://github.com/home-assistant/home-assistant/pull/9065 [#9068]: https://github.com/home-assistant/home-assistant/pull/9068 [#9069]: https://github.com/home-assistant/home-assistant/pull/9069 [#9070]: https://github.com/home-assistant/home-assistant/pull/9070 [#9072]: https://github.com/home-assistant/home-assistant/pull/9072 [#9074]: https://github.com/home-assistant/home-assistant/pull/9074 [#9077]: https://github.com/home-assistant/home-assistant/pull/9077 [#9078]: https://github.com/home-assistant/home-assistant/pull/9078 [#9079]: https://github.com/home-assistant/home-assistant/pull/9079 [#9080]: https://github.com/home-assistant/home-assistant/pull/9080 [#9081]: https://github.com/home-assistant/home-assistant/pull/9081 [#9082]: https://github.com/home-assistant/home-assistant/pull/9082 [#9085]: https://github.com/home-assistant/home-assistant/pull/9085 [#9086]: https://github.com/home-assistant/home-assistant/pull/9086 [#9088]: https://github.com/home-assistant/home-assistant/pull/9088 [#9089]: https://github.com/home-assistant/home-assistant/pull/9089 [#9091]: https://github.com/home-assistant/home-assistant/pull/9091 [#9093]: https://github.com/home-assistant/home-assistant/pull/9093 [#9099]: https://github.com/home-assistant/home-assistant/pull/9099 [#9100]: https://github.com/home-assistant/home-assistant/pull/9100 [#9101]: https://github.com/home-assistant/home-assistant/pull/9101 [#9104]: https://github.com/home-assistant/home-assistant/pull/9104 [#9111]: https://github.com/home-assistant/home-assistant/pull/9111 [#9122]: https://github.com/home-assistant/home-assistant/pull/9122 [#9125]: https://github.com/home-assistant/home-assistant/pull/9125 [#9126]: https://github.com/home-assistant/home-assistant/pull/9126 [#9127]: https://github.com/home-assistant/home-assistant/pull/9127 [@max-te]: https://github.com/max-te [@BioSehnsucht]: https://github.com/BioSehnsucht [@Cinntax]: https://github.com/Cinntax [@LaStrada]: https://github.com/LaStrada [@MartinHjelmare]: https://github.com/MartinHjelmare [@MungoRae]: https://github.com/MungoRae [@PhracturedBlue]: https://github.com/PhracturedBlue [@StevenLooman]: https://github.com/StevenLooman [@Tommatheussen]: https://github.com/Tommatheussen [@aetolus]: https://github.com/aetolus [@amelchio]: https://github.com/amelchio [@armills]: https://github.com/armills [@arsaboo]: https://github.com/arsaboo [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@boojew]: https://github.com/boojew [@celeroll]: https://github.com/celeroll [@danielhiversen]: https://github.com/danielhiversen [@danieljkemp]: https://github.com/danieljkemp [@fabaff]: https://github.com/fabaff [@fanaticDavid]: https://github.com/fanaticDavid [@groth-its]: https://github.com/groth-its [@happyleavesaoc]: https://github.com/happyleavesaoc [@iamjackg]: https://github.com/iamjackg [@janLo]: https://github.com/janLo [@jeroenterheerdt]: https://github.com/jeroenterheerdt [@kabongsteve]: https://github.com/kabongsteve [@karlkar]: https://github.com/karlkar [@lekobob]: https://github.com/lekobob [@mbrrg]: https://github.com/mbrrg [@mezz64]: https://github.com/mezz64 [@michaelarnauts]: https://github.com/michaelarnauts [@hertg]: https://github.com/hertg [@mjj4791]: https://github.com/mjj4791 [@molobrakos]: https://github.com/molobrakos [@nkgilley]: https://github.com/nkgilley [@pschmitt]: https://github.com/pschmitt [@pvizeli]: https://github.com/pvizeli [@robmarkcole]: https://github.com/robmarkcole [@rytilahti]: https://github.com/rytilahti [@schmittx]: https://github.com/schmittx [@soldag]: https://github.com/soldag [@syssi]: https://github.com/syssi [@teharris1]: https://github.com/teharris1 [@timstanley1985]: https://github.com/timstanley1985 [@tlyakhov]: https://github.com/tlyakhov [@w1ll1am23]: https://github.com/w1ll1am23 [abode docs]: /integrations/abode/ [alarm_control_panel docs]: /integrations/alarm_control_panel/ [alarm_control_panel.abode docs]: /integrations/abode [alarm_control_panel.egardia docs]: /integrations/egardia [alarm_control_panel.simplisafe docs]: /integrations/simplisafe [alarm_control_panel.totalconnect docs]: /integrations/totalconnect [binary_sensor.abode docs]: /integrations/abode#binary-传感器 [binary_sensor.mysensors docs]: /integrations/binary_sensor.mysensors/ [binary_sensor.workday docs]: /integrations/workday [温控.mysensors docs]: /integrations/温控.mysensors/ [config docs]: /integrations/config/ [configurator docs]: /integrations/configurator/ [遮盖.mysensors docs]: /integrations/遮盖.mysensors/ [遮盖.模板 docs]: /integrations/遮盖.模板/ [device_tracker.mysensors docs]: /integrations/device_tracker.mysensors/ [ecobee docs]: /integrations/ecobee/ [emulated_hue.upnp docs]: /integrations/emulated_hue.upnp/ [envisalink docs]: /integrations/envisalink/ [风扇.isy994 docs]: /integrations/isy994 [image_processing.dlib_face_detect docs]: /integrations/dlib_face_detect [image_processing.dlib_face_identify docs]: /integrations/dlib_face_identify [insteon_plm docs]: /integrations/insteon/ [灯光.decora_wifi docs]: /integrations/decora_wifi/ [灯光.flux_led docs]: /integrations/flux_led [灯光.hue docs]: /integrations/hue [灯光.lifx docs]: /integrations/lifx [灯光.mysensors docs]: /integrations/灯光.mysensors/ [灯光.rpi_gpio_pwm docs]: /integrations/rpi_gpio_pwm [灯光.tplink docs]: /integrations/tplink [灯光.yeelight docs]: /integrations/yeelight [门锁.nello docs]: /integrations/nello [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.mpd docs]: /integrations/mpd [媒体播放器.onkyo docs]: /integrations/onkyo [媒体播放器.snapcast docs]: /integrations/snapcast [媒体播放器.spotify docs]: /integrations/spotify [媒体播放器.squeezebox docs]: /integrations/squeezebox [媒体播放器.webostv docs]: /integrations/webostv#media-player [mysensors docs]: /integrations/mysensors/ [通知.discord docs]: /integrations/discord [通知.mysensors docs]: /integrations/通知.mysensors/ [通知.prowl docs]: /integrations/prowl [通知.pushbullet docs]: /integrations/pushbullet [通知.pushover docs]: /integrations/pushover [通知.sendgrid docs]: /integrations/sendgrid [通知.slack docs]: /integrations/slack [octoprint docs]: /integrations/octoprint/ [prometheus docs]: /integrations/prometheus/ [脚本 docs]: /integrations/脚本/ [传感器.buienradar docs]: /integrations/传感器.buienradar/ [传感器.cert_expiry docs]: /integrations/cert_expiry [传感器.eliqonline docs]: /integrations/eliqonline [传感器.fitbit docs]: /integrations/fitbit [传感器.fritzbox_callmonitor docs]: /integrations/fritzbox#sensor_callmonitor/ [传感器.geizhals docs]: /integrations/geizhals [传感器.ios docs]: /integrations/传感器.ios/ [传感器.london_air docs]: /integrations/london_air [传感器.mysensors docs]: /integrations/传感器.mysensors/ [传感器.netdata docs]: /integrations/netdata [传感器.octoprint docs]: /integrations/octoprint#传感器 [传感器.snmp docs]: /integrations/snmp#传感器 [传感器.swiss_public_transport docs]: /integrations/swiss_public_transport [传感器.uk_transport docs]: /integrations/uk_transport [传感器.版本 docs]: /integrations/版本 [传感器.worldtidesinfo docs]: /integrations/worldtidesinfo [开关.MQTT docs]: /integrations/开关.MQTT/ [开关.mysensors docs]: /integrations/开关.mysensors/ [开关.pilight docs]: /integrations/pilight#开关 [开关.rainmachine docs]: /integrations/rainmachine#开关 [开关.xiaomi docs]: /integrations/开关.xiaomi_aqara/ [usps docs]: /integrations/usps/ [天气.buienradar docs]: /integrations/buienradar [xiaomi docs]: /integrations/xiaomi_aqara [forum]: https://community.home-assistant.io/ [issue]: https://github.com/home-assistant/home-assistant/issues [discord]: https://discord.gg/c5DvZ4e [#9110]: https://github.com/home-assistant/home-assistant/pull/9110 [#9128]: https://github.com/home-assistant/home-assistant/pull/9128 [#9139]: https://github.com/home-assistant/home-assistant/pull/9139 [#9140]: https://github.com/home-assistant/home-assistant/pull/9140 [#9148]: https://github.com/home-assistant/home-assistant/pull/9148 [#9157]: https://github.com/home-assistant/home-assistant/pull/9157 [#9179]: https://github.com/home-assistant/home-assistant/pull/9179 [#9191]: https://github.com/home-assistant/home-assistant/pull/9191 [@foxel]: https://github.com/foxel [@sdague]: https://github.com/sdague [摄像头.foscam docs]: /integrations/foscam [温控.ecobee docs]: /integrations/ecobee [device_tracker.icloud docs]: /integrations/icloud --- url: /home-assistant/blog/2017-09-09-release-53.md --- # 0.53: Tesla、自定义编辑器与超高速 KNX 重写 过去两周里,Home Assistant 社区一直非常忙碌,只为带来这个精彩版本。60 位不同的贡献者提交了 100 多个 PR,其中包含新功能、Bug 修复和性能优化。 距离我们四岁生日还有 9 天,我们刚刚达成了几个值得分享的重要里程碑。GitHub Star 已经超过 8000 🌟,而且从这个版本开始,我们已经提供超过 800 个平台和组件! ## 自定义编辑器 @andrey-git 为让 Home Assistant 可以通过前端进行配置又迈进了一步:自定义编辑器!现在你只需点几下,就能查看某个实体所有(可能的)自定义项并进行更新。想修改实体名称或图标?几秒钟内就能完成。

新版自定义编辑器截图。

新的 Home Assistant 配置会被自动正确创建。如果你是老用户,请确保已启用配置界面,并从 `customize.yaml` 中引入自定义配置。 ```yaml # Example configuration.yaml entry homeassistant: # Include the customizations. customize: !include customize.yaml # Enable the config screen config: ``` ## Tesla Thanks to the contribution by @zabuldon, you will now be able to control your Tesla car from Home Assistant. You're able to check the temperature inside and outside your car, control your AC and unlock the car. ## 文本输入 这个版本引入了一个新的输入组件:由 @BioSehnsucht 贡献的 `input_text`。借助这个组件,你可以在 UI 中输入自由文本,并让自动化或模板使用这些内容。 ## KNX This 发布 ships a new KNX implementation thanks to @Julius2342. It will instantly show all changed 状态 of KNX 设备 within Home Assistant. Additionally it brings support for HVAC 设备 and 通知 服务. It also adds a 服务 for direct communication with the KNX bus. You can connect to KNX/IP routing and tunneling 设备. In the background it uses asyncio communication. Check the 温控 集成 in 动作 [here](https://www.youtube.com/watch?v=JI0VJzlGpx4) and see the 灯光 in 动作 below:
## 新平台 * Xiaomi Philips 灯光 集成 ([@syssi] - [#9087]) ([灯光.xiaomi\_philipslight docs][灯光.xiaomi_philipslight docs]) (new-platform) * Mycroft 通知/component ([@btotharye] - [#9173]) ([mycroft docs]) ([通知.mycroft docs]) (new-platform) * Add counter component ([@fabaff] - [#9146]) ([counter docs]) (new-platform) * Support for season 传感器 ([@w1ll1am23] - [#8958]) ([传感器.season docs]) (new-platform) * Abode push events and 门锁, 遮盖, and 开关 components (@\[MisterWil] - [#9095]) ([abode docs]) ([alarm\_control\_panel.abode docs][alarm_control_panel.abode docs]) ([binary\_sensor.abode docs][binary_sensor.abode docs]) ([遮盖.abode docs]) ([门锁.abode docs]) ([开关.abode docs]) (new-platform) * Bayesian 二元sensor ([@jlmcgehee21] - [#8810]) ([binary\_sensor.bayesian docs][binary_sensor.bayesian docs]) (new-platform) * Add Tank Utility 传感器 ([@krismolendyke] - [#9132]) ([传感器.tank\_utility docs][传感器.tank_utility docs]) (new-platform) * Tesla platform ([@zabuldon] - [#9211]) ([tesla docs]) ([binary\_sensor.tesla docs][binary_sensor.tesla docs]) ([温控.tesla docs]) ([device\_tracker.tesla docs][device_tracker.tesla docs]) ([门锁.tesla docs]) ([传感器.tesla docs]) (new-platform) * mopar 传感器 ([@happyleavesaoc] - [#9136]) (new-platform) * Add Geofency 设备 tracker ([@gunnarhelgason] - [#9106]) ([device\_tracker.geofency docs][device_tracker.geofency docs]) (new-platform) * Added DWD WarnApp 传感器 ([@runningman84] - [#8657]) ([传感器.dwdwarnapp docs]) (new-platform) * Add input\_text component ([@BioSehnsucht] - [#9112]) ([input\_text docs][input_text docs]) (new-platform) * Introducing a 媒体播放器 component for Yamaha Multicast 设备 ([@jalmeroth] - [#9258]) ([媒体播放器.yamaha\_musiccast docs][媒体播放器.yamaha_musiccast docs]) (new-platform) * Stable and asynchronous KNX library. ([@Julius2342] - [#8725]) ([knx docs]) ([binary\_sensor.knx docs][binary_sensor.knx docs]) ([温控.knx docs]) ([遮盖.knx docs]) ([灯光.knx docs]) ([传感器.knx docs]) ([开关.knx docs]) (new-platform) * Adds the AirVisual air quality 传感器 platform ([@bachya] - [#9320]) ([传感器.airvisual docs]) (new-platform) ## 发布 0.53.1 - September 12 * Fix Twitter 通知 with certain media such as small 图像 ([@MikeChristianson] - [#9354]) ([通知.twitter docs]) * Added additional string check in Wunderground 传感器 ([@arsaboo] - [#9380]) ([传感器.wunderground docs]) * Fixing foscam library dependency/requirements ([@viswa-swami] - [#9387]) ([摄像头.foscam docs]) * Fixes for customize editor ([@andrey-git]) ## 如果你需要帮助…… 欢迎使用我们非常活跃的 [论坛][forum],或加入 [聊天频道][discord] 与我们交流。虽然发布说明也开放评论,但我们更推荐使用前面的沟通渠道。谢谢。 ## 反馈问题 如果你遇到了这个版本引入的问题,请前往我们的 [issue tracker][issue] 提交反馈,并确保填写 issue 模板中的所有字段。 ## 不向后兼容的变更 * The new customize editor is using the file `customize.yaml` in your config folder. If you are using this file today for other config, make sure to rename it before using the new customize UI editor. ([@andrey-git] - [#9134]) ([config docs]) (breaking change) (new-platform) * The 前端 component now supports loading custom html files when Home Assistant front end starts ([@andrey-git] - [#9150]) (breaking change). It could be Javascript, CSS or custom Web Components. Along there was a breaking change in the way Custom UI is used: * `custom_ui_state_card` now specifies the exact element name and not a suffix after `state-card`. So if you had `state_card_custom_ui: custom-ui` in your config, you should change it to `state_card_custom_ui: state-card-custom-ui` * `custom_ui_state_card` no longer makes the html fetch, you should make it separately: ```yaml frontend: extra_html_url: - /local/custom_ui/state-card-custom-ui.html ``` * The Egardia 报警 control 面板 now defaults to port 52010 instead of 85. ([@jeroenterheerdt] - [#9225]) ([alarm\_control\_panel.egardia docs][alarm_control_panel.egardia docs]) (breaking change) * The Homematic `delay` option has been dropped because it is no longer necessary ([@pvizeli] - [#9058]) ([homematic docs]) ([binary\_sensor.homematic docs][binary_sensor.homematic docs]) ([温控.homematic docs]) ([遮盖.homematic docs]) ([灯光.homematic docs]) ([传感器.homematic docs]) ([开关.homematic docs]) (breaking change) * 开关 - Dlink: Remove spaces and capital letters from 属性 names for consistency ([@emlt] - [#9277]) ([开关.dlink docs]) (breaking change) ## 全部变更 * Xiaomi Philips 灯光 集成 ([@syssi] - [#9087]) ([灯光.xiaomi\_philipslight docs][灯光.xiaomi_philipslight docs]) (new-platform) * 后端 changes for customize config 面板. ([@andrey-git] - [#9134]) ([config docs]) (breaking change) * 升级 async\_timeout to 1.3.0 ([@fabaff] - [#9156]) * Remove links to gitter ([@fabaff] - [#9155]) * 升级 sphinx-autodoc-typehints to 1.2.3 ([@fabaff] - [#9151]) * 升级 uber\_rides to 0.5.2 ([@fabaff] - [#9149]) (传感器.uber docs) * Allow specifying custom html urls to load. ([@andrey-git] - [#9150]) (breaking change) * Allow getting number of available 状态 in 模板 ([@balloob] - [#9158]) * 升级 xiaomi lib to 0.3.1 to supprt water 传感器 ([@danielhiversen] - [#9168]) ([xiaomi docs]) * Use node\_modules gulp in 脚本/build\_frontend ([@armills] - [#9170]) * Mysensors nodes can be renamed in config file ([@EmitKiwi] - [#9123]) ([mysensors docs]) * Xiaomi gateway: 设备 support for the Aqara Water Leak 传感器 (sensor\_wleak.aq1) ([@syssi] - [#9172]) ([xiaomi docs]) ([binary\_sensor.xiaomi docs][binary_sensor.xiaomi docs]) * "TypeError: write\_to\_hub() takes 2 positional arguments but 4 were given" fixed. ([@syssi] - [#9174]) ([遮盖.xiaomi docs]) * Mycroft 通知/component ([@btotharye] - [#9173]) ([mycroft docs]) ([通知.mycroft docs]) (new-platform) * Fix dht22 when no data was read initially #8976 ([@maweki] - [#9198]) ([传感器.dht docs]) * 更新 pushbullet.py ([@bobnwk] - [#9200]) ([通知.pushbullet docs]) * fix worldtidesinfo #9184 ([@aetolus] - [#9201]) ([传感器.worldtidesinfo docs]) * Add "status" to Sonarr 传感器 ([@tboyce021] - [#9204]) ([传感器.radarr docs]) ([传感器.sonarr docs]) * Prevent 错误 when no forecast data was available ([@mjj4791] - [#9176]) ([传感器.buienradar docs]) * Fix and optimize digitalloggers platform ([@dale3h] - [#9203]) ([开关.digitalloggers docs]) * Add counter component ([@fabaff] - [#9146]) ([counter docs]) (new-platform) * Support for season 传感器 ([@w1ll1am23] - [#8958]) ([传感器.season docs]) (new-platform) * Issue #6893 in rfxtrx ([@danielhiversen] - [#9130]) ([rfxtrx docs]) * Refactor rfxtrx ([@danielhiversen] - [#9117]) ([rfxtrx docs]) ([遮盖.rfxtrx docs]) ([灯光.rfxtrx docs]) ([开关.rfxtrx docs]) * 升级 pymysensors to 0.11.1 ([@MartinHjelmare] - [#9212]) ([mysensors docs]) * Abode push events and 门锁, 遮盖, and 开关 components (@\[MisterWil] - [#9095]) ([abode docs]) ([alarm\_control\_panel.abode docs][alarm_control_panel.abode docs]) ([binary\_sensor.abode docs][binary_sensor.abode docs]) ([遮盖.abode docs]) ([门锁.abode docs]) ([开关.abode docs]) (new-platform) * Add cloud auth support ([@balloob] - [#9208]) * Bayesian 二元sensor ([@jlmcgehee21] - [#8810]) ([binary\_sensor.bayesian docs][binary_sensor.bayesian docs]) (new-platform) * directv: extended discovery via REST api, bug fix ([@sielicki] - [#8800]) ([媒体播放器.directv docs]) * 升级 pyasn1 to 0.3.3 and pyasn1-modules to 0.1.1 ([@fabaff] - [#9216]) ([通知.xmpp docs]) * 升级 sendgrid to 5.0.1 ([@fabaff] - [#9215]) ([通知.sendgrid docs]) * Fix fitbit 错误 when trying to access token after 升级. ([@tchellomello] - [#9183]) ([传感器.fitbit docs]) * Allow sonos to select album as a source ([@commento] - [#9221]) ([媒体播放器.sonos docs]) * Add max\_age to statistics 传感器 ([@tinloaf] - [#8790]) ([传感器.statistics docs]) * Egardia package to .19 and change in port number for egardiaserver ([@jeroenterheerdt] - [#9225]) ([alarm\_control\_panel.egardia docs][alarm_control_panel.egardia docs]) (breaking change) * pushbullet, send a file from url ([@danielhiversen] - [#9189]) ([通知.pushbullet docs]) * Add Tank Utility 传感器 ([@krismolendyke] - [#9132]) ([传感器.tank\_utility docs][传感器.tank_utility docs]) (new-platform) * 升级 shodan to 1.7.5 ([@fabaff] - [#9228]) ([传感器.shodan docs]) * Tesla platform ([@zabuldon] - [#9211]) ([tesla docs]) ([binary\_sensor.tesla docs][binary_sensor.tesla docs]) ([温控.tesla docs]) ([device\_tracker.tesla docs][device_tracker.tesla docs]) ([门锁.tesla docs]) ([传感器.tesla docs]) (new-platform) * \[灯光.tradfri] Full range of white spectrum lightbulbs support ([@matemaciek] - [#9224]) ([tradfri docs]) ([灯光.tradfri docs]) * Allow 面板 with external URL ([@andrey-git] - [#9214]) * Use ZCL mandatory 属性 to determine ZHA 灯光 capabilities ([@jkl1337] - [#9232]) ([灯光.zha docs]) * A bugfix for pushbullet ([@danielhiversen] - [#9237]) ([通知.pushbullet docs]) * mopar 传感器 ([@happyleavesaoc] - [#9136]) (new-platform) * 升级 discord.py to 0.16.11 ([@fabaff] - [#9239]) ([通知.discord docs]) * Skip automatic events older than latest data ([@armills] - [#9230]) * title and message was swapped in pushbullet ([@danielhiversen] - [#9241]) ([通知.pushbullet docs]) * Fix possible KeyError ([@MartinHjelmare] - [#9242]) ([mysensors docs]) * WIP: Homematic improvements with new hass interfaces ([@pvizeli] - [#9058]) ([homematic docs]) ([binary\_sensor.homematic docs][binary_sensor.homematic docs]) ([温控.homematic docs]) ([遮盖.homematic docs]) ([灯光.homematic docs]) ([传感器.homematic docs]) ([开关.homematic docs]) (breaking change) * Add available to sonos ([@pvizeli] - [#9243]) ([媒体播放器.sonos docs]) * Make sure Ring binary\_sensor 状态 will 更新 only if device\_id matches ([@tchellomello] - [#9247]) ([binary\_sensor.ring docs][binary_sensor.ring docs]) * Added configurable timeout for receiver HTTP requests | Additional AV… ([@scarface-4711] - [#9244]) ([媒体播放器.denonavr docs]) * 升级 xiaomi lib ([@danielhiversen] - [#9250]) ([xiaomi docs]) * Fix nello.io login ([@pschmitt] - [#9251]) ([门锁.nello docs]) * This is to fix #6386: Manual 报警 not re-arm after 2nd 触发器 ([@snjoetw] - [#9249]) ([alarm\_control\_panel.manual docs][alarm_control_panel.manual docs]) * 版本 bump of DLink 开关 to v0.6.0 ([@LinuxChristian] - [#9252]) ([开关.dlink docs]) * 升级 sendgrid to 5.2.0 ([@fabaff] - [#9254]) ([通知.sendgrid docs]) * 升级 psutil to 5.3.0 ([@fabaff] - [#9253]) ([传感器.systemmonitor docs]) * Adding ZWave CentralScene activation handler. ([@sirmalloc] - [#9178]) ([zwave docs]) * Add Geofency 设备 tracker ([@gunnarhelgason] - [#9106]) ([device\_tracker.geofency docs][device_tracker.geofency docs]) (new-platform) * flux: fix for when stop\_time is after midnight ([@abmantis] - [#8932]) * Change 属性 names ([@emlt] - [#9277]) ([开关.dlink docs]) (breaking change) * insteon\_plm: fix typo in 属性 ([@drkp] - [#9284]) ([insteon\_plm docs][insteon_plm docs]) * discovery: If unknown NetDisco 服务 discovered, 日志 about it. ([@pfalcon] - [#9280]) * 升级 youtube\_dl to 2017.9.2 ([@fabaff] - [#9279]) ([media\_extractor docs][media_extractor docs]) * 升级 python-telegram-bot to 8.0.0 ([@fabaff] - [#9282]) ([telegram\_bot docs][telegram_bot docs]) ([开关.rest docs]) * rfxtrx lib 升级 ([@danielhiversen] - [#9288]) ([rfxtrx docs]) * Fixing bug when using egardiaserver - package requirement updated to 1.0.20. ([@jeroenterheerdt] - [#9294]) ([alarm\_control\_panel.egardia docs][alarm_control_panel.egardia docs]) * Added intent\_type to exception 日志 ([@andreasjacobsen93] - [#9289]) ([snips docs]) * Handle spotify failing to refresh access\_token ([@Tommatheussen] - [#9295]) ([媒体播放器.spotify docs]) * 核心 track same 状态 for a period / Allow on platforms ([@pvizeli] - [#9273]) * Improved Lutron Caseta shade support ([@upsert] - [#9302]) ([lutron\_caseta docs][lutron_caseta docs]) ([遮盖.lutron\_caseta docs][遮盖.lutron_caseta docs]) ([灯光.lutron\_caseta docs][灯光.lutron_caseta docs]) ([开关.lutron\_caseta docs][开关.lutron_caseta docs]) * 升级 mycroftapi to 2.0 ([@btotharye] - [#9309]) ([mycroft docs]) * Fix for Honeywell Round thermostats ([@dansarginson] - [#9308]) ([温控.honeywell docs]) * 更新 jinja to 2.9.6 ([@pvizeli] - [#9306]) * Ensure display-name does not exceed 12 characters for CecAdapter. ([@gollo] - [#9268]) ([hdmi\_cec docs][hdmi_cec docs]) * Expose hue group 0 ([@filcole] - [#8663]) ([灯光.hue docs]) * Added DWD WarnApp 传感器 ([@runningman84] - [#8657]) ([传感器.dwdwarnapp docs]) (new-platform) * Add input\_text component ([@BioSehnsucht] - [#9112]) ([input\_text docs][input_text docs]) (new-platform) * Introducing a 媒体播放器 component for Yamaha Multicast 设备 ([@jalmeroth] - [#9258]) ([媒体播放器.yamaha\_musiccast docs][媒体播放器.yamaha_musiccast docs]) (new-platform) * Handle the case where no registration number is available (instead display VIN (vehicle identification number)). ([@molobrakos] - [#9073]) ([volvooncall docs]) ([device\_tracker.volvooncall docs][device_tracker.volvooncall docs]) * Add post\_pending\_state 属性 to manual alarm\_control\_panel ([@snjoetw] - [#9291]) ([alarm\_control\_panel.manual docs][alarm_control_panel.manual docs]) * Add new config variable to MQTT 灯光 ([@belyalov] - [#9304]) ([灯光.MQTT docs]) * Follow Twitter guidelines for media upload by conforming to the "STATUS" phase, when required, and by providing "media\_category" information. These will, for example, allow 用户 to upload videos that exceed the basic 30 second limit. ([@MikeChristianson] - [#9261]) ([通知.twitter docs]) * Optionally disable ssl certificate validity check. ([@ohmer1] - [#9181]) ([通知.xmpp docs]) * 版本 bump dlib to 1.0.0 ([@arsaboo] - [#9316]) ([image\_processing.dlib\_face\_detect docs][image_processing.dlib_face_detect docs]) ([image\_processing.dlib\_face\_identify docs][image_processing.dlib_face_identify docs]) * Fixed bug with 设备 not being discovered correctly. ([@MisterWil] - [#9311]) ([abode docs]) * Platform not ready behavior fixed. ([@syssi] - [#9325]) ([灯光.xiaomi\_philipslight docs][灯光.xiaomi_philipslight docs]) * Stable and asynchronous KNX library. ([@Julius2342] - [#8725]) ([knx docs]) ([binary\_sensor.knx docs][binary_sensor.knx docs]) ([温控.knx docs]) ([遮盖.knx docs]) ([灯光.knx docs]) ([传感器.knx docs]) ([开关.knx docs]) (new-platform) * Fix for potential issue with tesla initialization ([@zabuldon] - [#9307]) ([tesla docs]) * Adds the AirVisual air quality 传感器 platform ([@bachya] - [#9320]) ([传感器.airvisual docs]) (new-platform) * Cleanup input\_text ([@balloob] - [#9326]) ([input\_text docs][input_text docs]) * Bump pyHik 版本 to add IO support ([@mezz64] - [#9341]) ([binary\_sensor.hikvision docs][binary_sensor.hikvision docs]) [#8657]: https://github.com/home-assistant/home-assistant/pull/8657 [#8663]: https://github.com/home-assistant/home-assistant/pull/8663 [#8725]: https://github.com/home-assistant/home-assistant/pull/8725 [#8790]: https://github.com/home-assistant/home-assistant/pull/8790 [#8800]: https://github.com/home-assistant/home-assistant/pull/8800 [#8810]: https://github.com/home-assistant/home-assistant/pull/8810 [#8932]: https://github.com/home-assistant/home-assistant/pull/8932 [#8958]: https://github.com/home-assistant/home-assistant/pull/8958 [#9058]: https://github.com/home-assistant/home-assistant/pull/9058 [#9073]: https://github.com/home-assistant/home-assistant/pull/9073 [#9087]: https://github.com/home-assistant/home-assistant/pull/9087 [#9095]: https://github.com/home-assistant/home-assistant/pull/9095 [#9106]: https://github.com/home-assistant/home-assistant/pull/9106 [#9112]: https://github.com/home-assistant/home-assistant/pull/9112 [#9117]: https://github.com/home-assistant/home-assistant/pull/9117 [#9123]: https://github.com/home-assistant/home-assistant/pull/9123 [#9130]: https://github.com/home-assistant/home-assistant/pull/9130 [#9132]: https://github.com/home-assistant/home-assistant/pull/9132 [#9134]: https://github.com/home-assistant/home-assistant/pull/9134 [#9136]: https://github.com/home-assistant/home-assistant/pull/9136 [#9146]: https://github.com/home-assistant/home-assistant/pull/9146 [#9149]: https://github.com/home-assistant/home-assistant/pull/9149 [#9150]: https://github.com/home-assistant/home-assistant/pull/9150 [#9151]: https://github.com/home-assistant/home-assistant/pull/9151 [#9155]: https://github.com/home-assistant/home-assistant/pull/9155 [#9156]: https://github.com/home-assistant/home-assistant/pull/9156 [#9158]: https://github.com/home-assistant/home-assistant/pull/9158 [#9168]: https://github.com/home-assistant/home-assistant/pull/9168 [#9170]: https://github.com/home-assistant/home-assistant/pull/9170 [#9172]: https://github.com/home-assistant/home-assistant/pull/9172 [#9173]: https://github.com/home-assistant/home-assistant/pull/9173 [#9174]: https://github.com/home-assistant/home-assistant/pull/9174 [#9176]: https://github.com/home-assistant/home-assistant/pull/9176 [#9178]: https://github.com/home-assistant/home-assistant/pull/9178 [#9181]: https://github.com/home-assistant/home-assistant/pull/9181 [#9183]: https://github.com/home-assistant/home-assistant/pull/9183 [#9189]: https://github.com/home-assistant/home-assistant/pull/9189 [#9198]: https://github.com/home-assistant/home-assistant/pull/9198 [#9200]: https://github.com/home-assistant/home-assistant/pull/9200 [#9201]: https://github.com/home-assistant/home-assistant/pull/9201 [#9203]: https://github.com/home-assistant/home-assistant/pull/9203 [#9204]: https://github.com/home-assistant/home-assistant/pull/9204 [#9208]: https://github.com/home-assistant/home-assistant/pull/9208 [#9211]: https://github.com/home-assistant/home-assistant/pull/9211 [#9212]: https://github.com/home-assistant/home-assistant/pull/9212 [#9214]: https://github.com/home-assistant/home-assistant/pull/9214 [#9215]: https://github.com/home-assistant/home-assistant/pull/9215 [#9216]: https://github.com/home-assistant/home-assistant/pull/9216 [#9221]: https://github.com/home-assistant/home-assistant/pull/9221 [#9224]: https://github.com/home-assistant/home-assistant/pull/9224 [#9225]: https://github.com/home-assistant/home-assistant/pull/9225 [#9228]: https://github.com/home-assistant/home-assistant/pull/9228 [#9230]: https://github.com/home-assistant/home-assistant/pull/9230 [#9232]: https://github.com/home-assistant/home-assistant/pull/9232 [#9237]: https://github.com/home-assistant/home-assistant/pull/9237 [#9239]: https://github.com/home-assistant/home-assistant/pull/9239 [#9241]: https://github.com/home-assistant/home-assistant/pull/9241 [#9242]: https://github.com/home-assistant/home-assistant/pull/9242 [#9243]: https://github.com/home-assistant/home-assistant/pull/9243 [#9244]: https://github.com/home-assistant/home-assistant/pull/9244 [#9247]: https://github.com/home-assistant/home-assistant/pull/9247 [#9249]: https://github.com/home-assistant/home-assistant/pull/9249 [#9250]: https://github.com/home-assistant/home-assistant/pull/9250 [#9251]: https://github.com/home-assistant/home-assistant/pull/9251 [#9252]: https://github.com/home-assistant/home-assistant/pull/9252 [#9253]: https://github.com/home-assistant/home-assistant/pull/9253 [#9254]: https://github.com/home-assistant/home-assistant/pull/9254 [#9258]: https://github.com/home-assistant/home-assistant/pull/9258 [#9261]: https://github.com/home-assistant/home-assistant/pull/9261 [#9268]: https://github.com/home-assistant/home-assistant/pull/9268 [#9273]: https://github.com/home-assistant/home-assistant/pull/9273 [#9277]: https://github.com/home-assistant/home-assistant/pull/9277 [#9279]: https://github.com/home-assistant/home-assistant/pull/9279 [#9280]: https://github.com/home-assistant/home-assistant/pull/9280 [#9282]: https://github.com/home-assistant/home-assistant/pull/9282 [#9284]: https://github.com/home-assistant/home-assistant/pull/9284 [#9288]: https://github.com/home-assistant/home-assistant/pull/9288 [#9289]: https://github.com/home-assistant/home-assistant/pull/9289 [#9291]: https://github.com/home-assistant/home-assistant/pull/9291 [#9294]: https://github.com/home-assistant/home-assistant/pull/9294 [#9295]: https://github.com/home-assistant/home-assistant/pull/9295 [#9302]: https://github.com/home-assistant/home-assistant/pull/9302 [#9304]: https://github.com/home-assistant/home-assistant/pull/9304 [#9306]: https://github.com/home-assistant/home-assistant/pull/9306 [#9307]: https://github.com/home-assistant/home-assistant/pull/9307 [#9308]: https://github.com/home-assistant/home-assistant/pull/9308 [#9309]: https://github.com/home-assistant/home-assistant/pull/9309 [#9311]: https://github.com/home-assistant/home-assistant/pull/9311 [#9316]: https://github.com/home-assistant/home-assistant/pull/9316 [#9320]: https://github.com/home-assistant/home-assistant/pull/9320 [#9325]: https://github.com/home-assistant/home-assistant/pull/9325 [#9326]: https://github.com/home-assistant/home-assistant/pull/9326 [#9341]: https://github.com/home-assistant/home-assistant/pull/9341 [@MisterWil]: https://github.com/MisterWil [@ohmer1]: https://github.com/ohmer1 [@upsert]: https://github.com/upsert [@BioSehnsucht]: https://github.com/BioSehnsucht [@EmitKiwi]: https://github.com/EmitKiwi [@Julius2342]: https://github.com/Julius2342 [@LinuxChristian]: https://github.com/LinuxChristian [@MartinHjelmare]: https://github.com/MartinHjelmare [@MikeChristianson]: https://github.com/MikeChristianson [@Tommatheussen]: https://github.com/Tommatheussen [@abmantis]: https://github.com/abmantis [@aetolus]: https://github.com/aetolus [@andreasjacobsen93]: https://github.com/andreasjacobsen93 [@andrey-git]: https://github.com/andrey-git [@armills]: https://github.com/armills [@arsaboo]: https://github.com/arsaboo [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@belyalov]: https://github.com/belyalov [@bobnwk]: https://github.com/bobnwk [@btotharye]: https://github.com/btotharye [@commento]: https://github.com/commento [@dale3h]: https://github.com/dale3h [@danielhiversen]: https://github.com/danielhiversen [@dansarginson]: https://github.com/dansarginson [@drkp]: https://github.com/drkp [@emlt]: https://github.com/emlt [@fabaff]: https://github.com/fabaff [@filcole]: https://github.com/filcole [@gollo]: https://github.com/gollo [@gunnarhelgason]: https://github.com/gunnarhelgason [@happyleavesaoc]: https://github.com/happyleavesaoc [@jalmeroth]: https://github.com/jalmeroth [@jeroenterheerdt]: https://github.com/jeroenterheerdt [@jkl1337]: https://github.com/jkl1337 [@jlmcgehee21]: https://github.com/jlmcgehee21 [@krismolendyke]: https://github.com/krismolendyke [@matemaciek]: https://github.com/matemaciek [@maweki]: https://github.com/maweki [@mezz64]: https://github.com/mezz64 [@mjj4791]: https://github.com/mjj4791 [@molobrakos]: https://github.com/molobrakos [@pfalcon]: https://github.com/pfalcon [@pschmitt]: https://github.com/pschmitt [@pvizeli]: https://github.com/pvizeli [@runningman84]: https://github.com/runningman84 [@scarface-4711]: https://github.com/scarface-4711 [@sielicki]: https://github.com/sielicki [@sirmalloc]: https://github.com/sirmalloc [@snjoetw]: https://github.com/snjoetw [@syssi]: https://github.com/syssi [@tboyce021]: https://github.com/tboyce021 [@tchellomello]: https://github.com/tchellomello [@tinloaf]: https://github.com/tinloaf [@w1ll1am23]: https://github.com/w1ll1am23 [@zabuldon]: https://github.com/zabuldon [abode docs]: /integrations/abode/ [alarm_control_panel.abode docs]: /integrations/abode [alarm_control_panel.egardia docs]: /integrations/egardia [alarm_control_panel.manual docs]: /integrations/manual [binary_sensor.abode docs]: /integrations/abode#binary-传感器 [binary_sensor.bayesian docs]: /integrations/bayesian [binary_sensor.hikvision docs]: /integrations/hikvision [binary_sensor.homematic docs]: /integrations/homematic [binary_sensor.ring docs]: /integrations/ring#binary-传感器 [binary_sensor.tesla docs]: /integrations/tesla [binary_sensor.xiaomi docs]: /integrations/binary_sensor.xiaomi_aqara/ [binary_sensor.knx docs]: /integrations/binary_sensor.knx/ [温控.homematic docs]: /integrations/homematic [温控.honeywell docs]: /integrations/honeywell [温控.tesla docs]: /integrations/tesla [温控.knx docs]: /integrations/温控.knx/ [cloud docs]: /integrations/cloud/ [cloud.cloud_api docs]: /integrations/cloud.cloud_api/ [cloud.util docs]: /integrations/cloud.util/ [config docs]: /integrations/config/ [config.customize docs]: /integrations/config.customize/ [counter docs]: /integrations/counter/ [遮盖.abode docs]: /integrations/abode [遮盖.homematic docs]: /integrations/homematic [遮盖.lutron_caseta docs]: /integrations/lutron_caseta/ [遮盖.rfxtrx docs]: /integrations/rfxtrx#遮盖 [遮盖.xiaomi docs]: /integrations/遮盖.xiaomi_aqara/ [遮盖.knx docs]: /integrations/遮盖.knx/ [device_tracker.geofency docs]: /integrations/geofency [device_tracker.tesla docs]: /integrations/tesla [device_tracker.volvooncall docs]: /integrations/volvooncall [hdmi_cec docs]: /integrations/hdmi_cec/ [homematic docs]: /integrations/homematic/ [image_processing.dlib_face_detect docs]: /integrations/dlib_face_detect [image_processing.dlib_face_identify docs]: /integrations/dlib_face_identify [input_text docs]: /integrations/input_text/ [insteon_plm docs]: /integrations/insteon/ [灯光.homematic docs]: /integrations/homematic [灯光.hue docs]: /integrations/hue [灯光.lutron_caseta docs]: /integrations/lutron_caseta/ [灯光.MQTT docs]: /integrations/灯光.MQTT/ [灯光.xiaomi_philipslight docs]: /integrations/灯光.xiaomi_miio/ [灯光.rfxtrx docs]: /integrations/rfxtrx#灯光 [灯光.tradfri docs]: /integrations/tradfri [灯光.knx docs]: /integrations/灯光.knx/ [灯光.zha docs]: /integrations/zha [门锁.abode docs]: /integrations/abode [门锁.nello docs]: /integrations/nello [门锁.tesla docs]: /integrations/tesla [lutron_caseta docs]: /integrations/lutron_caseta/ [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.denonavr docs]: /integrations/denonavr/ [媒体播放器.directv docs]: /integrations/directv [媒体播放器.sonos docs]: /integrations/sonos [媒体播放器.spotify docs]: /integrations/spotify [媒体播放器.yamaha_musiccast docs]: /integrations/yamaha_musiccast/ [mycroft docs]: /integrations/mycroft/ [mysensors docs]: /integrations/mysensors/ [通知.discord docs]: /integrations/discord [通知.mycroft docs]: /integrations/mycroft [通知.pushbullet docs]: /integrations/pushbullet [通知.sendgrid docs]: /integrations/sendgrid [通知.twitter docs]: /integrations/twitter [通知.xmpp docs]: /integrations/xmpp [rfxtrx docs]: /integrations/rfxtrx/ [传感器.airvisual docs]: /integrations/airvisual [传感器.buienradar docs]: /integrations/传感器.buienradar/ [传感器.dht docs]: /integrations/dht [传感器.dwdwarnapp docs]: /integrations/dwd_weather_warnings/ [传感器.fitbit docs]: /integrations/fitbit [传感器.homematic docs]: /integrations/homematic [传感器.radarr docs]: /integrations/radarr [传感器.season docs]: /integrations/season [传感器.shodan docs]: /integrations/shodan [传感器.sonarr docs]: /integrations/sonarr [传感器.statistics docs]: /integrations/statistics [传感器.systemmonitor docs]: /integrations/systemmonitor [传感器.tank_utility docs]: /integrations/tank_utility [传感器.tesla docs]: /integrations/tesla [传感器.worldtidesinfo docs]: /integrations/worldtidesinfo [传感器.knx docs]: /integrations/传感器.knx/ [snips docs]: /integrations/snips/ [开关.abode docs]: /integrations/abode#开关 [开关.digitalloggers docs]: /integrations/digitalloggers [开关.dlink docs]: /integrations/dlink [开关.homematic docs]: /integrations/homematic [开关.lutron_caseta docs]: /integrations/lutron_caseta/ [开关.rest docs]: /integrations/开关.rest/ [开关.rfxtrx docs]: /integrations/rfxtrx#开关 [开关.knx docs]: /integrations/开关.knx/ [telegram_bot docs]: /integrations/telegram_bot/ [tesla docs]: /integrations/tesla/ [tradfri docs]: /integrations/tradfri/ [volvooncall docs]: /integrations/volvooncall/ [xiaomi docs]: /integrations/xiaomi_aqara [knx docs]: /integrations/knx/ [zwave docs]: /integrations/zwave/ [forum]: https://community.home-assistant.io/ [issue]: https://github.com/home-assistant/home-assistant/issues [discord]: https://discord.gg/c5DvZ4e [#9354]: https://github.com/home-assistant/home-assistant/pull/9354 [#9380]: https://github.com/home-assistant/home-assistant/pull/9380 [#9387]: https://github.com/home-assistant/home-assistant/pull/9387 [@viswa-swami]: https://github.com/viswa-swami [摄像头.foscam docs]: /integrations/foscam [传感器.wunderground docs]: /integrations/wunderground --- url: /home-assistant/blog/2017-09-16-hassbian-1.3-a-bit-of-a-stretch.md --- # Hassbian 1.3 - A bit of a stretch This new 发布 finally brings us the 发布 of Hassbian based on the 发布 of Raspbian Stretch. The most significant change with this is that we now run Home Assistant on Python 3.5. Other than that the changes are mostly to our tool `hassbian-config`. ### Hassbian-config To allow you to customize your 安装 further, we have made a few additions to our tool called `hassbian-config`. Majority of these changes where contributed by [@Ludeeus][ludeeus]. #### 升级 脚本 [@Ludeeus][ludeeus] contributed the possibility to run 升级 脚本 to the `hassbian-config` tool. * 升级 Hassbian: Upgrades packages of the base operating system. Contributed by [@Landrash][landrash]. * 升级 Hassbian-脚本: Downloads and upgrades the latest 发布 of Hassbian-脚本. Contributed by [@Ludeeus][ludeeus]. * 升级 Home-assistant: Upgrades the Home Assistant 安装 to the latest 发布. Contributed by [@Ludeeus][ludeeus]. To follow discussions about the development of the HASSbian 图像 or to contribute join our [Discord chat server][discord-hassbian]. To get started with the new 图像, check out the 安装 instructions on the installing Hassbian page. [landrash]: http://github.com/landrash [ludeeus]: http://github.com/ludeeus [hassbian-repo]: https://github.com/home-assistant/hassbian-脚本/ [hassbian-config-发布]: https://github.com/home-assistant/hassbian-脚本/releases/latest [discord-hassbian]: https://discord.gg/RkajcgS --- url: /home-assistant/blog/2017-09-23-release-54.md --- # 0.54: Todoist、DoorBird、Abode 摄像头 我们正在接近九月底,这也意味着生日到了!现在我们正式满 4 岁了,而且每个版本都在变得更强大。这次发布同样带来了很多很棒的新内容和大量 Bug 修复。其中还包括 [@fanthos] 提交的一项修复,它应该能解决某些浏览器中的前端问题。如果你之前在浏览器里遇到过异常,记得试试这个版本。 在这个版本中,我们开始着手让 Xiaomi 集成变得更稳健。这意味着我们需要重命名一些组件,以更清楚地区分它们使用的是哪一种 Xiaomi 协议。已有一些开发者正在努力让这套高性价比的家庭自动化方案成为 Home Assistant 生态中的一等公民,敬请期待更多集成! 这个版本中的另一项很酷的新功能是全新的 [`mqtt_statestream`][mqtt_statestream docs] 组件,它可以将状态变化导出到 MQTT。每个实体都会发布到各自独立的主题中,这让订阅单个实体的更新变得非常简单。 ## 新平台 * Added mqtt\_statestream component ([@mw-white] - [#9286]) ([mqtt\_statestream docs][mqtt_statestream docs]) (new-platform) * Add support for Todoist platform ([@Jay2645] - [#9236]) ([日历.todoist docs]) (new-platform) * DoorBird Component ([@Klikini] - [#9281]) ([doorbird docs]) (binary\_sensor.doorbird docs) ([摄像头.doorbird docs]) ([开关.doorbird docs]) (new-platform) * Basic MQTT 吸尘器 support ([@johnboiles] - [#9386]) ([吸尘器 docs]) ([吸尘器.MQTT docs]) (new-platform) * Added Zyxel Keenetic NDMS2 based routers support for 设备 tracking ([@foxel] - [#9315]) ([device\_tracker.keenetic\_ndms2 docs][device_tracker.keenetic_ndms2 docs]) (new-platform) * Telnet 开关 ([@multiholle] - [#8913]) ([开关.telnet docs]) (new-platform) * Abode 服务, events, 灯光, 摄像头, 自动化, quick 动作. ([@MisterWil] - [#9310]) ([abode docs]) ([alarm\_control\_panel.abode docs][alarm_control_panel.abode docs]) ([binary\_sensor.abode docs][binary_sensor.abode docs]) ([摄像头.abode docs]) ([遮盖.abode docs]) ([灯光.abode docs]) ([门锁.abode docs]) ([开关.abode docs]) (new-platform) * Added satel\_integra 报警 面板 and 二元sensor platform ([@c-soft] - [#9336]) ([satel\_integra docs][satel_integra docs]) ([alarm\_control\_panel.satel\_integra docs][alarm_control_panel.satel_integra docs]) ([binary\_sensor.satel\_integra docs][binary_sensor.satel_integra docs]) (new-platform) * Worx Landroid 传感器 ([@nilzen] - [#9416]) ([传感器.worxlandroid docs]) (new-platform) ## 如果你需要帮助…… 欢迎使用我们非常活跃的 [论坛][forum],或加入 [聊天频道][discord] 与我们交流。虽然发布说明也开放评论,但我们更推荐使用前面的沟通渠道。谢谢。 ## 反馈问题 如果你遇到了这个版本引入的问题,请前往我们的 [issue tracker][issue] 提交反馈,并确保填写 issue 模板中的所有字段。 ## 不向后兼容的变更 * 传感器 - OneWire: This 更新 changes the names of the 传感器 from `` to ` ` ([@tcastberg] - [#9404]) ([传感器.onewire docs]) (breaking change) * Renamed Xiaomi platforms to include their protocol names. xiaomi -> xiaomi\_aqara, xiaomi\_aqara.开关, xiaomi\_aqara.灯光, xiaomi\_aqara.binary\_sensor, ... and 吸尘器.xiaomi, xiaomi\_philipslight -> xiaomi\_miio, 吸尘器.xiaomi\_miio, 灯光.xiaomi\_miio ([@danielhiversen] - [#9426]) (breaking change) * Swiss Public Transport 传感器: All times handled by the Swiss Public Transport 传感器 are now in ISO 8601 format. Please 更新 your 模板 传感器 and 自动化. ([@fabaff] - [#9129]) ([传感器.swiss\_public\_transport docs][传感器.swiss_public_transport docs]) (breaking change) * iOS: All category identifiers need to be lowercase. If you do not 更新, it will break actionable 通知 to IOS 设备 sent by 脚本/自动化. ([@rbflurry] - [#9427]) (breaking change) * Fitbit: Put endpoints behind `/api` like the other oauth-using components ([@happyleavesaoc] - [#9460]) ([传感器.fitbit docs]) (breaking change) * 版本 0.53 introduced a bug in the HomeMatic component which breaks the usage of system variables on the CCU / Homegear. This has not been fixed yet. If you are using these variables in your 自动化 you should skip updates until the bug has been resolved. Upgrading is safe however if you only interact with 设备. ## 全部变更 * Add HTTP Basic auth to RESTful 开关 ([@amelchio] - [#9162]) ([开关.rest docs]) * Bump pywebpush and pyJWT versions ([@fanaticDavid] - [#9355]) ([通知.html5 docs]) * Add /usr/sbin to PATH ([@morberg] - [#9364]) * Add polling interval 服务 and setting available through zwave node 实体 面板 ([@turbokongen] - [#9056]) ([zwave docs]) * Round off probability to 2 decimals. ([@arsaboo] - [#9365]) ([binary\_sensor.bayesian docs][binary_sensor.bayesian docs]) * Added mqtt\_statestream component ([@mw-white] - [#9286]) ([mqtt\_statestream docs][mqtt_statestream docs]) (new-platform) * typo in waypoint import topic preventing waypoint import ([@diplix] - [#9338]) ([device\_tracker.owntracks docs][device_tracker.owntracks docs]) * Cleanup and simplitfy the async 状态 更新 ([@pvizeli] - [#9390]) * 更新 cloud auth ([@balloob] - [#9357]) * Allow multiple observations of same 实体 ([@jlmcgehee21] - [#9391]) ([binary\_sensor.bayesian docs][binary_sensor.bayesian docs]) * Break up Alexa per functionality ([@balloob] - [#9400]) ([alexa docs]) * 升级 psutil to 5.3.1 ([@fabaff] - [#9403]) ([传感器.systemmonitor docs]) * fix mopar 传感器 ([@happyleavesaoc] - [#9389]) * Support specifying no Apple TVs ([@postlund] - [#9394]) ([apple\_tv docs][apple_tv docs]) * 更新 netdisco to 1.2.0 ([@balloob] - [#9408]) * components/xiaomi: Add initial discovery using NetDisco. ([@pfalcon] - [#9283]) * Fix copy\&paste mistake ([@tinloaf] - [#9378]) * Added 日志-file command line flag ([@TD22057] - [#9422]) * Add LC\_CTYPE to environment variables in macOS ([@morberg] - [#9227]) * Added more 设备 and types to onewire ([@tcastberg] - [#9404]) ([传感器.onewire docs]) (breaking change) * Bump uvcclient to 0.10.1 to work with beta NVR releases ([@antonym] - [#9423]) ([摄像头.uvc docs]) * full RGB support for 用户 of tradfri GW ([@spektren] - [#9411]) ([灯光.tradfri docs]) * Add support for Todoist platform ([@Jay2645] - [#9236]) ([日历.todoist docs]) (new-platform) * Fix artwork bug in Apple TV ([@postlund] - [#9415]) ([媒体播放器.apple\_tv docs][媒体播放器.apple_tv docs]) * Bump python-mirobo for improved 设备 support and introduce API changes. ([@syssi] - [#9424]) * MPD small improvements ([@pdanilew] - [#9301]) ([媒体播放器.mpd docs]) * 更新 broadlink.py to add support for MP1 开关 ([@giangvo] - [#9222]) ([开关.broadlink docs]) * Fix displaying of friendly\_name for 灯光 模板 component ([@rollbrettler] - [#9413]) ([灯光.模板 docs]) * Improve Python 脚本 ([@doudz] - [#9417]) ([python\_script docs][python_script docs]) * Add manual alarm\_control\_panel pending time per 状态 ([@snjoetw] - [#9264]) ([alarm\_control\_panel.manual docs][alarm_control_panel.manual docs]) * Rename xiaomi #9425 ([@danielhiversen] - [#9426]) (breaking change) * Bump 版本 of aioautomatic ([@armills] - [#9435]) * Fix russound\_rio for python 3.4 ([@wickerwaka] - [#9428]) ([媒体播放器.russound\_rio docs][媒体播放器.russound_rio docs]) * Basic MQTT 吸尘器 support ([@johnboiles] - [#9386]) ([吸尘器 docs]) ([吸尘器.MQTT docs]) (new-platform) * Optimaze 吸尘器 MQTT platform ([@pvizeli] - [#9439]) ([吸尘器.MQTT docs]) * Polymer access to 日志 file broken when using new 日志 file command line ([@TD22057] - [#9437]) * Allow empty hostnames when detecting 设备 with the aruba device\_tracker. ([@michaelarnauts] - [#9440]) ([device\_tracker.aruba docs][device_tracker.aruba docs]) * mqtt\_statestream: 更新 to append '状态' to topic for future use with MQTT discovery ([@mw-white] - [#9446]) ([mqtt\_statestream docs][mqtt_statestream docs]) * Fix for DTE Energy Bridge returning the wrong units from time to time ([@kylehendricks] - [#9246]) ([传感器.dte\_energy\_bridge docs][传感器.dte_energy_bridge docs]) * Refactor Swiss Public Transport 传感器 ([@fabaff] - [#9129]) ([传感器.swiss\_public\_transport docs][传感器.swiss_public_transport docs]) (breaking change) * Added Zyxel Keenetic NDMS2 based routers support for 设备 tracking ([@foxel] - [#9315]) ([device\_tracker.keenetic\_ndms2 docs][device_tracker.keenetic_ndms2 docs]) (new-platform) * Add city/状态/country options and fix bugs for airvisual ([@bachya] - [#9436]) ([传感器.airvisual docs]) * Fix emulated hue 警告 message ([@astone123] - [#9452]) ([emulated\_hue docs][emulated_hue docs]) * Alexa smart home native support ([@pvizeli] - [#9443]) * fix for Twitter 通知 without media ([@MikeChristianson] - [#9448]) * Load WebComponent polyfill on header. ([@fanthos] - [#9438]) * Fix issue 5728: Emulated Hue UPnP crashes on special characters. ([@SqyD] - [#9453]) * Ios 通知 摄像头 fix ([@rbflurry] - [#9427]) (breaking change) * Adds MQTT 风扇 Discovery ([@hufman] - [#9463]) * 升级 sqlalchemy to 1.1.14 ([@fabaff] - [#9458]) * 升级 uber\_rides to 0.6.0 ([@fabaff] - [#9457]) (传感器.uber docs) * 升级 youtube\_dl to 2017.9.15 ([@fabaff] - [#9456]) * DoorBird Component ([@Klikini] - [#9281]) ([doorbird docs]) (binary\_sensor.doorbird docs) ([摄像头.doorbird docs]) ([开关.doorbird docs]) (new-platform) * Fix recorder does not 吸尘器 SQLite DB on purge ([@milanvo] - [#9469]) * fitbit fixes ([@happyleavesaoc] - [#9460]) ([传感器.fitbit docs]) (breaking change) * Fix typo in 服务.yaml ([@mika] - [#9475]) * 升级 pyasn1 to 0.3.5 and pyasn1-modules to 0.1.4 ([@fabaff] - [#9474]) ([通知.xmpp docs]) * Xiaomi Gateway: Allow static 配置 of a gateway without discovery ([@syssi] - [#9464]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * Added support for the DTE Energy Bridge v2 ([@Blender3D] - [#9431]) ([传感器.dte\_energy\_bridge docs][传感器.dte_energy_bridge docs]) * Telnet 开关 ([@multiholle] - [#8913]) ([开关.telnet docs]) (new-platform) * Abode 服务, events, 灯光, 摄像头, 自动化, quick 动作. ([@MisterWil] - [#9310]) ([abode docs]) ([alarm\_control\_panel.abode docs][alarm_control_panel.abode docs]) ([binary\_sensor.abode docs][binary_sensor.abode docs]) ([摄像头.abode docs]) ([遮盖.abode docs]) ([灯光.abode docs]) ([门锁.abode docs]) ([开关.abode docs]) (new-platform) * Added satel\_integra 报警 面板 and 二元sensor platform ([@c-soft] - [#9336]) ([satel\_integra docs][satel_integra docs]) ([alarm\_control\_panel.satel\_integra docs][alarm_control_panel.satel_integra docs]) ([binary\_sensor.satel\_integra docs][binary_sensor.satel_integra docs]) (new-platform) * Worx Landroid 传感器 ([@nilzen] - [#9416]) ([传感器.worxlandroid docs]) (new-platform) * Fix universal 媒体播放器 mute ([@colindunn] - [#9462]) ([媒体播放器.universal docs]) * Small improvement of KNX 遮盖 ([@Julius2342] - [#9476]) * 升级 async\_timeout to 1.4.0 ([@fabaff] - [#9488]) * Bump 版本 of abodepy ([@MisterWil] - [#9491]) ([abode docs]) * 升级 coinmarketcap to 4.1.1 ([@fabaff] - [#9490]) ([传感器.coinmarketcap docs]) * 升级 blockchain to 1.4.0 ([@fabaff] - [#9489]) * Solve Recorder component failing when using Axis component ([@Kane610] - [#9293]) ([axis docs]) ([摄像头.axis docs]) * 开关 to pypi for xiaomi gw ([@danielhiversen] - [#9498]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * renamed add\_devices to async\_add\_devices according to hass naming scheme ([@Julius2342] - [#9485]) ([binary\_sensor.knx docs][binary_sensor.knx docs]) ([温控.knx docs]) ([灯光.knx docs]) ([传感器.knx docs]) ([开关.knx docs]) * Revert "renamed add\_devices to async\_add\_devices according to hass naming scheme (#9485)" ([@pvizeli] - [#9503]) ([alarm\_control\_panel.spc docs][alarm_control_panel.spc docs]) ([binary\_sensor.knx docs][binary_sensor.knx docs]) ([binary\_sensor.spc docs][binary_sensor.spc docs]) ([温控.knx docs]) ([灯光.knx docs]) ([传感器.citybikes docs]) ([传感器.knx docs]) ([传感器.worxlandroid docs]) ([开关.knx docs]) * LIFX: fix multi-区域 color 恢复 after effects ([@amelchio] - [#9492]) ([灯光.lifx docs]) * renamed add\_devices to async\_add\_devices according to hass naming scheme (second try after failed #9485) ([@Julius2342] - [#9505]) ([alarm\_control\_panel.spc docs][alarm_control_panel.spc docs]) ([binary\_sensor.knx docs][binary_sensor.knx docs]) ([binary\_sensor.spc docs][binary_sensor.spc docs]) ([温控.knx docs]) ([灯光.knx docs]) ([传感器.citybikes docs]) ([传感器.knx docs]) ([传感器.worxlandroid docs]) ([开关.knx docs]) * Xiaomi pycryptodome ([@danielhiversen] - [#9511]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * Bumped pyhomematic, additional 设备 support ([@danielperna84] - [#9506]) ([homematic docs]) ([传感器.homematic docs]) * abode: Bump abodepy dependency to 0.11.7 ([@vickyg3] - [#9504]) ([abode docs]) * abode: Set device\_type in 状态 属性 ([@vickyg3] - [#9515]) ([abode docs]) * 更新 xiaomi aqara lib ([@danielhiversen] - [#9520]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * added 服务.yaml 集成 for input\_boolean ([@skalavala] - [#9519]) ([input\_boolean docs][input_boolean docs]) * Add 重载 服务 to python\_script ([@doudz] - [#9512]) ([python\_script docs][python_script docs]) * MQTT 二元sensor - Add availability\_topic for online/offline status ([@marthoc] - [#9507]) ([binary\_sensor.MQTT docs][binary_sensor.MQTT docs]) * Fix typo within 遮盖/knx https://github.com/XKNX/xknx/issues/64 ([@Julius2342] - [#9527]) ([遮盖.knx docs]) * LIFX: improve performance of setting multi-区域 灯光 to a single color ([@amelchio] - [#9526]) ([灯光.lifx docs]) [#8913]: https://github.com/home-assistant/home-assistant/pull/8913 [#9056]: https://github.com/home-assistant/home-assistant/pull/9056 [#9129]: https://github.com/home-assistant/home-assistant/pull/9129 [#9162]: https://github.com/home-assistant/home-assistant/pull/9162 [#9222]: https://github.com/home-assistant/home-assistant/pull/9222 [#9227]: https://github.com/home-assistant/home-assistant/pull/9227 [#9236]: https://github.com/home-assistant/home-assistant/pull/9236 [#9246]: https://github.com/home-assistant/home-assistant/pull/9246 [#9264]: https://github.com/home-assistant/home-assistant/pull/9264 [#9281]: https://github.com/home-assistant/home-assistant/pull/9281 [#9283]: https://github.com/home-assistant/home-assistant/pull/9283 [#9286]: https://github.com/home-assistant/home-assistant/pull/9286 [#9293]: https://github.com/home-assistant/home-assistant/pull/9293 [#9301]: https://github.com/home-assistant/home-assistant/pull/9301 [#9310]: https://github.com/home-assistant/home-assistant/pull/9310 [#9315]: https://github.com/home-assistant/home-assistant/pull/9315 [#9336]: https://github.com/home-assistant/home-assistant/pull/9336 [#9338]: https://github.com/home-assistant/home-assistant/pull/9338 [#9355]: https://github.com/home-assistant/home-assistant/pull/9355 [#9357]: https://github.com/home-assistant/home-assistant/pull/9357 [#9364]: https://github.com/home-assistant/home-assistant/pull/9364 [#9365]: https://github.com/home-assistant/home-assistant/pull/9365 [#9378]: https://github.com/home-assistant/home-assistant/pull/9378 [#9386]: https://github.com/home-assistant/home-assistant/pull/9386 [#9389]: https://github.com/home-assistant/home-assistant/pull/9389 [#9390]: https://github.com/home-assistant/home-assistant/pull/9390 [#9391]: https://github.com/home-assistant/home-assistant/pull/9391 [#9394]: https://github.com/home-assistant/home-assistant/pull/9394 [#9400]: https://github.com/home-assistant/home-assistant/pull/9400 [#9403]: https://github.com/home-assistant/home-assistant/pull/9403 [#9404]: https://github.com/home-assistant/home-assistant/pull/9404 [#9408]: https://github.com/home-assistant/home-assistant/pull/9408 [#9411]: https://github.com/home-assistant/home-assistant/pull/9411 [#9413]: https://github.com/home-assistant/home-assistant/pull/9413 [#9415]: https://github.com/home-assistant/home-assistant/pull/9415 [#9416]: https://github.com/home-assistant/home-assistant/pull/9416 [#9417]: https://github.com/home-assistant/home-assistant/pull/9417 [#9422]: https://github.com/home-assistant/home-assistant/pull/9422 [#9423]: https://github.com/home-assistant/home-assistant/pull/9423 [#9424]: https://github.com/home-assistant/home-assistant/pull/9424 [#9426]: https://github.com/home-assistant/home-assistant/pull/9426 [#9427]: https://github.com/home-assistant/home-assistant/pull/9427 [#9428]: https://github.com/home-assistant/home-assistant/pull/9428 [#9431]: https://github.com/home-assistant/home-assistant/pull/9431 [#9435]: https://github.com/home-assistant/home-assistant/pull/9435 [#9436]: https://github.com/home-assistant/home-assistant/pull/9436 [#9437]: https://github.com/home-assistant/home-assistant/pull/9437 [#9438]: https://github.com/home-assistant/home-assistant/pull/9438 [#9439]: https://github.com/home-assistant/home-assistant/pull/9439 [#9440]: https://github.com/home-assistant/home-assistant/pull/9440 [#9443]: https://github.com/home-assistant/home-assistant/pull/9443 [#9446]: https://github.com/home-assistant/home-assistant/pull/9446 [#9448]: https://github.com/home-assistant/home-assistant/pull/9448 [#9452]: https://github.com/home-assistant/home-assistant/pull/9452 [#9453]: https://github.com/home-assistant/home-assistant/pull/9453 [#9456]: https://github.com/home-assistant/home-assistant/pull/9456 [#9457]: https://github.com/home-assistant/home-assistant/pull/9457 [#9458]: https://github.com/home-assistant/home-assistant/pull/9458 [#9460]: https://github.com/home-assistant/home-assistant/pull/9460 [#9462]: https://github.com/home-assistant/home-assistant/pull/9462 [#9463]: https://github.com/home-assistant/home-assistant/pull/9463 [#9464]: https://github.com/home-assistant/home-assistant/pull/9464 [#9469]: https://github.com/home-assistant/home-assistant/pull/9469 [#9474]: https://github.com/home-assistant/home-assistant/pull/9474 [#9475]: https://github.com/home-assistant/home-assistant/pull/9475 [#9476]: https://github.com/home-assistant/home-assistant/pull/9476 [#9485]: https://github.com/home-assistant/home-assistant/pull/9485 [#9488]: https://github.com/home-assistant/home-assistant/pull/9488 [#9489]: https://github.com/home-assistant/home-assistant/pull/9489 [#9490]: https://github.com/home-assistant/home-assistant/pull/9490 [#9491]: https://github.com/home-assistant/home-assistant/pull/9491 [#9492]: https://github.com/home-assistant/home-assistant/pull/9492 [#9498]: https://github.com/home-assistant/home-assistant/pull/9498 [#9503]: https://github.com/home-assistant/home-assistant/pull/9503 [#9504]: https://github.com/home-assistant/home-assistant/pull/9504 [#9505]: https://github.com/home-assistant/home-assistant/pull/9505 [#9506]: https://github.com/home-assistant/home-assistant/pull/9506 [#9507]: https://github.com/home-assistant/home-assistant/pull/9507 [#9511]: https://github.com/home-assistant/home-assistant/pull/9511 [#9512]: https://github.com/home-assistant/home-assistant/pull/9512 [#9515]: https://github.com/home-assistant/home-assistant/pull/9515 [#9519]: https://github.com/home-assistant/home-assistant/pull/9519 [#9520]: https://github.com/home-assistant/home-assistant/pull/9520 [#9526]: https://github.com/home-assistant/home-assistant/pull/9526 [#9527]: https://github.com/home-assistant/home-assistant/pull/9527 [@MisterWil]: https://github.com/MisterWil [@pdanilew]: https://github.com/pdanilew [@marthoc]: https://github.com/marthoc [@spektren]: https://github.com/spektren [@Blender3D]: https://github.com/Blender3D [@Jay2645]: https://github.com/Jay2645 [@Julius2342]: https://github.com/Julius2342 [@Kane610]: https://github.com/Kane610 [@Klikini]: https://github.com/Klikini [@MikeChristianson]: https://github.com/MikeChristianson [@SqyD]: https://github.com/SqyD [@TD22057]: https://github.com/TD22057 [@amelchio]: https://github.com/amelchio [@antonym]: https://github.com/antonym [@armills]: https://github.com/armills [@arsaboo]: https://github.com/arsaboo [@astone123]: https://github.com/astone123 [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@c-soft]: https://github.com/c-soft [@colindunn]: https://github.com/colindunn [@danielhiversen]: https://github.com/danielhiversen [@danielperna84]: https://github.com/danielperna84 [@diplix]: https://github.com/diplix [@doudz]: https://github.com/doudz [@fabaff]: https://github.com/fabaff [@fanaticDavid]: https://github.com/fanaticDavid [@fanthos]: https://github.com/fanthos [@foxel]: https://github.com/foxel [@giangvo]: https://github.com/giangvo [@happyleavesaoc]: https://github.com/happyleavesaoc [@hufman]: https://github.com/hufman [@jlmcgehee21]: https://github.com/jlmcgehee21 [@johnboiles]: https://github.com/johnboiles [@kylehendricks]: https://github.com/kylehendricks [@michaelarnauts]: https://github.com/michaelarnauts [@mika]: https://github.com/mika [@milanvo]: https://github.com/milanvo [@morberg]: https://github.com/morberg [@multiholle]: https://github.com/multiholle [@mw-white]: https://github.com/mw-white [@nilzen]: https://github.com/nilzen [@pfalcon]: https://github.com/pfalcon [@postlund]: https://github.com/postlund [@pvizeli]: https://github.com/pvizeli [@rbflurry]: https://github.com/rbflurry [@rollbrettler]: https://github.com/rollbrettler [@skalavala]: https://github.com/skalavala [@snjoetw]: https://github.com/snjoetw [@syssi]: https://github.com/syssi [@tcastberg]: https://github.com/tcastberg [@tinloaf]: https://github.com/tinloaf [@turbokongen]: https://github.com/turbokongen [@vickyg3]: https://github.com/vickyg3 [@wickerwaka]: https://github.com/wickerwaka [abode docs]: /integrations/abode/ [alarm_control_panel.abode docs]: /integrations/abode [alarm_control_panel.manual docs]: /integrations/manual [alarm_control_panel.satel_integra docs]: /integrations/satel_integra [alarm_control_panel.spc docs]: /integrations/spc [alexa docs]: /integrations/alexa/ [api docs]: /integrations/api/ [apple_tv docs]: /integrations/apple_tv/ [axis docs]: /integrations/axis/ [binary_sensor.abode docs]: /integrations/abode#binary-传感器 [binary_sensor.bayesian docs]: /integrations/bayesian [binary_sensor.knx docs]: /integrations/binary_sensor.knx/ [binary_sensor.MQTT docs]: /integrations/binary_sensor.MQTT/ [binary_sensor.satel_integra docs]: /integrations/satel_integra [binary_sensor.spc docs]: /integrations/spc#binary-传感器 [日历.todoist docs]: /integrations/todoist [摄像头.abode docs]: /integrations/abode [摄像头.axis docs]: /integrations/axis [摄像头.doorbird docs]: /integrations/doorbird#摄像头 [摄像头.uvc docs]: /integrations/uvc [温控.knx docs]: /integrations/温控.knx/ [config.zwave docs]: /integrations/config.zwave/ [遮盖.abode docs]: /integrations/abode [遮盖.knx docs]: /integrations/遮盖.knx/ [device_tracker.aruba docs]: /integrations/aruba [device_tracker.keenetic_ndms2 docs]: /integrations/keenetic_ndms2 [device_tracker.owntracks docs]: /integrations/owntracks [doorbird docs]: /integrations/doorbird/ [emulated_hue docs]: /integrations/emulated_hue/ [homematic docs]: /integrations/homematic/ [input_boolean docs]: /integrations/input_boolean/ [灯光.abode docs]: /integrations/abode#灯光 [灯光.knx docs]: /integrations/灯光.knx/ [灯光.lifx docs]: /integrations/lifx [灯光.模板 docs]: /integrations/灯光.模板/ [灯光.tradfri docs]: /integrations/tradfri [灯光.xiaomi_philipslight docs]: /integrations/灯光.xiaomi_miio/ [门锁.abode docs]: /integrations/abode [媒体播放器.apple_tv docs]: /integrations/apple_tv [媒体播放器.mpd docs]: /integrations/mpd [媒体播放器.russound_rio docs]: /integrations/russound_rio [媒体播放器.universal docs]: /integrations/universal [mqtt_statestream docs]: /integrations/mqtt_statestream/ [通知.html5 docs]: /integrations/html5 [通知.xmpp docs]: /integrations/xmpp [python_script docs]: /integrations/python_script/ [satel_integra docs]: /integrations/satel_integra/ [传感器.airvisual docs]: /integrations/airvisual [传感器.citybikes docs]: /integrations/citybikes [传感器.coinmarketcap docs]: /integrations/coinmarketcap [传感器.dte_energy_bridge docs]: /integrations/dte_energy_bridge [传感器.fitbit docs]: /integrations/fitbit [传感器.homematic docs]: /integrations/homematic [传感器.knx docs]: /integrations/传感器.knx/ [传感器.onewire docs]: /integrations/onewire [传感器.swiss_public_transport docs]: /integrations/swiss_public_transport [传感器.systemmonitor docs]: /integrations/systemmonitor [传感器.worxlandroid docs]: /integrations/worxlandroid [开关.abode docs]: /integrations/abode#开关 [开关.broadlink docs]: /integrations/broadlink#开关 [开关.doorbird docs]: /integrations/doorbird#开关 [开关.knx docs]: /integrations/开关.knx/ [开关.rest docs]: /integrations/开关.rest/ [开关.telnet docs]: /integrations/telnet [吸尘器 docs]: /integrations/吸尘器/ [吸尘器.MQTT docs]: /integrations/吸尘器.MQTT/ [吸尘器.xiaomi docs]: /integrations/吸尘器.xiaomi_miio/ [xiaomi docs]: /integrations/xiaomi_aqara [xiaomi_aqara docs]: /integrations/xiaomi_aqara/ [zwave docs]: /integrations/zwave/ [forum]: https://community.home-assistant.io/ [issue]: https://github.com/home-assistant/home-assistant/issues [discord]: https://discord.gg/c5DvZ4e --- url: /home-assistant/blog/2017-09-25-new-hassio-build-system.md --- # Improved Hass.io build system :::note This is going to be a technical post for Hass.io 插件 开发者 and people that run locally build 插件 (not the default). ::: Two months ago we [introduced Hass.io][intro], allowing our 用户 to easily 安装, 更新 and manage their Home Assistant 安装. In this short time we've seen great adoption from the community. Around 20% of our 用户 are choosing Hass.io as their method of running Home Assistant today. We've also seen many 插件 being made available on [the forums][插件-repos]. There are currently 14 reposities full of 插件 being shared! Hass.io is built on top of Docker, a 容器 runtime. One thing that Docker did not support was dynamic build environements. That was annoying for Hass.io because by supporting multiple CPU architectures, that was exactly what we needed! Luckily this feature has been added in Docker 17.05. By moving to Docker 17.05 as the minimum supported 版本 we will be able to replace our templated Dockerfile approach with standard Dockerfiles that work out of the box. Thanks to [Frenck][frenck] for notifying us of this new build feature. This change only impacts people that build 插件 or use 插件 that are built locally. You can check if your 插件 is building locally on the detail page of 插件. :::tip If you are an 插件 developer, read [the 文档][publishing-插件] on how to publish your 插件 to Docker Hub. This will greatly improve the 用户 experience. ::: ### 模板 changes As an 插件 developer, you will only have to change one line in your 模板 to make it compatible with the new system. If you wish, you can also change the default build options for your 图像 using the new [`build.json`][build-file] file. Old: ```dockerfile FROM %%BASE_IMAGE%% ``` New: ```dockerfile ARG BUILD_FROM FROM $BUILD_FROM ``` ### When The new system will become active with Hass.io 0.64 and Host OS 1.1. Host OS 1.1 is available today. Navigate to Advanced 设置 in the Hass.io 面板 to start the OTA 更新. We have also updated our build 脚本 and replaced it with a [builder Docker engine][builder]. This builder makes deploying Hass.io components very easy. All basic functionality is supported. If you want more functionality, check out [the builder by the Community Hass.io 插件 project][community-builder]. [hassio-hardware-图像-发布]: https://github.com/home-assistant/hassio-build/releases/tag/1.1 [安装]: /hassio/installation/ [builder]: https://github.com/home-assistant/hassio-builder [frenck]: https://github.com/frenck [build-file]: /developers/hassio/addon_config/#插件-extended-build [插件-repos]: https://community.home-assistant.io/tags/hassio-repository [community-builder]: https://github.com/hassio-addons/build-env [intro]: /博客/2017/07/25/introducing-hassio/ [publishing-插件]: /developers/hassio/addon_publishing/#custom-插件 --- url: /home-assistant/blog/2017-09-27-effortless-encryption-with-lets-encrypt-and-duckdns.md --- # Effortless encryption with Let's Encrypt and DuckDNS When Let's Encrypt launched we were estatic: finally an easy and free way for our 用户 to securely access their homes remotely. Let's Encrypt signifianctly lowered the bar to get and renew SSL certificates. However, this process could still be quite an obstacle for our 用户. It required opening ports on the router and remembering to renew the certificate every so often. Thanks to a [博客 post][splitbrain] by Andreas Gohr I realized that DuckDNS supports setting TXT records, making it compatible with the DNS-01 challenge of Let's Encrypt. The DNS-01 challenge is using the DNS record of the domain instead of interacting with the server. This means that it's not needed for the 用户 to open any ports! I have worked together with [Pascal Vizeli][pvizeli] on updating the DuckDNS 插件 for Hass.io and today we're proud to announce it now includes automatic generation and updating of Let's Encrypt certificates for your DuckDNS domain. The only thing that you have to add to your DuckDNS 配置 is that you accept the Let's Encrypt [terms of 服务][terms] and point Home Assistant at the generated certificates and you're good to go. No other work is required. To get started today, start with making sure that you have [Hass.io 已安装][hassio]. After that, go to the Hass.io 面板 in Home Assistant, open the 插件 store, scroll down to DuckDNS and 安装 it. In the DuckDNS 设置 change "accept\_terms" to true and start it. Next up is to 配置 Home Assistant with the config below and 重启 it. You're now good to go! Make sure to use the right protocol when browsing to your instance: `https://.duckdns.org`. Happy secure controlling your house! ```yaml # Example configuration.yaml entry for the HTTP component http: ssl_certificate: /ssl/fullchain.pem ssl_key: /ssl/privkey.pem ``` If you're not using Hass.io, check out the [博客 post][splitbrain] by Andreas for instructions. If you enjoy the free 服务 provided by DuckDNS and Let's Encrypt, consider donating to their cause: * [Become a Patreon of DuckDNS](https://www.patreon.com/user?u=3209735) * [Donate to Let's Encrypt](https://letsencrypt.org/donate/) More information: * [Hass.io][hassio] * [Installing Hass.io][hassio-安装] * [DuckDNS 插件][插件-duckdns] * [DuckDNS][duckdns] * [Let's Encrypt][le] [splitbrain]: https://www.splitbrain.org/博客/2017-08/10-homeassistant_duckdns_letsencrypt [terms]: https://letsencrypt.org/repository/ [pvizeli]: https://github.com/pvizeli [hassio]: /hassio/ [hassio-安装]: /hassio/installation/ [插件-duckdns]: /插件/duckdns/ [duckdns]: http://www.duckdns.org/ [le]: https://letsencrypt.org/ --- url: /home-assistant/blog/2017-09-29-hacktoberfest.md --- # Participating in Hacktoberfest For the second year in a row, Home Assistant will be participating in [Hacktoberfest]. Hacktoberfest is an event organized by DigitalOcean and GitHub to support and celebrate 开源. The idea is that 开源 projects like Home Assistant will gather a bunch of entry-level bugs, features, and 文档 enhancements and that you, a current or future contributor, will help us fix them. If you submit four pull-requests during October, you will have earned yourself a limited edition Hacktoberfest T-shirt! Why contribute to Home Assistant? * Written in Python 3 with 94% test coverage * Active and helpful community * Friendly to new contributors Resources to get started: * [Sign up for Hacktoberfest][Hacktoberfest-reg] * [List of entry-level issues for Home Assistant][issues] * [Instructions to 设置 your development environment][dev-env] * [Home Assistant Development Chat][dev-chat] * [Home Assistant Development Forums][dev-forum] * [Hacktoberfest website][Hacktoberfest] Are you not a programmer but still want to contribute to Home Assistant? Check out our [list of entry-level issues for the Home Assistant website][issues-doc]. Our participation for [Hacktoberfest 2016][hackt-2016] was a huge success. Join us to repeat it this year. [![Hacktober fest logo][logo]][Hacktoberfest] [logo]: /images/blog/2016-10-hacktoberfest/hacktoberfest.png [Hacktoberfest]: https://hacktoberfest.digitalocean.com/ [Hacktoberfest-reg]: https://hacktoberfest.digitalocean.com/profile [issues]: https://github.com/home-assistant/home-assistant/labels/Hacktoberfest [issues-doc]: https://github.com/home-assistant/home-assistant.io/labels/Hacktoberfest [dev-env]: /developers/development_environment/index.md [dev-chat]: https://discord.gg/8X8DTH4 [dev-forum]: https://community.home-assistant.io/c/development [hackt-2016]: /博客/2016/11/05/hacktoberfest-influxdb-天气/#hacktoberfest --- url: /home-assistant/blog/2017-10-01-hass-podcast-ep9.md --- # Home Assistant Podcast #9 Dale ([dale3h](https://github.com/dale3h)) joins Rohan and Dan to talk about Dale’s involvement in the project as a community leader and his contributions. Dale and Rohan also 遮盖 off the 0.54 发布. Show notes available on the [Home Assistant Podcast Website](https://hasspodcast.io/ha009/). [Listen online][episode] [episode]: https://hasspodcast.io/ha009/ --- url: /home-assistant/blog/2017-10-06-deprecating-python-3.4-support.md --- # Deprecating Python 3.4 support **更新 February 16, 2018**: Home Assistant 0.64 will be the last 发布 to support Python 3.4. Starting with 发布 0.65, Home Assistant will require a minimum 版本 of Python 3.5.3. *** Starting with our next 发布, 0.55, we will deprecate Python 3.4 support. The current plan is to remove support for Python 3.4 at the beginning of 2018. Python 3.5 was released on September 13th, 2015. It has since then become the default Python 安装 on the stable releases of Debian, Ubuntu, Raspbian and Hassbian. Our other own operating system, Hass.io, is more advanced and is already running the greatly improved Python 3.6. The jump to Python 3.5 as a minimum 版本 is driven by the Home Assistant 核心, which is based on asyncio. Starting with Python 3.5, asyncio got improved support in the language with dedicated keywords `async` and `await`. As this is the proper way of doing async in Python, we're seeing a move by async libraries to either only support the new syntax from the beginning or dropping support for the Python 3.4 approach. Not moving along means an increased maintenance burden as we cannot use the latest releases of our libraries. Next to that it will prevent our 用户 from being able to leverage the bug fixes and performance improvements that come with Python 3.5. #### Hass.io If you're running Hass.io, you don't have to do anything. Your system will always stay up to date. #### Hassbian If you're running Hassbian it's recommended that you make a 备份 of your 配置 files and 恢复 them on a fresh 安装. Upgrading an existing 安装 isn't recommended. #### Windows If you're on Windows, you're fine as our minimum 版本 for Windows has been 3.5 for a while now. #### Other Debian based systems If you're running a Debian based system, follow [these instructions][dist-升级] to 升级. [dist-升级]: https://linuxconfig.org/raspbian-gnu-linux-升级-from-jessie-to-raspbian-stretch-9 --- url: /home-assistant/blog/2017-10-07-release-55.md --- # 0.55: Tibber、DuckDNS、The Things Network、Owntrack 除了 [@w1ll1am23] 带来的 Wink 支持增强之外,这次发布还加入了大量新的组件与平台。`input_slider` 组件经过 [@BioSehnsucht] 的改造,现在变成了 [`input_number`][input_number docs]。[@tinloaf] 还新增了一个允许输入日期的功能:[`input_datetime`][input_datetime docs]。这两者都会帮助你改进自动化规则。 ## DuckDNS 通过 [DuckDNS](http://www.duckdns.org) 为 Home Assistant 提供动态 DNS(DDNS 或 DynDNS)已经是个[老话题](/home-assistant/blog/2015/12/13/设置-encryption-using-lets-encrypt/)了。DuckDNS 也已集成进 [Hass.io](/home-assistant/addons/duckdns/)。而在 0.55 中,非 Hass.io 用户也终于可以通过组件获得类似功能。 ## Recorder 数据清理能力得到了[改进][recorder docs]。通过 `purge_interval`,你可以定期清理较旧的事件和状态;配合 `purge_keep_days`,还可以指定希望保留多少天的数据。新的服务 `recorder.purge` 则允许你在需要时手动处理这项任务。 ## OwnTracks [Owntracks](http://owntracks.org/) 是一种便捷的设备追踪方式。过去我们提供的是依赖 [MQTT][device_tracker.owntracks docs] 的设备追踪平台,而现在借助 Owntracks 的一项新特性,我们也支持 HTTP 了。这个[新平台][device_tracker.owntracks_http docs] 不再需要 MQTT broker,而是直接通过 HTTP 请求向 Home Assistant 发送消息。 ## Tibber 这个版本引入了一个新的传感器:[Tibber][传感器.tibber docs]。如果你是 [Tibber](https://tibber.com/) 用户,这个传感器可以提供当前电价。这样你就可以编写自动化,例如在电价高时关闭暖气,或只在电价低时给电动车充电。我们还计划进一步支持未来电价和历史用电数据展示。Tibber 目前仅在挪威和瑞典提供服务。 ## The Things Network [The Things Network](https://www.thethingsnetwork.org/)(TTN)是一个基于 [LoRaWAN](https://www.thethingsnetwork.org/wiki/LoRaWAN/Home) 的网络,专为 IoT 设备设计。通过这个[集成][thethingsnetwork docs],只要设备连接到 TTN 网关,即使它们超出本地 WiFi 网络覆盖范围,你也依然可以观察它们的状态。 ## 新平台 * GeoRSS 传感器 ([@exxamalte] - [#9331]) ([传感器.geo\_rss\_events docs][传感器.geo_rss_events docs]) (new-platform) * Add DuckDNS component ([@balloob] - [#9556]) ([duckdns docs]) (new-platform) * Add OwnTracks over HTTP ([@balloob] - [#9582]) ([http docs]) ([device\_tracker.owntracks docs][device_tracker.owntracks docs]) ([device\_tracker.owntracks\_http docs][device_tracker.owntracks_http docs]) (new-platform) * Add an input\_datetime ([@tinloaf] - [#9313]) ([input\_datetime docs][input_datetime docs]) (new-platform) * 遮盖 component for RFlink ([@passie] - [#9432]) ([rflink docs]) ([遮盖.rflink docs]) (new-platform) * Introducing support to Melnor RainCloud sprinkler systems ([@tchellomello] - [#9287]) ([raincloud docs]) ([binary\_sensor.raincloud docs][binary_sensor.raincloud docs]) ([传感器.raincloud docs]) ([开关.raincloud docs]) (new-platform) * MQTT 温控 platform \[continuation of #8750] ([@tinloaf] - [#9589]) ([温控.MQTT docs]) (new-platform) * Add Tibber 传感器 ([@danielhiversen] - [#9661]) ([传感器.tibber docs]) (new-platform) * Updating clicksendaudio component based on feedback ([@jeroenterheerdt] - [#9692]) ([通知.clicksendaudio docs]) (new-platform) * Support for The Things Network ([@fabaff] - [#9627]) ([thethingsnetwork docs]) ([传感器.thethingsnetwork docs]) (new-platform) ## 0.55.1 - October 15 * Fix for TypeError in synology 摄像头 ([@snjoetw] - [#9754]) ([摄像头.synology docs]) * missing is\_closed ( rflink 遮盖 fix ) ([@passie] - [#9776]) ([遮盖.rflink docs]) * \[灯光.tradfri] Fix transition time ([@lwis] - [#9785]) ([灯光.tradfri docs]) * OwnTracks: Fix handler is None checking ([@balloob] - [#9794]) ([device\_tracker.owntracks docs][device_tracker.owntracks docs]) * Changed yaml.load into yaml.safe\_load ([@GenericStudent] - [#9841]) ([google docs]) * Bugfix/9811 jinja autoescape ([@GenericStudent] - [#9842]) * Livebox Play TV bug: fix #9839 ([@pschmitt] - [#9880]) ## 如果你需要帮助…… 欢迎使用我们非常活跃的 [论坛][forum],或加入 [聊天频道][discord] 与我们交流。虽然发布说明也开放评论,但我们更推荐使用前面的沟通渠道。谢谢。 ## 反馈问题 如果你遇到了这个版本引入的问题,请前往我们的 [issue tracker][issue] 提交反馈,并确保填写 issue 模板中的所有字段。 ## 不向后兼容的变更 * history\_graph component: If your component used `history.get_significant_states` function then you need to adjust the string `entity_id` parameter has been changed to a list of strings `entity_ids` parameter. ([@andrey-git] - [#9472]) (breaking change) * UPNP component: The `external_port` 配置 option was removed. ([@balloob] - [#9560]) ([upnp docs]) (breaking change) * New Wink 服务: pair new 设备, rename, delete and add new 门锁 key code. All 设备 属性 that are multi-words are now separated by "\_" and no longer " ". ([@w1ll1am23] - [#9303]) ([wink docs]) ([binary\_sensor.wink docs][binary_sensor.wink docs]) ([门锁.wink docs]) (breaking change) * TP-Link 开关: 属性 names now uses underscores and unnecessary capitalization was removed. ([@djchen] - [#9607]) ([开关.tplink docs]) (breaking change) * Renamed `input_slider` to `input_number` which has now a numeric text box option. ([@BioSehnsucht] - [#9494]) ([demo docs]) ([input\_number docs][input_number docs]) (breaking change) * Recorder: Add new purge 服务 and interval. The recorder component no longer accepts a `purge_days` parameter. If you are using `purge_days` you must use `purge_interval` and `purge_keep_days`. ([@milanvo] - [#9523]) ([recorder docs]) (breaking change) * OpenCV 图像 processing: Typo in classifier was fixed. ([@arsaboo] - [#9697]) ([image\_processing.opencv docs][image_processing.opencv docs]) (breaking change) * Tradfri 灯光: Async support with resource observation. ([@lwis] - [#7815]) ([tradfri docs]) ([灯光.tradfri docs]) (breaking change) ## 全部变更 * flux led lib 0.20 ([@danielhiversen] - [#9533]) ([灯光.flux\_led docs][灯光.flux_led docs]) * 更新 AbodePy to 0.11.8 ([@MisterWil] - [#9537]) ([abode docs]) * Bump python\_openzwave to 0.4.0.35 ([@arsaboo] - [#9542]) ([zwave docs]) * 更新 usps ([@happyleavesaoc] - [#9540]) * Bugfix Homematic hub object ([@pvizeli] - [#9544]) ([homematic docs]) * Fix a bunch of typos ([@mika] - [#9545]) * Catch no longer existing process in systemmonitor ([@Tommatheussen] - [#9535]) ([传感器.systemmonitor docs]) * 升级 pyasn1 to 0.3.6 ([@fabaff] - [#9548]) * Add history\_graph component ([@andrey-git] - [#9472]) (breaking change) * GeoRSS 传感器 ([@exxamalte] - [#9331]) ([传感器.geo\_rss\_events docs][传感器.geo_rss_events docs]) (new-platform) * Fixed bug with all 开关 设备 being excluded ([@MisterWil] - [#9555]) ([开关.abode docs]) * fix usps? ([@happyleavesaoc] - [#9557]) * Added support for ARM\_NIGHT for manual\_mqtt 报警 ([@snjoetw] - [#9358]) ([alarm\_control\_panel.manual\_mqtt docs][alarm_control_panel.manual_mqtt docs]) * Various AirVisual bugfixes ([@bachya] - [#9554]) ([传感器.airvisual docs]) * Updated Arlo 摄像头 with new 属性 ([@bachya] - [#9565]) ([arlo docs]) ([摄像头.arlo docs]) * Allow specifying multiple ports for UPNP component ([@balloob] - [#9560]) ([upnp docs]) (breaking change) * 更新 yeelight to 0.3.3. ([@pfalcon] - [#9561]) ([灯光.yeelight docs]) * Add test cases and fix for device\_defaults fire\_event option. ([@aequitas] - [#9567]) ([灯光.rflink docs]) ([开关.rflink docs]) * Use simplepush module, enable event, and allow encrypted communication ([@fabaff] - [#9568]) ([通知.simplepush docs]) * Add DuckDNS component ([@balloob] - [#9556]) ([duckdns docs]) (new-platform) * Clean up OwnTracks ([@balloob] - [#9569]) ([device\_tracker.owntracks docs][device_tracker.owntracks docs]) * MQTT 遮盖: Add availability topic and configurable payloads ([@marthoc] - [#9445]) ([遮盖.MQTT docs]) * 升级 dsmr\_parser to 0.11 ([@fabaff] - [#9576]) ([传感器.dsmr docs]) * Added new statistic 属性 ([@sti0] - [#9433]) ([吸尘器.xiaomi docs]) * 升级 youtube\_dl to 2017.9.24 ([@fabaff] - [#9575]) ([media\_extractor docs][media_extractor docs]) * 升级 lyft\_rides to 0.2 ([@enriquegh] - [#9578]) ([传感器.lyft docs]) * Increase Comed timeout since it sometimes takes a long time for the API to respond ([@joe248] - [#9536]) ([传感器.comed\_hourly\_pricing docs][传感器.comed_hourly_pricing docs]) * Allow customizable 打开 动作 for LG WebOS tv ([@cmsimike] - [#9206]) ([媒体播放器.webostv docs]) (breaking change) * IMAP Unread 传感器 updated for async and push ([@amelchio] - [#9562]) ([传感器.imap docs]) * Replace emulated\_hue: with emulated\_hue\_hidden: for consistency. ([@rbflurry] - [#9382]) ([emulated\_hue docs][emulated_hue docs]) * 升级 Sphinx to 1.6.4 ([@fabaff] - [#9584]) * Bump pyatv to 0.3.5 ([@postlund] - [#9586]) ([apple\_tv docs][apple_tv docs]) ([媒体播放器.apple\_tv docs][媒体播放器.apple_tv docs]) * New Wink 服务. pair new 设备, rename, and delete, add new 门锁 key code. Add 热水器 support ([@w1ll1am23] - [#9303]) ([wink docs]) ([binary\_sensor.wink docs][binary_sensor.wink docs]) ([门锁.wink docs]) (breaking change) * Fixes UPS MyChoice exception ([@bachya] - [#9587]) * FedEx: Adds "packages" as a unit ([@bachya] - [#9588]) * Cleanup 实体 & remove 警告 ([@pvizeli] - [#9606]) * Add OwnTracks over HTTP ([@balloob] - [#9582]) ([http docs]) ([device\_tracker.owntracks docs][device_tracker.owntracks docs]) ([device\_tracker.owntracks\_http docs][device_tracker.owntracks_http docs]) (new-platform) * 升级 python-ecobee-api ([@nkgilley] - [#9612]) ([ecobee docs]) * Change TP-Link 开关 power statistics 属性 names ([@djchen] - [#9607]) ([开关.tplink docs]) (breaking change) * Migrate Alexa smart home to registry ([@balloob] - [#9616]) ([alexa.smart\_home docs][alexa.smart_home docs]) * Add an input\_datetime ([@tinloaf] - [#9313]) ([input\_datetime docs][input_datetime docs]) (new-platform) * 遮盖 component for RFlink ([@passie] - [#9432]) ([rflink docs]) ([遮盖.rflink docs]) (new-platform) * Introducing support to Melnor RainCloud sprinkler systems ([@tchellomello] - [#9287]) ([raincloud docs]) ([binary\_sensor.raincloud docs][binary_sensor.raincloud docs]) ([传感器.raincloud docs]) ([开关.raincloud docs]) (new-platform) * Rewrite synology 摄像头 by using py-synology package ([@snjoetw] - [#9583]) ([摄像头.synology docs]) * yeelight: allow turn\_off transitions, fixes #9602 ([@rytilahti] - [#9605]) ([灯光.yeelight docs]) * Move 'voltage' to const ([@fabaff] - [#9621]) ([传感器.pvoutput docs]) ([开关.tplink docs]) * Yamaha MusicCast: check known\_hosts ([@jalmeroth] - [#9580]) ([媒体播放器.yamaha\_musiccast docs][媒体播放器.yamaha_musiccast docs]) * Fixed away\_mode for Ecobee thermostat. ([@etsinko] - [#9559]) ([温控.ecobee docs]) * Switched VeraSensor to use category ids ([@alanfischer] - [#9624]) ([传感器.vera docs]) * splunk: Handle datetime objects in event payload ([@philk] - [#9628]) ([splunk docs]) * MQTT 温控 platform \[continuation of #8750] ([@tinloaf] - [#9589]) ([温控.MQTT docs]) (new-platform) * wunderground: fix supported language codes #9631 ([@szogi] - [#9633]) ([传感器.wunderground docs]) * add myself to codeowners ([@rytilahti] - [#9642]) * raspihats: unmet dependency fix ([@szogi] - [#9638]) ([raspihats docs]) * Fixes broken source links in API docs ([@David-Byrne] - [#9636]) * Move group 服务 into their own YAML ([@balloob] - [#9597]) ([group docs]) * Facebook Messenger 通知 component: add support for sending messages to specific page 用户 IDs ([@mweimerskirch] - [#9643]) ([通知.facebook docs]) * arlo: Add battery level 传感器 ([@vickyg3] - [#9637]) ([传感器.arlo docs]) * Add hysteresis 属性 to threshold 二元sensor ([@hotplot] - [#9596]) ([binary\_sensor.threshold docs][binary_sensor.threshold docs]) * 升级 numpy to 1.13.3 ([@fabaff] - [#9646]) ([image\_processing.opencv docs][image_processing.opencv docs]) * 升级 youtube\_dl to 2017.10.01 ([@fabaff] - [#9647]) ([media\_extractor docs][media_extractor docs]) * 升级 discord.py to 0.16.12 ([@fabaff] - [#9648]) ([通知.discord docs]) * 升级 netdisco to 1.2.2 ([@fabaff] - [#9649]) * 升级 influxdb to 4.1.1 ([@fabaff] - [#9652]) ([influxdb docs]) * 升级 googlemaps to 2.5.1 ([@fabaff] - [#9653]) ([传感器.google\_travel\_time docs][传感器.google_travel_time docs]) * mqtt\_statestream: Add options to publish 属性/timestamps ([@mw-white] - [#9645]) ([mqtt\_statestream docs][mqtt_statestream docs]) * Fixed bugs related to exception handling in pythonegardia. Updating package requirement accordingly ([@jeroenterheerdt] - [#9663]) ([alarm\_control\_panel.egardia docs][alarm_control_panel.egardia docs]) * 更新 google-api-python-client to 1.6.4 ([@arsaboo] - [#9658]) ([google docs]) * Bump abode to 0.11.9 ([@MisterWil] - [#9660]) ([abode docs]) * Unit tests to improve 核心 coverage ([@armills] - [#9659]) * 升级 pyitachip2ir to 0.0.7 ([@alanfischer] - [#9669]) ([遥控器.itach docs]) * Fix typo in cancel\_command description ([@FletcherAU] - [#9671]) * Rename input\_slider to input\_number and add numeric text box option ([@BioSehnsucht] - [#9494]) ([demo docs]) ([input\_number docs][input_number docs]) (breaking change) * Properly handle an invalid end\_time ([@alanfischer] - [#9675]) ([history docs]) * Support new feature to push API data to hassio ([@pvizeli] - [#9679]) ([hassio docs]) * Adding ignore capability to Egardia component ([@jeroenterheerdt] - [#9676]) ([alarm\_control\_panel.egardia docs][alarm_control_panel.egardia docs]) * Fix Google 日历/oauth2client 警告 ([@mbrrg] - [#9677]) ([google docs]) * Implement DSMR5 support. ([@aequitas] - [#9686]) ([传感器.dsmr docs]) * Add Tibber 传感器 ([@danielhiversen] - [#9661]) ([传感器.tibber docs]) (new-platform) * Add recorder purge 服务, rework purge timer ([@milanvo] - [#9523]) (breaking change) * Fix 恢复 状态 by filter out null value row from DB query ([@milanvo] - [#9690]) ([history docs]) * Updating clicksendaudio component based on feedback ([@jeroenterheerdt] - [#9692]) ([通知.clicksendaudio docs]) (new-platform) * Refactoring of onewire 传感器 component ([@bestlibre] - [#9691]) ([传感器.onewire docs]) * HassIO replace config changes ([@pvizeli] - [#9695]) ([hassio docs]) * Fixed typo in opencv ([@arsaboo] - [#9697]) ([image\_processing.opencv docs][image_processing.opencv docs]) (breaking change) * \[灯光.tradfri] async support with resource observation. ([@lwis] - [#7815]) ([tradfri docs]) ([灯光.tradfri docs]) (breaking change) * Create secrets file in default config ([@balloob] - [#9685]) * Support for The Things Network ([@fabaff] - [#9627]) ([thethingsnetwork docs]) ([传感器.thethingsnetwork docs]) (new-platform) * Deprecate Python 3.4 support ([@balloob] - [#9684]) * Fix coap commit ([@balloob] - [#9712]) * \[灯光.tradfri] Clone all of aiocoap to ensure pinned commit will be present ([@lwis] - [#9713]) [#7815]: https://github.com/home-assistant/home-assistant/pull/7815 [#9206]: https://github.com/home-assistant/home-assistant/pull/9206 [#9287]: https://github.com/home-assistant/home-assistant/pull/9287 [#9303]: https://github.com/home-assistant/home-assistant/pull/9303 [#9313]: https://github.com/home-assistant/home-assistant/pull/9313 [#9331]: https://github.com/home-assistant/home-assistant/pull/9331 [#9358]: https://github.com/home-assistant/home-assistant/pull/9358 [#9382]: https://github.com/home-assistant/home-assistant/pull/9382 [#9432]: https://github.com/home-assistant/home-assistant/pull/9432 [#9433]: https://github.com/home-assistant/home-assistant/pull/9433 [#9445]: https://github.com/home-assistant/home-assistant/pull/9445 [#9472]: https://github.com/home-assistant/home-assistant/pull/9472 [#9494]: https://github.com/home-assistant/home-assistant/pull/9494 [#9523]: https://github.com/home-assistant/home-assistant/pull/9523 [#9533]: https://github.com/home-assistant/home-assistant/pull/9533 [#9535]: https://github.com/home-assistant/home-assistant/pull/9535 [#9536]: https://github.com/home-assistant/home-assistant/pull/9536 [#9537]: https://github.com/home-assistant/home-assistant/pull/9537 [#9540]: https://github.com/home-assistant/home-assistant/pull/9540 [#9542]: https://github.com/home-assistant/home-assistant/pull/9542 [#9544]: https://github.com/home-assistant/home-assistant/pull/9544 [#9545]: https://github.com/home-assistant/home-assistant/pull/9545 [#9548]: https://github.com/home-assistant/home-assistant/pull/9548 [#9554]: https://github.com/home-assistant/home-assistant/pull/9554 [#9555]: https://github.com/home-assistant/home-assistant/pull/9555 [#9556]: https://github.com/home-assistant/home-assistant/pull/9556 [#9557]: https://github.com/home-assistant/home-assistant/pull/9557 [#9559]: https://github.com/home-assistant/home-assistant/pull/9559 [#9560]: https://github.com/home-assistant/home-assistant/pull/9560 [#9561]: https://github.com/home-assistant/home-assistant/pull/9561 [#9562]: https://github.com/home-assistant/home-assistant/pull/9562 [#9565]: https://github.com/home-assistant/home-assistant/pull/9565 [#9567]: https://github.com/home-assistant/home-assistant/pull/9567 [#9568]: https://github.com/home-assistant/home-assistant/pull/9568 [#9569]: https://github.com/home-assistant/home-assistant/pull/9569 [#9575]: https://github.com/home-assistant/home-assistant/pull/9575 [#9576]: https://github.com/home-assistant/home-assistant/pull/9576 [#9578]: https://github.com/home-assistant/home-assistant/pull/9578 [#9580]: https://github.com/home-assistant/home-assistant/pull/9580 [#9582]: https://github.com/home-assistant/home-assistant/pull/9582 [#9583]: https://github.com/home-assistant/home-assistant/pull/9583 [#9584]: https://github.com/home-assistant/home-assistant/pull/9584 [#9586]: https://github.com/home-assistant/home-assistant/pull/9586 [#9587]: https://github.com/home-assistant/home-assistant/pull/9587 [#9588]: https://github.com/home-assistant/home-assistant/pull/9588 [#9589]: https://github.com/home-assistant/home-assistant/pull/9589 [#9596]: https://github.com/home-assistant/home-assistant/pull/9596 [#9597]: https://github.com/home-assistant/home-assistant/pull/9597 [#9605]: https://github.com/home-assistant/home-assistant/pull/9605 [#9606]: https://github.com/home-assistant/home-assistant/pull/9606 [#9607]: https://github.com/home-assistant/home-assistant/pull/9607 [#9612]: https://github.com/home-assistant/home-assistant/pull/9612 [#9616]: https://github.com/home-assistant/home-assistant/pull/9616 [#9621]: https://github.com/home-assistant/home-assistant/pull/9621 [#9624]: https://github.com/home-assistant/home-assistant/pull/9624 [#9627]: https://github.com/home-assistant/home-assistant/pull/9627 [#9628]: https://github.com/home-assistant/home-assistant/pull/9628 [#9633]: https://github.com/home-assistant/home-assistant/pull/9633 [#9636]: https://github.com/home-assistant/home-assistant/pull/9636 [#9637]: https://github.com/home-assistant/home-assistant/pull/9637 [#9638]: https://github.com/home-assistant/home-assistant/pull/9638 [#9642]: https://github.com/home-assistant/home-assistant/pull/9642 [#9643]: https://github.com/home-assistant/home-assistant/pull/9643 [#9645]: https://github.com/home-assistant/home-assistant/pull/9645 [#9646]: https://github.com/home-assistant/home-assistant/pull/9646 [#9647]: https://github.com/home-assistant/home-assistant/pull/9647 [#9648]: https://github.com/home-assistant/home-assistant/pull/9648 [#9649]: https://github.com/home-assistant/home-assistant/pull/9649 [#9652]: https://github.com/home-assistant/home-assistant/pull/9652 [#9653]: https://github.com/home-assistant/home-assistant/pull/9653 [#9658]: https://github.com/home-assistant/home-assistant/pull/9658 [#9659]: https://github.com/home-assistant/home-assistant/pull/9659 [#9660]: https://github.com/home-assistant/home-assistant/pull/9660 [#9661]: https://github.com/home-assistant/home-assistant/pull/9661 [#9663]: https://github.com/home-assistant/home-assistant/pull/9663 [#9669]: https://github.com/home-assistant/home-assistant/pull/9669 [#9671]: https://github.com/home-assistant/home-assistant/pull/9671 [#9675]: https://github.com/home-assistant/home-assistant/pull/9675 [#9676]: https://github.com/home-assistant/home-assistant/pull/9676 [#9677]: https://github.com/home-assistant/home-assistant/pull/9677 [#9679]: https://github.com/home-assistant/home-assistant/pull/9679 [#9684]: https://github.com/home-assistant/home-assistant/pull/9684 [#9685]: https://github.com/home-assistant/home-assistant/pull/9685 [#9686]: https://github.com/home-assistant/home-assistant/pull/9686 [#9690]: https://github.com/home-assistant/home-assistant/pull/9690 [#9691]: https://github.com/home-assistant/home-assistant/pull/9691 [#9692]: https://github.com/home-assistant/home-assistant/pull/9692 [#9695]: https://github.com/home-assistant/home-assistant/pull/9695 [#9697]: https://github.com/home-assistant/home-assistant/pull/9697 [#9712]: https://github.com/home-assistant/home-assistant/pull/9712 [#9713]: https://github.com/home-assistant/home-assistant/pull/9713 [@BioSehnsucht]: https://github.com/BioSehnsucht [@David-Byrne]: https://github.com/David-Byrne [@FletcherAU]: https://github.com/FletcherAU [@MisterWil]: https://github.com/MisterWil [@Tommatheussen]: https://github.com/Tommatheussen [@aequitas]: https://github.com/aequitas [@alanfischer]: https://github.com/alanfischer [@amelchio]: https://github.com/amelchio [@andrey-git]: https://github.com/andrey-git [@armills]: https://github.com/armills [@arsaboo]: https://github.com/arsaboo [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@bestlibre]: https://github.com/bestlibre [@cmsimike]: https://github.com/cmsimike [@danielhiversen]: https://github.com/danielhiversen [@djchen]: https://github.com/djchen [@enriquegh]: https://github.com/enriquegh [@etsinko]: https://github.com/etsinko [@exxamalte]: https://github.com/exxamalte [@fabaff]: https://github.com/fabaff [@happyleavesaoc]: https://github.com/happyleavesaoc [@hotplot]: https://github.com/hotplot [@jalmeroth]: https://github.com/jalmeroth [@jeroenterheerdt]: https://github.com/jeroenterheerdt [@joe248]: https://github.com/joe248 [@lwis]: https://github.com/lwis [@marthoc]: https://github.com/marthoc [@mbrrg]: https://github.com/mbrrg [@mika]: https://github.com/mika [@milanvo]: https://github.com/milanvo [@mw-white]: https://github.com/mw-white [@mweimerskirch]: https://github.com/mweimerskirch [@nkgilley]: https://github.com/nkgilley [@passie]: https://github.com/passie [@pfalcon]: https://github.com/pfalcon [@philk]: https://github.com/philk [@postlund]: https://github.com/postlund [@pvizeli]: https://github.com/pvizeli [@rbflurry]: https://github.com/rbflurry [@rytilahti]: https://github.com/rytilahti [@snjoetw]: https://github.com/snjoetw [@sti0]: https://github.com/sti0 [@szogi]: https://github.com/szogi [@tchellomello]: https://github.com/tchellomello [@tinloaf]: https://github.com/tinloaf [@vickyg3]: https://github.com/vickyg3 [@w1ll1am23]: https://github.com/w1ll1am23 [abode docs]: /integrations/abode/ [alarm_control_panel.egardia docs]: /integrations/egardia [alarm_control_panel.manual_mqtt docs]: /integrations/manual_mqtt/ [alexa.smart_home docs]: /integrations/alexa/ [apple_tv docs]: /integrations/apple_tv/ [arlo docs]: /integrations/arlo/ [binary_sensor.raincloud docs]: /integrations/raincloud#binary-传感器 [binary_sensor.threshold docs]: /integrations/threshold [binary_sensor.wink docs]: /integrations/wink#binary-传感器 [摄像头.arlo docs]: /integrations/arlo#摄像头 [摄像头.synology docs]: /integrations/synology [温控.ecobee docs]: /integrations/ecobee [温控.MQTT docs]: /integrations/温控.MQTT/ [遮盖.MQTT docs]: /integrations/遮盖.MQTT/ [遮盖.rflink docs]: /integrations/遮盖.rflink/ [demo docs]: /integrations/demo/ [device_tracker.owntracks docs]: /integrations/owntracks [device_tracker.owntracks_http docs]: /integrations/owntracks [duckdns docs]: /integrations/duckdns/ [ecobee docs]: /integrations/ecobee/ [emulated_hue docs]: /integrations/emulated_hue/ [google docs]: /integrations/日历.google/ [group docs]: /integrations/group/ [hassio docs]: /hassio/ [history docs]: /integrations/history/ [homematic docs]: /integrations/homematic/ [http docs]: /integrations/http/ [image_processing.opencv docs]: /integrations/opencv [influxdb docs]: /integrations/influxdb/ [input_datetime docs]: /integrations/input_datetime/ [input_number docs]: /integrations/input_number/ [灯光.flux_led docs]: /integrations/flux_led [灯光.rflink docs]: /integrations/灯光.rflink/ [灯光.tradfri docs]: /integrations/tradfri [灯光.yeelight docs]: /integrations/yeelight [门锁.wink docs]: /integrations/wink#门锁 [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.apple_tv docs]: /integrations/apple_tv [媒体播放器.webostv docs]: /integrations/webostv#media-player [媒体播放器.yamaha_musiccast docs]: /integrations/yamaha_musiccast/ [mqtt_statestream docs]: /integrations/mqtt_statestream/ [通知.clicksendaudio docs]: /integrations/clicksend_tts/ [通知.discord docs]: /integrations/discord [通知.facebook docs]: /integrations/facebook [通知.simplepush docs]: /integrations/simplepush [raincloud docs]: /integrations/raincloud/ [raspihats docs]: /integrations/raspihats/ [recorder docs]: /integrations/recorder/ [遥控器.itach docs]: /integrations/itach [rflink docs]: /integrations/rflink/ [传感器.airvisual docs]: /integrations/airvisual [传感器.arlo docs]: /integrations/arlo#传感器 [传感器.comed_hourly_pricing docs]: /integrations/comed_hourly_pricing [传感器.dsmr docs]: /integrations/dsmr [传感器.geo_rss_events docs]: /integrations/geo_rss_events [传感器.google_travel_time docs]: /integrations/google_travel_time [传感器.imap docs]: /integrations/imap [传感器.lyft docs]: /integrations/lyft [传感器.onewire docs]: /integrations/onewire [传感器.pvoutput docs]: /integrations/pvoutput [传感器.raincloud docs]: /integrations/raincloud#传感器 [传感器.systemmonitor docs]: /integrations/systemmonitor [传感器.thethingsnetwork docs]: /integrations/thethingsnetwork#传感器 [传感器.tibber docs]: /integrations/tibber#传感器 [传感器.vera docs]: /integrations/vera#传感器 [传感器.wunderground docs]: /integrations/wunderground [splunk docs]: /integrations/splunk/ [开关.abode docs]: /integrations/abode#开关 [开关.raincloud docs]: /integrations/raincloud#开关 [开关.rflink docs]: /integrations/开关.rflink/ [开关.tplink docs]: /integrations/tplink [thethingsnetwork docs]: /integrations/thethingsnetwork/ [tradfri docs]: /integrations/tradfri/ [upnp docs]: /integrations/upnp/ [吸尘器.xiaomi docs]: /integrations/吸尘器.xiaomi_miio/ [wink docs]: /integrations/wink/ [zwave docs]: /integrations/zwave/ [forum]: https://community.home-assistant.io/ [issue]: https://github.com/home-assistant/home-assistant/issues [discord]: https://discord.gg/c5DvZ4e [#9754]: https://github.com/home-assistant/home-assistant/pull/9754 [#9776]: https://github.com/home-assistant/home-assistant/pull/9776 [#9785]: https://github.com/home-assistant/home-assistant/pull/9785 [#9794]: https://github.com/home-assistant/home-assistant/pull/9794 [#9841]: https://github.com/home-assistant/home-assistant/pull/9841 [#9842]: https://github.com/home-assistant/home-assistant/pull/9842 [#9880]: https://github.com/home-assistant/home-assistant/pull/9880 [@GenericStudent]: https://github.com/GenericStudent [@balloob]: https://github.com/balloob [@lwis]: https://github.com/lwis [@passie]: https://github.com/passie [@pschmitt]: https://github.com/pschmitt [@snjoetw]: https://github.com/snjoetw [摄像头.synology docs]: /integrations/synology [遮盖.rflink docs]: /integrations/遮盖.rflink/ [device_tracker.owntracks docs]: /integrations/owntracks [google docs]: /integrations/google_translate [灯光.tradfri docs]: /integrations/tradfri --- url: /home-assistant/blog/2017-10-14-templating-date-time.md --- # 模板、日期与时间 这个 [拉取请求](https://github.com/home-assistant/home-assistant/pull/9868) 很清楚地展示了:如果文档写得不够好,会发生什么。简而言之,这篇文章讲的是 [模板](/home-assistant/docs/configuration/templating/index.md),以及当相关内容没有被记录下来时,人们会如何开始想出各种有创意的方法来解决问题。假设我们想获取当前年份,可以使用下面几种方法: * 使用 [`rest` 传感器](/home-assistant/integrations/rest.md) 和 `value_template:` 去查询 [JSON Test](http://date.jsontest.com/)。 * 使用 [`time_date` 传感器](/home-assistant/integrations/time_date.md) 和模板 \`\`。 * 用任意语言写一个脚本,然后配合 [`command` 传感器](/home-assistant/integrations/sensor.command_line/) 使用,或者直接把 `date +"%Y"` 作为 `command:`。 我们当然希望事情更简单,对吧?[模板](/home-assistant/docs/configuration/templating/index.md) 提供了 `now()` 和 `utcnow()`。这篇博客里我们用 `now()` 举例,但同样也适用于 `utcnow()`。我们的文档当时是这样写的:
`now()` 会渲染为你所在时区的当前时间。
嗯,......好吧,算是个开始。那要怎么拿到年份呢?`` 会返回 `2017-10-14 20:27:23.700401+02:00`,这比我们真正想要的内容多得多。作为用户,你并不想一头扎进代码里,但答案其实就在那里。`` 返回的是一个 [Python `datetime` 对象](https://docs.python.org/3.6/library/datetime.html#datetime.datetime)。这意味着你在模板里可以访问到比想象中更多的内容: * 时间相关:`now().microsecond`、`now().second`、`now().minute` 和 `now().hour` * 日期相关:`now().day`、`now().month` 和 `now().year` * 其他:`now().weekday()` 和 `now().isoweekday()` 如果是年份,就可以写成:\`\`。我猜 `now().resolution`、`now().min` 和 `now().max` 也会有一些比较少见的使用场景。 [Hacktoberfest](/home-assistant/blog/2017/09/29/hacktoberfest/) 还在进行中。参与文档工作其实很简单。如果你知道什么不错的[技巧](/home-assistant/examples/),想帮忙改进某个平台页面,或者只是修正一个拼写错误,都欢迎参与。我们的[网站和文档部分](/home-assistant/developers/docs/)里列出了一些要求,这些要求定义在[文档规范](/home-assistant/developers/docs/standards/)中,而「[创建页面](/home-assistant/developers/docs/create_page/)」文档里还有其他有用的细节。 感谢 [Egor Tsinko](https://github.com/etsinko) 让我们注意到这个问题。 --- url: /home-assistant/blog/2017-10-18-hasspodcast-ep-10.md --- # Home Assistant 播客 #10 节目笔记可在 [Home Assistant 播客网站](https://hasspodcast.io/HA010/) 查看 [在线收听][episode] [episode]: https://hasspodcast.io/ha010/ --- url: /home-assistant/blog/2017-10-21-release-56.md --- # 0.56: Skybell, Google Assistant, Travis CI and Toon 我们达成了另一个里程碑,也就是编号:10000。GitHub 会为拉取请求和问题分配编号,而“10000”对应的是一个 [PR](https://github.com/home-assistant/home-assistant/pull/10000)。目前我们的比例大约是 1/3 的 issue 和 2/3 的 pull request。更准确地说:64% 是 pull request,36% 是 issue。 如果你还没注意到,我们现在已经有了一个 [术语表](/home-assistant/docs/glossary/index.md),用来整理一些与 Home Assistant 相关的术语。说到文档,[@DubhAd](https://github.com/DubhAd) 重写了 Z-Wave 章节的大部分内容,让入门、设置和配置时查找细节都更有条理。 ## Google Assistant / Google Home 集成 本次发布包含了由 [Phil Kates][@philk] 带来的全新组件,可将 Home Assistant 与 Google Assistant 集成。我们通过 Smart Home API 进行集成,这意味着你可以通过任何带有 Google Assistant 的设备来控制 Home Assistant 中的设备。更多信息请查看[文档][google_assistant docs]。 ## Hacktoberfest [Hacktoberfest](/home-assistant/blog/2017/09/29/hacktoberfest/) 仍在进行中,目前我们已经收到了大量改进提交。我们无法保证在 10 月底前审完所有内容,但会尽力确保你能拿到自己的 T 恤。 ## 地图 [map][map docs] 现在已经拆分为独立组件。和[配置(`config:`)](/home-assistant/integrations/config/index.md)类似,如果你不在 `configuration.yaml` 中添加它,它就不会显示出来。 ```yaml map: ``` ## Travis CI 为什么不用 Home Assistant 来监控你的 [Travis CI](https://travis-ci.org) 任务呢?[@tchellomello] 创建了一个 [Travis CI][传感器.travisci docs] 传感器,可以查看 Travis 任务的当前状态。现在你甚至可以在构建通过时,确保[咖啡](/home-assistant/blog/2017/01/28/face-coffee-wink/#first-coffee-maker-supported)已经准备好了。 ## 新平台 * Add Arlo 报警 control 面板 component ([@vickyg3] - [#9711]) ([alarm\_control\_panel.arlo docs][alarm_control_panel.arlo docs]) (new-platform) * Abode Temp, Humidity, and 灯光 传感器 ([@MisterWil] - [#9709]) ([abode docs]) ([传感器.abode docs]) (new-platform) * Introducing support to Travis-CI ([@tchellomello] - [#9701]) ([传感器.travisci docs]) (new-platform) * Skybell ([@MisterWil] - [#9681]) ([skybell docs]) ([binary\_sensor.skybell docs][binary_sensor.skybell docs]) ([摄像头.skybell docs]) ([灯光.skybell docs]) ([传感器.skybell docs]) ([开关.skybell docs]) (new-platform) * Xiaomi Smart WiFi Socket and Smart Power Strip 集成 ([@syssi] - [#9138]) ([开关.xiaomi\_miio docs][开关.xiaomi_miio docs]) (new-platform) * Add 通知 platform for Rocket.Chat ([@webworxshop] - [#9553]) ([通知.rocketchat docs]) (new-platform) * Tesla bug fixes. ([@zabuldon] - [#9774]) ([tesla docs]) ([binary\_sensor.tesla docs][binary_sensor.tesla docs]) ([温控.tesla docs]) ([门锁.tesla docs]) ([传感器.tesla docs]) ([开关.tesla docs]) (new-platform) * Split map 面板 out into its own component ([@cgarwood] - [#9814]) ([map docs]) (breaking change) (new-platform) * Support for Yi 摄像头 ([@bachya] - [#9787]) ([摄像头.yi docs]) (new-platform) * Add namecheap DNS component ([@Munsio] - [#9821]) ([namecheapdns docs]) (new-platform) * Uptime 传感器 ([@fronzbot] - [#9856]) ([传感器.uptime docs]) (new-platform) * Cloud connection via aiohttp ([@balloob] - [#9860]) (new-platform) * Google 动作 for Assistant ([@philk] - [#9632]) ([google\_assistant docs][google_assistant docs]) ([http docs]) (new-platform) * A new platform for controlling Monoprice 6-区域 amplifier ([@etsinko] - [#9662]) ([媒体播放器.monoprice docs]) (new-platform) * Add serial 传感器 ([@fabaff] - [#9861]) ([传感器.serial docs]) (new-platform) * Add Toon support ([@Boltgolt] - [#9483]) ([toon docs]) ([温控.toon docs]) ([传感器.toon docs]) ([开关.toon docs]) (new-platform) ## 0.56.1 - October 22 * Fix 设备 更新 / entity\_id with names ([@pvizeli] - [#10029]) * fix temperature/humidity 传感器 valid values ([@bieniu] - [#10024]) ([传感器.xiaomi\_aqara docs][传感器.xiaomi_aqara docs]) ## 0.56.2 - October 23 * Fix gateway illumination 传感器 value ([@bieniu] - [#10045]) ([传感器.xiaomi\_aqara docs][传感器.xiaomi_aqara docs]) * Fix 设备 更新/`entity_id` with names ([@rytilahti] - [#10053]) ([开关.tplink docs]) * Remove 警告 component / 更新 event 触发器 for UI 创建 ([@pvizeli] - [#10060]) ## 如果你需要帮助…… ……欢迎使用我们非常活跃的[论坛](https://community.home-assistant.io/),或者加入我们的[聊天频道](https://discord.gg/c5DvZ4e)。虽然发布说明开放了评论,但我们更推荐你使用前面的社区交流渠道。谢谢。 ## 反馈问题 如果你遇到了此次发布引入的问题,请在我们的 [issue tracker](https://github.com/home-assistant/home-assistant/issues) 中反馈。请确保完整填写 issue 模板中的所有字段。 ## 不向后兼容的变更 * Simplify track\_same\_state ([@balloob] - [#9795]) ([自动化.numeric\_state docs][自动化.numeric_state docs]) ([自动化.状态 docs]) ([binary\_sensor.模板 docs][binary_sensor.模板 docs]) (breaking change) * Split map 面板 out into its own component ([@cgarwood] - [#9814]) ([map docs]) (breaking change) (new-platform) * Fix ISY994 风扇 platform overwriting 状态 property ([@balloob] - [#9817]) (breaking change) * Changing name of clicksendaudio component to clicksend\_tts ([@jeroenterheerdt] - [#9859]) ([通知.clicksend\_tts docs][通知.clicksend_tts docs]) (breaking change) * Fix load of components without any config from packages ([@azogue] - [#9901]) (breaking change) * Fix the resource naming in the UI ([@cgtobi] - [#9916]) ([传感器.systemmonitor docs]) (breaking change) * Align away 状态 tag with device\_trackers ([@PeteBa] - [#9884]) ([传感器.mqtt\_room docs][传感器.mqtt_room docs]) (breaking change) * Moved 警报器 to Wink from 开关 ([@w1ll1am23] - [#9879]) ([wink docs]) ([开关.wink docs]) (breaking change) ## 全部变更 * fixed duplicate words ([@flowolf] - [#9705]) ([灯光.hue docs]) ([灯光.mqtt\_json docs][灯光.mqtt_json docs]) ([媒体播放器.denon docs]) ([媒体播放器.dunehd docs]) * move icon battery function from util to 助手 ([@happyleavesaoc] - [#9708]) ([吸尘器 docs]) ([传感器.android\_ip\_webcam docs][传感器.android_ip_webcam docs]) ([传感器.fitbit docs]) ([传感器.ios docs]) ([传感器.raincloud docs]) ([吸尘器.dyson docs]) ([吸尘器.MQTT docs]) * Updating 助手's icon\_for\_battery\_level location ([@tchellomello] - [#9594]) ([传感器.ring docs]) * 升级 pyhomematic, add path setting and HM-CC-VG-1 support ([@danielperna84] - [#9707]) ([homematic docs]) * bump the 版本 and catch all exceptions to avoid showing backtraces… ([@rytilahti] - [#9720]) ([温控.eq3btsmart docs]) * More netdata 传感器 ([@fronzbot] - [#9719]) ([传感器.netdata docs]) * 升级 pysnmp to 4.3.10 ([@fabaff] - [#9722]) ([device\_tracker.snmp docs][device_tracker.snmp docs]) ([传感器.snmp docs]) * arlo: Add 报警 control 面板 component ([@vickyg3] - [#9711]) ([alarm\_control\_panel.arlo docs][alarm_control_panel.arlo docs]) (new-platform) * Abode Temp, Humidity, and 灯光 传感器 ([@MisterWil] - [#9709]) ([abode docs]) ([传感器.abode docs]) (new-platform) * Arlo clean-up ([@fabaff] - [#9725]) ([arlo docs]) ([alarm\_control\_panel.arlo docs][alarm_control_panel.arlo docs]) ([摄像头.arlo docs]) ([传感器.arlo docs]) * Introducing support to Travis-CI ([@tchellomello] - [#9701]) ([传感器.travisci docs]) (new-platform) * Add show\_on\_map config option to AirVisual ([@bachya] - [#9654]) ([传感器.airvisual docs]) * Move 'show\_on\_map' to const ([@fabaff] - [#9727]) ([binary\_sensor.iss docs][binary_sensor.iss docs]) ([传感器.airvisual docs]) * Bump 发布 to 0.56.0dev ([@fabaff] - [#9726]) * Add andrey-git to codeowners ([@andrey-git] - [#9718]) * Fix: Last Played Media Title persists in plex ([@ryanm101] - [#9664]) ([媒体播放器.plex docs]) * Event 触发器 nested 条件 ([@armills] - [#9732]) ([自动化.event docs]) * Rewrite Alexa Smart-Home skill to v3 ([@pvizeli] - [#9699]) ([alexa.smart\_home docs][alexa.smart_home docs]) * Fix I/O in event loop by Arlo 报警 control 面板 ([@balloob] - [#9738]) ([alarm\_control\_panel.arlo docs][alarm_control_panel.arlo docs]) * Make Arlo battery\_level icon dynamic ([@tchellomello] - [#9747]) ([传感器.arlo docs]) * Fix for TypeError in synology 摄像头 ([@snjoetw] - [#9754]) ([摄像头.synology docs]) * 开关.tplink, 灯光.tplink: bump the pyhs100 版本 and adapt to api changes ([@rytilahti] - [#9454]) ([灯光.tplink docs]) ([开关.tplink docs]) * RFC: Use bind\_hass for 助手 ([@balloob] - [#9745]) * Skybell ([@MisterWil] - [#9681]) ([skybell docs]) ([binary\_sensor.skybell docs][binary_sensor.skybell docs]) ([摄像头.skybell docs]) ([灯光.skybell docs]) ([传感器.skybell docs]) ([开关.skybell docs]) (new-platform) * add myself to yeelight owners, too ([@rytilahti] - [#9759]) * 更新 CODEOWNERS ([@danielhiversen] - [#9760]) * Adding my contributions ([@bachya] - [#9761]) * Initializing statistics 传感器 with data from database ([@ChristianKuehnel] - [#9753]) ([传感器.statistics docs]) * Match test requirements by full package name. ([@andrey-git] - [#9764]) * yeelight: implement min\_mireds and max\_mireds, fixes #9509 ([@rytilahti] - [#9763]) ([灯光.yeelight docs]) * Bump raincloudy 版本 0.0.3 ([@tchellomello] - [#9767]) ([raincloud docs]) ([传感器.raincloud docs]) * Xiaomi Smart WiFi Socket and Smart Power Strip 集成 ([@syssi] - [#9138]) ([开关.xiaomi\_miio docs][开关.xiaomi_miio docs]) (new-platform) * fix for LocationParseError in netgear platform ([@etsinko] - [#9683]) ([device\_tracker docs][device_tracker docs]) ([device\_tracker.netgear docs][device_tracker.netgear docs]) * Expose time module in Python 脚本 ([@balloob] - [#9736]) ([python\_script docs][python_script docs]) * Add 通知 platform for Rocket.Chat. ([@webworxshop] - [#9553]) ([通知.rocketchat docs]) (new-platform) * Updating pythonegardia package requirement to .22 because of fixed bug in passing default value for parameter SSL for egardiaserver ([@jeroenterheerdt] - [#9770]) ([alarm\_control\_panel.egardia docs][alarm_control_panel.egardia docs]) * Adding myself as codeowner for egardia 报警 control 面板. ([@jeroenterheerdt] - [#9772]) * WIP: Fix Arlo 摄像头 blocking IO ([@bachya] - [#9758]) ([摄像头.arlo docs]) * Tesla bug fixes. ([@zabuldon] - [#9774]) ([tesla docs]) ([binary\_sensor.tesla docs][binary_sensor.tesla docs]) ([温控.tesla docs]) ([门锁.tesla docs]) ([传感器.tesla docs]) ([开关.tesla docs]) (new-platform) * Fix off by one 错误 in arwn platform ([@sdague] - [#9781]) ([传感器.arwn docs]) * missing is\_closed ( rflink 遮盖 fix ) ([@passie] - [#9776]) ([遮盖.rflink docs]) * Wink dome 警报器 support ([@w1ll1am23] - [#9667]) ([wink docs]) ([开关.wink docs]) * Bump rxv library to 0.5.1 ([@sdague] - [#9784]) ([媒体播放器.yamaha docs]) * Communication timeout support in modbus hub. ([@ziotibia81] - [#9780]) ([modbus docs]) * \[灯光.tradfri] Fix transition time ([@lwis] - [#9785]) ([灯光.tradfri docs]) * OwnTracks: Fix handler is None checking ([@balloob] - [#9794]) ([device\_tracker.owntracks docs][device_tracker.owntracks docs]) * Simplify track\_same\_state ([@balloob] - [#9795]) ([自动化.numeric\_state docs][自动化.numeric_state docs]) ([自动化.状态 docs]) ([binary\_sensor.模板 docs][binary_sensor.模板 docs]) (breaking change) * Optimize event matcher ([@balloob] - [#9798]) * Resolving bug that prevents ssl\_verify option for Unifi device\_tracker ([@GenericStudent] - [#9788]) ([device\_tracker.unifi docs][device_tracker.unifi docs]) * 升级 pyasn1 to 0.3.7 and pyasn1-modules to 0.1.5 ([@fabaff] - [#9810]) * Split map 面板 out into its own component ([@cgarwood] - [#9814]) ([map docs]) (breaking change) (new-platform) * 恢复 home-assistant-polymer pointer from #9720 ([@armills] - [#9825]) * Fix ISY994 风扇 platform overwriting 状态 property ([@balloob] - [#9817]) (breaking change) * Wait\_template - support for '触发器.entity\_id' and data\_template values ([@cdce8p] - [#9807]) * Adds 图像 属性 to html5 通知 (#9832) ([@cgarwood] - [#9835]) ([通知.html5 docs]) * OwnTracks: Handle lwt message ([@balloob] - [#9831]) ([device\_tracker.owntracks docs][device_tracker.owntracks docs]) * 升级 libnacl ([@fabaff] - [#9769]) ([device\_tracker.owntracks docs][device_tracker.owntracks docs]) * Fixed reporting of vera UV 传感器 ([@alanfischer] - [#9838]) ([传感器.vera docs]) * 更新 CODEOWNERS \*/axis.py ([@Kane610] - [#9823]) * fix 温控 服务 (missing indentation, wrongly formatted example) ([@rytilahti] - [#9805]) * Run initial generation for development mode ([@armills] - [#9826]) * Add 服务 descriptions ([@cgarwood] - [#9806]) ([homeassistant docs]) * Bugfix: Include MQTT schema ([@tinloaf] - [#9802]) ([温控.MQTT docs]) * Bugfix/9811 jinja autoescape ([@GenericStudent] - [#9842]) * Changed yaml.load into yaml.safe\_load ([@GenericStudent] - [#9841]) * New PR ([@bachya] - [#9787]) ([摄像头.yi docs]) (new-platform) * Do not auto-安装 credstash ([@balloob] - [#9844]) * Add namecheap DNS component ([@Munsio] - [#9821]) ([namecheapdns docs]) (new-platform) * Remove namecheap dns 服务 ([@balloob] - [#9845]) ([namecheapdns docs]) * Use the Last Seen 属性 in unify ([@rbflurry] - [#8998]) ([device\_tracker.unifi docs][device_tracker.unifi docs]) * Add CAPSman master to mikrotik 在场 detection ([@icovada] - [#9729]) ([device\_tracker.mikrotik docs][device_tracker.mikrotik docs]) * File permissions fix ([@cgarwood] - [#9847]) ([map docs]) * HassIO - TimeZone / Host 服务 ([@pvizeli] - [#9846]) ([hassio docs]) * Changing name of clicksendaudio component to clicksend\_tts ([@jeroenterheerdt] - [#9859]) ([通知.clicksend\_tts docs][通知.clicksend_tts docs]) (breaking change) * 升级 youtube\_dl to 2017.10.12 ([@fabaff] - [#9862]) ([media\_extractor docs][media_extractor docs]) * Uptime 传感器 ([@fronzbot] - [#9856]) ([传感器.uptime docs]) (new-platform) * Darksky enhancements ([@rdbahm] - [#9851]) ([传感器.darksky docs]) * 升级 psutil to 5.4.0 ([@fabaff] - [#9869]) ([传感器.systemmonitor docs]) * minimal fixes in the owntracks MQTT 设备 tracker ([@azogue] - [#9866]) ([device\_tracker.owntracks docs][device_tracker.owntracks docs]) * Cloud connection via aiohttp ([@balloob] - [#9860]) (new-platform) * handle OWM API 错误 calls ([@azogue] - [#9865]) ([传感器.openweathermap docs]) ([天气.openweathermap docs]) * 升级 paho-MQTT to 1.3.1 ([@fabaff] - [#9874]) ([MQTT docs]) ([shiftr docs]) * Fix for TypeError in synology 摄像头 ([@snjoetw] - [#9754]) ([摄像头.synology docs]) * missing is\_closed ( rflink 遮盖 fix ) ([@passie] - [#9776]) ([遮盖.rflink docs]) * \[灯光.tradfri] Fix transition time ([@lwis] - [#9785]) ([灯光.tradfri docs]) * OwnTracks: Fix handler is None checking ([@balloob] - [#9794]) ([device\_tracker.owntracks docs][device_tracker.owntracks docs]) * Changed yaml.load into yaml.safe\_load ([@GenericStudent] - [#9841]) * Bugfix/9811 jinja autoescape ([@GenericStudent] - [#9842]) * Fix #9839 ([@pschmitt] - [#9880]) * 升级 python-telegram-bot to 8.1.1 ([@azogue] - [#9882]) ([telegram\_bot docs][telegram_bot docs]) * Xknx improvements ([@Julius2342] - [#9871]) ([knx docs]) ([温控.knx docs]) * zha: 更新 to bellows 0.4.0 ([@rcloran] - [#9890]) ([zha docs]) ([传感器.zha docs]) * Changing clicksendaudio to clicksend\_tts in .coveragerc ([@jeroenterheerdt] - [#9900]) * Added super 属性 to Wink 二元sensor ([@w1ll1am23] - [#9824]) ([binary\_sensor.wink docs][binary_sensor.wink docs]) * 发布 0.55.2 ([@pvizeli] - [#9904]) * Dependemcy 版本 bump. ([@zabuldon] - [#9899]) ([device\_tracker.mikrotik docs][device_tracker.mikrotik docs]) * 更新 osramlightify.py ([@Bahnburner] - [#9905]) ([灯光.osramlightify docs]) * Fixes ([@bachya] - [#9912]) ([开关.rainmachine docs]) * Fix load of components without any config from packages ([@azogue] - [#9901]) (breaking change) * Fixes ([@bachya] - [#9911]) ([传感器.airvisual docs]) * add last\_action for xiaomi cube ([@danielhiversen] - [#9897]) ([binary\_sensor.xiaomi\_aqara docs][binary_sensor.xiaomi_aqara docs]) * Added support for Denon AVR-4810. ([@scarface-4711] - [#9887]) ([媒体播放器.denonavr docs]) * Recorder: Extra check to incoming connections which could be not sqlite3 ones ([@azogue] - [#9867]) * Fix the resource naming in the UI ([@cgtobi] - [#9916]) ([传感器.systemmonitor docs]) (breaking change) * 更新 xiaomi\_aqara.py ([@danielhiversen] - [#9920]) ([传感器.xiaomi\_aqara docs][传感器.xiaomi_aqara docs]) * Fix the resource naming in the UI ([@cgtobi] - [#9927]) ([传感器.glances docs]) * Add transmission 传感器: number of active torrents ([@mclem] - [#9914]) ([传感器.transmission docs]) * Google 动作 for Assistant ([@philk] - [#9632]) ([google\_assistant docs][google_assistant docs]) ([http docs]) (new-platform) * Allow flexible relayer url ([@balloob] - [#9939]) ([cloud.iot docs]) * 更新 async\_timeout from v1.4.0 tp v2.0.0 ([@TopdRob] - [#9938]) * Bump py-synology to 0.1.5 ([@arsaboo] - [#9932]) ([摄像头.synology docs]) * 更新 aioimaplib from v0.7.12 to v0.7.13 ([@TopdRob] - [#9930]) ([传感器.imap docs]) * A new platform for controlling Monoprice 6-区域 amplifier ([@etsinko] - [#9662]) ([媒体播放器.monoprice docs]) (new-platform) * Align away 状态 tag with device\_trackers ([@PeteBa] - [#9884]) ([传感器.mqtt\_room docs][传感器.mqtt_room docs]) (breaking change) * Add serial 传感器 ([@fabaff] - [#9861]) ([传感器.serial docs]) (new-platform) * Fix missing timeout for Netatmo 二元sensor ([@jabesq] - [#9850]) ([binary\_sensor.netatmo docs][binary_sensor.netatmo docs]) * Xiaomi config validation ([@danielhiversen] - [#9941]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * using defusedxml ElementTree for safer parsing of untrusted XML data ([@danielwelch] - [#9934]) ([device\_tracker.upc\_connect docs][device_tracker.upc_connect docs]) * 通知.xmpp - Add support for MUC ([@ldvc] - [#9931]) ([通知.xmpp docs]) * FFmpeg 1.8 ([@pvizeli] - [#9944]) ([ffmpeg docs]) ([摄像头.ffmpeg docs]) ([摄像头.onvif docs]) ([摄像头.yi docs]) * Changed returned 属性 from "Game" to "game" ([@itchaboy] - [#9945]) ([传感器.steam\_online docs][传感器.steam_online docs]) * Move '灯光' to const.py ([@fabaff] - [#9929]) ([abode docs]) ([vera docs]) ([灯光.模板 docs]) ([开关.flux docs]) * 更新 directpy to 0.2 ([@arsaboo] - [#9948]) * 更新 enocean to 0.40 ([@arsaboo] - [#9949]) ([enocean docs]) * 更新 hikvision to 1.2 ([@arsaboo] - [#9953]) ([开关.hikvisioncam docs]) * 更新 fritzhome to 1.0.3 ([@arsaboo] - [#9951]) * 更新 fritzconnection to 0.6.5 ([@arsaboo] - [#9950]) ([device\_tracker.fritz docs][device_tracker.fritz docs]) ([传感器.fritzbox\_callmonitor docs][传感器.fritzbox_callmonitor docs]) ([传感器.fritzbox\_netmonitor docs][传感器.fritzbox_netmonitor docs]) * Upgraded pyhomematic ([@danielperna84] - [#9956]) ([homematic docs]) * Add emeter 属性 ([@gollo] - [#9903]) ([灯光.tplink docs]) * Use default clientsession to stream synology video ([@snjoetw] - [#9959]) ([摄像头.synology docs]) * 更新 ffmpeg 1.9 ([@pvizeli] - [#9963]) * Improve SSL certs used by aiohttp ([@balloob] - [#9958]) ([cloud.iot docs]) * Fix async probs ([@pvizeli] - [#9924]) * Add Toon support ([@Boltgolt] - [#9483]) ([toon docs]) ([温控.toon docs]) ([传感器.toon docs]) ([开关.toon docs]) (new-platform) * \[tradfri] 更新 pytradfri, simplify dependencies. ([@lwis] - [#9875]) ([tradfri docs]) ([灯光.tradfri docs]) ([传感器.tradfri docs]) * Moved 警报器 to Wink from 开关 ([@w1ll1am23] - [#9879]) ([wink docs]) ([开关.wink docs]) (breaking change) * Remove async\_update ([@pvizeli] - [#9997]) [#8998]: https://github.com/home-assistant/home-assistant/pull/8998 [#9138]: https://github.com/home-assistant/home-assistant/pull/9138 [#9454]: https://github.com/home-assistant/home-assistant/pull/9454 [#9483]: https://github.com/home-assistant/home-assistant/pull/9483 [#9553]: https://github.com/home-assistant/home-assistant/pull/9553 [#9594]: https://github.com/home-assistant/home-assistant/pull/9594 [#9632]: https://github.com/home-assistant/home-assistant/pull/9632 [#9654]: https://github.com/home-assistant/home-assistant/pull/9654 [#9662]: https://github.com/home-assistant/home-assistant/pull/9662 [#9664]: https://github.com/home-assistant/home-assistant/pull/9664 [#9667]: https://github.com/home-assistant/home-assistant/pull/9667 [#9681]: https://github.com/home-assistant/home-assistant/pull/9681 [#9683]: https://github.com/home-assistant/home-assistant/pull/9683 [#9699]: https://github.com/home-assistant/home-assistant/pull/9699 [#9701]: https://github.com/home-assistant/home-assistant/pull/9701 [#9705]: https://github.com/home-assistant/home-assistant/pull/9705 [#9707]: https://github.com/home-assistant/home-assistant/pull/9707 [#9708]: https://github.com/home-assistant/home-assistant/pull/9708 [#9709]: https://github.com/home-assistant/home-assistant/pull/9709 [#9711]: https://github.com/home-assistant/home-assistant/pull/9711 [#9718]: https://github.com/home-assistant/home-assistant/pull/9718 [#9719]: https://github.com/home-assistant/home-assistant/pull/9719 [#9720]: https://github.com/home-assistant/home-assistant/pull/9720 [#9722]: https://github.com/home-assistant/home-assistant/pull/9722 [#9725]: https://github.com/home-assistant/home-assistant/pull/9725 [#9726]: https://github.com/home-assistant/home-assistant/pull/9726 [#9727]: https://github.com/home-assistant/home-assistant/pull/9727 [#9729]: https://github.com/home-assistant/home-assistant/pull/9729 [#9732]: https://github.com/home-assistant/home-assistant/pull/9732 [#9736]: https://github.com/home-assistant/home-assistant/pull/9736 [#9738]: https://github.com/home-assistant/home-assistant/pull/9738 [#9745]: https://github.com/home-assistant/home-assistant/pull/9745 [#9747]: https://github.com/home-assistant/home-assistant/pull/9747 [#9753]: https://github.com/home-assistant/home-assistant/pull/9753 [#9754]: https://github.com/home-assistant/home-assistant/pull/9754 [#9758]: https://github.com/home-assistant/home-assistant/pull/9758 [#9759]: https://github.com/home-assistant/home-assistant/pull/9759 [#9760]: https://github.com/home-assistant/home-assistant/pull/9760 [#9761]: https://github.com/home-assistant/home-assistant/pull/9761 [#9763]: https://github.com/home-assistant/home-assistant/pull/9763 [#9764]: https://github.com/home-assistant/home-assistant/pull/9764 [#9767]: https://github.com/home-assistant/home-assistant/pull/9767 [#9769]: https://github.com/home-assistant/home-assistant/pull/9769 [#9770]: https://github.com/home-assistant/home-assistant/pull/9770 [#9772]: https://github.com/home-assistant/home-assistant/pull/9772 [#9774]: https://github.com/home-assistant/home-assistant/pull/9774 [#9776]: https://github.com/home-assistant/home-assistant/pull/9776 [#9780]: https://github.com/home-assistant/home-assistant/pull/9780 [#9781]: https://github.com/home-assistant/home-assistant/pull/9781 [#9784]: https://github.com/home-assistant/home-assistant/pull/9784 [#9785]: https://github.com/home-assistant/home-assistant/pull/9785 [#9787]: https://github.com/home-assistant/home-assistant/pull/9787 [#9788]: https://github.com/home-assistant/home-assistant/pull/9788 [#9794]: https://github.com/home-assistant/home-assistant/pull/9794 [#9795]: https://github.com/home-assistant/home-assistant/pull/9795 [#9798]: https://github.com/home-assistant/home-assistant/pull/9798 [#9802]: https://github.com/home-assistant/home-assistant/pull/9802 [#9805]: https://github.com/home-assistant/home-assistant/pull/9805 [#9806]: https://github.com/home-assistant/home-assistant/pull/9806 [#9807]: https://github.com/home-assistant/home-assistant/pull/9807 [#9810]: https://github.com/home-assistant/home-assistant/pull/9810 [#9814]: https://github.com/home-assistant/home-assistant/pull/9814 [#9817]: https://github.com/home-assistant/home-assistant/pull/9817 [#9821]: https://github.com/home-assistant/home-assistant/pull/9821 [#9823]: https://github.com/home-assistant/home-assistant/pull/9823 [#9824]: https://github.com/home-assistant/home-assistant/pull/9824 [#9825]: https://github.com/home-assistant/home-assistant/pull/9825 [#9826]: https://github.com/home-assistant/home-assistant/pull/9826 [#9831]: https://github.com/home-assistant/home-assistant/pull/9831 [#9835]: https://github.com/home-assistant/home-assistant/pull/9835 [#9838]: https://github.com/home-assistant/home-assistant/pull/9838 [#9841]: https://github.com/home-assistant/home-assistant/pull/9841 [#9842]: https://github.com/home-assistant/home-assistant/pull/9842 [#9844]: https://github.com/home-assistant/home-assistant/pull/9844 [#9845]: https://github.com/home-assistant/home-assistant/pull/9845 [#9846]: https://github.com/home-assistant/home-assistant/pull/9846 [#9847]: https://github.com/home-assistant/home-assistant/pull/9847 [#9850]: https://github.com/home-assistant/home-assistant/pull/9850 [#9851]: https://github.com/home-assistant/home-assistant/pull/9851 [#9856]: https://github.com/home-assistant/home-assistant/pull/9856 [#9859]: https://github.com/home-assistant/home-assistant/pull/9859 [#9860]: https://github.com/home-assistant/home-assistant/pull/9860 [#9861]: https://github.com/home-assistant/home-assistant/pull/9861 [#9862]: https://github.com/home-assistant/home-assistant/pull/9862 [#9865]: https://github.com/home-assistant/home-assistant/pull/9865 [#9866]: https://github.com/home-assistant/home-assistant/pull/9866 [#9867]: https://github.com/home-assistant/home-assistant/pull/9867 [#9869]: https://github.com/home-assistant/home-assistant/pull/9869 [#9871]: https://github.com/home-assistant/home-assistant/pull/9871 [#9874]: https://github.com/home-assistant/home-assistant/pull/9874 [#9875]: https://github.com/home-assistant/home-assistant/pull/9875 [#9879]: https://github.com/home-assistant/home-assistant/pull/9879 [#9880]: https://github.com/home-assistant/home-assistant/pull/9880 [#9882]: https://github.com/home-assistant/home-assistant/pull/9882 [#9884]: https://github.com/home-assistant/home-assistant/pull/9884 [#9887]: https://github.com/home-assistant/home-assistant/pull/9887 [#9890]: https://github.com/home-assistant/home-assistant/pull/9890 [#9897]: https://github.com/home-assistant/home-assistant/pull/9897 [#9899]: https://github.com/home-assistant/home-assistant/pull/9899 [#9900]: https://github.com/home-assistant/home-assistant/pull/9900 [#9901]: https://github.com/home-assistant/home-assistant/pull/9901 [#9903]: https://github.com/home-assistant/home-assistant/pull/9903 [#9904]: https://github.com/home-assistant/home-assistant/pull/9904 [#9905]: https://github.com/home-assistant/home-assistant/pull/9905 [#9911]: https://github.com/home-assistant/home-assistant/pull/9911 [#9912]: https://github.com/home-assistant/home-assistant/pull/9912 [#9914]: https://github.com/home-assistant/home-assistant/pull/9914 [#9916]: https://github.com/home-assistant/home-assistant/pull/9916 [#9920]: https://github.com/home-assistant/home-assistant/pull/9920 [#9924]: https://github.com/home-assistant/home-assistant/pull/9924 [#9927]: https://github.com/home-assistant/home-assistant/pull/9927 [#9929]: https://github.com/home-assistant/home-assistant/pull/9929 [#9930]: https://github.com/home-assistant/home-assistant/pull/9930 [#9931]: https://github.com/home-assistant/home-assistant/pull/9931 [#9932]: https://github.com/home-assistant/home-assistant/pull/9932 [#9934]: https://github.com/home-assistant/home-assistant/pull/9934 [#9938]: https://github.com/home-assistant/home-assistant/pull/9938 [#9939]: https://github.com/home-assistant/home-assistant/pull/9939 [#9941]: https://github.com/home-assistant/home-assistant/pull/9941 [#9944]: https://github.com/home-assistant/home-assistant/pull/9944 [#9945]: https://github.com/home-assistant/home-assistant/pull/9945 [#9948]: https://github.com/home-assistant/home-assistant/pull/9948 [#9949]: https://github.com/home-assistant/home-assistant/pull/9949 [#9950]: https://github.com/home-assistant/home-assistant/pull/9950 [#9951]: https://github.com/home-assistant/home-assistant/pull/9951 [#9953]: https://github.com/home-assistant/home-assistant/pull/9953 [#9956]: https://github.com/home-assistant/home-assistant/pull/9956 [#9958]: https://github.com/home-assistant/home-assistant/pull/9958 [#9959]: https://github.com/home-assistant/home-assistant/pull/9959 [#9963]: https://github.com/home-assistant/home-assistant/pull/9963 [#9997]: https://github.com/home-assistant/home-assistant/pull/9997 [#10045]: https://github.com/home-assistant/home-assistant/pull/10045 [#10053]: https://github.com/home-assistant/home-assistant/pull/10053 [#10060]: https://github.com/home-assistant/home-assistant/pull/10060 [@Bahnburner]: https://github.com/Bahnburner [@Boltgolt]: https://github.com/Boltgolt [@ChristianKuehnel]: https://github.com/ChristianKuehnel [@GenericStudent]: https://github.com/GenericStudent [@Julius2342]: https://github.com/Julius2342 [@Kane610]: https://github.com/Kane610 [@MisterWil]: https://github.com/MisterWil [@Munsio]: https://github.com/Munsio [@PeteBa]: https://github.com/PeteBa [@TopdRob]: https://github.com/TopdRob [@alanfischer]: https://github.com/alanfischer [@andrey-git]: https://github.com/andrey-git [@armills]: https://github.com/armills [@arsaboo]: https://github.com/arsaboo [@azogue]: https://github.com/azogue [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@cdce8p]: https://github.com/cdce8p [@cgarwood]: https://github.com/cgarwood [@cgtobi]: https://github.com/cgtobi [@danielhiversen]: https://github.com/danielhiversen [@danielperna84]: https://github.com/danielperna84 [@danielwelch]: https://github.com/danielwelch [@etsinko]: https://github.com/etsinko [@fabaff]: https://github.com/fabaff [@flowolf]: https://github.com/flowolf [@fronzbot]: https://github.com/fronzbot [@gollo]: https://github.com/gollo [@happyleavesaoc]: https://github.com/happyleavesaoc [@icovada]: https://github.com/icovada [@itchaboy]: https://github.com/itchaboy [@jabesq]: https://github.com/jabesq [@jeroenterheerdt]: https://github.com/jeroenterheerdt [@ldvc]: https://github.com/ldvc [@lwis]: https://github.com/lwis [@mclem]: https://github.com/mclem [@passie]: https://github.com/passie [@philk]: https://github.com/philk [@pschmitt]: https://github.com/pschmitt [@pvizeli]: https://github.com/pvizeli [@rbflurry]: https://github.com/rbflurry [@rcloran]: https://github.com/rcloran [@rdbahm]: https://github.com/rdbahm [@ryanm101]: https://github.com/ryanm101 [@rytilahti]: https://github.com/rytilahti [@scarface-4711]: https://github.com/scarface-4711 [@sdague]: https://github.com/sdague [@snjoetw]: https://github.com/snjoetw [@syssi]: https://github.com/syssi [@tchellomello]: https://github.com/tchellomello [@tinloaf]: https://github.com/tinloaf [@vickyg3]: https://github.com/vickyg3 [@w1ll1am23]: https://github.com/w1ll1am23 [@webworxshop]: https://github.com/webworxshop [@zabuldon]: https://github.com/zabuldon [@ziotibia81]: https://github.com/ziotibia81 [abode docs]: /integrations/abode/ [alarm_control_panel.arlo docs]: /integrations/arlo [alarm_control_panel.egardia docs]: /integrations/egardia [alexa.smart_home docs]: /integrations/alexa.smart_home/ [arlo docs]: /integrations/arlo/ [自动化.event docs]: /docs/自动化/触发器/#event-触发器 [自动化.numeric_state docs]: /docs/自动化/触发器/#numeric-状态-触发器 [自动化.状态 docs]: /docs/自动化/触发器/#状态-触发器 [binary_sensor.iss docs]: /integrations/iss [binary_sensor.netatmo docs]: /integrations/netatmo#binary-传感器 [binary_sensor.skybell docs]: /integrations/skybell#binary-传感器 [binary_sensor.模板 docs]: /integrations/binary_sensor.模板/ [binary_sensor.tesla docs]: /integrations/tesla [binary_sensor.wink docs]: /integrations/wink#binary-传感器 [binary_sensor.xiaomi_aqara docs]: /integrations/binary_sensor.xiaomi_aqara/ [摄像头.arlo docs]: /integrations/arlo#摄像头 [摄像头.ffmpeg docs]: /integrations/摄像头.ffmpeg/ [摄像头.onvif docs]: /integrations/onvif [摄像头.skybell docs]: /integrations/skybell#摄像头 [摄像头.synology docs]: /integrations/synology [摄像头.yi docs]: /integrations/yi [温控.eq3btsmart docs]: /integrations/eq3btsmart [温控.knx docs]: /integrations/温控.knx/ [温控.MQTT docs]: /integrations/温控.MQTT/ [温控.tesla docs]: /integrations/tesla [温控.toon docs]: /integrations/toon#温控 [cloud.iot docs]: /integrations/cloud/ [遮盖.rflink docs]: /integrations/遮盖.rflink/ [device_tracker docs]: /integrations/device_tracker/ [device_tracker.fritz docs]: /integrations/fritz [device_tracker.mikrotik docs]: /integrations/mikrotik [device_tracker.netgear docs]: /integrations/netgear [device_tracker.owntracks docs]: /integrations/owntracks [device_tracker.snmp docs]: /integrations/snmp [device_tracker.unifi docs]: /integrations/unifi [device_tracker.upc_connect docs]: /integrations/upc_connect [enocean docs]: /integrations/enocean/ [ffmpeg docs]: /integrations/ffmpeg/ [google_assistant docs]: /integrations/google_assistant/ [hassio docs]: /integrations/hassio/ [homeassistant docs]: /integrations/homeassistant [homematic docs]: /integrations/homematic/ [http docs]: /integrations/http/ [knx docs]: /integrations/knx/ [灯光.hue docs]: /integrations/hue [灯光.mqtt_json docs]: /integrations/灯光.MQTT [灯光.osramlightify docs]: /integrations/osramlightify [灯光.skybell docs]: /integrations/skybell#灯光 [灯光.模板 docs]: /integrations/灯光.模板/ [灯光.tplink docs]: /integrations/tplink [灯光.tradfri docs]: /integrations/tradfri [灯光.yeelight docs]: /integrations/yeelight [门锁.tesla docs]: /integrations/tesla [map docs]: /integrations/map/ [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.denon docs]: /integrations/denon [媒体播放器.denonavr docs]: /integrations/denonavr/ [媒体播放器.dunehd docs]: /integrations/dunehd [媒体播放器.monoprice docs]: /integrations/monoprice [媒体播放器.plex docs]: /integrations/plex#media-player [媒体播放器.yamaha docs]: /integrations/yamaha [modbus docs]: /integrations/modbus/ [MQTT docs]: /integrations/MQTT/ [namecheapdns docs]: /integrations/namecheapdns/ [通知.clicksend_tts docs]: /integrations/clicksend_tts/ [通知.html5 docs]: /integrations/html5 [通知.rocketchat docs]: /integrations/rocketchat [通知.xmpp docs]: /integrations/xmpp [python_script docs]: /integrations/python_script/ [raincloud docs]: /integrations/raincloud/ [传感器.abode docs]: /integrations/abode [传感器.airvisual docs]: /integrations/airvisual [传感器.android_ip_webcam docs]: /integrations/android_ip_webcam#传感器 [传感器.arlo docs]: /integrations/arlo#传感器 [传感器.arwn docs]: /integrations/arwn [传感器.darksky docs]: /integrations/darksky [传感器.fitbit docs]: /integrations/fitbit [传感器.fritzbox_callmonitor docs]: /integrations/fritzbox#sensor_callmonitor/ [传感器.fritzbox_netmonitor docs]: /integrations/fritzbox#sensor_netmonitor/ [传感器.glances docs]: /integrations/glances [传感器.imap docs]: /integrations/imap [传感器.ios docs]: /integrations/传感器.ios/ [传感器.mqtt_room docs]: /integrations/mqtt_room [传感器.netdata docs]: /integrations/netdata [传感器.openweathermap docs]: /integrations/openweathermap#传感器 [传感器.raincloud docs]: /integrations/raincloud#传感器 [传感器.ring docs]: /integrations/ring#传感器 [传感器.serial docs]: /integrations/serial [传感器.skybell docs]: /integrations/skybell#传感器 [传感器.snmp docs]: /integrations/snmp#传感器 [传感器.statistics docs]: /integrations/statistics [传感器.steam_online docs]: /integrations/steam_online [传感器.systemmonitor docs]: /integrations/systemmonitor [传感器.tesla docs]: /integrations/tesla [传感器.toon docs]: /integrations/toon [传感器.tradfri docs]: /integrations/tradfri [传感器.transmission docs]: /integrations/transmission [传感器.travisci docs]: /integrations/travisci [传感器.uptime docs]: /integrations/uptime [传感器.vera docs]: /integrations/vera#传感器 [传感器.xiaomi_aqara docs]: /integrations/传感器.xiaomi_aqara/ [传感器.zha docs]: /integrations/zha [shiftr docs]: /integrations/shiftr/ [skybell docs]: /integrations/skybell/ [开关.flux docs]: /integrations/flux [开关.hikvisioncam docs]: /integrations/hikvisioncam [开关.rainmachine docs]: /integrations/rainmachine#开关 [开关.skybell docs]: /integrations/skybell#开关 [开关.tesla docs]: /integrations/tesla [开关.toon docs]: /integrations/toon [开关.tplink docs]: /integrations/tplink [开关.wink docs]: /integrations/wink#开关 [开关.xiaomi_miio docs]: /integrations/开关.xiaomi_miio/ [telegram_bot docs]: /integrations/telegram_bot/ [tesla docs]: /integrations/tesla/ [toon docs]: /integrations/toon/ [tradfri docs]: /integrations/tradfri/ [吸尘器 docs]: /integrations/吸尘器/ [吸尘器.dyson docs]: /integrations/dyson#吸尘器 [吸尘器.MQTT docs]: /integrations/吸尘器.MQTT/ [vera docs]: /integrations/vera/ [天气.openweathermap docs]: /integrations/openweathermap#天气 [wink docs]: /integrations/wink/ [xiaomi_aqara docs]: /integrations/xiaomi_aqara/ [zha docs]: /integrations/zha/ [#10024]: https://github.com/home-assistant/home-assistant/pull/10024 [#10029]: https://github.com/home-assistant/home-assistant/pull/10029 [@bieniu]: https://github.com/bieniu --- url: /home-assistant/blog/2017-10-23-simple-analog-sensor.md --- # Serial analog 传感器 This 博客 post is about building a super simple analog 传感器 for Home Assistant. The physical 传感器 will send the data over its virtual serial port as it will be connected over USB. The concept is similar to the [TEMPer USB](/home-assistant/integrations/temper.md) 设备. The attatched 传感器 type to the microcontroller can be any kind of 传感器 which gives you an analog signal from brightness over soil moisture to temperature. The microcontroller will only transfer the voltage of an analog input pin which will be between 0 and 1024. Home Assistant will use the new [`serial`](/home-assistant/integrations/serial.md) 传感器 platform to read the data and perform 动作 to convert the raw reading into a real measurement. This means that you don't have to adjust the code of your microcontroller if you change the attached 传感器 type.

The assembled 传感器

All parts needed in this how-to can be bought for less than 2 Euro or 2 USD from China. I'm going to use the following items which were already available in my craft crate: * [Digispark USB Development Board](http://digistump.com/category/1) * Temperature 传感器 [TMP36](http://www.analog.com/media/en/technical-文档/data-sheets/TMP35_36_37.pdf) (or any other 传感器 that gives you an analog signal) * Cables (if you don't want to connect the 传感器 directly to the board) The cabling is easy. | 传感器 | Digispark | |--------|-----------| | GND | GND | | VCC | 5V | | VOUT | P4 | There are other boards with the same size available. Like those with the far more powerful Mega32U4 chip. However, it would work with boards from the Arduino family as well if you adjust the code provided below. The sketch is pretty simple. We are going to send the readings to a virtual [serial output](https://digistump.com/wiki/digispark/tutorials/digicdc) every 5 seconds. No logic needed. A little plus is that the onboard LED is blinking as an indicator that the board is working. [Upload](https://digistump.com/wiki/digispark) the code to your Digispark board. Keep in mind that the upload process is different than with Arduino or ESP8266 boards. ```cpp #include #define LED_PIN 1 #define INPUT_PIN 2 // Physical pin P4 is analog input 2 void setup() { SerialUSB.begin(); pinMode(LED_PIN, OUTPUT); } void loop() { if (SerialUSB.available()) { digitalWrite(LED_PIN, HIGH); SerialUSB.delay(250); int reading = analogRead(INPUT_PIN); SerialUSB.println(reading); digitalWrite(LED_PIN, LOW); SerialUSB.delay(5000); } } ``` To make it work with other boards simply use [`Serial.begin(115200);`](https://www.arduino.cc/en/Reference/Serial) and [`Serial.println(reading);`](https://www.arduino.cc/en/Serial/Println). If you connect with a tool like `minicom` to your system's serial port `/dev/ttyACM0`, then you will get the data. To use the 传感器 with Home Assistant the [`serial`](/home-assistant/integrations/serial.md) 传感器 platform needs to be set up. ```yaml sensor: - platform: serial port: /dev/ttyACM0 ``` The physical 传感器 reads the current voltage of the pin. A [template 传感器](/home-assistant/integrations/template.md) takes the reading and converts it into a measurement. The data sheet of the 传感器 unit usually contains details about the involved calculations. ```yaml - platform: template sensors: temperature: friendly_name: Temperature unit_of_measurement: "°C" value_template: "" ``` Hide the serial 传感器 if you don't want to see the raw data in the 前端 and you are done. The whole 设置 with a Digispark is not very reliable because there is no hardware USB support. As a showcase and if you don't build your 自动化 rules around it does the 传感器 what it should for a very small price. --- url: /home-assistant/blog/2017-10-28-demo.md --- # Home Assistant Demo If you are planning to host a Home Assistant meetup or doing a talk, then you probably want to show Home Assistant to an audience. You could use a Wireless router, bulbs, 开关, and a single board computer to do a realistic demo. For a workshop, this is what I usually do because I think that working with physical hardware is more fun for the participants. The issue is that you need time to set up, power and space. For a talk or in a location, where you only have a beamer and a table or a lectern, the physical hardware approach is not very convenient. The simplest way to show Home Assistant to others is the online demo at [/demo/](/home-assistant/demo/)

Home Assistant's online demo

## `--demo-mode` and Demo platform To be safe for your talk, you don't want to depend on an internet connection. The demo mode `--demo-mode` allows you to run a demo locally including the latest features. Make sure that you have a 备份 of your 配置. ```bash hass --demo-mode ``` If you already have a `configuration.yaml` file in place then you will get a combination of your 设置 with all available [`demo`](/home-assistant/integrations/demo/index.md) platforms. This can be overwhelming for the audience. The suggestion is that you tailor the demo to your needs by only showing a few selected platforms. For example: ```yaml sensor: - platform: demo binary_sensor: - platform: demo switch: - platform: demo ```

Home Assistant's demo platforms

## `random` platforms Till now the 前端 is static. Nothing is changing over time. Starting with 0.57 we ship a [`random` 二元sensor](/home-assistant/integrations/random/index.md#binary-sensor) platform in addition to the already available [`random` sensor](/home-assistant/integrations/random.md#sensor). By adding those platform to your `configuration.yaml` file, your demo will become more interactive. ```yaml sensor: - platform: demo name: Temperature unit_of_measurement: "°C" binary_sensor: - platform: random name: Front Door - platform: random name: Back Door scan_interval: 5 ```

Demo with `random` platforms

The `random` and the `demo` platforms can, of course, be used together. With a little work and some of the [`template`](/home-assistant/integrations/index.md#search/template) platforms or the [`input_*`](/home-assistant/integrations/index.md#search/input) components it would even be possible to simulate a complete apartment or a house. For a hint check the sample below: ```yaml input_boolean: on_off: name: On or off binary_sensor: - platform: template sensors: on_tester: value_template: "" friendly_name: "Movement" device_class: motion ``` ## MQTT Discovery This is a section for advanced 用户 as it will require to run a separate 脚本. Instead of adding `demo` platforms to the 配置 this 设置 make use of [MQTT discovery](/home-assistant/docs/MQTT/discovery/). Simply add MQTT to your `configuration.yaml` file with `discovery:` ```yaml mqtt: host: YOUR_MQTT_HOST discovery: true ``` Download the [sample 脚本](https://github.com/home-assistant/home-assistant-dev-helper/blob/master/ha-MQTT-demo.py). It depends on [paho-MQTT](https://pypi.python.org/pypi/paho-MQTT). If you run the 脚本 inside your [Home Assistant's virtual environment](/home-assistant/docs/installation/virtualenv/) then you are good to go as the dependency should be present if you have used MQTT before. Otherwise, 安装 it with `$ pip3 install paho-mqtt`. ```bash (ha)[ha-demo]$ python3 ha-mqtt-demo.py Demo is running... -> CTRL + C to shutdown ``` It will create 传感器, a 灯光, and a 开关 and 更新 the 状态 as long the 脚本 is running. It possible to stop and 重启 脚本 without losing the 实体. Some 用户 share their slides and other documents in [our assets repository](https://github.com/home-assistant/home-assistant-assets). Also, take a look at that repository if you need a logo for your slides. --- url: /home-assistant/blog/2017-11-02-secure-shell-tunnel.md --- # Home Assistant 与 SSH 大多数系统工程师都非常熟悉 [SSH (Secure shell)](https://en.wikipedia.org/wiki/Secure_Shell)。这个工具由服务端和客户端两部分组成,用于以安全的方式访问远程系统。如果你正在运行 Home Assistant,但又不想把它直接暴露在公网中,它同样能帮上忙。在 Linux 系统上,SSH 通常默认可用。如果你使用的是 Windows 安装,则需要额外步骤,而这些内容不在本文讨论范围内。 在这篇博客文章中,我们将使用 SSH 的隧道功能来建立一条安全连接,并把 Home Assistant 前端转发到本地系统。 涉及的双方如下: * **远程系统**:运行 Home Assistant 的地方,通常位于你的家庭网络中。 * **本地系统**:你想查看前端的设备。 前提条件是,你需要在路由器上把 22 端口转发到家庭网络中运行 Home Assistant 的那台设备。你可能还需要在远程系统上通过 `$ sudo systemctl start sshd` 启用 SSH 守护进程,并调整主机防火墙设置。如果你运行的是 [Hass.io](/home-assistant/hassio/),那就启用 [SSH Server add-on](/home-assistant/addons/ssh/)。你还必须具备一个公网 IP 地址或主机名,这可以通过动态 DNS 提供(例如 [NO-IP](https://www.noip.com/) 或 [DuckDNS](https://www.duckdns.org/))。 在本地系统上,你只需要一个 SSH 客户端,并且你所在的网络允许 SSH 连接即可。 先来看一下我们要使用的命令。更多信息可以通过 `man ssh` 获取。 ```bash $ ssh -L 8000:localhost:8123 user@[IP_ADDRESS_REMOTE] | | | | | | | | | | | |_ IP address or hostname of your router. | | | | |_ Username on the remote system. | | | |_ Port where the application is running. | | |_ We want the frontend on this system. | |_ The port on our local system to use (above 1024). |_ We want to do local port forwarding. ``` 一个可能的示例如下。 ```bash ssh -L 8000:localhost:8123 ha@192.168.0.11 ``` 第一次建立连接时,你需要接受指纹。 ```bash The authenticity of host '192.168.0.11 (192.168.0.11)' can't be established. ECDSA key fingerprint is SHA256:asdf2faasd4gk45454fadr78wfadfasdfeg4vvvsae33. ECDSA key fingerprint is MD5:44:d4:f7:44:d4:aa:b8:de:ef:09:3e:0d:4e:12:11:09. Are you sure you want to continue connecting (yes/no)? Warning: Permanently added '192.168.0.162' (ECDSA) to the list of known hosts. ha@192.168.0.11's password: Last login: Fri Oct 27 17:50:09 2017 [ha@home-assistant ~]$ ``` 现在你就可以在本地系统上使用前端了:`http://localhost:8000` 需要记住的几点: * 如果你想通过互联网使用它,就需要公网 IP 地址或主机名(动态 DNS 也可以)。 * 你需要在路由器上设置端口转发。 * 不要允许 `root` 使用 SSH。请在远程系统上设置 `PermitRootLogin no`。 * 本地端口必须大于 1024。只有 `root` 才能转发 1024 以下的特权端口。 * 使用 [SSH keys for authentication](http://docs.fedoraproject.org//en-US/Fedora/14/html/Deployment_Guide/s2-ssh-configuration-keypairs.html) 而不是密码,以避免暴力破解攻击。 --- url: /home-assistant/blog/2017-11-04-release-57.md --- # 0.57: Translations, Hacktoberfest, Timers

The Home Assistant sidebar in 12 different languages Home Assistant 侧边栏的 12 种语言版本。

大家好啊?! 在虚拟的 Home Assistant 总部,这又是疯狂的两周,来自世界各地的大量优秀贡献纷至沓来。新功能、Bug 修复、性能提升,应有尽有。内容很多,我们直接开始吧。 ## 翻译 如果你还没从上面的截图里看出来,第一个重磅功能就是:我们现在可以翻译 UI 了!目前翻译范围还只限于侧边栏菜单项。即使当时还没有正式的翻译工具,贡献者们也已经迅速投入,提交了二十多种语言的菜单翻译!Home Assistant 会根据你的浏览器设置自动选择可用翻译,也可以在配置面板里手动切换语言。 我们目前正在把基于 Web 的翻译工具 [lokalise.co](https://lokalise.co) 集成进来,让任何愿意贡献的人都能方便参与翻译。更多文档和博客文章很快就会发布,敬请期待。 ## 前端改进 为了让翻译功能顺利运作,我们在前端侧做了大量清理工作。这次重组将帮助我们更快地迭代前端。@armills 和 @andrey-git 持续推动质量提升,也让这轮清理工作成果显著! ## Hacktoberfest [Hacktoberfest](https://hacktoberfest.digitalocean.com/) 2017 终于结束了!总算告一段落。每年都会有更多开发者想为 Home Assistant 做贡献,这当然是好事,但也让代码评审者们非常辛苦。我要特别向 @pvizeli、@andrey-git、@armills、@MartinHjelmare、@fabaff 致以超级巨大的感谢。你们做得太棒了,没有你们就没有 Home Assistant! ❤ Hacktoberfest 说到底,就是属于所有为开源做贡献的人。非常感谢每一位愿意花时间了解我们代码库并提交贡献的朋友。希望这次经历让你感受到开源的魅力,也期待未来继续看到你们的贡献 👍 下面是我们的 Hacktoberfest 2017 数据统计。大家居然都还活着,简直是个奇迹: * Main repo: [273 Pull requests](https://github.com/home-assistant/home-assistant/pulls?utf8=%E2%9C%93\&q=merged%3A%3E2017-10-01%20is%3Apr%20label%3AHacktoberfest%20is%3Aclosed%20) were merged out of 307. * Docs repo: [295 Pull requests](https://github.com/home-assistant/home-assistant.io/pulls?page=1\&q=merged%3A%3E2017-10-01+is%3Apr+label%3AHacktoberfest+is%3Aclosed\&utf8=%E2%9C%93) merged out of 310. * Frontend: [57 pull requests](https://github.com/home-assistant/home-assistant-polymer/pulls?utf8=%E2%9C%93\&q=merged%3A%3E2017-10-01%20is%3Apr%20label%3AHacktoberfest%20is%3Aclosed%20) merged. 这意味着我们平均每天处理超过 20 个 Pull Request。0.56 中已经能看到成果,而这次发布也差不多。仅这几次发布中,我们就加入了 40 多个新集成。 ## IKEA TRÅDFRI 关于 IKEA TRADFRI,这里有好消息也有坏消息。坏消息是,IKEA 在一次固件更新中修改了内部 API,导致 Home Assistant 集成失效。好消息是,他们非常友善地[给我们发了邮件,说明这些不向后兼容的变更][ikea email]。 长期贡献者 [@lwis] 迅速接手处理,并及时完成了 Home Assistant 中该集成的迁移,赶上了这次发布。干得漂亮!

Pumpkin with Home Assistant logo carved in. @clhett01 给我们刻了一只南瓜([来自 Twitter](https://twitter.com/clhett01/status/925481848612032512))

## 计时器 在你开始查看更新日志之前,再来看一个亮点。贡献者 [@danielperna84](因创建 [HASS Configurator](/home-assistant/addons/configurator/) 而广为人知)这次又带来了一个很棒的新组件:计时器组件。借助它,你可以启动倒计时计时器,是自动化工具箱里非常实用的一件工具!更多信息请查看 [timer docs]。 ## 新平台 * Introducing Ring Door Bell Camera (including StickUp cameras) and WiFi sensors ([@tchellomello] - [#9962]) ([ring docs]) ([binary\_sensor.ring docs][binary_sensor.ring docs]) ([摄像头.ring docs]) ([传感器.ring docs]) (new-platform) * add irish rail transport sensor ([@ttroy50] - [#9883]) ([传感器.irish\_rail\_transport docs][传感器.irish_rail_transport docs]) (new-platform) * Add fail2ban sensor ([@fronzbot] - [#9975]) ([传感器.fail2ban docs]) (new-platform) * add eph ember controls ([@ttroy50] - [#9721]) ([温控.ephember docs]) (new-platform) * whois domain lookup sensor ([@GenericStudent] - [#10000]) ([传感器.whois docs]) (new-platform) * Add Deluge Switch Component ([@HydrelioxGitHub] - [#9979]) ([开关.deluge docs]) (new-platform) * SNMP switch ([@kirichkov] - [#9840]) ([开关.snmp docs]) (new-platform) * Microsoft tts ([@jeroenterheerdt] - [#9973]) ([tts.microsoft docs]) (new-platform) * Telldus Live: Device without methods is a binary sensor ([@rasmusbe] - [#10106]) ([tellduslive docs]) ([binary\_sensor.tellduslive docs][binary_sensor.tellduslive docs]) (new-platform) * Support for NO-IP ([@fabaff] - [#10155]) ([no\_ip docs][no_ip docs]) (new-platform) * Linode ([@ryanm101] - [#9936]) ([linode docs]) ([binary\_sensor.linode docs][binary_sensor.linode docs]) (new-platform) * Nederlandse spoorwegen ([@b10m] - [#10136]) ([传感器.nederlandse\_spoorwegen docs][传感器.nederlandse_spoorwegen docs]) (new-platform) * added Yesss SMS platform ([@flowolf] - [#10177]) (new-platform) * Add Sytadin Traffic component ([@gautric] - [#9524]) (new-platform) * Added new Clickatell SMS messaging Notify Platform ([@davlloyd] - [#9775]) ([通知.clickatell docs]) (new-platform) * Add Random binary sensor ([@fabaff] - [#10164]) ([binary\_sensor.random docs][binary_sensor.random docs]) (new-platform) * Add gc100 platforms and component ([@davegravy] - [#10159]) ([gc100 docs]) ([binary\_sensor.gc100 docs][binary_sensor.gc100 docs]) ([开关.gc100 docs]) (new-platform) * Timer component ([@danielperna84] - [#9889]) ([timer docs]) (new-platform) * integration with Remember The Milk. ([@ChristianKuehnel] - [#9803]) ([remember\_the\_milk docs][remember_the_milk docs]) (new-platform) * Luftdaten sensor ([@lichtteil] - [#10274]) ([传感器.luftdaten docs]) (new-platform) ## release 0.57.1 - november 4 * Fix login screen not showing when no password stored ([@balloob]) ## release 0.57.2 - november 5 * Update frontend with fixes for setting temperature on climate card ([@balloob]) * Fix setting max brightness for TRADFRI ([@ggravlingen] - [#10359]) ## release 0.57.3 - november 11 * Tellstick Duo acync callback fix ([@stefan-jonasson] - [#10384]) ([tellstick docs]) * Fixed update() method and removed `ding` feature from stickupcams/floodlight ([@tchellomello] - [#10428]) ([binary\_sensor.ring docs][binary_sensor.ring docs]) ([摄像头.ring docs]) ([传感器.ring docs]) ## 如果你需要帮助…… ……欢迎使用我们非常活跃的[论坛](https://community.home-assistant.io/),或者加入我们的[聊天频道](https://discord.gg/c5DvZ4e)。虽然发布说明开放了评论,但我们更推荐你使用前面的社区交流渠道。谢谢。 ## 反馈问题 如果你遇到了此次发布引入的问题,请在我们的 [issue tracker](https://github.com/home-assistant/home-assistant/issues) 中反馈。请确保完整填写 issue 模板中的所有字段。 ## 不向后兼容的变更 * IKEA TRÅDFRI: We no longer support entering the key in the configuration. ([@lwis] - [#10282]) ([tradfri docs]) (breaking change) * API.AI was renamed to [Dialogflow](/home-assistant/integrations/dialogflow/index.md). This requires to rename the entry in your `configuration.yaml` file from `apiai:` to `dialogflow`. ([@fabaff] - [#10006]) ([dialogflow docs]) (breaking change) * Wink: Removed support for entering your `username` and `password` in your config. Use the [new authentication method][wink-auth] instead. ([@w1ll1am23] - [#10277]) ([wink docs]) (breaking change) * Use feed name assigned in EmonCMS if there is one. This changes the default behavior but still uses configured 'name' if it's set, so it won't break the configuration of people who have customized their feed names in HA config. ([@KlaasH] - [#10021]) ([传感器.emoncms docs]) (breaking change) * The `namecheapdns` now uses `password:` instead of `access_token` in the configuration. Also, `host` is now optional which allow people who are not using subdomains to keep their configuration shorter. ([@fabaff] - [#10063]) ([namecheapdns docs]) (breaking change) * Fix recorder crash for long state string - enforce a maximum state of 255 characters at core level ([@milanvo] - [#9696]) (breaking change) * Add display currency setting to CoinMarketCap 传感器. The name of the sensor attribute '24h\_volume\_usd' is changed to '24h\_volume'. ([@EarthlingRich] - [#10093]) ([传感器.coinmarketcap docs]) (breaking change) * MQTT Statestream now serializes all data to JSON before publishing. This means that string attributes and values will be quoted from now on (e.g.: '"on"' instead of 'on'). You can still read these strings without the quotes by using 'value\_json' instead of 'value' where applicable (e.g., templates). This causes automatic JSON deserialization. Other simple types are not affected. This fixes errors when an entity has an attribute that is not "a string, bytearray, int, float or None" and mqtt\_statestream is used. As of now, the attribute is just handed over to paho, and paho can only send the aforementioned types. This patch fixes the issue by just casting everything to string before handing it over to paho. There are a number of components / entities which have "other" attributes, e.g., light that have an RGB attribute which is a list. ([@tinloaf] - [#9872]) ([mqtt\_statestream docs][mqtt_statestream docs]) (breaking change) * Generic thermostat: the configuration option `tolerance` has been removed and has been replaced by `cold_tolerance` and `hot_tolerance`. This allows on and off states to have different error bands. ([@biggms] - [#9843]) ([温控.generic\_thermostat docs][温控.generic_thermostat docs]) (breaking change) * Developers only: frontend has been refactored. The method `register_panel` has been turned into a coroutine function called `async_register_panel`. The parameter `url_path` has been renamed to `frontend_url_path`. For frontend, development, you no longer pass `development: 1` to the http component but instead configure the frontend component to be in development mode by pointing it at a local checkout of the Polymer repo: ([@balloob] - [#9915]) (breaking change) ## 全部变更 * Update requests requirement ([@TopdRob] - [#9876]) * Update `screenshot-components.png` file. ([@quamilek] - [#9987]) * Upgrade speedtest-cli to 1.0.7 ([@fabaff] - [#9984]) ([传感器.speedtest docs]) * Upgrade gitterpy to 0.1.6 ([@fabaff] - [#9983]) ([传感器.gitter docs]) * Add optional attribute option to scrape sensor ([@DarkFox] - [#10001]) ([传感器.scrape docs]) * Introducing Ring Door Bell Camera (including StickUp cameras) and WiFi sensors ([@tchellomello] - [#9962]) ([ring docs]) ([binary\_sensor.ring docs][binary_sensor.ring docs]) ([摄像头.ring docs]) ([传感器.ring docs]) (new-platform) * Add support for multiple disks to be monitored. ([@cgtobi] - [#9977]) ([传感器.hddtemp docs]) * Update the Russound RNET component to use enhanced Russound.py ([@altersis] - [#9739]) ([media\_player.russound\_rnet docs][media_player.russound_rnet docs]) * Fix spelling error ([@SilvrrGIT] - [#10009]) * Change persistent notification to avoid long text in entity state ([@milanvo] - [#9967]) ([persistent\_notification docs][persistent_notification docs]) * Renaming API.AI to Dialogflow ([@fabaff] - [#10006]) ([dialogflow docs]) (breaking change) * Bump dev to 0.57.0.dev0 ([@fabaff] - [#10010]) * Add xy attribute to Yeelight ([@HydrelioxGitHub] - [#9957]) ([light.yeelight docs]) * Added gaction script to support the new Google Assistant component in Docker ([@chriskacerguis] - [#10019]) * Json api fix ([@alanfischer] - [#10017]) * Upgrade mypy to 0.540 ([@fabaff] - [#10013]) * Xiaomi Aqara: New xiaomi wireless button (sensor\_开关.aq3) introduced ([@syssi] - [#10008]) ([binary\_sensor.xiaomi\_aqara docs][binary_sensor.xiaomi_aqara docs]) * Upgrade youtube\_dl to 2017.10.20 ([@fabaff] - [#10014]) ([media\_extractor docs][media_extractor docs]) * 开关.flux: add interval and transition attributes ([@abmantis] - [#9700]) ([开关.flux docs]) * Use feed name assigned in EmonCMS if there is one ([@KlaasH] - [#10021]) ([传感器.emoncms docs]) (breaking change) * add irish rail transport sensor ([@ttroy50] - [#9883]) ([传感器.irish\_rail\_transport docs][传感器.irish_rail_transport docs]) (new-platform) * RGB Tradfri simple support ([@matemaciek] - [#9703]) ([light.tradfri docs]) * Add regression test for entity ID update bug ([@armills] - [#10037]) * Aioautomatic bump and scope update ([@armills] - [#10043]) * Fix no data event triggers ([@armills] - [#10049]) ([automation.event docs]) * fixing a typo in the old library which broke hub gen2 compatibility ([@sander76] - [#9990]) * Add fail2ban sensor ([@fronzbot] - [#9975]) ([传感器.fail2ban docs]) (new-platform) * Show current program thumbnail as media\_image ([@pschmitt] - [#10033]) * Add link to docs and update ordering ([@fabaff] - [#10062]) ([duckdns docs]) * Remove STATE\_UNKNOWN ([@fabaff] - [#10064]) ([传感器.glances docs]) * update library for xiaomi\_aqara, change from pyCrypto to cryptography ([@danielhiversen] - [#10066]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * Make host optional ([@fabaff] - [#10063]) ([namecheapdns docs]) (breaking change) * Change deprecated use of maintainer tag in Dockerfile. ([@EarthlingRich] - [#10068]) * add eph ember controls ([@ttroy50] - [#9721]) ([温控.ephember docs]) (new-platform) * EntityComponent: revert warning ([@pvizeli] - [#10078]) * Upgrade Sphinx to 1.6.5 ([@fabaff] - [#10090]) * Support for Entity.available in sensor/rest ([@pezinek] - [#10073]) ([传感器.rest docs]) * whois domain lookup sensor ([@GenericStudent] - [#10000]) ([传感器.whois docs]) (new-platform) * Update CODEOWNERS ([@danielhiversen] - [#10103]) * fixed typo ([@iMarkus] - [#10110]) * Revert gactions in Docker ([@balloob] - [#10115]) * Add Deluge Switch Component ([@HydrelioxGitHub] - [#9979]) ([开关.deluge docs]) (new-platform) * Fix PEP8 and PEP257 issues ([@fabaff] - [#10108]) ([toon docs]) ([温控.toon docs]) ([传感器.toon docs]) ([开关.toon docs]) * Fixes #10030. Extented Network Exceptions handling. ([@zabuldon] - [#10116]) ([tesla docs]) * Consolidate frontend ([@balloob] - [#9915]) (breaking change) * Rfxtrx fix ([@danielhiversen] - [#10128]) ([rfxtrx docs]) * Xiaomi MiIO Fan: Xiaomi Air Purifier 2 integration ([@syssi] - [#9837]) ([fan.xiaomi\_miio docs][fan.xiaomi_miio docs]) * WIP: Refactor Axis component removing external dependencies ([@Kane610] - [#9791]) ([axis docs]) ([binary\_sensor.axis docs][binary_sensor.axis docs]) * Allow folder selection for IMAP unread sensor ([@amelchio] - [#10126]) ([传感器.imap docs]) * Fix Sonarr and Radarr divide by zero ([@tboyce021] - [#10101]) ([传感器.radarr docs]) ([传感器.sonarr docs]) * Plex refactor Part 1 - Update plexapi to 3.0.3 ([@ryanm101] - [#9988]) ([media\_player.plex docs][media_player.plex docs]) * Add Google Domains component ([@tboyce021] - [#9996]) * Add Deluge Sensor ([@HydrelioxGitHub] - [#10117]) * Added increment + decrement to input\_number ([@danielperna84] - [#9870]) ([input\_number docs][input_number docs]) * Fix lint google-domains ([@pvizeli] - [#10135]) ([google\_domains docs][google_domains docs]) * Fire numeric\_state action when first state change matches criteria ([@amelchio] - [#10125]) ([automation.numeric\_state docs][automation.numeric_state docs]) * SNMP switch ([@kirichkov] - [#9840]) ([开关.snmp docs]) (new-platform) * Binary sensor for detecting linear trends ([@hotplot] - [#9808]) ([binary\_sensor.trend docs][binary_sensor.trend docs]) * Fix recorder crash for long state string - enforce at core level ([@milanvo] - [#9696]) (breaking change) * Microsoft tts ([@jeroenterheerdt] - [#9973]) ([tts.microsoft docs]) (new-platform) * Upgrade pysnmp to 4.4.1 ([@fabaff] - [#10138]) ([device\_tracker.snmp docs][device_tracker.snmp docs]) ([传感器.snmp docs]) ([开关.snmp docs]) * Telldus Live: Device without methods is a binary sensor ([@rasmusbe] - [#10106]) ([tellduslive docs]) ([binary\_sensor.tellduslive docs][binary_sensor.tellduslive docs]) (new-platform) * Add last action to xiaomi aqara button ([@danielhiversen] - [#10131]) ([binary\_sensor.xiaomi\_aqara docs][binary_sensor.xiaomi_aqara docs]) * Add display currency setting to CoinMarketCap sensor ([@EarthlingRich] - [#10093]) ([传感器.coinmarketcap docs]) (breaking change) * Xiaomi MiIO Switch: Support for different device types ([@syssi] - [#9836]) ([开关.xiaomi\_miio docs][开关.xiaomi_miio docs]) * Core POC support for polymer i18n ([@armills] - [#6344]) ([history docs]) ([logbook docs]) * Don't use pypi package in dev mode. Allow non-fingerprinted mdi. ([@andrey-git] - [#10144]) * added platform discovery code back into device\_tracker ([@etsinko] - [#10169]) ([device\_tracker docs][device_tracker docs]) * Upgrade sendgrid to 5.3.0 ([@fabaff] - [#10166]) ([通知.sendgrid docs]) * Upgrade python\_opendata\_transport to 0.0.3 ([@fabaff] - [#10162]) ([传感器.swiss\_public\_transport docs][传感器.swiss_public_transport docs]) * Upgrade libnacl to 1.6.1 ([@fabaff] - [#10161]) ([device\_tracker.owntracks docs][device_tracker.owntracks docs]) * New DTLSSocket version that fixes Cython dependency for Trådfri ([@flowolf] - [#10123]) ([tradfri docs]) * Rfxtrx binary sensor rewrite ([@ypollart] - [#10152]) ([rfxtrx docs]) ([binary\_sensor.rfxtrx docs][binary_sensor.rfxtrx docs]) * Support for NO-IP ([@fabaff] - [#10155]) ([no\_ip docs][no_ip docs]) (new-platform) * Reduce album art flickering in media player UI ([@amelchio] - [#10163]) ([media\_player docs][media_player docs]) * Avoid Sonos errors for tracks with no artist information ([@amelchio] - [#10160]) ([media\_player.sonos docs][media_player.sonos docs]) * MPD now uses the filename if song doesn't have metadata ([@C0DK] - [#10085]) * Updated denon component to play nice with the 3808CI that doesn't support NSFRN command ([@randellhodges] - [#10157]) * Fix for issue #9240 ([@bastshoes] - [#10173]) ([fan.mqtt docs]) * Linode ([@ryanm101] - [#9936]) ([linode docs]) ([binary\_sensor.linode docs][binary_sensor.linode docs]) (new-platform) * Cast attribute values to string before publishing to MQTT ([@tinloaf] - [#9872]) ([mqtt\_statestream docs][mqtt_statestream docs]) (breaking change) * Xiaomi MiIO Light: Philips Eyecare Lamp 2 support ([@syssi] - [#10007]) ([light.xiaomi\_miio docs][light.xiaomi_miio docs]) ([开关.xiaomi\_miio docs][开关.xiaomi_miio docs]) ([vacuum.xiaomi\_miio docs][vacuum.xiaomi_miio docs]) * Nederlandse spoorwegen ([@b10m] - [#10136]) ([传感器.nederlandse\_spoorwegen docs][传感器.nederlandse_spoorwegen docs]) (new-platform) * Added capability to pass a filename to the downloader component ([@tchellomello] - [#10059]) ([downloader docs]) * Limits of the favorite level updated. Values between 0 and 16 will be accepted. ([@syssi] - [#10186]) ([fan.xiaomi\_miio docs][fan.xiaomi_miio docs]) * added Yesss SMS platform ([@flowolf] - [#10177]) (new-platform) * Add Sytadin Traffic component ([@gautric] - [#9524]) (new-platform) * media\_title property now returns current source ([@etsinko] - [#10120]) ([media\_player.monoprice docs][media_player.monoprice docs]) * Added new Clickatell SMS messaging Notify Platform ([@davlloyd] - [#9775]) ([通知.clickatell docs]) (new-platform) * update boto3 to 1.4.7 and botocore to 1.7.34 ([@TopdRob] - [#10121]) ([tts.amazon\_polly docs][tts.amazon_polly docs]) * Add Random binary sensor ([@fabaff] - [#10164]) ([binary\_sensor.random docs][binary_sensor.random docs]) (new-platform) * Add clickatell ([@fabaff] - [#10199]) * Update CODEOWNERS ([@ggravlingen] - [#10198]) * Add unit test for hddtemp 传感器. ([@cgtobi] - [#10154]) * Upgrade pylast to 2.0.0 ([@fabaff] - [#10200]) ([传感器.lastfm docs]) * Move constant to 'const.py' and use already definied ones ([@fabaff] - [#10204]) ([input\_number docs][input_number docs]) ([温控.honeywell docs]) ([device\_tracker.asuswrt docs][device_tracker.asuswrt docs]) ([image\_processing.openalpr\_local docs][image_processing.openalpr_local docs]) ([传感器.google\_travel\_time docs][传感器.google_travel_time docs]) ([传感器.uk\_transport docs][传感器.uk_transport docs]) ([开关.flux docs]) * Upgrade youtube\_dl to 2017.10.29 ([@fabaff] - [#10202]) ([media\_extractor docs][media_extractor docs]) * Bump pyvera to 0.2.38. ([@pavoni] - [#10206]) ([vera docs]) * Move constant to 'const.py' and use already defined ones ([@fabaff] - [#10211]) * Add new service 'snapshot' for camera ([@pvizeli] - [#10207]) ([camera docs]) * Upgrade restrictedpython to 4.0b2 ([@fabaff] - [#10179]) * Google Assistant Script Support ([@epleypa] - [#10148]) ([google\_assistant docs][google_assistant docs]) * Raincloudy version bump ([@tchellomello] - [#10225]) ([raincloud docs]) * Add gc100 platforms and component ([@davegravy] - [#10159]) ([gc100 docs]) ([binary\_sensor.gc100 docs][binary_sensor.gc100 docs]) ([开关.gc100 docs]) (new-platform) * Librouteros capsman fix ([@nicolaevladescu] - [#10217]) ([device\_tracker.mikrotik docs][device_tracker.mikrotik docs]) * Add entity\_picture\_template options to Template Cover, Template Light, Template Sensor, and Template Switch ([@bachya] - [#9854]) ([cover.template docs]) * Xiaomi Aqara: Remove/Add device service added ([@syssi] - [#10150]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * Introducing multi-zone support for yamaha\_musiccast devices ([@jalmeroth] - [#9968]) * Clarify yamaha play\_media parameters ([@sdague] - [#10228]) ([media\_player.yamaha docs][media_player.yamaha docs]) * Update services.yaml files ([@fabaff] - [#10229]) * Add priority attribute for hyperion ([@ImEmJay] - [#10102]) ([light.hyperion docs]) * OwnTracks work. Beacon logic and testcases ([@ehagan] - [#10183]) ([device\_tracker.owntracks docs][device_tracker.owntracks docs]) * Sytadin default value must be a list #10233 ([@gautric] - [#10234]) * Use theme color in loading screen. ([@andrey-git] - [#10248]) * Move constant to 'const.py' ([@fabaff] - [#10249]) ([传感器.hddtemp docs]) ([传感器.synologydsm docs]) * Add support for odhcpd DHCP server ([@chemicalstorm] - [#9858]) ([device\_tracker.ubus docs][device_tracker.ubus docs]) * Changed single tolerance value to COLD and HOT tolerances. Allows on and off states to have different error bands. ([@biggms] - [#9843]) ([温控.generic\_thermostat docs][温控.generic_thermostat docs]) (breaking change) * Add support for 'Send Current Position' feature in Geofency 5.1 ([@gunnarhelgason] - [#10012]) ([device\_tracker.geofency docs][device_tracker.geofency docs]) * input\_text - Added service doc ([@cdce8p] - [#10238]) ([input\_text docs][input_text docs]) * Mqtt light options to fix #9330 and #7810 ([@TD22057] - [#9829]) ([light.mqtt docs]) * WIP: Timer component ([@danielperna84] - [#9889]) ([timer docs]) (new-platform) * Use translated panel names on frontend ([@armills] - [#10197]) * Alexa SmartHome API extend ([@pvizeli] - [#10251]) * integration with Remember The Milk. ([@ChristianKuehnel] - [#9803]) ([remember\_the\_milk docs][remember_the_milk docs]) (new-platform) * Google Assistant: make it possible to set a custom domain/type ([@perosb] - [#10188]) ([google\_assistant docs][google_assistant docs]) * Add EntityFilter helper ([@mw-white] - [#10221]) * Avoid Sonos error during startup ([@amelchio] - [#10146]) ([media\_player.sonos docs][media_player.sonos docs]) * Update netdisco to 1.2.3 ([@balloob] - [#10266]) * Extracted json saving and loading ([@molobrakos] - [#10216]) ([media\_player.plex docs][media_player.plex docs]) * Change introduction card to use persistent notification ([@balloob] - [#10265]) * Add unit test for wake on lan component. ([@cgtobi] - [#10262]) * Add link to docs ([@fabaff] - [#10272]) * Add xy support to Alexa HomeAPI v3 ([@pvizeli] - [#10268]) * Remove http.development ([@balloob] - [#10267]) ([http docs]) * Add setup platform tests for the season sensor component. ([@cgtobi] - [#10270]) * Add Google Assistant support for setting climate temperature and operation mode. ([@emosenkis] - [#10174]) ([google\_assistant docs][google_assistant docs]) * WIP: Cleanup async stuff on templates ([@pvizeli] - [#10275]) ([开关.template docs]) * Removed username/password auth and moved to new save/load json ([@w1ll1am23] - [#10277]) ([wink docs]) (breaking change) * Support new tradfri individual DTLS identification method ([@lwis] - [#10282]) ([tradfri docs]) (breaking change) * Update plant for dealing with float values ([@dominikandreas] - [#10246]) ([plant docs]) * Fixed Tradfri whitebulbs handling after #9703 ([@matemaciek] - [#10040]) ([light.tradfri docs]) * Luftdaten sensor ([@lichtteil] - [#10274]) ([传感器.luftdaten docs]) (new-platform) * Improve unit tests for season sensor component. ([@cgtobi] - [#10288]) * Better scene handling ([@joaqtor] - [#10213]) * Follow-up: Replace emulated\_hue: with emulated\_hue\_hidden ([@vatir] - [#9894]) ([light.hue docs]) * Maintain recorder purge schedule ([@PeteBa] - [#10279]) * update mask-icon to a working mask-icon.svg ([@NovapaX] - [#10290]) * Cleanup Xiaomi Aqara ([@balloob] - [#10302]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * Fix panel\_custom ([@balloob] - [#10303]) ([panel\_custom docs][panel_custom docs]) * Cloud: Authenticate with id token ([@balloob] - [#10304]) * Allow an empty MAC address at the Xiaomi Aqara Gateway configuration. ([@syssi] - [#10307]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * Upgrade credstash to 1.14.0 ([@fabaff] - [#10310]) * TellStick / Remove async flavor / add hassio ([@pvizeli] - [#10315]) ([tellstick docs]) * Strip white space from configurator input ([@w1ll1am23] - [#10317]) ([wink docs]) * Fix recorder purge ([@pvizeli] - [#10318]) * Fix formatting invalid config text ([@balloob] - [#10319]) * Tc update ([@craigjmidwinter] - [#10322]) ([alarm\_control\_panel.totalconnect docs][alarm_control_panel.totalconnect docs]) * Move timer into correct folder ([@pvizeli] - [#10324]) ([timer docs]) [#10000]: https://github.com/home-assistant/home-assistant/pull/10000 [#10001]: https://github.com/home-assistant/home-assistant/pull/10001 [#10006]: https://github.com/home-assistant/home-assistant/pull/10006 [#10007]: https://github.com/home-assistant/home-assistant/pull/10007 [#10008]: https://github.com/home-assistant/home-assistant/pull/10008 [#10009]: https://github.com/home-assistant/home-assistant/pull/10009 [#10010]: https://github.com/home-assistant/home-assistant/pull/10010 [#10012]: https://github.com/home-assistant/home-assistant/pull/10012 [#10013]: https://github.com/home-assistant/home-assistant/pull/10013 [#10014]: https://github.com/home-assistant/home-assistant/pull/10014 [#10017]: https://github.com/home-assistant/home-assistant/pull/10017 [#10019]: https://github.com/home-assistant/home-assistant/pull/10019 [#10021]: https://github.com/home-assistant/home-assistant/pull/10021 [#10033]: https://github.com/home-assistant/home-assistant/pull/10033 [#10037]: https://github.com/home-assistant/home-assistant/pull/10037 [#10040]: https://github.com/home-assistant/home-assistant/pull/10040 [#10043]: https://github.com/home-assistant/home-assistant/pull/10043 [#10049]: https://github.com/home-assistant/home-assistant/pull/10049 [#10059]: https://github.com/home-assistant/home-assistant/pull/10059 [#10062]: https://github.com/home-assistant/home-assistant/pull/10062 [#10063]: https://github.com/home-assistant/home-assistant/pull/10063 [#10064]: https://github.com/home-assistant/home-assistant/pull/10064 [#10066]: https://github.com/home-assistant/home-assistant/pull/10066 [#10068]: https://github.com/home-assistant/home-assistant/pull/10068 [#10073]: https://github.com/home-assistant/home-assistant/pull/10073 [#10078]: https://github.com/home-assistant/home-assistant/pull/10078 [#10085]: https://github.com/home-assistant/home-assistant/pull/10085 [#10090]: https://github.com/home-assistant/home-assistant/pull/10090 [#10093]: https://github.com/home-assistant/home-assistant/pull/10093 [#10101]: https://github.com/home-assistant/home-assistant/pull/10101 [#10102]: https://github.com/home-assistant/home-assistant/pull/10102 [#10103]: https://github.com/home-assistant/home-assistant/pull/10103 [#10106]: https://github.com/home-assistant/home-assistant/pull/10106 [#10108]: https://github.com/home-assistant/home-assistant/pull/10108 [#10110]: https://github.com/home-assistant/home-assistant/pull/10110 [#10115]: https://github.com/home-assistant/home-assistant/pull/10115 [#10116]: https://github.com/home-assistant/home-assistant/pull/10116 [#10117]: https://github.com/home-assistant/home-assistant/pull/10117 [#10120]: https://github.com/home-assistant/home-assistant/pull/10120 [#10121]: https://github.com/home-assistant/home-assistant/pull/10121 [#10123]: https://github.com/home-assistant/home-assistant/pull/10123 [#10125]: https://github.com/home-assistant/home-assistant/pull/10125 [#10126]: https://github.com/home-assistant/home-assistant/pull/10126 [#10128]: https://github.com/home-assistant/home-assistant/pull/10128 [#10131]: https://github.com/home-assistant/home-assistant/pull/10131 [#10135]: https://github.com/home-assistant/home-assistant/pull/10135 [#10136]: https://github.com/home-assistant/home-assistant/pull/10136 [#10138]: https://github.com/home-assistant/home-assistant/pull/10138 [#10144]: https://github.com/home-assistant/home-assistant/pull/10144 [#10146]: https://github.com/home-assistant/home-assistant/pull/10146 [#10148]: https://github.com/home-assistant/home-assistant/pull/10148 [#10150]: https://github.com/home-assistant/home-assistant/pull/10150 [#10152]: https://github.com/home-assistant/home-assistant/pull/10152 [#10154]: https://github.com/home-assistant/home-assistant/pull/10154 [#10155]: https://github.com/home-assistant/home-assistant/pull/10155 [#10157]: https://github.com/home-assistant/home-assistant/pull/10157 [#10159]: https://github.com/home-assistant/home-assistant/pull/10159 [#10160]: https://github.com/home-assistant/home-assistant/pull/10160 [#10161]: https://github.com/home-assistant/home-assistant/pull/10161 [#10162]: https://github.com/home-assistant/home-assistant/pull/10162 [#10163]: https://github.com/home-assistant/home-assistant/pull/10163 [#10164]: https://github.com/home-assistant/home-assistant/pull/10164 [#10166]: https://github.com/home-assistant/home-assistant/pull/10166 [#10169]: https://github.com/home-assistant/home-assistant/pull/10169 [#10173]: https://github.com/home-assistant/home-assistant/pull/10173 [#10174]: https://github.com/home-assistant/home-assistant/pull/10174 [#10177]: https://github.com/home-assistant/home-assistant/pull/10177 [#10179]: https://github.com/home-assistant/home-assistant/pull/10179 [#10183]: https://github.com/home-assistant/home-assistant/pull/10183 [#10186]: https://github.com/home-assistant/home-assistant/pull/10186 [#10188]: https://github.com/home-assistant/home-assistant/pull/10188 [#10197]: https://github.com/home-assistant/home-assistant/pull/10197 [#10198]: https://github.com/home-assistant/home-assistant/pull/10198 [#10199]: https://github.com/home-assistant/home-assistant/pull/10199 [#10200]: https://github.com/home-assistant/home-assistant/pull/10200 [#10202]: https://github.com/home-assistant/home-assistant/pull/10202 [#10204]: https://github.com/home-assistant/home-assistant/pull/10204 [#10206]: https://github.com/home-assistant/home-assistant/pull/10206 [#10207]: https://github.com/home-assistant/home-assistant/pull/10207 [#10211]: https://github.com/home-assistant/home-assistant/pull/10211 [#10213]: https://github.com/home-assistant/home-assistant/pull/10213 [#10216]: https://github.com/home-assistant/home-assistant/pull/10216 [#10217]: https://github.com/home-assistant/home-assistant/pull/10217 [#10221]: https://github.com/home-assistant/home-assistant/pull/10221 [#10225]: https://github.com/home-assistant/home-assistant/pull/10225 [#10228]: https://github.com/home-assistant/home-assistant/pull/10228 [#10229]: https://github.com/home-assistant/home-assistant/pull/10229 [#10234]: https://github.com/home-assistant/home-assistant/pull/10234 [#10238]: https://github.com/home-assistant/home-assistant/pull/10238 [#10246]: https://github.com/home-assistant/home-assistant/pull/10246 [#10248]: https://github.com/home-assistant/home-assistant/pull/10248 [#10249]: https://github.com/home-assistant/home-assistant/pull/10249 [#10251]: https://github.com/home-assistant/home-assistant/pull/10251 [#10262]: https://github.com/home-assistant/home-assistant/pull/10262 [#10265]: https://github.com/home-assistant/home-assistant/pull/10265 [#10266]: https://github.com/home-assistant/home-assistant/pull/10266 [#10267]: https://github.com/home-assistant/home-assistant/pull/10267 [#10268]: https://github.com/home-assistant/home-assistant/pull/10268 [#10270]: https://github.com/home-assistant/home-assistant/pull/10270 [#10272]: https://github.com/home-assistant/home-assistant/pull/10272 [#10274]: https://github.com/home-assistant/home-assistant/pull/10274 [#10275]: https://github.com/home-assistant/home-assistant/pull/10275 [#10277]: https://github.com/home-assistant/home-assistant/pull/10277 [#10279]: https://github.com/home-assistant/home-assistant/pull/10279 [#10282]: https://github.com/home-assistant/home-assistant/pull/10282 [#10288]: https://github.com/home-assistant/home-assistant/pull/10288 [#10290]: https://github.com/home-assistant/home-assistant/pull/10290 [#10302]: https://github.com/home-assistant/home-assistant/pull/10302 [#10303]: https://github.com/home-assistant/home-assistant/pull/10303 [#10304]: https://github.com/home-assistant/home-assistant/pull/10304 [#10307]: https://github.com/home-assistant/home-assistant/pull/10307 [#10310]: https://github.com/home-assistant/home-assistant/pull/10310 [#10315]: https://github.com/home-assistant/home-assistant/pull/10315 [#10317]: https://github.com/home-assistant/home-assistant/pull/10317 [#10318]: https://github.com/home-assistant/home-assistant/pull/10318 [#10319]: https://github.com/home-assistant/home-assistant/pull/10319 [#10322]: https://github.com/home-assistant/home-assistant/pull/10322 [#10324]: https://github.com/home-assistant/home-assistant/pull/10324 [#6344]: https://github.com/home-assistant/home-assistant/pull/6344 [#9524]: https://github.com/home-assistant/home-assistant/pull/9524 [#9696]: https://github.com/home-assistant/home-assistant/pull/9696 [#9700]: https://github.com/home-assistant/home-assistant/pull/9700 [#9703]: https://github.com/home-assistant/home-assistant/pull/9703 [#9721]: https://github.com/home-assistant/home-assistant/pull/9721 [#9739]: https://github.com/home-assistant/home-assistant/pull/9739 [#9775]: https://github.com/home-assistant/home-assistant/pull/9775 [#9791]: https://github.com/home-assistant/home-assistant/pull/9791 [#9803]: https://github.com/home-assistant/home-assistant/pull/9803 [#9808]: https://github.com/home-assistant/home-assistant/pull/9808 [#9829]: https://github.com/home-assistant/home-assistant/pull/9829 [#9836]: https://github.com/home-assistant/home-assistant/pull/9836 [#9837]: https://github.com/home-assistant/home-assistant/pull/9837 [#9840]: https://github.com/home-assistant/home-assistant/pull/9840 [#9843]: https://github.com/home-assistant/home-assistant/pull/9843 [#9854]: https://github.com/home-assistant/home-assistant/pull/9854 [#9858]: https://github.com/home-assistant/home-assistant/pull/9858 [#9870]: https://github.com/home-assistant/home-assistant/pull/9870 [#9872]: https://github.com/home-assistant/home-assistant/pull/9872 [#9876]: https://github.com/home-assistant/home-assistant/pull/9876 [#9883]: https://github.com/home-assistant/home-assistant/pull/9883 [#9889]: https://github.com/home-assistant/home-assistant/pull/9889 [#9894]: https://github.com/home-assistant/home-assistant/pull/9894 [#9915]: https://github.com/home-assistant/home-assistant/pull/9915 [#9936]: https://github.com/home-assistant/home-assistant/pull/9936 [#9957]: https://github.com/home-assistant/home-assistant/pull/9957 [#9962]: https://github.com/home-assistant/home-assistant/pull/9962 [#9967]: https://github.com/home-assistant/home-assistant/pull/9967 [#9968]: https://github.com/home-assistant/home-assistant/pull/9968 [#9973]: https://github.com/home-assistant/home-assistant/pull/9973 [#9975]: https://github.com/home-assistant/home-assistant/pull/9975 [#9977]: https://github.com/home-assistant/home-assistant/pull/9977 [#9979]: https://github.com/home-assistant/home-assistant/pull/9979 [#9983]: https://github.com/home-assistant/home-assistant/pull/9983 [#9984]: https://github.com/home-assistant/home-assistant/pull/9984 [#9987]: https://github.com/home-assistant/home-assistant/pull/9987 [#9988]: https://github.com/home-assistant/home-assistant/pull/9988 [#9990]: https://github.com/home-assistant/home-assistant/pull/9990 [#9996]: https://github.com/home-assistant/home-assistant/pull/9996 [#10359]: https://github.com/home-assistant/home-assistant/pull/10359 [@C0DK]: https://github.com/C0DK [@ChristianKuehnel]: https://github.com/ChristianKuehnel [@DarkFox]: https://github.com/DarkFox [@GenericStudent]: https://github.com/GenericStudent [@HydrelioxGitHub]: https://github.com/HydrelioxGitHub [@ImEmJay]: https://github.com/ImEmJay [@Kane610]: https://github.com/Kane610 [@KlaasH]: https://github.com/KlaasH [@NovapaX]: https://github.com/NovapaX [@PeteBa]: https://github.com/PeteBa [@EarthlingRich]: https://github.com/EarthlingRich [@SilvrrGIT]: https://github.com/SilvrrGIT [@TD22057]: https://github.com/TD22057 [@TopdRob]: https://github.com/TopdRob [@abmantis]: https://github.com/abmantis [@alanfischer]: https://github.com/alanfischer [@altersis]: https://github.com/altersis [@amelchio]: https://github.com/amelchio [@andrey-git]: https://github.com/andrey-git [@armills]: https://github.com/armills [@b10m]: https://github.com/b10m [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@bastshoes]: https://github.com/bastshoes [@biggms]: https://github.com/biggms [@cdce8p]: https://github.com/cdce8p [@cgtobi]: https://github.com/cgtobi [@chemicalstorm]: https://github.com/chemicalstorm [@chriskacerguis]: https://github.com/chriskacerguis [@danielhiversen]: https://github.com/danielhiversen [@danielperna84]: https://github.com/danielperna84 [@davegravy]: https://github.com/davegravy [@davlloyd]: https://github.com/davlloyd [@dominikandreas]: https://github.com/dominikandreas [@ehagan]: https://github.com/ehagan [@emosenkis]: https://github.com/emosenkis [@epleypa]: https://github.com/epleypa [@etsinko]: https://github.com/etsinko [@fabaff]: https://github.com/fabaff [@flowolf]: https://github.com/flowolf [@fronzbot]: https://github.com/fronzbot [@gautric]: https://github.com/gautric [@ggravlingen]: https://github.com/ggravlingen [@gunnarhelgason]: https://github.com/gunnarhelgason [@hotplot]: https://github.com/hotplot [@iMarkus]: https://github.com/iMarkus [@jalmeroth]: https://github.com/jalmeroth [@jeroenterheerdt]: https://github.com/jeroenterheerdt [@joaqtor]: https://github.com/joaqtor [@kirichkov]: https://github.com/kirichkov [@lichtteil]: https://github.com/lichtteil [@lwis]: https://github.com/lwis [@matemaciek]: https://github.com/matemaciek [@milanvo]: https://github.com/milanvo [@molobrakos]: https://github.com/molobrakos [@mw-white]: https://github.com/mw-white [@nicolaevladescu]: https://github.com/nicolaevladescu [@pavoni]: https://github.com/pavoni [@perosb]: https://github.com/perosb [@pezinek]: https://github.com/pezinek [@pschmitt]: https://github.com/pschmitt [@pvizeli]: https://github.com/pvizeli [@quamilek]: https://github.com/quamilek [@randellhodges]: https://github.com/randellhodges [@rasmusbe]: https://github.com/rasmusbe [@ryanm101]: https://github.com/ryanm101 [@sander76]: https://github.com/sander76 [@sdague]: https://github.com/sdague [@syssi]: https://github.com/syssi [@tboyce021]: https://github.com/tboyce021 [@tchellomello]: https://github.com/tchellomello [@tinloaf]: https://github.com/tinloaf [@ttroy50]: https://github.com/ttroy50 [@vatir]: https://github.com/vatir [@w1ll1am23]: https://github.com/w1ll1am23 [@craigjmidwinter]: https://github.com/craigjmidwinter [@ypollart]: https://github.com/ypollart [@zabuldon]: https://github.com/zabuldon [alarm_control_panel.totalconnect docs]: /integrations/totalconnect [alexa.smart_home docs]: /integrations/alexa.smart_home/ [api docs]: /integrations/api/ [automation.event docs]: /docs/automation/trigger/#event-trigger [automation.numeric_state docs]: /docs/automation/trigger/#numeric-state-trigger [axis docs]: /integrations/axis/ [binary_sensor.axis docs]: /integrations/axis#binary-sensor [binary_sensor.gc100 docs]: /integrations/gc100#binary-sensor [binary_sensor.linode docs]: /integrations/linode#binary-sensor [binary_sensor.random docs]: /integrations/random#binary-sensor [binary_sensor.rfxtrx docs]: /integrations/rfxtrx#binary-sensors [binary_sensor.ring docs]: /integrations/ring#binary-sensor [binary_sensor.tellduslive docs]: /integrations/tellduslive [binary_sensor.trend docs]: /integrations/trend [binary_sensor.xiaomi_aqara docs]: /integrations/binary_sensor.xiaomi_aqara/ [camera docs]: /integrations/camera/ [摄像头.ring docs]: /integrations/ring#camera [温控.ephember docs]: /integrations/ephember [温控.generic_thermostat docs]: /integrations/generic_thermostat [温控.honeywell docs]: /integrations/honeywell [温控.toon docs]: /integrations/toon#climate [cloud docs]: /integrations/cloud/ [cover.template docs]: /integrations/cover.template/ [device_tracker docs]: /integrations/device_tracker/ [device_tracker.asuswrt docs]: /integrations/asuswrt [device_tracker.geofency docs]: /integrations/geofency [device_tracker.mikrotik docs]: /integrations/mikrotik [device_tracker.owntracks docs]: /integrations/owntracks [device_tracker.snmp docs]: /integrations/snmp [device_tracker.ubus docs]: /integrations/ubus [dialogflow docs]: /integrations/dialogflow/ [downloader docs]: /integrations/downloader/ [duckdns docs]: /integrations/duckdns/ [fan.mqtt docs]: /integrations/fan.mqtt/ [fan.xiaomi_miio docs]: /integrations/fan.xiaomi_miio/ [gc100 docs]: /integrations/gc100/ [google_assistant docs]: /integrations/google_assistant/ [google_domains docs]: /integrations/google_domains/ [hassio docs]: /integrations/hassio/ [history docs]: /integrations/history/ [http docs]: /integrations/http/ [image_processing.openalpr_local docs]: /integrations/openalpr_local/ [input_number docs]: /integrations/input_number/ [input_text docs]: /integrations/input_text/ [light.hue docs]: /integrations/hue [light.hyperion docs]: /integrations/hyperion [light.mqtt docs]: /integrations/light.mqtt/ [light.tradfri docs]: /integrations/tradfri [light.xiaomi_miio docs]: /integrations/light.xiaomi_miio/ [light.yeelight docs]: /integrations/yeelight [linode docs]: /integrations/linode/ [logbook docs]: /integrations/logbook/ [mailbox docs]: /integrations/mailbox/ [media_extractor docs]: /integrations/media_extractor/ [media_player docs]: /integrations/media_player/ [media_player.monoprice docs]: /integrations/monoprice [media_player.plex docs]: /integrations/plex#media-player [media_player.russound_rnet docs]: /integrations/russound_rnet [media_player.sonos docs]: /integrations/sonos [media_player.yamaha docs]: /integrations/yamaha [mqtt_statestream docs]: /integrations/mqtt_statestream/ [namecheapdns docs]: /integrations/namecheapdns/ [no_ip docs]: /integrations/no_ip/ [通知.clickatell docs]: /integrations/clickatell [通知.sendgrid docs]: /integrations/sendgrid [panel_custom docs]: /integrations/panel_custom/ [persistent_notification docs]: /integrations/persistent_notification/ [plant docs]: /integrations/plant/ [raincloud docs]: /integrations/raincloud/ [remember_the_milk docs]: /integrations/remember_the_milk/ [rfxtrx docs]: /integrations/rfxtrx/ [ring docs]: /integrations/ring/ [传感器.coinmarketcap docs]: /integrations/coinmarketcap [传感器.emoncms docs]: /integrations/emoncms [传感器.fail2ban docs]: /integrations/fail2ban [传感器.gitter docs]: /integrations/gitter [传感器.glances docs]: /integrations/glances [传感器.google_travel_time docs]: /integrations/google_travel_time [传感器.hddtemp docs]: /integrations/hddtemp [传感器.imap docs]: /integrations/imap [传感器.irish_rail_transport docs]: /integrations/irish_rail_transport [传感器.lastfm docs]: /integrations/lastfm [传感器.luftdaten docs]: /integrations/luftdaten#sensor [传感器.nederlandse_spoorwegen docs]: /integrations/nederlandse_spoorwegen [传感器.radarr docs]: /integrations/radarr [传感器.rest docs]: /integrations/rest [传感器.ring docs]: /integrations/ring#sensor [传感器.scrape docs]: /integrations/scrape [传感器.snmp docs]: /integrations/snmp#sensor [传感器.sonarr docs]: /integrations/sonarr [传感器.speedtest docs]: /integrations/speedtestdotnet [传感器.swiss_public_transport docs]: /integrations/swiss_public_transport [传感器.synologydsm docs]: /integrations/synologydsm [传感器.sytadin docs]: /integrations/sytadin [传感器.toon docs]: /integrations/toon [传感器.uk_transport docs]: /integrations/uk_transport [传感器.whois docs]: /integrations/whois [shopping_list docs]: /integrations/shopping_list/ [开关.deluge docs]: /integrations/deluge#switch [开关.flux docs]: /integrations/flux [开关.gc100 docs]: /integrations/gc100#switch [开关.snmp docs]: /integrations/snmp#switch [开关.template docs]: /integrations/开关.template/ [开关.toon docs]: /integrations/toon [开关.xiaomi_miio docs]: /integrations/开关.xiaomi_miio/ [tellduslive docs]: /integrations/tellduslive/ [tellstick docs]: /integrations/tellstick/ [tesla docs]: /integrations/tesla/ [timer docs]: /integrations/timer/ [toon docs]: /integrations/toon/ [tradfri docs]: /integrations/tradfri/ [tts.amazon_polly docs]: /integrations/amazon_polly [tts.microsoft docs]: /integrations/microsoft [vacuum.xiaomi_miio docs]: /integrations/vacuum.xiaomi_miio/ [vera docs]: /integrations/vera/ [wink docs]: /integrations/wink/ [xiaomi_aqara docs]: /integrations/xiaomi_aqara/ [ikea email]: https://twitter.com/home_assistant/status/925373865802502144 [wink-auth]: /integrations/wink/#authenticate-using-developerwinkcomhttpsdeveloperwinkcom [#10384]: https://github.com/home-assistant/home-assistant/pull/10384 [#10428]: https://github.com/home-assistant/home-assistant/pull/10428 [@stefan-jonasson]: https://github.com/stefan-jonasson [@tchellomello]: https://github.com/tchellomello [binary_sensor.ring docs]: /integrations/ring#binary-sensor [摄像头.ring docs]: /integrations/ring#camera [传感器.ring docs]: /integrations/ring#sensor [tellstick docs]: /integrations/tellstick/ --- url: /home-assistant/blog/2017-11-05-frontend-translations.md --- # Translating Home Assistant

The Home Assistant 侧边栏 in 12 different languages The Home Assistant 侧边栏 in 12 different languages.

## Translations As mentioned in the [0.57 发布 notes](/home-assistant/blog/2017/11/04/release-57/), Home Assistant has launched a translated 前端. With the immediate influx of translations, we’ve made 集成 with a translation tool a top priority. [@c727] took the initiative to evaluate several tools, and we’re happy to announce that Home Assistant will be partnering with [Lokalise](https://lokalise.co/) to manage our translations! Lokalise allows us to open up translations for all of our multilingual 用户 willing to contribute. 用户 can join the project using our [public signup link](https://lokalise.co/signup/3420425759f6d6d241f598.13594006/all/), and start translating right away. We’ve 创建 a [translation startup guide](https://开发者.home-assistant.io/docs/en/internationalization_translation.html) with additional details about how to contribute. Instructions are provided there for how to request a new language. Now that we have a system in place, expect a lot more of the interface to be translatable soon. We still have some technical hurdles to overcome, but the hardest work is behind us now. The community has already done an outstanding job of providing translations. The future is looking bright! [@c727]: https://github.com/c727 --- url: /home-assistant/blog/2017-11-10-ttn-with-mqtt.md --- # Home Assistant and The Things Network (TTN) The Home Assistant 集成 for [The Things Network (TTN)](https://www.thethingsnetwork.org/) uses their [Storage](https://www.thethingsnetwork.org/docs/applications/storage/) feature to get the 传感器 data. The easiest way to observe TTN 传感器 would be [MQTT](https://www.thethingsnetwork.org/docs/applications/MQTT/) as it doesn't requires any additional 配置. At the moment Home Assistant only supports one [MQTT broker](/home-assistant/docs/MQTT/). This means that you can't subscribe to topics which are located on different brokers. ## Subscribe to the TTN Broker To check what your 设备 are sending, subscribe to the topic `+/devices/+/up` with a command-line tool like `mosquitto_sub`. The `` is the postfix of the **Handler** entry in your **Application 概述**. `` is the **Application ID** and `` is your access key. ```bash $ mosquitto_sub -v -h .thethings.network -t '+/devices/+/up' -u '' -P '' { "app_id": "ha-demo", "dev_id": "device01", "hardware_serial": "AJDJENDNHRBFBBT", "port": 1, [...] ``` The payload contains details about the 设备 itself and the 传感器 data. The 传感器 data is stored in `payload_fields`. Depending on the 设备 配置 it may contain a single value or multiple values. ## The relay To be able to work locally with the MQTT data that is received from the 设备 connected to TTN, we need to transfer it to the local broker. With this simple 脚本 below all messages from a given 设备 are re-published on your local MQTT broker after they are received. Modify the 脚本 with your details as outlined in the previous section. ```python """Relay MQTT messages from The Things Network to a local MQTT broker.""" import paho.mqtt.client as mqtt import paho.mqtt.publish as publish DEVICE_NAME = '' TTN_BROKER = '.thethings.network' TTN_USERNAME = '' TTN_PASSWORD = '' TTN_TOPIC = '+/devices/{}/up'.format(DEVICE_NAME) LOCAL_BROKER = '192.168.0.2' LOCAL_TOPIC = 'home/ttn/garden_temp' def on_connect(client, userdata, flags, rc): """Subscribe to topic after connection to broker is made.""" print("Connected with result code", str(rc)) client.subscribe(TTN_TOPIC) def on_message(client, userdata, msg): """Relay message to a different broker.""" publish.single( LOCAL_TOPIC, payload=msg.payload, qos=0, retain=False, hostname=LOCAL_BROKER, port=1883, client_id='ttn-local', keepalive=60, will=None, auth=None, tls=None, protocol=mqtt.MQTTv311) client = mqtt.Client() client.username_pw_set(TTN_USERNAME, password=TTN_PASSWORD) client.on_connect = on_connect client.on_message = on_message client.connect(TTN_BROKER, 1883, 60) client.loop_forever() ``` Save it and run it. As soon as a MQTT message is received from your 设备 you should see it on your local broker (here 192.168.0.2) if you subscribe to `#` or the topic given in the 脚本 above `home/ttn/garden_temp`. ```bash mosquitto_sub -h 192.168.0.2 -t "#" -d ``` ## The 传感器 All we would need now, is a [`mqtt` sensor](/home-assistant/integrations/sensor.MQTT/) with a `value_template`. With a sophisticated custom 传感器 it would be possible to displaying a little more than just the 状态. The 设备 is only sending the temperature `{"temperature": 7.5}` but there are other details available which the 传感器 should show. ```python """Support for The Things Network MQTT sensors.""" import asyncio from datetime import timedelta import json import logging import voluptuous as vol import homeassistant.components.mqtt as mqtt from homeassistant.components.mqtt import CONF_STATE_TOPIC from homeassistant.const import CONF_NAME, CONF_UNIT_OF_MEASUREMENT from homeassistant.core import callback import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entity import Entity _LOGGER = logging.getLogger(__name__) DEFAULT_NAME = 'MQTT TTN Sensor' DEFAULT_FORCE_UPDATE = False DEPENDENCIES = ['mqtt'] PLATFORM_SCHEMA = mqtt.MQTT_RO_PLATFORM_SCHEMA.extend({ vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string, }) @asyncio.coroutine def async_setup_platform(hass, config, async_add_devices, discovery_info=None): """Set up the TTN MQTT Sensor.""" async_add_devices([MqttTtnSensor( config.get(CONF_NAME), config.get(CONF_STATE_TOPIC), config.get(CONF_UNIT_OF_MEASUREMENT)) ]) class MqttTtnSensor(Entity): """Representation of a sensor.""" def __init__(self, name, state_topic, unit_of_measurement): """Initialize the sensor.""" self._state = None self._name = name self._unit_of_measurement = unit_of_measurement self._attributes = {} self._state_topic = state_topic def async_added_to_hass(self): """Subscribe to MQTT events.""" @callback def message_received(topic, payload, qos): """Handle new MQTT messages.""" try: data = json.loads(payload) except json.JSONDecodeError: _LOGGER.error("Invalid JSON data received: %s", data) self._state = data['payload_fields'][next( iter(data['payload_fields']))] self._attributes = data del self._attributes['payload_fields'] del self._attributes['metadata'] self.async_schedule_update_ha_state() return mqtt.async_subscribe( self.hass, self._state_topic, message_received, 0) @property def should_poll(self): """No polling needed.""" return False @property def name(self): """Return the name of the sensor.""" return self._name @property def unit_of_measurement(self): """Return the unit this state is expressed in.""" return self._unit_of_measurement @property def state_attributes(self): """Return the attributes of the entity.""" return self._attributes @property def state(self): """Return the state of the entity.""" return self._state ``` Store it in `/custom_components/sensor/mqtt_ttn.py` and it will handle the messages. ## The 配置 Now create the [`mqtt_ttn` sensor](/home-assistant/integrations/sensor.MQTT/) entry for your 设备. ```yaml sensor: - platform: mqtt_ttn name: TTN Sensor state_topic: "home/ttn/garden_temp" ``` This solution is not production-ready, scalable or stable but it could fill the gape till Home Assistant is able to connect to multiple MQTT brokers. If you have multiple 设备 relay all messages to your local broker and add a 配置 variable to `mqtt_ttn` 传感器 which allows you to select the 设备. --- url: /home-assistant/blog/2017-11-12-tor.md --- # Secure 遥控器 access to Home Assistant using Tor Routers and gateways provided by broadband internet providers are very often limited regarding features and 配置 possibilities. Most of these limitations affect the opportunities that allow 用户 to set up port-forwarding, DMZ, and DHCP reservations since the suppliers figured that average 用户 does not want (or should not) deal with these. Making your Home Assistant instance available remotely (and securely), in this case, becomes more difficult. Are you one of those unlucky ones? There are a couple of options available to achieve a 遥控器 (and secure) accessible Home Assistant instance. However, almost all of them require you to: open one or more ports on your router, expose a public IP address, and require you to reserve a fixed IP in your DHCP server (or set up a static IP address). Examples of these are: * Combination of [DuckDNS](/home-assistant/integrations/duckdns/index.md) (or similar), [Let's Encrypt](/home-assistant/docs/ecosystem/certificates/lets_encrypt/) (SSL), DHCP reservation, and forwarding a port to your 设备 running Home Assistant. * 设置 a VPN, which often requires more hardware and software. Additionally, it also requires port-forwarding, DHCP reservation and most likely [DuckDNS](/home-assistant/integrations/duckdns/index.md) (or similar). * [SSH tunnel-ing](/home-assistant/blog/2017/11/02/secure-shell-tunnel/). Which still requires port-forwarding, DHCP reservation and most likely (yeah, you've guessed it) [DuckDNS](/home-assistant/integrations/duckdns/index.md) (or similar). There is, however, another option available that most people do not realize: [Tor](https://www.torproject.org). [Tor](https://www.torproject.org) offers a capability that they refer to as [Tor's Hidden 服务](https://www.torproject.org/docs/hidden-服务.html.en), which allows you to securely access your Home Assistant 安装 *without* the need for all these things. No need to forward and open ports, no need to expose your public IP, no DNS entry, no need for SSL certificates, and you do not have to assign a fixed IP to the 设备 running your Home Assistant. The most amazing part? It is super easy to set up! ## Setting up Tor The 设置 is straight-forward: 1. 安装 Tor. On a Debian-based system: `$ sudo apt-get install tor`. On Fedora: `$ sudo dnf install tor` 2. Modify Tor's main 配置 file `/etc/tor/torrc` to include the following lines: ```bash ############### This section is just for location-hidden services ### ## Once you have configured a hidden service, you can look at the ## contents of the file ".../hidden_service/hostname" for the address ## to tell people. ... HiddenServiceDir /var/lib/tor/homeassistant/ HiddenServicePort 80 127.0.0.1:8123 ... ``` 3. 重启 Tor: `$ sudo systemctl restart tor` 4. The Tor-generated hostname file contains the hostname you need to access your 安装. ```bash $ sudo cat /var/lib/tor/homeassistant/hostname abcdef1234567890.onion ``` ## Tor 插件 for Hass.io [Franck Nijhof (@frenck)](https://github.com/frenck) 创建 the [Tor add-on](https://github.com/hassio-addons/addon-tor) for [Hass.io](/home-assistant/hassio/). This 插件 makes the 安装 and the 设置 extremely simple. Go to the **Hass.io** 面板, then to the **Store**, copy `https://github.com/hassio-addons/repository` into the text box of **插件 Repositories** and save it. A new entry **Tor** will show-up in the list of 插件. Click on it to 安装 it. The 配置 is done in **Options**. Please refer to the [configuration 文档](https://github.com/hassio-addons/addon-tor#configuration) for further details. A possible 配置 could look like the sample below (which is the default 配置). ```json { "log_level": "info", "socks": false, "hidden_services": true, "stealth": false, "client_names": [], "ports": [ "8123:80" ] } ``` When you are done, press **Save** and then **Start**. In the **日志** section, you can see what the 插件 is doing. Watch out for an entry like the one below, which will tell you your hostname on the Tor network. ```bash INFO: ----------------------------------------------------------- INFO: Your Home Assistant instance is available on Tor! INFO: Address: abcdef1234567890.onion INFO: ----------------------------------------------------------- ``` Don't worry if you missed it, restarting the 插件 will display it again. The details are also stored and available in the `/ssl/tor/hidden_service/hostname` file. ## Tor clients To access you Home Assistant via the Tor Hidden 服务, you will need a Tor client. There are multiple clients, for different 设备 and platforms, available. The [Tor Browser](https://www.torproject.org/projects/torbrowser.html.en) is by far the simplest option, which is available for Windows, MacOS & Linux. Simply download and 安装 the [Tor Browser](https://www.torproject.org/projects/torbrowser.html.en), start it, and enter the "dot onion" address you've gained from the earlier steps (`abcdef1234567890.onion` in this case). Voila! Some other clients: * [Orbot](https://guardianproject.info/apps/orbot/) for Android * Orfox for Android has been deprecated. Please use [Tor Browser for Android](https://www.torproject.org/download/#android). More information about the deprecation [here](https://trac.torproject.org/projects/tor/ticket/29955). * [Onion Browser](https://mike.tig.as/onionbrowser/) for iOS ## Cranking up security The 设置 described in this 博客 post is easy and relatively secure, but anyone who knows your `.onion` address can still connect to your Home Assistant instance (Remember to use passwords!). With all of the [discussion](https://博客.torproject.org/quick-simple-guide-tor-and-internet-things-so-far) about putting your IoT on the Tor Network, maybe you want to add an extra layer of defense, especially if you’re going to be the only one that uses it. Tor offers an additional layer of security, called "Hidden 服务 认证", usually referred to as "Stealth"-mode. This "Stealth"-mode adds an extra layer of security to your Hidden 服务 by only responding to a client that passes a unique secret cookie as it connects. Obviously, this requires additional 配置 on the Tor client applications. The Tor Project itself provides details about a variety of topics in their [文档](https://www.torproject.org/docs/文档.html.en). --- url: /home-assistant/blog/2017-11-18-release-58.md --- # 0.58: More translations, faster 前端, system log :::note 由于 Pascal 这个周末要搬家,Hass.io 版 0.58 将推迟几天发布。 ::: ## 翻译更新 翻译工作已经全面提速。上一个版本发布后不久,我们就理顺了整套翻译流程。[@armills] 和 [@c727] 在这个项目上的管理工作做得非常出色。支持语言数量已经翻倍达到 42 种,需要翻译的条目也从 8 个增长到 130 个。翻译者们状态极佳,目前已经完成了 79% 的翻译。 说到翻译者,现在已经有 445 人注册账号参与翻译。三周能做到这样,相当不错! 而且,既然翻译越多越好,[@robbiet480] 还把 iOS App 加入了我们的翻译管理平台 Lokalise。目前 iOS App 已支持 7 种语言。 [了解如何参与翻译](/home-assistant/blog/2017/11/06/前端-translations/) ## 前端改进仍在继续 多亏了 [@Andrey-git],我们现在可以用现代 JavaScript 提供前端资源了。使用现代 JavaScript 能让前端加载更快、运行更流畅。目前这是一个可选项,但未来我们打算把它变成默认启用。与此同时,面向旧设备的 ES5 前端版本也会继续保留。 如果你想先试试看,可以在 Home Assistant 书签后加上 `?latest`。如果想让它成为你安装环境中的默认选项,请把配置改成下面这样: ```yaml frontend: javascript_version: latest ``` :::important 对于 Custom UI 用户:你的自定义 UI 需要先完成更新,才能兼容新的前端版本。 ::: ### 系统日志增强 显示错误日志的关于页面经过 [@postlund] 的改进后获得了一次漂亮升级。现在会展示最近 50 条异常,并提供查看更多信息的选项。

Screenshot of the about screen showing the system 日志. 显示系统日志的关于页面截图。

## 新平台 * pyLoad download 传感器 ([@iMarkus] - [#10089]) ([传感器.pyload docs]) (new-platform) * Add LaCrosse 传感器 platform ([@hthiery] - [#10195]) ([传感器.lacrosse docs]) (new-platform) * Refactor Neato botvac components as a 吸尘器 ([@jabesq] - [#9946]) ([neato docs]) ([传感器.neato docs]) ([开关.neato docs]) ([吸尘器.neato docs]) (breaking change) (new-platform) * Add platform and 传感器 for Vultr VPS ([@GenericStudent] - [#9928]) ([vultr docs]) ([binary\_sensor.vultr docs][binary_sensor.vultr docs]) ([传感器.vultr docs]) (new-platform) * Adds support for Tile® 蓝牙 trackers ([@bachya] - [#10478]) ([device\_tracker.tile docs][device_tracker.tile docs]) (new-platform) * Support 在场 detection using Hitron Coda router ([@arilotter] - [#9682]) ([device\_tracker.hitron\_coda docs][device_tracker.hitron_coda docs]) (new-platform) * Add basic 后端 support for a system 日志 ([@postlund] - [#10492]) ([system\_log docs][system_log docs]) (new-platform) * New 传感器 viaggiatreno. ([@fabfurnari] - [#10522]) ([传感器.viaggiatreno docs]) (new-platform) ## 发布 0.58.1 - November 21 * Fix yweather ([@tinloaf] - [#10661]) * Properly initialize Harmony 遥控器 ([@amelchio] - [#10665]) ([遥控器.harmony docs]) * Handle the new 版本 of HydroQuebec website ([@titilambert] - [#10682]) * Fix for time\_date 传感器 ([@etsinko] - [#10694]) ([传感器.time\_date docs][传感器.time_date docs]) * 前端 fixes ([@andrey-git] [@armills] [@balloob]) ## 如果你需要帮助…… ……欢迎使用我们非常活跃的[论坛](https://community.home-assistant.io/),或者加入我们的[聊天频道](https://discord.gg/c5DvZ4e)。虽然发布说明开放了评论,但我们更推荐你使用前面的社区交流渠道。谢谢。 ## 反馈问题 如果你遇到了此次发布引入的问题,请在我们的 [issue tracker](https://github.com/home-assistant/home-assistant/issues) 中反馈。请确保完整填写 issue 模板中的所有字段。 ## 不向后兼容的变更 * `hass.states.is_state_attr(entity_id, attribute, value)` has been removed. The 模板 版本 still exists. Unused method parameter `wait` has been removed from `hass.bus.async_fire` ([@balloob] - [#10305]) (breaking change) * Refactor Neato botvac components as a 吸尘器 ([@jabesq] - [#9946]) ([neato docs]) ([开关.neato docs]) ([吸尘器.neato docs]) (breaking change) (new-platform) * Lutron released a firmware updated for the Caseta system which removed our ability to connect to and control the bridge 设备 over SSH, breaking compatibility with pylutron\_caseta and Home Assistant. Component has been updated to work again, please see the docs on how to set it up. ([@mdonoughe] - [#10286]) ([lutron\_caseta docs][lutron_caseta docs]) (breaking change) ## 全部变更 * Bump python-miio for improved 设备 support ([@syssi] - [#10294]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) ([开关.xiaomi\_miio docs][开关.xiaomi_miio docs]) * pyLoad download 传感器 ([@iMarkus] - [#10089]) ([传感器.pyload docs]) (new-platform) * Add LaCrosse 传感器 platform ([@hthiery] - [#10195]) ([传感器.lacrosse docs]) (new-platform) * Clean up 核心 ([@balloob] - [#10305]) (breaking change) * Refactor Neato botvac components as a 吸尘器 ([@jabesq] - [#9946]) ([neato docs]) ([传感器.neato docs]) ([开关.neato docs]) ([吸尘器.neato docs]) (breaking change) (new-platform) * Move constants to 设置.py ([@fabaff] - [#10312]) ([no\_ip docs][no_ip docs]) * Add option to overwrite file to the downloader component ([@arsaboo] - [#10298]) ([downloader docs]) * Use constants for HTTP headers ([@fabaff] - [#10313]) ([binary\_sensor.aurora docs][binary_sensor.aurora docs]) ([device\_tracker.tplink docs][device_tracker.tplink docs]) ([device\_tracker.upc\_connect docs][device_tracker.upc_connect docs]) ([媒体播放器.bluesound docs]) ([传感器.haveibeenpwned docs]) ([传感器.zamg docs]) ([telegram\_bot.polling docs][telegram_bot.polling docs]) * fix a import in test causing vs code to fail to discover ([@perosb] - [#10358]) * 升级 sqlalchemy to 1.1.15 ([@fabaff] - [#10330]) * Move counter component ([@fabaff] - [#10332]) ([counter docs]) * Add platform and 传感器 for Vultr VPS ([@GenericStudent] - [#9928]) ([vultr docs]) ([binary\_sensor.vultr docs][binary_sensor.vultr docs]) ([传感器.vultr docs]) (new-platform) * Add heal\_node and test\_node 服务. ([@turbokongen] - [#10369]) ([zwave docs]) * Addition of new 二元sensor class 'plug' ([@echox] - [#10336]) ([binary\_sensor docs][binary_sensor docs]) * Upgrae simplepush to 1.1.4 ([@fabaff] - [#10365]) ([通知.simplepush docs]) * 更新 aiohttp to 2.3.1 ([@pvizeli] - [#10139]) * 设备 model identification of the Xiaomi Philips Ceiling Lamp fixed. ([@syssi] - [#10401]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) * Zwave save cache to file now. ([@turbokongen] - [#10381]) * Bump to 0.12.2 to fix urllib3 dependency ([@MisterWil] - [#10420]) ([abode docs]) * Remove extra info from zwave 实体 状态 ([@armills] - [#10413]) ([zwave docs]) * Fixes issue #10425 ([@robmarkcole] - [#10426]) ([传感器.london\_air docs][传感器.london_air docs]) * Add baudrate option to Serial 传感器 ([@dgomes] - [#10439]) ([传感器.serial docs]) (breaking change) * Remove model info from 状态 ([@balloob] - [#10399]) ([灯光.tradfri docs]) * 更新 tibber library ([@danielhiversen] - [#10460]) ([传感器.tibber docs]) * 更新 pywebpush==1.3.0 ([@perosb] - [#10374]) ([通知.html5 docs]) * Fix slow WOL 开关 test ([@balloob] - [#10455]) * Fix recorder stop on SQLite vacuuming 错误 ([@milanvo] - [#10405]) * Add include/exclude filter to mqtt\_statestream ([@mw-white] - [#10354]) ([mqtt\_statestream docs][mqtt_statestream docs]) * 升级 to 0.1.2 ([@TopdRob] - [#10348]) ([通知.free\_mobile docs][通知.free_mobile docs]) * 升级 pyatv to 0.3.6 ([@TopdRob] - [#10349]) ([apple\_tv docs][apple_tv docs]) * Remove useless temp converting ([@pvizeli] - [#10465]) ([温控.homematic docs]) * 升级 apns2 to 0.3.0 ([@TopdRob] - [#10347]) ([通知.apns docs]) * Improvement of KNX 温控 component ([@Julius2342] - [#10388]) ([knx docs]) ([温控.knx docs]) * Updated gc100 package requirement to 1.0.3a ([@davegravy] - [#10484]) ([gc100 docs]) * Remove lag from Harmony 遥控器 platform ([@amelchio] - [#10218]) ([遥控器 docs]) ([遥控器.harmony docs]) * Improve 错误 handling. ([@cgtobi] - [#10482]) ([influxdb docs]) * 升级 psutil to 5.4.1 ([@fabaff] - [#10490]) ([传感器.systemmonitor docs]) * 升级 youtube\_dl to 2017.11.06 ([@fabaff] - [#10491]) ([media\_extractor docs][media_extractor docs]) * Fix for telegram polling. (added pausing when 错误 occurs) ([@sander76] - [#10214]) ([telegram\_bot.polling docs][telegram_bot.polling docs]) * add JSON processing capabilities to sensor\_serial ([@dgomes] - [#10476]) ([传感器.serial docs]) * 升级 to new pylutron\_caseta with TLS ([@mdonoughe] - [#10286]) ([lutron\_caseta docs][lutron_caseta docs]) (breaking change) * Bump dev to 0.58.0.dev0 ([@fabaff] - [#10510]) * OwnTracks Message Handling ([@ehagan] - [#10489]) ([device\_tracker.owntracks docs][device_tracker.owntracks docs]) * Add support for Alexa intent slot synonyms. ([@kmdm] - [#10469]) * Introduce media progress for Yamaha Musiccast 设备 ([@jalmeroth] - [#10256]) ([媒体播放器.yamaha\_musiccast docs][媒体播放器.yamaha_musiccast docs]) * Add an option to serve ES6 JS to clients ([@andrey-git] - [#10474]) * Adapt to new yarl API ([@tinloaf] - [#10527]) ([tts.google docs]) * 更新 nederlandse\_spoorwegen.py to include platform information ([@hmmbob] - [#10494]) ([传感器.nederlandse\_spoorwegen docs][传感器.nederlandse_spoorwegen docs]) * Pin yarl ([@tinloaf] - [#10528]) * Support 配置 of region (no 服务 url necessary ([@molobrakos] - [#10513]) ([volvooncall docs]) * Fix import in tests ([@andrey-git] - [#10525]) * 更新 axis.py ([@Kane610] - [#10412]) ([axis docs]) * Add 属性 to show who last un/set 报警 (SPC) ([@mbrrg] - [#9906]) ([spc docs]) ([alarm\_control\_panel.spc docs][alarm_control_panel.spc docs]) ([binary\_sensor.spc docs][binary_sensor.spc docs]) * Fixed Wink Quirky Aros bugs. ([@w1ll1am23] - [#10533]) ([温控.wink docs]) * Adds support for Tile® 蓝牙 trackers ([@bachya] - [#10478]) ([device\_tracker.tile docs][device_tracker.tile docs]) (new-platform) * telegram\_bot: Support for sending videos ([@vickyg3] - [#10470]) ([telegram\_bot docs][telegram_bot docs]) ([通知.telegram docs]) * Pre-construct 前端 index.html ([@balloob] - [#10520]) * 通知.html5: use new json save and load functions ([@perosb] - [#10416]) ([通知.html5 docs]) * Change to 设备 状态 属性 ([@dgomes] - [#10536]) ([传感器.serial docs]) * Google Assistant request sync 服务 ([@r4nd0mbr1ck] - [#10165]) * Optimize concurrent access to media player 图像 cache ([@amelchio] - [#10345]) ([媒体播放器 docs]) * webostv: set current source correctly ([@KapJI] - [#10548]) ([媒体播放器.webostv docs]) * 升级 pysnmp to 4.4.2 ([@fabaff] - [#10539]) ([device\_tracker.snmp docs][device_tracker.snmp docs]) ([传感器.snmp docs]) ([开关.snmp docs]) * Fix and clean lametric ([@MartinHjelmare] - [#10391]) ([lametric docs]) ([通知.lametric docs]) * Support 在场 detection using Hitron Coda router ([@arilotter] - [#9682]) ([device\_tracker.hitron\_coda docs][device_tracker.hitron_coda docs]) (new-platform) * Better support for int types ([@ziotibia81] - [#10409]) ([传感器.modbus docs]) * Don't use the 'id' field since it can be autogenerated (fixes #10551). ([@kmdm] - [#10554]) * pad packets to multiple of 4 characters ([@SteveEdson] - [#10560]) ([开关.broadlink docs]) * Move temperature display 助手 from components to 助手 ([@fabaff] - [#10555]) ([温控 docs]) ([天气 docs]) ([温控.eq3btsmart docs]) * webostv: Reduce default timeout to prevent 日志 spamming ([@abmantis] - [#10564]) ([媒体播放器.webostv docs]) * Fix lametric sound ([@MartinHjelmare] - [#10562]) ([lametric docs]) ([通知.lametric docs]) * Use a 模板 for the Universal media player 状态 ([@azogue] - [#10395]) ([媒体播放器.universal docs]) * Verisure: Added option to set 安装 giid ([@abjorshammar] - [#10504]) ([verisure docs]) * Bump ring\_doorbell to 0.1.7 ([@tchellomello] - [#10566]) ([ring docs]) * Add code to enable discovery for MQTT 遮盖 ([@marthoc] - [#10580]) ([遮盖.MQTT docs]) * Google Assistant for 温控 实体: Support QUERY and respect system-wide unit\_system setting. ([@emosenkis] - [#10346]) * turn 服务 call handler into coroutine ([@NovapaX] - [#10576]) ([configurator docs]) * Add basic 后端 support for a system 日志 ([@postlund] - [#10492]) ([system\_log docs][system_log docs]) (new-platform) * Tradfri unique identities ([@NovapaX] - [#10414]) ([tradfri docs]) * Add 面板 build type ([@balloob] - [#10589]) * Cloud updates ([@balloob] - [#10567]) * 升级 youtube\_dl to 2017.11.15 ([@fabaff] - [#10592]) ([media\_extractor docs][media_extractor docs]) * Fix Yahoo 天气 icons over SSL ([@OnFreund] - [#10602]) * Arlo - Fixes for updated library ([@jwillaz] - [#9892]) ([arlo docs]) ([摄像头.arlo docs]) ([传感器.arlo docs]) * Do not add 面板 from system\_log ([@postlund] - [#10600]) ([system\_log docs][system_log docs]) * Fix ValueError exception ([@ziotibia81] - [#10596]) ([传感器.modbus docs]) * Fix Hikvision (motion) 开关 bug ([@arsaboo] - [#10608]) ([开关.hikvisioncam docs]) * Allow unicode when dumping yaml ([@andrey-git] - [#10607]) * Support 脚本 execution for Alexa ([@micbase] - [#10517]) * bump client 版本 ([@craigjmidwinter] - [#10610]) ([alarm\_control\_panel.totalconnect docs][alarm_control_panel.totalconnect docs]) * New 传感器 viaggiatreno. ([@fabfurnari] - [#10522]) ([传感器.viaggiatreno docs]) (new-platform) * Modbus 开关 register support ([@ziotibia81] - [#10563]) ([开关.modbus docs]) * 升级 mypy to 0.550 ([@fabaff] - [#10591]) * Small fix to be able to use mac and vendor in "device\_tracker\_new\_device" event. ([@Boltgolt] - [#10537]) ([device\_tracker docs][device_tracker docs]) * add support for color temperature and color to Google Assistant ([@perosb] - [#10039]) * Cleanup old stale 恢复 feature ([@pvizeli] - [#10593]) ([灯光 docs]) * Correct input\_datetime initial value parsing ([@colindunn] - [#10417]) ([input\_datetime docs][input_datetime docs]) * Change generic thermostat to control heating on mode change Off -> Auto ([@milanvo] - [#10601]) ([温控.generic\_thermostat docs][温控.generic_thermostat docs]) * Improve WUnderground config validation ([@milanvo] - [#10573]) ([传感器.wunderground docs]) * 更新 hbmqtt to 0.9.1 ([@masarliev] - [#10611]) * Allow to pass YandexTTS options via 服务 call ([@andrey-git] - [#10578]) ([tts docs]) ([tts.yandextts docs]) * Snapcast: bump 版本 and enable reconnect. ([@janLo] - [#10626]) ([媒体播放器.snapcast docs]) * Fix async missing decorators ([@armills] - [#10628]) * Alexa slot synonym fix ([@devspacenine] - [#10614]) * Adjust logging in downloader component ([@amelchio] - [#10622]) ([downloader docs]) * Added sorted() to python\_script ([@etsinko] - [#10621]) ([python\_script docs][python_script docs]) * Add loglinefetch for 前端 API call ([@turbokongen] - [#10579]) * Fixes AirVisual bug regarding incorrect location data ([@bachya] - [#10054]) ([传感器.airvisual docs]) * Make MQTT reconnection logic more resilient and fix race 条件 ([@cezarsa] - [#10133]) ([MQTT docs]) * Alexa improvements ([@robbiet480] - [#10632]) * Print 实体 type in "too slow" 警告 ([@andrey-git] - [#10641]) * Bump pyatv to 0.3.8 ([@postlund] - [#10643]) ([apple\_tv docs][apple_tv docs]) * Implement 实体 and domain exclude/include for Alexa ([@robbiet480] - [#10647]) [#10039]: https://github.com/home-assistant/home-assistant/pull/10039 [#10054]: https://github.com/home-assistant/home-assistant/pull/10054 [#10089]: https://github.com/home-assistant/home-assistant/pull/10089 [#10133]: https://github.com/home-assistant/home-assistant/pull/10133 [#10139]: https://github.com/home-assistant/home-assistant/pull/10139 [#10165]: https://github.com/home-assistant/home-assistant/pull/10165 [#10195]: https://github.com/home-assistant/home-assistant/pull/10195 [#10214]: https://github.com/home-assistant/home-assistant/pull/10214 [#10218]: https://github.com/home-assistant/home-assistant/pull/10218 [#10256]: https://github.com/home-assistant/home-assistant/pull/10256 [#10286]: https://github.com/home-assistant/home-assistant/pull/10286 [#10294]: https://github.com/home-assistant/home-assistant/pull/10294 [#10298]: https://github.com/home-assistant/home-assistant/pull/10298 [#10305]: https://github.com/home-assistant/home-assistant/pull/10305 [#10312]: https://github.com/home-assistant/home-assistant/pull/10312 [#10313]: https://github.com/home-assistant/home-assistant/pull/10313 [#10330]: https://github.com/home-assistant/home-assistant/pull/10330 [#10332]: https://github.com/home-assistant/home-assistant/pull/10332 [#10336]: https://github.com/home-assistant/home-assistant/pull/10336 [#10345]: https://github.com/home-assistant/home-assistant/pull/10345 [#10346]: https://github.com/home-assistant/home-assistant/pull/10346 [#10347]: https://github.com/home-assistant/home-assistant/pull/10347 [#10348]: https://github.com/home-assistant/home-assistant/pull/10348 [#10349]: https://github.com/home-assistant/home-assistant/pull/10349 [#10354]: https://github.com/home-assistant/home-assistant/pull/10354 [#10358]: https://github.com/home-assistant/home-assistant/pull/10358 [#10365]: https://github.com/home-assistant/home-assistant/pull/10365 [#10369]: https://github.com/home-assistant/home-assistant/pull/10369 [#10374]: https://github.com/home-assistant/home-assistant/pull/10374 [#10381]: https://github.com/home-assistant/home-assistant/pull/10381 [#10388]: https://github.com/home-assistant/home-assistant/pull/10388 [#10391]: https://github.com/home-assistant/home-assistant/pull/10391 [#10395]: https://github.com/home-assistant/home-assistant/pull/10395 [#10399]: https://github.com/home-assistant/home-assistant/pull/10399 [#10401]: https://github.com/home-assistant/home-assistant/pull/10401 [#10405]: https://github.com/home-assistant/home-assistant/pull/10405 [#10409]: https://github.com/home-assistant/home-assistant/pull/10409 [#10412]: https://github.com/home-assistant/home-assistant/pull/10412 [#10413]: https://github.com/home-assistant/home-assistant/pull/10413 [#10414]: https://github.com/home-assistant/home-assistant/pull/10414 [#10416]: https://github.com/home-assistant/home-assistant/pull/10416 [#10417]: https://github.com/home-assistant/home-assistant/pull/10417 [#10420]: https://github.com/home-assistant/home-assistant/pull/10420 [#10426]: https://github.com/home-assistant/home-assistant/pull/10426 [#10439]: https://github.com/home-assistant/home-assistant/pull/10439 [#10455]: https://github.com/home-assistant/home-assistant/pull/10455 [#10460]: https://github.com/home-assistant/home-assistant/pull/10460 [#10465]: https://github.com/home-assistant/home-assistant/pull/10465 [#10469]: https://github.com/home-assistant/home-assistant/pull/10469 [#10470]: https://github.com/home-assistant/home-assistant/pull/10470 [#10474]: https://github.com/home-assistant/home-assistant/pull/10474 [#10476]: https://github.com/home-assistant/home-assistant/pull/10476 [#10478]: https://github.com/home-assistant/home-assistant/pull/10478 [#10482]: https://github.com/home-assistant/home-assistant/pull/10482 [#10484]: https://github.com/home-assistant/home-assistant/pull/10484 [#10489]: https://github.com/home-assistant/home-assistant/pull/10489 [#10490]: https://github.com/home-assistant/home-assistant/pull/10490 [#10491]: https://github.com/home-assistant/home-assistant/pull/10491 [#10492]: https://github.com/home-assistant/home-assistant/pull/10492 [#10494]: https://github.com/home-assistant/home-assistant/pull/10494 [#10504]: https://github.com/home-assistant/home-assistant/pull/10504 [#10510]: https://github.com/home-assistant/home-assistant/pull/10510 [#10513]: https://github.com/home-assistant/home-assistant/pull/10513 [#10517]: https://github.com/home-assistant/home-assistant/pull/10517 [#10520]: https://github.com/home-assistant/home-assistant/pull/10520 [#10522]: https://github.com/home-assistant/home-assistant/pull/10522 [#10525]: https://github.com/home-assistant/home-assistant/pull/10525 [#10527]: https://github.com/home-assistant/home-assistant/pull/10527 [#10528]: https://github.com/home-assistant/home-assistant/pull/10528 [#10533]: https://github.com/home-assistant/home-assistant/pull/10533 [#10536]: https://github.com/home-assistant/home-assistant/pull/10536 [#10537]: https://github.com/home-assistant/home-assistant/pull/10537 [#10539]: https://github.com/home-assistant/home-assistant/pull/10539 [#10548]: https://github.com/home-assistant/home-assistant/pull/10548 [#10554]: https://github.com/home-assistant/home-assistant/pull/10554 [#10555]: https://github.com/home-assistant/home-assistant/pull/10555 [#10560]: https://github.com/home-assistant/home-assistant/pull/10560 [#10562]: https://github.com/home-assistant/home-assistant/pull/10562 [#10563]: https://github.com/home-assistant/home-assistant/pull/10563 [#10564]: https://github.com/home-assistant/home-assistant/pull/10564 [#10566]: https://github.com/home-assistant/home-assistant/pull/10566 [#10567]: https://github.com/home-assistant/home-assistant/pull/10567 [#10573]: https://github.com/home-assistant/home-assistant/pull/10573 [#10576]: https://github.com/home-assistant/home-assistant/pull/10576 [#10578]: https://github.com/home-assistant/home-assistant/pull/10578 [#10579]: https://github.com/home-assistant/home-assistant/pull/10579 [#10580]: https://github.com/home-assistant/home-assistant/pull/10580 [#10589]: https://github.com/home-assistant/home-assistant/pull/10589 [#10591]: https://github.com/home-assistant/home-assistant/pull/10591 [#10592]: https://github.com/home-assistant/home-assistant/pull/10592 [#10593]: https://github.com/home-assistant/home-assistant/pull/10593 [#10596]: https://github.com/home-assistant/home-assistant/pull/10596 [#10600]: https://github.com/home-assistant/home-assistant/pull/10600 [#10601]: https://github.com/home-assistant/home-assistant/pull/10601 [#10602]: https://github.com/home-assistant/home-assistant/pull/10602 [#10607]: https://github.com/home-assistant/home-assistant/pull/10607 [#10608]: https://github.com/home-assistant/home-assistant/pull/10608 [#10610]: https://github.com/home-assistant/home-assistant/pull/10610 [#10611]: https://github.com/home-assistant/home-assistant/pull/10611 [#10614]: https://github.com/home-assistant/home-assistant/pull/10614 [#10621]: https://github.com/home-assistant/home-assistant/pull/10621 [#10622]: https://github.com/home-assistant/home-assistant/pull/10622 [#10626]: https://github.com/home-assistant/home-assistant/pull/10626 [#10628]: https://github.com/home-assistant/home-assistant/pull/10628 [#10632]: https://github.com/home-assistant/home-assistant/pull/10632 [#10641]: https://github.com/home-assistant/home-assistant/pull/10641 [#10643]: https://github.com/home-assistant/home-assistant/pull/10643 [#10647]: https://github.com/home-assistant/home-assistant/pull/10647 [#9682]: https://github.com/home-assistant/home-assistant/pull/9682 [#9892]: https://github.com/home-assistant/home-assistant/pull/9892 [#9906]: https://github.com/home-assistant/home-assistant/pull/9906 [#9928]: https://github.com/home-assistant/home-assistant/pull/9928 [#9946]: https://github.com/home-assistant/home-assistant/pull/9946 [@Boltgolt]: https://github.com/Boltgolt [@GenericStudent]: https://github.com/GenericStudent [@Julius2342]: https://github.com/Julius2342 [@Kane610]: https://github.com/Kane610 [@KapJI]: https://github.com/KapJI [@MartinHjelmare]: https://github.com/MartinHjelmare [@MisterWil]: https://github.com/MisterWil [@NovapaX]: https://github.com/NovapaX [@OnFreund]: https://github.com/OnFreund [@SteveEdson]: https://github.com/SteveEdson [@TopdRob]: https://github.com/TopdRob [@abjorshammar]: https://github.com/abjorshammar [@abmantis]: https://github.com/abmantis [@amelchio]: https://github.com/amelchio [@andrey-git]: https://github.com/andrey-git [@arilotter]: https://github.com/arilotter [@armills]: https://github.com/armills [@arsaboo]: https://github.com/arsaboo [@azogue]: https://github.com/azogue [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@cezarsa]: https://github.com/cezarsa [@cgtobi]: https://github.com/cgtobi [@colindunn]: https://github.com/colindunn [@danielhiversen]: https://github.com/danielhiversen [@davegravy]: https://github.com/davegravy [@devspacenine]: https://github.com/devspacenine [@dgomes]: https://github.com/dgomes [@echox]: https://github.com/echox [@ehagan]: https://github.com/ehagan [@emosenkis]: https://github.com/emosenkis [@etsinko]: https://github.com/etsinko [@fabaff]: https://github.com/fabaff [@fabfurnari]: https://github.com/fabfurnari [@hmmbob]: https://github.com/hmmbob [@hthiery]: https://github.com/hthiery [@iMarkus]: https://github.com/iMarkus [@jabesq]: https://github.com/jabesq [@jalmeroth]: https://github.com/jalmeroth [@janLo]: https://github.com/janLo [@jwillaz]: https://github.com/jwillaz [@kmdm]: https://github.com/kmdm [@marthoc]: https://github.com/marthoc [@masarliev]: https://github.com/masarliev [@mbrrg]: https://github.com/mbrrg [@mdonoughe]: https://github.com/mdonoughe [@micbase]: https://github.com/micbase [@milanvo]: https://github.com/milanvo [@molobrakos]: https://github.com/molobrakos [@mw-white]: https://github.com/mw-white [@perosb]: https://github.com/perosb [@postlund]: https://github.com/postlund [@pvizeli]: https://github.com/pvizeli [@r4nd0mbr1ck]: https://github.com/r4nd0mbr1ck [@robbiet480]: https://github.com/robbiet480 [@c727]: https://github.com/c727 [@robmarkcole]: https://github.com/robmarkcole [@sander76]: https://github.com/sander76 [@syssi]: https://github.com/syssi [@tchellomello]: https://github.com/tchellomello [@tinloaf]: https://github.com/tinloaf [@turbokongen]: https://github.com/turbokongen [@vickyg3]: https://github.com/vickyg3 [@w1ll1am23]: https://github.com/w1ll1am23 [@craigjmidwinter]: https://github.com/craigjmidwinter [@ziotibia81]: https://github.com/ziotibia81 [abode docs]: /integrations/abode/ [alarm_control_panel.spc docs]: /integrations/spc [alarm_control_panel.totalconnect docs]: /integrations/totalconnect [apple_tv docs]: /integrations/apple_tv/ [arlo docs]: /integrations/arlo/ [axis docs]: /integrations/axis/ [binary_sensor docs]: /integrations/binary_sensor/ [binary_sensor.aurora docs]: /integrations/aurora [binary_sensor.spc docs]: /integrations/spc#binary-传感器 [binary_sensor.vultr docs]: /integrations/vultr#binary-传感器 [摄像头.arlo docs]: /integrations/arlo#摄像头 [温控 docs]: /integrations/温控/ [温控.eq3btsmart docs]: /integrations/eq3btsmart [温控.generic_thermostat docs]: /integrations/generic_thermostat [温控.homematic docs]: /integrations/homematic [温控.knx docs]: /integrations/温控.knx/ [温控.wink docs]: /integrations/wink#温控 [cloud docs]: /integrations/cloud/ [config.zwave docs]: /integrations/config.zwave/ [configurator docs]: /integrations/configurator/ [counter docs]: /integrations/counter/ [遮盖.MQTT docs]: /integrations/遮盖.MQTT/ [device_tracker docs]: /integrations/device_tracker/ [device_tracker.hitron_coda docs]: /integrations/hitron_coda [device_tracker.owntracks docs]: /integrations/owntracks [device_tracker.snmp docs]: /integrations/snmp [device_tracker.tile docs]: /integrations/tile [device_tracker.tplink docs]: /integrations/tplink [device_tracker.upc_connect docs]: /integrations/upc_connect [downloader docs]: /integrations/downloader/ [gc100 docs]: /integrations/gc100/ [google_assistant.smart_home docs]: /integrations/google_assistant [hassio docs]: /integrations/hassio/ [influxdb docs]: /integrations/influxdb/ [input_datetime docs]: /integrations/input_datetime/ [knx docs]: /integrations/knx/ [lametric docs]: /integrations/lametric/ [灯光 docs]: /integrations/灯光/ [灯光.tradfri docs]: /integrations/tradfri [灯光.xiaomi_miio docs]: /integrations/灯光.xiaomi_miio/ [lutron_caseta docs]: /integrations/lutron_caseta/ [media_extractor docs]: /integrations/media_extractor/ [媒体播放器 docs]: /integrations/媒体播放器/ [媒体播放器.bluesound docs]: /integrations/bluesound [媒体播放器.snapcast docs]: /integrations/snapcast [媒体播放器.universal docs]: /integrations/universal [媒体播放器.webostv docs]: /integrations/webostv#media-player [媒体播放器.yamaha_musiccast docs]: /integrations/yamaha_musiccast/ [MQTT docs]: /integrations/MQTT/ [MQTT.discovery docs]: /docs/MQTT/discovery/ [MQTT.server docs]: /integrations/MQTT.server/ [mqtt_statestream docs]: /integrations/mqtt_statestream/ [neato docs]: /integrations/neato/ [no_ip docs]: /integrations/no_ip/ [通知.apns docs]: /integrations/apns [通知.free_mobile docs]: /integrations/free_mobile [通知.html5 docs]: /integrations/html5 [通知.lametric docs]: /integrations/lametric [通知.simplepush docs]: /integrations/simplepush [通知.telegram docs]: /integrations/telegram [python_script docs]: /integrations/python_script/ [遥控器 docs]: /integrations/遥控器/ [遥控器.harmony docs]: /integrations/harmony [ring docs]: /integrations/ring/ [传感器.airvisual docs]: /integrations/airvisual [传感器.arlo docs]: /integrations/arlo#传感器 [传感器.haveibeenpwned docs]: /integrations/haveibeenpwned [传感器.lacrosse docs]: /integrations/lacrosse [传感器.london_air docs]: /integrations/london_air [传感器.modbus docs]: /integrations/传感器.modbus/ [传感器.neato docs]: /integrations/neato/ [传感器.nederlandse_spoorwegen docs]: /integrations/nederlandse_spoorwegen [传感器.pyload docs]: /integrations/pyload [传感器.serial docs]: /integrations/serial [传感器.snmp docs]: /integrations/snmp#传感器 [传感器.systemmonitor docs]: /integrations/systemmonitor [传感器.tibber docs]: /integrations/tibber#传感器 [传感器.viaggiatreno docs]: /integrations/viaggiatreno [传感器.vultr docs]: /integrations/vultr#传感器 [传感器.wunderground docs]: /integrations/wunderground [传感器.zamg docs]: /integrations/zamg#传感器 [spc docs]: /integrations/spc/ [开关.broadlink docs]: /integrations/broadlink#开关 [开关.hikvisioncam docs]: /integrations/hikvisioncam [开关.modbus docs]: /integrations/开关.modbus/ [开关.neato docs]: /integrations/neato#开关 [开关.snmp docs]: /integrations/snmp#开关 [开关.xiaomi_miio docs]: /integrations/开关.xiaomi_miio/ [system_log docs]: /integrations/system_log/ [telegram_bot docs]: /integrations/telegram_bot/ [telegram_bot.polling docs]: /integrations/telegram_polling [tradfri docs]: /integrations/tradfri/ [tts docs]: /integrations/tts/ [tts.google docs]: /integrations/google_translate [tts.yandextts docs]: /integrations/yandextts [吸尘器.neato docs]: /integrations/neato#吸尘器 [verisure docs]: /integrations/verisure/ [volvooncall docs]: /integrations/volvooncall/ [vultr docs]: /integrations/vultr/ [天气 docs]: /integrations/天气/ [天气.demo docs]: /integrations/天气.demo/ [websocket_api docs]: /integrations/websocket_api/ [zwave docs]: /integrations/zwave/ [#10661]: https://github.com/home-assistant/home-assistant/pull/10661 [#10665]: https://github.com/home-assistant/home-assistant/pull/10665 [#10682]: https://github.com/home-assistant/home-assistant/pull/10682 [#10694]: https://github.com/home-assistant/home-assistant/pull/10694 [@amelchio]: https://github.com/amelchio [@etsinko]: https://github.com/etsinko [@tinloaf]: https://github.com/tinloaf [@titilambert]: https://github.com/titilambert [遥控器.harmony docs]: /integrations/harmony [传感器.time_date docs]: /integrations/time_date --- url: /home-assistant/blog/2017-11-29-hassio-virtual-machine.md --- # Set up Hass.io on top of a virtual machine The 图像 for the 树莓派 family and the Intel NUC are an easy way to get started with [Hass.io](/home-assistant/getting-started.md). For a test or if you have a system which is already hosting virtual machines then the [**Hass.io installer**](/home-assistant/installation/index.md) is an option to use Hass.io in a virtualized environment. In this guide the host is a Fedora 27 system with [libvirt](https://libvirt.org/) support and the guest will be running Debian 9. Hass.io will be 已安装 on the guest. Assuming that you already have 设置 `libvirtd`. You might need to 安装 `virt-builder` and `virt-viewer` additionally. ```bash sudo dnf -y install libguestfs-tools-c virt-install virt-viewer ``` We will create a virtual machine with Debian 9 and a 10 GB disk 图像 in the QCOW format. Use `$ virt-builder --list` to get an 概述 about what's operating systems are available if you prefer to use a different system. ```bash $ sudo virt-builder debian-9 \ --output /var/lib/libvirt/images/hassio.img \ --format qcow2 \ --size 10G \ --root-password password:test123 \ --hostname hassio \ --firstboot-command "dpkg-reconfigure openssh-server" [...] [ 147.6] Finishing off Output file: /var/lib/libvirt/images/hassio.img Output size: 10.0G Output format: qcow2 Total usable space: 9.3G Free space: 8.1G (87%) ``` Now, we are making our new virtual machine available for `libvirtd`. If you get an 错误 that the OS is unknown, use `$ osinfo-query os` to get the name to use with `--os-variant`. To access the virtual machine is connected to the bridge `bridge0`. ```bash $ sudo virt-install --name hassio --import --ram 1024 \ --os-variant debian9 -w bridge=bridge0 \ --autostart --disk /var/lib/libvirt/images/hassio.img ```

Hass.io virtual machine in Virtual Machine Manager

Depending on your preferences you can use the Virtual Machine Manager (`virt-manager`) or `virsh` to manage the 创建 virtual machine. 日志 in and create an 用户 with `# useradd ha` and set a 密码 with `# passwd ha`. We will need that 用户 to make a SSH connection to the virtual machine. 日志 in as `ha` with the given 密码. If your are using the default network of `libvirtd` then the DHCP range is defined in `/var/lib/libvirt/dnsmasq/default.conf`. In this guide the virtual machine is present at 192.168.0.109. ```bash $ ssh ha@192.168.0.109 ha@192.168.0.109's password: Linux hassio 4.9.0-3-amd64 #1 SMP Debian 4.9.30-2+deb9u3 (2017-08-06) x86_64 [...] $ ``` 安装 the requirements after you 开关 the 用户 to `root`. ```bash $ su Password: root@hassio:/home/ha# root@hassio:/home/ha# apt-get update root@hassio:/home/ha# apt-get install bash socat jq curl avahi-daemon \ apt-transport-https ca-certificates ``` We want the latest Docker 发布. This requires additional steps to set it up as unlike other distributions Debian is lacking behind with current packages. ```bash root@hassio:/home/ha# wget https://download.docker.com/linux/debian/gpg root@hassio:/home/ha# apt-key add gpg OK root@hassio:/home/ha# echo "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee -a /etc/apt/sources.list.d/docker.list root@hassio:/home/ha# apt-get update ``` Now, it's possible to 安装 a current 发布 of [Docker](https://www.Docker.com/). ```bash root@hassio:/home/ha# apt-get -y install docker-ce ``` Start `docker` and enable it. ```bash root@hassio:/home/ha# systemctl start docker && systemctl enable docker ``` An [安装 脚本](https://github.com/home-assistant/hassio-build/tree/master/安装#安装-hassio) will take care about the 设置 of all moving parts. ```bash root@hassio:/home/ha# curl -sL https://raw.githubusercontent.com/home-assistant/hassio-build/master/install/hassio_install | bash - [INFO] Install supervisor docker [INFO] Install generic HostControl [INFO] Install startup scripts [INFO] Init systemd Created symlink /etc/systemd/system/multi-user.target.wants/hassio-supervisor.service → /etc/systemd/system/hassio-supervisor.service. [INFO] Start services ``` If it's done, then there will be two new 容器. ```bash root@hassio:/home/ha# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ada5bbfc74f0 homeassistant/qemux86-64-homeassistant "/usr/bin/entry.sh..." 4 minutes ago Up 4 minutes homeassistant 5954ac452ffc homeassistant/amd64-hassio-supervisor "/usr/bin/entry.sh..." 7 minutes ago Up 7 minutes hassio_supervisor ``` After a connection to the 容器 which is containing Home Assistant is made, you will see the 日志 output. ```bash root@hassio:/home/ha# docker attach --sig-proxy=false ada5bbfc74f0 2017-11-28 19:24:30 INFO (MainThread) [homeassistant.core] Bus:Handling . Yes, the IP address is the one of the guest.

Hass.io 概述

Keep in mind that there are limitations with this approach. Not all [add-ons](/home-assistant/addons/) will work and some don't make sense to use as the hardware is not present. E.g., use the [SSH community add-on](https://github.com/hassio-addons/addon-ssh) instead of the default [SSH add-on](/home-assistant/addons/ssh/). --- url: /home-assistant/blog/2017-12-03-release-59.md --- # 0.59: Order pizza, 实体 Picker, Color Wheel 我们很高兴宣布 Home Assistant 0.59 正式发布。顺便告诉大家一声:这是 2017 年倒数第二个版本。过去一年我们始终坚持双周发布节奏,不过今年圣诞到新年期间会稍微休息一下。 ## Dominos Pizza 平台 借助 [@craigjmidwinter] 制作的 Dominos Pizza 集成,你的家现在都能帮你避免饿肚子了。再配合 [Skybell](/home-assistant/integrations/skybell/index.md) 或 [DoorBird](/home-assistant/integrations/doorbird/index.md),你就能准确知道披萨什么时候送到门口。 ## 颜色选择器 [@NovapaX] 创建了一个新的颜色选择器。当你用手指拖动颜色标记时,手指上方会出现一个提示标记,让你能看到当前选中的颜色。

Screenshot of the color wheel. 颜色轮截图。

## 购物清单改进 [@balloob] 重新优化了购物清单 UI,让它更易用。现在除了语音外,也可以直接通过输入文字添加项目,编辑操作也更方便了。 ## 实体选择器 [@balloob] 改进了实体选择体验。在自动化编辑器、脚本编辑器以及开发者工具的服务区域中,现在更容易找到正确的实体了!自动化编辑器也只会推荐相关实体。

Screenshot of the 实体 Picker. 实体选择器截图。

## Hass.io 插件 If you follow our [twitter feed](https://twitter.com/home_assistant) then you may already know that [@frenck](https://github.com/frenck) spent some time to bring new stuff to the [Community Hass.io Add-ons repository](https://github.com/hassio-addons/repository). * [Cloud9 IDE](https://github.com/hassio-addons/addon-ide) * [Terminal support](https://github.com/hassio-addons/addon-terminal) * New 发布 of the [Tor add-on](https://github.com/hassio-addons/addon-tor) ## 新平台 * Support for Unifi direct access 设备 tracker (No unifi controller software) ([@w1ll1am23] - [#10097]) ([device\_tracker.unifi\_direct docs][device_tracker.unifi_direct docs]) (new-platform) * Tahoma platform for Somfy 遮盖 and 传感器 ([@philklei] - [#10652]) ([tahoma docs]) ([遮盖.tahoma docs]) ([传感器.tahoma docs]) (new-platform) * New Hive Component / Platforms ([@Rendili] - [#9804]) ([hive docs]) ([温控.hive docs]) ([灯光.hive docs]) ([传感器.hive docs]) ([开关.hive docs]) (new-platform) * Add Dominos Pizza platform ([@craigjmidwinter] - [#10379]) ([dominos docs]) (new-platform) * Add tts.baidu platform ([@zhujisheng] - [#10724]) ([tts.baidu docs]) (new-platform) * Create ecobee 天气 platform ([@PhracturedBlue] - [#10869]) ([ecobee docs]) ([天气.ecobee docs]) (new-platform) ## 发布 0.59.1 - December 4 * Fix 通知 for Android TV ([@danielperna84] - [#10798]) ([通知.nfandroidtv docs]) * fix iOS component config generation ([@wrboyce] - [#10923]) * Fix color wheel in group more info dialogs ([@NovapaX] - [#10934]) * Dominos no order fix ([@craigjmidwinter] - [#10935]) ([dominos docs]) ## 发布 0.59.2 - December 6 * Require FF43 for latest js ([@andrey-git] - [#10941]) * Fix linksys\_ap.py by inheriting DeviceScanner ([@mateuszdrab] - [#10947]) * 升级 tellduslive library 版本 (closes https://github.com/home-assistant/home-assistant/issues/10922) ([@molobrakos] - [#10950]) ([tellduslive docs]) * Allow chime to work for wink 警报器/chime ([@w1ll1am23] - [#10961]) ([wink docs]) * 重载 closest store on api menu request ([@craigjmidwinter] - [#10962]) ([dominos docs]) * Revert pychromecast 更新 ([@balloob] - [#10989]) ([媒体播放器.cast docs]) ## 如果你需要帮助…… ……欢迎使用我们非常活跃的[论坛](https://community.home-assistant.io/),或者加入我们的[聊天频道](https://discord.gg/c5DvZ4e)。虽然发布说明开放了评论,但我们更推荐你使用前面的社区交流渠道。谢谢。 ## 反馈问题 如果你遇到了此次发布引入的问题,请在我们的 [issue tracker](https://github.com/home-assistant/home-assistant/issues) 中反馈。请确保完整填写 issue 模板中的所有字段。 ## 不向后兼容的变更 * Added cycles config option to LaMetric 通知 ([@frittes] - [#10656]) ([通知.lametric docs]) (breaking change) * Fix name collision when using multiple Hue bridges ([@zBart] - [#10486]) ([灯光.hue docs]) (breaking change) * Single LEDs in Blinkt support ([@matemaciek] - [#10581]) ([灯光.blinkt docs]) (breaking change) * Tellduslive 更新 with support for auto config and Local api ([@fredrike] - [#10435]) ([tellduslive docs]) (breaking change) * Add useragent-based detection of JS 版本 ([@andrey-git] - [#10776]) (breaking change) ## 全部变更 * Added unit\_of\_measurement to Currencylayer ([@arsaboo] - [#10598]) ([传感器.currencylayer docs]) * Change generic thermostat - any 切换 设备 as heater 开关 ([@milanvo] - [#10597]) ([温控.generic\_thermostat docs][温控.generic_thermostat docs]) * Add hddtemp 传感器 设备 even if unreachable. ([@cgtobi] - [#10623]) ([传感器.hddtemp docs]) * 恢复 target temperature for generic thermostat ([@tinloaf] - [#10635]) ([温控.generic\_thermostat docs][温控.generic_thermostat docs]) * 更新 lnetatmo ([@gieljnssns] - [#10631]) ([netatmo docs]) * Support for Unifi direct access 设备 tracker (No unifi controller software) ([@w1ll1am23] - [#10097]) ([device\_tracker.unifi\_direct docs][device_tracker.unifi_direct docs]) (new-platform) * Add Facebook 通知 tests ([@broox] - [#10642]) * Change some 警告 to info ([@cgarwood] - [#10386]) ([emulated\_hue docs][emulated_hue docs]) * Added cycles config option to LaMetric 通知 ([@frittes] - [#10656]) ([通知.lametric docs]) (breaking change) * Netatmo httperror403 fix ([@gieljnssns] - [#10659]) ([netatmo docs]) * Bump dev to 0.59.0.dev0 ([@fabaff] - [#10675]) * Include unit\_of\_measurement as InfluxDb field ([@PeteBa] - [#9790]) ([influxdb docs]) * Tahoma platform for Somfy 遮盖 and 传感器 ([@philklei] - [#10652]) ([tahoma docs]) ([遮盖.tahoma docs]) ([传感器.tahoma docs]) (new-platform) * Populate measurement 状态 field for HA 状态 like home/not\_home ([@PeteBa] - [#9833]) ([influxdb docs]) * Reorganize lint travis builds ([@balloob] - [#10670]) * Refactored to new global json saving and loading ([@mnigbur] - [#10677]) * Convert configurator to use markdown ([@balloob] - [#10668]) ([configurator docs]) ([灯光.hue docs]) * index.html improvements ([@balloob] - [#10696]) * Add Arm Custom Bypass to alarm\_control\_panel ([@uchagani] - [#10697]) ([alarm\_control\_panel docs][alarm_control_panel docs]) * Fix conversation ([@balloob] - [#10686]) ([conversation docs]) * Shopping list: add item HTTP API ([@balloob] - [#10674]) ([shopping\_list docs][shopping_list docs]) * Add 在场 device\_class ([@arsaboo] - [#10705]) ([binary\_sensor docs][binary_sensor docs]) * python-miio 版本 bumped for improved 设备 support. ([@syssi] - [#10720]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) ([开关.xiaomi\_miio docs][开关.xiaomi_miio docs]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) * Adding Queue count 传感器 ([@bigwoof] - [#10723]) ([传感器.sabnzbd docs]) * Bump pychromecast to 1.0.2 ([@OttoWinter] - [#10728]) ([媒体播放器.cast docs]) * Fix unit conversion for Sensibo A/C units ([@bryanyork] - [#10692]) ([温控.sensibo docs]) * Optimised 图像. Saved 80 KB out of 656 KB. 12.3% overall (up to 32.1% per file) ([@grischard] - [#10735]) * Add transmission rate ([@svenstaro] - [#10740]) ([传感器.fritzbox\_netmonitor docs][传感器.fritzbox_netmonitor docs]) * 更新 pytradfri to 4.1.0 ([@lwis] - [#10521]) ([tradfri docs]) ([灯光.tradfri docs]) * Use new DoorBirdPy (v0.1.0) ([@Klikini] - [#10734]) ([doorbird docs]) * Add 风扇 and reduce I/O calls in radiotherm ([@TD22057] - [#10437]) ([温控.radiotherm docs]) * New Hive Component / Platforms ([@Rendili] - [#9804]) ([hive docs]) ([温控.hive docs]) ([灯光.hive docs]) ([传感器.hive docs]) ([开关.hive docs]) (new-platform) * Temporarily fix yahoo 天气 API issue and add unit test. ([@cgtobi] - [#10737]) * Google assistant 温控 mode fix ([@braddparker] - [#10726]) ([google\_assistant.smart\_home docs][google_assistant.smart_home docs]) * Protect sensitive information for Amcrest 摄像头 ([@tchellomello] - [#10569]) ([amcrest docs]) ([摄像头.amcrest docs]) ([传感器.amcrest docs]) * InfluxDB send retry after IOError ([@janLo] - [#10263]) ([influxdb docs]) * Add Dominos Pizza platform ([@craigjmidwinter] - [#10379]) ([dominos docs]) (new-platform) * Fix name collision when using multiple Hue bridges ([@zBart] - [#10486]) ([灯光.hue docs]) (breaking change) * Make shell\_command async ([@n8henrie] - [#10741]) ([shell\_command docs][shell_command docs]) * 更新 CODEOWNERS with hive Component / Platforms ([@Rendili] - [#10775]) * Bump total-connect-client 版本 ([@uchagani] - [#10769]) ([alarm\_control\_panel.totalconnect docs][alarm_control_panel.totalconnect docs]) * Fix 场景 description formatting. ([@balloob] - [#10785]) * Fixes #10773: Demo 报警 Broken ([@uchagani] - [#10777]) ([alarm\_control\_panel.demo docs][alarm_control_panel.demo docs]) * Load Ring 摄像头 only with Ring Protect plan activated ([@tchellomello] - [#10739]) ([ring docs]) ([摄像头.ring docs]) * system\_log improvements ([@andrey-git] - [#10709]) ([system\_log docs][system_log docs]) * Fix WUnderground 错误 handling, rework 实体 methods ([@milanvo] - [#10295]) ([传感器.wunderground docs]) * Add away\_mode\_name to arlo 报警 control 面板 ([@bcl1713] - [#10796]) ([alarm\_control\_panel.arlo docs][alarm_control_panel.arlo docs]) * Add missing docstring ([@fabaff] - [#10812]) ([通知.pushbullet docs]) * Cloud cognito 开关 ([@balloob] - [#10823]) ([cloud docs]) * Added 传感器 types from telldus server src ([@rasmusbe] - [#10787]) ([传感器.tellduslive docs]) * Add tts.baidu platform ([@zhujisheng] - [#10724]) ([tts.baidu docs]) (new-platform) * make RGB values consistent as int. fixes #10766 ([@perosb] - [#10782]) * Single LEDs in Blinkt support ([@matemaciek] - [#10581]) ([灯光.blinkt docs]) (breaking change) * Add 调试 ([@dgomes] - [#10828]) ([传感器.serial docs]) * Fix "recently pair 设备" ([@stephenyeargin] - [#10832]) * Fixed Yeelight's color temperature conversion to RGB ([@chocomega] - [#10831]) ([灯光.yeelight docs]) * Fix for Sensibo with missing temperature ([@andrey-git] - [#10801]) ([温控.sensibo docs]) * 升级 somecomfort to 0.5.0 ([@dferrante] - [#10834]) ([温控.honeywell docs]) * Add support for logarithm in 模板 ([@odinuge] - [#10824]) * Changing handling for google\_assistant groups to treat them as 灯光. ([@snowzach] - [#10111]) * Tellduslive 更新 with support for auto config and Local api ([@fredrike] - [#10435]) ([tellduslive docs]) (breaking change) * KNX: Added config option for broadcasting current time to KNX bus. ([@Julius2342] - [#10654]) ([knx docs]) * Ecobee set humidity level ([@cbulock] - [#10780]) ([ecobee docs]) ([温控.ecobee docs]) * Add 设备 class for low battery ([@schmittx] - [#10829]) ([binary\_sensor docs][binary_sensor docs]) * Tellduslive: Use magic constants for battery level. Also, the previous formula for battery level was wrong. ([@molobrakos] - [#10788]) ([tellduslive docs]) * Add useragent-based detection of JS 版本 ([@andrey-git] - [#10776]) (breaking change) * add support for multiple execution per execute request ([@perosb] - [#10844]) ([google\_assistant.http docs][google_assistant.http docs]) * 升级 HomeMatic, add 设备 ([@danielperna84] - [#10845]) ([homematic docs]) ([binary\_sensor.homematic docs][binary_sensor.homematic docs]) ([传感器.homematic docs]) * 温控 component: add supported\_features ([@tinloaf] - [#10658]) ([温控 docs]) ([温控.generic\_thermostat docs][温控.generic_thermostat docs]) ([温控.MQTT docs]) * 升级 mutagen to 1.39 ([@fabaff] - [#10851]) ([tts docs]) * Updated codeowner for Tile 设备 tracker ([@bachya] - [#10861]) * Revert "KNX: Added config option for broadcasting current time to KNX bus. (#10654)" ([@Julius2342] - [#10874]) ([knx docs]) * 升级 distro to 1.1.0 ([@fabaff] - [#10850]) ([updater docs]) * Bugfix 触发器 状态 with multible 实体 ([@pvizeli] - [#10857]) ([自动化.状态 docs]) * tellstick fix DEPENDENCIES and 更新 tellcore-net ([@pvizeli] - [#10859]) ([tellstick docs]) ([传感器.tellstick docs]) * 升级 aiohttp to 2.3.5 ([@fabaff] - [#10889]) * 升级 fastdotcom to 0.0.3 ([@fabaff] - [#10886]) ([传感器.fastdotcom docs]) * 升级 schiene to 0.19 ([@fabaff] - [#10887]) ([传感器.deutsche\_bahn docs][传感器.deutsche_bahn docs]) * Xiaomi 吸尘器: remove deprecated calls ([@rytilahti] - [#10839]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) * Create ecobee 天气 platform ([@PhracturedBlue] - [#10869]) ([ecobee docs]) ([天气.ecobee docs]) (new-platform) * Microsoft Text-to-speech: Fixing missing en-gb support bug ([@jeroenterheerdt] - [#10429]) ([tts.microsoft docs]) * 升级 youtube\_dl to 2017.11.26 ([@fabaff] - [#10890]) ([media\_extractor docs][media_extractor docs]) * 升级 yarl to 0.15.0 ([@fabaff] - [#10888]) * Fix tests ([@pvizeli] - [#10891]) * Refactored WHOIS 传感器 to resolve assumed key 错误 ([@GenericStudent] - [#10662]) ([传感器.whois docs]) * Serve latest extra\_html in dev mode ([@andrey-git] - [#10863]) * 重载 groups after saving a change via config API ([@andrey-git] - [#10877]) ([config.group docs]) * Fix issues from review of ecobee 天气 component ([@PhracturedBlue] - [#10903]) ([天气.ecobee docs]) * Bugfix #10902 ([@turbokongen] - [#10904]) ([zwave docs]) [#10097]: https://github.com/home-assistant/home-assistant/pull/10097 [#10111]: https://github.com/home-assistant/home-assistant/pull/10111 [#10263]: https://github.com/home-assistant/home-assistant/pull/10263 [#10295]: https://github.com/home-assistant/home-assistant/pull/10295 [#10379]: https://github.com/home-assistant/home-assistant/pull/10379 [#10386]: https://github.com/home-assistant/home-assistant/pull/10386 [#10429]: https://github.com/home-assistant/home-assistant/pull/10429 [#10435]: https://github.com/home-assistant/home-assistant/pull/10435 [#10437]: https://github.com/home-assistant/home-assistant/pull/10437 [#10486]: https://github.com/home-assistant/home-assistant/pull/10486 [#10521]: https://github.com/home-assistant/home-assistant/pull/10521 [#10569]: https://github.com/home-assistant/home-assistant/pull/10569 [#10581]: https://github.com/home-assistant/home-assistant/pull/10581 [#10597]: https://github.com/home-assistant/home-assistant/pull/10597 [#10598]: https://github.com/home-assistant/home-assistant/pull/10598 [#10623]: https://github.com/home-assistant/home-assistant/pull/10623 [#10631]: https://github.com/home-assistant/home-assistant/pull/10631 [#10635]: https://github.com/home-assistant/home-assistant/pull/10635 [#10642]: https://github.com/home-assistant/home-assistant/pull/10642 [#10652]: https://github.com/home-assistant/home-assistant/pull/10652 [#10654]: https://github.com/home-assistant/home-assistant/pull/10654 [#10656]: https://github.com/home-assistant/home-assistant/pull/10656 [#10658]: https://github.com/home-assistant/home-assistant/pull/10658 [#10659]: https://github.com/home-assistant/home-assistant/pull/10659 [#10662]: https://github.com/home-assistant/home-assistant/pull/10662 [#10668]: https://github.com/home-assistant/home-assistant/pull/10668 [#10670]: https://github.com/home-assistant/home-assistant/pull/10670 [#10674]: https://github.com/home-assistant/home-assistant/pull/10674 [#10675]: https://github.com/home-assistant/home-assistant/pull/10675 [#10677]: https://github.com/home-assistant/home-assistant/pull/10677 [#10686]: https://github.com/home-assistant/home-assistant/pull/10686 [#10692]: https://github.com/home-assistant/home-assistant/pull/10692 [#10696]: https://github.com/home-assistant/home-assistant/pull/10696 [#10697]: https://github.com/home-assistant/home-assistant/pull/10697 [#10705]: https://github.com/home-assistant/home-assistant/pull/10705 [#10709]: https://github.com/home-assistant/home-assistant/pull/10709 [#10720]: https://github.com/home-assistant/home-assistant/pull/10720 [#10723]: https://github.com/home-assistant/home-assistant/pull/10723 [#10724]: https://github.com/home-assistant/home-assistant/pull/10724 [#10726]: https://github.com/home-assistant/home-assistant/pull/10726 [#10728]: https://github.com/home-assistant/home-assistant/pull/10728 [#10734]: https://github.com/home-assistant/home-assistant/pull/10734 [#10735]: https://github.com/home-assistant/home-assistant/pull/10735 [#10737]: https://github.com/home-assistant/home-assistant/pull/10737 [#10739]: https://github.com/home-assistant/home-assistant/pull/10739 [#10740]: https://github.com/home-assistant/home-assistant/pull/10740 [#10741]: https://github.com/home-assistant/home-assistant/pull/10741 [#10769]: https://github.com/home-assistant/home-assistant/pull/10769 [#10775]: https://github.com/home-assistant/home-assistant/pull/10775 [#10776]: https://github.com/home-assistant/home-assistant/pull/10776 [#10777]: https://github.com/home-assistant/home-assistant/pull/10777 [#10780]: https://github.com/home-assistant/home-assistant/pull/10780 [#10782]: https://github.com/home-assistant/home-assistant/pull/10782 [#10785]: https://github.com/home-assistant/home-assistant/pull/10785 [#10787]: https://github.com/home-assistant/home-assistant/pull/10787 [#10788]: https://github.com/home-assistant/home-assistant/pull/10788 [#10796]: https://github.com/home-assistant/home-assistant/pull/10796 [#10801]: https://github.com/home-assistant/home-assistant/pull/10801 [#10812]: https://github.com/home-assistant/home-assistant/pull/10812 [#10823]: https://github.com/home-assistant/home-assistant/pull/10823 [#10824]: https://github.com/home-assistant/home-assistant/pull/10824 [#10828]: https://github.com/home-assistant/home-assistant/pull/10828 [#10829]: https://github.com/home-assistant/home-assistant/pull/10829 [#10831]: https://github.com/home-assistant/home-assistant/pull/10831 [#10832]: https://github.com/home-assistant/home-assistant/pull/10832 [#10834]: https://github.com/home-assistant/home-assistant/pull/10834 [#10839]: https://github.com/home-assistant/home-assistant/pull/10839 [#10844]: https://github.com/home-assistant/home-assistant/pull/10844 [#10845]: https://github.com/home-assistant/home-assistant/pull/10845 [#10850]: https://github.com/home-assistant/home-assistant/pull/10850 [#10851]: https://github.com/home-assistant/home-assistant/pull/10851 [#10857]: https://github.com/home-assistant/home-assistant/pull/10857 [#10859]: https://github.com/home-assistant/home-assistant/pull/10859 [#10861]: https://github.com/home-assistant/home-assistant/pull/10861 [#10863]: https://github.com/home-assistant/home-assistant/pull/10863 [#10869]: https://github.com/home-assistant/home-assistant/pull/10869 [#10874]: https://github.com/home-assistant/home-assistant/pull/10874 [#10877]: https://github.com/home-assistant/home-assistant/pull/10877 [#10886]: https://github.com/home-assistant/home-assistant/pull/10886 [#10887]: https://github.com/home-assistant/home-assistant/pull/10887 [#10888]: https://github.com/home-assistant/home-assistant/pull/10888 [#10889]: https://github.com/home-assistant/home-assistant/pull/10889 [#10890]: https://github.com/home-assistant/home-assistant/pull/10890 [#10891]: https://github.com/home-assistant/home-assistant/pull/10891 [#10903]: https://github.com/home-assistant/home-assistant/pull/10903 [#10904]: https://github.com/home-assistant/home-assistant/pull/10904 [#9790]: https://github.com/home-assistant/home-assistant/pull/9790 [#9804]: https://github.com/home-assistant/home-assistant/pull/9804 [#9833]: https://github.com/home-assistant/home-assistant/pull/9833 [@GenericStudent]: https://github.com/GenericStudent [@Julius2342]: https://github.com/Julius2342 [@Klikini]: https://github.com/Klikini [@OttoWinter]: https://github.com/OttoWinter [@PeteBa]: https://github.com/PeteBa [@PhracturedBlue]: https://github.com/PhracturedBlue [@Rendili]: https://github.com/Rendili [@TD22057]: https://github.com/TD22057 [@andrey-git]: https://github.com/andrey-git [@arsaboo]: https://github.com/arsaboo [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@bcl1713]: https://github.com/bcl1713 [@bigwoof]: https://github.com/bigwoof [@braddparker]: https://github.com/braddparker [@broox]: https://github.com/broox [@bryanyork]: https://github.com/bryanyork [@cbulock]: https://github.com/cbulock [@cgarwood]: https://github.com/cgarwood [@cgtobi]: https://github.com/cgtobi [@chocomega]: https://github.com/chocomega [@danielperna84]: https://github.com/danielperna84 [@dferrante]: https://github.com/dferrante [@dgomes]: https://github.com/dgomes [@fabaff]: https://github.com/fabaff [@fredrike]: https://github.com/fredrike [@frittes]: https://github.com/frittes [@gieljnssns]: https://github.com/gieljnssns [@grischard]: https://github.com/grischard [@janLo]: https://github.com/janLo [@jeroenterheerdt]: https://github.com/jeroenterheerdt [@lwis]: https://github.com/lwis [@matemaciek]: https://github.com/matemaciek [@milanvo]: https://github.com/milanvo [@mnigbur]: https://github.com/mnigbur [@molobrakos]: https://github.com/molobrakos [@n8henrie]: https://github.com/n8henrie [@odinuge]: https://github.com/odinuge [@perosb]: https://github.com/perosb [@philklei]: https://github.com/philklei [@pvizeli]: https://github.com/pvizeli [@rasmusbe]: https://github.com/rasmusbe [@rytilahti]: https://github.com/rytilahti [@schmittx]: https://github.com/schmittx [@snowzach]: https://github.com/snowzach [@stephenyeargin]: https://github.com/stephenyeargin [@svenstaro]: https://github.com/svenstaro [@syssi]: https://github.com/syssi [@tchellomello]: https://github.com/tchellomello [@tinloaf]: https://github.com/tinloaf [@turbokongen]: https://github.com/turbokongen [@uchagani]: https://github.com/uchagani [@w1ll1am23]: https://github.com/w1ll1am23 [@craigjmidwinter]: https://github.com/craigjmidwinter [@zBart]: https://github.com/zBart [@zhujisheng]: https://github.com/zhujisheng [alarm_control_panel docs]: /integrations/alarm_control_panel/ [alarm_control_panel.arlo docs]: /integrations/arlo [alarm_control_panel.demo docs]: /integrations/demo/ [alarm_control_panel.totalconnect docs]: /integrations/totalconnect [amcrest docs]: /integrations/amcrest/ [自动化.状态 docs]: /docs/自动化/触发器/#状态-触发器 [binary_sensor docs]: /integrations/binary_sensor/ [binary_sensor.homematic docs]: /integrations/homematic [摄像头.amcrest docs]: /integrations/amcrest [摄像头.ring docs]: /integrations/ring#摄像头 [温控 docs]: /integrations/温控/ [温控.ecobee docs]: /integrations/ecobee [温控.generic_thermostat docs]: /integrations/generic_thermostat [温控.hive docs]: /integrations/hive#温控 [温控.honeywell docs]: /integrations/honeywell [温控.MQTT docs]: /integrations/温控.MQTT/ [温控.radiotherm docs]: /integrations/radiotherm [温控.sensibo docs]: /integrations/sensibo [cloud docs]: /integrations/cloud/ [config.group docs]: /integrations/config/ [configurator docs]: /integrations/configurator/ [conversation docs]: /integrations/conversation/ [遮盖.tahoma docs]: /integrations/tahoma [device_tracker.unifi_direct docs]: /integrations/unifi_direct/ [dominos docs]: /integrations/dominos/ [doorbird docs]: /integrations/doorbird/ [ecobee docs]: /integrations/ecobee/ [emulated_hue docs]: /integrations/emulated_hue/ [风扇.xiaomi_miio docs]: /integrations/风扇.xiaomi_miio/ [google_assistant.http docs]: /integrations/google_assistant/ [google_assistant.smart_home docs]: /integrations/google_assistant [hive docs]: /integrations/hive/ [homematic docs]: /integrations/homematic/ [influxdb docs]: /integrations/influxdb/ [knx docs]: /integrations/knx/ [灯光.blinkt docs]: /integrations/blinkt [灯光.hive docs]: /integrations/hive#灯光 [灯光.hue docs]: /integrations/hue [灯光.tradfri docs]: /integrations/tradfri [灯光.xiaomi_miio docs]: /integrations/灯光.xiaomi_miio/ [灯光.yeelight docs]: /integrations/yeelight [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.cast docs]: /integrations/cast [netatmo docs]: /integrations/netatmo/ [通知.lametric docs]: /integrations/lametric [通知.pushbullet docs]: /integrations/pushbullet [ring docs]: /integrations/ring/ [传感器.amcrest docs]: /integrations/amcrest [传感器.currencylayer docs]: /integrations/currencylayer [传感器.deutsche_bahn docs]: /integrations/deutsche_bahn [传感器.fastdotcom docs]: /integrations/fastdotcom [传感器.fritzbox_netmonitor docs]: /integrations/fritzbox#sensor_netmonitor/ [传感器.hddtemp docs]: /integrations/hddtemp [传感器.hive docs]: /integrations/hive#传感器 [传感器.homematic docs]: /integrations/homematic [传感器.sabnzbd docs]: /integrations/sabnzbd [传感器.serial docs]: /integrations/serial [传感器.tahoma docs]: /integrations/tahoma [传感器.tellduslive docs]: /integrations/tellduslive [传感器.tellstick docs]: /integrations/tellstick#传感器 [传感器.whois docs]: /integrations/whois [传感器.wunderground docs]: /integrations/wunderground [shell_command docs]: /integrations/shell_command/ [shopping_list docs]: /integrations/shopping_list/ [开关.hive docs]: /integrations/hive#开关 [开关.xiaomi_miio docs]: /integrations/开关.xiaomi_miio/ [system_log docs]: /integrations/system_log/ [tahoma docs]: /integrations/tahoma/ [tellduslive docs]: /integrations/tellduslive/ [tellstick docs]: /integrations/tellstick/ [tradfri docs]: /integrations/tradfri/ [tts docs]: /integrations/tts/ [tts.baidu docs]: /integrations/baidu [tts.microsoft docs]: /integrations/microsoft [updater docs]: /integrations/updater/ [吸尘器.xiaomi_miio docs]: /integrations/吸尘器.xiaomi_miio/ [天气.ecobee docs]: /integrations/ecobee [zwave docs]: /integrations/zwave/ [#10798]: https://github.com/home-assistant/home-assistant/pull/10798 [#10923]: https://github.com/home-assistant/home-assistant/pull/10923 [#10934]: https://github.com/home-assistant/home-assistant/pull/10934 [#10935]: https://github.com/home-assistant/home-assistant/pull/10935 [@NovapaX]: https://github.com/NovapaX [@wrboyce]: https://github.com/wrboyce [通知.nfandroidtv docs]: /integrations/nfandroidtv [#10941]: https://github.com/home-assistant/home-assistant/pull/10941 [#10947]: https://github.com/home-assistant/home-assistant/pull/10947 [#10950]: https://github.com/home-assistant/home-assistant/pull/10950 [#10961]: https://github.com/home-assistant/home-assistant/pull/10961 [#10962]: https://github.com/home-assistant/home-assistant/pull/10962 [#10989]: https://github.com/home-assistant/home-assistant/pull/10989 [@andrey-git]: https://github.com/andrey-git [@balloob]: https://github.com/balloob [@mateuszdrab]: https://github.com/mateuszdrab [@molobrakos]: https://github.com/molobrakos [@w1ll1am23]: https://github.com/w1ll1am23 [@craigjmidwinter]: https://github.com/craigjmidwinter [dominos docs]: /integrations/dominos/ [媒体播放器.cast docs]: /integrations/cast [tellduslive docs]: /integrations/tellduslive/ [wink docs]: /integrations/wink/ --- url: /home-assistant/blog/2017-12-17-introducing-home-assistant-cloud.md --- # Introducing Home Assistant Cloud Today we’re introducing the next step in the Home Assistant saga: the Home Assistant Cloud. The goal of the Home Assistant Cloud is to bridge the gap between your local Home Assistant instance and 服务 in the cloud while delivering the maximum possible security and privacy. The first 服务 that is supported via the Home Assistant Cloud is the Amazon Alexa Smart Home skill. 此integrations will allow you to control all your 设备 in Home Assistant via Amazon Alexa. You will be able to say *“Alexa, 打开 the kitchen 灯光”* and your local Home Assistant will 打开 the 灯光. Because Alexa talks to Home Assistant, it doesn’t Matter what kind of 灯光 they are! Anything that is linked to Home Assistant will work. IKEA 灯光, a 10 year old X10 开关 or something you’ve made yourself. As long as Home Assistant can control it, you can control it via Alexa. We have designed the Home Assistant Cloud with security in mind. When you activate the new Cloud component, your instance will create a secure connection to the Home Assistant Cloud. There is no need for any further 配置 or to expose your instance to the internet. 集成 like Alexa will deliver messages to our cloud which we will forward to your local instance for processing. We just forward the response back to Alexa. This means that we do not have to store the 状态 of your house in our cloud, we’re just the messenger! We are making the beta of the Home Assistant Cloud publicly available today. During the beta period the Home Assistant Cloud will be free to use. We are currently planning to run a beta till March 1, 2018 0:00 UTC. Once the beta ends, the Home Assistant Cloud will be part of our Community Support package which will run at $5 USD/month. By subscribing to the Community Support package you will show your support for the Home Assistant organization, its projects and its community. It will help fund development, 遮盖 our operating costs and gives you access to use Home Assistant Cloud. So if you ever felt like donating money to support the development of Home Assistant and Hass.io: sign up for the Home Assistant Cloud! ### Why not take donations? With donations you have to convince people to keep donating and it will be hard to plan around the amount of available money. The biggest concern is what do you do when there is not enough money. We could shut down the servers or again depend on the wallets of our 开发者. We could run Wikipedia style advertisements for donating, but those are even more annoying than running advertisements. ## 入门 升级 Home Assistant to 0.60 and enable the [`cloud`](/home-assistant/integrations/cloud/index.md) and [`config`](/home-assistant/integrations/config/index.md) components: ```yaml # Example configuration.yaml entry cloud: config: ``` Now 重启 Home Assistant and navigate to the 配置 面板. It will offer a new cloud section. Here you can create an account and login. Once logged in, your instance will connect to the cloud. The next step is to 配置 Alexa. This can be done by enabling the Home Assistant skill for Alexa and link your Home Assistant cloud account. Once you’re done, ask Alexa to discover 设备 (“Alexa, discover 设备”) and you are all set to control them: “Alexa, 打开 <设备 name>”. See the [Cloud component 配置](/home-assistant/integrations/cloud/index.md) to learn how to filter which 设备 get exposed to Alexa. ## 常见问题 *Last updated: February 22, 2018* #### I thought the Home Assistant crew didn't like the cloud? You are right, [we don't](/home-assistant/blog/2016/01/19/perfect-home-automation/#your-system-should-run-at-home-not-in-the-cloud)! The Home Assistant Cloud is not an alternative to running your local Home Assistant instance. All control and 自动化 are still running locally. Instead, the Home Assistant Cloud is an extension of your local instance. It allows to communicate with companies that force us to communicate via a public available cloud endpoint like Amazon Alexa and Google Assistant. Home Assistant Cloud is only used to route the messages to your local Home Assistant instance. All messages are processed locally. *(Some people have suggested we rename to Home Assistant Bridge to avoid this confusion)* #### Will Home Assistant and Hass.io remain 开源? Yes. Yes. Yes! Home Assistant is the work of hundreds of 开发者 all working together in creating something amazing. The only thing that will require a subscription is the optional cloud functionality. #### Where is the source code for the Alexa skill? All messages are processed locally and so the Alexa skill code is part of the Home Assistant code. The Home Assistant Cloud only routes the messages to your local Home Assistant instance. This means that you can audit the source code to check all the things that the cloud can do: * [Module that processes incoming cloud messages](https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/integrations/cloud/iot.py) * [Alexa Smart Home v3 skill](https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/integrations/alexa/smart_home.py) #### What other features will come to the cloud? We have a lot of ideas! We are not going to make any promises but here are some things that we’re looking into: * Google Home / Google Assistant Smart Home skill * Allow easy linking of other cloud 服务 to Home Assistant. No more local juggling with OAuth flows. For example, link your Fitbit account and the Fitbit component will show up in Home Assistant. * Encrypted 备份 of your Hass.io data * Text-to-speech powered by AWS Polly * Generic HTTP cloud endpoint for people to send messages to their local instance. This will allow people to build applications on top of the Home Assistant cloud. * IFTTT 集成 * Alexa shopping list 集成 #### What countries are supported at launch? As of February 2018, we are live in all countries that have Alexa except for Japan (which is under certification). #### How is the connection made to the cloud? The connection is made using a WebSocket connection over HTTPS. [See the source here](https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/integrations/cloud/iot.py). #### I think that the price is too high for what I get. The Home Assistant Cloud functionality is a perk for becoming a supporter of the Home Assistant project. As a supporter you will help fund development, 遮盖 our operating costs and gives you access to use Home Assistant Cloud. You are not paying to just maintain the cloud servers. The perks offered for being a supporter will also extend over time, as noted in [this answer](#what-other-features-will-come-to-the-cloud). #### What will the Home Assistant organization do with the funds ? The plan is to hire 开发者 to work fulltime on Home Assistant. We have grown a lot in the last 4 years and the work load is pushing the limits of what our 核心 开发者 can do. 开源 burn out is very common ([1], [2]) and we want to avoid this by moving most organization and 发布 chores to a paid position. *For more background on these topics, check out [HASS Podcast 15](https://hasspodcast.io/ha015/).* [1]: https://nolanlawson.com/2017/03/05/what-it-feels-like-to-be-an-open-source-maintainer/ [2]: https://kennethreitz.org/essays/2017/01/05/the-reality-of-developer-burnout --- url: /home-assistant/blog/2017-12-17-release-60.md --- # 0.60: Beckhoff/TwinCAT, WebDav, Gearbest, iAlarm 0.60 最大的变化会在另一篇单独的[博客文章](/home-assistant/blog/2017/12/17/introducing-home-assistant-cloud/)中介绍,所以这里我们就简短一些。只提一句:这是 2017 年最后一个版本。2018 年我们会恢复双周发布节奏。 非常感谢所有帮助我们促成这次发布的人。 ## TwinCAT 借助 [@stlehmann] 带来的全新 [ADS(自动化设备规范)][ads docs] 组件,你现在可以将 Home Assistant 接入这种独立于现场总线的接口,而它通常用于运行 TwinCAT 的 Beckhoff 设备之间。 ## WebDav 日历 感谢 [@maxlaverse],Home Assistant 现在已经支持 [WebDav 日历][日历.caldav docs]。 ## 价格追踪 借助新的 `gearbest` 传感器,现在又多了一个可以追踪商品价格的传感器可供使用。 ## 金融信息 Yahoo! 已经停止了他们的金融服务。为了填补这一空缺,我们在这次发布中加入了新的 [`alpha_vantage` 传感器][传感器.alpha_vantage docs],让你可以继续监控股票市场。 ## 新平台 * Add iAlarm support ([@RyuzakiKK] - [#10878]) (new-platform) * Add Alpha Vantage 传感器 ([@fabaff] - [#10873]) ([传感器.alpha\_vantage docs][传感器.alpha_vantage docs]) (new-platform) * Add ADS component ([@stlehmann] - [#10142]) ([ads docs]) ([binary\_sensor.ads docs][binary_sensor.ads docs]) ([灯光.ads docs]) ([传感器.ads docs]) ([开关.ads docs]) (new-platform) * Gearbest 传感器 ([@HerrHofrat] - [#10556]) (new-platform) * Add Ziggo Mediabox XL 媒体播放器 ([@b10m] - [#10514]) ([媒体播放器.ziggo\_mediabox\_xl docs][媒体播放器.ziggo_mediabox_xl docs]) (new-platform) * Meraki AP 设备 tracker ([@masarliev] - [#10971]) ([device\_tracker.meraki docs][device_tracker.meraki docs]) (new-platform) * Added Vera 场景 ([@alanfischer] - [#10424]) ([vera docs]) ([场景.vera docs]) (new-platform) * Add support for Canary component and platforms ([@snjoetw] - [#10306]) ([canary docs]) ([摄像头.canary docs]) ([传感器.canary docs]) (new-platform) * Add support for Logitech UE Smart Radios. ([@GreenTurtwig] - [#10077]) ([媒体播放器.ue\_smart\_radio docs][媒体播放器.ue_smart_radio docs]) (new-platform) * Added support for 遮盖 in tellstick ([@perfalk] - [#10858]) ([tellstick docs]) ([遮盖.tellstick docs]) (new-platform) * Add a caldav 日历 component ([@maxlaverse] - [#10842]) ([日历.caldav docs]) (new-platform) * Refactor hue to split bridge support from 灯光 platform ([@andreacampi] - [#10691]) ([hue docs]) ([灯光.hue docs]) (breaking change) (new-platform) ## 发布 0.60.1 - January 6 * Fix async IO in Sesame 门锁 component. ([@veleek] - [#11054]) ([门锁.sesame docs]) * Fix webdav 日历 schema ([@maxlaverse] - [#11185]) ([日历.caldav docs]) * homematic: add username and 密码 to interface config schema ([@jannau] - [#11214]) ([homematic docs]) * Fix webostv select source ([@OddBloke] - [#11227]) ([媒体播放器.webostv docs]) * Fix detection of if a negative node is in use ([@OverloadUT] - [#11255]) ([binary\_sensor.isy994 docs][binary_sensor.isy994 docs]) * Bugfix homematic available modus ([@pvizeli] - [#11256]) ([homematic docs]) * Support multiple Hue bridges with 灯光 of the same id ([@andreacampi] - [#11259]) ([灯光.hue docs]) * Fix inverted 传感器 on the concord232 二元sensor component ([@CTLS] - [#11261]) ([binary\_sensor.concord232 docs][binary_sensor.concord232 docs]) * Fix handling zero values for state\_on/state\_off ([@ziotibia81] - [#11264]) ([开关.modbus docs]) * Fix allday events in custom\_calendars ([@maxlaverse] - [#11272]) ([日历.caldav docs]) * Fix unpredictable 实体 names in concord232 binary\_sensor ([@rwa] - [#11292]) ([binary\_sensor.concord232 docs][binary_sensor.concord232 docs]) * Fix leak 传感器 always showing Unknown until Wet ([@OverloadUT] - [#11313]) ([binary\_sensor.isy994 docs][binary_sensor.isy994 docs]) * Don't block on 服务 call for alexa ([@pvizeli] - [#11358]) ([alexa.smart\_home docs][alexa.smart_home docs]) * iOS 10 should be served javascript\_version:es5 ([@mnoorenberghe] - [#11387]) ## 如果你需要帮助…… ……欢迎使用我们非常活跃的[论坛](https://community.home-assistant.io/),或者加入我们的[聊天频道](https://discord.gg/c5DvZ4e)。虽然发布说明开放了评论,但我们更推荐你使用前面的社区交流渠道。谢谢。 ## 反馈问题 如果你遇到了此次发布引入的问题,请在我们的 [issue tracker](https://github.com/home-assistant/home-assistant/issues) 中反馈。请确保完整填写 issue 模板中的所有字段。 ## 不向后兼容的变更 * 更新 snips to listen on new MQTT topic and utilize rawValue ([@tschmidty69] - [#11020]) ([snips docs]) (breaking change) * Refactor hue to split bridge support from 灯光 platform ([@andreacampi] - [#10691]) ([hue docs]) ([灯光.hue docs]) (breaking change) (new-platform) * Use luftdaten module ([@fabaff] - [#10970]) ([传感器.luftdaten docs]) (breaking change) * ISY994 传感器 improvements ([@OverloadUT] - [#10805]) ([isy994 docs]) ([binary\_sensor.isy994 docs][binary_sensor.isy994 docs]) (breaking change) * Homematic next ([@pvizeli] - [#11156]) ([homematic docs]) (breaking change) ## 全部变更 * 更新 ecobee 版本 to fix stack-trace issue ([@PhracturedBlue] - [#10894]) ([ecobee docs]) * Pybotvac multi ([@raymccarthy] - [#10843]) ([neato docs]) * More declarative timeout syntax for manual 报警 control 面板. ([@bonzini] - [#10738]) ([alarm\_control\_panel.manual docs][alarm_control_panel.manual docs]) ([alarm\_control\_panel.manual\_mqtt docs][alarm_control_panel.manual_mqtt docs]) * Unpacking RESTful 传感器 JSON results into 属性. ([@nickovs] - [#10753]) ([传感器.rest docs]) * Bump dev to 0.60.0.dev0 ([@fabaff] - [#10912]) * 更新 eliqonline.py ([@molobrakos] - [#10914]) ([传感器.eliqonline docs]) * Add iAlarm support ([@RyuzakiKK] - [#10878]) (new-platform) * Correction of Samsung Power OFF behaviour ([@RiRomain] - [#10907]) ([媒体播放器.samsungtv docs]) * Add Alpha Vantage 传感器 ([@fabaff] - [#10873]) ([传感器.alpha\_vantage docs][传感器.alpha_vantage docs]) (new-platform) * Don't repeat getting receiver name on each 更新 / pushed to denonavr 0.5.5 ([@scarface-4711] - [#10915]) ([媒体播放器.denonavr docs]) * Add Min and Event Count Metrics To Prometheus ([@bah2830] - [#10530]) ([prometheus docs]) * 更新 coveragerc ([@balloob] - [#10931]) * Report availability of TP-Link smart sockets ([@DanNixon] - [#10933]) ([开关.tplink docs]) * Set percent unit for battery level so that history displays properly; edited variable name for consistency ([@nbougues] - [#10932]) ([传感器.tesla docs]) * Export 温控 status and target temperature to Prometheus ([@hudashot] - [#10919]) ([prometheus docs]) * Tado ignore invalid 设备 ([@dasos] - [#10927]) ([温控.tado docs]) * don't ignore voltage data if 传感器 data changed ([@PaulAnnekov] - [#10925]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * Add ADS component ([@stlehmann] - [#10142]) ([ads docs]) ([binary\_sensor.ads docs][binary_sensor.ads docs]) ([灯光.ads docs]) ([传感器.ads docs]) ([开关.ads docs]) (new-platform) * Gearbest 传感器 ([@HerrHofrat] - [#10556]) (new-platform) * Add Ziggo Mediabox XL 媒体播放器 ([@b10m] - [#10514]) ([媒体播放器.ziggo\_mediabox\_xl docs][媒体播放器.ziggo_mediabox_xl docs]) (new-platform) * Generic thermostat initial\_operation\_mode ([@ziotibia81] - [#10690]) ([温控.generic\_thermostat docs][温控.generic_thermostat docs]) * Use new build path for dev translations ([@armills] - [#10937]) * Add option to set default hide if away for new 设备 ([@masarliev] - [#10762]) ([device\_tracker docs][device_tracker docs]) * Allow disabling the LEDs on TP-Link smart plugs ([@DanNixon] - [#10980]) ([开关.tplink docs]) * Meraki AP 设备 tracker ([@masarliev] - [#10971]) ([device\_tracker.meraki docs][device_tracker.meraki docs]) (new-platform) * 更新 tradfri.py ([@pvizeli] - [#10991]) ([灯光.tradfri docs]) * webostv: Ensure source exists before use ([@OddBloke] - [#10959]) ([媒体播放器.webostv docs]) * Ensure Docker 脚本 files uses LF line endings to support Docker for Windows. ([@EarthlingRich] - [#10067]) * Added Vera 场景 ([@alanfischer] - [#10424]) ([vera docs]) ([场景.vera docs]) (new-platform) * Fix Egardia 报警 status shown as unknown after 重启 ([@jeroenterheerdt] - [#11010]) ([alarm\_control\_panel.egardia docs][alarm_control_panel.egardia docs]) * Handle OSError when forcibly turning off 媒体播放器.samsungtv ([@lwis] - [#10997]) ([媒体播放器.samsungtv docs]) * Shuffle support in Sonos ([@mar-schmidt] - [#10875]) ([媒体播放器.sonos docs]) * Add support for Canary component and platforms ([@snjoetw] - [#10306]) ([canary docs]) ([摄像头.canary docs]) ([传感器.canary docs]) (new-platform) * Ignore Sonos players with unknown hostnames ([@amelchio] - [#11013]) * Support LIFX Mini products ([@amelchio] - [#10996]) ([灯光.lifx docs]) * 更新 snips to listen on new MQTT topic and utilize rawValue ([@tschmidty69] - [#11020]) ([snips docs]) (breaking change) * Change default js 版本 to auto ([@andrey-git] - [#10999]) * Serialize mochad requests ([@mtreinish] - [#11029]) ([mochad docs]) ([灯光.mochad docs]) ([开关.mochad docs]) * In dev mode expose only relevant sources ([@andrey-git] - [#11026]) * Added force\_update for REST 传感器 ([@foxel] - [#11016]) ([传感器.miflora docs]) ([传感器.MQTT docs]) ([传感器.rest docs]) * Add support for Logitech UE Smart Radios. ([@GreenTurtwig] - [#10077]) ([媒体播放器.ue\_smart\_radio docs][媒体播放器.ue_smart_radio docs]) (new-platform) * Make 通知.html5 depend on config ([@balloob] - [#11052]) ([通知.html5 docs]) * This change fixes the 错误 `OSError: [WinError 193]` on Windows debuggers (i.e., PyCharm) ([@tringler] - [#11034]) * Added support for 遮盖 in tellstick ([@perfalk] - [#10858]) ([tellstick docs]) ([遮盖.tellstick docs]) (new-platform) * Add a caldav 日历 component ([@maxlaverse] - [#10842]) ([日历.caldav docs]) (new-platform) * Add GPS coords to meraki ([@addelovein] - [#10998]) ([device\_tracker.meraki docs][device_tracker.meraki docs]) * Refactor hue to split bridge support from 灯光 platform ([@andreacampi] - [#10691]) ([hue docs]) ([灯光.hue docs]) (breaking change) (new-platform) * add custom bypass status to total connect ([@uchagani] - [#11042]) ([alarm\_control\_panel.totalconnect docs][alarm_control_panel.totalconnect docs]) * Volvo on call: Optional use of Scandinavian miles. Also add average fuel consumption property ([@molobrakos] - [#11051]) ([volvooncall docs]) ([传感器.volvooncall docs]) * Allow tradfri to read the available 状态 of the 设备 ([@pvizeli] - [#11056]) ([灯光.tradfri docs]) * 升级 aiohttp to 2.3.6 ([@fabaff] - [#11079]) * 升级 yarl to 0.16.0 ([@fabaff] - [#11078]) * 升级 psutil to 5.4.2 ([@fabaff] - [#11083]) ([传感器.systemmonitor docs]) * 升级 youtube\_dl to 2017.12.10 ([@fabaff] - [#11080]) ([media\_extractor docs][media_extractor docs]) * 升级 shodan to 1.7.7 ([@fabaff] - [#11084]) ([传感器.shodan docs]) * 更新 tellcore-net to 0.4 ([@pvizeli] - [#11087]) ([tellstick docs]) * Bump pymusiccast to 版本 0.1.6 ([@jalmeroth] - [#11091]) ([媒体播放器.yamaha\_musiccast docs][媒体播放器.yamaha_musiccast docs]) * Use luftdaten module ([@fabaff] - [#10970]) ([传感器.luftdaten docs]) (breaking change) * Bump pyatv to 0.3.9 ([@postlund] - [#11104]) ([apple\_tv docs][apple_tv docs]) * Report availability for TP-Link smart bulbs ([@DanNixon] - [#10976]) ([灯光.tplink docs]) * Fix incorrect comment. ([@emosenkis] - [#11111]) * 更新 Warrant ([@balloob] - [#11101]) ([cloud docs]) * Fixed typo in 自动化.py ([@ryanm101] - [#11116]) ([config docs]) * Add media position properties ([@pschmitt] - [#10076]) * 更新 pyripple ([@nkgilley] - [#11122]) ([传感器.ripple docs]) * Skip HASS emulated Hue bridges from detection. ([@andreacampi] - [#11128]) ([hue docs]) * Always consume the no\_throttle keyword argument. ([@andreacampi] - [#11126]) * Add problem 设备 class ([@armills] - [#11130]) ([binary\_sensor docs][binary_sensor docs]) * set default utc offset to 0 ([@pollett] - [#11114]) ([传感器.efergy docs]) * Allow using more than one keyboard 遥控器 ([@BryanJacobs] - [#11061]) ([keyboard\_remote docs][keyboard_remote docs]) * ISY994 传感器 improvements ([@OverloadUT] - [#10805]) ([isy994 docs]) ([binary\_sensor.isy994 docs][binary_sensor.isy994 docs]) (breaking change) * Disable html5 通知 dependency ([@balloob] - [#11135]) ([通知.html5 docs]) * 升级 Homematic ([@danielperna84] - [#11149]) ([homematic docs]) * Fix X10 commands for mochad 灯光 打开 ([@mtreinish] - [#11146]) ([灯光.mochad docs]) * Homematic next ([@pvizeli] - [#11156]) ([homematic docs]) (breaking change) * Resolve hostnames ([@pvizeli] - [#11160]) ([homematic docs]) * Perform logbook filtering on the worker Thread ([@armills] - [#11161]) ([logbook docs]) * Don't connect to cloud if subscription expired ([@balloob] - [#11163]) ([cloud docs]) ([cloud.const docs]) * Add 安装 mode to homematic ([@pvizeli] - [#11164]) ([homematic docs]) * convert alarmdecoder interface from async to sync ([@PhracturedBlue] - [#11168]) ([alarmdecoder docs]) * Remove logging ([@cmsimike] - [#11173]) ([传感器.octoprint docs]) * Revbump to SoCo 0.13 and add support for Night Sound and Speech Enhancement. ([@rbdixon] - [#10765]) ([媒体播放器.sonos docs]) [#10067]: https://github.com/home-assistant/home-assistant/pull/10067 [#10076]: https://github.com/home-assistant/home-assistant/pull/10076 [#10077]: https://github.com/home-assistant/home-assistant/pull/10077 [#10142]: https://github.com/home-assistant/home-assistant/pull/10142 [#10306]: https://github.com/home-assistant/home-assistant/pull/10306 [#10424]: https://github.com/home-assistant/home-assistant/pull/10424 [#10514]: https://github.com/home-assistant/home-assistant/pull/10514 [#10530]: https://github.com/home-assistant/home-assistant/pull/10530 [#10556]: https://github.com/home-assistant/home-assistant/pull/10556 [#10690]: https://github.com/home-assistant/home-assistant/pull/10690 [#10691]: https://github.com/home-assistant/home-assistant/pull/10691 [#10738]: https://github.com/home-assistant/home-assistant/pull/10738 [#10753]: https://github.com/home-assistant/home-assistant/pull/10753 [#10762]: https://github.com/home-assistant/home-assistant/pull/10762 [#10765]: https://github.com/home-assistant/home-assistant/pull/10765 [#10805]: https://github.com/home-assistant/home-assistant/pull/10805 [#10842]: https://github.com/home-assistant/home-assistant/pull/10842 [#10843]: https://github.com/home-assistant/home-assistant/pull/10843 [#10858]: https://github.com/home-assistant/home-assistant/pull/10858 [#10873]: https://github.com/home-assistant/home-assistant/pull/10873 [#10875]: https://github.com/home-assistant/home-assistant/pull/10875 [#10878]: https://github.com/home-assistant/home-assistant/pull/10878 [#10894]: https://github.com/home-assistant/home-assistant/pull/10894 [#10907]: https://github.com/home-assistant/home-assistant/pull/10907 [#10912]: https://github.com/home-assistant/home-assistant/pull/10912 [#10914]: https://github.com/home-assistant/home-assistant/pull/10914 [#10915]: https://github.com/home-assistant/home-assistant/pull/10915 [#10919]: https://github.com/home-assistant/home-assistant/pull/10919 [#10925]: https://github.com/home-assistant/home-assistant/pull/10925 [#10927]: https://github.com/home-assistant/home-assistant/pull/10927 [#10931]: https://github.com/home-assistant/home-assistant/pull/10931 [#10932]: https://github.com/home-assistant/home-assistant/pull/10932 [#10933]: https://github.com/home-assistant/home-assistant/pull/10933 [#10937]: https://github.com/home-assistant/home-assistant/pull/10937 [#10959]: https://github.com/home-assistant/home-assistant/pull/10959 [#10970]: https://github.com/home-assistant/home-assistant/pull/10970 [#10971]: https://github.com/home-assistant/home-assistant/pull/10971 [#10976]: https://github.com/home-assistant/home-assistant/pull/10976 [#10980]: https://github.com/home-assistant/home-assistant/pull/10980 [#10991]: https://github.com/home-assistant/home-assistant/pull/10991 [#10996]: https://github.com/home-assistant/home-assistant/pull/10996 [#10997]: https://github.com/home-assistant/home-assistant/pull/10997 [#10998]: https://github.com/home-assistant/home-assistant/pull/10998 [#10999]: https://github.com/home-assistant/home-assistant/pull/10999 [#11010]: https://github.com/home-assistant/home-assistant/pull/11010 [#11013]: https://github.com/home-assistant/home-assistant/pull/11013 [#11016]: https://github.com/home-assistant/home-assistant/pull/11016 [#11020]: https://github.com/home-assistant/home-assistant/pull/11020 [#11026]: https://github.com/home-assistant/home-assistant/pull/11026 [#11029]: https://github.com/home-assistant/home-assistant/pull/11029 [#11034]: https://github.com/home-assistant/home-assistant/pull/11034 [#11042]: https://github.com/home-assistant/home-assistant/pull/11042 [#11051]: https://github.com/home-assistant/home-assistant/pull/11051 [#11052]: https://github.com/home-assistant/home-assistant/pull/11052 [#11056]: https://github.com/home-assistant/home-assistant/pull/11056 [#11061]: https://github.com/home-assistant/home-assistant/pull/11061 [#11078]: https://github.com/home-assistant/home-assistant/pull/11078 [#11079]: https://github.com/home-assistant/home-assistant/pull/11079 [#11080]: https://github.com/home-assistant/home-assistant/pull/11080 [#11083]: https://github.com/home-assistant/home-assistant/pull/11083 [#11084]: https://github.com/home-assistant/home-assistant/pull/11084 [#11087]: https://github.com/home-assistant/home-assistant/pull/11087 [#11091]: https://github.com/home-assistant/home-assistant/pull/11091 [#11101]: https://github.com/home-assistant/home-assistant/pull/11101 [#11104]: https://github.com/home-assistant/home-assistant/pull/11104 [#11111]: https://github.com/home-assistant/home-assistant/pull/11111 [#11114]: https://github.com/home-assistant/home-assistant/pull/11114 [#11116]: https://github.com/home-assistant/home-assistant/pull/11116 [#11122]: https://github.com/home-assistant/home-assistant/pull/11122 [#11126]: https://github.com/home-assistant/home-assistant/pull/11126 [#11128]: https://github.com/home-assistant/home-assistant/pull/11128 [#11130]: https://github.com/home-assistant/home-assistant/pull/11130 [#11135]: https://github.com/home-assistant/home-assistant/pull/11135 [#11146]: https://github.com/home-assistant/home-assistant/pull/11146 [#11149]: https://github.com/home-assistant/home-assistant/pull/11149 [#11156]: https://github.com/home-assistant/home-assistant/pull/11156 [#11160]: https://github.com/home-assistant/home-assistant/pull/11160 [#11161]: https://github.com/home-assistant/home-assistant/pull/11161 [#11163]: https://github.com/home-assistant/home-assistant/pull/11163 [#11164]: https://github.com/home-assistant/home-assistant/pull/11164 [#11168]: https://github.com/home-assistant/home-assistant/pull/11168 [#11173]: https://github.com/home-assistant/home-assistant/pull/11173 [@BryanJacobs]: https://github.com/BryanJacobs [@DanNixon]: https://github.com/DanNixon [@GreenTurtwig]: https://github.com/GreenTurtwig [@HerrHofrat]: https://github.com/HerrHofrat [@OddBloke]: https://github.com/OddBloke [@OverloadUT]: https://github.com/OverloadUT [@PaulAnnekov]: https://github.com/PaulAnnekov [@PhracturedBlue]: https://github.com/PhracturedBlue [@EarthlingRich]: https://github.com/EarthlingRich [@RiRomain]: https://github.com/RiRomain [@RyuzakiKK]: https://github.com/RyuzakiKK [@addelovein]: https://github.com/addelovein [@alanfischer]: https://github.com/alanfischer [@amelchio]: https://github.com/amelchio [@andreacampi]: https://github.com/andreacampi [@andrey-git]: https://github.com/andrey-git [@armills]: https://github.com/armills [@b10m]: https://github.com/b10m [@bah2830]: https://github.com/bah2830 [@balloob]: https://github.com/balloob [@bonzini]: https://github.com/bonzini [@cmsimike]: https://github.com/cmsimike [@danielperna84]: https://github.com/danielperna84 [@dasos]: https://github.com/dasos [@emosenkis]: https://github.com/emosenkis [@fabaff]: https://github.com/fabaff [@foxel]: https://github.com/foxel [@hudashot]: https://github.com/hudashot [@jalmeroth]: https://github.com/jalmeroth [@jeroenterheerdt]: https://github.com/jeroenterheerdt [@lwis]: https://github.com/lwis [@mar-schmidt]: https://github.com/mar-schmidt [@masarliev]: https://github.com/masarliev [@maxlaverse]: https://github.com/maxlaverse [@molobrakos]: https://github.com/molobrakos [@mtreinish]: https://github.com/mtreinish [@nbougues]: https://github.com/nbougues [@nickovs]: https://github.com/nickovs [@nkgilley]: https://github.com/nkgilley [@perfalk]: https://github.com/perfalk [@pollett]: https://github.com/pollett [@postlund]: https://github.com/postlund [@pschmitt]: https://github.com/pschmitt [@pvizeli]: https://github.com/pvizeli [@raymccarthy]: https://github.com/raymccarthy [@rbdixon]: https://github.com/rbdixon [@ryanm101]: https://github.com/ryanm101 [@scarface-4711]: https://github.com/scarface-4711 [@snjoetw]: https://github.com/snjoetw [@stlehmann]: https://github.com/stlehmann [@tringler]: https://github.com/tringler [@tschmidty69]: https://github.com/tschmidty69 [@uchagani]: https://github.com/uchagani [@ziotibia81]: https://github.com/ziotibia81 [ads docs]: /integrations/ads/ [alarm_control_panel.egardia docs]: /integrations/egardia [alarm_control_panel.manual docs]: /integrations/manual [alarm_control_panel.manual_mqtt docs]: /integrations/manual_mqtt/ [alarm_control_panel.totalconnect docs]: /integrations/totalconnect [alarmdecoder docs]: /integrations/alarmdecoder/ [apple_tv docs]: /integrations/apple_tv/ [binary_sensor docs]: /integrations/binary_sensor/ [binary_sensor.ads docs]: /integrations/ads#binary-传感器 [binary_sensor.isy994 docs]: /integrations/isy994 [日历.caldav docs]: /integrations/caldav [摄像头.canary docs]: /integrations/canary#摄像头 [canary docs]: /integrations/canary/ [温控.generic_thermostat docs]: /integrations/generic_thermostat [温控.tado docs]: /integrations/tado [cloud docs]: /integrations/cloud/ [cloud.const docs]: /integrations/cloud/ [config docs]: /integrations/config [遮盖.tellstick docs]: /integrations/tellstick#遮盖 [device_tracker docs]: /integrations/device_tracker/ [device_tracker.meraki docs]: /integrations/meraki [ecobee docs]: /integrations/ecobee/ [homematic docs]: /integrations/homematic/ [hue docs]: /integrations/hue/ [isy994 docs]: /integrations/isy994/ [keyboard_remote docs]: /integrations/keyboard_remote/ [灯光.ads docs]: /integrations/ads#灯光 [灯光.hue docs]: /integrations/hue [灯光.lifx docs]: /integrations/lifx [灯光.mochad docs]: /integrations/mochad#灯光 [灯光.tplink docs]: /integrations/tplink [灯光.tradfri docs]: /integrations/tradfri [logbook docs]: /integrations/logbook/ [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.denonavr docs]: /integrations/denonavr/ [媒体播放器.samsungtv docs]: /integrations/samsungtv [媒体播放器.sonos docs]: /integrations/sonos [媒体播放器.ue_smart_radio docs]: /integrations/ue_smart_radio [媒体播放器.webostv docs]: /integrations/webostv#media-player [媒体播放器.yamaha_musiccast docs]: /integrations/yamaha_musiccast/ [媒体播放器.ziggo_mediabox_xl docs]: /integrations/ziggo_mediabox_xl [mochad docs]: /integrations/mochad/ [neato docs]: /integrations/neato/ [通知.html5 docs]: /integrations/html5 [prometheus docs]: /integrations/prometheus/ [场景.vera docs]: /integrations/vera [传感器.ads docs]: /integrations/ads#传感器 [传感器.alpha_vantage docs]: /integrations/alpha_vantage [传感器.canary docs]: /integrations/canary#传感器 [传感器.efergy docs]: /integrations/efergy [传感器.eliqonline docs]: /integrations/eliqonline [传感器.luftdaten docs]: /integrations/luftdaten#传感器 [传感器.miflora docs]: /integrations/miflora [传感器.MQTT docs]: /integrations/传感器.MQTT/ [传感器.octoprint docs]: /integrations/octoprint#传感器 [传感器.rest docs]: /integrations/rest [传感器.ripple docs]: /integrations/ripple [传感器.shodan docs]: /integrations/shodan [传感器.systemmonitor docs]: /integrations/systemmonitor [传感器.tesla docs]: /integrations/tesla [传感器.volvooncall docs]: /integrations/volvooncall [snips docs]: /integrations/snips/ [开关.ads docs]: /integrations/ads#开关 [开关.mochad docs]: /integrations/mochad#开关 [开关.tplink docs]: /integrations/tplink [tellstick docs]: /integrations/tellstick/ [vera docs]: /integrations/vera/ [volvooncall docs]: /integrations/volvooncall/ [xiaomi_aqara docs]: /integrations/xiaomi_aqara/ [#11054]: https://github.com/home-assistant/home-assistant/pull/11054 [#11185]: https://github.com/home-assistant/home-assistant/pull/11185 [#11214]: https://github.com/home-assistant/home-assistant/pull/11214 [#11227]: https://github.com/home-assistant/home-assistant/pull/11227 [#11255]: https://github.com/home-assistant/home-assistant/pull/11255 [#11256]: https://github.com/home-assistant/home-assistant/pull/11256 [#11259]: https://github.com/home-assistant/home-assistant/pull/11259 [#11261]: https://github.com/home-assistant/home-assistant/pull/11261 [#11264]: https://github.com/home-assistant/home-assistant/pull/11264 [#11272]: https://github.com/home-assistant/home-assistant/pull/11272 [#11292]: https://github.com/home-assistant/home-assistant/pull/11292 [#11313]: https://github.com/home-assistant/home-assistant/pull/11313 [#11358]: https://github.com/home-assistant/home-assistant/pull/11358 [#11387]: https://github.com/home-assistant/home-assistant/pull/11387 [@CTLS]: https://github.com/CTLS [@OddBloke]: https://github.com/OddBloke [@OverloadUT]: https://github.com/OverloadUT [@andreacampi]: https://github.com/andreacampi [@jannau]: https://github.com/jannau [@maxlaverse]: https://github.com/maxlaverse [@mnoorenberghe]: https://github.com/mnoorenberghe [@pvizeli]: https://github.com/pvizeli [@rwa]: https://github.com/rwa [@veleek]: https://github.com/veleek [@ziotibia81]: https://github.com/ziotibia81 [alexa.smart_home docs]: /integrations/alexa.smart_home/ [binary_sensor.concord232 docs]: /integrations/concord232#binary-传感器 [binary_sensor.isy994 docs]: /integrations/isy994 [日历.caldav docs]: /integrations/caldav [homematic docs]: /integrations/homematic/ [灯光.hue docs]: /integrations/hue [门锁.sesame docs]: /integrations/sesame [媒体播放器.webostv docs]: /integrations/webostv#media-player [开关.modbus docs]: /integrations/开关.modbus/ --- url: /home-assistant/blog/2017-12-28-thank-you.md --- # Thank You 2017 is almost over and this means it's time to do a little recap of our 2017. This was a great year for Home Assistant. Again, we were able to stick to our bi-weekly 发布 cycle. There were 25 releases over the year and each 发布 included the work of around 60 contributors. We got 10.000 stars on [GitHub], reached 10.000 commits in the main repo (over 4300 were made in 2017), got a [Thomas-Krenn award], participated in [Hacktoberfest], we have now almost 1000 集成 (the exact number is 938), we [moved to Discord] and we are up to over 2 million pageviews per month on our forum. Beside that we announced the [Home Assistant cloud] and have regular [Home Assistant Podcasts]. We also do not want to forget to mention [Hass.io] and all the great Hass.io 插件. Uff, what a year...Thank you, dear community for being so helpful, supportive and awesome 🙇. A very big thanks goes out to the 开发者 of the Python language and all the 开源 libraries and tools that Home Assistant depends on. You are the foundation for our success and all of you can be proud of yourself. We would also like to thanks all the companies that offer their 服务 for free to 开源 projects. Without these we would not be able to operate at our speed or scale. Thank you [GitHub], [TravisCI], [CloudFlare], [Discord] and [Discourse]! Some of us are taking a break and spending some quality time with family and loved ones. Stay tuned for more Home Assistant awesomeness in 2018. We will keep the pace but first: Happy New Year! \-- Home Assistant Organization [CloudFlare]: https://CloudFlare.com [Discord]: https://discordapp.com [Discourse]: https://Discourse.com [forum]: https://community.home-assistant.io [GitHub]: https://GitHub.com [Hacktoberfest]: /博客/2017/11/04/发布-57/#hacktoberfest [Hass.io]: /hassio/ [Home Assistant cloud]: /博客/2017/12/17/introducing-home-assistant-cloud/ [Home Assistant Podcasts]: https://hasspodcast.io/ [moved to Discord]: /博客/2017/07/03/home-assistant-is-moving-to-discord/ [Thomas-Krenn award]: /博客/2017/04/01/thomas-krenn-award/ [TravisCI]: https://Travis-ci.org --- url: /home-assistant/blog/2018-01-14-release-61.md --- # 0.61:Coinbase、Discogs、iGlo、Sochain 这次发布有将近 100 位贡献者参与 🎉 这就是跳过一次发布后的“能量爆发”。虽然稍微晚了一点,但还是要说一声“新年快乐”,欢迎来到 2018 年的第一个版本:0.61。 本次发布包含一些不向后兼容的变更。如果你在升级后遇到问题,请务必查看下方对应章节。 ## 助手配置 我们在 Google Assistant 和 Alexa 集成的基础配置上犯了一个错误:之前把配置存放在 `customize` 里。这个位置并不合适,所以现在已经迁移到各自组件下方。如何迁移请查看不向后兼容变更章节。 ## Hass.io 更新 [@pvizeli] 通过新增服务让 Hass.io 的快照创建与恢复变得更简单。这样一来,你就能轻松自动化夜间快照创建。更新器也已修复,现在会正确提示可用的 Hass.io 新版本。 ## 加载速度提升 [@amelchio] 让 Home Assistant 启动速度 *更快* 了。现在所有服务描述都会在前端需要时才加载,而不是在启动阶段全部加载。为此我们加强了服务命名规范检查,并修复了少数不符合规范的平台: ```text todoist.new_task -> calendar.todoist_new_task snapcast.snapcast_snapshot -> media_player.snapcast_snapshot snapcast.snapcast_restore -> media_player.snapcast_restore mopar.remote_command -> sensor.mopar_remote_command broadlink.learn_command_192_168_0_107 -> switch.broadlink_learn_command_192_168_0_107 broadlink.send_packet_192_168_0_107 -> switch.broadlink_send_packet_192_168_0_107 ``` ## 新平台 * Add Discogs 传感器 platform ([@thibmaek] - [#10957]) ([传感器.discogs docs]) (new-platform) * Greenwave Reality (TCP Connected) Lighting Component ([@dfiel] - [#11282]) ([灯光.greenwave docs]) (new-platform) * Added rainsensor ([@jbarrancos] - [#11023]) ([rainbird docs]) ([传感器.rainbird docs]) ([开关.rainbird docs]) (new-platform) * Sochain cryptocurrency 传感器 ([@Klathmon] - [#11335]) ([传感器.sochain docs]) (new-platform) * Support for EcoNet 热水器 ([@w1ll1am23] - [#11260]) ([温控.econet docs]) (new-platform) * Add deCONZ component ([@Kane610] - [#10321]) ([deconz docs]) ([binary\_sensor.deconz docs][binary_sensor.deconz docs]) ([灯光.deconz docs]) ([传感器.deconz docs]) (new-platform) * Added new 温控 component from Daikin ([@rofrantz] - [#10983]) ([温控.daikin docs]) (new-platform) * Add Touchline 温控 platform ([@abondoe] - [#10547]) ([温控.touchline docs]) (new-platform) * Add new iGlo component ([@jesserockz] - [#11171]) ([灯光.iglo docs]) (new-platform) * Add Dark Sky 天气 component ([@DanNixon] - [#11435]) ([天气.darksky docs]) (new-platform) * Coinbase.com 传感器 platform ([@nkgilley] - [#11036]) ([coinbase docs]) ([传感器.coinbase docs]) (new-platform) ## 发布 0.61.1 - January 16 * Fix zha color probe ([@rcloran] - [#11670]) ([zha docs]) ([灯光.zha docs]) * Move several local 服务 to their right domain ([@amelchio] - [#11677]) ([日历.todoist docs]) ([媒体播放器.snapcast docs]) ([媒体播放器.soundtouch docs]) ([开关.broadlink docs]) ([开关.scsgate docs]) (breaking change) * Rfxtrx fix ([@danielhiversen] - [#11678]) ([rfxtrx docs]) ([binary\_sensor.rfxtrx docs][binary_sensor.rfxtrx docs]) * History order bugfix and opt-in option ([@rwa] - [#11686]) ([history docs]) * Fix purge with MariaDB / MySQL ([@tinloaf] - [#11713]) ## 需要帮助? 如果你需要帮助,欢迎前往我们非常活跃的 [论坛](https://community.home-assistant.io/),或加入 [聊天频道](https://discord.gg/c5DvZ4e)。发布说明虽然开放评论,但我们更推荐你使用前面的社区渠道。谢谢! ## 问题反馈 如果你遇到由本次发布引入的问题,请在我们的 [issue tracker](https://github.com/home-assistant/home-assistant/issues) 提交反馈。请确保完整填写 issue 模板中的所有字段。 ## 不向后兼容的变更 * Threshold 二元传感器现已支持区间范围,也就是说你现在可以同时设置 `upper` 和 `lower`。([@DanNixon] - [#11110]) ([binary\_sensor.threshold docs][binary_sensor.threshold docs]) (breaking change) * Steam game 平台有以下变更: * 如果当前没有正在游玩的游戏,`device_state_attributes` 中将不再设置 `game` 属性;也就是说不会再传入字符串 `"None"`,而是直接不再提供这个属性。 * 状态值现在统一使用小写蛇形命名。 * `Play` 和 `Trade` 状态已分别重命名为 `looking_to_play` 和 `looking_to_trade`。 ([@frwickst] - [#11182]) ([传感器.steam\_online docs][传感器.steam_online docs]) (breaking change) * [`tile`][device_tracker.tile docs] 平台现在默认只显示处于活动状态的 Tile;如果想显示全部 Tile(包括过期或未激活的),需要将 `show_inactive` 设为 `true`。同时移除了以下状态属性:`last_seen` 和 `last_updated`。([@bachya] - [#11172]) ([device\_tracker.tile docs][device_tracker.tile docs]) (breaking change) * `isy994` 组件移除了 `hidden_string` 功能。此前,如果 ISY 设备名称或文件夹路径中包含某个已配置字符串,就可以让对应实体在 Home Assistant 中“隐藏”。之所以移除,是因为如今隐藏设备应通过 customization 功能完成。 请注意,这项功能被新的 `ignore_string` 配置项取代了。现在,匹配该字符串的设备会被 Home Assistant 彻底忽略,不会再被导入为 Home Assistant 设备。如果你的 ISY 里有一些在 Hass 中完全没用的节点(比如红外发射器节点),这个选项会非常有帮助。([@OverloadUT] - [#11243]) ([isy994 docs]) ([binary\_sensor.isy994 docs][binary_sensor.isy994 docs]) ([遮盖.isy994 docs]) ([风扇.isy994 docs]) ([灯光.isy994 docs]) ([门锁.isy994 docs]) ([传感器.isy994 docs]) ([开关.isy994 docs]) (breaking change) * [`egardia` 报警面板][alarm_control_panel.egardia docs] 平台不再需要用户额外运行一个单独的 Egardiaserver 组件,现在它也可以直接运行在 HASS.io 上。([@jeroenterheerdt] - [#11344]) ([alarm\_control\_panel.egardia docs][alarm_control_panel.egardia docs]) (breaking change) * DoorBird 集成中的二元传感器平台已被删除,因此请从你的 `binary_sensor` 配置中移除 DoorBird。改为将 `doorbird` 组件的 `doorbell_events` 选项设为 `true`。同时,摄像头组件中的 `last_visitor` 选项也已移除,因为它现在会始终作为实体自动添加。([@Klikini] - [#11193]) ([摄像头.doorbird docs]) (breaking change) * The following 属性 of the TP-Link 开关 and 灯光 platform have been renamed: * 灯光: `current_consumption` -> `current_power_w`, `daily_consumption` -> `daily_energy_kwh` and `monthly_consumption` -> `monthly_energy_kwh` * 开关: `current` -> `current_a`, `current_consumption` -> `current_power_w`, `total_consumption` -> `total_energy_kwh` and `daily_consumption` -> `today_energy_kwh` ([@DanNixon] - [#10979]) ([灯光.tplink docs]) ([开关.tplink docs]) (breaking change) * Move IMAP Email Content body to an 属性 ([@notoriousbdg] - [#11096]) ([传感器.imap\_email\_content docs][传感器.imap_email_content docs]) (breaking change) * 自动化 which were using `state` that was returning `target_temperature` of the `netatmo` 温控 platform needs an 更新. ([@ciotlosm] - [#11345]) ([温控.netatmo docs]) (breaking change) * The default availability payloads for the `MQTT` 开关 platform have changed from "ON" and "OFF" to "online" and "offline" (in order to match the majority of MQTT platforms that already supported availability reporting). ([@DanNixon] - [#11336]) (breaking change) * Customizations for how 实体 are exposed to Alexa are no longer set via `customize`. Instead they are set via the 配置 of the cloud component: ```yaml cloud: alexa: entity_config: switch.kitchen: name: "Name for Alexa" description: "Description for Alexa" display_categories: "LIGHT" ``` ([@balloob] - [#11461]) ([cloud docs]) ([alexa.smart\_home docs][alexa.smart_home docs]) (breaking change) * The extension of the `alpha_vantage` requires an 更新 of the 配置 as now are exchange data available as well. ([@ChristianKuehnel] - [#11427]) ([传感器.alpha\_vantage docs][传感器.alpha_vantage docs]) (breaking change) * The `prometheus` component now supports pushing all 传感器 and fixes wrong metrics. If may require that you 更新 your 配置. ([@michaelkuty] - [#11159]) ([prometheus docs]) (breaking change) * Insteon local 设备 will now use their address as the `entity_id` and `name`. The friendly name can be customized using the [standard customization configuration](/home-assistant/docs/configuration/customizing-devices/index.md). ([@camrun91] - [#11088]) ([insteon\_local docs][insteon_local docs]) ([风扇.insteon\_local docs][风扇.insteon_local docs]) ([灯光.insteon\_local docs][灯光.insteon_local docs]) ([开关.insteon\_local docs][开关.insteon_local docs]) (breaking change) * Google Assistant is no longer configured via `customize` but instead has its 配置 under the `google_assistant` entry in your `configuration.yaml`. The 属性 will no longer have to be prefixed with `google_assistant_` either. | Old option | New option | | ---------- | ------------ | | google\_assistant | expose | | aliases | aliases | | google\_assistant\_name | name | | google\_assistant\_type | type | Before: ```yaml homeassistant: customize: switch.kitchen: google_assistant: false google_assistant_name: nice lights google_assistant_type: light aliases: - roof lights google_assistant: ``` After: ```yaml google_assistant: entity_config: switch.kitchen: expose: false alias: "roof lights" name: nice lights type: light ``` ([@balloob] - [#11499]) ([cloud docs]) ([google\_assistant docs][google_assistant docs]) (breaking change) * The `climate.set_aux_heat` 服务 is no longer available for the Sensibo 温控 platform. Now call `climate.turn_on` or `climate.turn_off`. ([@andrey-git] - [#11579]) ([温控.sensibo docs]) (breaking change) * 发布 0.61.0 introduced a lazy 服务 loading strategy that relied on all components and platforms following our naming convention. After the 发布 we realized that not all 服务 did, which have been addressed by this fix. This results in certain 服务 changing names: ```yaml todoist.new_task -> calendar.todoist_new_task snapcast.snapcast_snapshot -> media_player.snapcast_snapshot snapcast.snapcast_restore -> media_player.snapcast_restore mopar.remote_command -> sensor.mopar_remote_command broadlink.learn_command_192_168_0_107 -> switch.broadlink_learn_command_192_168_0_107 broadlink.send_packet_192_168_0_107 -> switch.broadlink_send_packet_192_168_0_107 ``` ([@amelchio] - [#11677]) ([日历.todoist docs]) ([媒体播放器.snapcast docs]) ([媒体播放器.soundtouch docs]) ([开关.broadlink docs]) ([开关.scsgate docs]) (breaking change) ## 全部变更 * Try multiple methods of getting data in asuswrt. ([@PeWu] - [#11140]) ([device\_tracker.asuswrt docs][device_tracker.asuswrt docs]) * Hydroquebec component use now asyncio ([@titilambert] - [#10795]) * Hive Component 发布 Two ([@KJonline] - [#11053]) ([hive docs]) ([温控.hive docs]) ([灯光.hive docs]) * Add Discogs 传感器 platform ([@thibmaek] - [#10957]) ([传感器.discogs docs]) (new-platform) * Fix statistics 传感器 mean and median when only one sample is available. ([@markferry] - [#11180]) ([传感器.statistics docs]) * Extend Threshold 二元sensor to support ranges ([@DanNixon] - [#11110]) ([binary\_sensor.threshold docs][binary_sensor.threshold docs]) (breaking change) * Bump python-miio 版本 ([@djchen] - [#11232]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) ([开关.xiaomi\_miio docs][开关.xiaomi_miio docs]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) * 备份 配置 files before overwriting ([@cgarwood] - [#11216]) * 升级 to new miflora 版本 0.2.0 ([@ChristianKuehnel] - [#11250]) ([传感器.miflora docs]) * Add workaround for running tox on Windows platforms ([@veleek] - [#11188]) * added myself to become code owner for miflora and plant ([@ChristianKuehnel] - [#11251]) * Proper Steam game names and small fixes ([@frwickst] - [#11182]) ([传感器.steam\_online docs][传感器.steam_online docs]) (breaking change) * Bugfix: 10509 - http is hard coded in plex 传感器 ([@ryanm101] - [#11072]) ([传感器.plex docs]) * Adding MotionIP to BinarySensors for HMIP-SMI ([@schnoetz] - [#11268]) ([homematic docs]) * Revert "备份 配置 files before overwriting" ([@pvizeli] - [#11269]) * Functinality to save/恢复 snapshots for monoprice platform ([@etsinko] - [#10296]) ([媒体播放器.monoprice docs]) * Change manifest path to /状态 as this is the path / actually sets. ([@andrey-git] - [#11274]) * Report Sensibo as off when it is off ([@andrey-git] - [#11281]) ([温控.sensibo docs]) * Added 密码 for GPS logger endpoint ([@foxel] - [#11245]) ([device\_tracker.gpslogger docs][device_tracker.gpslogger docs]) * Greenwave Reality (TCP Connected) Lighting Component ([@dfiel] - [#11282]) ([灯光.greenwave docs]) (new-platform) * Adds support for disabled Tiles and automatic session renewal ([@bachya] - [#11172]) ([device\_tracker.tile docs][device_tracker.tile docs]) (breaking change) * Plex refactor ([@ryanm101] - [#11235]) ([媒体播放器.plex docs]) * alexa: Add handling for 遮盖 ([@philk] - [#11242]) ([alexa.smart\_home docs][alexa.smart_home docs]) * Added rainsensor ([@jbarrancos] - [#11023]) ([rainbird docs]) ([传感器.rainbird docs]) ([开关.rainbird docs]) (new-platform) * Store raw 状态 of RF 传感器 from alarmdecoder ([@PhracturedBlue] - [#10841]) ([alarmdecoder docs]) ([binary\_sensor.alarmdecoder docs][binary_sensor.alarmdecoder docs]) * Add Chime status and control to 报警 Decoder component ([@goyney] - [#11271]) ([alarm\_control\_panel.alarmdecoder docs][alarm_control_panel.alarmdecoder docs]) * Better 错误 handling ([@rofrantz] - [#11297]) ([传感器.transmission docs]) ([开关.transmission docs]) * Removed 错误 日志 used as 调试 ([@cmsimike] - [#11301]) ([octoprint docs]) * Huge ISY994 platform cleanup, fixes support for 5.0.10 firmware ([@OverloadUT] - [#11243]) ([isy994 docs]) ([binary\_sensor.isy994 docs][binary_sensor.isy994 docs]) ([遮盖.isy994 docs]) ([风扇.isy994 docs]) ([灯光.isy994 docs]) ([门锁.isy994 docs]) ([传感器.isy994 docs]) ([开关.isy994 docs]) (breaking change) * Add heartbeat to websocket connections ([@balloob] - [#11298]) ([cloud.iot docs]) * Fix typo in bitcoin.py component for mined blocks. ([@awkwardDuck] - [#11318]) ([传感器.bitcoin docs]) * xiaomi\_aqara: Fix 遮盖 never being closed ([@cnrd] - [#11319]) ([遮盖.xiaomi\_aqara docs][遮盖.xiaomi_aqara docs]) * Fix for track\_new\_devices BC ([@masarliev] - [#11202]) ([device\_tracker docs][device_tracker docs]) * 升级 aiohttp\_cors to 0.6.0 ([@fabaff] - [#11310]) ([http docs]) * 升级 pysnmp to 4.4.3 ([@fabaff] - [#11317]) ([device\_tracker.snmp docs][device_tracker.snmp docs]) ([传感器.snmp docs]) ([开关.snmp docs]) * 升级 luftdaten to 0.1.3 ([@fabaff] - [#11316]) ([传感器.luftdaten docs]) * 升级 yahooweather to 0.10 ([@fabaff] - [#11309]) * 升级 distro to 1.2.0 ([@fabaff] - [#11312]) ([updater docs]) * 升级 python-digitalocean to 1.13.2 ([@fabaff] - [#11311]) ([digital\_ocean docs][digital_ocean docs]) * 升级 youtube\_dl to 2017.12.23 ([@fabaff] - [#11308]) ([media\_extractor docs][media_extractor docs]) * 升级 alpha\_vantage to 1.6.0 ([@fabaff] - [#11307]) ([传感器.alpha\_vantage docs][传感器.alpha_vantage docs]) * Bugfix for HA Issue 7292, 9412 - 开关 to gamertag to receive ssl 图像 url ([@ReneNulschDE] - [#11315]) ([传感器.xbox\_live docs][传感器.xbox_live docs]) * closes #11314 by not restricting the voice to anything but a string ([@Human] - [#11326]) ([tts.marytts docs]) * Additional 设备 classes for 二元sensor ([@schmittx] - [#11280]) ([binary\_sensor docs][binary_sensor docs]) * Remove need for separate EgardiaServer 设置 ([@jeroenterheerdt] - [#11344]) ([alarm\_control\_panel.egardia docs][alarm_control_panel.egardia docs]) (breaking change) * Add default names and validation for TP-Link 设备 ([@DanNixon] - [#11346]) ([灯光.tplink docs]) ([开关.tplink docs]) * Sochain cryptocurrency 传感器 ([@Klathmon] - [#11335]) ([传感器.sochain docs]) (new-platform) * pass stops\_at to get\_station\_by\_name ([@ttroy50] - [#11304]) ([传感器.irish\_rail\_transport docs][传感器.irish_rail_transport docs]) * Move data instance to 设置 ([@fabaff] - [#11350]) ([传感器.swiss\_public\_transport docs][传感器.swiss_public_transport docs]) * 更新 modbus.py ([@goldminenine] - [#11238]) ([modbus docs]) * DoorBird feature 更新 ([@Klikini] - [#11193]) ([摄像头.doorbird docs]) (breaking change) * 升级 aiohttp to 2.3.7 ([@fabaff] - [#11329]) * 升级 fuzzywuzzy to 0.16.0 ([@fabaff] - [#11331]) ([conversation docs]) * 升级 pyowm to 2.8.0 ([@fabaff] - [#11332]) ([传感器.openweathermap docs]) ([天气.openweathermap docs]) * 升级 sqlalchemy to 1.2.0 ([@fabaff] - [#11333]) * 升级 mypy to 0.560 ([@fabaff] - [#11334]) * 升级 python-telegram-bot to 9.0.0 ([@fabaff] - [#11341]) ([telegram\_bot docs][telegram_bot docs]) * 升级 youtube\_dl to 2017.12.28 ([@fabaff] - [#11357]) ([media\_extractor docs][media_extractor docs]) * Correct units used in TP-Link energy monioring ([@DanNixon] - [#10979]) ([灯光.tplink docs]) ([开关.tplink docs]) (breaking change) * Add HTTP endpoint for resending email confirmation ([@balloob] - [#11354]) ([cloud.auth\_api docs][cloud.auth_api docs]) ([cloud.http\_api docs][cloud.http_api docs]) * Fix RGB 模板 ordering in MQTT 灯光 ([@DanNixon] - [#11362]) ([灯光.MQTT docs]) * Ping 设备 tracker now respects interval\_seconds ([@tschmidty69] - [#11348]) ([device\_tracker.ping docs][device_tracker.ping docs]) * Fido component use now asyncio ([@titilambert] - [#11244]) ([传感器.fido docs]) * Support for EcoNet 热水器 ([@w1ll1am23] - [#11260]) ([温控.econet docs]) (new-platform) * Remember the Milk - updating and completing tasks ([@ChristianKuehnel] - [#11069]) ([remember\_the\_milk docs][remember_the_milk docs]) * Reverts unit conversions in TP-Link bulb ([@DanNixon] - [#11381]) ([灯光.tplink docs]) * Clean up Google Assistant ([@balloob] - [#11375]) ([google\_assistant docs][google_assistant docs]) ([google\_assistant.http docs][google_assistant.http docs]) ([google\_assistant.smart\_home docs][google_assistant.smart_home docs]) * Adding support for Egardia / Woonveilig 版本 GATE-03 ([@jeroenterheerdt] - [#11397]) ([alarm\_control\_panel.egardia docs][alarm_control_panel.egardia docs]) * Add deCONZ component ([@Kane610] - [#10321]) ([deconz docs]) ([binary\_sensor.deconz docs][binary_sensor.deconz docs]) ([灯光.deconz docs]) ([传感器.deconz docs]) (new-platform) * Fix broken tests ([@balloob] - [#11395]) * 升级 pychromecast to 1.0.3 ([@OttoWinter] - [#11410]) ([媒体播放器.cast docs]) * Bump pywemo to fix request include problems. ([@pavoni] - [#11401]) ([wemo docs]) * 日志 exceptions that happen during 服务 call ([@balloob] - [#11394]) * Move IMAP Email Content body to an 属性 ([@notoriousbdg] - [#11096]) ([传感器.imap\_email\_content docs][传感器.imap_email_content docs]) (breaking change) * 通知 webos timeout 错误 fix ([@masarliev] - [#11027]) ([通知.webostv docs]) * Removed status block to allow https://github.com/home-assistant/home-assistant-polymer/pull/766 with no impact ([@ciotlosm] - [#11345]) ([温控.netatmo docs]) (breaking change) * More support for availability reporting on MQTT components ([@DanNixon] - [#11336]) (breaking change) * Do not purge the most recent 状态 for an 实体 ([@tinloaf] - [#11039]) * Performance optimization of TP-Link 开关 ([@amelchio] - [#11416]) ([开关.tplink docs]) * Fixing OpenWeatherMap 传感器. Current 天气 is 'unknown' if forecast: false. It was reported as #8640. ([@tomaszduda23] - [#11417]) ([传感器.openweathermap docs]) * Silence redundant 警告 about slow 设置 ([@amelchio] - [#11352]) * Account for 用户-Agent being non-existent, causing a TypeError ([@akatrevorjay] - [#11064]) * Cloud Updates ([@balloob] - [#11404]) ([cloud docs]) * Add support for the renaming of Yamaha Receiver 区域 via 配置 file. Added a test to 遮盖 the change, plus previously untested options. ([@dfinlay] - [#11402]) ([媒体播放器.yamaha docs]) * Plex api 更新 ([@ryanm101] - [#11423]) ([媒体播放器.plex docs]) ([传感器.plex docs]) * fix: hmip-etrv-2 now working with homeassistant ([@daenny] - [#11175]) ([homematic docs]) ([温控.homematic docs]) * Fix 错误 in Zigbee push 状态 ([@SteveEasley] - [#11386]) ([Zigbee docs]) * Add on/off supported feature to 温控 ([@andrey-git] - [#11379]) ([温控 docs]) ([温控.demo docs]) ([温控.sensibo docs]) * Fix CONF\_FRIENDLY\_NAME ([@cdce8p] - [#11438]) ([遮盖.模板 docs]) ([灯光.模板 docs]) * 温控: fix missing "|" ([@andrey-git] - [#11441]) ([温控.demo docs]) * Google Assistant -> Google 动作 ([@balloob] - [#11442]) ([cloud.iot docs]) * Added new 温控 component from Daikin ([@rofrantz] - [#10983]) ([温控.daikin docs]) (new-platform) * Updated generic thermostat to respect operation\_mode and added away mode ([@ciotlosm] - [#11445]) ([温控.generic\_thermostat docs][温控.generic_thermostat docs]) * Reconnect to alarmdecoder on disconnect ([@PhracturedBlue] - [#11383]) ([alarmdecoder docs]) * Set tahoma 遮盖 scan interval to 60 seconds ([@thijsdejong] - [#11447]) ([遮盖.tahoma docs]) * Add some tests to the cloud component ([@balloob] - [#11460]) ([cloud docs]) ([cloud.iot docs]) * Input Select - Added 服务 description ([@cdce8p] - [#11456]) ([input\_select docs][input_select docs]) * Input Boolean - Deleted 'DEFAULT\_INITIAL' ([@cdce8p] - [#11453]) ([input\_boolean docs][input_boolean docs]) * Updated gitignore file ([@cdce8p] - [#11452]) * 更新 hydroquebec component to use hass httpsession ([@titilambert] - [#11412]) * Catch everything when calling to OctoPrint API to fix #10557 ([@w1ll1am23] - [#11457]) ([octoprint docs]) * 更新 PULL\_REQUEST\_TEMPLATE.md ([@danielhiversen] - [#11465]) * Alexa to not use customize for 实体 config ([@balloob] - [#11461]) ([cloud docs]) ([alexa.smart\_home docs][alexa.smart_home docs]) (breaking change) * Don't duplicate html5 registrations ([@Chris-V] - [#11451]) ([通知.html5 docs]) * AlarmDecoder remove icon function as BinarySensorDevice handles it correctly now ([@hawk259] - [#11467]) ([binary\_sensor.alarmdecoder docs][binary_sensor.alarmdecoder docs]) * 升级 psutil to 5.4.3 ([@fabaff] - [#11468]) ([传感器.systemmonitor docs]) * 升级 alpha\_vantage to 1.8.0 ([@fabaff] - [#11476]) ([传感器.alpha\_vantage docs][传感器.alpha_vantage docs]) * Fix vultr tests ([@balloob] - [#11477]) * 升级 yarl to 0.17.0 ([@fabaff] - [#11478]) * Add Touchline 温控 platform ([@abondoe] - [#10547]) ([温控.touchline docs]) (new-platform) * 升级 pysnmp to 4.4.4 ([@fabaff] - [#11485]) ([device\_tracker.snmp docs][device_tracker.snmp docs]) ([传感器.snmp docs]) ([开关.snmp docs]) * Add new iGlo component ([@jesserockz] - [#11171]) ([灯光.iglo docs]) (new-platform) * Add missing 配置 variables ([@fabaff] - [#11390]) ([metoffice docs]) * Clean up Alexa.intent and DialogFlow.intent ([@balloob] - [#11492]) ([alexa.intent docs]) * Fix time functions would throw 错误 in python 脚本 ([@tomwaters] - [#11414]) ([python\_script docs][python_script docs]) * 升级 pywebpush to 1.5.0 ([@Chris-V] - [#11497]) ([通知.html5 docs]) * 升级 schiene to 0.20 ([@JulianKahnert] - [#11504]) ([传感器.deutsche\_bahn docs][传感器.deutsche_bahn docs]) * timer: include the remaining time in the 状态 属性 ([@Julio-Guerra] - [#11510]) ([timer docs]) * More tolerant KNX component if gateway cant be connected ([@Julius2342] - [#11511]) ([knx docs]) ([binary\_sensor.knx docs][binary_sensor.knx docs]) ([温控.knx docs]) ([遮盖.knx docs]) ([灯光.knx docs]) ([传感器.knx docs]) ([开关.knx docs]) * Snips (new) added speech response, parse snips/duration ([@tschmidty69] - [#11513]) ([snips docs]) * Add Dark Sky 天气 component ([@DanNixon] - [#11435]) ([天气.darksky docs]) (new-platform) * Lazy loading of 服务 descriptions ([@amelchio] - [#11479]) ([api docs]) ([websocket\_api docs][websocket_api docs]) ([灯光.lifx docs]) * Fix canary flaky test ([@balloob] - [#11519]) * Address missed review comments for Dark Sky 天气 ([@DanNixon] - [#11520]) ([天气.darksky docs]) * New features for Owntracks device\_tracker ([@cpcowart] - [#11480]) ([device\_tracker.owntracks docs][device_tracker.owntracks docs]) * Reconnect before mochad 开关 send command ([@aosadchyy] - [#11296]) ([开关.mochad docs]) * Fix Kodi channels media type ([@florianj1] - [#11505]) ([媒体播放器.kodi docs]) * Extension 传感器 alpha\_vantage ([@ChristianKuehnel] - [#11427]) ([传感器.alpha\_vantage docs][传感器.alpha_vantage docs]) (breaking change) * MQTT json 属性 ([@timstanley1985] - [#11439]) ([传感器.MQTT docs]) * Support pushing all 传感器 and fix wrong metrics. ([@michaelkuty] - [#11159]) ([prometheus docs]) (breaking change) * Add options feature to Baidu TTS. ([@yienxu] - [#11462]) ([tts.baidu docs]) * Insteon local 更新 ([@camrun91] - [#11088]) ([insteon\_local docs][insteon_local docs]) ([风扇.insteon\_local docs][风扇.insteon_local docs]) ([灯光.insteon\_local docs][灯光.insteon_local docs]) ([开关.insteon\_local docs][开关.insteon_local docs]) (breaking change) * Snips: (fix) support new intentName format ([@tschmidty69] - [#11509]) ([snips docs]) * 升级 numpy to 1.14.0 ([@fabaff] - [#11542]) ([binary\_sensor.trend docs][binary_sensor.trend docs]) ([image\_processing.opencv docs][image_processing.opencv docs]) * 升级 python-etherscan-api to 0.0.2 ([@fabaff] - [#11535]) ([传感器.etherscan docs]) * 升级 Sphinx to 1.6.6 ([@fabaff] - [#11534]) * ZoneMinder event 传感器 updates ([@swilson] - [#11369]) ([传感器.zoneminder docs]) * Move Google Assistant 实体 config out of customize ([@balloob] - [#11499]) ([cloud docs]) ([google\_assistant docs][google_assistant docs]) (breaking change) * 升级 lightify to 1.0.6.1 ([@fabaff] - [#11545]) ([灯光.osramlightify docs]) * Improved test runtime ([@cdce8p] - [#11553]) ([binary\_sensor.workday docs][binary_sensor.workday docs]) * Add 2 媒体播放器 服务 and 1 custom 服务 to Squeezebox platform ([@ericpignet] - [#10969]) ([媒体播放器.squeezebox docs]) * Fix 错误 on entity\_config missing ([@philk] - [#11561]) ([google\_assistant.http docs][google_assistant.http docs]) * 升级 keyring to 10.3.2 ([@fabaff] - [#11531]) * Coinbase.com 传感器 platform ([@nkgilley] - [#11036]) ([coinbase docs]) ([传感器.coinbase docs]) (new-platform) * Try to fix crashes after Hue refactoring ([@andreacampi] - [#11270]) ([灯光.hue docs]) * Remove execution file perm ([@balloob] - [#11563]) * Deprecate explicit entity\_id in 模板 platforms ([@amelchio] - [#11123]) ([binary\_sensor.模板 docs][binary_sensor.模板 docs]) ([遮盖.模板 docs]) ([灯光.模板 docs]) ([传感器.模板 docs]) ([开关.模板 docs]) * Test tweaks ([@balloob] - [#11560]) * Add Velux Windows to Tahoma ([@thijsdejong] - [#11538]) ([tahoma docs]) ([遮盖.tahoma docs]) * Extend hass.io 服务 / updater ([@pvizeli] - [#11549]) ([hassio docs]) * Add sensibo\_assume\_state 服务 to Sensibo 温控 ([@andrey-git] - [#11567]) ([温控.sensibo docs]) * Tracking all groups to allow changing of existing groups ([@randellhodges] - [#11444]) ([group docs]) * Fix new squeezebox 服务 descriptions for lazy loading ([@amelchio] - [#11574]) ([媒体播放器.squeezebox docs]) * Mark REST binary\_sensor unavailable if request fails ([@DanNixon] - [#11506]) ([binary\_sensor.rest docs][binary_sensor.rest docs]) * Tado improvements - hot water 区域 传感器 and 温控 precision ([@andersonshatch] - [#11521]) ([温控.tado docs]) ([传感器.tado docs]) * Make the rpi\_rf component Thread-safe using an RLock ([@ulido] - [#11487]) ([开关.rpi\_rf docs][开关.rpi_rf docs]) * 更新 pyhomematic, support new 设备 ([@danielperna84] - [#11578]) ([homematic docs]) * Alarmdecoder add validation of the 区域 types ([@hawk259] - [#11488]) ([alarmdecoder docs]) * Support OSRAM 灯光 on ZHA ([@armills] - [#11522]) ([灯光.zha docs]) * Fix 蓝牙 tracker source ([@swilson] - [#11469]) ([device\_tracker docs][device_tracker docs]) ([device\_tracker.bluetooth\_le\_tracker docs][device_tracker.bluetooth_le_tracker docs]) ([device\_tracker.bluetooth\_tracker docs][device_tracker.bluetooth_tracker docs]) * Fix for asuswrt, telnet not working and 在场-detection for router mode ([@kennedyshead] - [#11422]) ([device\_tracker.asuswrt docs][device_tracker.asuswrt docs]) * Remove aux\_heat support from Sensibo now that UI supports on/off ([@andrey-git] - [#11579]) ([温控.sensibo docs]) (breaking change) * Changed 设备 type of media player and 遮盖 to 开关 ([@Laqoore] - [#11483]) ([google\_assistant.smart\_home docs][google_assistant.smart_home docs]) * Control ordering of display in history component ([@rwa] - [#11340]) ([history docs]) * Pr/11430 ([@balloob] - [#11587]) * Cast return values and add unit tests for the yahoo 天气 component. ([@cgtobi] - [#10699]) * add velux roller shutter to tahoma ([@thijsdejong] - [#11586]) ([tahoma docs]) * Added support for enable/disable motion detection ([@abjorshammar] - [#11583]) ([摄像头.uvc docs]) * Avoid returning empty media\_image\_url string ([@JackWindows] - [#11557]) ([媒体播放器.cast docs]) * 核心 support for hass.io calls & Bugfix check\_config ([@pvizeli] - [#11571]) ([homeassistant docs]) ([hassio docs]) ([updater docs]) * Fix Tahoma stop command for 2 types of shutters ([@thijsdejong] - [#11588]) ([遮盖.tahoma docs]) * Pushbullet email support (fix) ([@tschmidty69] - [#11590]) ([通知.pushbullet docs]) * Fix 状态 for 触发器 with forced updates ([@armills] - [#11595]) ([自动化.状态 docs]) * Snips add say and say\_actions 服务 (new) ([@tschmidty69] - [#11596]) ([snips docs]) * Concord232 报警 arm away fix ([@rwa] - [#11597]) ([alarm\_control\_panel.concord232 docs][alarm_control_panel.concord232 docs]) ([binary\_sensor.concord232 docs][binary_sensor.concord232 docs]) * Bugfix and cleanup for Rfxtrx ([@danielhiversen] - [#11600]) * Xiaomi lib 升级 ([@danielhiversen] - [#11603]) * 升级 yarl to 0.18.0 ([@fabaff] - [#11609]) * patch stop command ([@thijsdejong] - [#11612]) ([遮盖.tahoma docs]) * Use kelvin/mireds correctly for setting iglo white ([@jesserockz] - [#11622]) * 更新 Pyarlo to 0.1.2 ([@arsaboo] - [#11626]) [#10296]: https://github.com/home-assistant/home-assistant/pull/10296 [#10321]: https://github.com/home-assistant/home-assistant/pull/10321 [#10547]: https://github.com/home-assistant/home-assistant/pull/10547 [#10699]: https://github.com/home-assistant/home-assistant/pull/10699 [#10795]: https://github.com/home-assistant/home-assistant/pull/10795 [#10841]: https://github.com/home-assistant/home-assistant/pull/10841 [#10957]: https://github.com/home-assistant/home-assistant/pull/10957 [#10969]: https://github.com/home-assistant/home-assistant/pull/10969 [#10979]: https://github.com/home-assistant/home-assistant/pull/10979 [#10983]: https://github.com/home-assistant/home-assistant/pull/10983 [#11023]: https://github.com/home-assistant/home-assistant/pull/11023 [#11027]: https://github.com/home-assistant/home-assistant/pull/11027 [#11036]: https://github.com/home-assistant/home-assistant/pull/11036 [#11039]: https://github.com/home-assistant/home-assistant/pull/11039 [#11053]: https://github.com/home-assistant/home-assistant/pull/11053 [#11064]: https://github.com/home-assistant/home-assistant/pull/11064 [#11069]: https://github.com/home-assistant/home-assistant/pull/11069 [#11072]: https://github.com/home-assistant/home-assistant/pull/11072 [#11088]: https://github.com/home-assistant/home-assistant/pull/11088 [#11096]: https://github.com/home-assistant/home-assistant/pull/11096 [#11110]: https://github.com/home-assistant/home-assistant/pull/11110 [#11123]: https://github.com/home-assistant/home-assistant/pull/11123 [#11140]: https://github.com/home-assistant/home-assistant/pull/11140 [#11159]: https://github.com/home-assistant/home-assistant/pull/11159 [#11171]: https://github.com/home-assistant/home-assistant/pull/11171 [#11172]: https://github.com/home-assistant/home-assistant/pull/11172 [#11175]: https://github.com/home-assistant/home-assistant/pull/11175 [#11180]: https://github.com/home-assistant/home-assistant/pull/11180 [#11182]: https://github.com/home-assistant/home-assistant/pull/11182 [#11188]: https://github.com/home-assistant/home-assistant/pull/11188 [#11193]: https://github.com/home-assistant/home-assistant/pull/11193 [#11202]: https://github.com/home-assistant/home-assistant/pull/11202 [#11216]: https://github.com/home-assistant/home-assistant/pull/11216 [#11232]: https://github.com/home-assistant/home-assistant/pull/11232 [#11235]: https://github.com/home-assistant/home-assistant/pull/11235 [#11238]: https://github.com/home-assistant/home-assistant/pull/11238 [#11242]: https://github.com/home-assistant/home-assistant/pull/11242 [#11243]: https://github.com/home-assistant/home-assistant/pull/11243 [#11244]: https://github.com/home-assistant/home-assistant/pull/11244 [#11245]: https://github.com/home-assistant/home-assistant/pull/11245 [#11250]: https://github.com/home-assistant/home-assistant/pull/11250 [#11251]: https://github.com/home-assistant/home-assistant/pull/11251 [#11260]: https://github.com/home-assistant/home-assistant/pull/11260 [#11268]: https://github.com/home-assistant/home-assistant/pull/11268 [#11269]: https://github.com/home-assistant/home-assistant/pull/11269 [#11270]: https://github.com/home-assistant/home-assistant/pull/11270 [#11271]: https://github.com/home-assistant/home-assistant/pull/11271 [#11274]: https://github.com/home-assistant/home-assistant/pull/11274 [#11280]: https://github.com/home-assistant/home-assistant/pull/11280 [#11281]: https://github.com/home-assistant/home-assistant/pull/11281 [#11282]: https://github.com/home-assistant/home-assistant/pull/11282 [#11296]: https://github.com/home-assistant/home-assistant/pull/11296 [#11297]: https://github.com/home-assistant/home-assistant/pull/11297 [#11298]: https://github.com/home-assistant/home-assistant/pull/11298 [#11301]: https://github.com/home-assistant/home-assistant/pull/11301 [#11304]: https://github.com/home-assistant/home-assistant/pull/11304 [#11307]: https://github.com/home-assistant/home-assistant/pull/11307 [#11308]: https://github.com/home-assistant/home-assistant/pull/11308 [#11309]: https://github.com/home-assistant/home-assistant/pull/11309 [#11310]: https://github.com/home-assistant/home-assistant/pull/11310 [#11311]: https://github.com/home-assistant/home-assistant/pull/11311 [#11312]: https://github.com/home-assistant/home-assistant/pull/11312 [#11315]: https://github.com/home-assistant/home-assistant/pull/11315 [#11316]: https://github.com/home-assistant/home-assistant/pull/11316 [#11317]: https://github.com/home-assistant/home-assistant/pull/11317 [#11318]: https://github.com/home-assistant/home-assistant/pull/11318 [#11319]: https://github.com/home-assistant/home-assistant/pull/11319 [#11326]: https://github.com/home-assistant/home-assistant/pull/11326 [#11329]: https://github.com/home-assistant/home-assistant/pull/11329 [#11331]: https://github.com/home-assistant/home-assistant/pull/11331 [#11332]: https://github.com/home-assistant/home-assistant/pull/11332 [#11333]: https://github.com/home-assistant/home-assistant/pull/11333 [#11334]: https://github.com/home-assistant/home-assistant/pull/11334 [#11335]: https://github.com/home-assistant/home-assistant/pull/11335 [#11336]: https://github.com/home-assistant/home-assistant/pull/11336 [#11340]: https://github.com/home-assistant/home-assistant/pull/11340 [#11341]: https://github.com/home-assistant/home-assistant/pull/11341 [#11344]: https://github.com/home-assistant/home-assistant/pull/11344 [#11345]: https://github.com/home-assistant/home-assistant/pull/11345 [#11346]: https://github.com/home-assistant/home-assistant/pull/11346 [#11348]: https://github.com/home-assistant/home-assistant/pull/11348 [#11350]: https://github.com/home-assistant/home-assistant/pull/11350 [#11352]: https://github.com/home-assistant/home-assistant/pull/11352 [#11354]: https://github.com/home-assistant/home-assistant/pull/11354 [#11357]: https://github.com/home-assistant/home-assistant/pull/11357 [#11362]: https://github.com/home-assistant/home-assistant/pull/11362 [#11369]: https://github.com/home-assistant/home-assistant/pull/11369 [#11375]: https://github.com/home-assistant/home-assistant/pull/11375 [#11379]: https://github.com/home-assistant/home-assistant/pull/11379 [#11381]: https://github.com/home-assistant/home-assistant/pull/11381 [#11383]: https://github.com/home-assistant/home-assistant/pull/11383 [#11386]: https://github.com/home-assistant/home-assistant/pull/11386 [#11390]: https://github.com/home-assistant/home-assistant/pull/11390 [#11394]: https://github.com/home-assistant/home-assistant/pull/11394 [#11395]: https://github.com/home-assistant/home-assistant/pull/11395 [#11397]: https://github.com/home-assistant/home-assistant/pull/11397 [#11401]: https://github.com/home-assistant/home-assistant/pull/11401 [#11402]: https://github.com/home-assistant/home-assistant/pull/11402 [#11404]: https://github.com/home-assistant/home-assistant/pull/11404 [#11410]: https://github.com/home-assistant/home-assistant/pull/11410 [#11412]: https://github.com/home-assistant/home-assistant/pull/11412 [#11414]: https://github.com/home-assistant/home-assistant/pull/11414 [#11416]: https://github.com/home-assistant/home-assistant/pull/11416 [#11417]: https://github.com/home-assistant/home-assistant/pull/11417 [#11422]: https://github.com/home-assistant/home-assistant/pull/11422 [#11423]: https://github.com/home-assistant/home-assistant/pull/11423 [#11427]: https://github.com/home-assistant/home-assistant/pull/11427 [#11435]: https://github.com/home-assistant/home-assistant/pull/11435 [#11438]: https://github.com/home-assistant/home-assistant/pull/11438 [#11439]: https://github.com/home-assistant/home-assistant/pull/11439 [#11441]: https://github.com/home-assistant/home-assistant/pull/11441 [#11442]: https://github.com/home-assistant/home-assistant/pull/11442 [#11444]: https://github.com/home-assistant/home-assistant/pull/11444 [#11445]: https://github.com/home-assistant/home-assistant/pull/11445 [#11447]: https://github.com/home-assistant/home-assistant/pull/11447 [#11451]: https://github.com/home-assistant/home-assistant/pull/11451 [#11452]: https://github.com/home-assistant/home-assistant/pull/11452 [#11453]: https://github.com/home-assistant/home-assistant/pull/11453 [#11456]: https://github.com/home-assistant/home-assistant/pull/11456 [#11457]: https://github.com/home-assistant/home-assistant/pull/11457 [#11460]: https://github.com/home-assistant/home-assistant/pull/11460 [#11461]: https://github.com/home-assistant/home-assistant/pull/11461 [#11462]: https://github.com/home-assistant/home-assistant/pull/11462 [#11465]: https://github.com/home-assistant/home-assistant/pull/11465 [#11467]: https://github.com/home-assistant/home-assistant/pull/11467 [#11468]: https://github.com/home-assistant/home-assistant/pull/11468 [#11469]: https://github.com/home-assistant/home-assistant/pull/11469 [#11476]: https://github.com/home-assistant/home-assistant/pull/11476 [#11477]: https://github.com/home-assistant/home-assistant/pull/11477 [#11478]: https://github.com/home-assistant/home-assistant/pull/11478 [#11479]: https://github.com/home-assistant/home-assistant/pull/11479 [#11480]: https://github.com/home-assistant/home-assistant/pull/11480 [#11483]: https://github.com/home-assistant/home-assistant/pull/11483 [#11485]: https://github.com/home-assistant/home-assistant/pull/11485 [#11487]: https://github.com/home-assistant/home-assistant/pull/11487 [#11488]: https://github.com/home-assistant/home-assistant/pull/11488 [#11492]: https://github.com/home-assistant/home-assistant/pull/11492 [#11497]: https://github.com/home-assistant/home-assistant/pull/11497 [#11499]: https://github.com/home-assistant/home-assistant/pull/11499 [#11504]: https://github.com/home-assistant/home-assistant/pull/11504 [#11505]: https://github.com/home-assistant/home-assistant/pull/11505 [#11506]: https://github.com/home-assistant/home-assistant/pull/11506 [#11509]: https://github.com/home-assistant/home-assistant/pull/11509 [#11510]: https://github.com/home-assistant/home-assistant/pull/11510 [#11511]: https://github.com/home-assistant/home-assistant/pull/11511 [#11513]: https://github.com/home-assistant/home-assistant/pull/11513 [#11519]: https://github.com/home-assistant/home-assistant/pull/11519 [#11520]: https://github.com/home-assistant/home-assistant/pull/11520 [#11521]: https://github.com/home-assistant/home-assistant/pull/11521 [#11522]: https://github.com/home-assistant/home-assistant/pull/11522 [#11531]: https://github.com/home-assistant/home-assistant/pull/11531 [#11534]: https://github.com/home-assistant/home-assistant/pull/11534 [#11535]: https://github.com/home-assistant/home-assistant/pull/11535 [#11538]: https://github.com/home-assistant/home-assistant/pull/11538 [#11542]: https://github.com/home-assistant/home-assistant/pull/11542 [#11545]: https://github.com/home-assistant/home-assistant/pull/11545 [#11549]: https://github.com/home-assistant/home-assistant/pull/11549 [#11553]: https://github.com/home-assistant/home-assistant/pull/11553 [#11557]: https://github.com/home-assistant/home-assistant/pull/11557 [#11560]: https://github.com/home-assistant/home-assistant/pull/11560 [#11561]: https://github.com/home-assistant/home-assistant/pull/11561 [#11563]: https://github.com/home-assistant/home-assistant/pull/11563 [#11567]: https://github.com/home-assistant/home-assistant/pull/11567 [#11571]: https://github.com/home-assistant/home-assistant/pull/11571 [#11574]: https://github.com/home-assistant/home-assistant/pull/11574 [#11578]: https://github.com/home-assistant/home-assistant/pull/11578 [#11579]: https://github.com/home-assistant/home-assistant/pull/11579 [#11583]: https://github.com/home-assistant/home-assistant/pull/11583 [#11586]: https://github.com/home-assistant/home-assistant/pull/11586 [#11587]: https://github.com/home-assistant/home-assistant/pull/11587 [#11588]: https://github.com/home-assistant/home-assistant/pull/11588 [#11590]: https://github.com/home-assistant/home-assistant/pull/11590 [#11595]: https://github.com/home-assistant/home-assistant/pull/11595 [#11596]: https://github.com/home-assistant/home-assistant/pull/11596 [#11597]: https://github.com/home-assistant/home-assistant/pull/11597 [#11600]: https://github.com/home-assistant/home-assistant/pull/11600 [#11603]: https://github.com/home-assistant/home-assistant/pull/11603 [#11609]: https://github.com/home-assistant/home-assistant/pull/11609 [#11612]: https://github.com/home-assistant/home-assistant/pull/11612 [#11622]: https://github.com/home-assistant/home-assistant/pull/11622 [#11626]: https://github.com/home-assistant/home-assistant/pull/11626 [@Chris-V]: https://github.com/Chris-V [@ChristianKuehnel]: https://github.com/ChristianKuehnel [@DanNixon]: https://github.com/DanNixon [@Human]: https://github.com/Human [@JackWindows]: https://github.com/JackWindows [@JulianKahnert]: https://github.com/JulianKahnert [@Julio-Guerra]: https://github.com/Julio-Guerra [@Julius2342]: https://github.com/Julius2342 [@KJonline]: https://github.com/KJonline [@Kane610]: https://github.com/Kane610 [@Klathmon]: https://github.com/Klathmon [@Klikini]: https://github.com/Klikini [@Laqoore]: https://github.com/Laqoore [@OttoWinter]: https://github.com/OttoWinter [@OverloadUT]: https://github.com/OverloadUT [@PeWu]: https://github.com/PeWu [@PhracturedBlue]: https://github.com/PhracturedBlue [@ReneNulschDE]: https://github.com/ReneNulschDE [@SteveEasley]: https://github.com/SteveEasley [@abjorshammar]: https://github.com/abjorshammar [@abondoe]: https://github.com/abondoe [@akatrevorjay]: https://github.com/akatrevorjay [@amelchio]: https://github.com/amelchio [@andersonshatch]: https://github.com/andersonshatch [@andreacampi]: https://github.com/andreacampi [@andrey-git]: https://github.com/andrey-git [@aosadchyy]: https://github.com/aosadchyy [@armills]: https://github.com/armills [@arsaboo]: https://github.com/arsaboo [@awkwardDuck]: https://github.com/awkwardDuck [@bachya]: https://github.com/bachya [@thijsdejong]: https://github.com/thijsdejong [@balloob]: https://github.com/balloob [@camrun91]: https://github.com/camrun91 [@cdce8p]: https://github.com/cdce8p [@cgarwood]: https://github.com/cgarwood [@cgtobi]: https://github.com/cgtobi [@ciotlosm]: https://github.com/ciotlosm [@cmsimike]: https://github.com/cmsimike [@cnrd]: https://github.com/cnrd [@cpcowart]: https://github.com/cpcowart [@daenny]: https://github.com/daenny [@danielhiversen]: https://github.com/danielhiversen [@danielperna84]: https://github.com/danielperna84 [@dfiel]: https://github.com/dfiel [@dfinlay]: https://github.com/dfinlay [@djchen]: https://github.com/djchen [@ericpignet]: https://github.com/ericpignet [@etsinko]: https://github.com/etsinko [@fabaff]: https://github.com/fabaff [@florianj1]: https://github.com/florianj1 [@foxel]: https://github.com/foxel [@frwickst]: https://github.com/frwickst [@goldminenine]: https://github.com/goldminenine [@goyney]: https://github.com/goyney [@hawk259]: https://github.com/hawk259 [@jbarrancos]: https://github.com/jbarrancos [@jeroenterheerdt]: https://github.com/jeroenterheerdt [@jesserockz]: https://github.com/jesserockz [@kennedyshead]: https://github.com/kennedyshead [@markferry]: https://github.com/markferry [@masarliev]: https://github.com/masarliev [@michaelkuty]: https://github.com/michaelkuty [@nkgilley]: https://github.com/nkgilley [@notoriousbdg]: https://github.com/notoriousbdg [@pavoni]: https://github.com/pavoni [@philk]: https://github.com/philk [@pvizeli]: https://github.com/pvizeli [@randellhodges]: https://github.com/randellhodges [@rofrantz]: https://github.com/rofrantz [@rwa]: https://github.com/rwa [@ryanm101]: https://github.com/ryanm101 [@schmittx]: https://github.com/schmittx [@schnoetz]: https://github.com/schnoetz [@swilson]: https://github.com/swilson [@thibmaek]: https://github.com/thibmaek [@timstanley1985]: https://github.com/timstanley1985 [@tinloaf]: https://github.com/tinloaf [@titilambert]: https://github.com/titilambert [@tomaszduda23]: https://github.com/tomaszduda23 [@tomwaters]: https://github.com/tomwaters [@tschmidty69]: https://github.com/tschmidty69 [@ttroy50]: https://github.com/ttroy50 [@ulido]: https://github.com/ulido [@veleek]: https://github.com/veleek [@w1ll1am23]: https://github.com/w1ll1am23 [@yienxu]: https://github.com/yienxu [alarm_control_panel.alarmdecoder docs]: /integrations/alarmdecoder#报警-control-面板 [alarm_control_panel.concord232 docs]: /integrations/concord232#报警-control-面板 [alarm_control_panel.egardia docs]: /integrations/egardia [alarmdecoder docs]: /integrations/alarmdecoder/ [alexa.intent docs]: /integrations/alexa.intent/ [alexa.smart_home docs]: /integrations/alexa.smart_home/ [api docs]: /integrations/api/ [自动化.状态 docs]: /docs/自动化/触发器/#状态-触发器 [binary_sensor docs]: /integrations/binary_sensor/ [binary_sensor.alarmdecoder docs]: /integrations/alarmdecoder [binary_sensor.concord232 docs]: /integrations/concord232#binary-传感器 [binary_sensor.deconz docs]: /integrations/deconz#binary-传感器 [binary_sensor.isy994 docs]: /integrations/isy994 [binary_sensor.knx docs]: /integrations/binary_sensor.knx/ [binary_sensor.rest docs]: /integrations/binary_sensor.rest/ [binary_sensor.模板 docs]: /integrations/binary_sensor.模板/ [binary_sensor.threshold docs]: /integrations/threshold [binary_sensor.trend docs]: /integrations/trend [binary_sensor.workday docs]: /integrations/workday [摄像头.doorbird docs]: /integrations/doorbird#摄像头 [摄像头.uvc docs]: /integrations/uvc [温控 docs]: /integrations/温控/ [温控.daikin docs]: /integrations/daikin#温控 [温控.demo docs]: /integrations/demo/ [温控.econet docs]: /integrations/econet [温控.generic_thermostat docs]: /integrations/generic_thermostat [温控.hive docs]: /integrations/hive#温控 [温控.homematic docs]: /integrations/homematic [温控.knx docs]: /integrations/温控.knx/ [温控.netatmo docs]: /integrations/netatmo#温控 [温控.sensibo docs]: /integrations/sensibo [温控.tado docs]: /integrations/tado [温控.touchline docs]: /integrations/touchline [cloud docs]: /integrations/cloud/ [cloud.auth_api docs]: /integrations/cloud/ [cloud.http_api docs]: /integrations/cloud/ [cloud.iot docs]: /integrations/cloud/ [coinbase docs]: /integrations/coinbase/ [conversation docs]: /integrations/conversation/ [遮盖.isy994 docs]: /integrations/isy994 [遮盖.knx docs]: /integrations/遮盖.knx/ [遮盖.tahoma docs]: /integrations/tahoma [遮盖.模板 docs]: /integrations/遮盖.模板/ [遮盖.xiaomi_aqara docs]: /integrations/遮盖.xiaomi_aqara/ [deconz docs]: /integrations/deconz/ [device_tracker docs]: /integrations/device_tracker/ [device_tracker.asuswrt docs]: /integrations/asuswrt [device_tracker.bluetooth_le_tracker docs]: /integrations/bluetooth_le_tracker [device_tracker.bluetooth_tracker docs]: /integrations/bluetooth_tracker [device_tracker.gpslogger docs]: /integrations/gpslogger [device_tracker.owntracks docs]: /integrations/owntracks [device_tracker.ping docs]: /integrations/ping [device_tracker.snmp docs]: /integrations/snmp [device_tracker.tile docs]: /integrations/tile [digital_ocean docs]: /integrations/digital_ocean/ [风扇.insteon_local docs]: /integrations/insteon/ [风扇.isy994 docs]: /integrations/isy994 [风扇.xiaomi_miio docs]: /integrations/风扇.xiaomi_miio/ [google_assistant docs]: /integrations/google_assistant/ [google_assistant.http docs]: /integrations/google_assistant/ [google_assistant.smart_home docs]: /integrations/google_assistant [group docs]: /integrations/group/ [homeassistant docs]: /integrations/homeassistant [hassio docs]: /integrations/hassio/ [history docs]: /integrations/history/ [hive docs]: /integrations/hive/ [homematic docs]: /integrations/homematic/ [http docs]: /integrations/http/ [image_processing.opencv docs]: /integrations/opencv [input_boolean docs]: /integrations/input_boolean/ [input_select docs]: /integrations/input_select/ [insteon_local docs]: /integrations/insteon/ [isy994 docs]: /integrations/isy994/ [knx docs]: /integrations/knx/ [灯光.deconz docs]: /integrations/deconz#灯光 [灯光.greenwave docs]: /integrations/greenwave [灯光.hive docs]: /integrations/hive#灯光 [灯光.hue docs]: /integrations/hue [灯光.iglo docs]: /integrations/iglo [灯光.insteon_local docs]: /integrations/insteon/ [灯光.isy994 docs]: /integrations/isy994 [灯光.knx docs]: /integrations/灯光.knx/ [灯光.lifx docs]: /integrations/lifx [灯光.MQTT docs]: /integrations/灯光.MQTT/ [灯光.osramlightify docs]: /integrations/osramlightify [灯光.模板 docs]: /integrations/灯光.模板/ [灯光.tplink docs]: /integrations/tplink [灯光.xiaomi_miio docs]: /integrations/灯光.xiaomi_miio/ [灯光.zha docs]: /integrations/zha [门锁.isy994 docs]: /integrations/isy994 [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.cast docs]: /integrations/cast [媒体播放器.kodi docs]: /integrations/kodi [媒体播放器.monoprice docs]: /integrations/monoprice [媒体播放器.plex docs]: /integrations/plex#media-player [媒体播放器.squeezebox docs]: /integrations/squeezebox [媒体播放器.yamaha docs]: /integrations/yamaha [metoffice docs]: /integrations/metoffice/ [modbus docs]: /integrations/modbus/ [通知.html5 docs]: /integrations/html5 [通知.pushbullet docs]: /integrations/pushbullet [通知.webostv docs]: /integrations/webostv [octoprint docs]: /integrations/octoprint/ [prometheus docs]: /integrations/prometheus/ [python_script docs]: /integrations/python_script/ [rainbird docs]: /integrations/rainbird/ [remember_the_milk docs]: /integrations/remember_the_milk/ [传感器.alpha_vantage docs]: /integrations/alpha_vantage [传感器.bitcoin docs]: /integrations/bitcoin [传感器.coinbase docs]: /integrations/coinbase [传感器.deconz docs]: /integrations/deconz#传感器 [传感器.deutsche_bahn docs]: /integrations/deutsche_bahn [传感器.discogs docs]: /integrations/discogs [传感器.etherscan docs]: /integrations/etherscan [传感器.fido docs]: /integrations/fido [传感器.hydroquebec docs]: /integrations/hydroquebec [传感器.imap_email_content docs]: /integrations/imap_email_content/ [传感器.irish_rail_transport docs]: /integrations/irish_rail_transport [传感器.isy994 docs]: /integrations/isy994#传感器 [传感器.knx docs]: /integrations/传感器.knx/ [传感器.luftdaten docs]: /integrations/luftdaten#传感器 [传感器.miflora docs]: /integrations/miflora [传感器.MQTT docs]: /integrations/传感器.MQTT/ [传感器.openweathermap docs]: /integrations/openweathermap#传感器 [传感器.plex docs]: /integrations/plex#传感器 [传感器.rainbird docs]: /integrations/rainbird#传感器 [传感器.snmp docs]: /integrations/snmp#传感器 [传感器.sochain docs]: /integrations/sochain [传感器.statistics docs]: /integrations/statistics [传感器.steam_online docs]: /integrations/steam_online [传感器.swiss_public_transport docs]: /integrations/swiss_public_transport [传感器.systemmonitor docs]: /integrations/systemmonitor [传感器.tado docs]: /integrations/tado [传感器.模板 docs]: /integrations/模板 [传感器.transmission docs]: /integrations/transmission [传感器.xbox_live docs]: /integrations/xbox_live [传感器.zoneminder docs]: /integrations/zoneminder#传感器 [snips docs]: /integrations/snips/ [开关.insteon_local docs]: /integrations/insteon/ [开关.isy994 docs]: /integrations/isy994 [开关.knx docs]: /integrations/开关.knx/ [开关.mochad docs]: /integrations/mochad#开关 [开关.rainbird docs]: /integrations/rainbird#开关 [开关.rpi_rf docs]: /integrations/rpi_rf [开关.snmp docs]: /integrations/snmp#开关 [开关.模板 docs]: /integrations/开关.模板/ [开关.tplink docs]: /integrations/tplink [开关.transmission docs]: /integrations/transmission [开关.xiaomi_miio docs]: /integrations/开关.xiaomi_miio/ [tahoma docs]: /integrations/tahoma/ [telegram_bot docs]: /integrations/telegram_bot/ [timer docs]: /integrations/timer/ [tts.baidu docs]: /integrations/baidu [tts.marytts docs]: /integrations/marytts [updater docs]: /integrations/updater/ [吸尘器.xiaomi_miio docs]: /integrations/吸尘器.xiaomi_miio/ [天气.darksky docs]: /integrations/天气.darksky/ [天气.openweathermap docs]: /integrations/openweathermap#天气 [websocket_api docs]: /integrations/websocket_api/ [wemo docs]: /integrations/wemo/ [Zigbee docs]: /integrations/Zigbee/ [#11670]: https://github.com/home-assistant/home-assistant/pull/11670 [#11677]: https://github.com/home-assistant/home-assistant/pull/11677 [#11678]: https://github.com/home-assistant/home-assistant/pull/11678 [#11686]: https://github.com/home-assistant/home-assistant/pull/11686 [#11713]: https://github.com/home-assistant/home-assistant/pull/11713 [@amelchio]: https://github.com/amelchio [@danielhiversen]: https://github.com/danielhiversen [@rcloran]: https://github.com/rcloran [@rwa]: https://github.com/rwa [@tinloaf]: https://github.com/tinloaf [binary_sensor.rfxtrx docs]: /integrations/rfxtrx#binary-传感器 [日历.todoist docs]: /integrations/todoist [history docs]: /integrations/history/ [灯光.zha docs]: /integrations/zha [媒体播放器.snapcast docs]: /integrations/snapcast [媒体播放器.soundtouch docs]: /integrations/soundtouch [rfxtrx docs]: /integrations/rfxtrx/ [开关.broadlink docs]: /integrations/broadlink#开关 [开关.scsgate docs]: /integrations/scsgate#开关 [zha docs]: /integrations/zha/ --- url: /home-assistant/blog/2018-01-21-clarification-emulated-hue.md --- --- url: /home-assistant/blog/2018-01-27-release-62.md --- # 0.62:MyChevy、Iota 和 Venstar 温控器 这是今年第二次发布,GitHub 上依旧热度十足。本次共有 70 位开发者贡献代码。我们也终于把待处理 PR 数量再次压到 100 以下。还有很多很酷的内容正在排队进入后续 Home Assistant 发布。 特别感谢 [@martinhjelmare] 和 [@frenck]。Martin 在代码评审上做得非常出色,Franck 则在 Hass.io 插件以及文档 PR 跟进方面持续高效推进。感谢你们的精彩贡献! ## MyChevy 借助 [@sdague] 带来的这个新集成,你可以随时查看 Chevy Bolt EV 的状态:车辆是否在充电、电池数据,以及当前可行驶里程。很棒! ## 新平台 * Adding support for Lutron 遮盖 ([@nickovs] - [#11602]) ([lutron docs]) ([遮盖.lutron docs]) (new-platform) * Add basic mychevy component ([@sdague] - [#11409]) ([mychevy docs]) (new-platform) * Added support for TekSavvy bandwidth 传感器 ([@jpjodoin] - [#11186]) (new-platform) * Ihc component and platforms ([@dingusdk] - [#10916]) ([ihc docs]) ([binary\_sensor.ihc docs][binary_sensor.ihc docs]) ([灯光.ihc docs]) ([传感器.ihc docs]) ([开关.ihc docs]) (new-platform) * Iota wallet ([@jinnerbichler] - [#11398]) ([iota docs]) ([传感器.iota docs]) (new-platform) ## 发布 0.62.1 - January 30 * Snips - (fix/change) remove response when intent not handled ([@tschmidty69] - [#11929]) ([snips docs]) * Fix asuswrt AttributeError on neigh for unknown 设备 ([@scop] - [#11960]) ([device\_tracker.asuswrt docs][device_tracker.asuswrt docs]) * Set default values for Daikin 设备 that don't support 风扇 direction and 风扇 speed features ([@rofrantz] - [#12000]) ([温控.daikin docs]) * Fix parameter escaping ([@smoldaner] - [#12008]) ([媒体播放器.squeezebox docs]) * 错误 handling, in case no connections are available ([@ReneNulschDE] - [#12010]) ([传感器.deutsche\_bahn docs][传感器.deutsche_bahn docs]) * Fix 404 for Hass.io 面板 using 前端 dev ([@c727] - [#12039]) ([前端 docs]) * 升级 pyharmony to 1.0.20 ([@amelchio] - [#12043]) ([遥控器.harmony docs]) ## 需要帮助? 如果你需要帮助,欢迎前往我们非常活跃的 [论坛](https://community.home-assistant.io/),或加入 [聊天频道](https://discord.gg/c5DvZ4e)。发布说明虽然开放评论,但我们更推荐你使用前面的社区渠道。谢谢! ## 问题反馈 如果你遇到由本次发布引入的问题,请在我们的 [issue tracker](https://github.com/home-assistant/home-assistant/issues) 提交反馈。请确保完整填写 issue 模板中的所有字段。 ## 不向后兼容的变更 * Tahoma platform will get new 实体 IDs ([@glpatcern] - [#11547]) ([tahoma docs]) ([遮盖.tahoma docs]) (breaking change) * Mold indicator: 属性 names no longer include spaces or periods ([@olskar] - [#11694]) ([传感器.mold\_indicator docs][传感器.mold_indicator docs]) (breaking change) * 仅针对自定义组件开发者:`EntityComponent.add_entity(entity)` 和 `EntityComponent.async_add_entity(entity)` 已被移除,请改用 `EntityComponent.add_entities([entity])` 和 `EntityComponent.async_add_entities([entity])`。另外,`EntityComponent.entities` 也不再是字典,而是一个可迭代对象。若需按 id 获取实体,请使用 `EntityComponent.get_entity(entity_id)`。([@balloob] - [#11691]) (breaking change) ## 全部变更 * 升级 keyring to 10.6.0 ([@fabaff] - [#11608]) * Upgrad youtube\_dl to 2017.12.31 ([@fabaff] - [#11610]) * small sonos cleanup ([@pvizeli] - [#11607]) ([媒体播放器.sonos docs]) * 更新 Xiaomi Miio compontent broken URI ([@keesschollaart81] - [#11621]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) * 灯光/mqqt\_json: allow brightness scaling ([@jkoelker] - [#11613]) * Adding support for Lutron 遮盖 ([@nickovs] - [#11602]) ([lutron docs]) ([遮盖.lutron docs]) (new-platform) * Hyperion: Add brightness, HDMI and effect support ([@starkillerOG] - [#11543]) ([灯光.hyperion docs]) * Fixes and enhancements for the Tahoma platform ([@glpatcern] - [#11547]) ([tahoma docs]) ([遮盖.tahoma docs]) (breaking change) * 升级 xiaomi lib ([@danielhiversen] - [#11629]) * Add 模板 to MQTT 温控 ([@tinloaf] - [#11623]) * 升级 coinmarketcap to 4.1.2 ([@fabaff] - [#11634]) * Add Deconz support for Zigbee green power 设备 like Hue Tap ([@Kane610] - [#11455]) ([deconz docs]) ([传感器.deconz docs]) * Bump dev to 0.62.0.dev0 ([@fabaff] - [#11652]) * Add ability to specify a sender in the clicksend 通知 ([@heydonms] - [#11046]) ([通知.clicksend docs]) * Round values to one decimal ([@covrig] - [#11673]) ([传感器.xiaomi\_aqara docs][传感器.xiaomi_aqara docs]) * Add basic mychevy component ([@sdague] - [#11409]) ([mychevy docs]) (new-platform) * 更新 mypy commandline arguments ([@benleb] - [#11638]) * Add support for configuring jeelink RF parameters ([@hthiery] - [#11620]) * Wemo Dimmer Support ([@angel12] - [#10882]) ([wemo docs]) ([灯光.wemo docs]) * add temperature controls to eph-ember ([@ttroy50] - [#11400]) ([温控.ephember docs]) * 升级 youtube\_dl to 2018.01.14 ([@fabaff] - [#11661]) * Change line separator to LN ([@fabaff] - [#11662]) ([hive docs]) ([map docs]) ([binary\_sensor.hive docs][binary_sensor.hive docs]) ([温控.hive docs]) ([灯光.hive docs]) ([通知.prowl docs]) ([传感器.hive docs]) ([开关.hive docs]) * 升级 sqlalchemy to 1.2.1 ([@fabaff] - [#11666]) * 升级 pylast to 2.1.0 ([@fabaff] - [#11668]) * Added extra arguments to onvif platform config ([@karlkar] - [#11680]) ([摄像头.onvif docs]) * Enable probot move ([@fabaff] - [#11690]) * fixed not to include spaces or dots in 属性 names ([@olskar] - [#11694]) ([传感器.mold\_indicator docs][传感器.mold_indicator docs]) (breaking change) * Add 属性 ([@fabaff] - [#11698]) ([传感器.random docs]) * Feature/fritzdect errorhandling ([@BastianPoe] - [#11490]) * Tesla bug fix #11598 ([@zabuldon] - [#11707]) * 更新 mold\_indicator.py ([@olskar] - [#11715]) ([传感器.mold\_indicator docs][传感器.mold_indicator docs]) * Override default name for TP-Link 设备 ([@DanNixon] - [#11710]) ([灯光.tplink docs]) ([开关.tplink docs]) * Don't use None inside header ([@pvizeli] - [#11725]) ([hassio docs]) * Add enable\_output 服务 to Yamaha platform ([@postlund] - [#11103]) ([媒体播放器.yamaha docs]) * Fix effects not appearing in UI due to missing 属性 ([@shortbloke] - [#11738]) ([灯光.flux\_led docs][灯光.flux_led docs]) * Fix for None object access attempt ([@karlkar] - [#11748]) * Fixed universal media player templated source\_select bug (issue #10981) and corrected typo in test\_universal ([@iliketoprogram14] - [#11746]) * Fix Tahoma 设备 class ([@thijsdejong] - [#11745]) ([遮盖.tahoma docs]) * Add deCONZ 实体 in a predicitive order ([@Kane610] - [#11712]) ([binary\_sensor.deconz docs][binary_sensor.deconz docs]) ([传感器.deconz docs]) * Xbox 传感器 - Extend 错误 handling ([@ReneNulschDE] - [#11637]) ([传感器.xbox\_live docs][传感器.xbox_live docs]) * 升级 netdisco ([@balloob] - [#11752]) * set default value for rfxtrx config ([@danielhiversen] - [#11767]) ([binary\_sensor.rfxtrx docs][binary_sensor.rfxtrx docs]) * Round off exchange rate ([@arsaboo] - [#11765]) ([传感器.alpha\_vantage docs][传感器.alpha_vantage docs]) * 更新 icon (fixes #11744) ([@fabaff] - [#11758]) ([传感器.fixer docs]) * Use localized forecast for openweathermap ([@brainexe] - [#11770]) ([传感器.openweathermap docs]) * Unit should be mph as that is what the metoffices datapoint API returns ([@ioangogo] - [#11760]) ([metoffice docs]) * Owntracks: Use bluetooth\_le as source\_type if beacon was used for location change. ([@cnrd] - [#11615]) ([device\_tracker.owntracks docs][device_tracker.owntracks docs]) * Add a 'last' mode and 属性 to min\_max 传感器 ([@markferry] - [#11037]) ([传感器.min\_max docs][传感器.min_max docs]) * 更新 header and make it less verbose ([@fabaff] - [#11774]) ([asterisk\_mbox docs][asterisk_mbox docs]) * Added support for TekSavvy bandwidth 传感器 ([@jpjodoin] - [#11186]) (new-platform) * Fix for Neato D3 and D5 ([@karlkar] - [#11775]) * Axis discovery fails to save conf ([@Kane610] - [#11769]) ([axis docs]) * Limit 服务 description loading to a single Thread ([@amelchio] - [#11733]) * Snips: (change) Removed unknown intent speech response ([@tschmidty69] - [#11776]) ([snips docs]) * Implemented event\_data\_template (new) ([@tschmidty69] - [#11057]) * Fix PEP8 and PEP257 issues ([@fabaff] - [#11780]) ([deconz docs]) ([场景 docs]) ([binary\_sensor.deconz docs][binary_sensor.deconz docs]) ([灯光.deconz docs]) ([传感器.deconz docs]) * Fix typos ([@fabaff] - [#11781]) ([system\_log docs][system_log docs]) * Support for performance mode on Rheem 热水器. ([@w1ll1am23] - [#11786]) ([温控.econet docs]) * 服务 for setting a fixed 场景 of Xiaomi MIIO 灯光 ([@syssi] - [#10819]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) * Homematic ip tilt 遮盖 ([@steffenslavetinsky] - [#11650]) ([遮盖.homematic docs]) * plant - check history for min\_brightness ([@ChristianKuehnel] - [#9534]) ([plant docs]) * add generic rollershutter again, was missing in last merge ([@philklei] - [#11788]) ([tahoma docs]) * Additional 属性 and 服务 of the Xiaomi Air Purifier introduced ([@syssi] - [#11249]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) ([开关.xiaomi\_miio docs][开关.xiaomi_miio docs]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) * flux led 版本 0.20 ([@danielhiversen] - [#11791]) * Hyperion: fix ([@starkillerOG] - [#11793]) ([灯光.hyperion docs]) * Fix sensibo function names ([@andrey-git] - [#11797]) ([温控.sensibo docs]) * Always load yr picture from https ([@andrey-git] - [#11796]) * Make Google TTS secure ([@PRabahy] - [#11031]) ([tts.google docs]) * Correct inadvertent change to file permissions ([@shortbloke] - [#11755]) ([灯光.flux\_led docs][灯光.flux_led docs]) * Fix recorder purge ([@tinloaf] - [#11802]) * Disable installing Telldus in Docker ([@balloob] - [#11806]) * Nad ([@robhuls] - [#11800]) * bump roku 版本 ([@soberstadt] - [#11816]) * MiFlora - use bluepy on linux systems ([@ChristianKuehnel] - [#11284]) ([灯光.decora docs]) ([传感器.miflora docs]) * Ihc component and platforms ([@dingusdk] - [#10916]) ([ihc docs]) ([binary\_sensor.ihc docs][binary_sensor.ihc docs]) ([灯光.ihc docs]) ([传感器.ihc docs]) ([开关.ihc docs]) (new-platform) * Change telldus domain to download.telldus.com ([@michaelarnauts] - [#11825]) * Add more workday 传感器 countries and 更新 holidays library to 版本 0.9.3 ([@drndos] - [#11826]) ([binary\_sensor.workday docs][binary_sensor.workday docs]) * Add missing availability schema to MQTT 报警 面板 ([@DanNixon] - [#11829]) ([alarm\_control\_panel.MQTT docs][alarm_control_panel.MQTT docs]) * python-miio 版本 bumped. Fixes all xiaomi\_miio components. (Closes: #11768) ([@syssi] - [#11837]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) ([开关.xiaomi\_miio docs][开关.xiaomi_miio docs]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) * Add waterfurnace platform ([@sdague] - [#11732]) * (Re)Enable Daikin autodiscovery ([@rofrantz] - [#11842]) * Fixes for PEP257 ([@fabaff] - [#11810]) * bump eq3bt 版本 ([@rytilahti] - [#11834]) ([温控.eq3btsmart docs]) * Fix Unifi direct 错误 caused by AP reboot. ([@w1ll1am23] - [#11835]) ([device\_tracker.unifi\_direct docs][device_tracker.unifi_direct docs]) * Change 'on' to 'heat' as fallback thermostat mode ([@andrewdolphin] - [#11377]) ([google\_assistant docs][google_assistant docs]) * Use strict timeout when polling Samsung TV (Fix for #6375) ([@kennedyshead] - [#11759]) ([媒体播放器.samsungtv docs]) * Fix issues with generic thermostat ([@ciotlosm] - [#11805]) * maxcube: Set MAX! Window 传感器's class to 'window' ([@leppa] - [#11799]) ([binary\_sensor.maxcube docs][binary_sensor.maxcube docs]) * Fix new iframe 面板 url ([@pvizeli] - [#11850]) ([hassio docs]) * Fix races on recorder test ([@sdague] - [#11857]) * Clean up 实体 component ([@balloob] - [#11691]) (breaking change) * Allow exposing 传感器 as temperature or humidity '温控' 设备 to Google Assistant ([@rofrantz] - [#11095]) ([google\_assistant docs][google_assistant docs]) * BME680 传感器 Component ([@arcsur] - [#11695]) * Respond to Alexa 场景 activation correctly ([@bitglue] - [#11869]) ([alexa docs]) * Checking Xiaomi Aqara 设备 unavailability 状态 ([@PaulAnnekov] - [#11631]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) ([binary\_sensor.xiaomi\_aqara docs][binary_sensor.xiaomi_aqara docs]) ([遮盖.xiaomi\_aqara docs][遮盖.xiaomi_aqara docs]) ([灯光.xiaomi\_aqara docs][灯光.xiaomi_aqara docs]) ([传感器.xiaomi\_aqara docs][传感器.xiaomi_aqara docs]) ([开关.xiaomi\_aqara docs][开关.xiaomi_aqara docs]) * Hass.io 面板 v2 ([@pvizeli] - [#11860]) ([hassio docs]) * Add missing mock call for test\_minimal\_config ([@sdague] - [#11858]) * Expose Alexa Smart Home via HTTP POST ([@bitglue] - [#11859]) ([alexa docs]) * fixed async function called in a Thread ([@PaulAnnekov] - [#11882]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * 升级 ecobee ([@nkgilley] - [#11878]) ([ecobee docs]) * Fix for hive aux\_heat target temperature display ([@Rendili] - [#11884]) ([hive docs]) * Bump waterfurnace library to 0.3.0 ([@sdague] - [#11888]) ([waterfurnace docs]) * Postpone "Z-Wave not ready" 警告 ([@amelchio] - [#11807]) ([zwave docs]) * \[SMALL-PR] Don't make 温控 calls if feature is not supported ([@rofrantz] - [#11841]) ([温控 docs]) * Handle Daikin AC adapters without 风扇 mode and swing mode support ([@rofrantz] - [#11840]) ([温控.daikin docs]) * 设备 tracker - tomato https support ([@GregoryDosh] - [#11566]) ([device\_tracker.tomato docs][device_tracker.tomato docs]) * Bme680 ([@arcsur] - [#11892]) ([传感器.bme680 docs]) * Add android option for linux\_battery.py ([@mu4yu3] - [#11852]) ([传感器.linux\_battery docs][传感器.linux_battery docs]) * Pushbullet (fix) invalid keyword, added unittests ([@tschmidty69] - [#11804]) * Snips - (fix) removed endSession MQTT response on 错误 and unknown intents ([@tschmidty69] - [#11908]) ([snips docs]) * Clarify emulated hue 警告 ([@balloob] - [#11910]) ([emulated\_hue docs][emulated_hue docs]) * Use API to discover Hue if no bridges specified ([@balloob] - [#11909]) ([hue docs]) * 更新 python-wink 版本 and multiple wink fixes/updates. ([@w1ll1am23] - [#11833]) ([wink docs]) ([binary\_sensor.wink docs][binary_sensor.wink docs]) ([温控.wink docs]) ([遮盖.wink docs]) * New venstar 温控 component ([@Cinntax] - [#11639]) * Iota wallet ([@jinnerbichler] - [#11398]) ([iota docs]) ([传感器.iota docs]) (new-platform) * Improve foscam library exception support ([@i-am-shodan] - [#11701]) ([摄像头.foscam docs]) * Added Xeoma 摄像头 platform ([@jeradM] - [#11619]) * Multi-房间 Support for Greenwave Reality ([@dfiel] - [#11364]) ([灯光.greenwave docs]) * Minor fix to 配置 validation and related 日志 line. ([@arcsur] - [#11898]) ([传感器.bme680 docs]) * Report 脚本 and groups as 场景 to Alexa ([@bitglue] - [#11900]) ([alexa docs]) * Add ERC20 tokens to etherscan.io 传感器 ([@nkgilley] - [#11916]) ([传感器.etherscan docs]) * Allow separate command and 状态 OIDs and payloads in SNMP 开关 ([@nkaminski] - [#11075]) ([开关.snmp docs]) * Add "write" 服务 to system\_log ([@andrey-git] - [#11901]) ([system\_log docs][system_log docs]) * fixes #11848 ([@kennedyshead] - [#11915]) ([device\_tracker.asuswrt docs][device_tracker.asuswrt docs]) * Allow setting 温控 设备 to AUTO mode via Google Assistant ([@balloob] - [#11923]) ([google\_assistant docs][google_assistant docs]) ([温控.nest docs]) * Fixed rfxtrx binary\_sensor KeyError on missing optional device\_class ([@basschipper] - [#11925]) ([rfxtrx docs]) ([binary\_sensor.rfxtrx docs][binary_sensor.rfxtrx docs]) * Implement Alexa temperature 传感器 ([@bitglue] - [#11930]) ([alexa docs]) * 更新 pyhomematic to 0.1.38 ([@danielperna84] - [#11936]) ([homematic docs]) [#10819]: https://github.com/home-assistant/home-assistant/pull/10819 [#10882]: https://github.com/home-assistant/home-assistant/pull/10882 [#10916]: https://github.com/home-assistant/home-assistant/pull/10916 [#11031]: https://github.com/home-assistant/home-assistant/pull/11031 [#11037]: https://github.com/home-assistant/home-assistant/pull/11037 [#11046]: https://github.com/home-assistant/home-assistant/pull/11046 [#11057]: https://github.com/home-assistant/home-assistant/pull/11057 [#11075]: https://github.com/home-assistant/home-assistant/pull/11075 [#11095]: https://github.com/home-assistant/home-assistant/pull/11095 [#11103]: https://github.com/home-assistant/home-assistant/pull/11103 [#11186]: https://github.com/home-assistant/home-assistant/pull/11186 [#11249]: https://github.com/home-assistant/home-assistant/pull/11249 [#11284]: https://github.com/home-assistant/home-assistant/pull/11284 [#11364]: https://github.com/home-assistant/home-assistant/pull/11364 [#11377]: https://github.com/home-assistant/home-assistant/pull/11377 [#11398]: https://github.com/home-assistant/home-assistant/pull/11398 [#11400]: https://github.com/home-assistant/home-assistant/pull/11400 [#11409]: https://github.com/home-assistant/home-assistant/pull/11409 [#11455]: https://github.com/home-assistant/home-assistant/pull/11455 [#11490]: https://github.com/home-assistant/home-assistant/pull/11490 [#11543]: https://github.com/home-assistant/home-assistant/pull/11543 [#11547]: https://github.com/home-assistant/home-assistant/pull/11547 [#11566]: https://github.com/home-assistant/home-assistant/pull/11566 [#11602]: https://github.com/home-assistant/home-assistant/pull/11602 [#11607]: https://github.com/home-assistant/home-assistant/pull/11607 [#11608]: https://github.com/home-assistant/home-assistant/pull/11608 [#11610]: https://github.com/home-assistant/home-assistant/pull/11610 [#11613]: https://github.com/home-assistant/home-assistant/pull/11613 [#11615]: https://github.com/home-assistant/home-assistant/pull/11615 [#11619]: https://github.com/home-assistant/home-assistant/pull/11619 [#11620]: https://github.com/home-assistant/home-assistant/pull/11620 [#11621]: https://github.com/home-assistant/home-assistant/pull/11621 [#11623]: https://github.com/home-assistant/home-assistant/pull/11623 [#11629]: https://github.com/home-assistant/home-assistant/pull/11629 [#11631]: https://github.com/home-assistant/home-assistant/pull/11631 [#11634]: https://github.com/home-assistant/home-assistant/pull/11634 [#11637]: https://github.com/home-assistant/home-assistant/pull/11637 [#11638]: https://github.com/home-assistant/home-assistant/pull/11638 [#11639]: https://github.com/home-assistant/home-assistant/pull/11639 [#11650]: https://github.com/home-assistant/home-assistant/pull/11650 [#11652]: https://github.com/home-assistant/home-assistant/pull/11652 [#11661]: https://github.com/home-assistant/home-assistant/pull/11661 [#11662]: https://github.com/home-assistant/home-assistant/pull/11662 [#11666]: https://github.com/home-assistant/home-assistant/pull/11666 [#11668]: https://github.com/home-assistant/home-assistant/pull/11668 [#11673]: https://github.com/home-assistant/home-assistant/pull/11673 [#11680]: https://github.com/home-assistant/home-assistant/pull/11680 [#11690]: https://github.com/home-assistant/home-assistant/pull/11690 [#11691]: https://github.com/home-assistant/home-assistant/pull/11691 [#11694]: https://github.com/home-assistant/home-assistant/pull/11694 [#11695]: https://github.com/home-assistant/home-assistant/pull/11695 [#11698]: https://github.com/home-assistant/home-assistant/pull/11698 [#11701]: https://github.com/home-assistant/home-assistant/pull/11701 [#11707]: https://github.com/home-assistant/home-assistant/pull/11707 [#11710]: https://github.com/home-assistant/home-assistant/pull/11710 [#11712]: https://github.com/home-assistant/home-assistant/pull/11712 [#11715]: https://github.com/home-assistant/home-assistant/pull/11715 [#11725]: https://github.com/home-assistant/home-assistant/pull/11725 [#11732]: https://github.com/home-assistant/home-assistant/pull/11732 [#11733]: https://github.com/home-assistant/home-assistant/pull/11733 [#11738]: https://github.com/home-assistant/home-assistant/pull/11738 [#11745]: https://github.com/home-assistant/home-assistant/pull/11745 [#11746]: https://github.com/home-assistant/home-assistant/pull/11746 [#11748]: https://github.com/home-assistant/home-assistant/pull/11748 [#11752]: https://github.com/home-assistant/home-assistant/pull/11752 [#11755]: https://github.com/home-assistant/home-assistant/pull/11755 [#11758]: https://github.com/home-assistant/home-assistant/pull/11758 [#11759]: https://github.com/home-assistant/home-assistant/pull/11759 [#11760]: https://github.com/home-assistant/home-assistant/pull/11760 [#11765]: https://github.com/home-assistant/home-assistant/pull/11765 [#11767]: https://github.com/home-assistant/home-assistant/pull/11767 [#11769]: https://github.com/home-assistant/home-assistant/pull/11769 [#11770]: https://github.com/home-assistant/home-assistant/pull/11770 [#11774]: https://github.com/home-assistant/home-assistant/pull/11774 [#11775]: https://github.com/home-assistant/home-assistant/pull/11775 [#11776]: https://github.com/home-assistant/home-assistant/pull/11776 [#11780]: https://github.com/home-assistant/home-assistant/pull/11780 [#11781]: https://github.com/home-assistant/home-assistant/pull/11781 [#11786]: https://github.com/home-assistant/home-assistant/pull/11786 [#11788]: https://github.com/home-assistant/home-assistant/pull/11788 [#11791]: https://github.com/home-assistant/home-assistant/pull/11791 [#11793]: https://github.com/home-assistant/home-assistant/pull/11793 [#11796]: https://github.com/home-assistant/home-assistant/pull/11796 [#11797]: https://github.com/home-assistant/home-assistant/pull/11797 [#11799]: https://github.com/home-assistant/home-assistant/pull/11799 [#11800]: https://github.com/home-assistant/home-assistant/pull/11800 [#11802]: https://github.com/home-assistant/home-assistant/pull/11802 [#11804]: https://github.com/home-assistant/home-assistant/pull/11804 [#11805]: https://github.com/home-assistant/home-assistant/pull/11805 [#11806]: https://github.com/home-assistant/home-assistant/pull/11806 [#11807]: https://github.com/home-assistant/home-assistant/pull/11807 [#11810]: https://github.com/home-assistant/home-assistant/pull/11810 [#11816]: https://github.com/home-assistant/home-assistant/pull/11816 [#11825]: https://github.com/home-assistant/home-assistant/pull/11825 [#11826]: https://github.com/home-assistant/home-assistant/pull/11826 [#11829]: https://github.com/home-assistant/home-assistant/pull/11829 [#11833]: https://github.com/home-assistant/home-assistant/pull/11833 [#11834]: https://github.com/home-assistant/home-assistant/pull/11834 [#11835]: https://github.com/home-assistant/home-assistant/pull/11835 [#11837]: https://github.com/home-assistant/home-assistant/pull/11837 [#11840]: https://github.com/home-assistant/home-assistant/pull/11840 [#11841]: https://github.com/home-assistant/home-assistant/pull/11841 [#11842]: https://github.com/home-assistant/home-assistant/pull/11842 [#11850]: https://github.com/home-assistant/home-assistant/pull/11850 [#11852]: https://github.com/home-assistant/home-assistant/pull/11852 [#11857]: https://github.com/home-assistant/home-assistant/pull/11857 [#11858]: https://github.com/home-assistant/home-assistant/pull/11858 [#11859]: https://github.com/home-assistant/home-assistant/pull/11859 [#11860]: https://github.com/home-assistant/home-assistant/pull/11860 [#11869]: https://github.com/home-assistant/home-assistant/pull/11869 [#11878]: https://github.com/home-assistant/home-assistant/pull/11878 [#11882]: https://github.com/home-assistant/home-assistant/pull/11882 [#11884]: https://github.com/home-assistant/home-assistant/pull/11884 [#11888]: https://github.com/home-assistant/home-assistant/pull/11888 [#11892]: https://github.com/home-assistant/home-assistant/pull/11892 [#11898]: https://github.com/home-assistant/home-assistant/pull/11898 [#11900]: https://github.com/home-assistant/home-assistant/pull/11900 [#11901]: https://github.com/home-assistant/home-assistant/pull/11901 [#11908]: https://github.com/home-assistant/home-assistant/pull/11908 [#11909]: https://github.com/home-assistant/home-assistant/pull/11909 [#11910]: https://github.com/home-assistant/home-assistant/pull/11910 [#11915]: https://github.com/home-assistant/home-assistant/pull/11915 [#11916]: https://github.com/home-assistant/home-assistant/pull/11916 [#11923]: https://github.com/home-assistant/home-assistant/pull/11923 [#11925]: https://github.com/home-assistant/home-assistant/pull/11925 [#11930]: https://github.com/home-assistant/home-assistant/pull/11930 [#11936]: https://github.com/home-assistant/home-assistant/pull/11936 [#9534]: https://github.com/home-assistant/home-assistant/pull/9534 [@BastianPoe]: https://github.com/BastianPoe [@ChristianKuehnel]: https://github.com/ChristianKuehnel [@Cinntax]: https://github.com/Cinntax [@DanNixon]: https://github.com/DanNixon [@GregoryDosh]: https://github.com/GregoryDosh [@Kane610]: https://github.com/Kane610 [@PRabahy]: https://github.com/PRabahy [@PaulAnnekov]: https://github.com/PaulAnnekov [@Rendili]: https://github.com/Rendili [@ReneNulschDE]: https://github.com/ReneNulschDE [@amelchio]: https://github.com/amelchio [@andrewdolphin]: https://github.com/andrewdolphin [@andrey-git]: https://github.com/andrey-git [@angel12]: https://github.com/angel12 [@arcsur]: https://github.com/arcsur [@arsaboo]: https://github.com/arsaboo [@thijsdejong]: https://github.com/thijsdejong [@balloob]: https://github.com/balloob [@basschipper]: https://github.com/basschipper [@benleb]: https://github.com/benleb [@bitglue]: https://github.com/bitglue [@brainexe]: https://github.com/brainexe [@ciotlosm]: https://github.com/ciotlosm [@cnrd]: https://github.com/cnrd [@covrig]: https://github.com/covrig [@danielhiversen]: https://github.com/danielhiversen [@danielperna84]: https://github.com/danielperna84 [@dfiel]: https://github.com/dfiel [@dingusdk]: https://github.com/dingusdk [@drndos]: https://github.com/drndos [@fabaff]: https://github.com/fabaff [@glpatcern]: https://github.com/glpatcern [@heydonms]: https://github.com/heydonms [@hthiery]: https://github.com/hthiery [@i-am-shodan]: https://github.com/i-am-shodan [@iliketoprogram14]: https://github.com/iliketoprogram14 [@ioangogo]: https://github.com/ioangogo [@jeradM]: https://github.com/jeradM [@jinnerbichler]: https://github.com/jinnerbichler [@jkoelker]: https://github.com/jkoelker [@jpjodoin]: https://github.com/jpjodoin [@karlkar]: https://github.com/karlkar [@keesschollaart81]: https://github.com/keesschollaart81 [@kennedyshead]: https://github.com/kennedyshead [@leppa]: https://github.com/leppa [@markferry]: https://github.com/markferry [@michaelarnauts]: https://github.com/michaelarnauts [@mu4yu3]: https://github.com/mu4yu3 [@nickovs]: https://github.com/nickovs [@nkaminski]: https://github.com/nkaminski [@nkgilley]: https://github.com/nkgilley [@olskar]: https://github.com/olskar [@philklei]: https://github.com/philklei [@postlund]: https://github.com/postlund [@pvizeli]: https://github.com/pvizeli [@robhuls]: https://github.com/robhuls [@rofrantz]: https://github.com/rofrantz [@rytilahti]: https://github.com/rytilahti [@sdague]: https://github.com/sdague [@shortbloke]: https://github.com/shortbloke [@soberstadt]: https://github.com/soberstadt [@starkillerOG]: https://github.com/starkillerOG [@steffenslavetinsky]: https://github.com/steffenslavetinsky [@syssi]: https://github.com/syssi [@tinloaf]: https://github.com/tinloaf [@tschmidty69]: https://github.com/tschmidty69 [@ttroy50]: https://github.com/ttroy50 [@w1ll1am23]: https://github.com/w1ll1am23 [@zabuldon]: https://github.com/zabuldon [alarm_control_panel.MQTT docs]: /integrations/alarm_control_panel.MQTT/ [alexa docs]: /integrations/alexa/ [asterisk_mbox docs]: /integrations/asterisk_mbox/ [axis docs]: /integrations/axis/ [binary_sensor.deconz docs]: /integrations/deconz#binary-传感器 [binary_sensor.hive docs]: /integrations/hive#binary-传感器 [binary_sensor.ihc docs]: /integrations/ihc#binary-传感器 [binary_sensor.maxcube docs]: /integrations/maxcube [binary_sensor.rfxtrx docs]: /integrations/rfxtrx#binary-传感器 [binary_sensor.wink docs]: /integrations/wink#binary-传感器 [binary_sensor.workday docs]: /integrations/workday [binary_sensor.xiaomi_aqara docs]: /integrations/binary_sensor.xiaomi_aqara/ [摄像头.foscam docs]: /integrations/foscam [摄像头.onvif docs]: /integrations/onvif [温控 docs]: /integrations/温控/ [温控.daikin docs]: /integrations/daikin#温控 [温控.econet docs]: /integrations/econet [温控.ephember docs]: /integrations/ephember [温控.eq3btsmart docs]: /integrations/eq3btsmart [温控.hive docs]: /integrations/hive#温控 [温控.nest docs]: /integrations/nest#温控 [温控.sensibo docs]: /integrations/sensibo [温控.wink docs]: /integrations/wink#温控 [遮盖.homematic docs]: /integrations/homematic [遮盖.lutron docs]: /integrations/lutron [遮盖.tahoma docs]: /integrations/tahoma [遮盖.wink docs]: /integrations/wink#遮盖 [遮盖.xiaomi_aqara docs]: /integrations/遮盖.xiaomi_aqara/ [deconz docs]: /integrations/deconz/ [device_tracker.asuswrt docs]: /integrations/asuswrt [device_tracker.owntracks docs]: /integrations/owntracks [device_tracker.tomato docs]: /integrations/tomato [device_tracker.unifi_direct docs]: /integrations/unifi_direct/ [ecobee docs]: /integrations/ecobee/ [emulated_hue docs]: /integrations/emulated_hue/ [风扇.xiaomi_miio docs]: /integrations/风扇.xiaomi_miio/ [google_assistant docs]: /integrations/google_assistant/ [hassio docs]: /integrations/hassio/ [hive docs]: /integrations/hive/ [homematic docs]: /integrations/homematic/ [hue docs]: /integrations/hue/ [ihc docs]: /integrations/ihc/ [ihc.const docs]: /integrations/ihc.const/ [ihc.ihcdevice docs]: /integrations/ihc.ihcdevice/ [iota docs]: /integrations/iota/ [灯光.deconz docs]: /integrations/deconz#灯光 [灯光.decora docs]: /integrations/decora [灯光.flux_led docs]: /integrations/flux_led [灯光.greenwave docs]: /integrations/greenwave [灯光.hive docs]: /integrations/hive#灯光 [灯光.hyperion docs]: /integrations/hyperion [灯光.ihc docs]: /integrations/ihc#灯光 [灯光.tplink docs]: /integrations/tplink [灯光.wemo docs]: /integrations/wemo [灯光.xiaomi_aqara docs]: /integrations/灯光.xiaomi_aqara/ [灯光.xiaomi_miio docs]: /integrations/灯光.xiaomi_miio/ [lutron docs]: /integrations/lutron/ [map docs]: /integrations/map/ [媒体播放器.samsungtv docs]: /integrations/samsungtv [媒体播放器.sonos docs]: /integrations/sonos [媒体播放器.yamaha docs]: /integrations/yamaha [metoffice docs]: /integrations/metoffice/ [通知.clicksend docs]: /integrations/clicksend [通知.prowl docs]: /integrations/prowl [plant docs]: /integrations/plant/ [rfxtrx docs]: /integrations/rfxtrx/ [场景 docs]: /integrations/场景/ [传感器.alpha_vantage docs]: /integrations/alpha_vantage [传感器.linux_battery docs]: /integrations/linux_battery [传感器.bme680 docs]: /integrations/bme680 [传感器.deconz docs]: /integrations/deconz#传感器 [传感器.etherscan docs]: /integrations/etherscan [传感器.fixer docs]: /integrations/fixer [传感器.hive docs]: /integrations/hive#传感器 [传感器.ihc docs]: /integrations/ihc#传感器 [传感器.iota docs]: /integrations/iota#传感器 [传感器.miflora docs]: /integrations/miflora [传感器.min_max docs]: /integrations/min_max [传感器.mold_indicator docs]: /integrations/mold_indicator [mychevy docs]: /integrations/mychevy/ [传感器.openweathermap docs]: /integrations/openweathermap#传感器 [传感器.random docs]: /integrations/random#传感器 [传感器.xbox_live docs]: /integrations/xbox_live [传感器.xiaomi_aqara docs]: /integrations/传感器.xiaomi_aqara/ [snips docs]: /integrations/snips/ [开关.hive docs]: /integrations/hive#开关 [开关.ihc docs]: /integrations/ihc#开关 [开关.snmp docs]: /integrations/snmp#开关 [开关.tplink docs]: /integrations/tplink [开关.xiaomi_aqara docs]: /integrations/开关.xiaomi_aqara/ [开关.xiaomi_miio docs]: /integrations/开关.xiaomi_miio/ [system_log docs]: /integrations/system_log/ [tahoma docs]: /integrations/tahoma/ [tts.google docs]: /integrations/google_translate [吸尘器.xiaomi_miio docs]: /integrations/吸尘器.xiaomi_miio/ [waterfurnace docs]: /integrations/waterfurnace/ [wemo docs]: /integrations/wemo/ [wink docs]: /integrations/wink/ [xiaomi_aqara docs]: /integrations/xiaomi_aqara/ [zwave docs]: /integrations/zwave/ [@martinhjelmare]: https://github.com/martinhjelmare [@frenck]: https://github.com/frenck [#11929]: https://github.com/home-assistant/home-assistant/pull/11929 [#11960]: https://github.com/home-assistant/home-assistant/pull/11960 [#12000]: https://github.com/home-assistant/home-assistant/pull/12000 [#12008]: https://github.com/home-assistant/home-assistant/pull/12008 [#12010]: https://github.com/home-assistant/home-assistant/pull/12010 [#12039]: https://github.com/home-assistant/home-assistant/pull/12039 [#12043]: https://github.com/home-assistant/home-assistant/pull/12043 [@ReneNulschDE]: https://github.com/ReneNulschDE [@amelchio]: https://github.com/amelchio [@c727]: https://github.com/c727 [@rofrantz]: https://github.com/rofrantz [@scop]: https://github.com/scop [@smoldaner]: https://github.com/smoldaner [@tschmidty69]: https://github.com/tschmidty69 [温控.daikin docs]: /integrations/daikin#温控 [device_tracker.asuswrt docs]: /integrations/asuswrt [前端 docs]: /integrations/frontend/ [媒体播放器.squeezebox docs]: /integrations/squeezebox [遥控器.harmony docs]: /integrations/harmony [传感器.deutsche_bahn docs]: /integrations/deutsche_bahn [snips docs]: /integrations/snips/ --- url: /home-assistant/blog/2018-02-09-disabling-disqus.md --- # 停用 Disqus 评论 上周,从 [Home Assistant 0.62](/home-assistant/blog/2018/01/27/release-62/) 发布开始,我们将博客评论切换到了[社区论坛](https://community.home-assistant.io)。这样一来,大家可以直接使用现有的 Home Assistant 社区账号参与博客讨论,彼此互动。对用户来说,也少了一个需要额外关注的渠道。 之前我们一直使用 Disqus 免费版承载博客评论。切换后,为了保留历史评论,我们原本只在旧博客页面继续保留 Disqus。但今天我们决定也将其关闭。 今天 Disqus 调整了广告策略,在评论区上下展示了不相关的图形广告([截图](https://twitter.com/balloob/status/961677501725421568))。在手机上,这些广告占据了大量屏幕空间,几乎整页都是减肥奶粉广告。过去 Disqus 的广告方式相对克制,主要是推荐访问者可能感兴趣的内容。 从今天起,所有博客文章都已切换到新评论系统,不再提供 Disqus 评论。我们也在探索恢复历史评论的方法。 --- url: /home-assistant/blog/2018-02-10-release-63.md --- # 0.63:实体注册表、SQL 传感器、Mercedes 车辆 ## Python 3.4 停止支持时间已确定 正如我们在 [去年 10 月的公告](/home-assistant/blog/2017/10/06/deprecating-python-3.4-support/) 中提到的,Home Assistant 将在 2018 年停止支持 Python 3.4。现在我们确定:再过两个版本(0.65)后,最低支持的 Python 版本将提升到 3.5.3。这对大多数用户不会有影响。如果你使用的是 Hass.io、Debian Stable(Stretch)或其衍生发行版(如 Raspbian、Ubuntu),通常无需担心。 ## 实体注册表 本次发布引入了实体注册表。实体注册表允许集成为设备预留实体 ID。这意味着系统会自动为设备分配实体 ID,并且该 ID 会被保留,不会再被其他设备占用。同时,作为用户,你也可以为这些设备自定义实体 ID。 要让集成使用实体注册表,需要为每个实体定义唯一 ID。这个唯一 ID 必须能够稳定、唯一地识别设备,且不可配置。例如序列号和 MAC 地址是合适的,而 IP 地址或设备名称不合适。 本次发布中,已定义唯一 ID 的集成包括:Z-Wave、Hue、Nest、LIFX、Sonos 和 Apple TV。 如果你想修改设备将被分配的实体 ID,请编辑 `/entity_registry.yaml` 并重启 Home Assistant(未来版本计划支持无需重启的热重载)。 实体注册表会在设备首次被发现时分配实体 ID。默认情况下,这个 ID 应与过去一致;如果不一致,请更新注册表条目,将其改回旧的实体 ID。 围绕实体注册表,我们还有很多很酷的计划,敬请期待! ## 新平台 * Adds allergy/disease 传感器 platform from Pollen.com ([@bachya] - [#11573]) ([传感器.pollen docs]) (new-platform) * Add Goalfeed platform ([@craigjmidwinter] - [#11098]) ([goalfeed docs]) (new-platform) * Add Melissa (HVAC/温控) component ([@kennedyshead] - [#11503]) ([melissa docs]) ([传感器.melissa docs]) (new-platform) * Mediaroom ([@dgomes] - [#11864]) ([媒体播放器.mediaroom docs]) (new-platform) * Add Xiaomi Universal IR 遥控器 (Chuangmi IR) ([@cnrd] - [#11891]) ([遥控器.xiaomi\_miio docs][遥控器.xiaomi_miio docs]) (new-platform) * SQL 传感器 ([@dgomes] - [#12142]) ([传感器.sql docs]) (new-platform) * Add Mercedes me component ([@ReneNulschDE] - [#11743]) (new-platform) ## 发布 0.63.1 - February 12 * Fix Alexa Step Volume ([@lucasweb78] - [#12314]) ([alexa docs]) * Remove unique ID from netatmo ([@balloob] - [#12317]) ([binary\_sensor.netatmo docs][binary_sensor.netatmo docs]) ([摄像头.netatmo docs]) ([传感器.netatmo docs]) * Allow overriding name via 实体 registry ([@balloob] - [#12292]) * Respect 实体 namespace for 实体 registry ([@balloob] - [#12313]) * Fix Report 状态 for Alexa Brightness Controller ([@lucasweb78] - [#12318]) ([alexa docs]) * Always return lockState == LOCKED when handling Alexa.LockController ([@lucasweb78] - [#12328]) ([alexa docs]) * Fix platform dependencies ([@balloob] - [#12330]) ## 发布 0.63.2 - February 14 * Fix MercedesMe - add check for unsupported features ([@ReneNulschDE] - [#12342]) (mercedesme docs) (binary\_sensor.mercedesme docs) (device\_tracker.mercedesme docs) (传感器.mercedesme docs) * Fix WUnderground names ([@OttoWinter] - [#12346]) ([传感器.wunderground docs]) * Updated beacontools ([@citruz] - [#12368]) ([传感器.eddystone\_temperature docs][传感器.eddystone_temperature docs]) * Introduce zone\_id to identify player+区域 ([@sdague] - [#12382]) ([媒体播放器.yamaha docs]) * Downgrade limitlessled to 1.0.8 ([@amelchio] - [#12403]) ([灯光.limitlessled docs]) ## 发布 0.63.3 - February 17 * python-miio 版本 bumped. (Closes: #12389, Closes: #12298) ([@syssi] - [#12392]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) ([遥控器.xiaomi\_miio docs][遥控器.xiaomi_miio docs]) ([开关.xiaomi\_miio docs][开关.xiaomi_miio docs]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) * Fixed 3 small issues in isy994 component ([@OverloadUT] - [#12421]) ([isy994 docs]) * Reduce the load on met.no servers, yr.no 传感器 ([@danielhiversen] - [#12435]) * Fix for contentRating 错误 ([@ryanm101] - [#12445]) ([媒体播放器.plex docs]) * Fix 灯光 模板 to return brightness as int ([@andrey-git] - [#12447]) ([灯光.模板 docs]) * Optimize recorder purge ([@amelchio] - [#12448]) * \[SQL 传感器] always close session ([@dgomes] - [#12452]) ([传感器.sql docs]) ## 需要帮助? 如果你需要帮助,欢迎前往我们非常活跃的 [论坛](https://community.home-assistant.io/),或加入 [聊天频道](https://discord.gg/c5DvZ4e)。发布说明虽然开放评论,但我们更推荐你使用前面的社区渠道。谢谢! ## 问题反馈 如果你遇到由本次发布引入的问题,请在我们的 [issue tracker](https://github.com/home-assistant/home-assistant/issues) 提交反馈。请确保完整填写 issue 模板中的所有字段。 ## 不向后兼容的变更 * updated 传感器 name ([@philklei] - [#12084]) ([传感器.tahoma docs]) (breaking change) * 过去 Canary 摄像头是按位置添加的,并且只显示因运动触发而捕获的图像。现在改为按设备添加(每个位置可以有多个设备),并支持实时视频流。([@snjoetw] - [#11949]) ([canary docs]) ([摄像头.canary docs]) (breaking change) * 为避免 influxdb 占满连接池,`retry_queue_limit` 这个 influxdb 配置项已不再生效,可以直接删除。([@amelchio] - [#12182]) ([influxdb docs]) (breaking change) * 一些默认实体名称中的拼写错误已经修复([@OttoWinter] - [#12041]),因此会导致以下 `entity_id` 发生变化: * [Seven segments display](/home-assistant/integrations/seven_segments.md): `image_processing.seven_segement_ocr_[...]` → `image_processing.seven_segment_ocr_[...]` * [Rain Bird 开关](/home-assistant/integrations/rainbird.md#开关): `switch.sprinker_[...]` → `switch.sprinkler_[...]` * [OpenEVSE 传感器](/home-assistant/integrations/openevse.md): `sensor.ambient_termperature` → `sensor.ambient_temperature` * [Fido](/home-assistant/integrations/fido.md): `sensor.[...]_internaltional_remaining` → `sensor.[...]_international remaining` * 从 0.64 版本开始,Home Assistant 默认会清理超过 10 天的历史状态记录。如果你想保留更长时间的数据,就必须配置保留天数: ```yaml recorder: purge_keep_days: 30 ``` 如果你想维持之前“永不删除历史记录”的默认行为,请使用以下配置: ```yaml recorder: purge_interval: 0 ``` ([@amelchio] - [#11976]) * Fix duplicate entity\_ids in System Monitor ([@fanaticDavid] - [#12124]) ([传感器.systemmonitor docs]) (breaking change) | Resource | Old 实体 ID | New 实体 ID | | :------------------ | :------------------ |:-------------------------| | disk\_use | 传感器.disk\_used | 传感器.disk\_use | | disk\_use\_percent | 传感器.disk\_used | 传感器.disk\_use\_percent | | load\_15m | 传感器.average\_load\_15m | 传感器.load\_15m | | load\_1m | 传感器.average\_load\_1m | 传感器.load\_1m | | load\_5m | 传感器.average\_load\_5m | 传感器.load\_5m | | memory\_free | 传感器.ram\_available | 传感器.memory\_free | | memory\_use | 传感器.ram\_used | 传感器.memory\_use | | memory\_use\_percent | 传感器.ram\_used | 传感器.memory\_use\_percent | | network\_in | 传感器.received | 传感器.network\_in | | network\_out | 传感器.sent | 传感器.network\_out | | packets\_in | 传感器.packets\_received | 传感器.packets\_in | | packets\_out | 传感器.packets\_sent | 传感器.packets\_out | | processor\_use | 传感器.cpu\_used | 传感器.processor\_use | | swap\_use | 传感器.swap\_used | 传感器.swap\_use | | swap\_use\_percent | 传感器.swap\_used | 传感器.swap\_use\_percent | * 仅针对开发者:以下 EntityComponent 方法已被移除:`extract_from_service`、`async_update_group`、`async_reset`、`prepare_reload`。([@balloob] - [#12237]) (breaking change) ## 全部变更 * Map media\_stop to idle 状态 ([@akloeckner] - [#11819]) * Adds allergy/disease 传感器 platform from Pollen.com ([@bachya] - [#11573]) ([传感器.pollen docs]) (new-platform) * check\_config.py: allow colorlog==3.1. ([@dotlambda] - [#11927]) * Weblink - Allow relative urls in config ([@ReneNulschDE] - [#11808]) * Panel\_Iframe - Allow relative urls in config ([@ReneNulschDE] - [#11832]) ([panel\_iframe docs][panel_iframe docs]) * Python 3.6 invalid escape sequence deprecation fixes ([@scop] - [#11941]) * tests: Use assertEqual instead of deprecated assertEquals ([@scop] - [#11943]) * huawei\_router: Fix 文档 link ([@scop] - [#11961]) ([device\_tracker.huawei\_router docs][device_tracker.huawei_router docs]) * Spelling fixes ([@scop] - [#11940]) * 升级 sqlalchemy to 1.2.2 ([@fabaff] - [#11956]) * 升级 youtube\_dl to 2018.01.21 ([@fabaff] - [#11955]) ([media\_extractor docs][media_extractor docs]) * 升级 sphinx-autodoc-typehints to 1.2.4 ([@fabaff] - [#11954]) * 升级 coinmarketcap to 4.2.1 ([@fabaff] - [#11953]) ([传感器.coinmarketcap docs]) * Bump dev to 0.63.0.dev0 ([@fabaff] - [#11952]) * 更新 xiaomi\_aqara.py ([@MGWGIT] - [#11969]) ([传感器.xiaomi\_aqara docs][传感器.xiaomi_aqara docs]) * panasonic\_viera: Set 设备 name from discovery info ([@scop] - [#11990]) ([媒体播放器.panasonic\_viera docs][媒体播放器.panasonic_viera docs]) * 更新 panasonic\_viera to 0.3 ([@scop] - [#11989]) ([媒体播放器.panasonic\_viera docs][媒体播放器.panasonic_viera docs]) * Fix 11982 - uvc don't handle null as username ([@bratanon] - [#11984]) ([摄像头.uvc docs]) * Add Goalfeed platform ([@craigjmidwinter] - [#11098]) ([goalfeed docs]) (new-platform) * Added support for hourly percent change in coinmarketcap component ([@kevindgoff] - [#11996]) ([传感器.coinmarketcap docs]) * 升级 coinbase to 2.0.7 ([@fabaff] - [#11992]) ([coinbase docs]) ([传感器.coinbase docs]) * 升级 pyota to 2.0.4 ([@fabaff] - [#11991]) ([iota docs]) * Fixed Canary temperature 传感器 and remapped air quality value ([@snjoetw] - [#11355]) ([canary docs]) ([传感器.canary docs]) * Refactor Alexa Smart Home API ([@bitglue] - [#12016]) ([alexa docs]) * Report 状态 ([@bitglue] - [#11973]) ([alexa docs]) * alexa: Add 媒体播放器 InputController support ([@philk] - [#11946]) ([alexa docs]) * emulated\_hue: allow customization within emulated\_hue 配置 ([@jackwilsdon] - [#11981]) ([emulated\_hue docs][emulated_hue docs]) * Flake8 35 ([@scop] - [#11972]) ([feedreader docs]) ([spc docs]) ([媒体播放器.bluesound docs]) ([媒体播放器.clementine docs]) ([传感器.fritzbox\_callmonitor docs][传感器.fritzbox_callmonitor docs]) ([传感器.qnap docs]) ([传感器.synologydsm docs]) * Typing fixes ([@scop] - [#12015]) * Fix DoorBird push 通知 for 安装 with an API 密码 ([@Klikini] - [#12020]) ([doorbird docs]) * Bump upstream lib 版本. ([@Cinntax] - [#12021]) ([温控.venstar docs]) * 传感器.deutsche\_bahn: add only\_direct option ([@akloeckner] - [#11999]) ([传感器.deutsche\_bahn docs][传感器.deutsche_bahn docs]) * Fix MQTT 遮盖 availability subscription ([@OttoWinter] - [#12036]) ([遮盖.MQTT docs]) * Spelling fixes ([@OttoWinter] - [#12041]) (breaking change) * Online 状态 for samsungtv is jumping when TV is idle ([@kennedyshead] - [#11998]) ([媒体播放器.samsungtv docs]) * 升级 astral to 1.5 ([@fabaff] - [#12042]) * Refactor alexa smart\_home tests ([@bitglue] - [#12044]) * Handling of payload not for this 实体. ([@freol35241] - [#11836]) ([binary\_sensor.MQTT docs][binary_sensor.MQTT docs]) * Refactor Google Assistant query\_device ([@philk] - [#12022]) ([google\_assistant docs][google_assistant docs]) * 实体 registry ([@balloob] - [#11979]) ([group docs]) ([温控.nest docs]) * Return all 属性 that are not None in base 门锁 实体 class ([@snjoetw] - [#12049]) ([门锁 docs]) * Extract requirements ([@balloob] - [#12051]) * Prepare for recorder purge to be active by default ([@amelchio] - [#11976]) (breaking change) * Bumped up pymochad requirement to 0.2.0 as a fix for #11928 ([@aosadchyy] - [#12014]) ([mochad docs]) * Publish 错误 on the event bus ([@postlund] - [#11964]) ([system\_log docs][system_log docs]) * Unique ID for LIFX 灯光 ([@amelchio] - [#12064]) ([灯光.lifx docs]) * Deconz use 实体 registry ([@Kane610] - [#12067]) ([deconz docs]) ([binary\_sensor.deconz docs][binary_sensor.deconz docs]) ([灯光.deconz docs]) ([传感器.deconz docs]) * Flake8 bugbear fixes ([@scop] - [#12072]) ([plant docs]) ([rfxtrx docs]) ([zwave docs]) ([温控.heatmiser docs]) ([媒体播放器.plex docs]) ([通知.kodi docs]) * Fix demo platform support ([@ciotlosm] - [#12070]) * fix event channel name ([@craigjmidwinter] - [#12077]) ([goalfeed docs]) * fixed timestamp problem in firefox ([@escoand] - [#12073]) ([天气.openweathermap docs]) * Handle more file closing using context manager ([@scop] - [#11942]) ([灯光.greenwave docs]) ([通知.gntp docs]) ([传感器.onewire docs]) * Influx import improvements ([@RePeet13] - [#11988]) * Set flux default stop time to dusk ([@infernix] - [#12062]) ([开关.flux docs]) * Add 条件 to forecast ([@escoand] - [#12074]) ([天气.openweathermap docs]) * Squeezebox Fix duplicate server from discovery ([@mezz64] - [#12063]) ([媒体播放器.squeezebox docs]) * 升级 keyring to 11.0.0 ([@fabaff] - [#12082]) * Correct use of middleware async handling. ([@pelson] - [#12078]) ([http docs]) * updated 传感器 name ([@philklei] - [#12084]) ([传感器.tahoma docs]) (breaking change) * Fix detection of mobile browsers ([@c727] - [#12075]) ([前端 docs]) * 更新 tahoma api to 版本 0.0.11 ([@philklei] - [#12099]) ([tahoma docs]) * added media\_stop ([@jodur] - [#12100]) ([媒体播放器.vlc docs]) * Goalfeed channel ([@craigjmidwinter] - [#12086]) ([goalfeed docs]) * 更新 jinja2 to 2.10 ([@arsaboo] - [#12118]) * Downgrade Sonarr and Radarr 'Host is not available' 错误 to 警告 ([@timmo001] - [#12119]) ([传感器.radarr docs]) ([传感器.sonarr docs]) * Fixes away\_mode 错误 on startup ([@ciotlosm] - [#12121]) ([温控.generic\_thermostat docs][温控.generic_thermostat docs]) * except vol.MultipleInvalid in Broadlink #11795 ([@danielhiversen] - [#12107]) ([传感器.broadlink docs]) * Adds SUPPORT\_TARGET\_TEMPERATURE\_HIGH and SUPPORT\_TARGET\_TEMPERATURE\_LOW support ([@hawk259] - [#12110]) ([温控.ecobee docs]) * Dark sky precip accumulation ([@nordlead2005] - [#12127]) ([传感器.darksky docs]) * fixed wrong check for valid range of 'rgb' values ([@PaulAnnekov] - [#12132]) ([灯光.xiaomi\_aqara docs][灯光.xiaomi_aqara docs]) * OpenALPR Cloud API - transfer 图像 in body of POST request ([@ReneNulschDE] - [#12112]) ([image\_processing.openalpr\_cloud docs][image_processing.openalpr_cloud docs]) * Add support for "off" function to iTunes ([@lexam79] - [#12109]) ([媒体播放器.itunes docs]) * Remove asyncio.test\_utils to fix tests in Docker/Python 3.7 ([@ubnt-marc-khouri] - [#12102]) * Add Mercedes me component ([@ReneNulschDE] - [#11743]) * Spelling fixes ([@scop] - [#12138]) ([plant docs]) ([开关.pulseaudio\_loopback docs][开关.pulseaudio_loopback docs]) * 更新 volumio component ([@titilambert] - [#12045]) ([媒体播放器.volumio docs]) * Adding information about current TV channel to WebOS media player ([@led-spb] - [#11339]) ([媒体播放器.webostv docs]) * Fix #8475 设备 tracker ubus tracks unauthenticated and unassociated 设备 ([@aarnaud] - [#12140]) ([device\_tracker.ubus docs][device_tracker.ubus docs]) * Fix #11875 Ubus broken since 升级 to 0 57 ([@aarnaud] - [#12141]) ([device\_tracker.ubus docs][device_tracker.ubus docs]) * 更新 flake8-docstrings to 1.0.3 ([@scop] - [#12136]) * Tado fixes ([@NigelRook] - [#11294]) ([tado docs]) ([温控.tado docs]) * Add Melissa (HVAC/温控) component ([@kennedyshead] - [#11503]) ([melissa docs]) ([传感器.melissa docs]) (new-platform) * Mediaroom ([@dgomes] - [#11864]) ([媒体播放器.mediaroom docs]) (new-platform) * 升级 mutagen to 1.40.0 ([@fabaff] - [#12152]) ([tts docs]) * 升级 TwitterAPI to 2.4.8 ([@fabaff] - [#12148]) ([通知.twitter docs]) * fix generic\_thermostat bug when 恢复 状态 from HA start up ([@crhan] - [#12134]) ([温控.generic\_thermostat docs][温控.generic_thermostat docs]) * Adding xy\_color 属性 support to deconz 灯光 ([@ErnstEeldert] - [#12106]) ([灯光.deconz docs]) * 更新 python-openzwave to 4.1.3 ([@perosb] - [#12057]) ([zwave docs]) * Panasonic viera new 服务 ([@dgomes] - [#11963]) ([媒体播放器 docs]) ([媒体播放器.panasonic\_viera docs][媒体播放器.panasonic_viera docs]) * \[Mediaroom 媒体播放器] Follow up on PR #11864 ([@dgomes] - [#12155]) ([媒体播放器.mediaroom docs]) * Tests for samsungtv ([@kennedyshead] - [#11933]) * 升级 influxdb to 5.0.0 ([@fabaff] - [#12156]) ([influxdb docs]) * add delay\_arrival ([@akloeckner] - [#12169]) ([传感器.deutsche\_bahn docs][传感器.deutsche_bahn docs]) * Move TP-Link socket LED 状态 setting to 更新() ([@DanNixon] - [#12170]) ([开关.tplink docs]) * 升级 schiene to 0.21 ([@fabaff] - [#12176]) ([传感器.deutsche\_bahn docs][传感器.deutsche_bahn docs]) * python-miio 版本 bumped. Fixes all xiaomi\_miio components. (Closes: #12017, Closes: #11948, Closes: #11200) ([@syssi] - [#12188]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) ([开关.xiaomi\_miio docs][开关.xiaomi_miio docs]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) * 服务 (small\_pr)(fix): Added missing return on data 模板 错误 ([@tschmidty69] - [#12184]) * fix ecobee is\_aux\_heat\_on property ([@titilambert] - [#12186]) ([温控.ecobee docs]) * 升级 pytouchline to 0.7 ([@tbergo] - [#12179]) ([温控.touchline docs]) * Canary live stream ([@snjoetw] - [#11949]) ([canary docs]) ([摄像头.canary docs]) (breaking change) * Replace Gitter with Discord ([@fabaff] - [#12199]) * 升级 Sphinx to 1.6.7 ([@fabaff] - [#12200]) * Change 属性 in new Mercedes Me component ([@ReneNulschDE] - [#12147]) (mercedesme docs) (binary\_sensor.mercedesme docs) (device\_tracker.mercedesme docs) (传感器.mercedesme docs) * 二元sensor 模板: Add icon\_template and entity\_picture\_template support ([@hawk259] - [#12158]) ([binary\_sensor.模板 docs][binary_sensor.模板 docs]) * Bump pyeconet 版本 to fix JSONDecodeError ([@w1ll1am23] - [#12204]) ([温控.econet docs]) * Add support for Alexa.StepSpeaker ([@lucasweb78] - [#12183]) ([alexa docs]) * 升级 wakeonlan to 1.0.0 ([@Tadly] - [#12190]) ([wake\_on\_lan docs][wake_on_lan docs]) ([媒体播放器.panasonic\_viera docs][媒体播放器.panasonic_viera docs]) ([媒体播放器.samsungtv docs]) ([媒体播放器.webostv docs]) ([开关.wake\_on\_lan docs][开关.wake_on_lan docs]) * zha: 更新 to bellows 0.5.0+zigpy ([@rcloran] - [#12187]) ([zha docs]) ([binary\_sensor.zha docs][binary_sensor.zha docs]) ([灯光.zha docs]) ([传感器.zha docs]) * Make waterfurnace recovery more robust ([@sdague] - [#12202]) ([waterfurnace docs]) * Much nicer icon ([@lance36] - [#12212]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) * Properly handle thresholds of zero ([@DanNixon] - [#12175]) ([binary\_sensor.threshold docs][binary_sensor.threshold docs]) * zha: Add support for XBee radios ([@rcloran] - [#12205]) ([zha docs]) ([binary\_sensor.zha docs][binary_sensor.zha docs]) * Fix clear playlist in Volumio component ([@titilambert] - [#12173]) ([媒体播放器.volumio docs]) * Add Xiaomi Universal IR 遥控器 (Chuangmi IR) ([@cnrd] - [#11891]) ([遥控器.xiaomi\_miio docs][遥控器.xiaomi_miio docs]) (new-platform) * Fix Xeoma 摄像头 platform to allow different admin/viewer credentials ([@jeradM] - [#12161]) ([摄像头.xeoma docs]) * Xiaomi MiIO 灯光: Brightness mapping improved ([@syssi] - [#12203]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) * Fixes according to review from @MartinHjelmare Thank you. ([@kennedyshead] - [#12171]) ([温控.melissa docs]) ([传感器.melissa docs]) * Fix logger bug on Windows: path contains ''. ([@fanthos] - [#12197]) ([system\_log docs][system_log docs]) * Catch concurrent.futures.CancelledError in websocket code. ([@pelson] - [#12150]) ([websocket\_api docs][websocket_api docs]) * 更新 pushsafer.py ([@appzer] - [#11466]) ([通知.pushsafer docs]) * Add wake on lan capability to philips TV ([@frog32] - [#12065]) ([媒体播放器.philips\_js docs][媒体播放器.philips_js docs]) * Specify the minimum python 版本 in the 设置.py. ([@pelson] - [#12144]) * Return of entity\_id in 模板 platforms ([@amelchio] - [#12234]) ([binary\_sensor.模板 docs][binary_sensor.模板 docs]) ([遮盖.模板 docs]) ([灯光.模板 docs]) ([传感器.模板 docs]) ([开关.模板 docs]) * Allow zero purge\_interval to disable recorder purge ([@amelchio] - [#12220]) * 更新 min js=latest 版本 ([@andrey-git] - [#12091]) ([前端 docs]) * librouteros 版本 bump ([@zabuldon] - [#12227]) ([device\_tracker.mikrotik docs][device_tracker.mikrotik docs]) * SQL 传感器 ([@dgomes] - [#12142]) ([传感器.sql docs]) (new-platform) * Fixes for tesla. New 传感器. ([@zabuldon] - [#12225]) ([tesla docs]) ([传感器.tesla docs]) * 实体 layer cleanup ([@balloob] - [#12237]) (breaking change) * \[SMALL PATCH] Sql 传感器 ([@dgomes] - [#12242]) ([传感器.sql docs]) * Set tahoma 遮盖 更新 interval to default ([@thijsdejong] - [#12232]) ([遮盖.tahoma docs]) * Avoid influxdb filling connection pool ([@amelchio] - [#12182]) ([influxdb docs]) (breaking change) * Force 更新 support for MQTT 二元sensor ([@mkfink] - [#12092]) ([binary\_sensor.MQTT docs][binary_sensor.MQTT docs]) * Added 密码 mode to input\_text (obscure content of text box) ([@covrig] - [#11849]) ([input\_text docs][input_text docs]) ([传感器.xiaomi\_aqara docs][传感器.xiaomi_aqara docs]) * Fix 遮盖 服务 description ([@cdce8p] - [#12243]) * Add explicit first-time config for new purge\_keep\_days default ([@amelchio] - [#12246]) * added more 调试 logging for 传感器.alpha\_vantage ([@ChristianKuehnel] - [#12249]) ([传感器.alpha\_vantage docs][传感器.alpha_vantage docs]) * Add 服务 Schema to Broadlink 开关 ([@maddox] - [#12253]) ([开关.broadlink docs]) * 更新 aiohttp 2.3.10 / yarl 1.1.0 ([@pvizeli] - [#12244]) * Fix source code using Windows newline ([@OttoWinter] - [#12248]) * miflora - fix for exception handling bug ([@ChristianKuehnel] - [#12149]) ([传感器.miflora docs]) * 更新 pyhomematic to 0.1.39 ([@danielperna84] - [#12265]) ([homematic docs]) * 更新 owntracks.py ([@luca-angemi] - [#12260]) ([device\_tracker.owntracks docs][device_tracker.owntracks docs]) * Fix for iTunes media player not updating artwork ([@lexam79] - [#12089]) ([媒体播放器.itunes docs]) * Fix duplicate entity\_ids in System Monitor ([@fanaticDavid] - [#12124]) ([传感器.systemmonitor docs]) (breaking change) * One bug fix and one improvement to the statistics 传感器. ([@glance-] - [#12259]) ([传感器.statistics docs]) * allow wildcards in subscription ([@escoand] - [#12247]) ([device\_tracker.MQTT docs][device_tracker.MQTT docs]) * Retry keyset cloud ([@balloob] - [#12270]) ([cloud docs]) * 更新 limitlessled requirement to v1.0.9 ([@vaceslav] - [#12275]) ([灯光.limitlessled docs]) [#11098]: https://github.com/home-assistant/home-assistant/pull/11098 [#11294]: https://github.com/home-assistant/home-assistant/pull/11294 [#11339]: https://github.com/home-assistant/home-assistant/pull/11339 [#11355]: https://github.com/home-assistant/home-assistant/pull/11355 [#11466]: https://github.com/home-assistant/home-assistant/pull/11466 [#11503]: https://github.com/home-assistant/home-assistant/pull/11503 [#11573]: https://github.com/home-assistant/home-assistant/pull/11573 [#11743]: https://github.com/home-assistant/home-assistant/pull/11743 [#11808]: https://github.com/home-assistant/home-assistant/pull/11808 [#11819]: https://github.com/home-assistant/home-assistant/pull/11819 [#11832]: https://github.com/home-assistant/home-assistant/pull/11832 [#11836]: https://github.com/home-assistant/home-assistant/pull/11836 [#11849]: https://github.com/home-assistant/home-assistant/pull/11849 [#11864]: https://github.com/home-assistant/home-assistant/pull/11864 [#11891]: https://github.com/home-assistant/home-assistant/pull/11891 [#11927]: https://github.com/home-assistant/home-assistant/pull/11927 [#11933]: https://github.com/home-assistant/home-assistant/pull/11933 [#11940]: https://github.com/home-assistant/home-assistant/pull/11940 [#11941]: https://github.com/home-assistant/home-assistant/pull/11941 [#11942]: https://github.com/home-assistant/home-assistant/pull/11942 [#11943]: https://github.com/home-assistant/home-assistant/pull/11943 [#11946]: https://github.com/home-assistant/home-assistant/pull/11946 [#11949]: https://github.com/home-assistant/home-assistant/pull/11949 [#11952]: https://github.com/home-assistant/home-assistant/pull/11952 [#11953]: https://github.com/home-assistant/home-assistant/pull/11953 [#11954]: https://github.com/home-assistant/home-assistant/pull/11954 [#11955]: https://github.com/home-assistant/home-assistant/pull/11955 [#11956]: https://github.com/home-assistant/home-assistant/pull/11956 [#11961]: https://github.com/home-assistant/home-assistant/pull/11961 [#11963]: https://github.com/home-assistant/home-assistant/pull/11963 [#11964]: https://github.com/home-assistant/home-assistant/pull/11964 [#11969]: https://github.com/home-assistant/home-assistant/pull/11969 [#11972]: https://github.com/home-assistant/home-assistant/pull/11972 [#11973]: https://github.com/home-assistant/home-assistant/pull/11973 [#11976]: https://github.com/home-assistant/home-assistant/pull/11976 [#11979]: https://github.com/home-assistant/home-assistant/pull/11979 [#11981]: https://github.com/home-assistant/home-assistant/pull/11981 [#11984]: https://github.com/home-assistant/home-assistant/pull/11984 [#11988]: https://github.com/home-assistant/home-assistant/pull/11988 [#11989]: https://github.com/home-assistant/home-assistant/pull/11989 [#11990]: https://github.com/home-assistant/home-assistant/pull/11990 [#11991]: https://github.com/home-assistant/home-assistant/pull/11991 [#11992]: https://github.com/home-assistant/home-assistant/pull/11992 [#11996]: https://github.com/home-assistant/home-assistant/pull/11996 [#11998]: https://github.com/home-assistant/home-assistant/pull/11998 [#11999]: https://github.com/home-assistant/home-assistant/pull/11999 [#12014]: https://github.com/home-assistant/home-assistant/pull/12014 [#12015]: https://github.com/home-assistant/home-assistant/pull/12015 [#12016]: https://github.com/home-assistant/home-assistant/pull/12016 [#12020]: https://github.com/home-assistant/home-assistant/pull/12020 [#12021]: https://github.com/home-assistant/home-assistant/pull/12021 [#12022]: https://github.com/home-assistant/home-assistant/pull/12022 [#12036]: https://github.com/home-assistant/home-assistant/pull/12036 [#12041]: https://github.com/home-assistant/home-assistant/pull/12041 [#12042]: https://github.com/home-assistant/home-assistant/pull/12042 [#12044]: https://github.com/home-assistant/home-assistant/pull/12044 [#12045]: https://github.com/home-assistant/home-assistant/pull/12045 [#12049]: https://github.com/home-assistant/home-assistant/pull/12049 [#12051]: https://github.com/home-assistant/home-assistant/pull/12051 [#12057]: https://github.com/home-assistant/home-assistant/pull/12057 [#12062]: https://github.com/home-assistant/home-assistant/pull/12062 [#12063]: https://github.com/home-assistant/home-assistant/pull/12063 [#12064]: https://github.com/home-assistant/home-assistant/pull/12064 [#12065]: https://github.com/home-assistant/home-assistant/pull/12065 [#12067]: https://github.com/home-assistant/home-assistant/pull/12067 [#12070]: https://github.com/home-assistant/home-assistant/pull/12070 [#12072]: https://github.com/home-assistant/home-assistant/pull/12072 [#12073]: https://github.com/home-assistant/home-assistant/pull/12073 [#12074]: https://github.com/home-assistant/home-assistant/pull/12074 [#12075]: https://github.com/home-assistant/home-assistant/pull/12075 [#12077]: https://github.com/home-assistant/home-assistant/pull/12077 [#12078]: https://github.com/home-assistant/home-assistant/pull/12078 [#12082]: https://github.com/home-assistant/home-assistant/pull/12082 [#12084]: https://github.com/home-assistant/home-assistant/pull/12084 [#12086]: https://github.com/home-assistant/home-assistant/pull/12086 [#12089]: https://github.com/home-assistant/home-assistant/pull/12089 [#12091]: https://github.com/home-assistant/home-assistant/pull/12091 [#12092]: https://github.com/home-assistant/home-assistant/pull/12092 [#12099]: https://github.com/home-assistant/home-assistant/pull/12099 [#12100]: https://github.com/home-assistant/home-assistant/pull/12100 [#12102]: https://github.com/home-assistant/home-assistant/pull/12102 [#12106]: https://github.com/home-assistant/home-assistant/pull/12106 [#12107]: https://github.com/home-assistant/home-assistant/pull/12107 [#12109]: https://github.com/home-assistant/home-assistant/pull/12109 [#12110]: https://github.com/home-assistant/home-assistant/pull/12110 [#12112]: https://github.com/home-assistant/home-assistant/pull/12112 [#12118]: https://github.com/home-assistant/home-assistant/pull/12118 [#12119]: https://github.com/home-assistant/home-assistant/pull/12119 [#12121]: https://github.com/home-assistant/home-assistant/pull/12121 [#12124]: https://github.com/home-assistant/home-assistant/pull/12124 [#12127]: https://github.com/home-assistant/home-assistant/pull/12127 [#12132]: https://github.com/home-assistant/home-assistant/pull/12132 [#12134]: https://github.com/home-assistant/home-assistant/pull/12134 [#12136]: https://github.com/home-assistant/home-assistant/pull/12136 [#12138]: https://github.com/home-assistant/home-assistant/pull/12138 [#12140]: https://github.com/home-assistant/home-assistant/pull/12140 [#12141]: https://github.com/home-assistant/home-assistant/pull/12141 [#12142]: https://github.com/home-assistant/home-assistant/pull/12142 [#12144]: https://github.com/home-assistant/home-assistant/pull/12144 [#12147]: https://github.com/home-assistant/home-assistant/pull/12147 [#12148]: https://github.com/home-assistant/home-assistant/pull/12148 [#12149]: https://github.com/home-assistant/home-assistant/pull/12149 [#12150]: https://github.com/home-assistant/home-assistant/pull/12150 [#12152]: https://github.com/home-assistant/home-assistant/pull/12152 [#12155]: https://github.com/home-assistant/home-assistant/pull/12155 [#12156]: https://github.com/home-assistant/home-assistant/pull/12156 [#12158]: https://github.com/home-assistant/home-assistant/pull/12158 [#12161]: https://github.com/home-assistant/home-assistant/pull/12161 [#12169]: https://github.com/home-assistant/home-assistant/pull/12169 [#12170]: https://github.com/home-assistant/home-assistant/pull/12170 [#12171]: https://github.com/home-assistant/home-assistant/pull/12171 [#12173]: https://github.com/home-assistant/home-assistant/pull/12173 [#12175]: https://github.com/home-assistant/home-assistant/pull/12175 [#12176]: https://github.com/home-assistant/home-assistant/pull/12176 [#12179]: https://github.com/home-assistant/home-assistant/pull/12179 [#12182]: https://github.com/home-assistant/home-assistant/pull/12182 [#12183]: https://github.com/home-assistant/home-assistant/pull/12183 [#12184]: https://github.com/home-assistant/home-assistant/pull/12184 [#12186]: https://github.com/home-assistant/home-assistant/pull/12186 [#12187]: https://github.com/home-assistant/home-assistant/pull/12187 [#12188]: https://github.com/home-assistant/home-assistant/pull/12188 [#12190]: https://github.com/home-assistant/home-assistant/pull/12190 [#12197]: https://github.com/home-assistant/home-assistant/pull/12197 [#12199]: https://github.com/home-assistant/home-assistant/pull/12199 [#12200]: https://github.com/home-assistant/home-assistant/pull/12200 [#12202]: https://github.com/home-assistant/home-assistant/pull/12202 [#12203]: https://github.com/home-assistant/home-assistant/pull/12203 [#12204]: https://github.com/home-assistant/home-assistant/pull/12204 [#12205]: https://github.com/home-assistant/home-assistant/pull/12205 [#12212]: https://github.com/home-assistant/home-assistant/pull/12212 [#12220]: https://github.com/home-assistant/home-assistant/pull/12220 [#12225]: https://github.com/home-assistant/home-assistant/pull/12225 [#12227]: https://github.com/home-assistant/home-assistant/pull/12227 [#12232]: https://github.com/home-assistant/home-assistant/pull/12232 [#12234]: https://github.com/home-assistant/home-assistant/pull/12234 [#12237]: https://github.com/home-assistant/home-assistant/pull/12237 [#12242]: https://github.com/home-assistant/home-assistant/pull/12242 [#12243]: https://github.com/home-assistant/home-assistant/pull/12243 [#12244]: https://github.com/home-assistant/home-assistant/pull/12244 [#12246]: https://github.com/home-assistant/home-assistant/pull/12246 [#12247]: https://github.com/home-assistant/home-assistant/pull/12247 [#12248]: https://github.com/home-assistant/home-assistant/pull/12248 [#12249]: https://github.com/home-assistant/home-assistant/pull/12249 [#12253]: https://github.com/home-assistant/home-assistant/pull/12253 [#12259]: https://github.com/home-assistant/home-assistant/pull/12259 [#12260]: https://github.com/home-assistant/home-assistant/pull/12260 [#12265]: https://github.com/home-assistant/home-assistant/pull/12265 [#12270]: https://github.com/home-assistant/home-assistant/pull/12270 [#12275]: https://github.com/home-assistant/home-assistant/pull/12275 [@ChristianKuehnel]: https://github.com/ChristianKuehnel [@Cinntax]: https://github.com/Cinntax [@DanNixon]: https://github.com/DanNixon [@ErnstEeldert]: https://github.com/ErnstEeldert [@Kane610]: https://github.com/Kane610 [@Klikini]: https://github.com/Klikini [@MGWGIT]: https://github.com/MGWGIT [@NigelRook]: https://github.com/NigelRook [@OttoWinter]: https://github.com/OttoWinter [@PaulAnnekov]: https://github.com/PaulAnnekov [@RePeet13]: https://github.com/RePeet13 [@ReneNulschDE]: https://github.com/ReneNulschDE [@Tadly]: https://github.com/Tadly [@aarnaud]: https://github.com/aarnaud [@akloeckner]: https://github.com/akloeckner [@amelchio]: https://github.com/amelchio [@andrey-git]: https://github.com/andrey-git [@aosadchyy]: https://github.com/aosadchyy [@appzer]: https://github.com/appzer [@arsaboo]: https://github.com/arsaboo [@bachya]: https://github.com/bachya [@thijsdejong]: https://github.com/thijsdejong [@balloob]: https://github.com/balloob [@bitglue]: https://github.com/bitglue [@bratanon]: https://github.com/bratanon [@c727]: https://github.com/c727 [@cdce8p]: https://github.com/cdce8p [@ciotlosm]: https://github.com/ciotlosm [@cnrd]: https://github.com/cnrd [@covrig]: https://github.com/covrig [@crhan]: https://github.com/crhan [@danielhiversen]: https://github.com/danielhiversen [@danielperna84]: https://github.com/danielperna84 [@dgomes]: https://github.com/dgomes [@dotlambda]: https://github.com/dotlambda [@escoand]: https://github.com/escoand [@fabaff]: https://github.com/fabaff [@fanaticDavid]: https://github.com/fanaticDavid [@fanthos]: https://github.com/fanthos [@freol35241]: https://github.com/freol35241 [@frog32]: https://github.com/frog32 [@glance-]: https://github.com/glance- [@hawk259]: https://github.com/hawk259 [@infernix]: https://github.com/infernix [@jackwilsdon]: https://github.com/jackwilsdon [@jeradM]: https://github.com/jeradM [@jodur]: https://github.com/jodur [@kennedyshead]: https://github.com/kennedyshead [@kevindgoff]: https://github.com/kevindgoff [@lance36]: https://github.com/lance36 [@led-spb]: https://github.com/led-spb [@lexam79]: https://github.com/lexam79 [@luca-angemi]: https://github.com/luca-angemi [@lucasweb78]: https://github.com/lucasweb78 [@maddox]: https://github.com/maddox [@mezz64]: https://github.com/mezz64 [@mkfink]: https://github.com/mkfink [@nordlead2005]: https://github.com/nordlead2005 [@pelson]: https://github.com/pelson [@perosb]: https://github.com/perosb [@philk]: https://github.com/philk [@philklei]: https://github.com/philklei [@postlund]: https://github.com/postlund [@pvizeli]: https://github.com/pvizeli [@rcloran]: https://github.com/rcloran [@scop]: https://github.com/scop [@sdague]: https://github.com/sdague [@snjoetw]: https://github.com/snjoetw [@syssi]: https://github.com/syssi [@tbergo]: https://github.com/tbergo [@timmo001]: https://github.com/timmo001 [@titilambert]: https://github.com/titilambert [@tschmidty69]: https://github.com/tschmidty69 [@ubnt-marc-khouri]: https://github.com/ubnt-marc-khouri [@vaceslav]: https://github.com/vaceslav [@w1ll1am23]: https://github.com/w1ll1am23 [@craigjmidwinter]: https://github.com/craigjmidwinter [@zabuldon]: https://github.com/zabuldon [alexa docs]: /integrations/alexa/ [binary_sensor.deconz docs]: /integrations/deconz#binary-传感器 [binary_sensor.MQTT docs]: /integrations/binary_sensor.MQTT/ [binary_sensor.模板 docs]: /integrations/binary_sensor.模板/ [binary_sensor.threshold docs]: /integrations/threshold [binary_sensor.zha docs]: /integrations/zha [摄像头.canary docs]: /integrations/canary#摄像头 [摄像头.uvc docs]: /integrations/uvc [摄像头.xeoma docs]: /integrations/xeoma [canary docs]: /integrations/canary/ [温控.demo docs]: /integrations/demo/ [温控.ecobee docs]: /integrations/ecobee [温控.econet docs]: /integrations/econet [温控.generic_thermostat docs]: /integrations/generic_thermostat [温控.heatmiser docs]: /integrations/heatmiser [温控.melissa docs]: /integrations/melissa [温控.nest docs]: /integrations/nest#温控 [温控.tado docs]: /integrations/tado [温控.touchline docs]: /integrations/touchline [温控.venstar docs]: /integrations/venstar [cloud docs]: /integrations/cloud/ [coinbase docs]: /integrations/coinbase/ [遮盖.MQTT docs]: /integrations/遮盖.MQTT/ [遮盖.tahoma docs]: /integrations/tahoma [遮盖.模板 docs]: /integrations/遮盖.模板/ [deconz docs]: /integrations/deconz/ [device_tracker.huawei_router docs]: /integrations/huawei_router [device_tracker.mikrotik docs]: /integrations/mikrotik [device_tracker.MQTT docs]: /integrations/device_tracker.MQTT/ [device_tracker.owntracks docs]: /integrations/owntracks [device_tracker.ubus docs]: /integrations/ubus [doorbird docs]: /integrations/doorbird/ [emulated_hue docs]: /integrations/emulated_hue/ [风扇.xiaomi_miio docs]: /integrations/风扇.xiaomi_miio/ [feedreader docs]: /integrations/feedreader/ [前端 docs]: /integrations/frontend/ [goalfeed docs]: /integrations/goalfeed/ [google_assistant docs]: /integrations/google_assistant/ [group docs]: /integrations/group/ [homematic docs]: /integrations/homematic/ [http docs]: /integrations/http/ [image_processing.openalpr_cloud docs]: /integrations/openalpr_cloud [influxdb docs]: /integrations/influxdb/ [input_text docs]: /integrations/input_text/ [ios docs]: /integrations/ios/ [iota docs]: /integrations/iota/ [灯光.deconz docs]: /integrations/deconz#灯光 [灯光.greenwave docs]: /integrations/greenwave [灯光.lifx docs]: /integrations/lifx [灯光.limitlessled docs]: /integrations/limitlessled [灯光.模板 docs]: /integrations/灯光.模板/ [灯光.xiaomi_aqara docs]: /integrations/灯光.xiaomi_aqara/ [灯光.xiaomi_miio docs]: /integrations/灯光.xiaomi_miio/ [灯光.zha docs]: /integrations/zha [门锁 docs]: /integrations/门锁/ [media_extractor docs]: /integrations/media_extractor/ [媒体播放器 docs]: /integrations/媒体播放器/ [媒体播放器.bluesound docs]: /integrations/bluesound [媒体播放器.clementine docs]: /integrations/clementine [媒体播放器.itunes docs]: /integrations/itunes [媒体播放器.mediaroom docs]: /integrations/mediaroom [媒体播放器.panasonic_viera docs]: /integrations/panasonic_viera [媒体播放器.philips_js docs]: /integrations/philips_js [媒体播放器.plex docs]: /integrations/plex#media-player [媒体播放器.samsungtv docs]: /integrations/samsungtv [媒体播放器.squeezebox docs]: /integrations/squeezebox [媒体播放器.vlc docs]: /integrations/vlc [媒体播放器.volumio docs]: /integrations/volumio [媒体播放器.webostv docs]: /integrations/webostv#media-player [melissa docs]: /integrations/melissa/ [mochad docs]: /integrations/mochad/ [通知.gntp docs]: /integrations/gntp [通知.kodi docs]: /integrations/kodi [通知.pushsafer docs]: /integrations/pushsafer [通知.twitter docs]: /integrations/twitter [panel_iframe docs]: /integrations/panel_iframe/ [plant docs]: /integrations/plant/ [遥控器.xiaomi_miio docs]: /integrations/遥控器.xiaomi_miio/ [rfxtrx docs]: /integrations/rfxtrx/ [传感器.alpha_vantage docs]: /integrations/alpha_vantage [传感器.broadlink docs]: /integrations/broadlink#传感器 [传感器.canary docs]: /integrations/canary#传感器 [传感器.coinbase docs]: /integrations/coinbase [传感器.coinmarketcap docs]: /integrations/coinmarketcap [传感器.darksky docs]: /integrations/darksky [传感器.deconz docs]: /integrations/deconz#传感器 [传感器.deutsche_bahn docs]: /integrations/deutsche_bahn [传感器.fritzbox_callmonitor docs]: /integrations/fritzbox#sensor_callmonitor/ [传感器.melissa docs]: /integrations/melissa/ [传感器.miflora docs]: /integrations/miflora [传感器.onewire docs]: /integrations/onewire [传感器.pollen docs]: /integrations/iqvia [传感器.qnap docs]: /integrations/qnap [传感器.radarr docs]: /integrations/radarr [传感器.sonarr docs]: /integrations/sonarr [传感器.sql docs]: /integrations/sql [传感器.statistics docs]: /integrations/statistics [传感器.synologydsm docs]: /integrations/synologydsm [传感器.systemmonitor docs]: /integrations/systemmonitor [传感器.tahoma docs]: /integrations/tahoma [传感器.模板 docs]: /integrations/模板 [传感器.tesla docs]: /integrations/tesla [传感器.xiaomi_aqara docs]: /integrations/传感器.xiaomi_aqara/ [传感器.zha docs]: /integrations/zha [spc docs]: /integrations/spc/ [开关.broadlink docs]: /integrations/broadlink#开关 [开关.flux docs]: /integrations/flux [开关.pulseaudio_loopback docs]: /integrations/pulseaudio_loopback [开关.模板 docs]: /integrations/开关.模板/ [开关.tplink docs]: /integrations/tplink [开关.wake_on_lan docs]: /integrations/wake_on_lan#开关 [开关.xiaomi_miio docs]: /integrations/开关.xiaomi_miio/ [system_log docs]: /integrations/system_log/ [tado docs]: /integrations/tado/ [tahoma docs]: /integrations/tahoma/ [tesla docs]: /integrations/tesla/ [tts docs]: /integrations/tts/ [吸尘器.xiaomi_miio docs]: /integrations/吸尘器.xiaomi_miio/ [wake_on_lan docs]: /integrations/wake_on_lan/ [waterfurnace docs]: /integrations/waterfurnace/ [天气.openweathermap docs]: /integrations/openweathermap#天气 [websocket_api docs]: /integrations/websocket_api/ [zha docs]: /integrations/zha/ [zha.const docs]: /integrations/zha.const/ [zwave docs]: /integrations/zwave/ [#12292]: https://github.com/home-assistant/home-assistant/pull/12292 [#12313]: https://github.com/home-assistant/home-assistant/pull/12313 [#12314]: https://github.com/home-assistant/home-assistant/pull/12314 [#12317]: https://github.com/home-assistant/home-assistant/pull/12317 [#12318]: https://github.com/home-assistant/home-assistant/pull/12318 [#12328]: https://github.com/home-assistant/home-assistant/pull/12328 [#12330]: https://github.com/home-assistant/home-assistant/pull/12330 [@balloob]: https://github.com/balloob [@lucasweb78]: https://github.com/lucasweb78 [alexa docs]: /integrations/alexa/ [binary_sensor.netatmo docs]: /integrations/netatmo#binary-传感器 [摄像头.netatmo docs]: /integrations/netatmo#摄像头 [传感器.netatmo docs]: /integrations/netatmo#传感器 [#12342]: https://github.com/home-assistant/home-assistant/pull/12342 [#12346]: https://github.com/home-assistant/home-assistant/pull/12346 [#12368]: https://github.com/home-assistant/home-assistant/pull/12368 [#12382]: https://github.com/home-assistant/home-assistant/pull/12382 [#12403]: https://github.com/home-assistant/home-assistant/pull/12403 [@OttoWinter]: https://github.com/OttoWinter [@ReneNulschDE]: https://github.com/ReneNulschDE [@amelchio]: https://github.com/amelchio [@citruz]: https://github.com/citruz [@sdague]: https://github.com/sdague [灯光.limitlessled docs]: /integrations/limitlessled [媒体播放器.yamaha docs]: /integrations/yamaha [传感器.eddystone_temperature docs]: /integrations/eddystone_temperature [传感器.wunderground docs]: /integrations/wunderground [#12392]: https://github.com/home-assistant/home-assistant/pull/12392 [#12421]: https://github.com/home-assistant/home-assistant/pull/12421 [#12435]: https://github.com/home-assistant/home-assistant/pull/12435 [#12445]: https://github.com/home-assistant/home-assistant/pull/12445 [#12447]: https://github.com/home-assistant/home-assistant/pull/12447 [#12448]: https://github.com/home-assistant/home-assistant/pull/12448 [#12452]: https://github.com/home-assistant/home-assistant/pull/12452 [@OverloadUT]: https://github.com/OverloadUT [@amelchio]: https://github.com/amelchio [@andrey-git]: https://github.com/andrey-git [@danielhiversen]: https://github.com/danielhiversen [@dgomes]: https://github.com/dgomes [@ryanm101]: https://github.com/ryanm101 [@syssi]: https://github.com/syssi [风扇.xiaomi_miio docs]: /integrations/风扇.xiaomi_miio/ [isy994 docs]: /integrations/isy994/ [灯光.模板 docs]: /integrations/灯光.模板/ [灯光.xiaomi_miio docs]: /integrations/灯光.xiaomi_miio/ [媒体播放器.plex docs]: /integrations/plex#media-player [遥控器.xiaomi_miio docs]: /integrations/遥控器.xiaomi_miio/ [传感器.sql docs]: /integrations/sql [开关.xiaomi_miio docs]: /integrations/开关.xiaomi_miio/ [吸尘器.xiaomi_miio docs]: /integrations/吸尘器.xiaomi_miio/ --- url: /home-assistant/blog/2018-02-20-cloud-update.md --- # 云服务更新 我们很高兴地宣布,Home Assistant 技能现已在加拿大、英国、德国、印度和澳大利亚上线!请在 [Amazon Alexa 技能商店][alexa skill] 中查看。 与此同时,我们也在致力于 Google Assistant 集成。我们已经通过了第一轮验证,现在正在与 Google 合作进行最终验证。敬请期待! 不到两周,公开测试版即将到期。我们仍在努力建立公司和支付系统,以便开始接受付款。在此之前,Home Assistant Cloud 将继续保持免费。 [alexa skill]: https://alexa.amazon.com/spa/index.html#skills/dp/B0772J1QKB/ --- url: /home-assistant/blog/2018-02-26-release-64.md --- # 0.64:集成总数突破 1000!新增:HomeKit、BMW、August 🎉 1000 个集成,1000 个集成,1000 个集成!🎉 没错,Home Assistant 0.64 来了!如果你错过了我们最新的 [Cloud 更新](/home-assistant/blog/2018/02/19/cloud-更新/),这里补一句:Home Assistant Alexa 技能现已在所有地区上线,我们也正在与 Google 合作推进 Google Assistant 的 Smart Home 技能审核。非常令人兴奋! 与此同时,一批很棒的新集成也已落地,其中还包括又一个汽车集成 🚗 这次是 BMW。 这将是最后一个支持 Python 3.4 的版本。从下一个发布开始,最低要求将提升至 Python 3.5.3。[了解更多](/home-assistant/blog/2017/10/06/deprecating-python-3.4-support/) ## HomeKit 原生 HomeKit 支持现已到来!感谢 @cdce8p。你现在可以通过 HomeKit 暴露部分设备,从而通过 Siri 以及其他支持 HomeKit 协议的设备进行控制。首批已支持温度传感器和遮盖设备,后续会继续扩展。 [查看 HomeKit 文档][HomeKit docs] ## Hass.io UI 更新 你们中有些人可能已经注意到了:从今天早上开始,Hass.io 面板看起来有点不一样了。@pvizeli 按下了 ~~红色~~ 绿色按钮,新 UI 正式上线。Hass.io 团队([@frenck] [@pvizeli] [@ryanm101])在 Hass.io 后端持续加入新功能(比如部分快照与加密快照)并修复问题,做得非常出色。不过此前这些能力主要只在命令行工具里可用,前端还没有完整跟上。 这时 [@c727] 和 [@ciotlosm] 加入进来,让这些新功能可以直接通过前端使用,并改进了整体导航体验。 我们知道目前仍有一些功能缺失或存在问题,也正在持续修复中!如果你要反馈 Hass.io 面板相关问题,请先查看这个 [issue](https://github.com/home-assistant/home-assistant-polymer/issues/912)。 ## Chart.js 感谢 [@fanthos] 的出色工作,前端现在改为使用 Chart.js 渲染图表。这意味着即使没有互联网连接,你也可以正常查看所有图表! ## August 集成 [@snjoetw] 带来了重量级新集成:August 门锁和门铃!你可以直接在 Home Assistant 中锁门/开锁,并在门铃被按下或检测到移动时收到状态变化。非常赞! ## Cast 问题修复 [@OttoWinter] 修复了 ChromeCast 集成中的一大批问题,包括那个烦人的 Cast 群组发现问题!他还在继续推进更多改进,预计很快就会到来,敬请期待。干得漂亮,Otto! ## 新平台 * 支持 August 门铃 ([@snjoetw] - [#11124]) ([august docs]) ([binary\_sensor.august docs][binary_sensor.august docs]) ([摄像头.august docs]) ([门锁.august docs]) (new-platform) * 新增 BMW Connected Drive 组件 ([@ChristianKuehnel] - [#12277]) ([bmw\_connected\_drive docs][bmw_connected_drive docs]) ([device\_tracker.bmw\_connected\_drive docs][device_tracker.bmw_connected_drive docs]) ([传感器.bmw\_connected\_drive docs][传感器.bmw_connected_drive docs]) (new-platform) * 为 ISP Start.ca 新增传感器 ([@mikeodr] - [#12356]) ([传感器.startca docs]) (new-platform) * 新增小米电视平台 ([@simse] - [#12359]) ([媒体播放器.xiaomi\_tv docs][媒体播放器.xiaomi_tv docs]) (new-platform) * 新增 Smappee 组件 ([@hmn] - [#11491]) ([smappee docs]) ([传感器.smappee docs]) ([开关.smappee docs]) (new-platform) * 新增 HomeKit 支持 ([@cdce8p] - [#12488]) ([homekit docs]) (new-platform) * 新增文件大小组件 ([@robmarkcole] - [#12211]) ([传感器.filesize docs]) (new-platform) * 新增文件夹传感器 ([@robmarkcole] - [#12208]) ([传感器.folder docs]) (new-platform) * Spotcrime ([@jcconnell] - [#12460]) ([传感器.spotcrime docs]) (new-platform) * Add Tahoma 场景 ([@thijsdejong] - [#12498]) ([场景 docs]) ([tahoma docs]) (new-platform) ## 发布 0.64.1 - February 27 * 前端:不要把传感器单位放到新的一行 ([@NovapaX]) * 前端:修复 iOS 9.3.5 上的显示问题 ([@NovapaX]) * 前端:修复只有 1 个序列时图例显示不正确的问题 ([@fanthos]) * 前端:修复卡片不更新的问题 ([@balloob]) * Cast automatically drop connection ([@OttoWinter] - [#12635]) ([媒体播放器.cast docs]) * Roomba timeout ([@kellerza] - [#12645]) ([吸尘器.roomba docs]) * Fix a problem with calling `deconz.close` ([@aronsky] - [#12657]) ([deconz docs]) * Harmony: make activity optional ([@balloob] - [#12679]) ([遥控器.harmony docs]) * Fix getting 状态 from iglo ([@jesserockz] - [#12685]) ([灯光.iglo docs]) * Fix mysensor defaults ([@balloob] - [#12687]) ([mysensors docs]) * Component deconz: Fix dark 属性 on 在场 传感器 ([@tumik] - [#12691]) ([binary\_sensor.deconz docs][binary_sensor.deconz docs]) * Bugfix: 更新 of sources for non AVR-X 设备 always fails ([@scarface-4711] - [#12711]) ([媒体播放器.denonavr docs]) * Don't allow to use a old unsecure library ([@pvizeli] - [#12715]) * Unbreak tahoma ([@thijsdejong] - [#12719]) ([tahoma docs]) * fix for https://github.com/home-assistant/home-assistant/issues/12673 ([@ChristianKuehnel] - [#12726]) ([传感器.alpha\_vantage docs][传感器.alpha_vantage docs]) * Fix harmony duplicate detection ([@amelchio] - [#12729]) ([遥控器.harmony docs]) * 更新 ZHA deps ([@balloob] - [#12737]) ([zha docs]) * MQTT: Fix doing async inside sync context ([@OttoWinter]) * Fix DarSky humidity precision ([@PhilRW]) ## 发布 0.64.2 - March 1 * updated to bimmer\_connected 0.4.1 ([@ChristianKuehnel] - [#12759]) ([bmw\_connected\_drive docs][bmw_connected_drive docs]) * Revert optimized logbook SQL ([@amelchio] - [#12762]) ([logbook docs]) * bump fedex 版本 ([@happyleavesaoc] - [#12764]) * Silence harmless sonos data structure 警告 ([@amelchio] - [#12767]) ([媒体播放器.sonos docs]) * 更新 samsungctl library to latest 版本 ([@uchagani] - [#12769]) ([媒体播放器.samsungtv docs]) * Fixed missing optional keyerror data\_bits ([@basschipper] - [#12789]) ([binary\_sensor.rfxtrx docs][binary_sensor.rfxtrx docs]) * Fixed Pollen.com bugs with ZIP codes and invalid API responses ([@bachya] - [#12790]) ([传感器.pollen docs]) * Fix dead Sonos web interface with some music sources ([@amelchio] - [#12796]) ([媒体播放器.sonos docs]) * Unique IDs for Plex Clients ([@ryanm101] - [#12799]) ([媒体播放器.plex docs]) ## 发布 0.64.3 - March 2 * is\_allowed\_path: Also test folder #12788 #12807 ([@kellerza] - [#12810]) * Fix sensibo default IDs to be according to schema ([@andrey-git] - [#12837]) ([温控.sensibo docs]) * Cloud: handle unauth better ([@balloob] - [#12840]) ([cloud docs]) * Handle Hue 错误 better ([@balloob] - [#12845]) ([hue docs]) ## 需要帮助? 如果你需要帮助,欢迎前往我们非常活跃的 [论坛](https://community.home-assistant.io/),或加入 [聊天频道](https://discord.gg/c5DvZ4e)。发布说明虽然开放评论,但我们更推荐你使用前面的社区渠道。谢谢! ## 问题反馈 如果你遇到由本次发布引入的问题,请在我们的 [issue tracker](https://github.com/home-assistant/home-assistant/issues) 提交反馈。请确保完整填写 issue 模板中的所有字段。 ## 不向后兼容的变更 * Home Assistant 现在默认会清理超过 10 天的历史记录。如果你希望保留更久的数据,必须在 *首次启动 0.64 之前* 配置保留天数,例如: ```yaml recorder: purge_keep_days: 30 ``` 如果你想保持之前“永不删除历史”的默认行为,请使用以下配置: ```yaml recorder: purge_interval: 0 ``` ([@amelchio] - [#12271]) (breaking change) * 如果未配置任何股票代码或货币,将显示一条 persistent\_notification(持久通知)。([@ChristianKuehnel] - [#12252]) ([传感器.alpha\_vantage docs][传感器.alpha_vantage docs]) (breaking change) * RainMachine 的唯一 ID 已更新,以便更好地适配实体注册表。如果此前已经配置过 RainMachine,新的条目会写入实体注册表,因此每个程序/区域可能会出现两个实体。你只需按需修改 `entity_registry.yaml` 即可处理。([@bachya] - [#12315]) ([开关.rainmachine docs]) (breaking change) * AirVisual 的唯一 ID 已更新,以便更好地适配实体注册表。如果此前已经配置过 AirVisual,新的条目会写入实体注册表,因此每种传感器类型可能会出现两个实体。你只需按需修改 `entity_registry.yaml` 即可处理。([@bachya] - [#12319]) ([传感器.airvisual docs]) (breaking change) * 仅针对自定义组件开发者:voluptuous 现在要求配置键的默认值本身也必须是合法值。([@balloob] - [#12463]) (breaking change) * 修复了 `usps` 平台。依赖 `myusps` 现在改用 Selenium webdriver 来绕过登录问题。这是一个破坏性变更,因为用户现在必须额外安装依赖:`google-chrome` 与 `chromedriver`,或 `phantomjs`。同时新增了配置项 `driver`,允许用户指定偏好的驱动,默认仍为 `phantomjs`。后续文档 PR 会说明可选方案,并根据用户操作系统给出建议。 ([@happyleavesaoc] - [#12465]) (breaking change) * LimitlessLED 已改为 assumed 状态。Home Assistant 重启时将不再关闭灯光,也不会再回滚由其他控制器做出的更改。([@amelchio] - [#12475]) ([灯光.limitlessled docs]) (breaking change) ## 所有变更 * device\_tracker.asuswrt: Clean up unused connection param ([@trisk] - [#12262]) ([device\_tracker.asuswrt docs][device_tracker.asuswrt docs]) * Fix some rfxtrx 设备 with multiple 传感器 ([@neffs] - [#12264]) ([传感器.rfxtrx docs]) * have 温控 fallback to 状态 if no ATTR\_OPERATION\_MODE (#12271) ([@ttroy50] - [#12279]) ([google\_assistant docs][google_assistant docs]) * check\_config check bootstrap 错误 ([@kellerza] - [#12291]) * Attempt fixing flakiness of check config test ([@balloob] - [#12283]) * Fix MQTT retained message not being re-dispatched ([@OttoWinter] - [#12004]) ([MQTT docs]) * Fix config 错误 for FTP links, add test ([@ReneNulschDE] - [#12294]) * Fix Panel\_IFrame - FTP URL not allowed in 0.63 ([@ReneNulschDE] - [#12295]) ([panel\_iframe docs][panel_iframe docs]) * 升级 pylint to 1.8.2 ([@OttoWinter] - [#12274]) * Move HassIntent handler code into 助手/intent ([@tschmidty69] - [#12181]) ([conversation docs]) * Migrated SABnzbd 传感器 to asyncio and switched to pypi library ([@jeradM] - [#12290]) ([传感器.sabnzbd docs]) * 📝 Fix fixture encoding ([@OttoWinter] - [#12296]) * Clarify tahoma errrors ([@thijsdejong] - [#12307]) ([tahoma docs]) * add friendly\_name\_template to 模板 传感器 ([@NovapaX] - [#12268]) ([传感器.模板 docs]) * Purge recorder data by default ([@amelchio] - [#12271]) (breaking change) * Protect bloomsky platform 设置 ([@balloob] - [#12316]) ([binary\_sensor.bloomsky docs][binary_sensor.bloomsky docs]) ([摄像头.bloomsky docs]) ([传感器.bloomsky docs]) * Removed default 传感器 配置 ([@ChristianKuehnel] - [#12252]) ([传感器.alpha\_vantage docs][传感器.alpha_vantage docs]) (breaking change) * Force LF line endings for Windows ([@kellerza] - [#12266]) * Updated RainMachine to play better with the 实体 registry ([@bachya] - [#12315]) ([开关.rainmachine docs]) (breaking change) * Revert #12316 ([@balloob] - [#12329]) ([binary\_sensor.bloomsky docs][binary_sensor.bloomsky docs]) ([摄像头.bloomsky docs]) ([传感器.bloomsky docs]) * zha: Add remove 服务 ([@rcloran] - [#11683]) ([zha docs]) * Fix line endings \[skipci] ([@balloob] - [#12333]) * Unifi tracking filter by SSID ([@mikeodr] - [#12281]) ([device\_tracker.unifi docs][device_tracker.unifi docs]) * device\_tracker.asuswrt: Ignore unreachable ip neigh entries ([@trisk] - [#12201]) ([device\_tracker.asuswrt docs][device_tracker.asuswrt docs]) * nmap\_tracker: don't scan on 设置 ([@abmantis] - [#12322]) ([device\_tracker.nmap\_tracker docs][device_tracker.nmap_tracker docs]) * 升级 Sphinx to 1.7.0 ([@fabaff] - [#12335]) * Mock Module + Platform default to async ([@balloob] - [#12347]) * Change Unifi SSID filtering to list comprehension ([@mikeodr] - [#12344]) ([device\_tracker.unifi docs][device_tracker.unifi docs]) * Use the speedometer icon in the fastdotcom 传感器 ([@d0ugal] - [#12348]) ([传感器.fastdotcom docs]) * Communication reduced. Setting brightness and/or color temperature will 打开 the 设备. ([@syssi] - [#12343]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) * Add New 传感器 for ISP Start.ca ([@mikeodr] - [#12356]) ([传感器.startca docs]) (new-platform) * bump fedex 版本 ([@happyleavesaoc] - [#12362]) * 升级 alpha\_vantage to 1.9.0 ([@fabaff] - [#12352]) ([传感器.alpha\_vantage docs][传感器.alpha_vantage docs]) * Eq3btsmart more reliable ([@karlkar] - [#11555]) ([温控.eq3btsmart docs]) * Allow disabling 实体 in the registry ([@balloob] - [#12360]) * 升级 panasonic\_viera to 0.3.1 ([@dgomes] - [#12370]) ([媒体播放器.panasonic\_viera docs][媒体播放器.panasonic_viera docs]) * SMA 传感器 add SSL and 升级 to pysma 0.2 ([@kellerza] - [#12354]) ([传感器.sma docs]) * Specify algorithms for webpush jwt verification ([@balloob] - [#12378]) ([通知.html5 docs]) * 升级 youtube\_dl to 2018.02.11 ([@fabaff] - [#12383]) ([media\_extractor docs][media_extractor docs]) * Remove usage of deprecated assert method ([@balloob] - [#12379]) * Add 属性 (fixes #12332) ([@fabaff] - [#12377]) ([传感器.speedtest docs]) * Improve 服务 by allowing to reference 实体 id instead of deconz id ([@Kane610] - [#11862]) ([deconz docs]) ([场景 docs]) ([binary\_sensor.deconz docs][binary_sensor.deconz docs]) ([灯光.deconz docs]) ([传感器.deconz docs]) * Pollen.com: 实体 Registry updates and cleanup ([@bachya] - [#12361]) ([传感器.pollen docs]) * Changed pyvera 版本 to 0.2.41 ([@patrik3k] - [#12391]) ([vera docs]) * File Path fixes for RPi 摄像头 ([@FrederikBolding] - [#12338]) ([摄像头.rpi\_camera docs][摄像头.rpi_camera docs]) * Code cleanup of velux 场景 ([@Julius2342] - [#12390]) ([场景 docs]) * 升级 sphinx-autodoc-typehints to 1.2.5 ([@fabaff] - [#12404]) * Extract data validator to own file and add tests ([@balloob] - [#12401]) ([cloud docs]) ([conversation docs]) ([http docs]) ([shopping\_list docs][shopping_list docs]) (new-platform) * Fix MQTT payload decode returning prematurely ([@OttoWinter] - [#12420]) ([MQTT docs]) * Print every changed file on new line ([@cdce8p] - [#12412]) * Added support for colored KNX 灯光 ([@Julius2342] - [#12411]) ([knx docs]) ([灯光.knx docs]) * Small code cleanup: ([@Julius2342] - [#12409]) ([场景 docs]) * Cleanup of knx component ([@Julius2342] - [#12408]) ([knx docs]) ([binary\_sensor.knx docs][binary_sensor.knx docs]) ([温控.knx docs]) ([遮盖.knx docs]) ([灯光.knx docs]) ([通知.knx docs]) ([传感器.knx docs]) ([开关.knx docs]) * 更新 the Tibber 传感器 at startup ([@danielhiversen] - [#12428]) ([传感器.tibber docs]) * zha: Add unique\_id to 实体 ([@rcloran] - [#12331]) ([zha docs]) * Cleanup http ([@balloob] - [#12424]) ([前端 docs]) ([http docs]) * 更新 CODEOWNERS ([@dgomes] - [#12440]) * Fix: timeout data 属性 now is parsed to float ([@sjvc] - [#12432]) ([telegram\_bot docs][telegram_bot docs]) * Stop mapping Zigbee 开关 to 灯光 & 开关. ([@igorbernstein2] - [#12280]) ([zha docs]) * AirVisual: 实体 Registry updates and cleanup ([@bachya] - [#12319]) ([传感器.airvisual docs]) (breaking change) * Vagrant - sendfile python3.5 debian-stretch ([@tabakhase] - [#12454]) * Add effects to iGlo 灯光 ([@jesserockz] - [#12365]) ([灯光.iglo docs]) * Fake the 状态 for a short period and skip the next 更新. ([@syssi] - [#12446]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) * Initial support for Config Entries ([@balloob] - [#12079]) * Make WUnderground async ([@OttoWinter] - [#12385]) ([传感器.wunderground docs]) * Add the Xiaomi TV platform. ([@simse] - [#12359]) ([媒体播放器.xiaomi\_tv docs][媒体播放器.xiaomi_tv docs]) (new-platform) * 更新 voluputous ([@balloob] - [#12463]) (breaking change) * Map Alexa StepVolume responses to volume\_up/down ([@lucasweb78] - [#12467]) ([alexa docs]) * ONVIF 摄像头 added 错误 handling and rtsp 认证. ([@matt2005] - [#11129]) ([摄像头.onvif docs]) * Bump aioautomatic to 0.6.5 for voluptuous 0.11 ([@armills] - [#12480]) * Add example in test how to create list or object in 模板 ([@balloob] - [#12469]) * KNX/温控: Fixed platform schema min/max values. ([@Julius2342] - [#12477]) ([温控.knx docs]) * Prevent 错误 when no internet or DNS is available ([@mjj4791] - [#12486]) ([传感器.buienradar docs]) ([天气.buienradar docs]) * Added doorbird\_last\_motion to DoorBird 摄像头 platform ([@sjvc] - [#12457]) ([摄像头.doorbird docs]) * Fail gracefully with unreachable LaMetric ([@PhilRW] - [#12451]) ([通知.lametric docs]) * Enable compression when sending json to client ([@elupus] - [#11165]) ([http docs]) * bump usps 版本 ([@happyleavesaoc] - [#12465]) (breaking change) * Try deflaking recorder tests ([@balloob] - [#12492]) * Support for August doorbell ([@snjoetw] - [#11124]) ([august docs]) ([binary\_sensor.august docs][binary_sensor.august docs]) ([摄像头.august docs]) ([门锁.august docs]) (new-platform) * Avoid 警告 when purging an empty database ([@amelchio] - [#12494]) * Support for PTZ in Onvif 摄像头 ([@karlkar] - [#11630]) ([摄像头.onvif docs]) * Rework Sonos media player platform ([@amelchio] - [#12126]) ([媒体播放器.sonos docs]) * Converted shopping list to use json util and added default override for json util ([@FrederikBolding] - [#12478]) ([shopping\_list docs][shopping_list docs]) * added smappee component ([@hmn] - [#11491]) ([smappee docs]) ([传感器.smappee docs]) ([开关.smappee docs]) (new-platform) * More features for the Bluesound component ([@thrawnarn] - [#11450]) ([媒体播放器.bluesound docs]) * zha: Simplify unique ID ([@rcloran] - [#12495]) ([zha docs]) * zha: Add support for humidity 传感器 ([@rcloran] - [#12496]) ([zha docs]) ([传感器.zha docs]) * bump python-eq3bt 版本, fixes #12499 ([@rytilahti] - [#12510]) ([温控.eq3btsmart docs]) * new 版本 of xiaomi lib ([@danielhiversen] - [#12513]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * python-miio 版本 bumped. (Closes: #12471) ([@syssi] - [#12481]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) ([遥控器.xiaomi\_miio docs][遥控器.xiaomi_miio docs]) ([开关.xiaomi\_miio docs][开关.xiaomi_miio docs]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) * LimitlessLED assumed 状态 ([@amelchio] - [#12475]) ([灯光.limitlessled docs]) (breaking change) * Add support for HomeKit ([@cdce8p] - [#12488]) ([homekit docs]) (new-platform) * Add 密码 support ([@pvizeli] - [#12525]) ([hassio docs]) * Changed to async\_schedule\_update\_ha\_state ([@thrawnarn] - [#12518]) ([媒体播放器.bluesound docs]) * Fix Sphinx build ([@balloob] - [#12535]) * 更新 voluptuous serialize ([@balloob] - [#12538]) ([config docs]) * Clarify a comment regarding python versions ([@aprasanna] - [#12537]) * Adds filesize component ([@robmarkcole] - [#12211]) ([传感器.filesize docs]) (new-platform) * Clarify cloud 错误 ([@balloob] - [#12540]) ([cloud docs]) * Build JSON in executor ([@amelchio] - [#12536]) ([history docs]) ([logbook docs]) * Bugfix: Input Datetime config schema ([@cdce8p] - [#12552]) ([input\_datetime docs][input_datetime docs]) * Fix numeric\_state 条件 spamming on unavailable ([@OttoWinter] - [#12550]) * Frontier silicon async ([@zhelev] - [#12503]) ([媒体播放器.frontier\_silicon docs][媒体播放器.frontier_silicon docs]) * Fix WUnderground spamming 日志 ([@OttoWinter] - [#12548]) ([传感器.wunderground docs]) * Added support for milight single channel dimmer ([@rubenverhoef] - [#12558]) ([灯光.limitlessled docs]) * Add new component: BMW connected drive ([@ChristianKuehnel] - [#12277]) ([bmw\_connected\_drive docs][bmw_connected_drive docs]) ([device\_tracker.bmw\_connected\_drive docs][device_tracker.bmw_connected_drive docs]) ([传感器.bmw\_connected\_drive docs][传感器.bmw_connected_drive docs]) (new-platform) * Cleanup hass.io component ([@pvizeli] - [#12556]) ([hassio docs]) * Add support for smoke detector in deconz ([@Kane610] - [#12561]) ([deconz docs]) * Fix caldav component handling missing dtend ([@bottomquark] - [#12562]) ([日历.caldav docs]) * Add limitlessled night effect ([@amelchio] - [#12567]) ([灯光.limitlessled docs]) * Basic support of post 2016 AVR-X receivers ([@scarface-4711] - [#12569]) ([媒体播放器.denonavr docs]) * Fix config 404 ([@balloob] - [#12571]) ([config docs]) * Logbook speedup ([@amelchio] - [#12566]) ([logbook docs]) * Fix sonos default errorcodes ([@amelchio] - [#12582]) ([媒体播放器.sonos docs]) * 更新 pychromecast to 2.0.0 ([@balloob] - [#12587]) ([媒体播放器.cast docs]) * Set event\_id foreign key in recorded 状态 ([@amelchio] - [#12580]) * Deconz support water 传感器 ([@Kane610] - [#12581]) ([deconz docs]) * Cloud reconnect tweaks ([@balloob] - [#12586]) ([cloud docs]) * Hassio cleanup part2 ([@pvizeli] - [#12588]) ([hassio docs]) * Add 蓝牙 and NFC 卡片/tag 报警 types ([@matthewcky2k] - [#12151]) ([门锁.zwave docs]) * Fix fix isy994 风扇 detection ([@OverloadUT] - [#12595]) ([isy994 docs]) * Adds folder 传感器 ([@robmarkcole] - [#12208]) ([传感器.folder docs]) (new-platform) * Add unique\_id to Xiaomi Aqara ([@tinloaf] - [#12372]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * Make groups 实体 again ([@balloob] - [#12574]) ([alexa docs]) * Python spotcrime ([@jcconnell] - [#12460]) ([传感器.spotcrime docs]) (new-platform) * Allow ignoring call 服务 events in mqtt\_eventstream ([@cmsimike] - [#12519]) ([mqtt\_eventstream docs][mqtt_eventstream docs]) * Set speed 服务 fixed. ([@syssi] - [#12602]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) * Updated 脚本/lint ([@cdce8p] - [#12600]) * Adding RoomHinting to GoogleAssistant to allow for 房间 annotations. ([@jeremydk] - [#12598]) ([google\_assistant docs][google_assistant docs]) * Fix mclimate accounts with not only melissa components ([@kennedyshead] - [#12427]) ([melissa docs]) ([温控.melissa docs]) * Cast unique\_id and async discovery ([@OttoWinter] - [#12474]) ([媒体播放器.cast docs]) * Add Tahoma 场景 ([@thijsdejong] - [#12498]) ([场景 docs]) ([tahoma docs]) (new-platform) * Optimize logbook SQL query ([@amelchio] - [#12608]) ([logbook docs]) * Fix voluptuous breaking change things ([@balloob] - [#12611]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) ([binary\_sensor.knx docs][binary_sensor.knx docs]) * OpenGarage - correctly handle offline status (#12612) ([@swbradshaw] - [#12613]) ([遮盖.opengarage docs]) * Move recorder query out of event loop ([@amelchio] - [#12615]) * Hassio 更新 timeout filter list ([@pvizeli] - [#12617]) ([hassio docs]) * The name of the enum must be used here because of the speed\_list. ([@syssi] - [#12625]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) * Fix cast doing I/O in event loop ([@OttoWinter] - [#12632]) ([媒体播放器.cast docs]) [#11124]: https://github.com/home-assistant/home-assistant/pull/11124 [#11129]: https://github.com/home-assistant/home-assistant/pull/11129 [#11165]: https://github.com/home-assistant/home-assistant/pull/11165 [#11450]: https://github.com/home-assistant/home-assistant/pull/11450 [#11491]: https://github.com/home-assistant/home-assistant/pull/11491 [#11555]: https://github.com/home-assistant/home-assistant/pull/11555 [#11630]: https://github.com/home-assistant/home-assistant/pull/11630 [#11683]: https://github.com/home-assistant/home-assistant/pull/11683 [#11862]: https://github.com/home-assistant/home-assistant/pull/11862 [#12004]: https://github.com/home-assistant/home-assistant/pull/12004 [#12079]: https://github.com/home-assistant/home-assistant/pull/12079 [#12126]: https://github.com/home-assistant/home-assistant/pull/12126 [#12151]: https://github.com/home-assistant/home-assistant/pull/12151 [#12181]: https://github.com/home-assistant/home-assistant/pull/12181 [#12201]: https://github.com/home-assistant/home-assistant/pull/12201 [#12208]: https://github.com/home-assistant/home-assistant/pull/12208 [#12211]: https://github.com/home-assistant/home-assistant/pull/12211 [#12252]: https://github.com/home-assistant/home-assistant/pull/12252 [#12262]: https://github.com/home-assistant/home-assistant/pull/12262 [#12264]: https://github.com/home-assistant/home-assistant/pull/12264 [#12266]: https://github.com/home-assistant/home-assistant/pull/12266 [#12268]: https://github.com/home-assistant/home-assistant/pull/12268 [#12271]: https://github.com/home-assistant/home-assistant/pull/12271 [#12274]: https://github.com/home-assistant/home-assistant/pull/12274 [#12277]: https://github.com/home-assistant/home-assistant/pull/12277 [#12279]: https://github.com/home-assistant/home-assistant/pull/12279 [#12280]: https://github.com/home-assistant/home-assistant/pull/12280 [#12281]: https://github.com/home-assistant/home-assistant/pull/12281 [#12283]: https://github.com/home-assistant/home-assistant/pull/12283 [#12290]: https://github.com/home-assistant/home-assistant/pull/12290 [#12291]: https://github.com/home-assistant/home-assistant/pull/12291 [#12294]: https://github.com/home-assistant/home-assistant/pull/12294 [#12295]: https://github.com/home-assistant/home-assistant/pull/12295 [#12296]: https://github.com/home-assistant/home-assistant/pull/12296 [#12307]: https://github.com/home-assistant/home-assistant/pull/12307 [#12315]: https://github.com/home-assistant/home-assistant/pull/12315 [#12316]: https://github.com/home-assistant/home-assistant/pull/12316 [#12319]: https://github.com/home-assistant/home-assistant/pull/12319 [#12322]: https://github.com/home-assistant/home-assistant/pull/12322 [#12329]: https://github.com/home-assistant/home-assistant/pull/12329 [#12331]: https://github.com/home-assistant/home-assistant/pull/12331 [#12333]: https://github.com/home-assistant/home-assistant/pull/12333 [#12335]: https://github.com/home-assistant/home-assistant/pull/12335 [#12338]: https://github.com/home-assistant/home-assistant/pull/12338 [#12343]: https://github.com/home-assistant/home-assistant/pull/12343 [#12344]: https://github.com/home-assistant/home-assistant/pull/12344 [#12347]: https://github.com/home-assistant/home-assistant/pull/12347 [#12348]: https://github.com/home-assistant/home-assistant/pull/12348 [#12352]: https://github.com/home-assistant/home-assistant/pull/12352 [#12354]: https://github.com/home-assistant/home-assistant/pull/12354 [#12356]: https://github.com/home-assistant/home-assistant/pull/12356 [#12359]: https://github.com/home-assistant/home-assistant/pull/12359 [#12360]: https://github.com/home-assistant/home-assistant/pull/12360 [#12361]: https://github.com/home-assistant/home-assistant/pull/12361 [#12362]: https://github.com/home-assistant/home-assistant/pull/12362 [#12365]: https://github.com/home-assistant/home-assistant/pull/12365 [#12370]: https://github.com/home-assistant/home-assistant/pull/12370 [#12372]: https://github.com/home-assistant/home-assistant/pull/12372 [#12377]: https://github.com/home-assistant/home-assistant/pull/12377 [#12378]: https://github.com/home-assistant/home-assistant/pull/12378 [#12379]: https://github.com/home-assistant/home-assistant/pull/12379 [#12383]: https://github.com/home-assistant/home-assistant/pull/12383 [#12385]: https://github.com/home-assistant/home-assistant/pull/12385 [#12390]: https://github.com/home-assistant/home-assistant/pull/12390 [#12391]: https://github.com/home-assistant/home-assistant/pull/12391 [#12401]: https://github.com/home-assistant/home-assistant/pull/12401 [#12404]: https://github.com/home-assistant/home-assistant/pull/12404 [#12408]: https://github.com/home-assistant/home-assistant/pull/12408 [#12409]: https://github.com/home-assistant/home-assistant/pull/12409 [#12411]: https://github.com/home-assistant/home-assistant/pull/12411 [#12412]: https://github.com/home-assistant/home-assistant/pull/12412 [#12420]: https://github.com/home-assistant/home-assistant/pull/12420 [#12424]: https://github.com/home-assistant/home-assistant/pull/12424 [#12427]: https://github.com/home-assistant/home-assistant/pull/12427 [#12428]: https://github.com/home-assistant/home-assistant/pull/12428 [#12432]: https://github.com/home-assistant/home-assistant/pull/12432 [#12440]: https://github.com/home-assistant/home-assistant/pull/12440 [#12446]: https://github.com/home-assistant/home-assistant/pull/12446 [#12451]: https://github.com/home-assistant/home-assistant/pull/12451 [#12454]: https://github.com/home-assistant/home-assistant/pull/12454 [#12457]: https://github.com/home-assistant/home-assistant/pull/12457 [#12460]: https://github.com/home-assistant/home-assistant/pull/12460 [#12463]: https://github.com/home-assistant/home-assistant/pull/12463 [#12464]: https://github.com/home-assistant/home-assistant/pull/12464 [#12465]: https://github.com/home-assistant/home-assistant/pull/12465 [#12467]: https://github.com/home-assistant/home-assistant/pull/12467 [#12469]: https://github.com/home-assistant/home-assistant/pull/12469 [#12474]: https://github.com/home-assistant/home-assistant/pull/12474 [#12475]: https://github.com/home-assistant/home-assistant/pull/12475 [#12477]: https://github.com/home-assistant/home-assistant/pull/12477 [#12478]: https://github.com/home-assistant/home-assistant/pull/12478 [#12480]: https://github.com/home-assistant/home-assistant/pull/12480 [#12481]: https://github.com/home-assistant/home-assistant/pull/12481 [#12486]: https://github.com/home-assistant/home-assistant/pull/12486 [#12488]: https://github.com/home-assistant/home-assistant/pull/12488 [#12492]: https://github.com/home-assistant/home-assistant/pull/12492 [#12494]: https://github.com/home-assistant/home-assistant/pull/12494 [#12495]: https://github.com/home-assistant/home-assistant/pull/12495 [#12496]: https://github.com/home-assistant/home-assistant/pull/12496 [#12498]: https://github.com/home-assistant/home-assistant/pull/12498 [#12503]: https://github.com/home-assistant/home-assistant/pull/12503 [#12510]: https://github.com/home-assistant/home-assistant/pull/12510 [#12513]: https://github.com/home-assistant/home-assistant/pull/12513 [#12518]: https://github.com/home-assistant/home-assistant/pull/12518 [#12519]: https://github.com/home-assistant/home-assistant/pull/12519 [#12525]: https://github.com/home-assistant/home-assistant/pull/12525 [#12535]: https://github.com/home-assistant/home-assistant/pull/12535 [#12536]: https://github.com/home-assistant/home-assistant/pull/12536 [#12537]: https://github.com/home-assistant/home-assistant/pull/12537 [#12538]: https://github.com/home-assistant/home-assistant/pull/12538 [#12540]: https://github.com/home-assistant/home-assistant/pull/12540 [#12548]: https://github.com/home-assistant/home-assistant/pull/12548 [#12550]: https://github.com/home-assistant/home-assistant/pull/12550 [#12552]: https://github.com/home-assistant/home-assistant/pull/12552 [#12556]: https://github.com/home-assistant/home-assistant/pull/12556 [#12558]: https://github.com/home-assistant/home-assistant/pull/12558 [#12561]: https://github.com/home-assistant/home-assistant/pull/12561 [#12562]: https://github.com/home-assistant/home-assistant/pull/12562 [#12566]: https://github.com/home-assistant/home-assistant/pull/12566 [#12567]: https://github.com/home-assistant/home-assistant/pull/12567 [#12569]: https://github.com/home-assistant/home-assistant/pull/12569 [#12571]: https://github.com/home-assistant/home-assistant/pull/12571 [#12574]: https://github.com/home-assistant/home-assistant/pull/12574 [#12580]: https://github.com/home-assistant/home-assistant/pull/12580 [#12581]: https://github.com/home-assistant/home-assistant/pull/12581 [#12582]: https://github.com/home-assistant/home-assistant/pull/12582 [#12586]: https://github.com/home-assistant/home-assistant/pull/12586 [#12587]: https://github.com/home-assistant/home-assistant/pull/12587 [#12588]: https://github.com/home-assistant/home-assistant/pull/12588 [#12595]: https://github.com/home-assistant/home-assistant/pull/12595 [#12598]: https://github.com/home-assistant/home-assistant/pull/12598 [#12600]: https://github.com/home-assistant/home-assistant/pull/12600 [#12602]: https://github.com/home-assistant/home-assistant/pull/12602 [#12608]: https://github.com/home-assistant/home-assistant/pull/12608 [#12611]: https://github.com/home-assistant/home-assistant/pull/12611 [#12613]: https://github.com/home-assistant/home-assistant/pull/12613 [#12615]: https://github.com/home-assistant/home-assistant/pull/12615 [#12617]: https://github.com/home-assistant/home-assistant/pull/12617 [#12625]: https://github.com/home-assistant/home-assistant/pull/12625 [#12632]: https://github.com/home-assistant/home-assistant/pull/12632 [#12669]: https://github.com/home-assistant/home-assistant/pull/12669 [@ChristianKuehnel]: https://github.com/ChristianKuehnel [@FrederikBolding]: https://github.com/FrederikBolding [@Julius2342]: https://github.com/Julius2342 [@Kane610]: https://github.com/Kane610 [@NovapaX]: https://github.com/NovapaX [@OttoWinter]: https://github.com/OttoWinter [@OverloadUT]: https://github.com/OverloadUT [@PhilRW]: https://github.com/PhilRW [@ReneNulschDE]: https://github.com/ReneNulschDE [@abmantis]: https://github.com/abmantis [@amelchio]: https://github.com/amelchio [@aprasanna]: https://github.com/aprasanna [@armills]: https://github.com/armills [@bachya]: https://github.com/bachya [@thijsdejong]: https://github.com/thijsdejong [@balloob]: https://github.com/balloob [@bottomquark]: https://github.com/bottomquark [@cdce8p]: https://github.com/cdce8p [@cmsimike]: https://github.com/cmsimike [@d0ugal]: https://github.com/d0ugal [@danielhiversen]: https://github.com/danielhiversen [@dgomes]: https://github.com/dgomes [@elupus]: https://github.com/elupus [@fabaff]: https://github.com/fabaff [@simse]: https://github.com/simse [@gerard33]: https://github.com/gerard33 [@happyleavesaoc]: https://github.com/happyleavesaoc [@hmn]: https://github.com/hmn [@igorbernstein2]: https://github.com/igorbernstein2 [@jcconnell]: https://github.com/jcconnell [@jeradM]: https://github.com/jeradM [@jeremydk]: https://github.com/jeremydk [@jesserockz]: https://github.com/jesserockz [@karlkar]: https://github.com/karlkar [@kellerza]: https://github.com/kellerza [@kennedyshead]: https://github.com/kennedyshead [@lucasweb78]: https://github.com/lucasweb78 [@matt2005]: https://github.com/matt2005 [@matthewcky2k]: https://github.com/matthewcky2k [@mikeodr]: https://github.com/mikeodr [@mjj4791]: https://github.com/mjj4791 [@neffs]: https://github.com/neffs [@patrik3k]: https://github.com/patrik3k [@pvizeli]: https://github.com/pvizeli [@rcloran]: https://github.com/rcloran [@robmarkcole]: https://github.com/robmarkcole [@rubenverhoef]: https://github.com/rubenverhoef [@rytilahti]: https://github.com/rytilahti [@scarface-4711]: https://github.com/scarface-4711 [@sjvc]: https://github.com/sjvc [@snjoetw]: https://github.com/snjoetw [@swbradshaw]: https://github.com/swbradshaw [@syssi]: https://github.com/syssi [@tabakhase]: https://github.com/tabakhase [@thrawnarn]: https://github.com/thrawnarn [@tinloaf]: https://github.com/tinloaf [@trisk]: https://github.com/trisk [@tschmidty69]: https://github.com/tschmidty69 [@ttroy50]: https://github.com/ttroy50 [@zhelev]: https://github.com/zhelev [@fanthos]: https://github.com/fanthos [@c727]: https://github.com/c727 [@ciotlosm]: https://github.com/ciotlosm [@frenck]: https://github.com/frenck [@pvizeli]: https://github.com/pvizeli [@ryanm101]: https://github.com/ryanm101 [alexa docs]: /integrations/alexa/ [august docs]: /integrations/august/ [binary_sensor.august docs]: /integrations/august#binary-传感器 [binary_sensor.bloomsky docs]: /integrations/bloomsky#binary-传感器 [binary_sensor.deconz docs]: /integrations/deconz#binary-传感器 [binary_sensor.knx docs]: /integrations/binary_sensor.knx/ [bmw_connected_drive docs]: /integrations/bmw_connected_drive/ [日历.caldav docs]: /integrations/caldav [摄像头.august docs]: /integrations/august#摄像头 [摄像头.bloomsky docs]: /integrations/bloomsky/#摄像头 [摄像头.doorbird docs]: /integrations/doorbird#摄像头 [摄像头.onvif docs]: /integrations/onvif [摄像头.rpi_camera docs]: /integrations/rpi_camera [温控.eq3btsmart docs]: /integrations/eq3btsmart [温控.knx docs]: /integrations/温控.knx/ [温控.melissa docs]: /integrations/melissa [cloud docs]: /integrations/cloud/ [config docs]: /integrations/config/ [conversation docs]: /integrations/conversation/ [遮盖.knx docs]: /integrations/遮盖.knx/ [遮盖.opengarage docs]: /integrations/opengarage [deconz docs]: /integrations/deconz/ [device_tracker.asuswrt docs]: /integrations/asuswrt [device_tracker.bmw_connected_drive docs]: /integrations/bmw_connected_drive [device_tracker.nmap_tracker docs]: /integrations/nmap_tracker [device_tracker.unifi docs]: /integrations/unifi [风扇.xiaomi_miio docs]: /integrations/风扇.xiaomi_miio/ [前端 docs]: /integrations/frontend/ [google_assistant docs]: /integrations/google_assistant/ [hassio docs]: /integrations/hassio/ [history docs]: /integrations/history/ [homekit docs]: /integrations/homekit/ [homekit.accessories docs]: /integrations/homekit.accessories/ [homekit.const docs]: /integrations/homekit.const/ [homekit.遮盖 docs]: /integrations/homekit.遮盖/ [homekit.传感器 docs]: /integrations/homekit.传感器/ [http docs]: /integrations/http/ [input_datetime docs]: /integrations/input_datetime/ [isy994 docs]: /integrations/isy994/ [knx docs]: /integrations/knx/ [灯光.deconz docs]: /integrations/deconz#灯光 [灯光.iglo docs]: /integrations/iglo [灯光.knx docs]: /integrations/灯光.knx/ [灯光.limitlessled docs]: /integrations/limitlessled [灯光.xiaomi_miio docs]: /integrations/灯光.xiaomi_miio/ [门锁.august docs]: /integrations/august [门锁.zwave docs]: /integrations/zwave#门锁 [logbook docs]: /integrations/logbook/ [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.bluesound docs]: /integrations/bluesound [媒体播放器.braviatv_psk docs]: /integrations/braviatv_psk/ [媒体播放器.cast docs]: /integrations/cast [媒体播放器.denonavr docs]: /integrations/denonavr/ [媒体播放器.frontier_silicon docs]: /integrations/frontier_silicon [媒体播放器.panasonic_viera docs]: /integrations/panasonic_viera [媒体播放器.sonos docs]: /integrations/sonos [媒体播放器.xiaomi_tv docs]: /integrations/xiaomi_tv [melissa docs]: /integrations/melissa/ [MQTT docs]: /integrations/MQTT/ [mqtt_eventstream docs]: /integrations/mqtt_eventstream/ [通知.html5 docs]: /integrations/html5 [通知.knx docs]: /integrations/通知.knx/ [通知.lametric docs]: /integrations/lametric [panel_iframe docs]: /integrations/panel_iframe/ [遥控器.xiaomi_miio docs]: /integrations/遥控器.xiaomi_miio/ [场景 docs]: /integrations/场景/ [传感器.airvisual docs]: /integrations/airvisual [传感器.alpha_vantage docs]: /integrations/alpha_vantage [传感器.bloomsky docs]: /integrations/bloomsky/#传感器 [传感器.bmw_connected_drive docs]: /integrations/bmw_connected_drive [传感器.buienradar docs]: /integrations/传感器.buienradar/ [传感器.deconz docs]: /integrations/deconz#传感器 [传感器.fastdotcom docs]: /integrations/fastdotcom [传感器.filesize docs]: /integrations/file#sensorsize/ [传感器.folder docs]: /integrations/folder [传感器.knx docs]: /integrations/传感器.knx/ [传感器.pollen docs]: /integrations/iqvia [传感器.rfxtrx docs]: /integrations/rfxtrx#传感器 [传感器.sabnzbd docs]: /integrations/sabnzbd [传感器.sma docs]: /integrations/sma#传感器 [传感器.smappee docs]: /integrations/sma#sensorsppee/ [传感器.speedtest docs]: /integrations/speedtestdotnet [传感器.spotcrime docs]: /integrations/spotcrime [传感器.startca docs]: /integrations/startca [传感器.模板 docs]: /integrations/模板 [传感器.tibber docs]: /integrations/tibber#传感器 [传感器.wunderground docs]: /integrations/wunderground [传感器.zha docs]: /integrations/zha [shopping_list docs]: /integrations/shopping_list/ [smappee docs]: /integrations/smappee/ [开关.knx docs]: /integrations/开关.knx/ [开关.rainmachine docs]: /integrations/rainmachine#开关 [开关.smappee docs]: /integrations/smappee [开关.xiaomi_miio docs]: /integrations/开关.xiaomi_miio/ [tahoma docs]: /integrations/tahoma/ [telegram_bot docs]: /integrations/telegram_bot/ [吸尘器.xiaomi_miio docs]: /integrations/吸尘器.xiaomi_miio/ [vera docs]: /integrations/vera/ [天气.buienradar docs]: /integrations/buienradar [xiaomi_aqara docs]: /integrations/xiaomi_aqara/ [zha docs]: /integrations/zha/ [#12635]: https://github.com/home-assistant/home-assistant/pull/12635 [#12645]: https://github.com/home-assistant/home-assistant/pull/12645 [#12657]: https://github.com/home-assistant/home-assistant/pull/12657 [#12679]: https://github.com/home-assistant/home-assistant/pull/12679 [#12685]: https://github.com/home-assistant/home-assistant/pull/12685 [#12687]: https://github.com/home-assistant/home-assistant/pull/12687 [#12691]: https://github.com/home-assistant/home-assistant/pull/12691 [#12711]: https://github.com/home-assistant/home-assistant/pull/12711 [#12715]: https://github.com/home-assistant/home-assistant/pull/12715 [#12719]: https://github.com/home-assistant/home-assistant/pull/12719 [#12726]: https://github.com/home-assistant/home-assistant/pull/12726 [#12729]: https://github.com/home-assistant/home-assistant/pull/12729 [#12737]: https://github.com/home-assistant/home-assistant/pull/12737 [@ChristianKuehnel]: https://github.com/ChristianKuehnel [@NovapaX]: https://github.com/NovapaX [@OttoWinter]: https://github.com/OttoWinter [@amelchio]: https://github.com/amelchio [@aronsky]: https://github.com/aronsky [@balloob]: https://github.com/balloob [@jesserockz]: https://github.com/jesserockz [@kellerza]: https://github.com/kellerza [@pvizeli]: https://github.com/pvizeli [@scarface-4711]: https://github.com/scarface-4711 [@tumik]: https://github.com/tumik [@fanthos]: https://github.com/fanthos [@PhilRW]: https://github.com/PhilRW [binary_sensor.deconz docs]: /integrations/deconz#binary-传感器 [deconz docs]: /integrations/deconz/ [灯光.iglo docs]: /integrations/iglo [媒体播放器.cast docs]: /integrations/cast [媒体播放器.denonavr docs]: /integrations/denonavr/ [mysensors docs]: /integrations/mysensors/ [遥控器.harmony docs]: /integrations/harmony [传感器.alpha_vantage docs]: /integrations/alpha_vantage [tahoma docs]: /integrations/tahoma/ [吸尘器.roomba docs]: /integrations/roomba [zha docs]: /integrations/zha/ [#12759]: https://github.com/home-assistant/home-assistant/pull/12759 [#12762]: https://github.com/home-assistant/home-assistant/pull/12762 [#12764]: https://github.com/home-assistant/home-assistant/pull/12764 [#12767]: https://github.com/home-assistant/home-assistant/pull/12767 [#12769]: https://github.com/home-assistant/home-assistant/pull/12769 [#12789]: https://github.com/home-assistant/home-assistant/pull/12789 [#12790]: https://github.com/home-assistant/home-assistant/pull/12790 [#12796]: https://github.com/home-assistant/home-assistant/pull/12796 [#12799]: https://github.com/home-assistant/home-assistant/pull/12799 [@ChristianKuehnel]: https://github.com/ChristianKuehnel [@amelchio]: https://github.com/amelchio [@bachya]: https://github.com/bachya [@basschipper]: https://github.com/basschipper [@happyleavesaoc]: https://github.com/happyleavesaoc [@ryanm101]: https://github.com/ryanm101 [@uchagani]: https://github.com/uchagani [binary_sensor.rfxtrx docs]: /integrations/rfxtrx#binary-传感器 [bmw_connected_drive docs]: /integrations/bmw_connected_drive/ [logbook docs]: /integrations/logbook/ [媒体播放器.plex docs]: /integrations/plex#media-player [媒体播放器.samsungtv docs]: /integrations/samsungtv [媒体播放器.sonos docs]: /integrations/sonos [传感器.pollen docs]: /integrations/iqvia [#12810]: https://github.com/home-assistant/home-assistant/pull/12810 [#12837]: https://github.com/home-assistant/home-assistant/pull/12837 [#12840]: https://github.com/home-assistant/home-assistant/pull/12840 [#12845]: https://github.com/home-assistant/home-assistant/pull/12845 [@andrey-git]: https://github.com/andrey-git [@balloob]: https://github.com/balloob [@kellerza]: https://github.com/kellerza [温控.sensibo docs]: /integrations/sensibo [cloud docs]: /integrations/cloud/ [hue docs]: /integrations/hue/ --- url: /home-assistant/blog/2018-03-09-release-65.md --- --- url: /home-assistant/blog/2018-03-24-new-release-schedule.md --- # 更新发布节奏 这个周末我们会稍微调整一下发布方式。今天我们不会直接发布新版本,而是先发布新版本的 beta:`0.66.0.beta0`。经过一周 beta 测试后,这个版本会晋升为新的稳定版发布。在 beta 期间,我们也会像往常一样继续在 `dev` 分支接收下一个版本的贡献。

Diagram showing the updates 发布 cycle containing a week extra time before 发布. 新发布节奏示意图

我们的目标是让首次正式发布更稳定,尽量减少紧急热修复的需要。所以如果你希望更快体验新功能,并且可以接受偶发 bug 的风险,现在就可以切换到 beta 通道: * Hass.io 用户可在系统设置里启用 `dev` 通道。 * Docker 用户可以通过 `rc` 标签获取 beta 版本。 * 我们也会把 beta 版本发布到 PyPI。由于它是 beta 发布,`pip` 默认不会安装,需在命令中显式指定:`pip3 install --pre --upgrade homeassistant`。 beta 版本文档见 。 如果你在预发布版本的代码或文档中发现问题,请在[对应位置](/home-assistant/help/#bugs-feature-requests-and-alike)提交 issue,或者更好的是直接提交 pull request 修复。 --- url: /home-assistant/blog/2018-03-29-fedora-atomic.md --- # 在 Fedora Atomic 上运行 Home Assistant Hackerspace [Eastermundigen](http://www.eastermundigen.ch/) 一直是我做 Home Assistant 相关实战的“试验场”,其中不少场景甚至更偏工业自动化而非家庭场景。在那里我还能接触到自己没有的设备,比如 3D 打印机、激光切割机、联网插排等。过去,当地的 Home Assistant 实例运行在一台装有 [Fedora ARM](https://arm.fedoraproject.org/) 的旧 [CubieBoard2](http://cubieboard.org/) 上。它只是多台 24/7 运行设备之一。为了降低电费,我们决定把实体机器合并成两台:一台负责存储,另一台负责其余服务。 这篇文章记录了具体配置过程,也许对其他人有参考价值。我们的新系统运行的是来自 [Project Atomic](http://www.projectatomic.io) 的 Fedora 27。本文不会展开 Atomic 主机安装流程及 Project Atomic 本身细节。若需更多背景,可参考 [Benjamin Affolter](https://twitter.com/bliemli) 的[文章](https://www.puzzle.ch/博客/articles/2017/09/28/atomic-host-basic-设置-and-usage),其中也介绍了一些基础内容。 Atomic 主机的安装流程与 Fedora Server / Fedora Workstation 基本一致。你可以制作 Live USB,或使用 PXE 启动安装。比如先启动 iPXE,再用 `chain --autofree https://boot.netboot.xyz` 链式加载 [netboot.yxz](https://netboot.xyz/),然后按 `anaconda` 向导完成设置。 首次启动后,复制 SSH 密钥、用 `visudo` 添加用户,并完成新系统常规初始化。我们只允许密钥 SSH 登录、强制使用 `sudo`,并设置了特殊网络策略等。不过这些额外配置对普通局域网部署并非必需。 系统运行后,先检查是否为最新发布版本。 ```bash $ sudo atomic host status State: idle; auto updates disabled Deployments: ● ostree://fedora-atomic:fedora/27/x86_64/atomic-host Version: 27.100 (2018-03-13 17:19:44) Commit: 326f62b93a5cc836c97d31e73a71b6b6b6955c0f225f7651b52a693718e6aa91 GPGSignature: Valid signature by 860E19B0AFA800A1751881A6F55E7430F5282EE4 ``` 当前版本是 27.100,最新是 27.105。下面先更新主机并重启。 ```bash sudo atomic host upgrade sudo systemctl reboot ``` 你也会看到 Docker 已经在运行,无需额外安装。 ```bash $ sudo systemctl status docker ● docker.service - Docker Application Container Engine Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled) Active: active (running) since Thu 2018-03-28 15:44:04 CEST; 35min ago ... ``` 下面我们会介绍 Home Assistant 和 [Mosquitto](https://mosquitto.org/) 的部署方式。对于这个规模较小的环境,使用 [kubernetes](https://kubernetes.io) 有点过重,因此我们选择继续用 `systemd`。 除了 `docker`,我们也可以使用命令行工具 [`atomic`](http://www.projectatomic.io/docs/usr-bin-atomic/) 完成很多任务。先下载容器镜像。我们从 [Docker Hub](https://hub.Docker.com/) 拉取镜像,因此需要添加对应 registry。 ```bash sudo atomic install docker.io/​homeassistant/home-assistant sudo atomic install docker.io/eclipse-mosquitto ``` 两个容器都需要额外目录用于持久化存储。 ```bash sudo mkdir -p /opt/home-assistant sudo mkdir -p /opt/mosquitto/{config,data,log} ``` 后续运行 Mosquitto 需要一份 `mosquitto.conf`: ```bash sudo curl -o /opt/mosquitto/config/mosquitto.conf \ https://raw.githubusercontent.com/eclipse/mosquitto/master/mosquitto.conf ``` 为了管理容器,我们为 [Home Assistant](https://hub.Docker.com/r/homeassistant/home-assistant/) 和 [Mosquitto](https://hub.Docker.com/_/eclipse-mosquitto/) 创建 systemd 服务单元文件。示例如下。`ExecStart` 相关细节可参考 [Docker](/home-assistant/docs/installation/Docker/) 部署文档。先是 Home Assistant: ```bash $ su # cat <<'EOF' >> /etc/systemd/system/home-assistant.service [Unit] Description=Home Assistant Requires=docker.service Wants=docker.service After=docker.service [Service] Restart=on-failure RestartSec=10 ExecStart=/usr/bin/docker run --rm --name %p -v /opt/home-assistant:/config:Z -v /etc/localtime:/etc/localtime:ro --network host homeassistant/home-assistant ExecStop=-/usr/bin/docker stop -t 30 %p [Install] WantedBy=multi-user.target EOF ``` 下面是 Mosquitto: ```bash # cat <<'EOF' >> /etc/systemd/system/mosquitto.service [Unit] Description=Mosquitto MQTT docker container Requires=docker.service Wants=docker.service After=docker.service [Service] Restart=on-failure RestartSec=10 ExecStart=/usr/bin/docker run --name %p -v mosquitto.conf:/opt/mosquitto/config/mosquitto.conf -v /opt/mosquitto/data:/opt/mosquitto/data -v /opt/mosquitto/log:/mosquitto/log -p 1883:1883 -p 9001:9001 eclipse-mosquitto ExecStop=/usr/bin/docker stop -t 2 %p ExecStopPost=/usr/bin/docker rm -f %p [Install] WantedBy=multi-user.target EOF ``` 退出 `root` 用户: ```bash # exit ``` 重载 `systemd`,让它识别新的配置。 ```bash sudo systemctl daemon-reload ``` 现在两个容器都可以通过 `systemctl` 控制。 ```bash sudo systemctl enable home-assistant.service --now sudo systemctl enable mosquitto.service --now ``` 使用 `$ sudo systemctl status [name].service` 检查服务是否报错、是否正常运行。 [NGINX](https://nginx.org/en/)(静态内容 Web 服务器)、[grafana](https://grafana.com/) 和 [InfluxBD](https://www.influxdata.com/) 的部署方式与 Home Assistant、Mosquitto 类似。若要正确配置 [traefik](https://traefik.io/),还需要额外阅读资料并做更多配置。 --- url: /home-assistant/blog/2018-03-30-release-66.md --- # 0.66:VeSync 开关、HomematicIP,以及分组遮盖 这是我们采用新发布节奏后的第一个版本。在额外的一周里,我们总共发布了 4 个 beta 版本,并完成了 [26 项修复](https://github.com/home-assistant/home-assistant/milestone/128?closed=1)。因此这应该是迄今为止最稳定的一个版本。 这同样也是一个内容满满的版本。在这个发布周期的最后两周里,有 80 位贡献者提交了超过 223 项修复、改进和新集成 😎 我特别想感谢两位表现出色的贡献者:[@NovapaX] 在前端问题分流和各种疑难 bug 修复上做了大量工作;同时也要感谢 [@armills],他启用了后端翻译。这意味着此前很多还不能翻译的内容,很快都能翻译了。我们也在基于这项能力规划一些很酷的功能! 如果你正在使用 Philips Hue 且安装了 Hue 自定义组件,请注意:由于 Hue 平台内部实现已变更,该自定义组件将不再可用。请移除自定义组件,以确保你的 Hue 灯光继续正常工作。 ## 新平台 * 新增 VeSync 开关平台 ([@markperdue] - [#13000]) ([开关.vesync docs]) (new-platform) * HomeKit 重构(新增配置选项) ([@cdce8p] - [#12997]) ([homekit docs]) (breaking change) (new-platform) * 新增 `遮盖.group` 平台(替代 #12303) ([@cdce8p] - [#12692]) ([遮盖.group docs]) (new-platform) * 为 BMW ConnectedDrive 新增更多传感器 ([@gerard33] - [#12591]) ([bmw\_connected\_drive docs][bmw_connected_drive docs]) ([binary\_sensor.bmw\_connected\_drive docs][binary_sensor.bmw_connected_drive docs]) ([门锁.bmw\_connected\_drive docs][门锁.bmw_connected_drive docs]) ([传感器.bmw\_connected\_drive docs][传感器.bmw_connected_drive docs]) (new-platform) * HomeKit:新增更多支持的设备 ([@cdce8p] - [#13244]) ([homekit docs]) (new-platform) * 新增 Foobot 设备传感器 ([@reefab] - [#12417]) ([传感器.foobot docs]) (new-platform) * 新增 Stride 通知组件 ([@BioSehnsucht] - [#13221]) ([通知 docs]) (new-platform) * Xiaomi MiIO 传感器: Xiaomi Air Quality Monitor (PM2.5) 集成 ([@syssi] - [#13264]) ([传感器.xiaomi\_miio docs][传感器.xiaomi_miio docs]) (new-platform) * 初步支持 HomematicIP 组件 ([@mxworm] - [#12761]) (new-platform) * 支持通过 IFTTT 控制的安防系统 ([@maxclaey] - [#12975]) ([alarm\_control\_panel.ifttt docs][alarm_control_panel.ifttt docs]) (new-platform) * Zigbee 风扇 ([@igorbernstein2] - [#12289]) ([zha docs]) ([风扇.zha docs]) (new-platform) * Adding a discoverable Samsung Syncthru Printer 传感器 platform ([@nielstron] - [#13134]) ([传感器.syncthru docs]) (new-platform) * Add trafikverket\_weatherstation 传感器 platform ([@Qxlkdr] - [#12115]) ([传感器.trafikverket\_weatherstation docs][传感器.trafikverket_weatherstation docs]) (new-platform) * Security fix & 门锁 for HomeMatic ([@PH89] - [#11980]) ([homematic docs]) ([门锁 docs]) ([门锁.homematic docs]) (breaking change) (new-platform) ## 发布 0.66.1 - April 1 * 更新 前端 to fix 温控 and chart issues ([@NovapaX] & [@c727]) * Fix mqtt\_json color commands ([@armills] - [#13617]) ([灯光.mqtt\_json docs][灯光.mqtt_json docs]) * Add pincode fallback ([@cdce8p] - [#13587]) ([homekit docs]) * Fix mysensors 传感器 type lookup ([@MartinHjelmare] - [#13574]) ([传感器.mysensors docs]) ## 如果你需要帮助…… ……欢迎随时使用我们非常活跃的[论坛](https://community.home-assistant.io/),或加入我们的 [chat](https://discord.gg/c5DvZ4e) 交流。发布说明虽然开放评论,但我们更推荐你使用前面的沟通渠道。谢谢。 ## 报告问题 如果你遇到了由此版本引入的问题,请在我们的 [issue tracker](https://github.com/home-assistant/home-assistant/issues) 中反馈,并确保完整填写 issue 模板中的所有字段。 ## 不向后兼容的变更 * Hue 重构:如果你在配置中手动指定了桥接器,现在必须提供 `host` 键,且其值必须是合法 IP 地址。`allow_in_emulated_hue` 选项已被移除,请改为在 emulated hue 配置中排除灯光。由于 Hue 集成内部实现发生变化,任何 Hue 自定义组件都将不再可用。([@balloob] - [#13043]) ([hue docs]) ([灯光.hue docs]) (breaking change) * Z-Wave:在 0.47 版本中,为了平滑过渡曾加入可选配置 `new_entity_ids`。现在旧实体 ID 的支持已被移除,这项配置也不再需要。如果你是从 0.63 或更高版本升级,实体 ID 应已存储在实体注册表中,无需额外变更;否则,如有需要,现在可以通过实体注册表手动配置实体 ID。([@armills] - [#12652]) ([zwave docs]) (breaking change) * Spotcrime 传感器:本次更新改为要求用户在配置中提供 API key。Spotcrime 包内置的默认 key 已被移除,并修改为接受用户提供的 API key。([@jcconnell] - [#12926]) ([传感器.spotcrime docs]) (breaking change) * Smappee 传感器:修复电流消耗的 SI 单位。总消耗应为 kWh,而不是 kW。([@vandenberghev] - [#13190]) ([传感器.smappee docs]) (breaking change) * System monitor 传感器:系统监控组件上报的已用和可用交换分区空间,现在改为使用 MiB 而不是 GiB。([@DanNixon] - [#13148]) ([传感器.systemmonitor docs]) (breaking change) * HomeKit:`pincode` 参数已弃用,因为 `HomeKit` 组件现在会自动生成配对码,并在设置期间通过持久通知显示出来。此外,默认 `port` 已改为 `51827`,以避免与 `homebridge` 冲突。最后,为修复一个重大 bug,我们调整了 accessory ID 的生成方式,这意味着你需要重新完成此前所有 accessory 的设置。为避免后续冲突,强烈建议你先从 `Home` 应用中移除 `Home Assistant Bridge`,再重新配对设置。([HomeKit 设置](/home-assistant/integrations/homekit/index.md#设置)) ([@cdce8p] - [#12997]) ([homekit docs]) (breaking change) (new-platform) * Tibber:Tibber 传感器的名称和实体 ID 现在会与应用中的昵称保持一致。默认昵称是地址,因此如果你没有修改过应用中的昵称,效果应与之前相同。([@clementhk] - [#13231]) ([传感器.tibber docs]) (breaking change) * DarkSky 传感器:根据 Dark Sky API 文档,修复 IS 单位下 `Precip Intensity` 和 `Daily Max Precip Intensity` 的错误计量单位。([@cgtobi] - [#13415]) ([传感器.darksky docs]) (breaking change) * HomeMatic: 门锁 are now under the 门锁 component ([@PH89] - [#11980]) ([homematic docs]) ([门锁 docs]) ([门锁.homematic docs]) (breaking change) (new-platform) ## 所有变更 * New lazytox.py 脚本 ([@kellerza] - [#12862]) * 更新 netdisco to 1.3.0 ([@balloob] - [#13007]) * remove rounding of temperature reading ([@hthiery] - [#13018]) ([传感器.lacrosse docs]) * Make lazytox 脚本 executable ([@OttoWinter] - [#13040]) * python-miio 版本 bumped. ([@syssi] - [#13055]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) ([遥控器.xiaomi\_miio docs][遥控器.xiaomi_miio docs]) ([开关.xiaomi\_miio docs][开关.xiaomi_miio docs]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) * Glances Docker 传感器 ([@timmo001] - [#13026]) ([传感器.glances docs]) * 脚本/lint, Lazytox: Fix issue to ignore delete files ([@cdce8p] - [#13051]) * 传感器 模板 don't exit early on TemplateError ([@OttoWinter] - [#13041]) ([传感器.模板 docs]) * Better 错误 for unknown secrets ([@kellerza] - [#13072]) * Remove Z-Wave old/new entity\_id 属性 ([@armills] - [#12652]) ([zwave docs]) (breaking change) * Make Sensibo 温控 registry\_entity compliant ([@andrey-git] - [#13086]) ([温控.sensibo docs]) * Rename homeassistant.util.async to .async\_ ([@smurfix] - [#13088]) * Config flow translations ([@armills] - [#13066]) * Lint 脚本 tweaks ([@armills] - [#13093]) * asyncio.ensure\_future Python 3.5 ([@OttoWinter] - [#13141]) ([spc docs]) * 升级 aiohttp to 3.0.7 ([@fabaff] - [#13119]) * 升级 astral to 1.6 ([@fabaff] - [#13120]) * fix: Support different JointSpace API versions ([@FezVrasta] - [#13084]) ([媒体播放器.philips\_js docs][媒体播放器.philips_js docs]) * 更新 to async/await ([@perosb] - [#13137]) ([zha docs]) ([灯光.zha docs]) * 升级 mypy to 0.570 ([@fabaff] - [#13128]) * 升级 TwitterAPI to 2.4.10 ([@fabaff] - [#13126]) ([通知 docs]) * 升级 youtube\_dl to 2018.03.10 ([@fabaff] - [#13124]) ([media\_extractor docs][media_extractor docs]) * 升级 zeroconf to 0.20.0 ([@fabaff] - [#13123]) ([zeroconf docs]) * 升级 schiene to 0.22 ([@fabaff] - [#13121]) ([传感器.deutsche\_bahn docs][传感器.deutsche_bahn docs]) * Remove crazy JSON encoding things that are no longer used ([@balloob] - [#13029]) ([http docs]) ([websocket\_api docs][websocket_api docs]) * Disable Monkey Patch for 3.6.3+ ([@OttoWinter] - [#13150]) * 升级 Sphinx to 1.7.1 ([@fabaff] - [#13127]) * 升级 tibber library to 0.4.0 to use aiohttp 3.0 ([@danielhiversen] - [#13164]) ([传感器.tibber docs]) * Change iglo port to cv.port validator ([@jesserockz] - [#13163]) ([灯光.iglo docs]) * deConz rewrite to use async await syntax ([@Kane610] - [#13151]) ([deconz docs]) ([binary\_sensor.deconz docs][binary_sensor.deconz docs]) ([灯光.deconz docs]) ([场景.deconz docs]) ([传感器.deconz docs]) * 升级 holidays to 0.9.4 ([@OttoWinter] - [#13167]) ([binary\_sensor.workday docs][binary_sensor.workday docs]) * upcloud: Provide unique ID for server 实体 ([@scop] - [#13181]) ([upcloud docs]) * Added IPAreaThermostat and an exception-list for HM\_IGNORE\_DISCOVERY\_NODE ([@a-wolter] - [#13171]) ([homematic docs]) ([传感器.homematic docs]) * Improve MQTT failed connection 错误 message ([@OttoWinter] - [#13184]) ([MQTT docs]) * 升级 pytest to 3.4.2 ([@OttoWinter] - [#13169]) * Channels clean ups ([@maddox] - [#12967]) ([媒体播放器.channels docs]) * Fix freegeoip ([@pvizeli] - [#13193]) * Python Spotcrime 传感器 requires API key, fixes include/exclude ([@jcconnell] - [#12926]) ([传感器.spotcrime docs]) (breaking change) * Add new platform for VeSync 开关 ([@markperdue] - [#13000]) ([开关.vesync docs]) (new-platform) * Fixed SI units for current consumption ([@vandenberghev] - [#13190]) ([传感器.smappee docs]) (breaking change) * Report swap in MiB ([@DanNixon] - [#13148]) ([传感器.systemmonitor docs]) (breaking change) * Fix history API ([@balloob] - [#13214]) ([history docs]) * Add 通知 to downloader.py ([@engrbm87] - [#12961]) ([downloader docs]) * HomeKit Restructure (new config options) ([@cdce8p] - [#12997]) ([homekit docs]) (breaking change) (new-platform) * deCONZ - Add support for consumption and power 传感器 ([@Kane610] - [#13218]) ([deconz docs]) ([binary\_sensor.deconz docs][binary_sensor.deconz docs]) ([传感器.deconz docs]) * Change Hass.io icon to home-assistant ([@c727] - [#13230]) ([hassio docs]) * Add docstring ([@fabaff] - [#13232]) ([传感器.crimereports docs]) * Python 3.5 adjustments ([@OttoWinter] - [#13173]) ([mysensors docs]) * Added 遮盖.group platform (replaces #12303) ([@cdce8p] - [#12692]) ([遮盖.group docs]) (new-platform) * Tibber use appNickname as name ([@clementhk] - [#13231]) ([传感器.tibber docs]) (breaking change) * media\_content\_type 属性 display fix ([@kuzin2006] - [#13204]) ([媒体播放器.kodi docs]) * Edimax component reports wrong power values ([@andreipop2005] - [#13011]) ([开关.edimax docs]) * myStrom: Add RGB support to WiFi bulbs ([@the-glu] - [#13194]) ([灯光.mystrom docs]) * Fix logbook JSON serialize issue ([@balloob] - [#13229]) ([logbook docs]) * Try to fix caldav ([@maxlaverse] - [#13236]) ([日历.caldav docs]) * Cleanup Sonos platform 设置 ([@amelchio] - [#13225]) ([媒体播放器.sonos docs]) * Fix 'dict' object has no 属性 'strftime' ([@Juggels] - [#13215]) ([日历.todoist docs]) * Fix aiohttp deprecation 警告 ([@balloob] - [#13240]) * Add extra 传感器 for BMW ConnectedDrive ([@gerard33] - [#12591]) ([bmw\_connected\_drive docs][bmw_connected_drive docs]) ([binary\_sensor.bmw\_connected\_drive docs][binary_sensor.bmw_connected_drive docs]) ([门锁.bmw\_connected\_drive docs][门锁.bmw_connected_drive docs]) ([传感器.bmw\_connected\_drive docs][传感器.bmw_connected_drive docs]) (new-platform) * Homekit: New 支持的devices ([@cdce8p] - [#13244]) ([homekit docs]) (new-platform) * Adding Foobot 设备 传感器 ([@reefab] - [#12417]) ([传感器.foobot docs]) (new-platform) * Fix for not setting up the 摄像头 if it is offline during 设置 phase ([@karlkar] - [#13082]) ([摄像头.onvif docs]) * Added Stride 通知 component ([@BioSehnsucht] - [#13221]) ([通知 docs]) (new-platform) * Homekit: Use util functions for unit conversion ([@cdce8p] - [#13253]) ([homekit docs]) * Use the first, not the last volume controller when multiple are available on songpal ([@rytilahti] - [#13222]) ([媒体播放器.songpal docs]) * Xiaomi MiIO 开关: Power Strip support improved ([@syssi] - [#12917]) ([开关.xiaomi\_miio docs][开关.xiaomi_miio docs]) * Xiaomi MiIO 灯光: Philips Eyecare Smart Lamp 2 集成 ([@syssi] - [#12883]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) * Fix guide link in CONTRIBUTING.md ([@JensTimmerman] - [#13272]) * Xiaomi MiIO 遥控器: Unique id added ([@syssi] - [#13266]) ([遥控器.xiaomi\_miio docs][遥控器.xiaomi_miio docs]) * Xiaomi MiIO 传感器: Xiaomi Air Quality Monitor (PM2.5) 集成 ([@syssi] - [#13264]) ([传感器.xiaomi\_miio docs][传感器.xiaomi_miio docs]) (new-platform) * Refactor Hue: phue -> aiohue ([@balloob] - [#13043]) ([hue docs]) ([灯光.hue docs]) (breaking change) * Unused xiaomi miio 传感器 method removed ([@syssi] - [#13281]) ([传感器.xiaomi\_miio docs][传感器.xiaomi_miio docs]) * Changed to async/await ([@thrawnarn] - [#13246]) ([媒体播放器.bluesound docs]) * Python 3.5 async with ([@OttoWinter] - [#13283]) * Fix WUnderground duplicate 实体 ids ([@OttoWinter] - [#13285]) ([传感器.wunderground docs]) * 升级 aiohttp to 3.0.9 ([@fabaff] - [#13288]) * 升级 aiohttp\_cors to 0.7.0 ([@fabaff] - [#13289]) ([http docs]) * 升级 sqlalchemy to 1.2.5 ([@fabaff] - [#13292]) ([传感器.sql docs]) * 升级 TwitterAPI to 2.5.0 ([@fabaff] - [#13287]) ([通知 docs]) * 升级 numpy to 1.14.2 ([@fabaff] - [#13291]) ([binary\_sensor.trend docs][binary_sensor.trend docs]) ([image\_processing.opencv docs][image_processing.opencv docs]) * 升级 python-telegram-bot to 10.0.1 ([@fabaff] - [#13294]) ([telegram\_bot docs][telegram_bot docs]) * 升级 python-forecastio to 1.4.0 ([@cgtobi] - [#13282]) ([天气.darksky docs]) * Delete .gitmodules ([@pvizeli] - [#13295]) * 更新 to latest python-nest ([@cburgess] - [#12590]) ([nest docs]) * 升级 async\_timeout to 2.0.1 ([@fabaff] - [#13290]) * Add initial support fo HomematicIP components ([@mxworm] - [#12761]) (new-platform) * Added Time based SMA to Filter 传感器 ([@dgomes] - [#13104]) ([传感器.filter docs]) * Support for security systems controlled by IFTTT ([@maxclaey] - [#12975]) ([alarm\_control\_panel.ifttt docs][alarm_control_panel.ifttt docs]) (new-platform) * Add ecobee 风扇 mode ([@uchagani] - [#12732]) ([ecobee docs]) ([温控.ecobee docs]) * Zigbee 风扇 ([@igorbernstein2] - [#12289]) ([zha docs]) ([风扇.zha docs]) (new-platform) * 更新 plex.py ([@kraddatz] - [#12157]) ([传感器.plex docs]) * Support MQTT 门锁 discovery ([@molobrakos] - [#13303]) ([MQTT docs]) ([门锁.MQTT docs]) * Adding a discoverable Samsung Syncthru Printer 传感器 platform ([@nielstron] - [#13134]) ([传感器.syncthru docs]) (new-platform) * Use hue/sat as internal 灯光 color interface ([@armills] - [#11288]) ([灯光 docs]) * Superfluous None ([@dgomes] - [#13326]) ([传感器.filter docs]) * pytest 3.4.0 cache gitignore ([@OttoWinter] - [#13308]) * Add trafikverket\_weatherstation 传感器 platform ([@Qxlkdr] - [#12115]) ([传感器.trafikverket\_weatherstation docs][传感器.trafikverket_weatherstation docs]) (new-platform) * zha: catch the exception from bellows if a 设备 isn't available. ([@perosb] - [#13314]) ([灯光.zha docs]) ([开关.zha docs]) * Plex unavailable client cleanup ([@ryanm101] - [#13156]) ([媒体播放器.plex docs]) * Perform check\_config 服务 in current process ([@kellerza] - [#13017]) * Added 开关 for DoorBird second relay ([@sjvc] - [#13339]) ([doorbird docs]) ([开关.doorbird docs]) * Add min and max price as 属性 for Tibber 传感器 ([@danielhiversen] - [#13313]) ([传感器.tibber docs]) * Bugfix: Zwave set\_config\_parameter failed when config list contained int ([@turbokongen] - [#13301]) ([zwave docs]) * 更新 pyhomematic to 0.1.40 ([@danielperna84] - [#13354]) ([homematic docs]) * Fix mysensors 灯光 打开 hs color ([@MartinHjelmare] - [#13349]) ([灯光.mysensors docs]) * Add a polling fallback for Sonos ([@amelchio] - [#13310]) ([媒体播放器.sonos docs]) * Fix retrieval of track URL into medi\_content\_id ([@ih8gates] - [#13333]) ([媒体播放器.spotify docs]) * Homekit Bugfix: Use get instead of indexing ([@maxclaey] - [#13353]) ([homekit docs]) * 配置 options for IFTTT 报警 control 面板 ([@maxclaey] - [#13352]) ([alarm\_control\_panel.ifttt docs][alarm_control_panel.ifttt docs]) * Add the possibility to filter on line(s) in Västtrafik Public Transport 传感器 ([@ThomasSvedberg] - [#13317]) ([传感器.vasttrafik docs]) * Fix mysensors RGBW ([@MartinHjelmare] - [#13364]) ([灯光.mysensors docs]) * Add watt to mysensors 开关 属性 ([@MartinHjelmare] - [#13370]) * Mediaroom async ([@dgomes] - [#13321]) ([媒体播放器.mediaroom docs]) * Add language parameter to darksky 传感器 ([@cgtobi] - [#13297]) ([传感器.darksky docs]) ([天气.darksky docs]) * Fixing Egardia 'home armed' 状态 not shown correctly. ([@jeroenterheerdt] - [#13335]) * Include all config flow translations with 后端 translations ([@balloob] - [#13394]) * Avoid breaking change for BMW ConnectedDrive 传感器 in #12591 ([@gerard33] - [#13380]) ([binary\_sensor.bmw\_connected\_drive docs][binary_sensor.bmw_connected_drive docs]) ([门锁.bmw\_connected\_drive docs][门锁.bmw_connected_drive docs]) ([传感器.bmw\_connected\_drive docs][传感器.bmw_connected_drive docs]) * Support setting icon when configuring MQTT 实体 ([@molobrakos] - [#13304]) ([传感器.MQTT docs]) ([开关.MQTT docs]) * Enhance mysensors 传感器 units and icons ([@MartinHjelmare] - [#13365]) ([传感器.mysensors docs]) * Fix incorrect unit of measurement for precip\_intensity. ([@cgtobi] - [#13415]) ([传感器.darksky docs]) (breaking change) * Fix Sonos playing Sveriges Radio ([@amelchio] - [#13401]) ([媒体播放器.sonos docs]) * Cache LaMetric 设备 for offline use ([@PhilRW] - [#13379]) * Enhance mysensors 二元sensor 设备 classes ([@MartinHjelmare] - [#13367]) ([binary\_sensor.mysensors docs][binary_sensor.mysensors docs]) * Switched to async/await. Bumped pyxeoma 版本 ([@jeradM] - [#13404]) ([摄像头.xeoma docs]) * Added default return value for HS\_Color ([@cdce8p] - [#13395]) ([homekit docs]) * Hue: Use the currently active color mode ([@armills] - [#13376]) ([灯光 docs]) ([灯光.hue docs]) * Cleanup homematicip\_cloud ([@mxworm] - [#13356]) ([homematicip\_cloud docs][homematicip_cloud docs]) ([传感器.homematicip\_cloud docs][传感器.homematicip_cloud docs]) * Add send sticker 服务 to telegram bot ([@syssi] - [#13387]) ([telegram\_bot docs][telegram_bot docs]) * Google assistant sync ([@balloob] - [#13392]) ([cloud docs]) * Fix current\_cover\_position ([@cdce8p] - [#13135]) ([遮盖.模板 docs]) * Switched values to downcase. ([@diminishedprime] - [#13406]) * Cast 集成 Cleanup ([@OttoWinter] - [#13275]) ([媒体播放器.cast docs]) * Security fix & 门锁 for HomeMatic ([@PH89] - [#11980]) ([homematic docs]) ([门锁 docs]) ([门锁.homematic docs]) (breaking change) (new-platform) * 日志 invalid 模板 in 脚本 delays ([@amelchio] - [#13423]) * LimitlessLED hs\_color fixes ([@amelchio] - [#13425]) ([灯光.limitlessled docs]) * Hyperion: fix typo ([@a-andre] - [#13429]) ([灯光.hyperion docs]) * HomeKit: Bugfix & improved logging ([@cdce8p] - [#13431]) ([homekit docs]) * Improve detection of 实体 names in 模板 ([@amelchio] - [#13432]) * Add 版本 bump 脚本 ([@balloob] - [#13447]) * Add extra check for ESSID field in case there's a wired connection ([@Zepheus] - [#13459]) ([device\_tracker docs][device_tracker docs]) * Fix encoding 错误 in mikrotik 设备 tracker ([@bdurrer] - [#13464]) ([device\_tracker docs][device_tracker docs]) * Hue: Convert XY to HS color if HS not present ([@balloob] - [#13465]) ([灯光.hue docs]) * Fix ID (fixes #13444) ([@fabaff] - [#13471]) ([媒体播放器.mpchc docs]) * 升级 aiohue and fix race 条件 ([@balloob] - [#13475]) ([hue docs]) * 版本 should contain just 'b' not 'beta' ([@balloob] - [#13476]) * Fix Google 日历 caching when offline ([@PhilRW] - [#13375]) ([日历.google docs]) * Homekit: Bugfix Thermostat Fahrenheit support ([@cdce8p] - [#13477]) ([homekit docs]) * Validate basic customize entries ([@cdce8p] - [#13478]) * Homekit: Fix security systems ([@cdce8p] - [#13499]) ([homekit docs]) * python-miio 版本 bumped (Closes: 13449) ([@syssi] - [#13511]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) ([遥控器.xiaomi\_miio docs][遥控器.xiaomi_miio docs]) ([传感器.xiaomi\_miio docs][传感器.xiaomi_miio docs]) ([开关.xiaomi\_miio docs][开关.xiaomi_miio docs]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) * Fix mysensors 灯光 supported features ([@MartinHjelmare] - [#13512]) ([灯光.mysensors docs]) * Fix Insteon Leak 传感器 ([@teharris1] - [#13515]) * HomeKit: Fix setting 灯光 brightness ([@cdce8p] - [#13518]) ([homekit docs]) * Construct 版本 pinned ([@syssi] - [#13528]) ([温控.eq3btsmart docs]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) ([遥控器.xiaomi\_miio docs][遥控器.xiaomi_miio docs]) ([传感器.eddystone\_temperature docs][传感器.eddystone_temperature docs]) ([传感器.xiaomi\_miio docs][传感器.xiaomi_miio docs]) ([开关.xiaomi\_miio docs][开关.xiaomi_miio docs]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) * Don't add Falsy items to list #13412 ([@kellerza] - [#13536]) * Check whitelisted paths #13107 ([@kellerza] - [#13154]) * Fix FLUX\_LED 错误 when no color is set ([@dramamoose] - [#13527]) ([灯光.flux\_led docs][灯光.flux_led docs]) [#11288]: https://github.com/home-assistant/home-assistant/pull/11288 [#11980]: https://github.com/home-assistant/home-assistant/pull/11980 [#12115]: https://github.com/home-assistant/home-assistant/pull/12115 [#12157]: https://github.com/home-assistant/home-assistant/pull/12157 [#12289]: https://github.com/home-assistant/home-assistant/pull/12289 [#12417]: https://github.com/home-assistant/home-assistant/pull/12417 [#12590]: https://github.com/home-assistant/home-assistant/pull/12590 [#12591]: https://github.com/home-assistant/home-assistant/pull/12591 [#12652]: https://github.com/home-assistant/home-assistant/pull/12652 [#12692]: https://github.com/home-assistant/home-assistant/pull/12692 [#12732]: https://github.com/home-assistant/home-assistant/pull/12732 [#12761]: https://github.com/home-assistant/home-assistant/pull/12761 [#12862]: https://github.com/home-assistant/home-assistant/pull/12862 [#12883]: https://github.com/home-assistant/home-assistant/pull/12883 [#12917]: https://github.com/home-assistant/home-assistant/pull/12917 [#12926]: https://github.com/home-assistant/home-assistant/pull/12926 [#12961]: https://github.com/home-assistant/home-assistant/pull/12961 [#12967]: https://github.com/home-assistant/home-assistant/pull/12967 [#12975]: https://github.com/home-assistant/home-assistant/pull/12975 [#12997]: https://github.com/home-assistant/home-assistant/pull/12997 [#13000]: https://github.com/home-assistant/home-assistant/pull/13000 [#13007]: https://github.com/home-assistant/home-assistant/pull/13007 [#13011]: https://github.com/home-assistant/home-assistant/pull/13011 [#13017]: https://github.com/home-assistant/home-assistant/pull/13017 [#13018]: https://github.com/home-assistant/home-assistant/pull/13018 [#13026]: https://github.com/home-assistant/home-assistant/pull/13026 [#13029]: https://github.com/home-assistant/home-assistant/pull/13029 [#13040]: https://github.com/home-assistant/home-assistant/pull/13040 [#13041]: https://github.com/home-assistant/home-assistant/pull/13041 [#13043]: https://github.com/home-assistant/home-assistant/pull/13043 [#13051]: https://github.com/home-assistant/home-assistant/pull/13051 [#13055]: https://github.com/home-assistant/home-assistant/pull/13055 [#13066]: https://github.com/home-assistant/home-assistant/pull/13066 [#13072]: https://github.com/home-assistant/home-assistant/pull/13072 [#13082]: https://github.com/home-assistant/home-assistant/pull/13082 [#13084]: https://github.com/home-assistant/home-assistant/pull/13084 [#13086]: https://github.com/home-assistant/home-assistant/pull/13086 [#13088]: https://github.com/home-assistant/home-assistant/pull/13088 [#13093]: https://github.com/home-assistant/home-assistant/pull/13093 [#13104]: https://github.com/home-assistant/home-assistant/pull/13104 [#13119]: https://github.com/home-assistant/home-assistant/pull/13119 [#13120]: https://github.com/home-assistant/home-assistant/pull/13120 [#13121]: https://github.com/home-assistant/home-assistant/pull/13121 [#13123]: https://github.com/home-assistant/home-assistant/pull/13123 [#13124]: https://github.com/home-assistant/home-assistant/pull/13124 [#13126]: https://github.com/home-assistant/home-assistant/pull/13126 [#13127]: https://github.com/home-assistant/home-assistant/pull/13127 [#13128]: https://github.com/home-assistant/home-assistant/pull/13128 [#13134]: https://github.com/home-assistant/home-assistant/pull/13134 [#13135]: https://github.com/home-assistant/home-assistant/pull/13135 [#13137]: https://github.com/home-assistant/home-assistant/pull/13137 [#13141]: https://github.com/home-assistant/home-assistant/pull/13141 [#13148]: https://github.com/home-assistant/home-assistant/pull/13148 [#13150]: https://github.com/home-assistant/home-assistant/pull/13150 [#13151]: https://github.com/home-assistant/home-assistant/pull/13151 [#13154]: https://github.com/home-assistant/home-assistant/pull/13154 [#13156]: https://github.com/home-assistant/home-assistant/pull/13156 [#13163]: https://github.com/home-assistant/home-assistant/pull/13163 [#13164]: https://github.com/home-assistant/home-assistant/pull/13164 [#13167]: https://github.com/home-assistant/home-assistant/pull/13167 [#13169]: https://github.com/home-assistant/home-assistant/pull/13169 [#13171]: https://github.com/home-assistant/home-assistant/pull/13171 [#13173]: https://github.com/home-assistant/home-assistant/pull/13173 [#13181]: https://github.com/home-assistant/home-assistant/pull/13181 [#13184]: https://github.com/home-assistant/home-assistant/pull/13184 [#13190]: https://github.com/home-assistant/home-assistant/pull/13190 [#13193]: https://github.com/home-assistant/home-assistant/pull/13193 [#13194]: https://github.com/home-assistant/home-assistant/pull/13194 [#13204]: https://github.com/home-assistant/home-assistant/pull/13204 [#13214]: https://github.com/home-assistant/home-assistant/pull/13214 [#13215]: https://github.com/home-assistant/home-assistant/pull/13215 [#13218]: https://github.com/home-assistant/home-assistant/pull/13218 [#13221]: https://github.com/home-assistant/home-assistant/pull/13221 [#13222]: https://github.com/home-assistant/home-assistant/pull/13222 [#13225]: https://github.com/home-assistant/home-assistant/pull/13225 [#13229]: https://github.com/home-assistant/home-assistant/pull/13229 [#13230]: https://github.com/home-assistant/home-assistant/pull/13230 [#13231]: https://github.com/home-assistant/home-assistant/pull/13231 [#13232]: https://github.com/home-assistant/home-assistant/pull/13232 [#13236]: https://github.com/home-assistant/home-assistant/pull/13236 [#13240]: https://github.com/home-assistant/home-assistant/pull/13240 [#13244]: https://github.com/home-assistant/home-assistant/pull/13244 [#13246]: https://github.com/home-assistant/home-assistant/pull/13246 [#13253]: https://github.com/home-assistant/home-assistant/pull/13253 [#13264]: https://github.com/home-assistant/home-assistant/pull/13264 [#13266]: https://github.com/home-assistant/home-assistant/pull/13266 [#13272]: https://github.com/home-assistant/home-assistant/pull/13272 [#13275]: https://github.com/home-assistant/home-assistant/pull/13275 [#13281]: https://github.com/home-assistant/home-assistant/pull/13281 [#13282]: https://github.com/home-assistant/home-assistant/pull/13282 [#13283]: https://github.com/home-assistant/home-assistant/pull/13283 [#13285]: https://github.com/home-assistant/home-assistant/pull/13285 [#13287]: https://github.com/home-assistant/home-assistant/pull/13287 [#13288]: https://github.com/home-assistant/home-assistant/pull/13288 [#13289]: https://github.com/home-assistant/home-assistant/pull/13289 [#13290]: https://github.com/home-assistant/home-assistant/pull/13290 [#13291]: https://github.com/home-assistant/home-assistant/pull/13291 [#13292]: https://github.com/home-assistant/home-assistant/pull/13292 [#13294]: https://github.com/home-assistant/home-assistant/pull/13294 [#13295]: https://github.com/home-assistant/home-assistant/pull/13295 [#13297]: https://github.com/home-assistant/home-assistant/pull/13297 [#13301]: https://github.com/home-assistant/home-assistant/pull/13301 [#13303]: https://github.com/home-assistant/home-assistant/pull/13303 [#13304]: https://github.com/home-assistant/home-assistant/pull/13304 [#13308]: https://github.com/home-assistant/home-assistant/pull/13308 [#13310]: https://github.com/home-assistant/home-assistant/pull/13310 [#13313]: https://github.com/home-assistant/home-assistant/pull/13313 [#13314]: https://github.com/home-assistant/home-assistant/pull/13314 [#13317]: https://github.com/home-assistant/home-assistant/pull/13317 [#13321]: https://github.com/home-assistant/home-assistant/pull/13321 [#13326]: https://github.com/home-assistant/home-assistant/pull/13326 [#13333]: https://github.com/home-assistant/home-assistant/pull/13333 [#13335]: https://github.com/home-assistant/home-assistant/pull/13335 [#13339]: https://github.com/home-assistant/home-assistant/pull/13339 [#13349]: https://github.com/home-assistant/home-assistant/pull/13349 [#13352]: https://github.com/home-assistant/home-assistant/pull/13352 [#13353]: https://github.com/home-assistant/home-assistant/pull/13353 [#13354]: https://github.com/home-assistant/home-assistant/pull/13354 [#13356]: https://github.com/home-assistant/home-assistant/pull/13356 [#13364]: https://github.com/home-assistant/home-assistant/pull/13364 [#13365]: https://github.com/home-assistant/home-assistant/pull/13365 [#13367]: https://github.com/home-assistant/home-assistant/pull/13367 [#13370]: https://github.com/home-assistant/home-assistant/pull/13370 [#13375]: https://github.com/home-assistant/home-assistant/pull/13375 [#13376]: https://github.com/home-assistant/home-assistant/pull/13376 [#13379]: https://github.com/home-assistant/home-assistant/pull/13379 [#13380]: https://github.com/home-assistant/home-assistant/pull/13380 [#13387]: https://github.com/home-assistant/home-assistant/pull/13387 [#13392]: https://github.com/home-assistant/home-assistant/pull/13392 [#13394]: https://github.com/home-assistant/home-assistant/pull/13394 [#13395]: https://github.com/home-assistant/home-assistant/pull/13395 [#13401]: https://github.com/home-assistant/home-assistant/pull/13401 [#13404]: https://github.com/home-assistant/home-assistant/pull/13404 [#13406]: https://github.com/home-assistant/home-assistant/pull/13406 [#13415]: https://github.com/home-assistant/home-assistant/pull/13415 [#13423]: https://github.com/home-assistant/home-assistant/pull/13423 [#13425]: https://github.com/home-assistant/home-assistant/pull/13425 [#13429]: https://github.com/home-assistant/home-assistant/pull/13429 [#13431]: https://github.com/home-assistant/home-assistant/pull/13431 [#13432]: https://github.com/home-assistant/home-assistant/pull/13432 [#13447]: https://github.com/home-assistant/home-assistant/pull/13447 [#13459]: https://github.com/home-assistant/home-assistant/pull/13459 [#13464]: https://github.com/home-assistant/home-assistant/pull/13464 [#13465]: https://github.com/home-assistant/home-assistant/pull/13465 [#13471]: https://github.com/home-assistant/home-assistant/pull/13471 [#13475]: https://github.com/home-assistant/home-assistant/pull/13475 [#13476]: https://github.com/home-assistant/home-assistant/pull/13476 [#13477]: https://github.com/home-assistant/home-assistant/pull/13477 [#13478]: https://github.com/home-assistant/home-assistant/pull/13478 [#13499]: https://github.com/home-assistant/home-assistant/pull/13499 [#13511]: https://github.com/home-assistant/home-assistant/pull/13511 [#13512]: https://github.com/home-assistant/home-assistant/pull/13512 [#13515]: https://github.com/home-assistant/home-assistant/pull/13515 [#13518]: https://github.com/home-assistant/home-assistant/pull/13518 [#13527]: https://github.com/home-assistant/home-assistant/pull/13527 [#13528]: https://github.com/home-assistant/home-assistant/pull/13528 [#13536]: https://github.com/home-assistant/home-assistant/pull/13536 [@BioSehnsucht]: https://github.com/BioSehnsucht [@DanNixon]: https://github.com/DanNixon [@FezVrasta]: https://github.com/FezVrasta [@JensTimmerman]: https://github.com/JensTimmerman [@Juggels]: https://github.com/Juggels [@Kane610]: https://github.com/Kane610 [@MartinHjelmare]: https://github.com/MartinHjelmare [@OttoWinter]: https://github.com/OttoWinter [@PH89]: https://github.com/PH89 [@PhilRW]: https://github.com/PhilRW [@Qxlkdr]: https://github.com/Qxlkdr [@ThomasSvedberg]: https://github.com/ThomasSvedberg [@Zepheus]: https://github.com/Zepheus [@a-andre]: https://github.com/a-andre [@a-wolter]: https://github.com/a-wolter [@amelchio]: https://github.com/amelchio [@andreipop2005]: https://github.com/andreipop2005 [@andrey-git]: https://github.com/andrey-git [@armills]: https://github.com/armills [@balloob]: https://github.com/balloob [@bdurrer]: https://github.com/bdurrer [@c727]: https://github.com/c727 [@cburgess]: https://github.com/cburgess [@cdce8p]: https://github.com/cdce8p [@cgtobi]: https://github.com/cgtobi [@kraddatz]: https://github.com/kraddatz [@clementhk]: https://github.com/clementhk [@danielhiversen]: https://github.com/danielhiversen [@danielperna84]: https://github.com/danielperna84 [@dgomes]: https://github.com/dgomes [@diminishedprime]: https://github.com/diminishedprime [@dramamoose]: https://github.com/dramamoose [@engrbm87]: https://github.com/engrbm87 [@fabaff]: https://github.com/fabaff [@gerard33]: https://github.com/gerard33 [@hthiery]: https://github.com/hthiery [@igorbernstein2]: https://github.com/igorbernstein2 [@ih8gates]: https://github.com/ih8gates [@jcconnell]: https://github.com/jcconnell [@jeradM]: https://github.com/jeradM [@jeroenterheerdt]: https://github.com/jeroenterheerdt [@jesserockz]: https://github.com/jesserockz [@karlkar]: https://github.com/karlkar [@kellerza]: https://github.com/kellerza [@kuzin2006]: https://github.com/kuzin2006 [@maddox]: https://github.com/maddox [@markperdue]: https://github.com/markperdue [@maxclaey]: https://github.com/maxclaey [@maxlaverse]: https://github.com/maxlaverse [@molobrakos]: https://github.com/molobrakos [@mxworm]: https://github.com/mxworm [@nielstron]: https://github.com/nielstron [@perosb]: https://github.com/perosb [@pvizeli]: https://github.com/pvizeli [@reefab]: https://github.com/reefab [@ryanm101]: https://github.com/ryanm101 [@rytilahti]: https://github.com/rytilahti [@scop]: https://github.com/scop [@sjvc]: https://github.com/sjvc [@smurfix]: https://github.com/smurfix [@syssi]: https://github.com/syssi [@teharris1]: https://github.com/teharris1 [@the-glu]: https://github.com/the-glu [@thrawnarn]: https://github.com/thrawnarn [@timmo001]: https://github.com/timmo001 [@turbokongen]: https://github.com/turbokongen [@uchagani]: https://github.com/uchagani [@vandenberghev]: https://github.com/vandenberghev [alarm_control_panel.ifttt docs]: /integrations/alarm_control_panel.ifttt/ [binary_sensor.bmw_connected_drive docs]: /integrations/bmw_connected_drive [binary_sensor.deconz docs]: /integrations/deconz#binary-传感器 [binary_sensor.mysensors docs]: /integrations/binary_sensor.mysensors/ [binary_sensor.trend docs]: /integrations/trend [binary_sensor.workday docs]: /integrations/workday [bmw_connected_drive docs]: /integrations/bmw_connected_drive/ [日历.caldav docs]: /integrations/caldav [日历.google docs]: /integrations/日历.google/ [日历.todoist docs]: /integrations/todoist [摄像头.onvif docs]: /integrations/onvif [摄像头.xeoma docs]: /integrations/xeoma [温控.ecobee docs]: /integrations/ecobee [温控.eq3btsmart docs]: /integrations/eq3btsmart [温控.sensibo docs]: /integrations/sensibo [cloud docs]: /integrations/cloud/ [遮盖.group docs]: /integrations/遮盖.group/ [遮盖.模板 docs]: /integrations/遮盖.模板/ [deconz docs]: /integrations/deconz/ [device_tracker docs]: /integrations/device_tracker/ [doorbird docs]: /integrations/doorbird/ [downloader docs]: /integrations/downloader/ [ecobee docs]: /integrations/ecobee/ [风扇.xiaomi_miio docs]: /integrations/风扇.xiaomi_miio/ [风扇.zha docs]: /integrations/zha [hassio docs]: /integrations/hassio/ [history docs]: /integrations/history/ [homekit docs]: /integrations/homekit/ [homematic docs]: /integrations/homematic/ [homematicip_cloud docs]: /integrations/homematicip_cloud/ [http docs]: /integrations/http/ [hue docs]: /integrations/hue/ [image_processing.opencv docs]: /integrations/opencv [灯光 docs]: /integrations/灯光/ [灯光.deconz docs]: /integrations/deconz#灯光 [灯光.flux_led docs]: /integrations/flux_led [灯光.hue docs]: /integrations/hue [灯光.hyperion docs]: /integrations/hyperion [灯光.iglo docs]: /integrations/iglo [灯光.limitlessled docs]: /integrations/limitlessled [灯光.mysensors docs]: /integrations/灯光.mysensors/ [灯光.mystrom docs]: /integrations/mystrom#灯光 [灯光.xiaomi_miio docs]: /integrations/灯光.xiaomi_miio/ [灯光.zha docs]: /integrations/zha [门锁 docs]: /integrations/门锁/ [门锁.bmw_connected_drive docs]: /integrations/bmw_connected_drive [门锁.homematic docs]: /integrations/homematic [门锁.MQTT docs]: /integrations/门锁.MQTT/ [logbook docs]: /integrations/logbook/ [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.bluesound docs]: /integrations/bluesound [媒体播放器.cast docs]: /integrations/cast [媒体播放器.channels docs]: /integrations/channels [媒体播放器.kodi docs]: /integrations/kodi [@NovapaX]: https://github.com/NovapaX [媒体播放器.mediaroom docs]: /integrations/mediaroom [媒体播放器.mpchc docs]: /integrations/mpchc [媒体播放器.philips_js docs]: /integrations/philips_js [媒体播放器.plex docs]: /integrations/plex#media-player [媒体播放器.songpal docs]: /integrations/songpal [媒体播放器.sonos docs]: /integrations/sonos [媒体播放器.spotify docs]: /integrations/spotify [MQTT docs]: /integrations/MQTT/ [mysensors docs]: /integrations/mysensors/ [nest docs]: /integrations/nest/ [通知 docs]: /integrations/通知/ [遥控器.xiaomi_miio docs]: /integrations/遥控器.xiaomi_miio/ [场景.deconz docs]: /integrations/deconz#场景 [传感器.bmw_connected_drive docs]: /integrations/bmw_connected_drive [传感器.crimereports docs]: /integrations/crimereports [传感器.darksky docs]: /integrations/darksky [传感器.deconz docs]: /integrations/deconz#传感器 [传感器.deutsche_bahn docs]: /integrations/deutsche_bahn [传感器.eddystone_temperature docs]: /integrations/eddystone_temperature [传感器.filter docs]: /integrations/filter [传感器.foobot docs]: /integrations/foobot [传感器.glances docs]: /integrations/glances [传感器.homematic docs]: /integrations/homematic [传感器.homematicip_cloud docs]: /integrations/homematicip_cloud/ [传感器.lacrosse docs]: /integrations/lacrosse [传感器.MQTT docs]: /integrations/传感器.MQTT/ [传感器.mysensors docs]: /integrations/传感器.mysensors/ [传感器.plex docs]: /integrations/plex#传感器 [传感器.smappee docs]: /integrations/sma#sensorsppee/ [传感器.spotcrime docs]: /integrations/spotcrime [传感器.sql docs]: /integrations/sql [传感器.syncthru docs]: /integrations/syncthru [传感器.systemmonitor docs]: /integrations/systemmonitor [传感器.模板 docs]: /integrations/模板 [传感器.tibber docs]: /integrations/tibber#传感器 [传感器.trafikverket_weatherstation docs]: /integrations/trafikverket_weatherstation [传感器.vasttrafik docs]: /integrations/vasttrafik [传感器.wunderground docs]: /integrations/wunderground [传感器.xiaomi_miio docs]: /integrations/传感器.xiaomi_miio/ [spc docs]: /integrations/spc/ [开关.doorbird docs]: /integrations/doorbird#开关 [开关.edimax docs]: /integrations/edimax [开关.MQTT docs]: /integrations/开关.MQTT/ [开关.vesync docs]: /integrations/vesync#开关 [开关.xiaomi_miio docs]: /integrations/开关.xiaomi_miio/ [开关.zha docs]: /integrations/zha [telegram_bot docs]: /integrations/telegram_bot/ [upcloud docs]: /integrations/upcloud/ [吸尘器.xiaomi_miio docs]: /integrations/吸尘器.xiaomi_miio/ [天气.darksky docs]: /integrations/天气.darksky/ [websocket_api docs]: /integrations/websocket_api/ [zeroconf docs]: /integrations/zeroconf/ [zha docs]: /integrations/zha/ [zwave docs]: /integrations/zwave/ [#13574]: https://github.com/home-assistant/home-assistant/pull/13574 [#13587]: https://github.com/home-assistant/home-assistant/pull/13587 [#13617]: https://github.com/home-assistant/home-assistant/pull/13617 [@MartinHjelmare]: https://github.com/MartinHjelmare [@armills]: https://github.com/armills [@cdce8p]: https://github.com/cdce8p [homekit docs]: /integrations/homekit/ [灯光.mqtt_json docs]: /integrations/灯光.MQTT [传感器.mysensors docs]: /integrations/传感器.mysensors/ --- url: /home-assistant/blog/2018-04-12-ubiquiti-and-home-assistant.md --- # Home Assistant 🤝 Ubiquiti Networks TL;DR:Ubiquiti Networks 已聘用 Home Assistant 创始人 Paulus Schoutsen,支持 Home Assistant 继续实现这些目标:让用户配置更简单、与设备厂商集成更深入,并让集成的创建、维护与演进更轻松。 Home Assistant 是一个开源项目,到目前为止主要靠大家在业余时间推动。过去四年半里,它从我一个人维护、只有少量集成的小框架,成长为拥有自己的操作系统、超过 1000 个集成、优秀性能、900 多位贡献者,并且主 Docker 镜像下载量超过一千万次的项目! Ubiquiti Networks 看到这样的增长和充满热情的社区后,主动联系了我们。 Ubiquiti Networks 目前专注于三大技术方向:高容量分布式网络接入、统一信息技术平台,以及面向家庭与个人场景的新一代消费电子。企业级品质加上亲民价格,让他们在我们的用户中非常受欢迎。他们也和我们一样重视“尽量避免云依赖”。例如他们的 [UniFi Video] IP 监控方案,就是完全本地托管。 他们看到了 Home Assistant 成为家庭自动化事实标准平台的潜力:快速、开源、本地。他们也希望进一步深化 Ubiquiti 产品与 Home Assistant 的集成,甚至未来支持在其硬件上运行 Home Assistant 实例。 因此,我们达成一致:我(Paulus,Home Assistant 创始人)将以全职员工身份加入 Ubiquiti Networks,专注推动 Home Assistant 发展。这样我就能把全部精力投入到让用户配置更简单、加强与设备厂商的集成,以及让集成更易创建、维护和演进。 Ubiquiti Networks 不会获得 Home Assistant 的所有权。我们仍将保持独立与开源,只是在 Ubiquiti Networks 的支持下,以前所未有的速度持续改进。 我对这个机会非常激动,2018 会是 Home Assistant 特别精彩的一年!

Photo of Paulus, the founder of Home Assistant, standing in front of a Ubiquiti Networks logo wearing a Home Assistant t-shirt. Home Assistant 创始人 Paulus Schoutsen,拍摄于 Ubiquiti 纽约办公室。

[UniFi Video]: https://www.ubnt.com/unifi-video/unifi-video-摄像头-g3/#unifi-video-摄像头-hybrid-technology --- url: /home-assistant/blog/2018-04-14-release-67.md --- # 0.67:Mastodon、Tahoma 开关与 Nanoleaf Aurora 灯光面板 0.67 版本来了!如果你错过了[昨天的公告][ann-ubiquiti]:Ubiquiti 现在正在赞助我撰写这些发布说明。没错,就是这么棒。这样我就有更多时间专注于我们推迟已久的一些重大改进,首先会是用户系统。 这个版本包含一项安全修复。在此前版本中,错误日志可通过 API 访问且不要求认证。虽然这本身不一定直接导致泄露,但如果某个组件错误地将敏感信息写入错误日志,就可能造成暴露(目前我们并不知道有组件会这样做)。感谢 [Matt Hamilton](https://github.com/Eriner) 向我们披露这个问题。 ## 新平台 * 新增 `folder_watcher` 组件 ([@robmarkcole] - [#12918]) ([folder\_watcher docs][folder_watcher docs]) (new-platform) * 新增 FreeDNS 组件 ([@bdurrer] - [#13526]) ([freedns docs]) (new-platform) * 新增 Google Maps 位置共享设备追踪器 ([@michaelarnauts] - [#12301]) ([device\_tracker.google\_maps docs][device_tracker.google_maps docs]) (new-platform) * 新增 Waze 路程时间传感器 ([@Myrddyn1] - [#12387]) ([传感器.waze\_travel\_time docs][传感器.waze_travel_time docs]) (new-platform) * 为 Amcrest IP 摄像头新增开关组件 ([@adpriebe] - [#12992]) ([amcrest docs]) ([开关.amcrest docs]) (new-platform) * 新增 Mastodon 支持 ([@fabaff] - [#13441]) ([通知 docs]) (new-platform) * Tahoma 开关 ([@ikucuze] - [#13636]) ([tahoma docs]) ([开关.tahoma docs]) (new-platform) * Add support for Nanoleaf Aurora 灯光 面板 ([@Oro] - [#13456]) ([灯光.nanoleaf\_aurora docs][灯光.nanoleaf_aurora docs]) (new-platform) ## 发布 0.67.1 - April 17 * Fix Gogogate2 'available' 属性 ([@dlbroadfoot] - [#13728]) * Fix so it is possible to ignore discovered config entry handlers ([@Kane610] - [#13741]) * Prevent vesync doing I/O in event loop ([@balloob] - [#13862]) ([开关.vesync docs]) * Fix #13846 Double underscore in 蓝牙 address ([@aav7fl] - [#13884]) ([device\_tracker docs][device_tracker docs]) * Fix race 条件 for component loaded before listening ([@balloob] - [#13887]) ([config docs]) * Missing property decorator added ([@syssi] - [#13889]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) * Fix call to parent broadlink 开关 ([@Danielhiversen] - [#13906]) ([开关.broadlink docs]) * Import operation modes from air 加湿器 ([@syssi] - [#13908]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) * 升级 pyqwikswitch to 0.71 ([@kellerza] - [#13920]) ([qwikswitch docs]) * 升级 somecomfort to 0.5.2 ([@balloob] - [#13940]) ([温控.honeywell docs]) * 更新 pyhydroquebec to 2.2.2 ([@titilambert] - [#13946]) * 更新 pyfido to 2.1.1 ([@titilambert] - [#13947]) ([传感器.fido docs]) * Bumped pypollencom to 1.1.2 ([@bachya] - [#13959]) ([传感器.pollen docs]) * Revert "升级 pyqwikswitch to 0.71 ([@balloob] - [#13920]) ([qwikswitch docs]) ## 如果你需要帮助…… ……欢迎随时使用我们非常活跃的[论坛](https://community.home-assistant.io/),或加入我们的 [chat](https://discord.gg/c5DvZ4e) 交流。发布说明虽然开放评论,但我们更推荐你使用前面的沟通渠道。谢谢。 ## 报告问题 如果你遇到了由此版本引入的问题,请在我们的 [issue tracker](https://github.com/home-assistant/home-assistant/issues) 中反馈,并确保完整填写 issue 模板中的所有字段。 ## 不向后兼容的变更 * 更新默认 Pilight 端口号 ([@frenck] - [#13419]) ([pilight docs]) (breaking change) * 更新到 BMW ConnectedDrive 的新 `b2vapi` ([@ChristianKuehnel] - [#13305]) ([bmw\_connected\_drive docs][bmw_connected_drive docs]) ([binary\_sensor.bmw\_connected\_drive docs][binary_sensor.bmw_connected_drive docs]) ([门锁.bmw\_connected\_drive docs][门锁.bmw_connected_drive docs]) ([传感器.bmw\_connected\_drive docs][传感器.bmw_connected_drive docs]) (breaking change) * 移除 MercedesME 组件。([@ReneNulschDE] - [#13538]) ([device\_tracker docs][device_tracker docs]) (mercedesme docs) (binary\_sensor.mercedesme docs) (传感器.mercedesme docs) (breaking change) * 为 webostv 增加频道上下切换。([@stephanerosi] - [#13624]) ([媒体播放器.webostv docs]) (breaking change) * 为 video/movie 增加媒体类型区分。([@tadly] - [#13612]) (breaking change) * Added ENTITY\_ID\_FORMAT import and set entity\_id in **init** ([@timmo001] - [#13642]) ([开关.broadlink docs]) (breaking change) ## 所有变更 * Updates default Pilight port number ([@frenck] - [#13419]) ([pilight docs]) (breaking change) * 升级 mypy to 0.580 ([@fabaff] - [#13420]) * 更新 to new "b2vapi" of BMW ConnectedDrive ([@ChristianKuehnel] - [#13305]) ([bmw\_connected\_drive docs][bmw_connected_drive docs]) ([binary\_sensor.bmw\_connected\_drive docs][binary_sensor.bmw_connected_drive docs]) ([门锁.bmw\_connected\_drive docs][门锁.bmw_connected_drive docs]) ([传感器.bmw\_connected\_drive docs][传感器.bmw_connected_drive docs]) (breaking change) * Add code owner for Manual 报警 with MQTT Control ([@colinodell] - [#13438]) * QNAP updates ([@colinodell] - [#13435]) ([传感器.qnap docs]) * Xiaomi MiIO 风扇: Xiaomi Air 加湿器 集成 ([@syssi] - [#12627]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) * Bump songpal 版本, fixes lots of issues mentioned in #13022 ([@rytilahti] - [#13440]) ([媒体播放器.songpal docs]) * Removed the google home 警告 from emulated\_hue ([@mf-social] - [#13436]) * Fixing odometer to display km ([@alandtse] - [#13427]) ([传感器.tesla docs]) * 升级 keyring to 12.0.0 and keyrings.alt to 3.0 ([@fabaff] - [#13452]) * 升级 aiohttp to 3.1.0 ([@fabaff] - [#13451]) * Qwikswitch async & updates ([@kellerza] - [#12641]) ([qwikswitch docs]) ([灯光.qwikswitch docs]) ([开关.qwikswitch docs]) * Make Telnet 开关 value 模板 optional ([@DanNixon] - [#13433]) ([开关.telnet docs]) * 更新 yeelightsunflower to 0.0.10 ([@lindsaymarkward] - [#13448]) * Add more info to issue 模板 ([@c727] - [#12955]) * \[RFC] 更新 issue 模板 ([@amelchio] - [#12989]) * 更新 total\_connect\_client to 0.17 for Honeywell L5100-WiFi Support ([@phileaton] - [#13473]) ([alarm\_control\_panel.totalconnect docs][alarm_control_panel.totalconnect docs]) * 升级 python-mystrom to 0.4.2 ([@fabaff] - [#13485]) ([灯光.mystrom docs]) ([开关.mystrom docs]) * New 服务 added to control the power mode of the yeelight ([@syssi] - [#13267]) ([灯光.yeelight docs]) * 升级 slacker to 0.9.65 ([@fabaff] - [#13496]) ([通知 docs]) * Adds 模板 function state\_attr to get 属性 from a 状态 ([@Nossnevs] - [#13378]) * 升级 aiohttp to 3.1.1 ([@fabaff] - [#13510]) * 更新 tradfri v5 ([@lwis] - [#11187]) ([tradfri docs]) ([灯光.tradfri docs]) ([传感器.tradfri docs]) * Fix typos and 更新 link (fixes #13520) ([@fabaff] - [#13529]) * Tradfri - unique\_id's and color\_temp support for rgb-bulbs ([@NovapaX] - [#13531]) ([灯光.tradfri docs]) * Qwikswitch async refactor & 传感器 ([@kellerza] - [#13509]) ([qwikswitch docs]) ([灯光.qwikswitch docs]) ([传感器.qwikswitch docs]) ([开关.qwikswitch docs]) (new-platform) * Adds folder\_watcher component ([@robmarkcole] - [#12918]) ([folder\_watcher docs][folder_watcher docs]) (new-platform) * 更新 rflink to 0.0.37 ([@olskar] - [#12603]) ([rflink docs]) * Added file path validity checks to file 传感器 ([@FrederikBolding] - [#12505]) ([传感器.file docs]) * Allow for overriding the DoorBird push 通知 URL in 配置 ([@Klikini] - [#13268]) ([doorbird docs]) * Convert Hue to always use config entries ([@balloob] - [#13034]) ([hue docs]) * Implement thermostat support for Alexa ([@trisk] - [#13340]) ([alexa docs]) * deCONZ config entry ([@Kane610] - [#13402]) ([deconz docs]) * Remove andrey-git from requirements monitoring ([@andrey-git] - [#13547]) * Fix BMW 设备 tracker toggling 状态 if vehicle tracking is disabled ([@ChristianKuehnel] - [#12999]) ([device\_tracker.bmw\_connected\_drive docs][device_tracker.bmw_connected_drive docs]) * Xiaomi MiIO 开关: Support for the Xiaomi Chuangmi Plug V3 ([@syssi] - [#13271]) ([开关.xiaomi\_miio docs][开关.xiaomi_miio docs]) * Add FreeDNS component ([@bdurrer] - [#13526]) ([freedns docs]) (new-platform) * 更新 pylint to 1.8.3 ([@scop] - [#13544]) * Google Maps location sharing 设备 tracker ([@michaelarnauts] - [#12301]) ([device\_tracker.google\_maps docs][device_tracker.google_maps docs]) (new-platform) * Check\_config: Handle numbers correctly when printing config ([@hAmpzter] - [#13377]) * Add support for Canary Flex ([@snjoetw] - [#13280]) ([canary docs]) ([传感器.canary docs]) * Fixes #12758. Try other 摄像头 even if one fails to initialize ([@PhracturedBlue] - [#13276]) ([amcrest docs]) * Added HassOpenCover and HassCloseCover intents ([@tschmidty69] - [#13372]) ([conversation docs]) ([遮盖 docs]) * rfxtrx lib 0.22.0 ([@Danielhiversen] - [#13576]) ([rfxtrx docs]) * xiaomi lib 升级 ([@Danielhiversen] - [#13577]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * Remove MercedesME component ([@ReneNulschDE] - [#13538]) ([device\_tracker docs][device_tracker docs]) (mercedesme docs) (binary\_sensor.mercedesme docs) (传感器.mercedesme docs) (breaking change) * Added Waze travel time 传感器 ([@Myrddyn1] - [#12387]) ([传感器.waze\_travel\_time docs][传感器.waze_travel_time docs]) (new-platform) * Added 开关 component to Amcrest IP 摄像头. ([@adpriebe] - [#12992]) ([amcrest docs]) ([开关.amcrest docs]) (new-platform) * 升级 pyhydroquebec 2.2.1 ([@titilambert] - [#13586]) * Add mastodon ([@fabaff] - [#13441]) ([通知 docs]) (new-platform) * Added support for requesting RSSI values from 蓝牙 设备 ([@FrederikBolding] - [#12458]) ([device\_tracker.bluetooth\_tracker docs][device_tracker.bluetooth_tracker docs]) * Fix mysensors 更新 callback ([@MartinHjelmare] - [#13602]) ([mysensors docs]) * Broadlink ([@Danielhiversen] - [#13585]) ([传感器.broadlink docs]) ([开关.broadlink docs]) * Fix IMAP email message\_data ([@zhaokoh] - [#13606]) ([传感器.imap\_email\_content docs][传感器.imap_email_content docs]) * Re-add group polling as a fallback for observation ([@lwis] - [#13613]) ([灯光.tradfri docs]) * Unflake folder watcher test ([@balloob] - [#13569]) * Make mysensors updates and platform 设置 async ([@MartinHjelmare] - [#13603]) * Use 0/1 for 树莓派 遮盖 GPIO writes rather than true/false ([@fezfox] - [#13610]) ([遮盖.rpi\_gpio docs][遮盖.rpi_gpio docs]) * Fix Hue 错误 logging ([@balloob] - [#13616]) ([hue docs]) * Bugfix for tradfri to correctly execute Command. ([@lwis] - [#13618]) ([灯光.tradfri docs]) * Hue mireds value is actually 153 not 154 ([@Skaronator] - [#13601]) ([灯光 docs]) * changed PyTado 版本 ([@wmalgadey] - [#13626]) ([tado docs]) * 升级 py-cpuinfo to 4.0.0 ([@fabaff] - [#13629]) ([传感器.cpuspeed docs]) * Add Switzerland ([@fabaff] - [#13630]) ([binary\_sensor.workday docs][binary_sensor.workday docs]) * Xiaomi Mi WiFi Repeater 2 集成 as 设备 tracker ([@syssi] - [#13521]) * 升级 youtube\_dl to 2018.04.03 ([@fabaff] - [#13647]) ([media\_extractor docs][media_extractor docs]) * 更新 plex.py ([@kraddatz] - [#13659]) ([传感器.plex docs]) * Always enable config entries & remove config\_entry\_example ([@balloob] - [#13663]) ([config docs]) * Add missing 服务 docs for hs\_color ([@armills] - [#13667]) * Add regex functions as templating 助手 ([@mountainsandcode] - [#13631]) * Channel up and down for webostv ([@stephanerosi] - [#13624]) ([媒体播放器.webostv docs]) (breaking change) * Added headers 配置 variable to 通知.rest component ([@5LICK] - [#13674]) ([通知 docs]) * Spelling fixes ([@scop] - [#13681]) ([device\_tracker docs][device_tracker docs]) ([smappee docs]) ([alarm\_control\_panel.ifttt docs][alarm_control_panel.ifttt docs]) ([温控.nest docs]) ([遥控器.xiaomi\_miio docs][遥控器.xiaomi_miio docs]) * Xiaomi MiIO 灯光: White Philips Candle 灯光 support ([@syssi] - [#13682]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) * Bugfixes HomeKit 遮盖, 灯光 ([@cdce8p] - [#13689]) ([homekit docs]) * Minor style changes, cleanup ([@cdce8p] - [#13654]) ([homekit docs]) * Bugfix: Zwave Print\_node to logfile instead of console ([@turbokongen] - [#13302]) ([zwave docs]) * 更新 HAP-python to 1.1.8 ([@cdce8p] - [#13563]) ([homekit docs]) * 更新 ha-philips\_js to 0.0.3 ([@danielperna84] - [#13702]) ([媒体播放器.philips\_js docs][媒体播放器.philips_js docs]) * Coverage & Codeowners ([@kellerza] - [#13700]) * Bump insteonplm to 0.8.6 to fix 传感器 message handling ([@teharris1] - [#13691]) ([insteon\_plm docs][insteon_plm docs]) * Fix asuswrt ap mode failure ([@shuaiger] - [#13693]) ([device\_tracker docs][device_tracker docs]) * Support color temperature in Homekit ([@morberg] - [#13658]) ([homekit docs]) * Remove unused CONF\_WATCHERS ([@robmarkcole] - [#13678]) ([folder\_watcher docs][folder_watcher docs]) * Add media type separation for video/movie ([@tadly] - [#13612]) (breaking change) * Adding 配置 to disable IP address as a requirement Fixes: #13399 ([@PlanetJ] - [#13692]) ([device\_tracker docs][device_tracker docs]) * Tahoma 开关 ([@ikucuze] - [#13636]) ([tahoma docs]) ([开关.tahoma docs]) (new-platform) * Send XY color for non-osram hue bulbs ([@armills] - [#13665]) ([灯光.hue docs]) * 更新 AbodePy 版本 to 0.12.3 ([@MisterWil] - [#13709]) ([abode docs]) * Enable autodiscovery for MQTT 摄像头 ([@jmtatsch] - [#13697]) ([MQTT docs]) ([摄像头.MQTT docs]) * Added ENTITY\_ID\_FORMAT import and set entity\_id in **init** ([@timmo001] - [#13642]) ([开关.broadlink docs]) (breaking change) * Fix #10175 ([@pschmitt] - [#13713]) * Add support for Nanoleaf Aurora 灯光 面板 ([@Oro] - [#13456]) ([灯光.nanoleaf\_aurora docs][灯光.nanoleaf_aurora docs]) (new-platform) * Added gogogate2 遮盖 ([@dlbroadfoot] - [#13467]) * Remove vendor lookup for mac addresses ([@balloob] - [#13788]) ([device\_tracker docs][device_tracker docs]) * iglo hs color fix ([@armills] - [#13808]) ([灯光.iglo docs]) * Fix too green color conversion ([@amelchio] - [#13828]) * Rename from aurora 灯光 to nanoleaf\_aurora ([@Oro] - [#13831]) ([灯光.nanoleaf\_aurora docs][灯光.nanoleaf_aurora docs]) * Channel up/down for LiveTV and next/previous for other apps ([@stephanerosi] - [#13829]) ([媒体播放器.webostv docs]) * Add 认证 to 错误 日志 endpoint ([@balloob] - [#13836]) ([api docs]) [#11187]: https://github.com/home-assistant/home-assistant/pull/11187 [#12301]: https://github.com/home-assistant/home-assistant/pull/12301 [#12387]: https://github.com/home-assistant/home-assistant/pull/12387 [#12458]: https://github.com/home-assistant/home-assistant/pull/12458 [#12505]: https://github.com/home-assistant/home-assistant/pull/12505 [#12603]: https://github.com/home-assistant/home-assistant/pull/12603 [#12627]: https://github.com/home-assistant/home-assistant/pull/12627 [#12641]: https://github.com/home-assistant/home-assistant/pull/12641 [#12918]: https://github.com/home-assistant/home-assistant/pull/12918 [#12955]: https://github.com/home-assistant/home-assistant/pull/12955 [#12989]: https://github.com/home-assistant/home-assistant/pull/12989 [#12992]: https://github.com/home-assistant/home-assistant/pull/12992 [#12999]: https://github.com/home-assistant/home-assistant/pull/12999 [#13034]: https://github.com/home-assistant/home-assistant/pull/13034 [#13267]: https://github.com/home-assistant/home-assistant/pull/13267 [#13268]: https://github.com/home-assistant/home-assistant/pull/13268 [#13271]: https://github.com/home-assistant/home-assistant/pull/13271 [#13276]: https://github.com/home-assistant/home-assistant/pull/13276 [#13280]: https://github.com/home-assistant/home-assistant/pull/13280 [#13302]: https://github.com/home-assistant/home-assistant/pull/13302 [#13305]: https://github.com/home-assistant/home-assistant/pull/13305 [#13340]: https://github.com/home-assistant/home-assistant/pull/13340 [#13372]: https://github.com/home-assistant/home-assistant/pull/13372 [#13377]: https://github.com/home-assistant/home-assistant/pull/13377 [#13378]: https://github.com/home-assistant/home-assistant/pull/13378 [#13402]: https://github.com/home-assistant/home-assistant/pull/13402 [#13419]: https://github.com/home-assistant/home-assistant/pull/13419 [#13420]: https://github.com/home-assistant/home-assistant/pull/13420 [#13427]: https://github.com/home-assistant/home-assistant/pull/13427 [#13433]: https://github.com/home-assistant/home-assistant/pull/13433 [#13435]: https://github.com/home-assistant/home-assistant/pull/13435 [#13436]: https://github.com/home-assistant/home-assistant/pull/13436 [#13438]: https://github.com/home-assistant/home-assistant/pull/13438 [#13440]: https://github.com/home-assistant/home-assistant/pull/13440 [#13441]: https://github.com/home-assistant/home-assistant/pull/13441 [#13448]: https://github.com/home-assistant/home-assistant/pull/13448 [#13451]: https://github.com/home-assistant/home-assistant/pull/13451 [#13452]: https://github.com/home-assistant/home-assistant/pull/13452 [#13456]: https://github.com/home-assistant/home-assistant/pull/13456 [#13467]: https://github.com/home-assistant/home-assistant/pull/13467 [#13473]: https://github.com/home-assistant/home-assistant/pull/13473 [#13485]: https://github.com/home-assistant/home-assistant/pull/13485 [#13496]: https://github.com/home-assistant/home-assistant/pull/13496 [#13509]: https://github.com/home-assistant/home-assistant/pull/13509 [#13510]: https://github.com/home-assistant/home-assistant/pull/13510 [#13521]: https://github.com/home-assistant/home-assistant/pull/13521 [#13526]: https://github.com/home-assistant/home-assistant/pull/13526 [#13529]: https://github.com/home-assistant/home-assistant/pull/13529 [#13531]: https://github.com/home-assistant/home-assistant/pull/13531 [#13538]: https://github.com/home-assistant/home-assistant/pull/13538 [#13544]: https://github.com/home-assistant/home-assistant/pull/13544 [#13547]: https://github.com/home-assistant/home-assistant/pull/13547 [#13563]: https://github.com/home-assistant/home-assistant/pull/13563 [#13569]: https://github.com/home-assistant/home-assistant/pull/13569 [#13576]: https://github.com/home-assistant/home-assistant/pull/13576 [#13577]: https://github.com/home-assistant/home-assistant/pull/13577 [#13585]: https://github.com/home-assistant/home-assistant/pull/13585 [#13586]: https://github.com/home-assistant/home-assistant/pull/13586 [#13601]: https://github.com/home-assistant/home-assistant/pull/13601 [#13602]: https://github.com/home-assistant/home-assistant/pull/13602 [#13603]: https://github.com/home-assistant/home-assistant/pull/13603 [#13606]: https://github.com/home-assistant/home-assistant/pull/13606 [#13610]: https://github.com/home-assistant/home-assistant/pull/13610 [#13612]: https://github.com/home-assistant/home-assistant/pull/13612 [#13613]: https://github.com/home-assistant/home-assistant/pull/13613 [#13616]: https://github.com/home-assistant/home-assistant/pull/13616 [#13618]: https://github.com/home-assistant/home-assistant/pull/13618 [#13624]: https://github.com/home-assistant/home-assistant/pull/13624 [#13626]: https://github.com/home-assistant/home-assistant/pull/13626 [#13629]: https://github.com/home-assistant/home-assistant/pull/13629 [#13630]: https://github.com/home-assistant/home-assistant/pull/13630 [#13631]: https://github.com/home-assistant/home-assistant/pull/13631 [#13636]: https://github.com/home-assistant/home-assistant/pull/13636 [#13642]: https://github.com/home-assistant/home-assistant/pull/13642 [#13647]: https://github.com/home-assistant/home-assistant/pull/13647 [#13654]: https://github.com/home-assistant/home-assistant/pull/13654 [#13658]: https://github.com/home-assistant/home-assistant/pull/13658 [#13659]: https://github.com/home-assistant/home-assistant/pull/13659 [#13663]: https://github.com/home-assistant/home-assistant/pull/13663 [#13665]: https://github.com/home-assistant/home-assistant/pull/13665 [#13667]: https://github.com/home-assistant/home-assistant/pull/13667 [#13674]: https://github.com/home-assistant/home-assistant/pull/13674 [#13678]: https://github.com/home-assistant/home-assistant/pull/13678 [#13681]: https://github.com/home-assistant/home-assistant/pull/13681 [#13682]: https://github.com/home-assistant/home-assistant/pull/13682 [#13689]: https://github.com/home-assistant/home-assistant/pull/13689 [#13691]: https://github.com/home-assistant/home-assistant/pull/13691 [#13692]: https://github.com/home-assistant/home-assistant/pull/13692 [#13693]: https://github.com/home-assistant/home-assistant/pull/13693 [#13697]: https://github.com/home-assistant/home-assistant/pull/13697 [#13700]: https://github.com/home-assistant/home-assistant/pull/13700 [#13702]: https://github.com/home-assistant/home-assistant/pull/13702 [#13709]: https://github.com/home-assistant/home-assistant/pull/13709 [#13713]: https://github.com/home-assistant/home-assistant/pull/13713 [#13788]: https://github.com/home-assistant/home-assistant/pull/13788 [#13808]: https://github.com/home-assistant/home-assistant/pull/13808 [#13828]: https://github.com/home-assistant/home-assistant/pull/13828 [#13829]: https://github.com/home-assistant/home-assistant/pull/13829 [#13831]: https://github.com/home-assistant/home-assistant/pull/13831 [#13836]: https://github.com/home-assistant/home-assistant/pull/13836 [@5LICK]: https://github.com/5LICK [@ChristianKuehnel]: https://github.com/ChristianKuehnel [@DanNixon]: https://github.com/DanNixon [@Danielhiversen]: https://github.com/Danielhiversen [@FrederikBolding]: https://github.com/FrederikBolding [@Kane610]: https://github.com/Kane610 [@Klikini]: https://github.com/Klikini [@MartinHjelmare]: https://github.com/MartinHjelmare [@MisterWil]: https://github.com/MisterWil [@Myrddyn1]: https://github.com/Myrddyn1 [@Nossnevs]: https://github.com/Nossnevs [@NovapaX]: https://github.com/NovapaX [@Oro]: https://github.com/Oro [@PhracturedBlue]: https://github.com/PhracturedBlue [@PlanetJ]: https://github.com/PlanetJ [@ReneNulschDE]: https://github.com/ReneNulschDE [@Skaronator]: https://github.com/Skaronator [@adpriebe]: https://github.com/adpriebe [@alandtse]: https://github.com/alandtse [@amelchio]: https://github.com/amelchio [@andrey-git]: https://github.com/andrey-git [@armills]: https://github.com/armills [@balloob]: https://github.com/balloob [@bdurrer]: https://github.com/bdurrer [@c727]: https://github.com/c727 [@cdce8p]: https://github.com/cdce8p [@kraddatz]: https://github.com/kraddatz [@colinodell]: https://github.com/colinodell [@danielperna84]: https://github.com/danielperna84 [@dlbroadfoot]: https://github.com/dlbroadfoot [@fabaff]: https://github.com/fabaff [@fezfox]: https://github.com/fezfox [@frenck]: https://github.com/frenck [@hAmpzter]: https://github.com/hAmpzter [@ikucuze]: https://github.com/ikucuze [@jmtatsch]: https://github.com/jmtatsch [@kellerza]: https://github.com/kellerza [@lindsaymarkward]: https://github.com/lindsaymarkward [@lwis]: https://github.com/lwis [@mf-social]: https://github.com/mf-social [@michaelarnauts]: https://github.com/michaelarnauts [@morberg]: https://github.com/morberg [@mountainsandcode]: https://github.com/mountainsandcode [@olskar]: https://github.com/olskar [@phileaton]: https://github.com/phileaton [@pschmitt]: https://github.com/pschmitt [@robmarkcole]: https://github.com/robmarkcole [@rytilahti]: https://github.com/rytilahti [@scop]: https://github.com/scop [@shuaiger]: https://github.com/shuaiger [@snjoetw]: https://github.com/snjoetw [@stephanerosi]: https://github.com/stephanerosi [@syssi]: https://github.com/syssi [@tadly]: https://github.com/tadly [@teharris1]: https://github.com/teharris1 [@timmo001]: https://github.com/timmo001 [@titilambert]: https://github.com/titilambert [@trisk]: https://github.com/trisk [@tschmidty69]: https://github.com/tschmidty69 [@turbokongen]: https://github.com/turbokongen [@wmalgadey]: https://github.com/wmalgadey [@zhaokoh]: https://github.com/zhaokoh [abode docs]: /integrations/abode/ [alarm_control_panel.ifttt docs]: /integrations/alarm_control_panel.ifttt/ [alarm_control_panel.totalconnect docs]: /integrations/totalconnect [alexa docs]: /integrations/alexa/ [amcrest docs]: /integrations/amcrest/ [api docs]: /integrations/api/ [binary_sensor.bmw_connected_drive docs]: /integrations/bmw_connected_drive [binary_sensor.workday docs]: /integrations/workday [bmw_connected_drive docs]: /integrations/bmw_connected_drive/ [摄像头.MQTT docs]: /integrations/摄像头.MQTT/ [canary docs]: /integrations/canary/ [温控.nest docs]: /integrations/nest#温控 [config docs]: /integrations/config/ [config_entry_example docs]: /integrations/config_entry_example/ [conversation docs]: /integrations/conversation/ [遮盖 docs]: /integrations/遮盖/ [遮盖.rpi_gpio docs]: /integrations/rpi_gpio#遮盖 [deconz docs]: /integrations/deconz/ [device_tracker docs]: /integrations/device_tracker/ [device_tracker.bluetooth_tracker docs]: /integrations/bluetooth_tracker [device_tracker.bmw_connected_drive docs]: /integrations/bmw_connected_drive [device_tracker.google_maps docs]: /integrations/google_maps [doorbird docs]: /integrations/doorbird/ [风扇.xiaomi_miio docs]: /integrations/风扇.xiaomi_miio/ [folder_watcher docs]: /integrations/folder_watcher/ [freedns docs]: /integrations/freedns/ [homekit docs]: /integrations/homekit/ [hue docs]: /integrations/hue/ [insteon_plm docs]: /integrations/insteon/ [灯光 docs]: /integrations/灯光/ [灯光.nanoleaf_aurora docs]: /integrations/nanoleaf/ [灯光.hue docs]: /integrations/hue [灯光.iglo docs]: /integrations/iglo [灯光.mystrom docs]: /integrations/mystrom#灯光 [灯光.nanoleaf_aurora docs]: /integrations/nanoleaf/ [灯光.qwikswitch docs]: /integrations/qwikswitch [灯光.tradfri docs]: /integrations/tradfri [灯光.xiaomi_miio docs]: /integrations/灯光.xiaomi_miio/ [灯光.yeelight docs]: /integrations/yeelight [门锁.bmw_connected_drive docs]: /integrations/bmw_connected_drive [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.philips_js docs]: /integrations/philips_js [媒体播放器.songpal docs]: /integrations/songpal [媒体播放器.webostv docs]: /integrations/webostv#media-player [MQTT docs]: /integrations/MQTT/ [mysensors docs]: /integrations/mysensors/ [通知 docs]: /integrations/通知/ [pilight docs]: /integrations/pilight/ [qwikswitch docs]: /integrations/qwikswitch/ [遥控器.xiaomi_miio docs]: /integrations/遥控器.xiaomi_miio/ [rflink docs]: /integrations/rflink/ [rfxtrx docs]: /integrations/rfxtrx/ [传感器.bmw_connected_drive docs]: /integrations/bmw_connected_drive [传感器.broadlink docs]: /integrations/broadlink#传感器 [传感器.canary docs]: /integrations/canary#传感器 [传感器.cpuspeed docs]: /integrations/cpuspeed [传感器.file docs]: /integrations/file#传感器 [传感器.imap_email_content docs]: /integrations/imap_email_content/ [传感器.plex docs]: /integrations/plex#传感器 [传感器.qnap docs]: /integrations/qnap [传感器.qwikswitch docs]: /integrations/qwikswitch [传感器.tesla docs]: /integrations/tesla [传感器.tradfri docs]: /integrations/tradfri [传感器.waze_travel_time docs]: /integrations/waze_travel_time [smappee docs]: /integrations/smappee/ [开关.amcrest docs]: /integrations/amcrest [开关.broadlink docs]: /integrations/broadlink#开关 [开关.mystrom docs]: /integrations/mystrom#开关 [开关.qwikswitch docs]: /integrations/qwikswitch#开关 [开关.tahoma docs]: /integrations/tahoma [开关.telnet docs]: /integrations/telnet [开关.xiaomi_miio docs]: /integrations/开关.xiaomi_miio/ [tado docs]: /integrations/tado/ [tahoma docs]: /integrations/tahoma/ [tradfri docs]: /integrations/tradfri/ [folder_watcher docs]: /integrations/folder_watcher/ [xiaomi_aqara docs]: /integrations/xiaomi_aqara/ [zwave docs]: /integrations/zwave/ [ann-ubiquiti]: /博客/2018/04/12/ubiquiti-and-home-assistant/ [#13728]: https://github.com/home-assistant/home-assistant/pull/13728 [#13741]: https://github.com/home-assistant/home-assistant/pull/13741 [#13862]: https://github.com/home-assistant/home-assistant/pull/13862 [#13884]: https://github.com/home-assistant/home-assistant/pull/13884 [#13887]: https://github.com/home-assistant/home-assistant/pull/13887 [#13889]: https://github.com/home-assistant/home-assistant/pull/13889 [#13906]: https://github.com/home-assistant/home-assistant/pull/13906 [#13908]: https://github.com/home-assistant/home-assistant/pull/13908 [#13920]: https://github.com/home-assistant/home-assistant/pull/13920 [#13940]: https://github.com/home-assistant/home-assistant/pull/13940 [#13946]: https://github.com/home-assistant/home-assistant/pull/13946 [#13947]: https://github.com/home-assistant/home-assistant/pull/13947 [#13959]: https://github.com/home-assistant/home-assistant/pull/13959 [@Danielhiversen]: https://github.com/Danielhiversen [@Kane610]: https://github.com/Kane610 [@aav7fl]: https://github.com/aav7fl [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@dlbroadfoot]: https://github.com/dlbroadfoot [@kellerza]: https://github.com/kellerza [@syssi]: https://github.com/syssi [@titilambert]: https://github.com/titilambert [温控.honeywell docs]: /integrations/honeywell [config docs]: /integrations/config/ [device_tracker docs]: /integrations/device_tracker/ [风扇.xiaomi_miio docs]: /integrations/风扇.xiaomi_miio/ [qwikswitch docs]: /integrations/qwikswitch/ [传感器.fido docs]: /integrations/fido [传感器.pollen docs]: /integrations/iqvia [开关.broadlink docs]: /integrations/broadlink#开关 [开关.vesync docs]: /integrations/vesync#开关 --- url: /home-assistant/blog/2018-04-22-hassio-2018.md --- # Hass.io 2018 路线说明 我们注意到,社区对 Hass.io 与 Home Assistant 的关系,以及即将到来的 Hass.io 变更会带来什么影响,存在一些困惑。本文会尽量把这些问题说明清楚。 ## What is Hass.io Hass.io 是由 Home Assistant 作者打造的一套完整运行方案。它的目标是提供一个易用且安全的系统,并且可在 Home Assistant 用户界面中完成全部管理。 所谓“完整方案”,意味着它自带高度安全且经过优化的操作系统、用于维护和配置系统的 Supervisor 应用,以及 Home Assistant 本体。 使用 Hass.io 时,你会在 Home Assistant UI 里看到新的 Hass.io 面板。用户可以在这里配置系统,并通过点击按钮安装 Home Assistant 更新。用户还可以创建系统快照,轻松把全部配置迁移到新系统,或恢复到之前的状态。 我们也希望把通过 UI 无缝更新与配置的便利扩展到其他应用,因此推出了 Hass.io 插件。任何应用都可以被打包成 Hass.io 插件,让用户轻松安装和管理。自推出以来,社区共享插件的规模增长非常快。现在你可以一键安装网络广告拦截器、MQTT Broker 甚至 Tor。 ## Upcoming changes to Hass.io 我们在[去年 7 月][last July]推出了 Hass.io。此后我们发现还有不少改进空间,可以让 Hass.io 更易用、更易维护,也更容易与其他主机系统集成。 下面的改进说明会稍微偏技术向。如果你只想看结论,可以直接跳到[文末结论][the conclusion]。 ### Automatic 插件 配置 Home Assistant 最近引入了配置条目(config entries)。我们会接入这项能力,让插件自动配置其在 Home Assistant 中对应的集成。例如,用户安装 MQTT Broker 插件后,我们会自动配置 Home Assistant 与其连接。 ### Host management 目前我们通过名为 HostControl 的自定义服务控制主机系统,让用户可在 Home Assistant 中管理主机并重启/关机。接下来我们会改用 D-Bus,而不再依赖自有机制。D-Bus 是服务与应用通信的标准机制。采用标准后,主机各部分都可以远程配置,比如声音、网络等。我们也会扩展 Home Assistant 中的 Hass.io 面板,加入配置主机各项功能的控制项。 ### Hass.io OS Hass.io 目前使用的是我们 fork 的 ResinOS。ResinOS 原本面向 Docker 最小运行环境、简化的 OTA 更新,以及连接 ResinIO 云。我们的分支移除了 ResinIO 相关逻辑。随着时间推移,ResinOS 的演进方向逐渐与我们的目标不一致,导致维护 fork 分支占用了大量时间。 ResinOS 的构建系统基于 Yocto Project。它非常强大,但每个硬件平台都需要单独添加并维护支持(比如各个版本的树莓派),这导致 Hass.io 的构建和开发周期较长。 综合这些因素,我们决定构建自己的定制操作系统。当然我们不会从零开始,而是基于 [Buildroot] 构建,并使用 [RAUC] 实现 OTA 更新。 新操作系统将具备以下能力: * 更容易为新硬件添加支持。 * 更新采用原子方式并具备故障保护。如果系统在 OS 升级后无法启动,会自动回退并启动上一个可用版本。 * 更新包必须由 Home Assistant 团队进行安全签名,进一步提升安全等级。 * 根文件系统会被压缩,在 SD 卡和低速 IO 接口上运行更快。 * 通过压缩部分内存,可存储更多信息。 ## Hass.io 用户现在需要做什么 现在:什么都不用做。 新的 Hass.io Supervisor 仍支持旧 ResinOS 构建(我们面向树莓派和 Intel NUC 的官方下载),也支持通用 Linux 安装。如果你是在 SUSE Linux 或 Ubuntu 上进行通用 Linux 安装,想使用新功能就需要更新本地 AppArmor 配置文件(我们会在发布时提供说明)。 新 HassioOS 安装镜像发布后,你需要为设备重新刷写一次。通过 Snapshot 功能可以在不丢失配置的情况下完成: * 创建当前安装的快照并下载到电脑。 * 将新的 Hass.io OS 镜像刷入 SD 卡。 * 恢复你的快照。 * 开始使用全新升级后的 Hass.io。 [last July]: /博客/2017/07/25/introducing-hassio/ [the conclusion]: #what-hassio-用户-should-do-to-prepare-for-these-updates [Buildroot]: https://buildroot.org/ [RAUC]: https://www.rauc.io/ --- url: /home-assistant/blog/2018-04-24-launch-google-assistant-support.md --- # Google Assistant 技能正式上线!

Home Assistant logo and the Works with the Google Assistant badge

没错,我们的 Google Assistant Smart Home 技能已经上线!名字虽然有点长,但这意味着你现在可以通过任何支持 Google Assistant 的设备,用一句“Ok Google,打开灯”来控制 Home Assistant 设备。 快速开始: * [启用 Home Assistant Cloud](/home-assistant/cloud/index.md#enabling-the-cloud) * 安装我们的 Google Assistant 技能。本文发布时直达链接还未生效:你可以打开 Google Home 应用 -> Home Control,点击右下角蓝色 `+`,然后在列表中找到 Hass.io。 * 可选:[调整要暴露给 Google Assistant 的设备](/home-assistant/cloud/google_assistant/index.md)。 注意事项: * 技能名称叫 Hass.io,但普通 Home Assistant 同样可用。这个命名是为了避免 Home Assistant、Google Assistant 和 Google Home 之间的混淆。 * 支持 Home Assistant `0.65.6` 及以上版本。 * 所有消息处理都在本地完成,且实现已[开源](https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/integrations/google_assistant/trait.py)。 * 如果你有带 Google Assistant 的 Android 设备,也可以控制家中设备。 * Home Assistant `0.68` 会在 Cloud 配置面板加入一个按钮,用于触发可用设备同步。 Home Assistant Cloud 仍处于公开测试阶段,并且可免费使用。公开测试期已延长至 6 月 1 日。特别感谢 [Quadflight] 提供 Google 实机测试所用的树莓派,也感谢 [Arsaboo] 协助测试。
[Quadflight]: https://github.com/quadflight [Arsaboo]: https://github.com/arsaboo --- url: /home-assistant/blog/2018-04-26-developer-site.md --- # 全新开发者网站 2014 年 12 月我们上线官网时,只有少量组件和使用说明。此后网站成长到超过 1000 个页面,覆盖了非常广泛的话题。增长固然可喜,但也给文档组织方式带来了很大压力。受影响最明显的就是开发者部分:它长期挂在顶部菜单的一个入口下,所有内容都挤在同一个侧边栏里。 为了解决这个问题,我们发布了新网站:[开发者.home-assistant.io](https://开发者.home-assistant.io)。这个站点面向 Home Assistant 开发者,提供如何搭建开发环境、修复 bug、参与翻译和改进前端等资源。主站将专注于服务 Home Assistant 用户。 欢迎访问并告诉我们你的看法:[开发者.home-assistant.io](https://开发者.home-assistant.io)。 Screenshot of the developer website --- url: /home-assistant/blog/2018-04-27-release-68.md --- # 0.68:HomeKit 控制、Eufy、FritzBox、SigFox 传感器 周末将至,也意味着 Home Assistant 新版本又来了。0.68 带来了大量实用新功能和 bug 修复。 本次发布最酷的功能之一来自 [@mjg59]:你现在可以**控制** HomeKit 设备了。此前,HomeKit 协议只用于从 iOS 设备控制 Home Assistant;而从这个版本开始,Home Assistant 可以反过来充当控制器,直接通过 HomeKit 控制灯光和开关。由于 HomeKit 不受厂商限制,这意味着几乎任何 HomeKit 灯光或开关都能与 Home Assistant 兼容。非常酷。 另一个同样很酷的新平台也来自 [@mjg59],那就是对 Eufy 设备的支持。Eufy 是 Anker 旗下的智能家居品牌,他们推出了许多价格亲民的设备,现在这些设备也可以由 Home Assistant 控制了。感谢 [@mjg59] 的所有贡献 ❤️。 ## 新平台 * 新增对 Eufy 灯泡和开关的支持 ([@mjg59] - [#13773]) ([eufy docs]) ([灯光.eufy docs]) ([开关.eufy docs]) (new-platform) * 新增通过 HomeKit 控制灯光和开关的支持 ([@mjg59] - [#13346]) ([homekit\_controller docs][homekit_controller docs]) ([灯光.homekit\_controller docs][灯光.homekit_controller docs]) (new-platform) * 新增 USCIS 组件 ([@meauxt] - [#13764]) ([传感器.uscis docs]) (new-platform) * 新增 `温控.modbus` 平台支持 ([@Kirchoff] - [#12224]) ([温控.modbus docs]) (new-platform) * 新增 AVM FritzBox 智能家居组件 ([@hthiery] - [#10688]) ([fritzbox docs]) ([温控.fritzbox docs]) ([开关.fritzbox docs]) (new-platform) * 新增 SigFox 传感器 ([@robmarkcole] - [#13731]) ([传感器.sigfox docs]) (new-platform) * 新增 Blackbird 媒体播放器组件 ([@koolsb] - [#13549]) ([媒体播放器.blackbird docs]) (new-platform) * 新增 Sensirion SHT31 温湿度传感器支持 ([@viorels] - [#12952]) ([传感器.sht31 docs]) (new-platform) * Qwikswitch 二元sensor ([@kellerza] - [#14008]) ([qwikswitch docs]) ([binary\_sensor.qwikswitch docs][binary_sensor.qwikswitch docs]) ([传感器.qwikswitch docs]) (beta fix) (new-platform) ## 新功能 * HomeKit 新增对二元传感器和设备追踪器的支持 ([@Yonsm] - [#13735]) ([homekit docs]) (new-feature) * HomeKit 新增门锁支持 ([@philk] - [#13625]) ([homekit docs]) (new-feature) * HomeKit 新增对 CO2/PM2.5/光照传感器的支持 ([@Yonsm] - [#13804]) ([homekit docs]) (new-feature) * HomeKit 新增车库门支持 ([@marthoc] - [#13796]) ([homekit docs]) (new-feature) * HomeKit 新增对支持打开/关闭/停止服务的基础遮盖设备支持 ([@nickw444] - [#13819]) ([homekit docs]) (new-feature) ## 发布 0.68.1 - April 30 * Fix color setting of tplink 灯光 ([@amelchio] - [#14108]) ([灯光.tplink docs]) * Improve precision of Hue color 状态 ([@amelchio] - [#14113]) ([灯光.hue docs]) * Revert Hue color 状态 to be xy-based ([@amelchio] - [#14154]) * Fix Python 3.6 compatibility for HomeKit controller ([@mjg59] - [#14160]) ([homekit\_controller docs][homekit_controller docs]) * Added CONF\_IP\_ADDRESS to HomeKit ([@cdce8p] - [#14163]) ([homekit docs]) * Do not sync 实体 with an empty name ([@balloob] - [#14181]) ([google\_assistant docs][google_assistant docs]) * Improve chromecast disconnection logic ([@OttoWinter] - [#14190]) ([媒体播放器.cast docs]) * Fix poorly formatted 自动化 ([@balloob] - [#14196]) * Disable eliqonline requirement ([@balloob] - [#14156]) ## 如果你需要帮助…… ……欢迎随时使用我们非常活跃的[论坛](https://community.home-assistant.io/),或加入我们的 [chat](https://discord.gg/c5DvZ4e) 交流。发布说明虽然开放评论,但我们更推荐你使用前面的沟通渠道。谢谢。 ## 报告问题 如果你遇到了由此版本引入的问题,请在我们的 [issue tracker](https://github.com/home-assistant/home-assistant/issues) 中反馈,并确保完整填写 issue 模板中的所有字段。 ## 不向后兼容的变更 * 图标有变更!Material Design Icons 实施了新的命名规范,因此有 9 个图标改名,其中 3 个是家庭自动化相关图标:`roomba` -> `robot-vacuum`、`nest-protect` -> `smoke-detector`、`nest-thermostat` -> `thermostat`([查看全部变更](http://templarian.com/2018/04/18/material-design-icons-v2-3-54/))。 * 对多个 MAX!Cube LAN 网关的支持导致配置结构发生了轻微变化,请记得查看新版文档。([@syssi] - [#13517]) ([maxcube docs]) ([binary\_sensor.maxcube docs][binary_sensor.maxcube docs]) ([温控.maxcube docs]) (breaking change) * Ebox 传感器平台已被禁用,因为其依赖与 pip 10 不兼容。([@balloob] - [#14003]) ([传感器.ebox docs]) (breaking change) ## Beta 修复 * Qwikswitch 二元sensor ([@kellerza] - [#14008]) ([qwikswitch docs]) ([binary\_sensor.qwikswitch docs][binary_sensor.qwikswitch docs]) ([传感器.qwikswitch docs]) (beta fix) (new-platform) * Order the output of the 自动化 editor ([@balloob] - [#14019]) ([config docs]) (beta fix) * HomeKit 报警 Control 面板 Code Exception Fix ([@schmittx] - [#14025]) ([homekit docs]) (beta fix) * Revert cast platform polling mode ([@OttoWinter] - [#14027]) ([媒体播放器.cast docs]) (beta fix) * Handle HomeKit 配置 failure more cleanly ([@mjg59] - [#14041]) ([homekit\_controller docs][homekit_controller docs]) (beta fix) * 更新 设备 classes for contact 传感器 HomeKit ([@marthoc] - [#14051]) ([homekit docs]) (beta fix) * 升级 broadlink lib ([@Danielhiversen] - [#14074]) ([传感器.broadlink docs]) ([开关.broadlink docs]) (beta fix) * Fix timezone issue when calculating min/max values in tibber #14009 ([@Danielhiversen] - [#14080]) ([传感器.tibber docs]) (beta fix) * Updated list of AWS regions for Amazon Polly ([@GotoCode] - [#14097]) ([tts docs]) (beta fix) * Change Eufy brightness handling ([@mjg59] - \[#14111]) (beta fix) ## 所有变更 * 更新 Homekit to 1.1.9 ([@cdce8p] - [#13716]) ([homekit docs]) * 更新 docstrings ([@fabaff] - [#13720]) ([ihc docs]) ([遮盖.opengarage docs]) ([遮盖.tahoma docs]) ([传感器.trafikverket\_weatherstation docs][传感器.trafikverket_weatherstation docs]) * Add option to ignore availability in google 日历 events ([@cgtobi] - [#13714]) ([日历.google docs]) * Allow use of date\_string in 服务 call ([@Juggels] - [#13256]) ([日历.todoist docs]) * Add timeout / debounce (for brightness and others) ([@cdce8p] - [#13534]) ([homekit docs]) * added support for smappee water 传感器 ([@hmn] - [#12831]) ([smappee docs]) ([传感器.smappee docs]) * Initialise filter\_sensor with historical values ([@dgomes] - [#13075]) ([传感器.filter docs]) * Fix Gogogate2 'available' 属性 ([@dlbroadfoot] - [#13728]) (beta fix) * Bluesound bugfix status 595 and await ([@thrawnarn] - [#13727]) ([媒体播放器.bluesound docs]) * 升级 aiohttp to 3.1.2 ([@fabaff] - [#13732]) * 升级 sqlalchemy to 1.2.6 ([@fabaff] - [#13733]) ([传感器.sql docs]) * Brightness conversion for Abode dimmers ([@shred86] - [#13711]) ([灯光.abode docs]) * 更新 CODEOWNERS (传感器.filter, 传感器.upnp) ([@dgomes] - [#13736]) * Reset permission ([@fabaff] - [#13743]) ([灯光.abode docs]) * Throw an 错误 when invalid device\_mode is given ([@left4taco] - [#13739]) * Fix so it is possible to ignore discovered config entry handlers ([@Kane610] - [#13741]) (beta fix) * 升级 netdisco to 1.3.1 ([@fabaff] - [#13744]) * Add MQTT 传感器 unique\_id ([@OttoWinter] - [#13318]) ([传感器.MQTT docs]) * Prepare 实体 component for config entries ([@balloob] - [#13730]) * Check valid file on get\_size ([@robmarkcole] - [#13756]) ([传感器.folder docs]) * Qwikswitch 传感器 ([@kellerza] - [#13622]) ([传感器.qwikswitch docs]) * 设备 type mapping introduced to avoid breaking change ([@syssi] - [#13765]) ([灯光.yeelight docs]) * Only flag media position as updated when it really has ([@molobrakos] - [#13737]) ([媒体播放器.squeezebox docs]) * Support binary\_sensor and device\_tracker in HomeKit ([@Yonsm] - [#13735]) ([homekit docs]) (new-feature) * Use config entry to 设置 platforms ([@balloob] - [#13752]) ([hue docs]) ([灯光 docs]) ([灯光.hue docs]) * Add Homekit 门锁 support ([@philk] - [#13625]) ([homekit docs]) (new-feature) * Snips sounds ([@tschmidty69] - [#13746]) ([snips docs]) * Add missing DISCHRG 状态 ([@swilson] - [#13787]) ([传感器.nut docs]) * Improved upgradeability HomeKit security\_systems ([@cdce8p] - [#13783]) ([homekit docs]) * Qwikswitch 实体 Register ([@kellerza] - [#13791]) ([qwikswitch docs]) ([传感器.qwikswitch docs]) * Updated beacontools to 1.2.3 ([@citruz] - [#13792]) ([传感器.eddystone\_temperature docs][传感器.eddystone_temperature docs]) * 脚本/lazytox: Ensure Flake8 passes for tests/ ([@kellerza] - [#13794]) * Fix bad metrics format for short metrics. ([@michaelkuty] - [#13778]) ([prometheus docs]) * 更新 bellows to 0.5.2 ([@rcloran] - [#13800]) ([zha docs]) * device\_tracker.ubus: Handle 设备 not running DHCP ([@tobygray] - [#13579]) ([device\_tracker docs][device_tracker docs]) * 更新 yweather.py ([@wiuwiu] - [#13802]) * Tibber lib 更新 ([@Danielhiversen] - [#13811]) ([传感器.tibber docs]) * 更新 pyhomematic to 0.1.41 ([@danielperna84] - [#13814]) ([homematic docs]) * Add support for Eufy bulbs and 开关 ([@mjg59] - [#13773]) ([eufy docs]) ([灯光.eufy docs]) ([开关.eufy docs]) (new-platform) * Homekit refactor ([@cdce8p] - [#13707]) ([homekit docs]) * HomeKit type\_cover fix ([@cdce8p] - [#13832]) ([homekit docs]) * Allow platform unloading ([@balloob] - [#13784]) ([hue docs]) ([灯光 docs]) * Support CO2/PM2.5/灯光 传感器 in HomeKit ([@Yonsm] - [#13804]) ([homekit docs]) (new-feature) * Clicksend: Added support for multiple recipients ([@asafbiton96] - [#13812]) ([通知 docs]) * Support Garage Doors in HomeKit ([@marthoc] - [#13796]) ([homekit docs]) (new-feature) * Abode better events ([@MisterWil] - [#13809]) ([abode docs]) * UPnP async ([@dgomes] - [#13666]) ([upnp docs]) ([传感器.upnp docs]) * 更新 example (fixes #13834) ([@fabaff] - [#13839]) * Add support for deCONZ daylight 传感器 ([@marthoc] - [#13479]) ([deconz docs]) ([传感器.deconz docs]) * initialize queue before filtering ([@dgomes] - [#13842]) ([传感器.filter docs]) * Extract config flow to own module ([@balloob] - [#13840]) ([config docs]) ([deconz docs]) ([hue docs]) * Add support for controlling homekit 灯光 and 开关 ([@mjg59] - [#13346]) ([homekit\_controller docs][homekit_controller docs]) ([灯光.homekit\_controller docs][灯光.homekit_controller docs]) (new-platform) * bump python-ecobee-api 版本 to 0.0.18 ([@geekofweek] - [#13854]) ([ecobee docs]) * Adding USCIS component ([@meauxt] - [#13764]) ([传感器.uscis docs]) (new-platform) * Avoid unnecessary cast 状态 updates ([@dersger] - [#13770]) ([媒体播放器.cast docs]) * Prevent vesync doing I/O in event loop ([@balloob] - [#13862]) ([开关.vesync docs]) (beta fix) * 更新 yweather.py ([@TheCellMC] - [#13851]) * add support for Kodi discovery ([@escoand] - [#13790]) ([媒体播放器.kodi docs]) * Further untangle data entry flow ([@balloob] - [#13855]) * Missing property decorator added ([@syssi] - [#13889]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) (beta fix) * Fix race 条件 for component loaded before listening ([@balloob] - [#13887]) ([config docs]) (beta fix) * Added snips 服务 descriptions ([@tschmidty69] - [#13883]) * Add unique\_id for BMW ConnectedDrive ([@gerard33] - [#13888]) ([binary\_sensor.bmw\_connected\_drive docs][binary_sensor.bmw_connected_drive docs]) ([门锁.bmw\_connected\_drive docs][门锁.bmw_connected_drive docs]) ([传感器.bmw\_connected\_drive docs][传感器.bmw_connected_drive docs]) * Revert "更新 yweather.py" ([@pvizeli] - [#13900]) * Eufy colour bulb updates ([@mjg59] - [#13895]) ([eufy docs]) ([灯光.eufy docs]) * Fix #13846 Double underscore in 蓝牙 address ([@aav7fl] - [#13884]) ([device\_tracker docs][device_tracker docs]) (beta fix) * Import operation modes from air 加湿器 ([@syssi] - [#13908]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) (beta fix) * Fritzbox netmonitor name ([@escoand] - [#13903]) ([传感器.fritzbox\_netmonitor docs][传感器.fritzbox_netmonitor docs]) * 恢复 typeerror check for units sans energy tracking ([@andersonshatch] - [#13824]) ([开关.edimax docs]) * Add more math functions to 模板 ([@Shou] - [#13915]) * 升级 pyqwikswitch to 0.71 ([@kellerza] - [#13920]) ([qwikswitch docs]) * Add extra 属性 for 设备 scanner, Nmap and Unifi (IP, SSID, etc.) ([@stephanerosi] - [#13673]) ([device\_tracker docs][device_tracker docs]) * Fixed Capsman data not being used ([@Marco98] - [#13917]) ([device\_tracker docs][device_tracker docs]) * Broadlink 传感器 - 开关 to connection-less mode ([@Paxy] - [#13761]) ([传感器.broadlink docs]) * Add support for new platform: 温控.modbus ([@Kirchoff] - [#12224]) ([温控.modbus docs]) (new-platform) * Hive R3 更新 ([@KJonline] - [#13357]) ([hive docs]) ([binary\_sensor.hive docs][binary_sensor.hive docs]) ([温控.hive docs]) ([灯光.hive docs]) ([传感器.hive docs]) ([开关.hive docs]) * Updated foobot\_async package 版本 ([@reefab] - [#13942]) ([传感器.foobot docs]) * 更新 pyhydroquebec to 2.2.2 ([@titilambert] - [#13946]) (beta fix) * 升级 alpha\_vantage to 2.0.0 ([@fabaff] - [#13943]) ([传感器.alpha\_vantage docs][传感器.alpha_vantage docs]) * Cleanup on exit ([@dgomes] - [#13918]) ([媒体播放器.mediaroom docs]) * 升级 somecomfort to 0.5.2 ([@balloob] - [#13940]) ([温控.honeywell docs]) (beta fix) * Add data entry flow 助手 ([@balloob] - [#13935]) ([config docs]) * Xiaomi MiIO 设备 Tracker: Unused variable removed ([@syssi] - [#13948]) ([device\_tracker docs][device_tracker docs]) * Implement play media to set a channel based on (by priority): ([@stephanerosi] - [#13934]) ([媒体播放器.webostv docs]) * 更新 of python-mpd2 ([@karlkar] - [#13921]) ([媒体播放器.mpd docs]) * Add AVM fritzbox smarthome component ([@hthiery] - [#10688]) ([fritzbox docs]) ([温控.fritzbox docs]) ([开关.fritzbox docs]) (new-platform) * Adds SigFox 传感器 ([@robmarkcole] - [#13731]) ([传感器.sigfox docs]) (new-platform) * 升级 aiohttp to 3.1.3 ([@fabaff] - [#13938]) * 升级 youtube\_dl to 2018.04.16 ([@fabaff] - [#13937]) ([media\_extractor docs][media_extractor docs]) * Added FB messenger broadcast api to 通知.facebook component ([@B1tMaster] - [#12459]) ([通知.facebook docs]) * Added web view for TTS to get url ([@tschmidty69] - [#13882]) ([tts docs]) * Add 服务 for bmw\_connected\_drive ([@ChristianKuehnel] - [#13497]) ([bmw\_connected\_drive docs][bmw_connected_drive docs]) ([device\_tracker docs][device_tracker docs]) * Fix call to parent broadlink 开关 ([@Danielhiversen] - [#13906]) ([开关.broadlink docs]) (beta fix) * Bump deCONZ requirement to v36 ([@Kane610] - [#13960]) ([deconz docs]) * Fix Gogogate2 'available' 属性 ([@dlbroadfoot] - [#13728]) (beta fix) * Fix so it is possible to ignore discovered config entry handlers ([@Kane610] - [#13741]) (beta fix) * Prevent vesync doing I/O in event loop ([@balloob] - [#13862]) ([开关.vesync docs]) (beta fix) * Fix #13846 Double underscore in 蓝牙 address ([@aav7fl] - [#13884]) ([device\_tracker docs][device_tracker docs]) (beta fix) * Fix race 条件 for component loaded before listening ([@balloob] - [#13887]) ([config docs]) (beta fix) * Missing property decorator added ([@syssi] - [#13889]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) (beta fix) * Fix call to parent broadlink 开关 ([@Danielhiversen] - [#13906]) ([开关.broadlink docs]) (beta fix) * Import operation modes from air 加湿器 ([@syssi] - [#13908]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) (beta fix) * 升级 pyqwikswitch to 0.71 ([@kellerza] - [#13920]) ([qwikswitch docs]) * 升级 somecomfort to 0.5.2 ([@balloob] - [#13940]) ([温控.honeywell docs]) (beta fix) * 更新 pyhydroquebec to 2.2.2 ([@titilambert] - [#13946]) (beta fix) * Revert "升级 pyqwikswitch to 0.71 ([@balloob] - [#13920]) ([qwikswitch docs]) * Bump skybellpy 版本 to 0.1.2 ([@MisterWil] - [#13974]) ([skybell docs]) * Fix typo an coding style ([@stephanerosi] - [#13970]) ([device\_tracker docs][device_tracker docs]) * Params of the send command can be a list now ([@syssi] - [#13905]) ([吸尘器 docs]) * Support basic 遮盖 with open/close/stop 服务 HomeKit ([@nickw444] - [#13819]) ([homekit docs]) (new-feature) * Colorlog windows fix ([@veleek] - [#13929]) ([通知 docs]) * deCONZ migrate 设置 fully to config entry ([@Kane610] - [#13679]) ([deconz docs]) * Alexa thermostat fails to properly parse 'value' field for 温控 ([@no2chem] - [#13958]) ([alexa docs]) * renaming icons ([@NovapaX] - [#13982]) ([hdmi\_cec docs][hdmi_cec docs]) ([吸尘器 docs]) ([吸尘器.dyson docs]) ([吸尘器.neato docs]) ([吸尘器.roomba docs]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) * Fix for Lokalise 后端 misinterpretation of keys ([@armills] - [#13986]) * Bump locationsharinglib to 1.2.1 ([@thelittlefireman] - [#13980]) ([device\_tracker docs][device_tracker docs]) * Support for multiple MAX!Cube LAN gateways added ([@syssi] - [#13517]) ([maxcube docs]) ([binary\_sensor.maxcube docs][binary_sensor.maxcube docs]) ([温控.maxcube docs]) (breaking change) * Add additional receiver for Onkyo 区域 2 ([@koolsb] - [#13551]) ([媒体播放器.onkyo docs]) * Add blackbird media player component ([@koolsb] - [#13549]) ([媒体播放器.blackbird docs]) (new-platform) * Add support for Sensirion SHT31 temperature/humidity 传感器 ([@viorels] - [#12952]) ([传感器.sht31 docs]) (new-platform) * Useless code removed ([@syssi] - [#13996]) ([maxcube docs]) * Add Homematic HmIP-SWO-PR 天气 传感器 support ([@pascalhahn] - [#13904]) ([homematic docs]) * Disable ebox requirement ([@balloob] - [#14003]) ([传感器.ebox docs]) (breaking change) * Upgraded miflora library to 版本 0.4.0 ([@ChristianKuehnel] - [#14005]) ([传感器.miflora docs]) * 日志 an 错误 instead of raising an exception ([@syssi] - [#14006]) ([传感器.sht31 docs]) * Tibber available ([@Danielhiversen] - [#13865]) ([传感器.tibber docs]) * 升级 pylutron-caseta to 0.5.0 to reestablish connections ([@rohankapoorcom] - [#14013]) ([lutron\_caseta docs][lutron_caseta docs]) * Add 传感器 设备 classes ([@balloob] - [#14010]) ([传感器 docs]) ([传感器.ecobee docs]) ([传感器.linux\_battery docs][传感器.linux_battery docs]) ([传感器.nest docs]) * Qwikswitch 二元sensor ([@kellerza] - [#14008]) ([qwikswitch docs]) ([binary\_sensor.qwikswitch docs][binary_sensor.qwikswitch docs]) ([传感器.qwikswitch docs]) (beta fix) (new-platform) * Order the output of the 自动化 editor ([@balloob] - [#14019]) ([config docs]) (beta fix) * HomeKit 报警 Control 面板 Code Exception Fix ([@schmittx] - [#14025]) ([homekit docs]) (beta fix) * Revert cast platform polling mode ([@OttoWinter] - [#14027]) ([媒体播放器.cast docs]) (beta fix) * Handle HomeKit 配置 failure more cleanly ([@mjg59] - [#14041]) ([homekit\_controller docs][homekit_controller docs]) (beta fix) * 更新 设备 classes for contact 传感器 HomeKit ([@marthoc] - [#14051]) ([homekit docs]) (beta fix) * 升级 broadlink lib ([@Danielhiversen] - [#14074]) ([传感器.broadlink docs]) ([开关.broadlink docs]) (beta fix) * Fix timezone issue when calculating min/max values in tibber #14009 ([@Danielhiversen] - [#14080]) ([传感器.tibber docs]) (beta fix) * Updated list of AWS regions for Amazon Polly ([@GotoCode] - [#14097]) ([tts docs]) (beta fix) [#10688]: https://github.com/home-assistant/home-assistant/pull/10688 [#12224]: https://github.com/home-assistant/home-assistant/pull/12224 [#12459]: https://github.com/home-assistant/home-assistant/pull/12459 [#12831]: https://github.com/home-assistant/home-assistant/pull/12831 [#12952]: https://github.com/home-assistant/home-assistant/pull/12952 [#13075]: https://github.com/home-assistant/home-assistant/pull/13075 [#13256]: https://github.com/home-assistant/home-assistant/pull/13256 [#13318]: https://github.com/home-assistant/home-assistant/pull/13318 [#13346]: https://github.com/home-assistant/home-assistant/pull/13346 [#13357]: https://github.com/home-assistant/home-assistant/pull/13357 [#13479]: https://github.com/home-assistant/home-assistant/pull/13479 [#13497]: https://github.com/home-assistant/home-assistant/pull/13497 [#13517]: https://github.com/home-assistant/home-assistant/pull/13517 [#13534]: https://github.com/home-assistant/home-assistant/pull/13534 [#13549]: https://github.com/home-assistant/home-assistant/pull/13549 [#13551]: https://github.com/home-assistant/home-assistant/pull/13551 [#13579]: https://github.com/home-assistant/home-assistant/pull/13579 [#13622]: https://github.com/home-assistant/home-assistant/pull/13622 [#13625]: https://github.com/home-assistant/home-assistant/pull/13625 [#13666]: https://github.com/home-assistant/home-assistant/pull/13666 [#13673]: https://github.com/home-assistant/home-assistant/pull/13673 [#13679]: https://github.com/home-assistant/home-assistant/pull/13679 [#13707]: https://github.com/home-assistant/home-assistant/pull/13707 [#13711]: https://github.com/home-assistant/home-assistant/pull/13711 [#13714]: https://github.com/home-assistant/home-assistant/pull/13714 [#13716]: https://github.com/home-assistant/home-assistant/pull/13716 [#13720]: https://github.com/home-assistant/home-assistant/pull/13720 [#13727]: https://github.com/home-assistant/home-assistant/pull/13727 [#13728]: https://github.com/home-assistant/home-assistant/pull/13728 [#13730]: https://github.com/home-assistant/home-assistant/pull/13730 [#13731]: https://github.com/home-assistant/home-assistant/pull/13731 [#13732]: https://github.com/home-assistant/home-assistant/pull/13732 [#13733]: https://github.com/home-assistant/home-assistant/pull/13733 [#13735]: https://github.com/home-assistant/home-assistant/pull/13735 [#13736]: https://github.com/home-assistant/home-assistant/pull/13736 [#13737]: https://github.com/home-assistant/home-assistant/pull/13737 [#13739]: https://github.com/home-assistant/home-assistant/pull/13739 [#13741]: https://github.com/home-assistant/home-assistant/pull/13741 [#13743]: https://github.com/home-assistant/home-assistant/pull/13743 [#13744]: https://github.com/home-assistant/home-assistant/pull/13744 [#13746]: https://github.com/home-assistant/home-assistant/pull/13746 [#13752]: https://github.com/home-assistant/home-assistant/pull/13752 [#13756]: https://github.com/home-assistant/home-assistant/pull/13756 [#13761]: https://github.com/home-assistant/home-assistant/pull/13761 [#13764]: https://github.com/home-assistant/home-assistant/pull/13764 [#13765]: https://github.com/home-assistant/home-assistant/pull/13765 [#13770]: https://github.com/home-assistant/home-assistant/pull/13770 [#13773]: https://github.com/home-assistant/home-assistant/pull/13773 [#13778]: https://github.com/home-assistant/home-assistant/pull/13778 [#13783]: https://github.com/home-assistant/home-assistant/pull/13783 [#13784]: https://github.com/home-assistant/home-assistant/pull/13784 [#13787]: https://github.com/home-assistant/home-assistant/pull/13787 [#13790]: https://github.com/home-assistant/home-assistant/pull/13790 [#13791]: https://github.com/home-assistant/home-assistant/pull/13791 [#13792]: https://github.com/home-assistant/home-assistant/pull/13792 [#13794]: https://github.com/home-assistant/home-assistant/pull/13794 [#13796]: https://github.com/home-assistant/home-assistant/pull/13796 [#13800]: https://github.com/home-assistant/home-assistant/pull/13800 [#13802]: https://github.com/home-assistant/home-assistant/pull/13802 [#13804]: https://github.com/home-assistant/home-assistant/pull/13804 [#13809]: https://github.com/home-assistant/home-assistant/pull/13809 [#13811]: https://github.com/home-assistant/home-assistant/pull/13811 [#13812]: https://github.com/home-assistant/home-assistant/pull/13812 [#13814]: https://github.com/home-assistant/home-assistant/pull/13814 [#13819]: https://github.com/home-assistant/home-assistant/pull/13819 [#13824]: https://github.com/home-assistant/home-assistant/pull/13824 [#13832]: https://github.com/home-assistant/home-assistant/pull/13832 [#13839]: https://github.com/home-assistant/home-assistant/pull/13839 [#13840]: https://github.com/home-assistant/home-assistant/pull/13840 [#13842]: https://github.com/home-assistant/home-assistant/pull/13842 [#13851]: https://github.com/home-assistant/home-assistant/pull/13851 [#13854]: https://github.com/home-assistant/home-assistant/pull/13854 [#13855]: https://github.com/home-assistant/home-assistant/pull/13855 [#13862]: https://github.com/home-assistant/home-assistant/pull/13862 [#13865]: https://github.com/home-assistant/home-assistant/pull/13865 [#13882]: https://github.com/home-assistant/home-assistant/pull/13882 [#13883]: https://github.com/home-assistant/home-assistant/pull/13883 [#13884]: https://github.com/home-assistant/home-assistant/pull/13884 [#13887]: https://github.com/home-assistant/home-assistant/pull/13887 [#13888]: https://github.com/home-assistant/home-assistant/pull/13888 [#13889]: https://github.com/home-assistant/home-assistant/pull/13889 [#13895]: https://github.com/home-assistant/home-assistant/pull/13895 [#13900]: https://github.com/home-assistant/home-assistant/pull/13900 [#13903]: https://github.com/home-assistant/home-assistant/pull/13903 [#13904]: https://github.com/home-assistant/home-assistant/pull/13904 [#13905]: https://github.com/home-assistant/home-assistant/pull/13905 [#13906]: https://github.com/home-assistant/home-assistant/pull/13906 [#13908]: https://github.com/home-assistant/home-assistant/pull/13908 [#13915]: https://github.com/home-assistant/home-assistant/pull/13915 [#13917]: https://github.com/home-assistant/home-assistant/pull/13917 [#13918]: https://github.com/home-assistant/home-assistant/pull/13918 [#13920]: https://github.com/home-assistant/home-assistant/pull/13920 [#13921]: https://github.com/home-assistant/home-assistant/pull/13921 [#13929]: https://github.com/home-assistant/home-assistant/pull/13929 [#13934]: https://github.com/home-assistant/home-assistant/pull/13934 [#13935]: https://github.com/home-assistant/home-assistant/pull/13935 [#13937]: https://github.com/home-assistant/home-assistant/pull/13937 [#13938]: https://github.com/home-assistant/home-assistant/pull/13938 [#13940]: https://github.com/home-assistant/home-assistant/pull/13940 [#13942]: https://github.com/home-assistant/home-assistant/pull/13942 [#13943]: https://github.com/home-assistant/home-assistant/pull/13943 [#13946]: https://github.com/home-assistant/home-assistant/pull/13946 [#13948]: https://github.com/home-assistant/home-assistant/pull/13948 [#13958]: https://github.com/home-assistant/home-assistant/pull/13958 [#13960]: https://github.com/home-assistant/home-assistant/pull/13960 [#13970]: https://github.com/home-assistant/home-assistant/pull/13970 [#13974]: https://github.com/home-assistant/home-assistant/pull/13974 [#13980]: https://github.com/home-assistant/home-assistant/pull/13980 [#13982]: https://github.com/home-assistant/home-assistant/pull/13982 [#13986]: https://github.com/home-assistant/home-assistant/pull/13986 [#13996]: https://github.com/home-assistant/home-assistant/pull/13996 [#14003]: https://github.com/home-assistant/home-assistant/pull/14003 [#14005]: https://github.com/home-assistant/home-assistant/pull/14005 [#14006]: https://github.com/home-assistant/home-assistant/pull/14006 [#14008]: https://github.com/home-assistant/home-assistant/pull/14008 [#14010]: https://github.com/home-assistant/home-assistant/pull/14010 [#14013]: https://github.com/home-assistant/home-assistant/pull/14013 [#14019]: https://github.com/home-assistant/home-assistant/pull/14019 [#14025]: https://github.com/home-assistant/home-assistant/pull/14025 [#14027]: https://github.com/home-assistant/home-assistant/pull/14027 [#14041]: https://github.com/home-assistant/home-assistant/pull/14041 [#14051]: https://github.com/home-assistant/home-assistant/pull/14051 [#14074]: https://github.com/home-assistant/home-assistant/pull/14074 [#14080]: https://github.com/home-assistant/home-assistant/pull/14080 [#14097]: https://github.com/home-assistant/home-assistant/pull/14097 [@B1tMaster]: https://github.com/B1tMaster [@ChristianKuehnel]: https://github.com/ChristianKuehnel [@Danielhiversen]: https://github.com/Danielhiversen [@GotoCode]: https://github.com/GotoCode [@Juggels]: https://github.com/Juggels [@KJonline]: https://github.com/KJonline [@Kane610]: https://github.com/Kane610 [@Kirchoff]: https://github.com/Kirchoff [@Marco98]: https://github.com/Marco98 [@MisterWil]: https://github.com/MisterWil [@NovapaX]: https://github.com/NovapaX [@OttoWinter]: https://github.com/OttoWinter [@Paxy]: https://github.com/Paxy [@Shou]: https://github.com/Shou [@TheCellMC]: https://github.com/TheCellMC [@Yonsm]: https://github.com/Yonsm [@aav7fl]: https://github.com/aav7fl [@andersonshatch]: https://github.com/andersonshatch [@armills]: https://github.com/armills [@balloob]: https://github.com/balloob [@cdce8p]: https://github.com/cdce8p [@cgtobi]: https://github.com/cgtobi [@citruz]: https://github.com/citruz [@left4taco]: https://github.com/left4taco [@danielperna84]: https://github.com/danielperna84 [@dersger]: https://github.com/dersger [@dgomes]: https://github.com/dgomes [@dlbroadfoot]: https://github.com/dlbroadfoot [@escoand]: https://github.com/escoand [@fabaff]: https://github.com/fabaff [@geekofweek]: https://github.com/geekofweek [@gerard33]: https://github.com/gerard33 [@hmn]: https://github.com/hmn [@hthiery]: https://github.com/hthiery [@karlkar]: https://github.com/karlkar [@kellerza]: https://github.com/kellerza [@koolsb]: https://github.com/koolsb [@marthoc]: https://github.com/marthoc [@meauxt]: https://github.com/meauxt [@michaelkuty]: https://github.com/michaelkuty [@mjg59]: https://github.com/mjg59 [@molobrakos]: https://github.com/molobrakos [@nickw444]: https://github.com/nickw444 [@no2chem]: https://github.com/no2chem [@pascalhahn]: https://github.com/pascalhahn [@philk]: https://github.com/philk [@pvizeli]: https://github.com/pvizeli [@rcloran]: https://github.com/rcloran [@reefab]: https://github.com/reefab [@robmarkcole]: https://github.com/robmarkcole [@rohankapoorcom]: https://github.com/rohankapoorcom [@schmittx]: https://github.com/schmittx [@shred86]: https://github.com/shred86 [@stephanerosi]: https://github.com/stephanerosi [@swilson]: https://github.com/swilson [@syssi]: https://github.com/syssi [@thelittlefireman]: https://github.com/thelittlefireman [@thrawnarn]: https://github.com/thrawnarn [@titilambert]: https://github.com/titilambert [@tobygray]: https://github.com/tobygray [@tschmidty69]: https://github.com/tschmidty69 [@veleek]: https://github.com/veleek [@viorels]: https://github.com/viorels [@wiuwiu]: https://github.com/wiuwiu [@asafbiton96]: https://github.com/asafbiton96 [abode docs]: /integrations/abode/ [alexa docs]: /integrations/alexa/ [binary_sensor.bmw_connected_drive docs]: /integrations/bmw_connected_drive [binary_sensor.hive docs]: /integrations/hive#binary-传感器 [binary_sensor.maxcube docs]: /integrations/maxcube [binary_sensor.qwikswitch docs]: /integrations/qwikswitch [bmw_connected_drive docs]: /integrations/bmw_connected_drive/ [日历.google docs]: /integrations/日历.google/ [日历.todoist docs]: /integrations/todoist [温控.fritzbox docs]: /integrations/fritzbox [温控.hive docs]: /integrations/hive#温控 [温控.honeywell docs]: /integrations/honeywell [温控.maxcube docs]: /integrations/maxcube [温控.modbus docs]: /integrations/温控.modbus/ [config docs]: /integrations/config/ [遮盖.opengarage docs]: /integrations/opengarage [遮盖.tahoma docs]: /integrations/tahoma [deconz docs]: /integrations/deconz/ [device_tracker docs]: /integrations/device_tracker/ [ecobee docs]: /integrations/ecobee/ [eufy docs]: /integrations/eufy/ [风扇.xiaomi_miio docs]: /integrations/风扇.xiaomi_miio/ [fritzbox docs]: /integrations/fritzbox/ [google docs]: /integrations/google_translate [hdmi_cec docs]: /integrations/hdmi_cec/ [hive docs]: /integrations/hive/ [homekit docs]: /integrations/homekit/ [homekit_controller docs]: /integrations/homekit_controller/ [homematic docs]: /integrations/homematic/ [hue docs]: /integrations/hue/ [ihc docs]: /integrations/ihc/ [灯光 docs]: /integrations/灯光/ [灯光.abode docs]: /integrations/abode#灯光 [灯光.aurora docs]: /integrations/灯光.aurora/ [灯光.eufy docs]: /integrations/eufy [灯光.hive docs]: /integrations/hive#灯光 [灯光.homekit_controller docs]: /integrations/homekit_controller [灯光.hue docs]: /integrations/hue [灯光.yeelight docs]: /integrations/yeelight [门锁.bmw_connected_drive docs]: /integrations/bmw_connected_drive [lutron_caseta docs]: /integrations/lutron_caseta/ [maxcube docs]: /integrations/maxcube/ [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.blackbird docs]: /integrations/blackbird [媒体播放器.bluesound docs]: /integrations/bluesound [媒体播放器.cast docs]: /integrations/cast [媒体播放器.kodi docs]: /integrations/kodi [媒体播放器.mediaroom docs]: /integrations/mediaroom [媒体播放器.mpd docs]: /integrations/mpd [媒体播放器.onkyo docs]: /integrations/onkyo [媒体播放器.squeezebox docs]: /integrations/squeezebox [媒体播放器.webostv docs]: /integrations/webostv#media-player [通知 docs]: /integrations/通知/ [通知.facebook docs]: /integrations/facebook [prometheus docs]: /integrations/prometheus/ [qwikswitch docs]: /integrations/qwikswitch/ [传感器 docs]: /integrations/传感器/ [传感器.alpha_vantage docs]: /integrations/alpha_vantage [传感器.bmw_connected_drive docs]: /integrations/bmw_connected_drive [传感器.broadlink docs]: /integrations/broadlink#传感器 [传感器.deconz docs]: /integrations/deconz#传感器 [传感器.ebox docs]: /integrations/ebox [传感器.ecobee docs]: /integrations/ecobee [传感器.eddystone_temperature docs]: /integrations/eddystone_temperature [传感器.filter docs]: /integrations/filter [传感器.folder docs]: /integrations/folder [传感器.foobot docs]: /integrations/foobot [传感器.fritzbox_netmonitor docs]: /integrations/fritzbox#sensor_netmonitor/ [传感器.hive docs]: /integrations/hive#传感器 [传感器.linux_battery docs]: /integrations/linux_battery [传感器.miflora docs]: /integrations/miflora [传感器.MQTT docs]: /integrations/传感器.MQTT/ [传感器.nest docs]: /integrations/nest#传感器 [传感器.nut docs]: /integrations/nut [传感器.qwikswitch docs]: /integrations/qwikswitch [传感器.sht31 docs]: /integrations/sht31 [传感器.sigfox docs]: /integrations/sigfox [传感器.smappee docs]: /integrations/sma#sensorsppee/ [传感器.sql docs]: /integrations/sql [传感器.tibber docs]: /integrations/tibber#传感器 [传感器.trafikverket_weatherstation docs]: /integrations/trafikverket_weatherstation [传感器.upnp docs]: /integrations/upnp [传感器.uscis docs]: /integrations/uscis [skybell docs]: /integrations/skybell/ [smappee docs]: /integrations/smappee/ [snips docs]: /integrations/snips/ [开关.broadlink docs]: /integrations/broadlink#开关 [开关.edimax docs]: /integrations/edimax [开关.eufy docs]: /integrations/eufy [开关.fritzbox docs]: /integrations/fritzbox [开关.hive docs]: /integrations/hive#开关 [开关.vesync docs]: /integrations/vesync#开关 [tts docs]: /integrations/tts/ [upnp docs]: /integrations/upnp/ [吸尘器 docs]: /integrations/吸尘器/ [吸尘器.dyson docs]: /integrations/dyson#吸尘器 [吸尘器.neato docs]: /integrations/neato#吸尘器 [吸尘器.roomba docs]: /integrations/roomba [吸尘器.xiaomi_miio docs]: /integrations/吸尘器.xiaomi_miio/ [zha docs]: /integrations/zha/ [#14108]: https://github.com/home-assistant/home-assistant/pull/14108 [#14113]: https://github.com/home-assistant/home-assistant/pull/14113 [#14154]: https://github.com/home-assistant/home-assistant/pull/14154 [#14160]: https://github.com/home-assistant/home-assistant/pull/14160 [#14163]: https://github.com/home-assistant/home-assistant/pull/14163 [#14181]: https://github.com/home-assistant/home-assistant/pull/14181 [#14190]: https://github.com/home-assistant/home-assistant/pull/14190 [#14196]: https://github.com/home-assistant/home-assistant/pull/14196 [#14156]: https://github.com/home-assistant/home-assistant/pull/14156 [@OttoWinter]: https://github.com/OttoWinter [@amelchio]: https://github.com/amelchio [@balloob]: https://github.com/balloob [@cdce8p]: https://github.com/cdce8p [@mjg59]: https://github.com/mjg59 [google_assistant docs]: /integrations/google_assistant/ [homekit docs]: /integrations/homekit/ [homekit_controller docs]: /integrations/homekit_controller/ [灯光.hue docs]: /integrations/hue [灯光.tplink docs]: /integrations/tplink [媒体播放器.cast docs]: /integrations/cast --- url: /home-assistant/blog/2018-05-11-release-69.md --- # 0.69:Matrix 聊天机器人、PostNL、Social Blade、小米米家传感器 这次我们在 PyCon 现场,没太多时间写长篇开场白!感谢 [@amelchio],Hue 和 Wink 的颜色问题修复了一些。用户系统的初步基础也已经落地,但离可用还很远,我们会继续改进。Home Assistant Cloud 的 Google Assistant 现在支持房间提示,这样在你关联账号时,Google Assistant 会把设备放到正确的分组里。 ## 新平台 * 新增小米米家蓝牙温湿度传感器支持 ([@ratcashdev] - [#13955]) ([传感器.mitemp\_bt docs][传感器.mitemp_bt docs]) (new-platform) * 将 RainMachine 迁移到组件/Hub 模型 ([@bachya] - [#14085]) ([rainmachine docs]) ([开关.rainmachine docs]) (breaking change) (new-platform) * 新增 Social Blade 传感器 ([@meauxt] - [#14060]) ([传感器.socialblade docs]) ([传感器.uscis docs]) (new-platform) * 新增 PostNL 传感器(荷兰邮政服务) ([@iMicknl] - [#12366]) (new-platform) * 新增模板风扇 ([@giangvo] - [#12027]) ([风扇.模板 docs]) (new-platform) * Matrix Chatbot ([@tinloaf] - [#13355]) ([matrix docs]) ([通知 docs]) (breaking change) (new-platform) ## 发布 0.69.1 - 5 月 12 日 * Fix loading of Matrix chatbot ([@tinloaf] - \[#14346]) ([matrix docs]) ## 如果你需要帮助... ...欢迎随时访问我们非常活跃的 [论坛](https://community.home-assistant.io/),或加入我们的 [聊天频道](https://discord.gg/c5DvZ4e)。虽然发布说明开放评论,但我们更推荐你使用前面的沟通渠道。谢谢。 ## 报告问题 如果你遇到了此版本引入的问题,请在我们的 [问题追踪器](https://github.com/home-assistant/home-assistant/issues) 中提交报告。请务必填写问题模板中的所有字段。 ## 不向后兼容的变更 * Pollen.com:为前三种过敏原新增了属性。这导致属性名 `primary_allergen_genus`、`primary_allergen_name` 和 `primary_allergen_type` 现在会带上 `_1` 后缀。([@bachya] - [#14018]) ([传感器.pollen docs]) (breaking change) * 为 Sonos 设备新增分组信息属性。`media_player.sonos` 的 `is_coordinator` 属性已移除,请改用新的 `sonos_group` 属性(列出该组全部成员,协调器排在第一位)。([@amelchio] - [#13553]) ([媒体播放器.sonos docs]) (breaking change) * 以异步方式重新实现 HomematicIP Cloud。配置结构有变更:`name` 变为可选且不能为空;移除了传感器的状态属性;也移除了用于显示所有已发现组件状态的额外传感器。([@mxworm] - [#13468]) ([homematicip\_cloud docs][homematicip_cloud docs]) ([传感器.homematicip\_cloud docs][传感器.homematicip_cloud docs]) (breaking change) * System Log:触发事件现在改为可选 ([@balloob] - [#14102]) ([system\_log docs][system_log docs]) (breaking change) * Converts RainMachine to hub model (part 2) ([@bachya] - [#14225]) ([rainmachine docs]) ([开关.rainmachine docs]) (breaking change) * Homekit: Changed device\_class requirement Humidity 传感器 ([@cdce8p] - [#14277]) ([homekit docs]) (breaking change) * 为保持一致,传感器单位 `lux` 已改为 `lx`。这影响以下传感器平台:homematic、isy994、miflora、mysensors、tahoma、vera 和模板传感器。若要为 HomeKit 组件添加光照传感器,`device_class` 现在需要改为 `illuminance`。([@cdce8p] - [#14282]) ([传感器 docs]) (breaking change) * Matrix 通知平台现在依赖新的 Matrix 组件。如何配置 Matrix 组件,请参阅文档。([@tinloaf] - [#13355]) ([matrix docs]) ([通知 docs]) (breaking change) (new-platform) * Move RainMachine to component/hub model and remove 遥控器 API. ([@bachya] - [#14085] - [#14225]) ([rainmachine docs]) ([开关.rainmachine docs]) (breaking change) (new-platform) ```yaml # New rainmachine config rainmachine: ip_address: 192.168.1.100 password: abc123 switches: zone_run_time: 240 ``` ## Beta 修复 * Add missing '传感器' to ABODE\_PLATFORMS ([@jloutsenhizer] - [#14313]) ([abode docs]) (beta fix) * Add debounce to move\_cover ([@cdce8p] - [#14314]) ([homekit docs]) (beta fix) * Fix module names for custom components ([@balloob] - [#14317]) (beta fix) * Revert custom component loading logic ([@balloob] - [#14327]) (beta fix) * fix(hbmqtt): partial packets breaking hbmqtt ([@graffic] - [#14329]) ([MQTT docs]) (beta fix) * Ignore more loading 错误 ([@balloob] - [#14331]) (beta fix) * Ignore NaN values for influxdb ([@amelchio] - [#14347]) ([influxdb docs]) (beta fix) ## 所有变更 * Pollen.com: Added 属性 on top 3 allergens ([@bachya] - [#14018]) ([传感器.pollen docs]) (breaking change) * Expose the 条件 code on 条件 传感器 ([@maddox] - [#14011]) * 升级 rfxtrx lib, dimming support for Lighting3 ([@Danielhiversen] - [#14026]) ([rfxtrx docs]) * Add Accuracy to Google Location Sharing ([@rdbahm] - [#14039]) ([device\_tracker docs][device_tracker docs]) * bump gogogate2 版本 ([@dlbroadfoot] - [#14044]) ([遮盖.gogogate2 docs]) * device\_tracker.ubus: catch ConnectionError ([@stintel] - [#14045]) ([device\_tracker docs][device_tracker docs]) * Show a 通知 when a config entry is discovered ([@balloob] - [#14022]) * deCONZ use forward entry 设置 ([@Kane610] - [#13990]) ([binary\_sensor docs][binary_sensor docs]) ([deconz docs]) ([场景 docs]) ([传感器 docs]) ([binary\_sensor.deconz docs][binary_sensor.deconz docs]) ([灯光.deconz docs]) ([场景.deconz docs]) ([传感器.deconz docs]) * Bump pyEight 版本 to 更新 API & reduce connection issues ([@mezz64] - [#14058]) ([eight\_sleep docs][eight_sleep docs]) * Bump locationsharinglib to 1.2.2 ([@thelittlefireman] - [#14070]) ([device\_tracker docs][device_tracker docs]) * Remove excessive debugging in webostv module ([@stephanerosi] - [#14056]) ([媒体播放器.webostv docs]) * Support new Xiaomi Aqara 设备 model names and LAN protocol 2.0 ([@ileler] - [#13540]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) ([binary\_sensor.xiaomi\_aqara docs][binary_sensor.xiaomi_aqara docs]) ([灯光.xiaomi\_aqara docs][灯光.xiaomi_aqara docs]) ([传感器.xiaomi\_aqara docs][传感器.xiaomi_aqara docs]) ([开关.xiaomi\_aqara docs][开关.xiaomi_aqara docs]) * Add 设备 to Tahoma ([@thijsdejong] - [#14075]) ([tahoma docs]) ([遮盖.tahoma docs]) ([传感器.tahoma docs]) * Modify 天气 components for "new" 前端 卡片 ([@c727] - [#14076]) ([天气.buienradar docs]) ([天气.darksky docs]) ([天气.openweathermap docs]) * Add Sonos 设备 属性 with grouping information ([@amelchio] - [#13553]) ([媒体播放器.sonos docs]) (breaking change) * Re-implement HomematicIP cloud to async ([@mxworm] - [#13468]) ([homematicip\_cloud docs][homematicip_cloud docs]) ([传感器.homematicip\_cloud docs][传感器.homematicip_cloud docs]) (breaking change) * 更新 pyhomematic to 0.1.42 ([@danielperna84] - [#14095]) ([homematic docs]) * Adds 更新 file\_path 服务 to local\_file 摄像头 ([@robmarkcole] - [#13976]) ([摄像头.local\_file docs][摄像头.local_file docs]) * 区域 component config entry support ([@Kane610] - [#14059]) ([区域 docs]) * Improve MQTT topic validation ([@OttoWinter] - [#14099]) ([MQTT docs]) * Fix the optional friendly name of the Yeelight (Closes: #14088) ([@syssi] - [#14110]) ([灯光.yeelight docs]) * 更新 QNAP lib to 0.2.6; handle null temps gracefully ([@colinodell] - [#14117]) ([传感器.qnap docs]) * Support Xiaomi Mijia 蓝牙 Wireless Temperature and Humidity 传感器 ([@ratcashdev] - [#13955]) ([传感器.mitemp\_bt docs][传感器.mitemp_bt docs]) (new-platform) * 升级 colorlog to 3.1.4 ([@fabaff] - [#14132]) * Move RainMachine to component/hub model ([@bachya] - [#14085]) ([rainmachine docs]) ([开关.rainmachine docs]) (breaking change) (new-platform) * Add support for 灯光 传感器 with 'lx' unit to HomeKit ([@bieniu] - [#14131]) ([homekit docs]) * 升级 restrictedpython to 4.0b3 ([@fabaff] - [#14140]) ([python\_script docs][python_script docs]) * Logitech Pop support for emulated\_hue component ([@dgraye] - [#12833]) ([emulated\_hue docs][emulated_hue docs]) * Bump pyvizio to 0.0.3 ([@cgarwood] - [#14147]) ([媒体播放器.vizio docs]) * System 日志: make firing event optional ([@balloob] - [#14102]) ([system\_log docs][system_log docs]) (breaking change) * 升级 pylast to 2.2.0 ([@fabaff] - [#14139]) ([传感器.lastfm docs]) * 升级 sqlalchemy to 1.2.7 ([@fabaff] - [#14138]) * 升级 tapsaff to 0.2.0 ([@fabaff] - [#14137]) ([binary\_sensor.tapsaff docs][binary_sensor.tapsaff docs]) * 升级 python-telegram-bot to 10.0.2 ([@fabaff] - [#14144]) * 升级 youtube\_dl to 2018.04.25 ([@fabaff] - [#14136]) ([media\_extractor docs][media_extractor docs]) * Clean up HomeKit accessory information characteristics ([@schmittx] - [#14114]) ([homekit docs]) * 升级 psutil to 5.4.5 ([@fabaff] - [#14135]) * Fixed datetime values ([@gives1976] - [#14153]) ([传感器.sql docs]) * deluge-components-更新 ([@engrbm87] - [#14016]) ([传感器.deluge docs]) ([开关.deluge docs]) * 灯光 mqtt\_json: Add HS color support ([@OttoWinter] - [#14029]) ([灯光.mqtt\_json docs][灯光.mqtt_json docs]) * Convert more files to async/await syntax ([@OttoWinter] - [#14142]) * Disable eliqonline requirement ([@balloob] - [#14156]) ([传感器.eliqonline docs]) (breaking change) * deCONZ allow unloading of config entry ([@Kane610] - [#14115]) ([binary\_sensor docs][binary_sensor docs]) ([deconz docs]) ([场景 docs]) ([传感器 docs]) * 升级 netdisco to 1.4.0 ([@fabaff] - [#14152]) * Add precipitation to OpenWeatherMap forecast ([@escoand] - [#13971]) ([天气.openweathermap docs]) * Allow transitioning to colour temp for tradfri ([@Hate-Usernames] - [#14157]) * Added update\_interval to maxcube ([@dingusdk] - [#14143]) ([maxcube docs]) * zha: Support 遥控器/按钮 ([@rcloran] - [#12528]) ([zha docs]) ([binary\_sensor.zha docs][binary_sensor.zha docs]) * 升级 numpy to 1.14.3 ([@fabaff] - [#14187]) ([binary\_sensor.trend docs][binary_sensor.trend docs]) ([image\_processing.opencv docs][image_processing.opencv docs]) * Updating darksky default 更新 interval to 5 mins ([@msubra] - [#14195]) ([传感器.darksky docs]) * Fix TypeError on round(self.humidity) (fixes #13116) ([@mvn23] - [#14174]) ([天气 docs]) * Add 房间 hint support to Google Assistant cloud ([@balloob] - [#14180]) * 更新 CODEOWNERS ([@pschmitt] - [#14214]) * Fixes #14169 (升级 pyupnp-async to 0.1.0.2) ([@dgomes] - [#14210]) ([upnp docs]) * zha: Clean up binary\_sensor listener registration/状态 updates ([@rcloran] - [#14197]) * HomematicIP cloud: Add logic to check accesspoint connection 状态 ([@sander76] - [#14203]) ([homematicip\_cloud docs][homematicip_cloud docs]) * Foundation for 用户 ([@balloob] - [#13968]) ([http docs]) (new-platform) * Allow easy extension of websocket API ([@balloob] - [#14186]) ([前端 docs]) ([websocket\_api docs][websocket_api docs]) * Change the divisor for total consumption output ([@CM000n] - [#14215]) ([开关.fritzbox docs]) * 升级 mypy to 0.590 ([@fabaff] - [#14207]) * 模板 传感器 add device\_class support ([@OttoWinter] - [#14034]) ([传感器.模板 docs]) * Add more parameters for DSMR 传感器 ([@rubenvandeven] - [#13967]) ([传感器.dsmr docs]) * Support setting explicit mute value for Panasonic Viera TV ([@blackwind] - [#13954]) ([媒体播放器.panasonic\_viera docs][媒体播放器.panasonic_viera docs]) * Allow to set a desired 更新 interval for camera\_proxy\_stream view ([@NovapaX] - [#13350]) ([摄像头 docs]) * panasonic\_viera: Provide unique\_id from SSDP UDN, if available ([@scop] - [#13541]) ([媒体播放器.panasonic\_viera docs][媒体播放器.panasonic_viera docs]) * Custom component loading cleanup ([@balloob] - [#14211]) (breaking change) * Buienradar improvements: continuous 传感器 and unique ID's ([@corneyl] - [#13249]) ([传感器.buienradar docs]) * add volumio discovery ([@escoand] - [#14220]) ([媒体播放器.volumio docs]) * Converts RainMachine to hub model (part 2) ([@bachya] - [#14225]) ([rainmachine docs]) ([开关.rainmachine docs]) (breaking change) * Add MQTT 传感器 device\_class ([@OttoWinter] - [#14033]) ([传感器.MQTT docs]) * Allow independent control of white level on flux\_led component ([@oblogic7] - [#13985]) ([灯光.flux\_led docs][灯光.flux_led docs]) * Add Social Blade 传感器 ([@meauxt] - [#14060]) ([传感器.socialblade docs]) ([传感器.uscis docs]) (new-platform) * UPnP code cleanup ([@dgomes] - [#14235]) ([upnp docs]) ([传感器.upnp docs]) * Improve config schema of the blackbird component ([@syssi] - [#14007]) ([媒体播放器.blackbird docs]) * Fix Hue color 状态 for missing xy ([@amelchio] - [#14230]) ([灯光.hue docs]) * Add support for tracking 设备 on Netgear access points ([@MatMaul] - [#13331]) ([device\_tracker docs][device_tracker docs]) * WUnderground unique ids ([@OttoWinter] - [#13311]) ([传感器.wunderground docs]) * Add PostNL 传感器 (Dutch Postal 服务) ([@iMicknl] - [#12366]) (new-platform) * python\_openzwave 更新 config 服务 ([@perosb] - [#12060]) ([zwave docs]) * Add unique\_id to zwave node 实体 ([@andrey-git] - [#14201]) ([zwave docs]) * Add prereqs for HomeKit Controller ([@marthoc] - [#14172]) * Restores 开关 状态, case the 开关 is optimistic ([@dgomes] - [#14151]) ([开关.MQTT docs]) * Issue/add 模板 风扇 ([@giangvo] - [#12027]) ([风扇.模板 docs]) (new-platform) * HomeKit - 温控: power 状态 on/off support ([@roiff] - [#14082]) ([homekit docs]) * Demo 传感器 - Added device\_class support ([@cdce8p] - [#14269]) * Re-enable eliqonline requirement ([@molobrakos] - [#14265]) ([传感器.eliqonline docs]) * Add fetching 摄像头 thumbnails over websocket ([@balloob] - [#14231]) ([摄像头 docs]) ([前端 docs]) ([image\_processing docs][image_processing docs]) ([microsoft\_face docs][microsoft_face docs]) ([websocket\_api docs][websocket_api docs]) * Allow fetching media player 遮盖 via websocket connection ([@balloob] - [#14233]) ([媒体播放器 docs]) * Fix ZWave 灯光 brightness ([@cdce8p] - [#14261]) ([灯光.zwave docs]) * Color fixes for Wink 灯光 ([@amelchio] - [#14263]) ([灯光.wink docs]) * fix check config not working after #14211 ([@fanthos] - [#14259]) * Issue 模板 Fix CRLF ([@OttoWinter] - [#14283]) * 升级 attrs to 18.1.0 ([@fabaff] - [#14281]) * 更新 HAP-python to 2.0.0 ([@cdce8p] - [#14278]) ([homekit docs]) * 升级 holidays to 0.9.5 ([@fabaff] - [#14274]) ([binary\_sensor.workday docs][binary_sensor.workday docs]) * Homekit: Changed device\_class requirement Humidity 传感器 ([@cdce8p] - [#14277]) ([homekit docs]) (breaking change) * HomeKit: Support triggered 状态 for alarm\_control\_panel ([@schmittx] - [#14285]) ([homekit docs]) * Fix filter 传感器 missing window\_size argument ([@dgomes] - [#14252]) ([传感器.filter docs]) * 升级 astral to 1.6.1 ([@fabaff] - [#14297]) * BOM 天气 throttle fix ([@nickw444] - [#14234]) * Publish 属性 unconditionally ([@blackwind] - [#14179]) ([mqtt\_statestream docs][mqtt_statestream docs]) * 传感器 设备 classes ([@cdce8p] - [#14282]) ([传感器 docs]) (breaking change) * Matrix Chatbot ([@tinloaf] - [#13355]) ([matrix docs]) ([通知 docs]) (breaking change) (new-platform) * deCONZ add new 设备 without 重启 ([@Kane610] - [#14221]) ([deconz docs]) ([binary\_sensor.deconz docs][binary_sensor.deconz docs]) ([灯光.deconz docs]) ([传感器.deconz docs]) * Add alarmdotcom 传感器 status ([@jnewland] - [#14254]) * Add domain to labels and count 状态 changes to Prometheus ([@jnewland] - [#14253]) ([prometheus docs]) * Add support for max\_volume ([@relvacode] - [#13822]) ([媒体播放器.onkyo docs]) * Refactor ImageProcessingFaceEntity ([@robmarkcole] - [#14296]) ([image\_processing docs][image_processing docs]) ([image\_processing.dlib\_face\_detect docs][image_processing.dlib_face_detect docs]) ([image\_processing.dlib\_face\_identify docs][image_processing.dlib_face_identify docs]) ([image\_processing.microsoft\_face\_detect docs][image_processing.microsoft_face_detect docs]) ([image\_processing.microsoft\_face\_identify docs][image_processing.microsoft_face_identify docs]) * Onkyo: SUPPORT\_VOLUME\_STEP ([@rsmeral] - [#14299]) ([媒体播放器.onkyo docs]) * Add All-Linking capabilities ([@teharris1] - [#14065]) ([insteon\_plm docs][insteon_plm docs]) ([binary\_sensor.insteon\_plm docs][binary_sensor.insteon_plm docs]) ([风扇.insteon\_plm docs][风扇.insteon_plm docs]) ([灯光.insteon\_plm docs][灯光.insteon_plm docs]) ([传感器.insteon\_plm docs][传感器.insteon_plm docs]) ([开关.insteon\_plm docs][开关.insteon_plm docs]) * Add missing '传感器' to ABODE\_PLATFORMS ([@jloutsenhizer] - [#14313]) ([abode docs]) (beta fix) * Add debounce to move\_cover ([@cdce8p] - [#14314]) ([homekit docs]) (beta fix) * Fix module names for custom components ([@balloob] - [#14317]) (beta fix) * Revert custom component loading logic ([@balloob] - [#14327]) (beta fix) * fix(hbmqtt): partial packets breaking hbmqtt ([@graffic] - [#14329]) ([MQTT docs]) (beta fix) * Ignore more loading 错误 ([@balloob] - [#14331]) (beta fix) * Ignore NaN values for influxdb ([@amelchio] - [#14347]) ([influxdb docs]) (beta fix) [#12027]: https://github.com/home-assistant/home-assistant/pull/12027 [#12060]: https://github.com/home-assistant/home-assistant/pull/12060 [#12366]: https://github.com/home-assistant/home-assistant/pull/12366 [#12528]: https://github.com/home-assistant/home-assistant/pull/12528 [#12833]: https://github.com/home-assistant/home-assistant/pull/12833 [#13249]: https://github.com/home-assistant/home-assistant/pull/13249 [#13311]: https://github.com/home-assistant/home-assistant/pull/13311 [#13331]: https://github.com/home-assistant/home-assistant/pull/13331 [#13350]: https://github.com/home-assistant/home-assistant/pull/13350 [#13355]: https://github.com/home-assistant/home-assistant/pull/13355 [#13468]: https://github.com/home-assistant/home-assistant/pull/13468 [#13540]: https://github.com/home-assistant/home-assistant/pull/13540 [#13541]: https://github.com/home-assistant/home-assistant/pull/13541 [#13553]: https://github.com/home-assistant/home-assistant/pull/13553 [#13822]: https://github.com/home-assistant/home-assistant/pull/13822 [#13954]: https://github.com/home-assistant/home-assistant/pull/13954 [#13955]: https://github.com/home-assistant/home-assistant/pull/13955 [#13967]: https://github.com/home-assistant/home-assistant/pull/13967 [#13968]: https://github.com/home-assistant/home-assistant/pull/13968 [#13971]: https://github.com/home-assistant/home-assistant/pull/13971 [#13976]: https://github.com/home-assistant/home-assistant/pull/13976 [#13985]: https://github.com/home-assistant/home-assistant/pull/13985 [#13990]: https://github.com/home-assistant/home-assistant/pull/13990 [#14007]: https://github.com/home-assistant/home-assistant/pull/14007 [#14011]: https://github.com/home-assistant/home-assistant/pull/14011 [#14016]: https://github.com/home-assistant/home-assistant/pull/14016 [#14018]: https://github.com/home-assistant/home-assistant/pull/14018 [#14022]: https://github.com/home-assistant/home-assistant/pull/14022 [#14026]: https://github.com/home-assistant/home-assistant/pull/14026 [#14029]: https://github.com/home-assistant/home-assistant/pull/14029 [#14033]: https://github.com/home-assistant/home-assistant/pull/14033 [#14034]: https://github.com/home-assistant/home-assistant/pull/14034 [#14039]: https://github.com/home-assistant/home-assistant/pull/14039 [#14044]: https://github.com/home-assistant/home-assistant/pull/14044 [#14045]: https://github.com/home-assistant/home-assistant/pull/14045 [#14056]: https://github.com/home-assistant/home-assistant/pull/14056 [#14058]: https://github.com/home-assistant/home-assistant/pull/14058 [#14059]: https://github.com/home-assistant/home-assistant/pull/14059 [#14060]: https://github.com/home-assistant/home-assistant/pull/14060 [#14065]: https://github.com/home-assistant/home-assistant/pull/14065 [#14067]: https://github.com/home-assistant/home-assistant/pull/14067 [#14070]: https://github.com/home-assistant/home-assistant/pull/14070 [#14075]: https://github.com/home-assistant/home-assistant/pull/14075 [#14076]: https://github.com/home-assistant/home-assistant/pull/14076 [#14082]: https://github.com/home-assistant/home-assistant/pull/14082 [#14085]: https://github.com/home-assistant/home-assistant/pull/14085 [#14095]: https://github.com/home-assistant/home-assistant/pull/14095 [#14099]: https://github.com/home-assistant/home-assistant/pull/14099 [#14102]: https://github.com/home-assistant/home-assistant/pull/14102 [#14110]: https://github.com/home-assistant/home-assistant/pull/14110 [#14114]: https://github.com/home-assistant/home-assistant/pull/14114 [#14115]: https://github.com/home-assistant/home-assistant/pull/14115 [#14117]: https://github.com/home-assistant/home-assistant/pull/14117 [#14131]: https://github.com/home-assistant/home-assistant/pull/14131 [#14132]: https://github.com/home-assistant/home-assistant/pull/14132 [#14135]: https://github.com/home-assistant/home-assistant/pull/14135 [#14136]: https://github.com/home-assistant/home-assistant/pull/14136 [#14137]: https://github.com/home-assistant/home-assistant/pull/14137 [#14138]: https://github.com/home-assistant/home-assistant/pull/14138 [#14139]: https://github.com/home-assistant/home-assistant/pull/14139 [#14140]: https://github.com/home-assistant/home-assistant/pull/14140 [#14142]: https://github.com/home-assistant/home-assistant/pull/14142 [#14143]: https://github.com/home-assistant/home-assistant/pull/14143 [#14144]: https://github.com/home-assistant/home-assistant/pull/14144 [#14147]: https://github.com/home-assistant/home-assistant/pull/14147 [#14151]: https://github.com/home-assistant/home-assistant/pull/14151 [#14152]: https://github.com/home-assistant/home-assistant/pull/14152 [#14153]: https://github.com/home-assistant/home-assistant/pull/14153 [#14156]: https://github.com/home-assistant/home-assistant/pull/14156 [#14157]: https://github.com/home-assistant/home-assistant/pull/14157 [#14172]: https://github.com/home-assistant/home-assistant/pull/14172 [#14174]: https://github.com/home-assistant/home-assistant/pull/14174 [#14179]: https://github.com/home-assistant/home-assistant/pull/14179 [#14180]: https://github.com/home-assistant/home-assistant/pull/14180 [#14186]: https://github.com/home-assistant/home-assistant/pull/14186 [#14187]: https://github.com/home-assistant/home-assistant/pull/14187 [#14195]: https://github.com/home-assistant/home-assistant/pull/14195 [#14197]: https://github.com/home-assistant/home-assistant/pull/14197 [#14201]: https://github.com/home-assistant/home-assistant/pull/14201 [#14203]: https://github.com/home-assistant/home-assistant/pull/14203 [#14207]: https://github.com/home-assistant/home-assistant/pull/14207 [#14210]: https://github.com/home-assistant/home-assistant/pull/14210 [#14211]: https://github.com/home-assistant/home-assistant/pull/14211 [#14214]: https://github.com/home-assistant/home-assistant/pull/14214 [#14215]: https://github.com/home-assistant/home-assistant/pull/14215 [#14220]: https://github.com/home-assistant/home-assistant/pull/14220 [#14221]: https://github.com/home-assistant/home-assistant/pull/14221 [#14225]: https://github.com/home-assistant/home-assistant/pull/14225 [#14230]: https://github.com/home-assistant/home-assistant/pull/14230 [#14231]: https://github.com/home-assistant/home-assistant/pull/14231 [#14233]: https://github.com/home-assistant/home-assistant/pull/14233 [#14234]: https://github.com/home-assistant/home-assistant/pull/14234 [#14235]: https://github.com/home-assistant/home-assistant/pull/14235 [#14252]: https://github.com/home-assistant/home-assistant/pull/14252 [#14253]: https://github.com/home-assistant/home-assistant/pull/14253 [#14254]: https://github.com/home-assistant/home-assistant/pull/14254 [#14259]: https://github.com/home-assistant/home-assistant/pull/14259 [#14261]: https://github.com/home-assistant/home-assistant/pull/14261 [#14263]: https://github.com/home-assistant/home-assistant/pull/14263 [#14265]: https://github.com/home-assistant/home-assistant/pull/14265 [#14269]: https://github.com/home-assistant/home-assistant/pull/14269 [#14274]: https://github.com/home-assistant/home-assistant/pull/14274 [#14277]: https://github.com/home-assistant/home-assistant/pull/14277 [#14278]: https://github.com/home-assistant/home-assistant/pull/14278 [#14281]: https://github.com/home-assistant/home-assistant/pull/14281 [#14282]: https://github.com/home-assistant/home-assistant/pull/14282 [#14283]: https://github.com/home-assistant/home-assistant/pull/14283 [#14285]: https://github.com/home-assistant/home-assistant/pull/14285 [#14296]: https://github.com/home-assistant/home-assistant/pull/14296 [#14297]: https://github.com/home-assistant/home-assistant/pull/14297 [#14299]: https://github.com/home-assistant/home-assistant/pull/14299 [#14313]: https://github.com/home-assistant/home-assistant/pull/14313 [#14314]: https://github.com/home-assistant/home-assistant/pull/14314 [#14317]: https://github.com/home-assistant/home-assistant/pull/14317 [#14327]: https://github.com/home-assistant/home-assistant/pull/14327 [#14329]: https://github.com/home-assistant/home-assistant/pull/14329 [#14331]: https://github.com/home-assistant/home-assistant/pull/14331 [#14347]: https://github.com/home-assistant/home-assistant/pull/14347 [#14381]: https://github.com/home-assistant/home-assistant/pull/14381 [#14108]: https://github.com/home-assistant/home-assistant/pull/14108 [@CM000n]: https://github.com/CM000n [@Danielhiversen]: https://github.com/Danielhiversen [@Hate-Usernames]: https://github.com/Hate-Usernames [@Kane610]: https://github.com/Kane610 [@MatMaul]: https://github.com/MatMaul [@NovapaX]: https://github.com/NovapaX [@OttoWinter]: https://github.com/OttoWinter [@amelchio]: https://github.com/amelchio [@andrey-git]: https://github.com/andrey-git [@bachya]: https://github.com/bachya [@thijsdejong]: https://github.com/thijsdejong [@balloob]: https://github.com/balloob [@bieniu]: https://github.com/bieniu [@blackwind]: https://github.com/blackwind [@c727]: https://github.com/c727 [@cdce8p]: https://github.com/cdce8p [@cgarwood]: https://github.com/cgarwood [@colinodell]: https://github.com/colinodell [@corneyl]: https://github.com/corneyl [@danielperna84]: https://github.com/danielperna84 [@dgomes]: https://github.com/dgomes [@dgraye]: https://github.com/dgraye [@dingusdk]: https://github.com/dingusdk [@dlbroadfoot]: https://github.com/dlbroadfoot [@engrbm87]: https://github.com/engrbm87 [@escoand]: https://github.com/escoand [@fabaff]: https://github.com/fabaff [@fanthos]: https://github.com/fanthos [@giangvo]: https://github.com/giangvo [@gives1976]: https://github.com/gives1976 [@graffic]: https://github.com/graffic [@iMicknl]: https://github.com/iMicknl [@ileler]: https://github.com/ileler [@jloutsenhizer]: https://github.com/jloutsenhizer [@jnewland]: https://github.com/jnewland [@maddox]: https://github.com/maddox [@marthoc]: https://github.com/marthoc [@masarliev]: https://github.com/masarliev [@meauxt]: https://github.com/meauxt [@mezz64]: https://github.com/mezz64 [@molobrakos]: https://github.com/molobrakos [@msubra]: https://github.com/msubra [@mvn23]: https://github.com/mvn23 [@mxworm]: https://github.com/mxworm [@nickw444]: https://github.com/nickw444 [@oblogic7]: https://github.com/oblogic7 [@perosb]: https://github.com/perosb [@pschmitt]: https://github.com/pschmitt [@ratcashdev]: https://github.com/ratcashdev [@rcloran]: https://github.com/rcloran [@rdbahm]: https://github.com/rdbahm [@relvacode]: https://github.com/relvacode [@robmarkcole]: https://github.com/robmarkcole [@roiff]: https://github.com/roiff [@rsmeral]: https://github.com/rsmeral [@rubenvandeven]: https://github.com/rubenvandeven [@sander76]: https://github.com/sander76 [@schmittx]: https://github.com/schmittx [@scop]: https://github.com/scop [@stephanerosi]: https://github.com/stephanerosi [@stintel]: https://github.com/stintel [@syssi]: https://github.com/syssi [@teharris1]: https://github.com/teharris1 [@thelittlefireman]: https://github.com/thelittlefireman [@tinloaf]: https://github.com/tinloaf [abode docs]: /integrations/abode/ [auth docs]: /integrations/auth/ [binary_sensor docs]: /integrations/binary_sensor/ [binary_sensor.deconz docs]: /integrations/deconz#binary-传感器 [binary_sensor.insteon_plm docs]: /integrations/insteon/ [binary_sensor.tapsaff docs]: /integrations/tapsaff [binary_sensor.trend docs]: /integrations/trend [binary_sensor.workday docs]: /integrations/workday [binary_sensor.xiaomi_aqara docs]: /integrations/binary_sensor.xiaomi_aqara/ [binary_sensor.zha docs]: /integrations/zha [摄像头 docs]: /integrations/摄像头/ [摄像头.local_file docs]: /integrations/local_file [遮盖.gogogate2 docs]: /integrations/gogogate2 [遮盖.tahoma docs]: /integrations/tahoma [deconz docs]: /integrations/deconz/ [device_tracker docs]: /integrations/device_tracker/ [eight_sleep docs]: /integrations/eight_sleep/ [emulated_hue docs]: /integrations/emulated_hue/ [风扇.insteon_plm docs]: /integrations/insteon/ [风扇.模板 docs]: /integrations/风扇.模板/ [前端 docs]: /integrations/frontend/ [homekit docs]: /integrations/homekit/ [homematic docs]: /integrations/homematic/ [homematicip_cloud docs]: /integrations/homematicip_cloud/ [http docs]: /integrations/http/ [image_processing docs]: /integrations/image_processing/ [image_processing.demo docs]: /integrations/image_processing.demo/ [image_processing.dlib_face_detect docs]: /integrations/dlib_face_detect [image_processing.dlib_face_identify docs]: /integrations/dlib_face_identify [image_processing.microsoft_face_detect docs]: /integrations/microsoft_face_detect [image_processing.microsoft_face_identify docs]: /integrations/microsoft_face_identify [image_processing.opencv docs]: /integrations/opencv [influxdb docs]: /integrations/influxdb/ [insteon_plm docs]: /integrations/insteon/ [灯光.deconz docs]: /integrations/deconz#灯光 [灯光.flux_led docs]: /integrations/flux_led [灯光.hue docs]: /integrations/hue [灯光.insteon_plm docs]: /integrations/insteon/ [灯光.mqtt_json docs]: /integrations/灯光.MQTT [灯光.wink docs]: /integrations/wink#灯光 [灯光.xiaomi_aqara docs]: /integrations/灯光.xiaomi_aqara/ [灯光.yeelight docs]: /integrations/yeelight [灯光.zwave docs]: /integrations/zwave [matrix docs]: /integrations/matrix/ [maxcube docs]: /integrations/maxcube/ [media_extractor docs]: /integrations/media_extractor/ [媒体播放器 docs]: /integrations/媒体播放器/ [媒体播放器.blackbird docs]: /integrations/blackbird [媒体播放器.onkyo docs]: /integrations/onkyo [媒体播放器.panasonic_viera docs]: /integrations/panasonic_viera [媒体播放器.sonos docs]: /integrations/sonos [媒体播放器.vizio docs]: /integrations/vizio [媒体播放器.volumio docs]: /integrations/volumio [媒体播放器.webostv docs]: /integrations/webostv#media-player [microsoft_face docs]: /integrations/microsoft_face/ [MQTT docs]: /integrations/MQTT/ [mqtt_statestream docs]: /integrations/mqtt_statestream/ [通知 docs]: /integrations/通知/ [prometheus docs]: /integrations/prometheus/ [python_script docs]: /integrations/python_script/ [rainmachine docs]: /integrations/rainmachine/ [rfxtrx docs]: /integrations/rfxtrx/ [场景 docs]: /integrations/场景/ [场景.deconz docs]: /integrations/deconz#场景 [传感器 docs]: /integrations/传感器/ [传感器.buienradar docs]: /integrations/传感器.buienradar/ [传感器.darksky docs]: /integrations/darksky [传感器.deconz docs]: /integrations/deconz#传感器 [传感器.deluge docs]: /integrations/deluge#传感器 [传感器.demo docs]: /integrations/传感器.demo/ [传感器.domain_expiry docs]: /integrations/传感器.domain_expiry/ [传感器.dsmr docs]: /integrations/dsmr [传感器.eliqonline docs]: /integrations/eliqonline [传感器.filter docs]: /integrations/filter [传感器.homematicip_cloud docs]: /integrations/homematicip_cloud/ [传感器.insteon_plm docs]: /integrations/insteon/ [传感器.lastfm docs]: /integrations/lastfm [传感器.mitemp_bt docs]: /integrations/mitemp_bt [传感器.MQTT docs]: /integrations/传感器.MQTT/ [传感器.pollen docs]: /integrations/iqvia [传感器.qnap docs]: /integrations/qnap [传感器.socialblade docs]: /integrations/socialblade [传感器.sql docs]: /integrations/sql [传感器.tahoma docs]: /integrations/tahoma [传感器.模板 docs]: /integrations/模板 [传感器.upnp docs]: /integrations/upnp [传感器.uscis docs]: /integrations/uscis [传感器.wunderground docs]: /integrations/wunderground [传感器.xiaomi_aqara docs]: /integrations/传感器.xiaomi_aqara/ [开关.deluge docs]: /integrations/deluge#开关 [开关.fritzbox docs]: /integrations/fritzbox [开关.insteon_plm docs]: /integrations/insteon/ [开关.MQTT docs]: /integrations/开关.MQTT/ [开关.rainmachine docs]: /integrations/rainmachine#开关 [开关.xiaomi_aqara docs]: /integrations/开关.xiaomi_aqara/ [system_log docs]: /integrations/system_log/ [tahoma docs]: /integrations/tahoma/ [upnp docs]: /integrations/upnp/ [天气 docs]: /integrations/天气/ [天气.buienradar docs]: /integrations/buienradar [天气.darksky docs]: /integrations/天气.darksky/ [天气.openweathermap docs]: /integrations/openweathermap#天气 [websocket_api docs]: /integrations/websocket_api/ [xiaomi_aqara docs]: /integrations/xiaomi_aqara/ [zha docs]: /integrations/zha/ [区域 docs]: /integrations/区域/ [zwave docs]: /integrations/zwave/ --- url: /home-assistant/blog/2018-05-18-release-70.md --- # 0.70:Facebox、SpaceAPI、Konnected 报警系统 0.70 版本来了。因为前端构建方式做了大规模重构,这次发布时间比预期稍晚一些。它不应该影响前端的外观和使用体验。感谢所有参与测试版并帮助验证的朋友。目前看 Firefox 在运行 Hass.io 面板时仍有一些问题,我们正在尽快发布修复。 如果你正在使用自定义 UI 或面板,这个版本有一些变更。请确保升级到最新版本。更多信息请查看我们的[开发者博客](https://开发者.home-assistant.io/博客/2018/05/22/custom-ui-面板-api.html)。 说到开发者博客,我们还上线了一个新的博客和配套的 [Twitter 账号](https://twitter.com/hass_devs)。这是我们持续推进的一部分:把 Home Assistant 用户与开发者的内容和互动渠道更清晰地分开。 这个版本里一个很酷的新组件是 [Konnected][konnected docs]([产品页](https://konnected.io/))。它可以让你把现有的有线报警系统直接接入 Home Assistant! 另一个很棒的新功能是 [Facebox][image_processing.facebox docs]。它让你可以在本地对摄像头画面进行人脸检测。很期待大家用它玩出新花样。 ## 新平台 * 将 SABnzbd 转换为组件 ([@jeradM] - [#12915]) ([sabnzbd docs]) ([传感器.sabnzbd docs]) (breaking change) (new-platform) * 新增更多 HomematicIP Cloud 组件 ([@mxworm] - [#14084]) ([homematicip\_cloud docs][homematicip_cloud docs]) ([binary\_sensor.homematicip\_cloud docs][binary_sensor.homematicip_cloud docs]) ([灯光.homematicip\_cloud docs][灯光.homematicip_cloud docs]) ([开关.homematicip\_cloud docs][开关.homematicip_cloud docs]) (new-platform) * 新增 Facebox ([@robmarkcole] - [#14356]) ([image\_processing.facebox docs][image_processing.facebox docs]) (new-platform) * 新增 SpaceAPI 支持 ([@fabaff] - [#14204]) ([spaceapi docs]) (new-platform) * 新增 Samsung Family Hub 摄像头组件 ([@Klathmon] - [#14458]) ([摄像头.familyhub docs]) (new-platform) * 新增 Konnected 组件,支持发现、二元传感器和开关 ([@heythisisnate] - [#13670]) ([konnected docs]) ([binary\_sensor.konnected docs][binary_sensor.konnected docs]) ([开关.konnected docs]) (new-platform) * 新增 FinTS 传感器 ([@ChristianKuehnel] - [#14334]) ([传感器.fints docs]) (new-platform) ## 新功能 * 允许自定义 HomeKit 名称 ([@schmittx] - [#14159]) ([homekit docs]) (new-feature) * HomeKit 新增风扇支持 ([@schmittx] - [#14351]) ([homekit docs]) (new-feature) ## 发布 0.70.1 - 5 月 31 日 * 更新 Hue platform to aiohue 1.5.0, and re-implement logic for duplicate 场景 names. ([@MizterB] - [#14653]) ([hue docs]) * Ignore unsupported Sonos favorite lists ([@amelchio] - [#14665]) ([媒体播放器.sonos docs]) * MQTT 遮盖 Fix Assumed 状态 ([@OttoWinter] - [#14672]) ([遮盖.MQTT docs]) * Fix Eco mode display on Nest ([@ciotlosm] - [#14706]) ([温控.nest docs]) * 前端: bug fixes for date time more info, 遮盖 icons, slider overflow issue (@c727, @cdce8p, @balloob) * Add Simplepush back (#14728) ## 如果你需要帮助... ...欢迎随时访问我们非常活跃的 [论坛](https://community.home-assistant.io/),或加入我们的 [聊天频道](https://discord.gg/c5DvZ4e)。虽然发布说明开放评论,但我们更推荐你使用前面的沟通渠道。谢谢。 ## 报告问题 如果你遇到了此版本引入的问题,请在我们的 [问题追踪器](https://github.com/home-assistant/home-assistant/issues) 中提交报告。请务必填写问题模板中的所有字段。 ## 不向后兼容的变更 * SABnzbd 已转换为组件。请使用以下新配置进行设置: ```yaml sabnzbd: api_key: YOUR_SABNZBD_API_KEY ``` ([@jeradM] - [#12915]) ([sabnzbd docs]) ([传感器.sabnzbd docs]) (breaking change) (new-platform) * 对于 BMW 电动车:当前传感器 `remaining_range_fuel` 已被 `remaining_range_total` 取代,用于表示带燃油发动机车辆的总剩余续航。([@gerard33] - [#14293]) ([bmw\_connected\_drive docs][bmw_connected_drive docs]) ([binary\_sensor.bmw\_connected\_drive docs][binary_sensor.bmw_connected_drive docs]) ([传感器.bmw\_connected\_drive docs][传感器.bmw_connected_drive docs]) (breaking change) * 由于 simplepush.io 网站已离线,相关应用也已无法使用,因此该服务已被移除。([@c727] - [#14358]) ([通知 docs]) (breaking change) * DarkSky 传感器:新增体感温度高/低值,废弃原先的 max/min。([@nordlead2005] - [#12233]) ([传感器.darksky docs]) (breaking change) ## Beta 修复 * Wait for future mysensors gateway ready ([@MartinHjelmare] - [#14398]) ([mysensors docs]) (beta fix) * Homekit style cleanup ([@cdce8p] - [#14556]) ([homekit docs]) (beta fix) * fix nanoleaf aurora 灯光 min and max temperature ([@Oro] - [#14571]) ([灯光.nanoleaf\_aurora docs][灯光.nanoleaf_aurora docs]) (beta fix) * Fix ISY moisure 传感器 showing unknown until a leak is detected ([@OverloadUT] - [#14496]) ([binary\_sensor.isy994 docs][binary_sensor.isy994 docs]) (beta fix) * Bump insteonplm 版本 to fix 设备 hanging ([@teharris1] - [#14582]) ([insteon\_plm docs][insteon_plm docs]) (beta fix) * Fix hue discovery popping up ([@balloob] - [#14614]) (beta fix) * Use libsodium18 ([@balloob] - [#14624]) (beta fix) * No longer use backports for ffmpeg ([@balloob] - [#14626]) (beta fix) * Allow Hass.io 面板 dir ([@balloob] - [#14655]) ([hassio docs]) (beta fix) ## 所有变更 * Add unique\_id to MQTT 开关 ([@thepotoo] - [#13719]) ([开关.MQTT docs]) * zha: Bump to zigpy 0.1.0 ([@rcloran] - [#14305]) ([zha docs]) * Converted SABnzbd to a component ([@jeradM] - [#12915]) ([sabnzbd docs]) ([传感器.sabnzbd docs]) (breaking change) (new-platform) * Adds unique ID to Roku for 实体 registry inclusion ([@bachya] - [#14325]) ([媒体播放器.roku docs]) * 更新 hitron\_coda.py to fix login for Shaw modems ([@mikedm139] - [#14306]) ([device\_tracker docs][device_tracker docs]) * Add 传感器 for BMW electric cars ([@gerard33] - [#14293]) ([bmw\_connected\_drive docs][bmw_connected_drive docs]) ([binary\_sensor.bmw\_connected\_drive docs][binary_sensor.bmw_connected_drive docs]) ([传感器.bmw\_connected\_drive docs][传感器.bmw_connected_drive docs]) (breaking change) * Add more homematicip cloud components ([@mxworm] - [#14084]) ([homematicip\_cloud docs][homematicip_cloud docs]) ([binary\_sensor.homematicip\_cloud docs][binary_sensor.homematicip_cloud docs]) ([灯光.homematicip\_cloud docs][灯光.homematicip_cloud docs]) ([开关.homematicip\_cloud docs][开关.homematicip_cloud docs]) (new-platform) * add 2 设备 ([@m4dmin] - [#14321]) ([tahoma docs]) ([遮盖.tahoma docs]) * Gogogate2 0.1.1 ([@dlbroadfoot] - [#14294]) ([遮盖.gogogate2 docs]) * Snips: Added slot values for siteId and probability ([@tschmidty69] - [#14315]) ([snips docs]) * Add help for conversation/process 服务 ([@stephanerosi] - [#14323]) * Fix BOM 天气 '-' value ([@nickw444] - [#14042]) * Make sure zwave nodes/实体 enter the registry is proper 状态. ([@andrey-git] - [#14251]) ([zwave docs]) * Improving icloud 设备 tracker ([@evgeniy-khatko] - [#14078]) ([device\_tracker docs][device_tracker docs]) * Adds useful 属性 to RainMachine programs and 区域 ([@bachya] - [#14087]) ([开关.rainmachine docs]) * Waze Travel Time: optional inclusive/exclusive filters ([@diraimondo] - [#14000]) ([传感器.waze\_travel\_time docs][传感器.waze_travel_time docs]) * Add 区域 3 for Onkyo media player ([@snikch] - [#14295]) ([媒体播放器.onkyo docs]) * Support control of away mode and hold mode in Venstar component. Correctly detect 加湿器. ([@nkaminski] - [#14256]) ([温控.venstar docs]) * 升级 keyring to 12.2.0 and keyrings.alt to 3.1 ([@fabaff] - [#14355]) * 调试++ for multiple volume controls ([@rytilahti] - [#14349]) ([媒体播放器.songpal docs]) * 后端 tweaks to make authorization work ([@balloob] - [#14339]) ([api docs]) ([前端 docs]) ([http docs]) ([websocket\_api docs][websocket_api docs]) * 脚本/lint: Ensure there are files to test with pylint ([@cdce8p] - [#14363]) * 更新 .coveragerc ([@pvizeli] - [#14368]) * Fix binary\_sensor async\_update ([@damarco] - [#14376]) ([zha docs]) ([binary\_sensor.zha docs][binary_sensor.zha docs]) * Add local auth provider ([@balloob] - [#14365]) * 更新 to sensibo 1.0.3 with better 错误 reporting ([@andrey-git] - [#14380]) ([温控.sensibo docs]) * Fix binary\_sensor device\_state\_attributes ([@damarco] - [#14375]) ([binary\_sensor.zha docs][binary_sensor.zha docs]) * Add support for pressure 传感器 ([@damarco] - [#14361]) ([zha docs]) ([传感器.zha docs]) * Add "framerate" parameter to generic 摄像头 ([@abmantis] - [#14079]) ([摄像头 docs]) ([摄像头.generic docs]) * Rewritten HomeKit tests ([@cdce8p] - [#14377]) ([homekit docs]) * 更新 传感器 状态 before adding 设备 ([@damarco] - [#14357]) ([传感器.zha docs]) * Make mysensors component async ([@MartinHjelmare] - [#13641]) ([mysensors docs]) ([通知 docs]) ([温控.mysensors docs]) ([遮盖.mysensors docs]) ([灯光.mysensors docs]) ([开关.mysensors docs]) * Adds facebox ([@robmarkcole] - [#14356]) ([image\_processing.facebox docs][image_processing.facebox docs]) (new-platform) * more detailed 错误 message ([@exxamalte] - [#14385]) ([传感器.rest docs]) * Allow HomeKit name to be customized ([@schmittx] - [#14159]) ([homekit docs]) (new-feature) * Xiaomi Aqara: Add new cube model (sensor\_cube.aqgl01) ([@syssi] - [#14393]) ([binary\_sensor.xiaomi\_aqara docs][binary_sensor.xiaomi_aqara docs]) * Bump pycmus 版本 ([@mtreinish] - [#14395]) ([媒体播放器.cmus docs]) * Fix name of tox pylint env ([@MartinHjelmare] - [#14402]) * Use None as initial 状态 in zha component ([@damarco] - [#14389]) ([传感器.zha docs]) * Bump PyXiaomiGateway 版本 ([@syssi] - [#14412]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * Homekit test cleanup ([@cdce8p] - [#14416]) ([homekit docs]) * 更新 pylint to 1.8.4 ([@scop] - [#14421]) * Bring back typing check. Meanwhile just for homeassistant/\*.py ([@andrey-git] - [#14410]) * Look at registry before pulling zwave config values ([@andrey-git] - [#14408]) ([zwave docs]) * Add Bulgarian to Google TTS ([@Chariyski] - [#14422]) ([tts docs]) * Remove extra quotes from docstrings ([@scop] - [#14431]) ([folder\_watcher docs][folder_watcher docs]) ([传感器.sigfox docs]) ([传感器.simulated docs]) * Spelling, grammar etc fixes ([@scop] - [#14432]) ([hassio docs]) ([homekit docs]) ([媒体播放器.yamaha docs]) ([传感器.buienradar docs]) ([传感器.hive docs]) ([传感器.statistics docs]) ([开关.tahoma docs]) * Invoke pytest instead of py.test per upstream recommendation, #dropthedot ([@scop] - [#14434]) * Fix 风扇 服务 description ([@cdce8p] - [#14423]) * Clean up some Python 3.4 remnants ([@scop] - [#14433]) ([system\_log docs][system_log docs]) * Remove universal wheel setting ([@MartinHjelmare] - [#14445]) * 升级 requests\_mock to 1.5 ([@fabaff] - [#14444]) * 升级 pyota to 2.0.5 ([@fabaff] - [#14442]) ([iota docs]) ([传感器.iota docs]) * 升级 python-telegram-bot to 10.1.0 ([@fabaff] - [#14441]) ([telegram\_bot docs][telegram_bot docs]) * 升级 Sphinx to 1.7.4 ([@fabaff] - [#14439]) * 升级 youtube\_dl to 2018.05.09 ([@fabaff] - [#14438]) ([media\_extractor docs][media_extractor docs]) * 升级 distro to 1.3.0 ([@fabaff] - [#14436]) ([updater docs]) * Add priority and cycles to LaMetric ([@PhilRW] - [#14414]) ([通知 docs]) * Allow qwikswitch 传感器 as part of 设备 ([@kellerza] - [#14454]) ([qwikswitch docs]) * Bump requirement to pydeconz v38 ([@Kane610] - [#14452]) ([deconz docs]) * Add SpaceAPI support ([@fabaff] - [#14204]) ([spaceapi docs]) (new-platform) * Use ATTR\_NAME from const.py ([@fabaff] - [#14450]) * zha: Fix cluster class check in single-cluster 设备 type ([@rcloran] - [#14303]) ([zha docs]) * 升级 pygatt to 3.2.0 ([@fabaff] - [#14447]) ([传感器.skybeacon docs]) * Add support for direction to 风扇 模板 ([@schmittx] - [#14371]) ([风扇.模板 docs]) * Samsung Family hub 摄像头 component ([@Klathmon] - [#14458]) ([摄像头.familyhub docs]) (new-platform) * Fix key 错误 upon missing node ([@MartinHjelmare] - [#14460]) ([mysensors docs]) * Bump lakeside 版本 ([@mjg59] - [#14471]) ([eufy docs]) * Minor Wink fixes ([@w1ll1am23] - [#14468]) ([温控.wink docs]) ([灯光.wink docs]) * Don't poll the Samsung Family hub 摄像头 ([@syssi] - [#14473]) ([摄像头.familyhub docs]) * Optimistic MQTT 灯光 ([@dgomes] - [#14401]) ([灯光.MQTT docs]) * Remove simplepush.io ([@c727] - [#14358]) ([通知 docs]) (breaking change) * Add Konnected component with support for discovery, 二元sensor and 开关 ([@heythisisnate] - [#13670]) ([konnected docs]) ([binary\_sensor.konnected docs][binary_sensor.konnected docs]) ([开关.konnected docs]) (new-platform) * Make Feedreader component more extendable ([@exxamalte] - [#14342]) ([feedreader docs]) * BMW code cleanup ([@gerard33] - [#14424]) ([binary\_sensor.bmw\_connected\_drive docs][binary_sensor.bmw_connected_drive docs]) ([传感器.bmw\_connected\_drive docs][传感器.bmw_connected_drive docs]) * Don't add a url to built-in 面板 ([@balloob] - [#14456]) ([前端 docs]) * Added temperature (apparent) high/low, deprecated max/min ([@nordlead2005] - [#12233]) ([传感器.darksky docs]) (breaking change) * Improve handling of offline Sonos 设备 ([@amelchio] - [#14479]) ([媒体播放器.sonos docs]) * "unavailable" Media players should be considered off in Universal player ([@OverloadUT] - [#14466]) ([媒体播放器.universal docs]) * Added option to invert aREST pin 开关 logic for active low relays ([@w1ll1am23] - [#14467]) ([开关.arest docs]) * Use "Returns" consistently to avoid being treated as section ([@scop] - [#14448]) * Add HomeKit support for 风扇 ([@schmittx] - [#14351]) ([homekit docs]) (new-feature) * Add stdout and stderr to 调试 output for shell\_command ([@n8henrie] - [#14465]) ([shell\_command docs][shell_command docs]) * New 传感器 FinTS ([@ChristianKuehnel] - [#14334]) ([传感器.fints docs]) (new-platform) * 更新 hitron\_coda.py ([@mikedm139] - [#14506]) ([device\_tracker docs][device_tracker docs]) * Konnected component follow up ([@heythisisnate] - [#14491]) ([konnected docs]) * Adjust LimitlessLED properties for running effects ([@amelchio] - [#14481]) ([灯光.limitlessled docs]) * Bump locationsharinglib to 2.0.2 ([@thelittlefireman] - [#14359]) ([device\_tracker docs][device_tracker docs]) * 更新 前端 to 20180518.0 ([@balloob] - [#14510]) ([前端 docs]) * Feedreader configurable 更新 interval and max entries ([@exxamalte] - [#14487]) ([feedreader docs]) * Flux bug fix ([@oblogic7] - [#14476]) ([灯光.flux\_led docs][灯光.flux_led docs]) ([开关.flux docs]) * Show 警告 if no locations are shared (fixes #14177) ([@fabaff] - [#14511]) ([device\_tracker docs][device_tracker docs]) * Add code to HomeKit 门锁 ([@cdce8p] - [#14524]) ([homekit docs]) * Set pytz to >=2018.04 ([@fabaff] - [#14520]) * Add Homematic IP RotaryHandleSensor support ([@hanzoh] - [#14522]) ([homematic docs]) * 更新 HAP-python to 2.1.0 ([@cdce8p] - [#14528]) ([homekit docs]) * Fix some ISY 传感器 not getting detected as 二元sensor ([@OverloadUT] - [#14497]) ([isy994 docs]) * 更新 mychevy to 0.4.0 ([@sdague] - [#14372]) ([mychevy docs]) ([binary\_sensor.mychevy docs][binary_sensor.mychevy docs]) ([传感器.mychevy docs]) * Set certifi to >=2018.04.16 ([@fabaff] - [#14536]) * Wait for future mysensors gateway ready ([@MartinHjelmare] - [#14398]) ([mysensors docs]) (beta fix) * Homekit style cleanup ([@cdce8p] - [#14556]) ([homekit docs]) (beta fix) * fix nanoleaf aurora 灯光 min and max temperature ([@Oro] - [#14571]) ([灯光.nanoleaf\_aurora docs][灯光.nanoleaf_aurora docs]) (beta fix) * Fix ISY moisure 传感器 showing unknown until a leak is detected ([@OverloadUT] - [#14496]) ([binary\_sensor.isy994 docs][binary_sensor.isy994 docs]) (beta fix) * Bump insteonplm 版本 to fix 设备 hanging ([@teharris1] - [#14582]) ([insteon\_plm docs][insteon_plm docs]) (beta fix) * Fix hue discovery popping up ([@balloob] - [#14614]) (beta fix) * Use libsodium18 ([@balloob] - [#14624]) (beta fix) * No longer use backports for ffmpeg ([@balloob] - [#14626]) (beta fix) * Allow Hass.io 面板 dir ([@balloob] - [#14655]) ([hassio docs]) (beta fix) [#12233]: https://github.com/home-assistant/home-assistant/pull/12233 [#12915]: https://github.com/home-assistant/home-assistant/pull/12915 [#13641]: https://github.com/home-assistant/home-assistant/pull/13641 [#13670]: https://github.com/home-assistant/home-assistant/pull/13670 [#13719]: https://github.com/home-assistant/home-assistant/pull/13719 [#14000]: https://github.com/home-assistant/home-assistant/pull/14000 [#14042]: https://github.com/home-assistant/home-assistant/pull/14042 [#14078]: https://github.com/home-assistant/home-assistant/pull/14078 [#14079]: https://github.com/home-assistant/home-assistant/pull/14079 [#14084]: https://github.com/home-assistant/home-assistant/pull/14084 [#14087]: https://github.com/home-assistant/home-assistant/pull/14087 [#14159]: https://github.com/home-assistant/home-assistant/pull/14159 [#14204]: https://github.com/home-assistant/home-assistant/pull/14204 [#14251]: https://github.com/home-assistant/home-assistant/pull/14251 [#14256]: https://github.com/home-assistant/home-assistant/pull/14256 [#14293]: https://github.com/home-assistant/home-assistant/pull/14293 [#14294]: https://github.com/home-assistant/home-assistant/pull/14294 [#14295]: https://github.com/home-assistant/home-assistant/pull/14295 [#14303]: https://github.com/home-assistant/home-assistant/pull/14303 [#14305]: https://github.com/home-assistant/home-assistant/pull/14305 [#14306]: https://github.com/home-assistant/home-assistant/pull/14306 [#14315]: https://github.com/home-assistant/home-assistant/pull/14315 [#14321]: https://github.com/home-assistant/home-assistant/pull/14321 [#14323]: https://github.com/home-assistant/home-assistant/pull/14323 [#14325]: https://github.com/home-assistant/home-assistant/pull/14325 [#14334]: https://github.com/home-assistant/home-assistant/pull/14334 [#14339]: https://github.com/home-assistant/home-assistant/pull/14339 [#14342]: https://github.com/home-assistant/home-assistant/pull/14342 [#14349]: https://github.com/home-assistant/home-assistant/pull/14349 [#14351]: https://github.com/home-assistant/home-assistant/pull/14351 [#14355]: https://github.com/home-assistant/home-assistant/pull/14355 [#14356]: https://github.com/home-assistant/home-assistant/pull/14356 [#14357]: https://github.com/home-assistant/home-assistant/pull/14357 [#14358]: https://github.com/home-assistant/home-assistant/pull/14358 [#14359]: https://github.com/home-assistant/home-assistant/pull/14359 [#14361]: https://github.com/home-assistant/home-assistant/pull/14361 [#14363]: https://github.com/home-assistant/home-assistant/pull/14363 [#14365]: https://github.com/home-assistant/home-assistant/pull/14365 [#14368]: https://github.com/home-assistant/home-assistant/pull/14368 [#14371]: https://github.com/home-assistant/home-assistant/pull/14371 [#14372]: https://github.com/home-assistant/home-assistant/pull/14372 [#14375]: https://github.com/home-assistant/home-assistant/pull/14375 [#14376]: https://github.com/home-assistant/home-assistant/pull/14376 [#14377]: https://github.com/home-assistant/home-assistant/pull/14377 [#14380]: https://github.com/home-assistant/home-assistant/pull/14380 [#14385]: https://github.com/home-assistant/home-assistant/pull/14385 [#14389]: https://github.com/home-assistant/home-assistant/pull/14389 [#14393]: https://github.com/home-assistant/home-assistant/pull/14393 [#14395]: https://github.com/home-assistant/home-assistant/pull/14395 [#14398]: https://github.com/home-assistant/home-assistant/pull/14398 [#14401]: https://github.com/home-assistant/home-assistant/pull/14401 [#14402]: https://github.com/home-assistant/home-assistant/pull/14402 [#14408]: https://github.com/home-assistant/home-assistant/pull/14408 [#14410]: https://github.com/home-assistant/home-assistant/pull/14410 [#14412]: https://github.com/home-assistant/home-assistant/pull/14412 [#14414]: https://github.com/home-assistant/home-assistant/pull/14414 [#14416]: https://github.com/home-assistant/home-assistant/pull/14416 [#14421]: https://github.com/home-assistant/home-assistant/pull/14421 [#14422]: https://github.com/home-assistant/home-assistant/pull/14422 [#14423]: https://github.com/home-assistant/home-assistant/pull/14423 [#14424]: https://github.com/home-assistant/home-assistant/pull/14424 [#14431]: https://github.com/home-assistant/home-assistant/pull/14431 [#14432]: https://github.com/home-assistant/home-assistant/pull/14432 [#14433]: https://github.com/home-assistant/home-assistant/pull/14433 [#14434]: https://github.com/home-assistant/home-assistant/pull/14434 [#14436]: https://github.com/home-assistant/home-assistant/pull/14436 [#14438]: https://github.com/home-assistant/home-assistant/pull/14438 [#14439]: https://github.com/home-assistant/home-assistant/pull/14439 [#14441]: https://github.com/home-assistant/home-assistant/pull/14441 [#14442]: https://github.com/home-assistant/home-assistant/pull/14442 [#14444]: https://github.com/home-assistant/home-assistant/pull/14444 [#14445]: https://github.com/home-assistant/home-assistant/pull/14445 [#14447]: https://github.com/home-assistant/home-assistant/pull/14447 [#14448]: https://github.com/home-assistant/home-assistant/pull/14448 [#14450]: https://github.com/home-assistant/home-assistant/pull/14450 [#14452]: https://github.com/home-assistant/home-assistant/pull/14452 [#14454]: https://github.com/home-assistant/home-assistant/pull/14454 [#14456]: https://github.com/home-assistant/home-assistant/pull/14456 [#14458]: https://github.com/home-assistant/home-assistant/pull/14458 [#14460]: https://github.com/home-assistant/home-assistant/pull/14460 [#14465]: https://github.com/home-assistant/home-assistant/pull/14465 [#14466]: https://github.com/home-assistant/home-assistant/pull/14466 [#14467]: https://github.com/home-assistant/home-assistant/pull/14467 [#14468]: https://github.com/home-assistant/home-assistant/pull/14468 [#14471]: https://github.com/home-assistant/home-assistant/pull/14471 [#14473]: https://github.com/home-assistant/home-assistant/pull/14473 [#14476]: https://github.com/home-assistant/home-assistant/pull/14476 [#14479]: https://github.com/home-assistant/home-assistant/pull/14479 [#14481]: https://github.com/home-assistant/home-assistant/pull/14481 [#14487]: https://github.com/home-assistant/home-assistant/pull/14487 [#14491]: https://github.com/home-assistant/home-assistant/pull/14491 [#14496]: https://github.com/home-assistant/home-assistant/pull/14496 [#14497]: https://github.com/home-assistant/home-assistant/pull/14497 [#14506]: https://github.com/home-assistant/home-assistant/pull/14506 [#14510]: https://github.com/home-assistant/home-assistant/pull/14510 [#14511]: https://github.com/home-assistant/home-assistant/pull/14511 [#14520]: https://github.com/home-assistant/home-assistant/pull/14520 [#14522]: https://github.com/home-assistant/home-assistant/pull/14522 [#14524]: https://github.com/home-assistant/home-assistant/pull/14524 [#14528]: https://github.com/home-assistant/home-assistant/pull/14528 [#14536]: https://github.com/home-assistant/home-assistant/pull/14536 [#14556]: https://github.com/home-assistant/home-assistant/pull/14556 [#14571]: https://github.com/home-assistant/home-assistant/pull/14571 [#14582]: https://github.com/home-assistant/home-assistant/pull/14582 [#14614]: https://github.com/home-assistant/home-assistant/pull/14614 [#14624]: https://github.com/home-assistant/home-assistant/pull/14624 [#14626]: https://github.com/home-assistant/home-assistant/pull/14626 [#14655]: https://github.com/home-assistant/home-assistant/pull/14655 [@Chariyski]: https://github.com/Chariyski [@ChristianKuehnel]: https://github.com/ChristianKuehnel [@Kane610]: https://github.com/Kane610 [@Klathmon]: https://github.com/Klathmon [@MartinHjelmare]: https://github.com/MartinHjelmare [@Oro]: https://github.com/Oro [@OverloadUT]: https://github.com/OverloadUT [@PhilRW]: https://github.com/PhilRW [@abmantis]: https://github.com/abmantis [@amelchio]: https://github.com/amelchio [@andrey-git]: https://github.com/andrey-git [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@c727]: https://github.com/c727 [@cdce8p]: https://github.com/cdce8p [@damarco]: https://github.com/damarco [@dgomes]: https://github.com/dgomes [@diraimondo]: https://github.com/diraimondo [@dlbroadfoot]: https://github.com/dlbroadfoot [@evgeniy-khatko]: https://github.com/evgeniy-khatko [@exxamalte]: https://github.com/exxamalte [@fabaff]: https://github.com/fabaff [@gerard33]: https://github.com/gerard33 [@hanzoh]: https://github.com/hanzoh [@heythisisnate]: https://github.com/heythisisnate [@jeradM]: https://github.com/jeradM [@kellerza]: https://github.com/kellerza [@m4dmin]: https://github.com/m4dmin [@mikedm139]: https://github.com/mikedm139 [@mjg59]: https://github.com/mjg59 [@mtreinish]: https://github.com/mtreinish [@mxworm]: https://github.com/mxworm [@n8henrie]: https://github.com/n8henrie [@nickw444]: https://github.com/nickw444 [@nkaminski]: https://github.com/nkaminski [@nordlead2005]: https://github.com/nordlead2005 [@oblogic7]: https://github.com/oblogic7 [@pvizeli]: https://github.com/pvizeli [@rcloran]: https://github.com/rcloran [@robmarkcole]: https://github.com/robmarkcole [@rytilahti]: https://github.com/rytilahti [@schmittx]: https://github.com/schmittx [@scop]: https://github.com/scop [@sdague]: https://github.com/sdague [@snikch]: https://github.com/snikch [@stephanerosi]: https://github.com/stephanerosi [@syssi]: https://github.com/syssi [@teharris1]: https://github.com/teharris1 [@thelittlefireman]: https://github.com/thelittlefireman [@thepotoo]: https://github.com/thepotoo [@tschmidty69]: https://github.com/tschmidty69 [@w1ll1am23]: https://github.com/w1ll1am23 [api docs]: /integrations/api/ [auth docs]: /integrations/auth/ [binary_sensor.bmw_connected_drive docs]: /integrations/bmw_connected_drive [binary_sensor.homematicip_cloud docs]: /integrations/homematicip_cloud/ [binary_sensor.isy994 docs]: /integrations/isy994 [binary_sensor.konnected docs]: /integrations/konnected#binary-传感器 [binary_sensor.mychevy docs]: /integrations/mychevy [binary_sensor.xiaomi_aqara docs]: /integrations/binary_sensor.xiaomi_aqara/ [binary_sensor.zha docs]: /integrations/zha [bmw_connected_drive docs]: /integrations/bmw_connected_drive/ [摄像头 docs]: /integrations/摄像头/ [摄像头.familyhub docs]: /integrations/familyhub [摄像头.generic docs]: /integrations/generic_ip_camera [温控.mysensors docs]: /integrations/温控.mysensors/ [温控.sensibo docs]: /integrations/sensibo [温控.venstar docs]: /integrations/venstar [温控.wink docs]: /integrations/wink#温控 [遮盖.gogogate2 docs]: /integrations/gogogate2 [遮盖.mysensors docs]: /integrations/遮盖.mysensors/ [遮盖.tahoma docs]: /integrations/tahoma [deconz docs]: /integrations/deconz/ [device_tracker docs]: /integrations/device_tracker/ [eufy docs]: /integrations/eufy/ [风扇.模板 docs]: /integrations/风扇.模板/ [feedreader docs]: /integrations/feedreader/ [folder_watcher docs]: /integrations/folder_watcher/ [前端 docs]: /integrations/frontend/ [hassio docs]: /integrations/hassio/ [homekit docs]: /integrations/homekit/ [homematic docs]: /integrations/homematic/ [homematicip_cloud docs]: /integrations/homematicip_cloud/ [http docs]: /integrations/http/ [image_processing.facebox docs]: /integrations/facebox [insteon_plm docs]: /integrations/insteon/ [iota docs]: /integrations/iota/ [isy994 docs]: /integrations/isy994/ [konnected docs]: /integrations/konnected/ [灯光.flux_led docs]: /integrations/flux_led [灯光.homematicip_cloud docs]: /integrations/homematicip_cloud/ [灯光.limitlessled docs]: /integrations/limitlessled [灯光.MQTT docs]: /integrations/灯光.MQTT/ [灯光.mysensors docs]: /integrations/灯光.mysensors/ [灯光.nanoleaf_aurora docs]: /integrations/nanoleaf/ [灯光.wink docs]: /integrations/wink#灯光 [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.cmus docs]: /integrations/cmus [媒体播放器.onkyo docs]: /integrations/onkyo [媒体播放器.roku docs]: /integrations/roku#media-player [媒体播放器.songpal docs]: /integrations/songpal [媒体播放器.sonos docs]: /integrations/sonos [媒体播放器.universal docs]: /integrations/universal [媒体播放器.yamaha docs]: /integrations/yamaha [mychevy docs]: /integrations/mychevy/ [mysensors docs]: /integrations/mysensors/ [通知 docs]: /integrations/通知/ [qwikswitch docs]: /integrations/qwikswitch/ [sabnzbd docs]: /integrations/sabnzbd/ [传感器.bmw_connected_drive docs]: /integrations/bmw_connected_drive [传感器.buienradar docs]: /integrations/传感器.buienradar/ [传感器.darksky docs]: /integrations/darksky [传感器.fints docs]: /integrations/fints [传感器.hive docs]: /integrations/hive#传感器 [传感器.iota docs]: /integrations/iota#传感器 [传感器.mychevy docs]: /integrations/mychevy [传感器.rest docs]: /integrations/rest [传感器.sabnzbd docs]: /integrations/sabnzbd [传感器.sigfox docs]: /integrations/sigfox [传感器.simulated docs]: /integrations/simulated [传感器.skybeacon docs]: /integrations/skybeacon [传感器.statistics docs]: /integrations/statistics [传感器.waze_travel_time docs]: /integrations/waze_travel_time [传感器.zha docs]: /integrations/zha [shell_command docs]: /integrations/shell_command/ [snips docs]: /integrations/snips/ [spaceapi docs]: /integrations/spaceapi/ [开关.arest docs]: /integrations/arest#开关 [开关.flux docs]: /integrations/flux [开关.homematicip_cloud docs]: /integrations/homematicip_cloud/ [开关.konnected docs]: /integrations/konnected#开关 [开关.MQTT docs]: /integrations/开关.MQTT/ [开关.mysensors docs]: /integrations/开关.mysensors/ [开关.rainmachine docs]: /integrations/rainmachine#开关 [开关.tahoma docs]: /integrations/tahoma [system_log docs]: /integrations/system_log/ [tahoma docs]: /integrations/tahoma/ [telegram_bot docs]: /integrations/telegram_bot/ [tts docs]: /integrations/tts/ [updater docs]: /integrations/updater/ [websocket_api docs]: /integrations/websocket_api/ [xiaomi_aqara docs]: /integrations/xiaomi_aqara/ [zha docs]: /integrations/zha/ [zwave docs]: /integrations/zwave/ [#14653]: https://github.com/home-assistant/home-assistant/pull/14653 [#14665]: https://github.com/home-assistant/home-assistant/pull/14665 [#14672]: https://github.com/home-assistant/home-assistant/pull/14672 [#14706]: https://github.com/home-assistant/home-assistant/pull/14706 [@MizterB]: https://github.com/MizterB [@OttoWinter]: https://github.com/OttoWinter [@amelchio]: https://github.com/amelchio [@ciotlosm]: https://github.com/ciotlosm [温控.nest docs]: /integrations/nest#温控 [遮盖.MQTT docs]: /integrations/遮盖.MQTT/ [hue docs]: /integrations/hue/ [媒体播放器.sonos docs]: /integrations/sonos --- url: /home-assistant/blog/2018-06-04-esphomelib.md --- # esphomelib - 在 Home Assistant 中使用 ESP 的一体化方案 [ESP8266](https://www.espressif.com/products/socs/esp8266) 和 [ESP32](https://www.espressif.com/products/socs/esp32) 是价格极低、支持 WiFi 的微控制器,已经成为许多 DIY 家庭自动化项目的基础。包括 iTead(Sonoff 设备)在内的不少厂商,也因为性价比选择了这些芯片。 这些微控制器要实现基础功能,如今也很容易:借助 ESPEasy 或 Sonoff-Tasmota 等流行项目,下载固件刷入芯片即可。但如果你尝试超出这些框架的基础能力、做一些定制,就会发现事情没那么简单。很多时候你最终得从网上找 Arduino 代码项目,再按自己的需求修改。 这正是 esphomelib 发挥作用的地方:[esphomelib 工具套件](https://esphome.io/)以提供尽可能好的用户体验为目标。它一方面允许你在不写*一行*代码的前提下完成大量定制,另一方面提供完整的 Home Assistant 集成。在 esphomelib 生态中,你基本只需要编写一个简单的 YAML 配置文件,后续的编译、刷写、上传等流程都会自动完成。 ## 安装 一个示例最能说明问题。使用 esphomeyaml 主要有两种方式:通过 [HassIO add-on](https://esphome.io/guides/getting_started_hassio.html),或者通过[命令行](https://esphome.io/guides/getting_started_command_line.html)。对于 esphomeyaml 插件,你只需把 "" 添加为插件仓库(见[安装第三方插件](/home-assistant/hassio/installing_third_party_addons/)),然后选择并安装“esphomeyaml”,等待安装完成。之后就可以启动插件并访问 Web 界面。 使用命令行时,只需用下面的 pip 命令安装 **Python 2** 包,然后访问 `localhost:6052` 打开仪表盘。 ```bash pip2 install esphomeyaml esphomeyaml config/ dashboard # Alternative for docker users: docker run --rm -p 6052:6052 -p 6123:6123 -v "$PWD":/config ottowinter/esphomeyaml /config dashboard ```
进入仪表盘后,你会看到一个简短的设置向导,帮助你快速开始使用 esphomeyaml 并创建基础配置。最终你会得到类似下面的配置文件。 ```yaml esphomeyaml: name: livingroom platform: ESP8266 board: nodemcuv2 wifi: ssid: "MySSID" password: "MyPassword" mqtt: broker: "192.168.178.83" username: "" password: "" logger: ota: ``` 到这一步你已经可以刷写固件了。先把 ESP 的 USB 线连接到运行 esphomeyaml 的设备上,等待出现“Discovered new serial port”提示(某些情况下需要重启插件)。然后在顶部导航栏选择上传端口,点击大号“UPLOAD”按钮。如果一切顺利,你现在就有一个可工作的 esphomelib 节点,并能看到调试日志 🎉 ## 添加一些基础功能 上面的配置说实话有点“无聊”:它只连接了 WiFi 和 MQTT,本身并不做事。所以我们来加一个基础的 [GPIO 开关](https://esphome.io/components/开关/gpio.html)!esphomelib 的 GPIO 开关组件可以控制 ESP 任意引脚的开/关状态。比如把下面这段配置加到 YAML 文件末尾,就会把 `GPIO5` 设置为一个名为 "Living Room Dehumidifer" 的开关。 ```yaml switch: - platform: gpio name: "Living Room Dehumidifer" pin: GPIO5 ``` 如果你现在再次点击上传(这次 ESP 不必再通过 USB 连接,因为更新[可以通过 WiFi 完成](https://esphome.io/components/ota.html)),你会看到一个开关通过 [MQTT discovery](/home-assistant/docs/MQTT/discovery/) 自动出现在 Home Assistant 中。

esphomeyamls 设置 wizard. 启用 MQTT discovery 且使用 default view 时,新配置的开关会这样显示在 Home Assistant 中。

确实,单靠这个功能在其他项目里也不算难。但当你开始加入[灯光](https://esphome.io/index.html#灯光-components)、[遮盖](https://esphome.io/index.html#遮盖-components)和[其他传感器](https://esphome.io/index.html#sensor-components)后,esphomelib 的模块化设计优势就会非常明显。 ## 另见 * [查看完整入门指南(包括从其他项目迁移的方法)](https://esphome.io/guides/) * [按设备分类的配置指南](https://esphome.io/#devices) * [支持的传感器/执行器列表](https://esphome.io/) * 如果需要帮助,欢迎加入 [Discord 服务器](https://discord.gg/KhAMKrd)。 --- url: /home-assistant/blog/2018-06-10-release-71.md --- # 0.71:Lagute LW-12、Iperf3、Hydrawise、Ryobi 车库门 0.71 版本来了。我在这个版本里最喜欢的功能,是 Nest 集成从云端轮询改成了云端推送。虽然还是通过云端,但变化一发生就会立刻同步到 Home Assistant。感谢 [@awarecan]! 在上个版本大改之后,我们继续对前端做了优化。此前 Hass.io 面板在 Firefox 和 Safari 上有一些问题,现在已经修复,希望各浏览器都能正常工作了。 在前端方面,自定义面板获得了一些新能力,包括支持使用 React 构建面板。所以如果你是开发者,可以[看看这篇介绍](https://开发者.home-assistant.io/博客/2018/06/01/071-custom-面板.html)。另外也感谢 [@c727],现在有更多字符串可以被翻译。关于如何参与前端翻译,可查看[这里](https://开发者.home-assistant.io/docs/en/internationalization_translation.html)。 HomeKit 支持也在持续扩展。感谢 [@schmittx],本次发布加入了对媒体播放器、自动化和插座的支持。 如果你错过了这条消息:[@OttoWinter] 创建了 [esphomeyaml],你可以使用受 Home Assistant 启发的 `configuration.yaml` 来编程并部署家中的 ESP 芯片。[快来看看](/home-assistant/blog/2018/06/05/esphomelib/)。 祝大家周末愉快! ## 新平台 * 新增 Lagute LW-12 WiFi LED 控制支持 ([@jaypikay] - [#13307]) ([灯光.lw12wifi docs]) (new-platform) * 新增小米 Aqara 门锁支持 ([@SchumyHao] - [#14419]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) ([门锁.xiaomi\_aqara docs][门锁.xiaomi_aqara docs]) (new-platform) * 新增 Iperf3 客户端传感器 ([@tchellomello] - [#14213]) ([传感器.iperf3 docs]) (new-platform) * 新增 HomematicIP Cloud 温控平台 ([@mxworm] - [#14388]) ([homematicip\_cloud docs][homematicip_cloud docs]) ([温控.homematicip\_cloud docs][温控.homematicip_cloud docs]) (new-platform) * 新增 Hydrawise 组件 ([@ptcryan] - [#14055]) ([hydrawise docs]) ([binary\_sensor.hydrawise docs][binary_sensor.hydrawise docs]) ([传感器.hydrawise docs]) ([开关.hydrawise docs]) (new-platform) * 新增 Ryobi 车库门开启器支持 ([@guillaume1410] - [#14618]) (遮盖.ryobi\_gdo docs) (new-platform) * 为 RainMachine 新增传感器和服务 ([@bachya] - [#14326]) ([rainmachine docs]) ([binary\_sensor.rainmachine docs][binary_sensor.rainmachine docs]) ([传感器.rainmachine docs]) ([开关.rainmachine docs]) (new-platform) * 新增 Flock 通知平台 ([@fabaff] - [#14533]) ([通知 docs]) (new-platform) ## 新功能 * HomeKit 新增媒体播放器支持 ([@schmittx] - [#14446]) ([homekit docs]) (new-feature) * HomeKit 新增自动化支持 ([@schmittx] - [#14595]) ([homekit docs]) (new-feature) * 扩展 package 支持 ([@cdce8p] - [#14611]) (new-feature) * Nest 改为云端推送模式 ([@awarecan] - [#14656]) ([nest docs]) ([binary\_sensor.nest docs][binary_sensor.nest docs]) ([温控.nest docs]) ([传感器.nest docs]) (new-feature) * HomeKit 新增插座支持 ([@schmittx] - [#14628]) ([homekit docs]) (new-feature) ## 如果你需要帮助... ...欢迎随时访问我们非常活跃的 [论坛](https://community.home-assistant.io/),或加入我们的 [聊天频道](https://discord.gg/c5DvZ4e)。虽然发布说明开放评论,但我们更推荐你使用前面的沟通渠道。谢谢。 ## 报告问题 如果你遇到了此版本引入的问题,请在我们的 [问题追踪器](https://github.com/home-assistant/home-assistant/issues) 中提交报告。请务必填写问题模板中的所有字段。 ## 不向后兼容的变更 * BOM 传感器:将 `'Wind Direction kt'` 更正为 `'Wind Speed kt'`(修复 #14535) ([@fabaff] - [#14541]) (breaking change) * 从 Raincloudy 传感器中移除 `current_time` 属性,以避免触发 recorder 组件 ([@tchellomello] - [#14584]) ([raincloud docs]) ([开关.raincloud docs]) (breaking change) * 移除 Notify My Android 组件,因为该服务已于 5 月 24 日关闭 ([@cgarwood] - [#14594]) ([通知 docs]) (breaking change) * CoinMarketCap 传感器:现在不能再通过货币名称(如 bitcoin)查询 ticker,API 改为使用对应的 ID(整数),例如 bitcoin -> 1。小数位数现在也可以配置,因为当显示货币设为 BTC 时固定四舍五入到两位小数并不合理,部分值会显示为 0.00。(#14437) ([@kotlarz] - [#14604]) ([传感器.coinmarketcap docs]) (breaking change) * Give unknown zwave nodes a better name and don't add them to 实体 registry ([@andrey-git] - [#14353]) ([zwave docs]) (breaking change) * `netdata` 传感器已重构,以支持 [Netdata](https://my-netdata.io/) 提供的全部可用细节。如果你正在使用 `netdata` 传感器,则需要调整现有配置。 ([@fabaff] - [#14613]) ([传感器.netdata docs]) (breaking change) * 不再允许没有 `entity_id` 的 `自动化.触发器`。一次触发所有自动化通常是用户误操作;如果你确实需要这样做,可以使用 `entity_id: group.all_automations`。([@amelchio] - [#14724]) ([自动化 docs]) (breaking change) ## Beta 修复 * Use hass iconset ([@balloob] - [#14185]) ([config docs]) ([前端 docs]) ([hassio docs]) ([history docs]) ([logbook docs]) (beta fix) * 区域 - Hass 配置 name is optional ([@Kane610] - [#14449]) ([区域 docs]) (beta fix) ## 所有变更 * 升级 aiohttp to 3.2.1 ([@fabaff] - [#14517]) * 升级 youtube\_dl to 2018.05.18 ([@fabaff] - [#14519]) ([media\_extractor docs][media_extractor docs]) * 升级 keyring to 12.2.1 ([@fabaff] - [#14521]) * 升级 restrictedpython to 4.0b4 ([@fabaff] - [#14537]) ([python\_script docs][python_script docs]) * Bump pyvera 版本 (improve stability of poll loop). ([@pavoni] - [#14540]) ([vera docs]) * Fix 传感器 name (fixes #14535) ([@fabaff] - [#14541]) (breaking change) * Add support to ignore a xiaomi aqara gateway ([@ileler] - [#14428]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * Pushed to 版本 0.7.2 of denonavr ([@scarface-4711] - [#14551]) ([媒体播放器.denonavr docs]) * Add auto discovery for nanoleaf aurora 灯光 ([@Oro] - [#14301]) ([灯光.nanoleaf\_aurora docs][灯光.nanoleaf_aurora docs]) * zha: Don't poll 开关 设备 ([@dmulcahey] - [#14560]) ([binary\_sensor.zha docs][binary_sensor.zha docs]) * zha: Add metering 传感器 ([@dmulcahey] - [#14562]) ([zha docs]) ([传感器.zha docs]) * zha: Set default binary\_sensor 状态 to false ([@damarco] - [#14553]) ([binary\_sensor.zha docs][binary_sensor.zha docs]) * Add IlluminanceMeasurementSensor to ZHA ([@dmulcahey] - [#14563]) ([zha docs]) ([传感器.zha docs]) * zha: Bump to zigpy-xbee 0.1.1 ([@rcloran] - [#14566]) ([zha docs]) * 更新 pyhomematic to 0.1.43 ([@danielperna84] - [#14583]) ([homematic docs]) * Removed 属性 current\_time from Raincloudy 传感器 to avoid being triggered by recorder component ([@tchellomello] - [#14584]) ([raincloud docs]) ([开关.raincloud docs]) (breaking change) * Lagute LW-12 WiFi LED control ([@jaypikay] - [#13307]) ([灯光.lw12wifi docs]) (new-platform) * Add new transmission 传感器 types ([@fabaff] - [#14530]) ([传感器.transmission docs]) * Add Xiaomi Aqara 门锁 support ([@SchumyHao] - [#14419]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) ([门锁.xiaomi\_aqara docs][门锁.xiaomi_aqara docs]) (new-platform) * 升级 TwitterAPI to 2.5.3 ([@fabaff] - [#14596]) ([通知 docs]) * Remove nma component ([@cgarwood] - [#14594]) ([通知 docs]) (breaking change) * Add Nest away 二元sensor and eta 传感器 ([@awarecan] - [#14406]) * Adds a 设备 class of 'garage' to MyQ 遮盖 ([@bachya] - [#14602]) ([遮盖.myq docs]) * Add Iperf3 client 传感器 ([@tchellomello] - [#14213]) ([传感器.iperf3 docs]) (new-platform) * 升级 linode-api to 4.1.9b1 (#13863) ([@robertbeal] - [#14610]) ([linode docs]) * 更新 pyrainbird ([@Klathmon] - [#14617]) ([rainbird docs]) * Add support 容器 status for Glances on RPi3 ([@bastshoes] - [#14529]) ([传感器.glances docs]) * Adding illumination 传感器 ([@nklever] - [#14615]) ([传感器.onewire docs]) * Add HomeKit support for media players ([@schmittx] - [#14446]) ([homekit docs]) (new-feature) * Add HomeKit support for 自动化 ([@schmittx] - [#14595]) ([homekit docs]) (new-feature) * Add configurable decimal rounding of display value for CoinMarketCap 传感器 and 升级 to 5.0.3 (#14437) ([@kotlarz] - [#14604]) ([传感器.coinmarketcap docs]) (breaking change) * Extend package support ([@cdce8p] - [#14611]) (new-feature) * Added option to connect via SSL for OpenWRT(luci) 设备 tracker ([@lorenzschmid] - [#14627]) ([device\_tracker docs][device_tracker docs]) * Added UDP and parallel streams support to Iperf3 ([@tchellomello] - [#14629]) ([传感器.iperf3 docs]) * Add 服务 for adding and removing items to shopping list ([@mammuth] - [#14574]) ([shopping\_list docs][shopping_list docs]) * Add homematicip cloud 温控 platform ([@mxworm] - [#14388]) ([homematicip\_cloud docs][homematicip_cloud docs]) ([温控.homematicip\_cloud docs][温控.homematicip_cloud docs]) (new-platform) * 升级 speedtest-cli to 2.0.2 ([@fabaff] - [#14633]) ([传感器.speedtest docs]) * Add Hydrawise component ([@ptcryan] - [#14055]) ([hydrawise docs]) ([binary\_sensor.hydrawise docs][binary_sensor.hydrawise docs]) ([传感器.hydrawise docs]) ([开关.hydrawise docs]) (new-platform) * Adding ryobi garage door opener ([@guillaume1410] - [#14618]) (遮盖.ryobi\_gdo docs) (new-platform) * Add electrical measurement 传感器 to ZHA ([@dmulcahey] - [#14561]) ([zha docs]) ([传感器.zha docs]) * 升级 luftdaten to 0.2.0 ([@fabaff] - [#14620]) ([传感器.luftdaten docs]) * 升级 python-nest to 4.0.0 ([@awarecan] - [#14638]) ([nest docs]) * 升级 gitterpy to 0.1.7 ([@fabaff] - [#14643]) ([传感器.gitter docs]) * 升级 TwitterAPI to 2.5.4 ([@fabaff] - [#14639]) ([通知 docs]) * Use constants ([@fabaff] - [#14647]) ([api docs]) * 升级 locationsharinglib to 2.0.7 ([@fabaff] - [#14640]) ([device\_tracker docs][device_tracker docs]) * 升级 youtube\_dl to 2018.05.26 ([@fabaff] - [#14654]) ([media\_extractor docs][media_extractor docs]) * 升级 python\_opendata\_transport to 0.1.0 ([@fabaff] - [#14652]) ([传感器.swiss\_public\_transport docs][传感器.swiss_public_transport docs]) * Remove Docker prereqs 脚本 that only 安装 a package. Add informational message for this. ([@michaelarnauts] - [#14661]) * Reduce 日志 churn from Envisalink 二元sensor ([@koreth] - [#14659]) ([binary\_sensor.envisalink docs][binary_sensor.envisalink docs]) * Force 更新 ZHA electrical 传感器 ([@dmulcahey] - [#14649]) ([传感器.zha docs]) * Improve Homekit 媒体播放器 options ([@cdce8p] - [#14637]) ([homekit docs]) * zha/灯光: Properly parse currentX and currentY on async\_update() ([@Adminiuga] - [#14605]) ([灯光.zha docs]) * Add tv channel and volume level for philips js API 5 ([@treehoof] - [#14276]) ([媒体播放器.philips\_js docs][媒体播放器.philips_js docs]) * Give unknown zwave nodes a better name ([@andrey-git] - [#14353]) ([zwave docs]) (breaking change) * Add pin pad to 报警 面板 ([@raccettura] - [#14178]) ([alarm\_control\_panel.manual docs][alarm_control_panel.manual docs]) * 更新 mfi.py ([@Bakkoda] - [#14667]) ([传感器.mfi docs]) * Increase Eufy's requirement on lakeside ([@mjg59] - [#14671]) ([eufy docs]) * Allow hassio 前端 development ([@balloob] - [#14675]) ([hassio docs]) * zha: fix temperature rounding for ZHA temperature 传感器. ([@Adminiuga] - [#14669]) ([传感器.zha docs]) * Allow 用户-defined 传感器 ([@fabaff] - [#14613]) ([传感器.netdata docs]) (breaking change) * deCONZ - Option to load or not to load clip 传感器 on start ([@Kane610] - [#14480]) ([binary\_sensor.deconz docs][binary_sensor.deconz docs]) ([传感器.deconz docs]) * Add asyncio support for Ebox ([@titilambert] - [#14183]) * Add 传感器 and 服务 to RainMachine ([@bachya] - [#14326]) ([rainmachine docs]) ([binary\_sensor.rainmachine docs][binary_sensor.rainmachine docs]) ([传感器.rainmachine docs]) ([开关.rainmachine docs]) (new-platform) * 更新 HAP-python to 2.2.2 ([@cdce8p] - [#14674]) ([homekit docs]) * Fix deprecated code ([@balloob] - [#14681]) ([cloud docs]) * Homekit Bugfixes ([@cdce8p] - [#14689]) ([homekit docs]) * Netatmo 传感器: Implement device\_class ([@heinemml] - [#14634]) ([传感器.netatmo docs]) * Change ACP code\_format to None|"Number"|"Any" ([@c727] - [#14686]) * Fixes (and stabilizes) some incorrect 区域 codes in RainMachine ([@bachya] - [#14719]) ([开关.rainmachine docs]) * Add Flock 通知 platform ([@fabaff] - [#14533]) ([通知 docs]) (new-platform) * Revert "Remove simplepush.io ([@balloob] - [#14358]) ([通知 docs]) (breaking change) * Add device\_descriptor and device\_name to keyboard event ([@glenn20] - [#14642]) ([keyboard\_remote docs][keyboard_remote docs]) * 升级 shodan to 1.8.0 ([@fabaff] - [#14717]) ([传感器.shodan docs]) * Homekit Thermostat: Better support for temperature ranges ([@roiff] - [#14679]) ([homekit docs]) * Custom 面板 ([@balloob] - [#14708]) ([panel\_custom docs][panel_custom docs]) * Disallow 自动化.触发器 without entity\_id ([@amelchio] - [#14724]) ([自动化 docs]) (breaking change) * Change nest to cloud push ([@awarecan] - [#14656]) ([nest docs]) ([binary\_sensor.nest docs][binary_sensor.nest docs]) ([温控.nest docs]) ([传感器.nest docs]) (new-feature) * Add support for outlets in HomeKit ([@schmittx] - [#14628]) ([homekit docs]) (new-feature) * Add battery 属性 to Sensibo ([@michaeldavie] - [#14735]) ([温控.sensibo docs]) * 更新 syntax ([@fabaff] - [#14742]) ([counter docs]) * 升级 blockchain to 1.4.4 ([@fabaff] - [#14738]) ([传感器.bitcoin docs]) * Added option to block Osram Lightify individual 灯光 in the same way that groups can be ([@austinlg96] - [#14470]) ([灯光.osramlightify docs]) * 升级 directpy to 0.5 ([@Bahnburner] - [#14750]) ([媒体播放器.directv docs]) * 更新 syntax of platform random ([@fabaff] - [#14767]) ([binary\_sensor.random docs][binary_sensor.random docs]) ([传感器.random docs]) * 更新 postnl api to 1.0.2 ([@iMicknl] - [#14769]) * Remove swagger file ([@fabaff] - [#14762]) * 更新 syntax ([@fabaff] - [#14771]) ([传感器.版本 docs]) * 更新 syntax ([@fabaff] - [#14768]) ([传感器.worldclock docs]) * 更新 syntax ([@fabaff] - [#14770]) ([传感器.uptime docs]) * 升级 Sphinx to 1.7.5 ([@fabaff] - [#14764]) * 升级 youtube\_dl to 2018.06.02 ([@fabaff] - [#14763]) ([media\_extractor docs][media_extractor docs]) * 升级 sqlalchemy to 1.2.8 ([@fabaff] - [#14765]) * 升级 shodan to 1.8.1 ([@fabaff] - [#14760]) ([传感器.shodan docs]) * 更新 syntax ([@fabaff] - [#14772]) ([传感器.simulated docs]) * Assign 设备 class to nest 传感器 ([@awarecan] - [#14746]) ([nest docs]) ([binary\_sensor.nest docs][binary_sensor.nest docs]) ([传感器.nest docs]) * Ignore the mistaken long\_click event of the 86sw (Closes: #14694) ([@syssi] - [#14785]) ([binary\_sensor.xiaomi\_aqara docs][binary_sensor.xiaomi_aqara docs]) * 更新 total-connect-client to 0.18 for Honeywell Lynx Touch-WiFi support ([@jwood55812] - [#14778]) ([alarm\_control\_panel.totalconnect docs][alarm_control_panel.totalconnect docs]) * Add Kodi OnResume event ([@quthla] - [#14790]) ([媒体播放器.kodi docs]) * Fix media\_title empty when title is empty but label is set ([@quthla] - [#14791]) ([媒体播放器.kodi docs]) * Add homematicip\_cloud illuminance 传感器 ([@mxworm] - [#14720]) ([传感器.homematicip\_cloud docs][传感器.homematicip_cloud docs]) * Use hass iconset ([@balloob] - [#14185]) ([config docs]) ([前端 docs]) ([hassio docs]) ([history docs]) ([logbook docs]) (beta fix) * 区域 - Hass 配置 name is optional ([@Kane610] - [#14449]) ([区域 docs]) (beta fix) [#13307]: https://github.com/home-assistant/home-assistant/pull/13307 [#14055]: https://github.com/home-assistant/home-assistant/pull/14055 [#14178]: https://github.com/home-assistant/home-assistant/pull/14178 [#14183]: https://github.com/home-assistant/home-assistant/pull/14183 [#14185]: https://github.com/home-assistant/home-assistant/pull/14185 [#14213]: https://github.com/home-assistant/home-assistant/pull/14213 [#14276]: https://github.com/home-assistant/home-assistant/pull/14276 [#14301]: https://github.com/home-assistant/home-assistant/pull/14301 [#14326]: https://github.com/home-assistant/home-assistant/pull/14326 [#14353]: https://github.com/home-assistant/home-assistant/pull/14353 [#14358]: https://github.com/home-assistant/home-assistant/pull/14358 [#14388]: https://github.com/home-assistant/home-assistant/pull/14388 [#14406]: https://github.com/home-assistant/home-assistant/pull/14406 [#14419]: https://github.com/home-assistant/home-assistant/pull/14419 [#14428]: https://github.com/home-assistant/home-assistant/pull/14428 [#14446]: https://github.com/home-assistant/home-assistant/pull/14446 [#14449]: https://github.com/home-assistant/home-assistant/pull/14449 [#14470]: https://github.com/home-assistant/home-assistant/pull/14470 [#14480]: https://github.com/home-assistant/home-assistant/pull/14480 [#14517]: https://github.com/home-assistant/home-assistant/pull/14517 [#14519]: https://github.com/home-assistant/home-assistant/pull/14519 [#14521]: https://github.com/home-assistant/home-assistant/pull/14521 [#14529]: https://github.com/home-assistant/home-assistant/pull/14529 [#14530]: https://github.com/home-assistant/home-assistant/pull/14530 [#14533]: https://github.com/home-assistant/home-assistant/pull/14533 [#14537]: https://github.com/home-assistant/home-assistant/pull/14537 [#14540]: https://github.com/home-assistant/home-assistant/pull/14540 [#14541]: https://github.com/home-assistant/home-assistant/pull/14541 [#14551]: https://github.com/home-assistant/home-assistant/pull/14551 [#14553]: https://github.com/home-assistant/home-assistant/pull/14553 [#14560]: https://github.com/home-assistant/home-assistant/pull/14560 [#14561]: https://github.com/home-assistant/home-assistant/pull/14561 [#14562]: https://github.com/home-assistant/home-assistant/pull/14562 [#14563]: https://github.com/home-assistant/home-assistant/pull/14563 [#14566]: https://github.com/home-assistant/home-assistant/pull/14566 [#14574]: https://github.com/home-assistant/home-assistant/pull/14574 [#14583]: https://github.com/home-assistant/home-assistant/pull/14583 [#14584]: https://github.com/home-assistant/home-assistant/pull/14584 [#14594]: https://github.com/home-assistant/home-assistant/pull/14594 [#14595]: https://github.com/home-assistant/home-assistant/pull/14595 [#14596]: https://github.com/home-assistant/home-assistant/pull/14596 [#14602]: https://github.com/home-assistant/home-assistant/pull/14602 [#14604]: https://github.com/home-assistant/home-assistant/pull/14604 [#14605]: https://github.com/home-assistant/home-assistant/pull/14605 [#14610]: https://github.com/home-assistant/home-assistant/pull/14610 [#14611]: https://github.com/home-assistant/home-assistant/pull/14611 [#14613]: https://github.com/home-assistant/home-assistant/pull/14613 [#14615]: https://github.com/home-assistant/home-assistant/pull/14615 [#14617]: https://github.com/home-assistant/home-assistant/pull/14617 [#14618]: https://github.com/home-assistant/home-assistant/pull/14618 [#14620]: https://github.com/home-assistant/home-assistant/pull/14620 [#14627]: https://github.com/home-assistant/home-assistant/pull/14627 [#14628]: https://github.com/home-assistant/home-assistant/pull/14628 [#14629]: https://github.com/home-assistant/home-assistant/pull/14629 [#14633]: https://github.com/home-assistant/home-assistant/pull/14633 [#14634]: https://github.com/home-assistant/home-assistant/pull/14634 [#14637]: https://github.com/home-assistant/home-assistant/pull/14637 [#14638]: https://github.com/home-assistant/home-assistant/pull/14638 [#14639]: https://github.com/home-assistant/home-assistant/pull/14639 [#14640]: https://github.com/home-assistant/home-assistant/pull/14640 [#14642]: https://github.com/home-assistant/home-assistant/pull/14642 [#14643]: https://github.com/home-assistant/home-assistant/pull/14643 [#14647]: https://github.com/home-assistant/home-assistant/pull/14647 [#14649]: https://github.com/home-assistant/home-assistant/pull/14649 [#14652]: https://github.com/home-assistant/home-assistant/pull/14652 [#14654]: https://github.com/home-assistant/home-assistant/pull/14654 [#14656]: https://github.com/home-assistant/home-assistant/pull/14656 [#14659]: https://github.com/home-assistant/home-assistant/pull/14659 [#14661]: https://github.com/home-assistant/home-assistant/pull/14661 [#14667]: https://github.com/home-assistant/home-assistant/pull/14667 [#14669]: https://github.com/home-assistant/home-assistant/pull/14669 [#14671]: https://github.com/home-assistant/home-assistant/pull/14671 [#14674]: https://github.com/home-assistant/home-assistant/pull/14674 [#14675]: https://github.com/home-assistant/home-assistant/pull/14675 [#14679]: https://github.com/home-assistant/home-assistant/pull/14679 [#14681]: https://github.com/home-assistant/home-assistant/pull/14681 [#14686]: https://github.com/home-assistant/home-assistant/pull/14686 [#14689]: https://github.com/home-assistant/home-assistant/pull/14689 [#14708]: https://github.com/home-assistant/home-assistant/pull/14708 [#14717]: https://github.com/home-assistant/home-assistant/pull/14717 [#14719]: https://github.com/home-assistant/home-assistant/pull/14719 [#14720]: https://github.com/home-assistant/home-assistant/pull/14720 [#14724]: https://github.com/home-assistant/home-assistant/pull/14724 [#14735]: https://github.com/home-assistant/home-assistant/pull/14735 [#14738]: https://github.com/home-assistant/home-assistant/pull/14738 [#14742]: https://github.com/home-assistant/home-assistant/pull/14742 [#14746]: https://github.com/home-assistant/home-assistant/pull/14746 [#14750]: https://github.com/home-assistant/home-assistant/pull/14750 [#14760]: https://github.com/home-assistant/home-assistant/pull/14760 [#14762]: https://github.com/home-assistant/home-assistant/pull/14762 [#14763]: https://github.com/home-assistant/home-assistant/pull/14763 [#14764]: https://github.com/home-assistant/home-assistant/pull/14764 [#14765]: https://github.com/home-assistant/home-assistant/pull/14765 [#14767]: https://github.com/home-assistant/home-assistant/pull/14767 [#14768]: https://github.com/home-assistant/home-assistant/pull/14768 [#14769]: https://github.com/home-assistant/home-assistant/pull/14769 [#14770]: https://github.com/home-assistant/home-assistant/pull/14770 [#14771]: https://github.com/home-assistant/home-assistant/pull/14771 [#14772]: https://github.com/home-assistant/home-assistant/pull/14772 [#14778]: https://github.com/home-assistant/home-assistant/pull/14778 [#14785]: https://github.com/home-assistant/home-assistant/pull/14785 [#14790]: https://github.com/home-assistant/home-assistant/pull/14790 [#14791]: https://github.com/home-assistant/home-assistant/pull/14791 [@Adminiuga]: https://github.com/Adminiuga [@Bahnburner]: https://github.com/Bahnburner [@Bakkoda]: https://github.com/Bakkoda [@Kane610]: https://github.com/Kane610 [@Klathmon]: https://github.com/Klathmon [@Oro]: https://github.com/Oro [@SchumyHao]: https://github.com/SchumyHao [@amelchio]: https://github.com/amelchio [@andrey-git]: https://github.com/andrey-git [@austinlg96]: https://github.com/austinlg96 [@awarecan]: https://github.com/awarecan [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@bastshoes]: https://github.com/bastshoes [@c727]: https://github.com/c727 [@cdce8p]: https://github.com/cdce8p [@cgarwood]: https://github.com/cgarwood [@damarco]: https://github.com/damarco [@danielperna84]: https://github.com/danielperna84 [@dmulcahey]: https://github.com/dmulcahey [@fabaff]: https://github.com/fabaff [@glenn20]: https://github.com/glenn20 [@guillaume1410]: https://github.com/guillaume1410 [@heinemml]: https://github.com/heinemml [@iMicknl]: https://github.com/iMicknl [@ileler]: https://github.com/ileler [@jaypikay]: https://github.com/jaypikay [@jwood55812]: https://github.com/jwood55812 [@koreth]: https://github.com/koreth [@kotlarz]: https://github.com/kotlarz [@lorenzschmid]: https://github.com/lorenzschmid [@mammuth]: https://github.com/mammuth [@michaelarnauts]: https://github.com/michaelarnauts [@michaeldavie]: https://github.com/michaeldavie [@mjg59]: https://github.com/mjg59 [@mxworm]: https://github.com/mxworm [@nklever]: https://github.com/nklever [@pavoni]: https://github.com/pavoni [@ptcryan]: https://github.com/ptcryan [@quthla]: https://github.com/quthla [@raccettura]: https://github.com/raccettura [@rcloran]: https://github.com/rcloran [@robertbeal]: https://github.com/robertbeal [@roiff]: https://github.com/roiff [@scarface-4711]: https://github.com/scarface-4711 [@schmittx]: https://github.com/schmittx [@syssi]: https://github.com/syssi [@tchellomello]: https://github.com/tchellomello [@titilambert]: https://github.com/titilambert [@treehoof]: https://github.com/treehoof [alarm_control_panel.manual docs]: /integrations/manual [alarm_control_panel.totalconnect docs]: /integrations/totalconnect [api docs]: /integrations/api/ [自动化 docs]: /integrations/自动化/ [binary_sensor.deconz docs]: /integrations/deconz#binary-传感器 [binary_sensor.envisalink docs]: /integrations/envisalink [binary_sensor.hydrawise docs]: /integrations/hydrawise#binary-传感器 [binary_sensor.nest docs]: /integrations/nest#binary-传感器 [binary_sensor.rainmachine docs]: /integrations/rainmachine [binary_sensor.random docs]: /integrations/random#binary-传感器 [binary_sensor.xiaomi_aqara docs]: /integrations/binary_sensor.xiaomi_aqara/ [binary_sensor.zha docs]: /integrations/zha [温控.homematicip_cloud docs]: /integrations/homematicip_cloud/ [温控.nest docs]: /integrations/nest#温控 [温控.sensibo docs]: /integrations/sensibo [cloud docs]: /integrations/cloud/ [config docs]: /integrations/config/ [counter docs]: /integrations/counter/ [遮盖.myq docs]: /integrations/myq [device_tracker docs]: /integrations/device_tracker/ [eufy docs]: /integrations/eufy/ [前端 docs]: /integrations/frontend/ [hassio docs]: /integrations/hassio/ [history docs]: /integrations/history/ [homekit docs]: /integrations/homekit/ [homematic docs]: /integrations/homematic/ [homematicip_cloud docs]: /integrations/homematicip_cloud/ [hydrawise docs]: /integrations/hydrawise/ [keyboard_remote docs]: /integrations/keyboard_remote/ [灯光.lw12wifi docs]: /integrations/lw12wifi [灯光.nanoleaf_aurora docs]: /integrations/nanoleaf/ [灯光.osramlightify docs]: /integrations/osramlightify [灯光.zha docs]: /integrations/zha [linode docs]: /integrations/linode/ [门锁.xiaomi_aqara docs]: /integrations/门锁.xiaomi_aqara/ [logbook docs]: /integrations/logbook/ [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.denonavr docs]: /integrations/denonavr/ [媒体播放器.directv docs]: /integrations/directv [媒体播放器.kodi docs]: /integrations/kodi [媒体播放器.philips_js docs]: /integrations/philips_js [nest docs]: /integrations/nest/ [通知 docs]: /integrations/通知/ [panel_custom docs]: /integrations/panel_custom/ [python_script docs]: /integrations/python_script/ [rainbird docs]: /integrations/rainbird/ [raincloud docs]: /integrations/raincloud/ [rainmachine docs]: /integrations/rainmachine/ [传感器.bitcoin docs]: /integrations/bitcoin [传感器.coinmarketcap docs]: /integrations/coinmarketcap [传感器.deconz docs]: /integrations/deconz#传感器 [传感器.gitter docs]: /integrations/gitter [传感器.glances docs]: /integrations/glances [传感器.homematicip_cloud docs]: /integrations/homematicip_cloud/ [传感器.hydrawise docs]: /integrations/hydrawise#传感器 [传感器.iperf3 docs]: /integrations/iperf3 [传感器.luftdaten docs]: /integrations/luftdaten#传感器 [传感器.mfi docs]: /integrations/mfi#传感器 [传感器.nest docs]: /integrations/nest#传感器 [传感器.netatmo docs]: /integrations/netatmo#传感器 [传感器.netdata docs]: /integrations/netdata [传感器.onewire docs]: /integrations/onewire [传感器.rainmachine docs]: /integrations/rainmachine [传感器.random docs]: /integrations/random#传感器 [传感器.shodan docs]: /integrations/shodan [传感器.simulated docs]: /integrations/simulated [传感器.speedtest docs]: /integrations/speedtestdotnet [传感器.swiss_public_transport docs]: /integrations/swiss_public_transport [传感器.transmission docs]: /integrations/transmission [传感器.uptime docs]: /integrations/uptime [传感器.版本 docs]: /integrations/版本 [传感器.worldclock docs]: /integrations/worldclock [传感器.zha docs]: /integrations/zha [shopping_list docs]: /integrations/shopping_list/ [开关.hydrawise docs]: /integrations/hydrawise#开关 [开关.raincloud docs]: /integrations/raincloud#开关 [开关.rainmachine docs]: /integrations/rainmachine#开关 [vera docs]: /integrations/vera/ [xiaomi_aqara docs]: /integrations/xiaomi_aqara/ [zha docs]: /integrations/zha/ [区域 docs]: /integrations/区域/ [zwave docs]: /integrations/zwave/ [@OttoWinter]: https://github.com/OttoWinter [esphomeyaml]: https://esphomelib.com/esphomeyaml/index.html [@c727]: https://github.com/c727 --- url: /home-assistant/blog/2018-06-22-release-72.md --- # 0.72:Lovelace UI、KIWI 门锁、Wireless Tags、Insteon X10 我对这次发布非常兴奋,它很好地展示了我们如何持续打磨系统:一方面更可定制,另一方面也更用户友好。最让我激动的是全新的实验性用户界面,我们称它为 Lovelace。可以看看 [@ciotlosm] 整理的[超详细功能总览](https://gist.github.com/ciotlosm/9508388876edf92c4c1f3579e740fbd5)。一句话总结:它更快、更可定制、可扩展性更强,同时保持了与旧版一致的视觉体验。 请注意,这个功能\_仍是实验性\_,后续还会变化。但我们不想再把它“藏着掖着”了。你可以查看 [Lovelace UI 文档](/home-assistant/Lovelace) 快速上手,也别忘了分享你的作品! 感谢所有在 [Discord](https://discord.gg/c5DvZ4e) 的 #beta 频道里参与开发、发现并修复错误、积极提出建议的朋友。特别感谢 [@c727] 的大量开发工作,以及第一位“吃螃蟹”的 [@arsaboo]。

Example 用户 interface 创建 using Lovelace. 使用 Lovelace 创建的用户界面示例([source](https://gist.github.com/ciotlosm/9508388876edf92c4c1f3579e740fbd5#file-ui-Lovelace-yaml))

另一个变化是,Nest、Sonos 和 Cast 现在需要通过配置条目来设置。你可以在配置面板的集成页面创建配置条目。这个机制我们已经开发了几个月,目标是最终把它作为所有组件的统一配置方式。

Screenshot of a browser showing a dialog to link a Nest account to Home Assistant. Nest 配置条目截图。

如果你觉得这次发布已经够丰富了,那还有一个惊喜:感谢 [@teharris1],Insteon 集成现在支持 X10。这是 Insteon 社区长期高频请求的功能。 最后,我们会将 Home Assistant Cloud 的公开测试延长到 9 月 1 日。 祝大家享受这个版本,周末愉快! ## 新平台 * 天气 Platform - IPMA ([@dgomes] - [#14716]) ([天气.ipma docs]) (new-platform) * Add Freebox 设备 tracker ([@stilllman] - [#12727]) ([device\_tracker.freebox docs][device_tracker.freebox docs]) (new-platform) * Add IBM Watson IoT Platform component ([@mtreinish] - [#13664]) ([watson\_iot docs][watson_iot docs]) (new-platform) * Wireless tags platform ([@sergeymaysak] - [#13495]) ([wirelesstag docs]) ([binary\_sensor.wirelesstag docs][binary_sensor.wirelesstag docs]) ([传感器.wirelesstag docs]) ([开关.wirelesstag docs]) (new-platform) * Add netgear\_lte component ([@amelchio] - [#14687]) ([netgear\_lte docs][netgear_lte docs]) ([通知 docs]) ([传感器.netgear\_lte docs][传感器.netgear_lte docs]) (new-platform) * Add Uptime Robot 传感器 ([@ludeeus] - [#14631]) ([binary\_sensor.uptimerobot docs][binary_sensor.uptimerobot docs]) (new-platform) * Add support for the Unitymedia Horizon HD Recorder ([@benleb] - [#14275]) ([媒体播放器.horizon docs]) (new-platform) * Add support for KIWI Door 门锁 ([@c7h] - [#14485]) ([门锁.kiwi docs]) (new-platform) * Epson projector support ([@pszafer] - [#14841]) ([媒体播放器.epson docs]) (new-platform) * Add 传感器.nsw\_fuel\_station component ([@nickw444] - [#14757]) ([传感器.nsw\_fuel\_station docs][传感器.nsw_fuel_station docs]) (new-platform) * Add support for ZhongHong HVAC Controllers ([@crhan] - [#14552]) ([温控.zhong\_hong docs][温控.zhong_hong docs]) (new-platform) * Xiaomi 摄像头 - multiple models ([@vaidyasr] - [#14244]) ([摄像头.xiaomi docs]) (new-platform) ## 发布 0.72.1 - 6 月 25 日 * Prevent Nest component 设置 crash due insufficient permission. ([@awarecan] - [#14966]) ([nest docs]) * Fix socket bug with Yi in 0.72 ([@bachya] - [#15109]) ([摄像头.yi docs]) * Skip nest security 状态 传感器 if no Nest Cam exists ([@awarecan] - [#15112]) ([传感器.nest docs]) * Fix cast config ([@balloob] - [#15143]) ([媒体播放器.cast docs]) * Bump python-nest to 4.0.3 ([@awarecan] - [#15098]) ([nest docs]) ([传感器.nest docs]) ## 如果你需要帮助... ...欢迎随时访问我们非常活跃的 [论坛](https://community.home-assistant.io/),或加入我们的 [聊天频道](https://discord.gg/c5DvZ4e)。虽然发布说明开放评论,但我们更推荐你使用前面的沟通渠道。谢谢。 ## 报告问题 如果你遇到了此版本引入的问题,请在我们的 [问题追踪器](https://github.com/home-assistant/home-assistant/issues) 中提交报告。请务必填写问题模板中的所有字段。 ## Backward-incompatible changes * For 开发者 of custom 面板: Remove ability to register 面板 directly with the 前端 component. Register with custom 面板 component instead. ([@balloob] - [#14805]) ([前端 docs]) (breaking change) * Rename Hive hub friendly name to include "Hive" name ([@SteveEdson] - [#14747]) ([传感器.hive docs]) (breaking change) * Homematic: RotaryHandleSensorIP 状态 will now report open, tilt, closed ([@hanzoh] - [#14885]) ([传感器.homematic docs]) (breaking change) * Add support for multiple Doorbird stations ([@oblogic7] - [#13994]) ([doorbird docs]) ([摄像头.doorbird docs]) ([开关.doorbird docs]) (breaking change) * AirVisual: The radius 配置 parameter no longer does anything and has been removed. This won't negatively impact any existing 集成. Second, this PR will modify the unique IDs for each 传感器 to correctly include the locale. New unique IDs will now include *us* and *cn* ([@bachya] - [#14943]) ([传感器.airvisual docs]) (breaking change) * Sonos and Cast are now configured via config entries. Go to the 集成 tab in config 面板 to set it up. ([@balloob] - [#14955]) ([媒体播放器 docs]) ([sonos docs]) ([媒体播放器.sonos docs]) (breaking change) * Eight Sleep add REM type, 更新 async syntax, Catch API quirks ([@mezz64] - [#14937]) ([eight\_sleep docs][eight_sleep docs]) ([binary\_sensor.eight\_sleep docs][binary_sensor.eight_sleep docs]) ([传感器.eight\_sleep docs][传感器.eight_sleep docs]) (breaking change) * Fix energy meter for HS110 v2 用户. Not a breaking change unless you are using a custom component ([@rytilahti] - [#15001]) ([灯光.tplink docs]) ([开关.tplink docs]) (breaking change) (beta fix) ## Beta Fixes * Remove load power 属性 for channel USB ([@syssi] - [#14996]) ([开关.xiaomi\_miio docs][开关.xiaomi_miio docs]) (beta fix) * 开关 to own packaged 版本 of spotipy ([@andrey-git] - [#14997]) ([媒体播放器.spotify docs]) (beta fix) * Bump pyhs100 版本 ([@rytilahti] - [#15001]) ([灯光.tplink docs]) ([开关.tplink docs]) (breaking change) (beta fix) * Add experimental UI 后端 ([@balloob] - [#15002]) ([前端 docs]) (beta fix) * Fix 面板 URL 认证 for Hass.io ([@pvizeli] - [#15024]) ([hassio docs]) (beta fix) * Fix linode I/O in 状态 property ([@MartinHjelmare] - [#15010]) ([binary\_sensor.linode docs][binary_sensor.linode docs]) ([开关.linode docs]) (beta fix) * 升级 aiohttp to 3.3.2 ([@fabaff] - [#15025]) (beta fix) * Make 区域 entries work without radius ([@balloob] - [#15032]) ([区域 docs]) (beta fix) * Bugfix empty 实体 lists ([@pvizeli] - [#15035]) (beta fix) * Rename experimental UI to Lovelace ([@balloob] - [#15065]) ([前端 docs]) (beta fix) * X10 ([@teharris1] - [#14741]) ([insteon\_plm docs][insteon_plm docs]) ([开关.insteon\_plm docs][开关.insteon_plm docs]) (beta fix) * Fix MQTT 灯光 with RGB and Brightness ([@thinkl33t] - [#15053]) ([灯光.MQTT docs]) (beta fix) * 更新 Neato Library And Reduce Cloud Calls ([@dshokouhi] - [#15072]) ([neato docs]) ([摄像头.neato docs]) ([开关.neato docs]) ([吸尘器.neato docs]) (beta fix) ## All changes * 天气 Platform - IPMA ([@dgomes] - [#14716]) ([天气.ipma docs]) (new-platform) * Add additional 86sw model identifier of the LAN protocol V2 ([@syssi] - [#14799]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) ([binary\_sensor.xiaomi\_aqara docs][binary_sensor.xiaomi_aqara docs]) * Allow Kodi live streams to be recognized as paused ([@quthla] - [#14623]) ([媒体播放器.kodi docs]) * 更新 syntax ([@fabaff] - [#14812]) ([传感器.moon docs]) * Use pihole module to get data ([@fabaff] - [#14809]) ([传感器.pi\_hole docs][传感器.pi_hole docs]) * Bump python-miio 版本 (Closes: #13749) ([@syssi] - [#14796]) ([device\_tracker docs][device_tracker docs]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) ([遥控器.xiaomi\_miio docs][遥控器.xiaomi_miio docs]) ([传感器.xiaomi\_miio docs][传感器.xiaomi_miio docs]) ([开关.xiaomi\_miio docs][开关.xiaomi_miio docs]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) * Further cleanup 前端 ([@balloob] - [#14805]) ([前端 docs]) (breaking change) * netatmo api is now in pip as pyatmo ([@jabesq] - [#14824]) ([netatmo docs]) ([binary\_sensor.netatmo docs][binary_sensor.netatmo docs]) ([摄像头.netatmo docs]) ([温控.netatmo docs]) ([传感器.netatmo docs]) * 动作 parameter doesn't longer have to be the first parameter ([@GruberMischa] - [#14815]) ([binary\_sensor.mystrom docs][binary_sensor.mystrom docs]) * Fixes an issue in Xiaomi TV platform that would some TVs not sleep correctly ([@simse] - [#14829]) ([媒体播放器.xiaomi\_tv docs][媒体播放器.xiaomi_tv docs]) * Improved Fritz!Box thermostat support ([@thomaskr] - [#14789]) ([温控.fritzbox docs]) * Add Freebox 设备 tracker ([@stilllman] - [#12727]) ([device\_tracker.freebox docs][device_tracker.freebox docs]) (new-platform) * Migrate 实体 registry to using websocket ([@balloob] - [#14830]) ([config docs]) * Route themes and translations over websocket ([@balloob] - [#14828]) ([前端 docs]) ([websocket\_api docs][websocket_api docs]) * Feature/gearbest library 更新 (Closes: #14813) ([@HerrHofrat] - [#14833]) * Ignore the mistaken long\_both\_click event of the 86sw (Closes: #14802) ([@syssi] - [#14808]) ([binary\_sensor.xiaomi\_aqara docs][binary_sensor.xiaomi_aqara docs]) * Fix non awaited test ([@balloob] - [#14854]) * 更新 Hue flow title ([@balloob] - [#14852]) ([hue docs]) * 升级 Mastodon.py to 1.3.0 ([@fabaff] - [#14858]) * Improvements to LIFX reliability ([@amelchio] - [#14848]) ([灯光.lifx docs]) * Add general sound mode support ([@starkillerOG] - [#14729]) ([媒体播放器 docs]) * Add IBM Watson IoT Platform component ([@mtreinish] - [#13664]) ([watson\_iot docs][watson_iot docs]) (new-platform) * 升级 aiohttp to 3.3.0 ([@fabaff] - [#14766]) * Add min\_temp and max\_temp to MQTT 温控 设备 ([@PhilRW] - [#14690]) ([温控.MQTT docs]) * Store config entry id in 实体 registry ([@balloob] - [#14851]) * Catch ConnectionError (fixes #14241) ([@fabaff] - [#14748]) ([媒体播放器.yamaha docs]) * Don't run unnecessary methods in executor pool ([@balloob] - [#14853]) * Wireless tags platform ([@sergeymaysak] - [#13495]) ([wirelesstag docs]) ([binary\_sensor.wirelesstag docs][binary_sensor.wirelesstag docs]) ([传感器.wirelesstag docs]) ([开关.wirelesstag docs]) (new-platform) * Fix door/window 传感器 support of the Xiaomi Aqara LAN protocol V2 (Closes: #14775) ([@syssi] - [#14777]) ([binary\_sensor.xiaomi\_aqara docs][binary_sensor.xiaomi_aqara docs]) * zha: handle "step\_with\_on\_off" cluster command in LevelListener. ([@Adminiuga] - [#14756]) ([binary\_sensor.zha docs][binary_sensor.zha docs]) * Rename Hive hub friendly name ([@SteveEdson] - [#14747]) ([传感器.hive docs]) (breaking change) * Add set\_default\_level to logger ([@dale3h] - [#14703]) ([logger docs]) * Fix unit conversion ([@dgomes] - [#14730]) ([温控.generic\_thermostat docs][温控.generic_thermostat docs]) ([温控.sensibo docs]) ([温控.tado docs]) * Disable volume control for Onkyo when unavailable (Closes: #14774) ([@snikch] - [#14863]) ([媒体播放器.onkyo docs]) * Add netgear\_lte component ([@amelchio] - [#14687]) ([netgear\_lte docs][netgear_lte docs]) ([通知 docs]) ([传感器.netgear\_lte docs][传感器.netgear_lte docs]) (new-platform) * Add support for new hass.io 面板 ([@balloob] - [#14873]) ([hassio docs]) ([panel\_custom docs][panel_custom docs]) * Add color\_status 传感器 for Nest Protect ([@awarecan] - [#14868]) ([传感器.nest docs]) * UVC 摄像头 platform handling unavailable NVR or 摄像头 better ([@exxamalte] - [#14864]) ([摄像头.uvc docs]) * Samsung TV can't 关闭 after idle period ([@ejel] - [#14587]) ([媒体播放器.samsungtv docs]) * Discover Qubino ZMHTDx smart meter 开关 ([@turbokongen] - [#14884]) ([zwave docs]) * Add missing mapping of RotaryHandleSensorIP 状态 ([@hanzoh] - [#14885]) ([传感器.homematic docs]) (breaking change) * Add 实体 registry support to 媒体播放器.snapcast ([@jedi7] - [#14895]) ([媒体播放器.snapcast docs]) * Allow different identifiers for the CPU temperature (fixes #10104) ([@fabaff] - [#14898]) ([传感器.glances docs]) * Make RainMachine async ([@bachya] - [#14879]) ([rainmachine docs]) ([binary\_sensor.rainmachine docs][binary_sensor.rainmachine docs]) ([传感器.rainmachine docs]) ([开关.rainmachine docs]) * Add Uptime Robot 传感器 ([@ludeeus] - [#14631]) ([binary\_sensor.uptimerobot docs][binary_sensor.uptimerobot docs]) (new-platform) * 升级 python\_opendata\_transport to 0.1.3 ([@fabaff] - [#14905]) ([传感器.swiss\_public\_transport docs][传感器.swiss_public_transport docs]) * 升级 psutil to 5.4.6 ([@fabaff] - [#14892]) ([传感器.systemmonitor docs]) * 升级 sendgrid to 5.4.0 ([@fabaff] - [#14891]) ([通知 docs]) * 升级 python-mystrom to 0.4.4 ([@fabaff] - [#14889]) ([灯光.mystrom docs]) ([开关.mystrom docs]) * 升级 pylast to 2.3.0 ([@fabaff] - [#14888]) ([传感器.lastfm docs]) * Added daily and hourly modes to Openweathermap ([@sgttrs] - [#14875]) ([天气.openweathermap docs]) * Bump to denonavr 0.7.3 ([@klada] - [#14907]) ([媒体播放器.denonavr docs]) * Add api\_host option to Konnected config ([@heythisisnate] - [#14896]) ([konnected docs]) * Add support for the Unitymedia Horizon HD Recorder ([@benleb] - [#14275]) ([媒体播放器.horizon docs]) (new-platform) * Add support for multiple Doorbird stations ([@oblogic7] - [#13994]) ([doorbird docs]) ([摄像头.doorbird docs]) ([开关.doorbird docs]) (breaking change) * 更新 mqtt\_eventstream.py ([@molobrakos] - [#14923]) ([mqtt\_eventstream docs][mqtt_eventstream docs]) * 升级 python-nest, add security\_state 传感器, nest.set\_mode 服务 set ETA as well ([@awarecan] - [#14901]) ([nest docs]) ([传感器.nest docs]) * Add more test cases for samsungtv ([@ejel] - [#14900]) * Refactored Arlo component and enhanced Arlo API queries and times ([@tchellomello] - [#14823]) ([arlo docs]) ([alarm\_control\_panel.arlo docs][alarm_control_panel.arlo docs]) ([摄像头.arlo docs]) ([传感器.arlo docs]) * Use cv.time\_period instead of cv.time\_period\_str ([@awarecan] - [#14938]) ([nest docs]) * Add support for KIWI Door 门锁 ([@c7h] - [#14485]) ([门锁.kiwi docs]) (new-platform) * Fix snapcast uuid to be more unique ([@jedi7] - [#14925]) ([媒体播放器.snapcast docs]) * pytradfri 5.5.1: Improved 3rd party bulb support ([@Hate-Usernames] - [#14887]) ([tradfri docs]) ([灯光.tradfri docs]) * Epson projector support ([@pszafer] - [#14841]) ([媒体播放器.epson docs]) (new-platform) * Add scan\_interval to RainMachine ([@bachya] - [#14945]) ([rainmachine docs]) * Myq 更新 from 0.0.8 to 0.0.11 ([@arraylabs] - [#14947]) ([遮盖.myq docs]) * 升级 pylint to 1.9.2 ([@scop] - [#14916]) * 更新 python-wink to 1.8.0 ([@vickyg3] - [#14894]) ([wink docs]) * Add unique\_id for MQTT 二元sensor ([@ciotlosm] - [#14929]) ([binary\_sensor.MQTT docs][binary_sensor.MQTT docs]) * Make Yi platform async ([@bachya] - [#14944]) ([摄像头.yi docs]) * Nest config flow ([@balloob] - [#14921]) ([nest docs]) * Fix Facebox face data parsing ([@robmarkcole] - [#14951]) ([image\_processing.facebox docs][image_processing.facebox docs]) * Add 传感器.nsw\_fuel\_station component ([@nickw444] - [#14757]) ([传感器.nsw\_fuel\_station docs][传感器.nsw_fuel_station docs]) (new-platform) * Make AirVisual platform async + other adjustments ([@bachya] - [#14943]) ([传感器.airvisual docs]) (breaking change) * Add support for ZhongHong HVAC Controllers ([@crhan] - [#14552]) ([温控.zhong\_hong docs][温控.zhong_hong docs]) (new-platform) * Fix tests ([@balloob] - [#14959]) * add relative time option to simulated 传感器 ([@Shou] - [#14038]) ([传感器.simulated docs]) * Add config entry for Sonos + Cast ([@balloob] - [#14955]) ([媒体播放器 docs]) ([sonos docs]) ([媒体播放器.sonos docs]) (breaking change) * Fix smappee component - "错误 on 设备 更新" ([@bachya] - [#14883]) ([传感器.smappee docs]) * Adhere to scan\_interval in platforms when 设置 via config entry ([@balloob] - [#14969]) * Add 日历 API endpoint to get events ([@titilambert] - [#14702]) ([日历 docs]) ([日历.caldav docs]) * Add 日历 面板, add tests ([@balloob] - [#14973]) ([日历 docs]) * Xiaomi 摄像头 - multiple models ([@vaidyasr] - [#14244]) ([摄像头.xiaomi docs]) (new-platform) * Fix binary\_sensor.skybell 状态 更新 when there are no events ([@trisk] - [#14927]) ([binary\_sensor.skybell docs][binary_sensor.skybell docs]) ([传感器.skybell docs]) * Deconz make groups configurable ([@Kane610] - [#14704]) ([deconz docs]) ([灯光.deconz docs]) * Show 通知 when 用户 configures Nest client\_id/secret ([@balloob] - [#14970]) ([hue docs]) ([nest docs]) * Eight Sleep add REM type, 更新 async syntax, Catch API quirks ([@mezz64] - [#14937]) ([eight\_sleep docs][eight_sleep docs]) ([binary\_sensor.eight\_sleep docs][binary_sensor.eight_sleep docs]) ([传感器.eight\_sleep docs][传感器.eight_sleep docs]) (breaking change) * Return ISO formated datetime in forecast ([@c727] - [#14975]) ([天气.ecobee docs]) * Remove inline pylint disables for messages disabled in pylintrc ([@scop] - [#14978]) * Add availability to Rflink 实体. ([@aequitas] - [#14977]) ([rflink docs]) * 升级 ring\_doorbell to 0.2.1 to fix oauth issues ([@tchellomello] - [#14984]) ([ring docs]) * Fix extended package support ([@cdce8p] - [#14980]) * Upgraded PyArlo to 0.1.7 ([@tchellomello] - [#14987]) ([arlo docs]) * Upgraded python-amcrest to 1.2.3 ([@tchellomello] - [#14988]) ([amcrest docs]) * Upgraded RainCloudy to 版本 0.0.5 ([@tchellomello] - [#14986]) ([raincloud docs]) * Do not mount deps folder when running in virtual env ([@balloob] - [#14993]) * Refactoring 摄像头 component to use async/await syntax. ([@awarecan] - [#14990]) ([摄像头 docs]) * Remove load power 属性 for channel USB ([@syssi] - [#14996]) ([开关.xiaomi\_miio docs][开关.xiaomi_miio docs]) (beta fix) * 开关 to own packaged 版本 of spotipy ([@andrey-git] - [#14997]) ([媒体播放器.spotify docs]) (beta fix) * Bump pyhs100 版本 ([@rytilahti] - [#15001]) ([灯光.tplink docs]) ([开关.tplink docs]) (breaking change) (beta fix) * Add experimental UI 后端 ([@balloob] - [#15002]) ([前端 docs]) (beta fix) * Fix 面板 URL 认证 for Hass.io ([@pvizeli] - [#15024]) ([hassio docs]) (beta fix) * Fix linode I/O in 状态 property ([@MartinHjelmare] - [#15010]) ([binary\_sensor.linode docs][binary_sensor.linode docs]) ([开关.linode docs]) (beta fix) * 升级 aiohttp to 3.3.2 ([@fabaff] - [#15025]) (beta fix) * Make 区域 entries work without radius ([@balloob] - [#15032]) ([区域 docs]) (beta fix) * Bugfix empty 实体 lists ([@pvizeli] - [#15035]) (beta fix) * Rename experimental UI to Lovelace ([@balloob] - [#15065]) ([前端 docs]) (beta fix) * X10 ([@teharris1] - [#14741]) ([insteon\_plm docs][insteon_plm docs]) ([开关.insteon\_plm docs][开关.insteon_plm docs]) (beta fix) * Fix MQTT 灯光 with RGB and Brightness ([@thinkl33t] - [#15053]) ([灯光.MQTT docs]) (beta fix) * 更新 Neato Library And Reduce Cloud Calls ([@dshokouhi] - [#15072]) ([neato docs]) ([摄像头.neato docs]) ([开关.neato docs]) ([吸尘器.neato docs]) (beta fix) [#12727]: https://github.com/home-assistant/home-assistant/pull/12727 [#13495]: https://github.com/home-assistant/home-assistant/pull/13495 [#13664]: https://github.com/home-assistant/home-assistant/pull/13664 [#13994]: https://github.com/home-assistant/home-assistant/pull/13994 [#14038]: https://github.com/home-assistant/home-assistant/pull/14038 [#14244]: https://github.com/home-assistant/home-assistant/pull/14244 [#14275]: https://github.com/home-assistant/home-assistant/pull/14275 [#14485]: https://github.com/home-assistant/home-assistant/pull/14485 [#14552]: https://github.com/home-assistant/home-assistant/pull/14552 [#14587]: https://github.com/home-assistant/home-assistant/pull/14587 [#14623]: https://github.com/home-assistant/home-assistant/pull/14623 [#14631]: https://github.com/home-assistant/home-assistant/pull/14631 [#14687]: https://github.com/home-assistant/home-assistant/pull/14687 [#14690]: https://github.com/home-assistant/home-assistant/pull/14690 [#14702]: https://github.com/home-assistant/home-assistant/pull/14702 [#14703]: https://github.com/home-assistant/home-assistant/pull/14703 [#14704]: https://github.com/home-assistant/home-assistant/pull/14704 [#14716]: https://github.com/home-assistant/home-assistant/pull/14716 [#14729]: https://github.com/home-assistant/home-assistant/pull/14729 [#14730]: https://github.com/home-assistant/home-assistant/pull/14730 [#14741]: https://github.com/home-assistant/home-assistant/pull/14741 [#14747]: https://github.com/home-assistant/home-assistant/pull/14747 [#14748]: https://github.com/home-assistant/home-assistant/pull/14748 [#14756]: https://github.com/home-assistant/home-assistant/pull/14756 [#14757]: https://github.com/home-assistant/home-assistant/pull/14757 [#14766]: https://github.com/home-assistant/home-assistant/pull/14766 [#14777]: https://github.com/home-assistant/home-assistant/pull/14777 [#14789]: https://github.com/home-assistant/home-assistant/pull/14789 [#14796]: https://github.com/home-assistant/home-assistant/pull/14796 [#14799]: https://github.com/home-assistant/home-assistant/pull/14799 [#14805]: https://github.com/home-assistant/home-assistant/pull/14805 [#14808]: https://github.com/home-assistant/home-assistant/pull/14808 [#14809]: https://github.com/home-assistant/home-assistant/pull/14809 [#14812]: https://github.com/home-assistant/home-assistant/pull/14812 [#14815]: https://github.com/home-assistant/home-assistant/pull/14815 [#14823]: https://github.com/home-assistant/home-assistant/pull/14823 [#14824]: https://github.com/home-assistant/home-assistant/pull/14824 [#14828]: https://github.com/home-assistant/home-assistant/pull/14828 [#14829]: https://github.com/home-assistant/home-assistant/pull/14829 [#14830]: https://github.com/home-assistant/home-assistant/pull/14830 [#14833]: https://github.com/home-assistant/home-assistant/pull/14833 [#14841]: https://github.com/home-assistant/home-assistant/pull/14841 [#14848]: https://github.com/home-assistant/home-assistant/pull/14848 [#14851]: https://github.com/home-assistant/home-assistant/pull/14851 [#14852]: https://github.com/home-assistant/home-assistant/pull/14852 [#14853]: https://github.com/home-assistant/home-assistant/pull/14853 [#14854]: https://github.com/home-assistant/home-assistant/pull/14854 [#14858]: https://github.com/home-assistant/home-assistant/pull/14858 [#14863]: https://github.com/home-assistant/home-assistant/pull/14863 [#14864]: https://github.com/home-assistant/home-assistant/pull/14864 [#14868]: https://github.com/home-assistant/home-assistant/pull/14868 [#14873]: https://github.com/home-assistant/home-assistant/pull/14873 [#14875]: https://github.com/home-assistant/home-assistant/pull/14875 [#14879]: https://github.com/home-assistant/home-assistant/pull/14879 [#14883]: https://github.com/home-assistant/home-assistant/pull/14883 [#14884]: https://github.com/home-assistant/home-assistant/pull/14884 [#14885]: https://github.com/home-assistant/home-assistant/pull/14885 [#14887]: https://github.com/home-assistant/home-assistant/pull/14887 [#14888]: https://github.com/home-assistant/home-assistant/pull/14888 [#14889]: https://github.com/home-assistant/home-assistant/pull/14889 [#14891]: https://github.com/home-assistant/home-assistant/pull/14891 [#14892]: https://github.com/home-assistant/home-assistant/pull/14892 [#14894]: https://github.com/home-assistant/home-assistant/pull/14894 [#14895]: https://github.com/home-assistant/home-assistant/pull/14895 [#14896]: https://github.com/home-assistant/home-assistant/pull/14896 [#14898]: https://github.com/home-assistant/home-assistant/pull/14898 [#14900]: https://github.com/home-assistant/home-assistant/pull/14900 [#14901]: https://github.com/home-assistant/home-assistant/pull/14901 [#14905]: https://github.com/home-assistant/home-assistant/pull/14905 [#14907]: https://github.com/home-assistant/home-assistant/pull/14907 [#14916]: https://github.com/home-assistant/home-assistant/pull/14916 [#14921]: https://github.com/home-assistant/home-assistant/pull/14921 [#14923]: https://github.com/home-assistant/home-assistant/pull/14923 [#14925]: https://github.com/home-assistant/home-assistant/pull/14925 [#14927]: https://github.com/home-assistant/home-assistant/pull/14927 [#14929]: https://github.com/home-assistant/home-assistant/pull/14929 [#14937]: https://github.com/home-assistant/home-assistant/pull/14937 [#14938]: https://github.com/home-assistant/home-assistant/pull/14938 [#14943]: https://github.com/home-assistant/home-assistant/pull/14943 [#14944]: https://github.com/home-assistant/home-assistant/pull/14944 [#14945]: https://github.com/home-assistant/home-assistant/pull/14945 [#14947]: https://github.com/home-assistant/home-assistant/pull/14947 [#14951]: https://github.com/home-assistant/home-assistant/pull/14951 [#14955]: https://github.com/home-assistant/home-assistant/pull/14955 [#14959]: https://github.com/home-assistant/home-assistant/pull/14959 [#14969]: https://github.com/home-assistant/home-assistant/pull/14969 [#14970]: https://github.com/home-assistant/home-assistant/pull/14970 [#14973]: https://github.com/home-assistant/home-assistant/pull/14973 [#14975]: https://github.com/home-assistant/home-assistant/pull/14975 [#14977]: https://github.com/home-assistant/home-assistant/pull/14977 [#14978]: https://github.com/home-assistant/home-assistant/pull/14978 [#14980]: https://github.com/home-assistant/home-assistant/pull/14980 [#14984]: https://github.com/home-assistant/home-assistant/pull/14984 [#14986]: https://github.com/home-assistant/home-assistant/pull/14986 [#14987]: https://github.com/home-assistant/home-assistant/pull/14987 [#14988]: https://github.com/home-assistant/home-assistant/pull/14988 [#14990]: https://github.com/home-assistant/home-assistant/pull/14990 [#14993]: https://github.com/home-assistant/home-assistant/pull/14993 [#14996]: https://github.com/home-assistant/home-assistant/pull/14996 [#14997]: https://github.com/home-assistant/home-assistant/pull/14997 [#15001]: https://github.com/home-assistant/home-assistant/pull/15001 [#15002]: https://github.com/home-assistant/home-assistant/pull/15002 [#15010]: https://github.com/home-assistant/home-assistant/pull/15010 [#15024]: https://github.com/home-assistant/home-assistant/pull/15024 [#15025]: https://github.com/home-assistant/home-assistant/pull/15025 [#15032]: https://github.com/home-assistant/home-assistant/pull/15032 [#15035]: https://github.com/home-assistant/home-assistant/pull/15035 [#15053]: https://github.com/home-assistant/home-assistant/pull/15053 [#15065]: https://github.com/home-assistant/home-assistant/pull/15065 [#15072]: https://github.com/home-assistant/home-assistant/pull/15072 [@Adminiuga]: https://github.com/Adminiuga [@GruberMischa]: https://github.com/GruberMischa [@Hate-Usernames]: https://github.com/Hate-Usernames [@HerrHofrat]: https://github.com/HerrHofrat [@Kane610]: https://github.com/Kane610 [@MartinHjelmare]: https://github.com/MartinHjelmare [@PhilRW]: https://github.com/PhilRW [@Shou]: https://github.com/Shou [@SteveEdson]: https://github.com/SteveEdson [@aequitas]: https://github.com/aequitas [@amelchio]: https://github.com/amelchio [@arsaboo]: https://github.com/arsaboo [@andrey-git]: https://github.com/andrey-git [@arraylabs]: https://github.com/arraylabs [@awarecan]: https://github.com/awarecan [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@benleb]: https://github.com/benleb [@c727]: https://github.com/c727 [@c7h]: https://github.com/c7h [@cdce8p]: https://github.com/cdce8p [@ciotlosm]: https://github.com/ciotlosm [@crhan]: https://github.com/crhan [@dale3h]: https://github.com/dale3h [@dgomes]: https://github.com/dgomes [@dshokouhi]: https://github.com/dshokouhi [@ejel]: https://github.com/ejel [@exxamalte]: https://github.com/exxamalte [@fabaff]: https://github.com/fabaff [@hanzoh]: https://github.com/hanzoh [@heythisisnate]: https://github.com/heythisisnate [@jabesq]: https://github.com/jabesq [@jedi7]: https://github.com/jedi7 [@klada]: https://github.com/klada [@ludeeus]: https://github.com/ludeeus [@mezz64]: https://github.com/mezz64 [@molobrakos]: https://github.com/molobrakos [@mtreinish]: https://github.com/mtreinish [@nickw444]: https://github.com/nickw444 [@oblogic7]: https://github.com/oblogic7 [@pszafer]: https://github.com/pszafer [@pvizeli]: https://github.com/pvizeli [@quthla]: https://github.com/quthla [@robmarkcole]: https://github.com/robmarkcole [@rytilahti]: https://github.com/rytilahti [@scop]: https://github.com/scop [@sergeymaysak]: https://github.com/sergeymaysak [@sgttrs]: https://github.com/sgttrs [@simse]: https://github.com/simse [@snikch]: https://github.com/snikch [@starkillerOG]: https://github.com/starkillerOG [@stilllman]: https://github.com/stilllman [@syssi]: https://github.com/syssi [@tchellomello]: https://github.com/tchellomello [@teharris1]: https://github.com/teharris1 [@thinkl33t]: https://github.com/thinkl33t [@thomaskr]: https://github.com/thomaskr [@titilambert]: https://github.com/titilambert [@trisk]: https://github.com/trisk [@turbokongen]: https://github.com/turbokongen [@vaidyasr]: https://github.com/vaidyasr [@vickyg3]: https://github.com/vickyg3 [alarm_control_panel.arlo docs]: /integrations/arlo [amcrest docs]: /integrations/amcrest/ [arlo docs]: /integrations/arlo/ [binary_sensor.eight_sleep docs]: /integrations/eight_sleep [binary_sensor.linode docs]: /integrations/linode#binary-传感器 [binary_sensor.MQTT docs]: /integrations/binary_sensor.MQTT/ [binary_sensor.mystrom docs]: /integrations/mystrom#binary-传感器 [binary_sensor.netatmo docs]: /integrations/netatmo#binary-传感器 [binary_sensor.rainmachine docs]: /integrations/rainmachine [binary_sensor.skybell docs]: /integrations/skybell#binary-传感器 [binary_sensor.uptimerobot docs]: /integrations/uptimerobot [binary_sensor.wirelesstag docs]: /integrations/wirelesstag#binary-传感器 [binary_sensor.xiaomi_aqara docs]: /integrations/binary_sensor.xiaomi_aqara/ [binary_sensor.zha docs]: /integrations/zha [日历 docs]: /integrations/日历/ [日历.caldav docs]: /integrations/caldav [摄像头 docs]: /integrations/摄像头/ [摄像头.arlo docs]: /integrations/arlo#摄像头 [摄像头.doorbird docs]: /integrations/doorbird#摄像头 [摄像头.neato docs]: /integrations/neato#摄像头 [摄像头.netatmo docs]: /integrations/netatmo#摄像头 [摄像头.uvc docs]: /integrations/uvc [摄像头.xiaomi docs]: /integrations/xiaomi_aqara [摄像头.yi docs]: /integrations/yi [温控.fritzbox docs]: /integrations/fritzbox [温控.generic_thermostat docs]: /integrations/generic_thermostat [温控.MQTT docs]: /integrations/温控.MQTT/ [温控.netatmo docs]: /integrations/netatmo#温控 [温控.sensibo docs]: /integrations/sensibo [温控.tado docs]: /integrations/tado [温控.zhong_hong docs]: /integrations/zhong_hong [config docs]: /integrations/config/ [遮盖.myq docs]: /integrations/myq [deconz docs]: /integrations/deconz/ [device_tracker docs]: /integrations/device_tracker/ [device_tracker.freebox docs]: /integrations/freebox [doorbird docs]: /integrations/doorbird/ [eight_sleep docs]: /integrations/eight_sleep/ [风扇.xiaomi_miio docs]: /integrations/风扇.xiaomi_miio/ [前端 docs]: /integrations/frontend/ [hassio docs]: /integrations/hassio/ [hue docs]: /integrations/hue/ [image_processing.facebox docs]: /integrations/facebox [insteon_plm docs]: /integrations/insteon/ [konnected docs]: /integrations/konnected/ [灯光.deconz docs]: /integrations/deconz#灯光 [灯光.lifx docs]: /integrations/lifx [灯光.MQTT docs]: /integrations/灯光.MQTT/ [灯光.mystrom docs]: /integrations/mystrom#灯光 [灯光.tplink docs]: /integrations/tplink [灯光.tradfri docs]: /integrations/tradfri [灯光.xiaomi_miio docs]: /integrations/灯光.xiaomi_miio/ [门锁.kiwi docs]: /integrations/kiwi [logger docs]: /integrations/logger/ [媒体播放器 docs]: /integrations/媒体播放器/ [媒体播放器.denonavr docs]: /integrations/denonavr/ [媒体播放器.epson docs]: /integrations/epson [媒体播放器.horizon docs]: /integrations/horizon [媒体播放器.kodi docs]: /integrations/kodi [媒体播放器.onkyo docs]: /integrations/onkyo [媒体播放器.samsungtv docs]: /integrations/samsungtv [媒体播放器.snapcast docs]: /integrations/snapcast [媒体播放器.sonos docs]: /integrations/sonos [媒体播放器.spotify docs]: /integrations/spotify [媒体播放器.xiaomi_tv docs]: /integrations/xiaomi_tv [媒体播放器.yamaha docs]: /integrations/yamaha [mqtt_eventstream docs]: /integrations/mqtt_eventstream/ [neato docs]: /integrations/neato/ [nest docs]: /integrations/nest/ [netatmo docs]: /integrations/netatmo/ [netgear_lte docs]: /integrations/netgear_lte/ [通知 docs]: /integrations/通知/ [panel_custom docs]: /integrations/panel_custom/ [raincloud docs]: /integrations/raincloud/ [rainmachine docs]: /integrations/rainmachine/ [遥控器.xiaomi_miio docs]: /integrations/遥控器.xiaomi_miio/ [rflink docs]: /integrations/rflink/ [ring docs]: /integrations/ring/ [传感器.airvisual docs]: /integrations/airvisual [传感器.arlo docs]: /integrations/arlo#传感器 [传感器.eight_sleep docs]: /integrations/eight_sleep [传感器.glances docs]: /integrations/glances [传感器.hive docs]: /integrations/hive#传感器 [传感器.homematic docs]: /integrations/homematic [传感器.lastfm docs]: /integrations/lastfm [传感器.moon docs]: /integrations/moon [传感器.nest docs]: /integrations/nest#传感器 [传感器.netatmo docs]: /integrations/netatmo#传感器 [传感器.netgear_lte docs]: /integrations/netgear_lte [传感器.nsw_fuel_station docs]: /integrations/nsw_fuel_station [传感器.pi_hole docs]: /integrations/pi_hole [传感器.rainmachine docs]: /integrations/rainmachine [传感器.simulated docs]: /integrations/simulated [传感器.skybell docs]: /integrations/skybell#传感器 [传感器.smappee docs]: /integrations/sma#sensorsppee/ [传感器.swiss_public_transport docs]: /integrations/swiss_public_transport [传感器.systemmonitor docs]: /integrations/systemmonitor [传感器.wirelesstag docs]: /integrations/wirelesstag#传感器 [传感器.xiaomi_miio docs]: /integrations/传感器.xiaomi_miio/ [sonos docs]: /integrations/sonos/ [开关.doorbird docs]: /integrations/doorbird#开关 [开关.insteon_plm docs]: /integrations/insteon/ [开关.linode docs]: /integrations/linode#开关 [开关.mystrom docs]: /integrations/mystrom#开关 [开关.neato docs]: /integrations/neato#开关 [开关.rainmachine docs]: /integrations/rainmachine#开关 [开关.tplink docs]: /integrations/tplink [开关.wirelesstag docs]: /integrations/wirelesstag#开关 [开关.xiaomi_miio docs]: /integrations/开关.xiaomi_miio/ [tradfri docs]: /integrations/tradfri/ [吸尘器.neato docs]: /integrations/neato#吸尘器 [吸尘器.xiaomi_miio docs]: /integrations/吸尘器.xiaomi_miio/ [watson_iot docs]: /integrations/watson_iot/ [天气.ecobee docs]: /integrations/ecobee [天气.ipma docs]: /integrations/ipma [天气.openweathermap docs]: /integrations/openweathermap#天气 [websocket_api docs]: /integrations/websocket_api/ [wink docs]: /integrations/wink/ [wirelesstag docs]: /integrations/wirelesstag/ [xiaomi_aqara docs]: /integrations/xiaomi_aqara/ [区域 docs]: /integrations/区域/ [zwave docs]: /integrations/zwave/ [#14966]: https://github.com/home-assistant/home-assistant/pull/14966 [#15098]: https://github.com/home-assistant/home-assistant/pull/15098 [#15109]: https://github.com/home-assistant/home-assistant/pull/15109 [#15112]: https://github.com/home-assistant/home-assistant/pull/15112 [#15143]: https://github.com/home-assistant/home-assistant/pull/15143 [@awarecan]: https://github.com/awarecan [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [摄像头.yi docs]: /integrations/yi [媒体播放器.cast docs]: /integrations/cast [nest docs]: /integrations/nest/ [传感器.nest docs]: /integrations/nest#传感器 --- url: /home-assistant/blog/2018-07-06-release-73.md --- # 0.73: Preview version new 用户 system, Rachio cloud push and Lovelace goes Today we're releasing Home Assistant 0.73. First, let's talk security. Home Assistant has a lot of power. It can control all 设备 in your house and know what you're up to. That's why securing it is very important. It's absolutely wrong to connect your instance unsecured to the internet and hope no one will find it. All ports on all computers are regularly scanned by bad actors. Please read [our guidelines thoroughly](/home-assistant/docs/configuration/securing/index.md) and follow them. In the meanwhile, we're also working hard on the new 认证 system. A preview 版本 is included in this 发布, more info on [our developer 博客](https://开发者.home-assistant.io/博客/2018/07/02/trying-new-auth.html). This 发布 also includes a TON of love for the new Lovelace UI. Yes, it's still experimental but daaang, it's already so awesome that you should probably just go ahead and try it out. Thanks to all the devs who have jumped on this: [@c727], [@ciotlosm] and [@jeradM]. We don't have time to go through all the changes in this 发布, but [@ciotlosm] has been keeping a very detailed changelog. I'll just leave this screenshot by [@arsaboo] of the new picture-elements 卡片 and [the Lovelace 配置](https://github.com/arsaboo/homeassistant-config/blob/master/ui-Lovelace.yaml#L15-L158):

Screenshot of a floorplan with 传感器 info and 灯光/摄像头 controls overlayed. The new picture elements 卡片.

And last but not least, [@Klikini] has upgraded Rachio support from cloud polling to cloud push! Now you'll be able to get instantly notified of changes to your sprinklers. NICE! ## New Platforms * Support for Homekit Controller 温控 设备 ([@armills] - [#15057]) ([homekit\_controller docs][homekit_controller docs]) ([温控.homekit\_controller docs][温控.homekit_controller docs]) ([灯光.homekit\_controller docs][灯光.homekit_controller docs]) ([开关.homekit\_controller docs][开关.homekit_controller docs]) (new-platform) * Rachio webhooks ([@Klikini] - [#15111]) ([rachio docs]) ([binary\_sensor.rachio docs][binary_sensor.rachio docs]) ([开关.rachio docs]) (beta fix) (new-platform) ## If you need help... ...don't hesitate to use our very active [forums](https://community.home-assistant.io/) or join us for a little [chat](https://discord.gg/c5DvZ4e). The 发布 notes have comments enabled but it's preferred if you use the former communication channels. Thanks. ## Reporting Issues Experiencing issues introduced by this 发布? Please report them in our [issue tracker](https://github.com/home-assistant/home-assistant/issues). Make sure to fill in all fields of the issue 模板. ## Backward-incompatible changes * The `pi_hole` 传感器 is now limited to `ads_blocked_today` by default and will no longer show all available data. Use [`monitored_conditions`](/home-assistant/integrations/pi_hole.md#monitored_conditions) to list the 传感器 you want. ([@fabaff] - [#15014]) ([传感器.pi\_hole docs][传感器.pi_hole docs]) (breaking change) * 更新 PostNL unit of measure to `packages` to align with UPS ([@keesschollaart81] - [#15023]) (breaking change) * Various 属性 have been relocated to 传感器 that make more sense; additionally, some names are corrected. More info in [#14963] ([@bachya] - [#14963]) ([传感器.pollen docs]) (breaking change) * The filter option for prometheus was aligned with other components ([@alexbarcelo] - [#13738]) ([prometheus docs]) (breaking change) * Change some operation\_modes for Z-Wave 温控 设备 to comply with Home Assistant standards and compatibility with Google Home, Alexa and HomeKit. ([@cdce8p] - [#15162]) ([温控.zwave docs]) (breaking change) * HTTP component: Anyone who has enabled `use_x_forwarded_for` will need to explicitly whitelist their proxy/proxies using the new `trusted_proxies` setting. ([@colinodell] - [#15204]) ([emulated\_hue docs][emulated_hue docs]) ([http docs]) (breaking change) * Stop supporting deprecated TLS ciphers ([@hmmbob] - [#15217]) ([http docs]) (breaking change) * LIFX will no longer report `hs_color`/`rgb_color` and `color_temp` simultaneously. ([@amelchio] - [#15234]) ([灯光.lifx docs]) (breaking change) (beta fix) ## Beta Fixes * Rachio webhooks ([@Klikini] - [#15111]) ([rachio docs]) ([binary\_sensor.rachio docs][binary_sensor.rachio docs]) ([开关.rachio docs]) (beta fix) (new-platform) * Only create front-end client\_id once ([@awarecan] - [#15214]) ([前端 docs]) (beta fix) * Make LIFX color/temperature 属性 mutually exclusive ([@amelchio] - [#15234]) ([灯光.lifx docs]) (beta fix) * Fix an issue when 用户's nest developer account don't have permission ([@awarecan] - [#15237]) ([binary\_sensor.nest docs][binary_sensor.nest docs]) (beta fix) * Revert some changes to 设置.py ([@cdce8p] - [#15248]) (beta fix) ## All changes * Add 实体 support to Waze Travel Time ([@Petro31] - [#14934]) ([传感器.waze\_travel\_time docs][传感器.waze_travel_time docs]) * 开关 to own packaged 版本 of anel\_pwrctrl ([@andrey-git] - [#15011]) ([开关.anel\_pwrctrl docs][开关.anel_pwrctrl docs]) * 开关 to own packaged 版本 of braviarc ([@andrey-git] - [#15009]) ([媒体播放器.braviatv docs]) * HomeKit style clean up ([@schmittx] - [#14793]) ([homekit docs]) * 升级 netdisco to 1.5.0 ([@fabaff] - [#15016]) * 更新 to hole to 0.3.0 ([@fabaff] - [#15014]) ([传感器.pi\_hole docs][传感器.pi_hole docs]) (breaking change) * 升级 numpy to 1.14.5 ([@fabaff] - [#15015]) ([binary\_sensor.trend docs][binary_sensor.trend docs]) ([image\_processing.opencv docs][image_processing.opencv docs]) * 升级 youtube\_dl to 2018.06.14 ([@fabaff] - [#15013]) ([media\_extractor docs][media_extractor docs]) * 开关 nuimo to a hopefully working pypi 版本 ([@andrey-git] - [#15006]) * Remove typing ([@fabaff] - [#15018]) * Add support for Homekit battery 服务 ([@schmittx] - [#14288]) ([homekit docs]) * 更新 PostNL unit of measure to align with UPS ([@keesschollaart81] - [#15023]) (breaking change) * Expose Wemo component availability to Home Assistant ([@gstorer] - [#14995]) ([灯光.wemo docs]) * Improve volume support for Vizio Smartcast ([@JeffLIrion] - [#14981]) ([媒体播放器.vizio docs]) * 升级 requests to 2.19.1 ([@fabaff] - [#15019]) * Show running apps as sources for Fire TV ([@JeffLIrion] - [#15033]) ([媒体播放器.firetv docs]) * Patch save\_json ([@Hate-Usernames] - [#15046]) * 更新 loopenergy link to docs ([@fabaff] - [#15050]) ([传感器.loopenergy docs]) * 开关 upstream adafruit package ([@andrey-git] - [#15038]) ([传感器.dht docs]) * 开关 to own packaged 版本 of pyflic ([@andrey-git] - [#15041]) ([binary\_sensor.flic docs][binary_sensor.flic docs]) * 更新 条件.py ([@raoulteeuwen] - [#15021]) * 更新 pywemo to 版本 0.4.28. ([@gstorer] - [#15052]) ([wemo docs]) * 升级 pyarlo to 0.1.8 to support Arlo Baby monitor ([@tchellomello] - [#15060]) ([arlo docs]) * Upgraded librouteros since it has support for authenticatoin in new RouterOS. ([@dejx] - [#15056]) ([device\_tracker docs][device_tracker docs]) * Python wink 更新 ([@w1ll1am23] - [#15048]) ([wink docs]) ([遮盖.wink docs]) * Fix tplink max/min kelvin for temperature adjustment ([@titilambert] - [#15020]) ([灯光.tplink docs]) * 更新 pyhomematic to 0.1.44 ([@danielperna84] - [#15069]) ([homematic docs]) * Homematic: Add optional port for resolvenames via JSON ([@hanzoh] - [#15029]) ([homematic docs]) * Add 脚本 to run monkeytype typing on test suite ([@MartinHjelmare] - [#14440]) * 开关 to pypi 版本 of pybotvac ([@andrey-git] - [#15115]) ([neato docs]) * Added 属性 attribution to Digital Ocean component ([@tchellomello] - [#15114]) ([digital\_ocean docs][digital_ocean docs]) ([binary\_sensor.digital\_ocean docs][binary_sensor.digital_ocean docs]) ([开关.digital\_ocean docs][开关.digital_ocean docs]) * Make Pollen.com platform async ([@bachya] - [#14963]) ([传感器.pollen docs]) (breaking change) * deCONZ small improvements ([@Kane610] - [#15128]) ([deconz docs]) ([灯光.deconz docs]) * Bump insteonplm 版本 to 0.11.2 ([@teharris1] - [#15133]) ([insteon\_plm docs][insteon_plm docs]) * Reorganize mysensors ([@MartinHjelmare] - [#15123]) * MQTT 报警 Control 面板: add retain option for publishing for cases... ([@b3nj1] - [#15134]) ([alarm\_control\_panel.MQTT docs][alarm_control_panel.MQTT docs]) * Add discovery support to MQTT 温控 component. ([@dreizehnelf] - [#15085]) ([MQTT docs]) ([温控.MQTT docs]) * Support for Homekit Controller 温控 设备 ([@armills] - [#15057]) ([homekit\_controller docs][homekit_controller docs]) ([温控.homekit\_controller docs][温控.homekit_controller docs]) ([灯光.homekit\_controller docs][灯光.homekit_controller docs]) ([开关.homekit\_controller docs][开关.homekit_controller docs]) (new-platform) * PyPi: Fix description and 设置.cfg ([@cdce8p] - [#15107]) * Add language to dark sky 天气 component ([@pvizeli] - [#15130]) ([天气.darksky docs]) * Add storage 助手 and migrate config entries ([@balloob] - [#15045]) ([传感器.fitbit docs]) * Fix pylintrc section order and option placements ([@scop] - [#15120]) * Fix #14919. Should throw exception when 摄像头 stream closed by 前端 ([@awarecan] - [#15028]) ([摄像头 docs]) ([摄像头.proxy docs]) * Revert "Add language to dark sky 天气 component" ([@pvizeli] - [#15142]) ([天气.darksky docs]) * Lint cleanup ([@scop] - [#15103]) * 更新 aiofreepybox to fix HTTPS connection issues ([@stilllman] - [#15104]) ([device\_tracker docs][device_tracker docs]) * Fix mysensors 温控 supported features ([@MartinHjelmare] - [#15110]) ([温控.mysensors docs]) * 更新 xiaomi.py ([@vaidyasr] - [#15136]) ([摄像头.xiaomi docs]) * Return None to indicate no config found ([@balloob] - [#15147]) * Add channel changing support to SamsungTV component ([@mlebrun] - [#14451]) ([媒体播放器.samsungtv docs]) * Add SSL peer certificate support to HTTP server ([@kepten] - [#15043]) ([emulated\_hue docs][emulated_hue docs]) ([http docs]) * Address inconsistent behavior on flux\_led component ([@oblogic7] - [#14713]) ([灯光.flux\_led docs][灯光.flux_led docs]) * 升级 youtube\_dl to 2018.06.25 ([@fabaff] - [#15168]) ([media\_extractor docs][media_extractor docs]) * 升级 keyring to 13.0.0 ([@fabaff] - [#15167]) * 升级 sendgrid to 5.4.1 ([@fabaff] - [#15166]) ([通知 docs]) * Add Mini 遥控器 support to insteon\_plm ([@teharris1] - [#15152]) ([insteon\_plm docs][insteon_plm docs]) * Warn when using custom components ([@balloob] - [#15172]) * Philips Hue 场景 Activation: Simplified 场景 lookup logic, improved 错误 handling ([@MizterB] - [#15175]) ([hue docs]) * Finalize BotVac D7 Support And Further Reduce Cloud Calls ([@dshokouhi] - [#15161]) ([neato docs]) ([摄像头.neato docs]) ([开关.neato docs]) ([吸尘器.neato docs]) * DarkSky 天气 / Fix 状态 ([@pvizeli] - [#15174]) ([天气.darksky docs]) * Only use the X-Forwarded-For header if connection is from a trusted network ([@colinodell] - [#15182]) ([http docs]) * Adding 'namespace' for prometheus metrics ([@alexbarcelo] - [#13738]) ([prometheus docs]) (breaking change) * Storage auth ([@balloob] - [#15192]) * Make sure we check access token expiration ([@balloob] - [#15207]) ([前端 docs]) * Migrate Home Assistant auth provider to use storage 助手 ([@balloob] - [#15200]) * Fix zwave 温控 operation mode mappings ([@cdce8p] - [#15162]) ([温控.zwave docs]) (breaking change) * Fixed Indentation 错误 ([@vaidyasr] - [#15210]) ([摄像头.xiaomi docs]) * X-Forwarded-For improvements and bug fixes ([@colinodell] - [#15204]) ([emulated\_hue docs][emulated_hue docs]) ([http docs]) (breaking change) * Stop supporting deprecated TLS ciphers ([@hmmbob] - [#15217]) ([http docs]) (breaking change) * 更新 eternalegypt ([@amelchio] - [#15180]) ([netgear\_lte docs][netgear_lte docs]) ([通知 docs]) * 更新 python-wink to 1.9.1 ([@vickyg3] - [#15215]) ([wink docs]) * Fix 'AirQualityMonitorStatus' object has no 属性 ‘time\_state’ ([@syssi] - [#15216]) ([传感器.xiaomi\_miio docs][传感器.xiaomi_miio docs]) * Use cached 状态 for neato when possible ([@dshokouhi] - [#15218]) ([开关.neato docs]) ([吸尘器.neato docs]) * Rachio webhooks ([@Klikini] - [#15111]) ([rachio docs]) ([binary\_sensor.rachio docs][binary_sensor.rachio docs]) ([开关.rachio docs]) (beta fix) (new-platform) * Only create front-end client\_id once ([@awarecan] - [#15214]) ([前端 docs]) (beta fix) * Make LIFX color/temperature 属性 mutually exclusive ([@amelchio] - [#15234]) ([灯光.lifx docs]) (beta fix) * Fix an issue when 用户's nest developer account don't have permission ([@awarecan] - [#15237]) ([binary\_sensor.nest docs][binary_sensor.nest docs]) (beta fix) * Revert some changes to 设置.py ([@cdce8p] - [#15248]) (beta fix) [#13738]: https://github.com/home-assistant/home-assistant/pull/13738 [#14288]: https://github.com/home-assistant/home-assistant/pull/14288 [#14440]: https://github.com/home-assistant/home-assistant/pull/14440 [#14451]: https://github.com/home-assistant/home-assistant/pull/14451 [#14713]: https://github.com/home-assistant/home-assistant/pull/14713 [#14793]: https://github.com/home-assistant/home-assistant/pull/14793 [#14934]: https://github.com/home-assistant/home-assistant/pull/14934 [#14963]: https://github.com/home-assistant/home-assistant/pull/14963 [#14981]: https://github.com/home-assistant/home-assistant/pull/14981 [#14995]: https://github.com/home-assistant/home-assistant/pull/14995 [#15006]: https://github.com/home-assistant/home-assistant/pull/15006 [#15009]: https://github.com/home-assistant/home-assistant/pull/15009 [#15011]: https://github.com/home-assistant/home-assistant/pull/15011 [#15013]: https://github.com/home-assistant/home-assistant/pull/15013 [#15014]: https://github.com/home-assistant/home-assistant/pull/15014 [#15015]: https://github.com/home-assistant/home-assistant/pull/15015 [#15016]: https://github.com/home-assistant/home-assistant/pull/15016 [#15018]: https://github.com/home-assistant/home-assistant/pull/15018 [#15019]: https://github.com/home-assistant/home-assistant/pull/15019 [#15020]: https://github.com/home-assistant/home-assistant/pull/15020 [#15021]: https://github.com/home-assistant/home-assistant/pull/15021 [#15023]: https://github.com/home-assistant/home-assistant/pull/15023 [#15028]: https://github.com/home-assistant/home-assistant/pull/15028 [#15029]: https://github.com/home-assistant/home-assistant/pull/15029 [#15033]: https://github.com/home-assistant/home-assistant/pull/15033 [#15038]: https://github.com/home-assistant/home-assistant/pull/15038 [#15041]: https://github.com/home-assistant/home-assistant/pull/15041 [#15043]: https://github.com/home-assistant/home-assistant/pull/15043 [#15045]: https://github.com/home-assistant/home-assistant/pull/15045 [#15046]: https://github.com/home-assistant/home-assistant/pull/15046 [#15048]: https://github.com/home-assistant/home-assistant/pull/15048 [#15050]: https://github.com/home-assistant/home-assistant/pull/15050 [#15052]: https://github.com/home-assistant/home-assistant/pull/15052 [#15056]: https://github.com/home-assistant/home-assistant/pull/15056 [#15057]: https://github.com/home-assistant/home-assistant/pull/15057 [#15060]: https://github.com/home-assistant/home-assistant/pull/15060 [#15069]: https://github.com/home-assistant/home-assistant/pull/15069 [#15085]: https://github.com/home-assistant/home-assistant/pull/15085 [#15103]: https://github.com/home-assistant/home-assistant/pull/15103 [#15104]: https://github.com/home-assistant/home-assistant/pull/15104 [#15107]: https://github.com/home-assistant/home-assistant/pull/15107 [#15110]: https://github.com/home-assistant/home-assistant/pull/15110 [#15111]: https://github.com/home-assistant/home-assistant/pull/15111 [#15114]: https://github.com/home-assistant/home-assistant/pull/15114 [#15115]: https://github.com/home-assistant/home-assistant/pull/15115 [#15120]: https://github.com/home-assistant/home-assistant/pull/15120 [#15123]: https://github.com/home-assistant/home-assistant/pull/15123 [#15128]: https://github.com/home-assistant/home-assistant/pull/15128 [#15130]: https://github.com/home-assistant/home-assistant/pull/15130 [#15133]: https://github.com/home-assistant/home-assistant/pull/15133 [#15134]: https://github.com/home-assistant/home-assistant/pull/15134 [#15136]: https://github.com/home-assistant/home-assistant/pull/15136 [#15142]: https://github.com/home-assistant/home-assistant/pull/15142 [#15147]: https://github.com/home-assistant/home-assistant/pull/15147 [#15152]: https://github.com/home-assistant/home-assistant/pull/15152 [#15161]: https://github.com/home-assistant/home-assistant/pull/15161 [#15162]: https://github.com/home-assistant/home-assistant/pull/15162 [#15166]: https://github.com/home-assistant/home-assistant/pull/15166 [#15167]: https://github.com/home-assistant/home-assistant/pull/15167 [#15168]: https://github.com/home-assistant/home-assistant/pull/15168 [#15172]: https://github.com/home-assistant/home-assistant/pull/15172 [#15174]: https://github.com/home-assistant/home-assistant/pull/15174 [#15175]: https://github.com/home-assistant/home-assistant/pull/15175 [#15180]: https://github.com/home-assistant/home-assistant/pull/15180 [#15182]: https://github.com/home-assistant/home-assistant/pull/15182 [#15192]: https://github.com/home-assistant/home-assistant/pull/15192 [#15200]: https://github.com/home-assistant/home-assistant/pull/15200 [#15204]: https://github.com/home-assistant/home-assistant/pull/15204 [#15207]: https://github.com/home-assistant/home-assistant/pull/15207 [#15210]: https://github.com/home-assistant/home-assistant/pull/15210 [#15214]: https://github.com/home-assistant/home-assistant/pull/15214 [#15215]: https://github.com/home-assistant/home-assistant/pull/15215 [#15216]: https://github.com/home-assistant/home-assistant/pull/15216 [#15217]: https://github.com/home-assistant/home-assistant/pull/15217 [#15218]: https://github.com/home-assistant/home-assistant/pull/15218 [#15234]: https://github.com/home-assistant/home-assistant/pull/15234 [#15237]: https://github.com/home-assistant/home-assistant/pull/15237 [#15248]: https://github.com/home-assistant/home-assistant/pull/15248 [@ciotlosm]: https://github.com/ciotlosm [@jeradM]: https://github.com/jeradM [@c727]: https://github.com/c727 [@arsaboo]: https://github.com/arsaboo [@Hate-Usernames]: https://github.com/Hate-Usernames [@JeffLIrion]: https://github.com/JeffLIrion [@Kane610]: https://github.com/Kane610 [@Klikini]: https://github.com/Klikini [@MartinHjelmare]: https://github.com/MartinHjelmare [@MizterB]: https://github.com/MizterB [@Petro31]: https://github.com/Petro31 [@alexbarcelo]: https://github.com/alexbarcelo [@amelchio]: https://github.com/amelchio [@andrey-git]: https://github.com/andrey-git [@armills]: https://github.com/armills [@awarecan]: https://github.com/awarecan [@b3nj1]: https://github.com/b3nj1 [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@cdce8p]: https://github.com/cdce8p [@colinodell]: https://github.com/colinodell [@danielperna84]: https://github.com/danielperna84 [@dejx]: https://github.com/dejx [@dreizehnelf]: https://github.com/dreizehnelf [@dshokouhi]: https://github.com/dshokouhi [@fabaff]: https://github.com/fabaff [@gstorer]: https://github.com/gstorer [@hanzoh]: https://github.com/hanzoh [@hmmbob]: https://github.com/hmmbob [@keesschollaart81]: https://github.com/keesschollaart81 [@kepten]: https://github.com/kepten [@mlebrun]: https://github.com/mlebrun [@oblogic7]: https://github.com/oblogic7 [@pvizeli]: https://github.com/pvizeli [@raoulteeuwen]: https://github.com/raoulteeuwen [@schmittx]: https://github.com/schmittx [@scop]: https://github.com/scop [@stilllman]: https://github.com/stilllman [@syssi]: https://github.com/syssi [@tchellomello]: https://github.com/tchellomello [@teharris1]: https://github.com/teharris1 [@titilambert]: https://github.com/titilambert [@vaidyasr]: https://github.com/vaidyasr [@vickyg3]: https://github.com/vickyg3 [@w1ll1am23]: https://github.com/w1ll1am23 [alarm_control_panel.MQTT docs]: /integrations/alarm_control_panel.MQTT/ [arlo docs]: /integrations/arlo/ [binary_sensor.digital_ocean docs]: /integrations/digital_ocean#binary-传感器 [binary_sensor.flic docs]: /integrations/flic [binary_sensor.nest docs]: /integrations/nest#binary-传感器 [binary_sensor.rachio docs]: /integrations/rachio [binary_sensor.trend docs]: /integrations/trend [摄像头 docs]: /integrations/摄像头/ [摄像头.neato docs]: /integrations/neato#摄像头 [摄像头.proxy docs]: /integrations/proxy [摄像头.xiaomi docs]: /integrations/xiaomi_aqara [温控.homekit_controller docs]: /integrations/homekit_controller [温控.MQTT docs]: /integrations/温控.MQTT/ [温控.mysensors docs]: /integrations/温控.mysensors/ [温控.zwave docs]: /integrations/zwave#温控 [遮盖.wink docs]: /integrations/wink#遮盖 [deconz docs]: /integrations/deconz/ [device_tracker docs]: /integrations/device_tracker/ [digital_ocean docs]: /integrations/digital_ocean/ [emulated_hue docs]: /integrations/emulated_hue/ [前端 docs]: /integrations/frontend/ [homekit docs]: /integrations/homekit/ [homekit_controller docs]: /integrations/homekit_controller/ [homematic docs]: /integrations/homematic/ [http docs]: /integrations/http/ [hue docs]: /integrations/hue/ [image_processing.opencv docs]: /integrations/opencv [insteon_plm docs]: /integrations/insteon/ [灯光.deconz docs]: /integrations/deconz#灯光 [灯光.flux_led docs]: /integrations/flux_led [灯光.homekit_controller docs]: /integrations/homekit_controller [灯光.lifx docs]: /integrations/lifx [灯光.tplink docs]: /integrations/tplink [灯光.wemo docs]: /integrations/wemo [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.braviatv docs]: /integrations/braviatv [媒体播放器.firetv docs]: /integrations/androidtv [媒体播放器.samsungtv docs]: /integrations/samsungtv [媒体播放器.vizio docs]: /integrations/vizio [MQTT docs]: /integrations/MQTT/ [neato docs]: /integrations/neato/ [netgear_lte docs]: /integrations/netgear_lte/ [通知 docs]: /integrations/通知/ [prometheus docs]: /integrations/prometheus/ [rachio docs]: /integrations/rachio/ [传感器.dht docs]: /integrations/dht [传感器.fitbit docs]: /integrations/fitbit [传感器.loopenergy docs]: /integrations/loopenergy [传感器.pi_hole docs]: /integrations/pi_hole [传感器.pollen docs]: /integrations/iqvia [传感器.waze_travel_time docs]: /integrations/waze_travel_time [传感器.xiaomi_miio docs]: /integrations/传感器.xiaomi_miio/ [开关.anel_pwrctrl docs]: /integrations/anel_pwrctrl [开关.digital_ocean docs]: /integrations/digital_ocean#开关 [开关.homekit_controller docs]: /integrations/homekit_controller [开关.neato docs]: /integrations/neato#开关 [开关.rachio docs]: /integrations/rachio#开关 [吸尘器.neato docs]: /integrations/neato#吸尘器 [天气.darksky docs]: /integrations/天气.darksky/ [wemo docs]: /integrations/wemo/ [wink docs]: /integrations/wink/ --- url: /home-assistant/blog/2018-07-11-hassio-images.md --- # 基于 HassOS 的全新 Hass.io 镜像 经过 4 个月的努力,我们很高兴发布基于 HassOS 的全新 Hass.io 镜像。HassOS 是我们专为运行 Hass.io 打造的全新操作系统。是的,它支持树莓派 3 B+! ## What is new 我们在 \[Buildroot] 框架之上构建了 HassOS。这个系统的目标是做成一个非常小巧且高效的操作系统,以类似 hypervisor 的方式运行 Docker。系统只安装了运行 Supervisor 所需的最小软件集。我们也重点加强了安全性,例如没有默认密码,并使用 \[AppArmor] 保护 HassOS 上的应用与容器。 主要特性: * 通过 USB 或互联网(OTA)使用 \[Rauc] 进行安全更新 * 根文件系统与部分内存采用 LZ4 压缩 * 只读根文件系统,专为嵌入式系统设计 * 支持通过 D-Bus 连接主机服务 * 使用最新 LT Linux 内核 * 使用最新 Docker-ce 版本 * 完整支持 NetworkManager * 通过 Bluez 提供蓝牙支持 * 支持多种不同硬件 ## Migration HassOS 与 ResinOS 的设计不同,因此我们无法提供从旧 ResinOS 系统到新 HassOS 系统的 OTA 更新。 你需要按以下步骤升级: 1. 如果你已安装蓝牙插件,请先移除,它已经不再需要。 2. 为当前系统创建 Hass.io snapshot,并下载到你的电脑。 3. 下载最新的 \[Hass.io stable]\[安装] 版本。 4. 使用 \[balenaEtcher] 将下载好的 Hass.io 镜像刷入 SD 卡。 5. 树莓派:如果你改过引导分区里的 `config.txt`,也需要把这些改动应用到 HassOS。请**不要**直接把旧配置文件复制到 HassOS,务必手动应用变更。 6. 如果你使用自定义网络配置,或配置了 SSH 开发访问,需要准备一个配置用 \[USB stick]。将 `resin-sample` 复制到 U 盘的 `network` 文件夹后插入设备。 7. 将刚刷好的 HassOS SD 卡装回设备并开机。 8. 通过 SSH 或 Samba 插件把 snapshot 拷贝到主机。 9. 通过 Hass.io 面板恢复你的 snapshot。 10. 完成! ## Future HassOS 是一个非常棒的基础系统,让我们可以开始把各种强大功能集成进 Hass.io(并同步带到 UI 中)。例如我们计划把网络和蓝牙配置能力加入 UI。目标是打造功能完整、任何人都能上手的 Home Assistant 中枢系统。 Hass.io API 很全面,我们也会把更多能力引入 Home Assistant。例如可以监控插件乃至 Home Assistant 本身系统资源占用的传感器。 特别感谢所有捐款帮助我们购买硬件的朋友!我们已经开始让 HassOS 兼容更多硬件,目前目标是每 7-14 天发布对新设备的支持,并持续推进,直到覆盖主流 IoT 开发板。 欢迎加入项目,一起改进文档或参与其他能推动项目前进的工作。 \[Rauc]: Safe and Secure Updating \[Buildroot]: https://buildroot.org/ \[AppArmor]: https://gitlab.com/apparmor/apparmor/wikis/home/ \[USB stick]: https://github.com/home-assistant/hassos/blob/rel-1/docs/configuration.md#automatic \[安装]: /hassio/installation/ \[balenaEtcher]: https://www.balena.io/etcher --- url: /home-assistant/blog/2018-07-16-release-73-2.md --- # 0.73.2 - Security Incident Today we are releasing 0.73.2 to fix a security incident. We've discovered that 9 months ago, with the 发布 of Home Assistant 0.56, we misconfigured the SSL context that aiohttp used ([PR](https://github.com/home-assistant/home-assistant/pull/9958)). By trying to do the right thing (use an up to date cert store instead of relying on the system certs), we ended up doing the complete opposite: SSL verification was disabled for **outgoing** requests that were done using the shared aiohttp session. This is our fault, and not aiohttp's faults. The impact of this is that certain 集成 in Home Assistant have been susceptible to [man in the middle attacks](https://en.wikipedia.org/wiki/Man-in-the-middle_attack). A man in the middle attack is when an attacker is able to inject itself between you and the server you're communicating with, allowing it to read and alter the communication. The odds of this happening at home is very rare, yet we wanted to be transparent about this incident. After research, the following 集成 have been impacted. Although the odds are extremely small, we still suggest that if you use any of these 集成, to create new API keys or change your 密码. * [温控.sensibo](/home-assistant/integrations/sensibo.md) * [cloud](/home-assistant/integrations/cloud/index.md) (only short lived tokens impacted) * device\_tracker.automatic * [duckdns](/home-assistant/integrations/duckdns/index.md) * [freedns](/home-assistant/integrations/freedns/index.md) * [google\_assistant](/home-assistant/integrations/google_assistant/index.md) (manual 设置) * [google\_domains](/home-assistant/integrations/google_domains/) * [homematicip\_cloud](/home-assistant/integrations/homematicip_cloud/index.md) * [image\_processing.openalpr\_cloud](/home-assistant/integrations/openalpr_cloud.md) * [microsoft\_face](/home-assistant/integrations/microsoft_face/index.md) * [namecheapdns](/home-assistant/integrations/namecheapdns/index.md) * [no\_ip](/home-assistant/integrations/no_ip/index.md) * [notify.flock](/home-assistant/integrations/flock.md) * [notify.prowl](/home-assistant/integrations/prowl.md) * [rest\_command](/home-assistant/integrations/rest_command/index.md) * [场景.lifx\_cloud](/home-assistant/integrations/lifx_cloud.md) * [开关.rest](/home-assistant/integrations/switch.rest/index.md) * [telegram\_bot.polling](/home-assistant/integrations/telegram_polling) * [tts.voicerss](/home-assistant/integrations/voicerss.md) Also impacted, but 集成 are read only: * [传感器.airvisual](/home-assistant/integrations/airvisual.md) * [传感器.ebox](/home-assistant/integrations/ebox.md) * [传感器.fido](/home-assistant/integrations/fido.md) * [传感器.foobot](/home-assistant/integrations/foobot.md) * 传感器.hydroquebec * [传感器.startca](/home-assistant/integrations/startca.md) * 传感器.teksavvy * [sensor.thethingsnetwork](/home-assistant/integrations/thethingsnetwork.md#sensor) * [sensor.tibber](/home-assistant/integrations/tibber.md#sensor) * [传感器.waqi](/home-assistant/integrations/waqi.md) If you are running Home Assistant on a system with Python 3.4, we've 创建 a new 发布 0.64.4b0 with the patch applied. We have made it available as a beta. To 安装 the pre-发布 run `python3 -m pip install homeassistant==0.64.4b0`. For complete transparency, the following two sets of 集成 also used aiohttp to send or retrieve data. However, they either did not transmit 认证 or only communicated with local 设备 and 服务. Affected, but not transmitting 认证: * [sensor.buienradar](/home-assistant/integrations/sensor.buienradar/) * [传感器.citybikes](/home-assistant/integrations/citybikes.md) * [传感器.comed\_hourly\_pricing](/home-assistant/integrations/comed_hourly_pricing.md) * [sensor.luftdaten](/home-assistant/integrations/luftdaten.md#sensor) * [传感器.pollen](/home-assistant/integrations/iqvia.md) * [传感器.sochain](/home-assistant/integrations/sochain) * [传感器.swiss\_public\_transport](/home-assistant/integrations/swiss_public_transport.md) * [传感器.viaggiatreno](/home-assistant/integrations/viaggiatreno.md) * [传感器.wunderground](/home-assistant/integrations/wunderground) * 传感器.yr * [weather.ipma](/home-assistant/integrations/ipma.md) * [tts.google](/home-assistant/integrations/google_translate.md) * [tts.yandextts](/home-assistant/integrations/yandextts.md) * [updater](/home-assistant/integrations/updater/) Local, so cannot be impacted: * [android\_ip\_webcam](/home-assistant/integrations/android_ip_webcam/index.md) * [apple\_tv](/home-assistant/integrations/apple_tv/index.md) * [摄像头.amcrest](/home-assistant/integrations/amcrest.md) * [摄像头.doorbird](/home-assistant/integrations/doorbird.md#摄像头) * [摄像头.familyhub](/home-assistant/integrations/familyhub.md) * [摄像头.generic](/home-assistant/integrations/generic_ip_camera) * [摄像头.mjpeg](/home-assistant/integrations/mjpeg.md) * [摄像头.proxy](/home-assistant/integrations/proxy.md) * [摄像头.synology](/home-assistant/integrations/synology) * [deconz](/home-assistant/integrations/deconz/index.md) * [device\_tracker.upc\_connect](/home-assistant/integrations/upc_connect.md) * [hassio](/home-assistant/integrations/hassio/index.md) * [hue](/home-assistant/integrations/hue/index.md) * [media\_player.bluesound](/home-assistant/integrations/bluesound.md) * [media\_player.epson](/home-assistant/integrations/epson.md) * [media\_player.kodi](/home-assistant/integrations/kodi.md) * [media\_player.squeezebox](/home-assistant/integrations/squeezebox.md) * [media\_player.volumio](/home-assistant/integrations/volumio.md) * [notify.kodi](/home-assistant/integrations/kodi.md) * [qwikswitch](/home-assistant/integrations/qwikswitch/index.md) * [rainmachine](/home-assistant/integrations/rainmachine/index.md) * [场景.hunterdouglas\_powerview](/home-assistant/integrations/hunterdouglas_powerview.md) * [传感器.netdata](/home-assistant/integrations/netdata.md) * [传感器.pi\_hole](/home-assistant/integrations/pi_hole.md) * [sensor.sma](/home-assistant/integrations/sma.md#sensor) * [传感器.worxlandroid](/home-assistant/integrations/worxlandroid.md) * [spc](/home-assistant/integrations/spc/index.md) * [tts.marytts](/home-assistant/integrations/marytts.md) --- url: /home-assistant/blog/2018-07-21-release-74.md --- # 0.74: Tuya, Cloudflare DNS, Push 摄像头 and 用户 UI It's time for Home Assistant 0.74! 🎉 This week we heard that Guido van Rossum, the founder of Python, is taking a permanent vacation as the leader of Python after being at the helm for almost 30 years. Guido has not been directly involved with Home Assistant. However he 创建 Python and was part of the team that built asyncio, technologies that power the foundation of Home Assistant and what makes us so fast and robust. Under Guido's guidance, the Python community has grown out to be very friendly and open. A great inspiration for us and other tech communities out there. Thanks for all you have done Guido!

Photo of Paulus, founder of Home Assistant, and Guido, founder of Python. Paulus & Guido at PyCon US 2018

All right, back to Home Assistant. The last 发布 introduced a tech preview of the new 用户 system. The initial preview still required creating 用户 via the command line. In the last two weeks, we've worked hard on adding support for an onboarding wizard and a 用户 management interface. A walkthrough of the new features can be found below. Thanks to [@awarecan] and [@jeradM] for all their work! To try it out today, [read these instructions](https://开发者.home-assistant.io/博客/2018/07/02/trying-new-auth.html). The 用户 system is still in tech preview. We've moved fast to get where we are today. The next step is that we need to take a step back and look at the system as a whole to make sure it's robust and ready for prime time.
We keep seeing [great examples](https://twitter.com/home_assistant/status/1019579208622845953) of UIs built with Lovelace. Follow us on social media ([FB](https://www.facebook.com/homeassistantio/), [Twitter](https://twitter.com/home_assistant)) where we will keep sharing great examples. To help our development and design teams, we've also introduced a [Lovelace 卡片 gallery](https://www.awesome-ha.com/). Thanks to [@c727], [@jeradM] and [@ciotlosm] for leading this effort ❤️ I'm happy to announce that this 发布 introduces support for Tuya thanks to [@huangyupeng]. Tuya produces cheap cloud-enabled 设备 that are sold under a wide variety of brand names across the globe, and now they work with Home Assistant too! ## New Platforms * Add Tuya component and 开关 support ([@huangyupeng] - [#15399]) ([tuya docs]) ([开关.tuya docs]) (new-platform) * Add Tuya 灯光 platform ([@huangyupeng] - [#15444]) ([tuya docs]) ([灯光.tuya docs]) (new-platform) * Added support for Duke Energy smart meters ([@w1ll1am23] - [#15165]) (new-platform) * Added Push 摄像头 ([@dgomes] - [#15151]) ([摄像头.push docs]) (new-platform) * Add Cloudflare DNS component. ([@ludeeus] - [#15388]) ([cloudflare docs]) (new-platform) * Add HomematicIP 报警 control 面板 ([@mxworm] - [#15342]) ([alarm\_control\_panel docs][alarm_control_panel docs]) ([homematicip\_cloud docs][homematicip_cloud docs]) ([alarm\_control\_panel.homematicip\_cloud docs][alarm_control_panel.homematicip_cloud docs]) (new-platform) ## 发布 0.74.1 - July 24 * Bugfix HomeKit name and serial\_number ([@cdce8p] - [#15600]) ([homekit docs]) * Use case insensitive comparison for Sonos model check ([@amelchio] - [#15604]) ([媒体播放器.sonos docs]) * 前端 component should auto load auth coomponent ([@awarecan] - [#15606]) ([前端 docs]) * Cast/Sonos: create config entry if manually configured ([@balloob] - [#15630]) ([cast docs]) ([sonos docs]) ## If you need help... ...don't hesitate to use our very active [forums](https://community.home-assistant.io/) or join us for a little [chat](https://discord.gg/c5DvZ4e). The 发布 notes have comments enabled but it's preferred if you use the former communication channels. Thanks. ## Reporting Issues Experiencing issues introduced by this 发布? Please report them in our [issue tracker](https://github.com/home-assistant/home-assistant/issues). Make sure to fill in all fields of the issue 模板. ## Backward-incompatible changes * Fixer.io has changed their API and now requires an API key. (fixes #14911) ([@fabaff] - [#15279]) ([传感器.fixer docs]) (breaking change) * Add support to use HTTPS URLs to SynologyDSM and make it the default ([@tchellomello] - [#15270]) ([传感器.synologydsm docs]) (breaking change) * HomeKit Controller: Ignore discovering the HomeKit component and HomeKit 设备 which offer native local API ([@mjg59] - [#15316]) ([homekit\_controller docs][homekit_controller docs]) (breaking change) * LimitlessLED will no longer report `hs_color`/`rgb_color` and `color_temp` simultaneously. ([@amelchio] - [#15298]) ([灯光.limitlessled docs]) (breaking change) * IP Ban: Reset failed login attempts counter when login success ([@awarecan] - [#15564]) ([http docs]) ([websocket\_api docs][websocket_api docs]) (breaking change) (beta fix) ## Beta Fixes * Add current 用户 WS command ([@balloob] - [#15485]) ([auth docs]) ([前端 docs]) (beta fix) * Add onboarding support ([@balloob] - [#15492]) ([前端 docs]) ([onboarding docs]) (beta fix) * 更新 HomeKit module code ([@mjg59] - [#15502]) ([homekit\_controller docs][homekit_controller docs]) (beta fix) * Disallow use insecure\_example auth provider in 配置.yml ([@awarecan] - [#15504]) (beta fix) * Added WS endpoint for changing homeassistant 密码. ([@jeradM] - [#15527]) ([config docs]) (beta fix) * Don't be so strict client-side ([@balloob] - [#15546]) (beta fix) * Decouple emulated hue from http server ([@balloob] - [#15530]) ([emulated\_hue docs][emulated_hue docs]) (beta fix) * Allow CORS requests to token endpoint ([@balloob] - [#15519]) ([auth docs]) ([http docs]) (beta fix) * 升级 pymysensors to 0.16.0 ([@MartinHjelmare] - [#15554]) ([mysensors docs]) (beta fix) * Allow auth providers to influence is\_active ([@balloob] - [#15557]) (beta fix) * Remove relative time from 状态 machine ([@balloob] - [#15560]) ([传感器.netatmo docs]) (beta fix) * Reset failed login attempts counter when login success ([@awarecan] - [#15564]) ([http docs]) ([websocket\_api docs][websocket_api docs]) (breaking change) (beta fix) ## All changes * deconz: fix 灯光.turn\_off with transition ([@lbschenkel] - [#15222]) ([灯光.deconz docs]) * Add new RTS 设备 ([@pepeEL] - [#15116]) ([tahoma docs]) * Add additional parameters to NUT UPS 传感器 ([@carlchan] - [#15066]) ([传感器.nut docs]) * Fix typos ([@fabaff] - [#15233]) ([watson\_iot docs][watson_iot docs]) * Use async syntax for 遮盖 platforms ([@cdce8p] - [#15230]) ([遮盖.lutron\_caseta docs][遮盖.lutron_caseta docs]) ([遮盖.MQTT docs]) ([遮盖.rflink docs]) ([遮盖.模板 docs]) ([遮盖.wink docs]) * 升级 pytest to 3.6.2 ([@scop] - [#15241]) * Add precipitations to Openweathermap daily forecast mode ([@sgttrs] - [#15240]) ([天气.openweathermap docs]) * deconz: proper fix 灯光.turn\_off with transition ([@lbschenkel] - [#15227]) ([灯光.deconz docs]) * allow extra slot values in intents ([@dthulke] - [#15246]) * Lint cleanups ([@scop] - [#15243]) ([google\_assistant docs][google_assistant docs]) ([传感器.tibber docs]) * 升级 sqlalchemy to 1.2.9 ([@fabaff] - [#15250]) ([传感器.sql docs]) * 升级 WazeRouteCalculator to 0.6 ([@fabaff] - [#15251]) ([传感器.waze\_travel\_time docs][传感器.waze_travel_time docs]) * Fix typo in Docker files ([@SConaway] - [#15256]) * 开关 to own packaged 版本 of pylgnetcast ([@andrey-git] - [#15042]) ([媒体播放器.lg\_netcast docs][媒体播放器.lg_netcast docs]) * Added setting 遮盖 tilt position in 场景 ([@kstaniek] - [#15255]) * Pass tox posargs to pylint ([@scop] - [#15226]) * Fix Roomba exception ([@arbreng] - [#15262]) ([吸尘器.roomba docs]) * Added support for Duke Energy smart meters ([@w1ll1am23] - [#15165]) (new-platform) * 更新 image\_processing async ([@dgomes] - [#15082]) ([image\_processing docs][image_processing docs]) * Fix python-miio 0.4 compatibility of the xiaomi miio 设备 tracker ([@serhtt] - [#15244]) ([device\_tracker docs][device_tracker docs]) * 升级 keyring to 13.1.0 ([@fabaff] - [#15268]) * deCONZ - new 传感器 属性 'on' and new 传感器 GenericFlag ([@Kane610] - [#15247]) ([deconz docs]) ([binary\_sensor.deconz docs][binary_sensor.deconz docs]) ([传感器.deconz docs]) * expose 温控 current temperature in prometeus metrics ([@stenius] - [#15232]) ([prometheus docs]) * New 设备 to support option MY in somfy ([@pepeEL] - [#15272]) ([遮盖.tahoma docs]) * Add isort 配置 ([@fabaff] - [#15278]) * Add support for new API (fixes #14911) ([@fabaff] - [#15279]) ([传感器.fixer docs]) (breaking change) * 开关 to own packaged 版本 of suds-passworddigest ([@andrey-git] - [#15261]) ([摄像头.onvif docs]) * Added Push 摄像头 ([@dgomes] - [#15151]) ([摄像头.push docs]) (new-platform) * Added support to HTTPS URLs on SynologyDSM ([@tchellomello] - [#15270]) ([传感器.synologydsm docs]) (breaking change) * Add system generated 用户 ([@balloob] - [#15291]) ([auth docs]) * Add additional 传感器 for Arlo Baby 摄像头 ([@lukiffer] - [#15074]) ([传感器.arlo docs]) * Add HomematicIP Cloud Config Flow and Entries loading ([@mxworm] - [#14861]) ([homematicip\_cloud docs][homematicip_cloud docs]) * 升级 youtube\_dl to 2018.07.04 ([@fabaff] - [#15323]) ([media\_extractor docs][media_extractor docs]) * 升级 keyring to 13.2.0 ([@fabaff] - [#15322]) * 升级 pytest to 3.6.3 ([@scop] - [#15332]) * Add original message as dialogflow\_query parameter ([@quazzie] - [#15304]) ([dialogflow docs]) * Add python 3.7 to travis and tox ([@andrey-git] - [#14523]) * 前端: Allow overriding default url when added to home screen ([@sjabby] - [#15368]) ([前端 docs]) * Add HomematicIP Cloud 灯光 power consumption and energie 属性 ([@mxworm] - [#15343]) ([灯光.homematicip\_cloud docs][灯光.homematicip_cloud docs]) * fix 摄像头.push API overwrite ([@dgomes] - [#15334]) ([摄像头.push docs]) * Add support for multi-channel enocean 开关 (D2-01-12 profile) ([@NoUsername] - [#14548]) ([enocean docs]) ([开关.enocean docs]) * Add sound mode support ([@starkillerOG] - [#14910]) ([媒体播放器.denonavr docs]) * Fixed issue 15340. alexa/smart\_home module can now skip properties that aren't supported in the current 状态, eg lowerSetpoint in Heat mode or targetSetpoint in Eco mode for Nest 设备. ([@iliketoprogram14] - [#15352]) ([alexa docs]) * Efergy ([@fabaff] - [#15380]) ([传感器.efergy docs]) * Use IndieAuth for client ID ([@balloob] - [#15369]) ([auth docs]) ([前端 docs]) * Add httplib2 to h.c.google requirements ([@scop] - [#15385]) ([日历.google docs]) * Remove some unneeded pylint import-错误 disables ([@scop] - [#15386]) ([device\_tracker docs][device_tracker docs]) ([eufy docs]) ([灯光.eufy docs]) ([开关.eufy docs]) * 更新 ha-philipsjs to 0.0.5 ([@danielperna84] - [#15378]) ([媒体播放器.philips\_js docs][媒体播放器.philips_js docs]) * Add new voices to Amazon Polly ([@hanzoh] - [#15320]) ([tts docs]) * Add Cloudflare DNS component. ([@ludeeus] - [#15388]) ([cloudflare docs]) (new-platform) * Add Facebox teach 服务 ([@robmarkcole] - [#14998]) ([image\_processing.facebox docs][image_processing.facebox docs]) * Expire auth code after 10 minutes ([@balloob] - [#15381]) ([auth docs]) * Improve NetAtmo 传感器 更新 logic ([@glpatcern] - [#14866]) ([传感器.netatmo docs]) * removed unused return ([@ludeeus] - [#15402]) ([cloudflare docs]) * Fix confused brightness of xiaomi\_aqara gateway 灯光 ([@amelchio] - [#15314]) ([灯光.xiaomi\_aqara docs][灯光.xiaomi_aqara docs]) * Fix liveboxplaytv empty channel list ([@pschmitt] - [#15404]) * Fix credentials lookup ([@balloob] - [#15409]) * Change Ring binary\_sensor frequency polling to avoid rate limit exceeded 错误 ([@tchellomello] - [#15414]) ([binary\_sensor.ring docs][binary_sensor.ring docs]) * Add Tuya component and 开关 support ([@huangyupeng] - [#15399]) ([tuya docs]) ([开关.tuya docs]) (new-platform) * Fix HomeMatic variables ([@danielperna84] - [#15417]) ([homematic docs]) * Ignore some HomeKit 设备 ([@mjg59] - [#15316]) ([homekit\_controller docs][homekit_controller docs]) (breaking change) * Make LimitlessLED color/temperature 属性 mutually exclusive ([@amelchio] - [#15298]) ([灯光.limitlessled docs]) (breaking change) * Add HomematicIP 报警 control 面板 ([@mxworm] - [#15342]) ([alarm\_control\_panel docs][alarm_control_panel docs]) ([homematicip\_cloud docs][homematicip_cloud docs]) ([alarm\_control\_panel.homematicip\_cloud docs][alarm_control_panel.homematicip_cloud docs]) (new-platform) * Include request.path in legacy api 密码 警告 message ([@awarecan] - [#15438]) ([http docs]) * Add python 3.8-dev to travis and tox ([@andrey-git] - [#15347]) * Reorg auth ([@balloob] - [#15443]) * Make typing checks more strict ([@andrey-git] - [#14429]) * 升级-mypy ([@scop] - [#14904]) * Fix comment formatting ([@balloob] - [#15447]) ([device\_tracker docs][device_tracker docs]) * 用户 management ([@balloob] - [#15420]) ([auth docs]) ([config docs]) ([http docs]) ([websocket\_api docs][websocket_api docs]) * More typing ([@andrey-git] - [#15449]) * Catch the ValueError if the bulb was in the wrong mode ([@fabaff] - [#15434]) ([灯光.mystrom docs]) * 升级 keyring to 13.2.1 ([@fabaff] - [#15453]) * Fix formatting pylint comments in test ([@balloob] - [#15450]) * Add HomematicIP Cloud dimmer 灯光 设备 ([@mxworm] - [#15456]) ([灯光.homematicip\_cloud docs][灯光.homematicip_cloud docs]) * Fix ZWave RGBW 灯光 not producing color without explicit white\_value ([@jantman] - [#15412]) ([灯光.zwave docs]) * Add IPPassageSensor (HmIP-SPDR) ([@danielperna84] - [#15458]) ([homematic docs]) * Implement is\_on ([@teharris1] - [#15459]) ([开关.insteon\_plm docs][开关.insteon_plm docs]) * Remove unnecessary executable permissions ([@scop] - [#15469]) ([fritzbox docs]) ([温控.fritzbox docs]) ([遮盖.group docs]) ([传感器.wirelesstag docs]) ([开关.amcrest docs]) ([开关.fritzbox docs]) * Add Tuya 灯光 platform ([@huangyupeng] - [#15444]) ([tuya docs]) ([灯光.tuya docs]) (new-platform) * 更新 homematicip\_cloud with enum 状态 ([@mxworm] - [#15460]) ([homematicip\_cloud docs][homematicip_cloud docs]) ([binary\_sensor.homematicip\_cloud docs][binary_sensor.homematicip_cloud docs]) ([灯光.homematicip\_cloud docs][灯光.homematicip_cloud docs]) ([传感器.homematicip\_cloud docs][传感器.homematicip_cloud docs]) * Add 用户 via cmd line creates owner ([@balloob] - [#15470]) ([auth docs]) ([http docs]) * 开关 to own packaged 版本 of pygtfs ([@andrey-git] - [#15040]) ([传感器.gtfs docs]) * Aware comments ([@balloob] - [#15480]) ([auth docs]) * Fix flux\_led turning on with color or effect ([@amelchio] - [#15472]) ([灯光.flux\_led docs][灯光.flux_led docs]) * 更新 limitlessled to 1.1.2 ([@amelchio] - [#15481]) ([灯光.limitlessled docs]) * Add current 用户 WS command ([@balloob] - [#15485]) ([auth docs]) ([前端 docs]) (beta fix) * Add onboarding support ([@balloob] - [#15492]) ([前端 docs]) ([onboarding docs]) (beta fix) * 更新 HomeKit module code ([@mjg59] - [#15502]) ([homekit\_controller docs][homekit_controller docs]) (beta fix) * Disallow use insecure\_example auth provider in 配置.yml ([@awarecan] - [#15504]) (beta fix) * Added WS endpoint for changing homeassistant 密码. ([@jeradM] - [#15527]) ([config docs]) (beta fix) * Don't be so strict client-side ([@balloob] - [#15546]) (beta fix) * Decouple emulated hue from http server ([@balloob] - [#15530]) ([emulated\_hue docs][emulated_hue docs]) (beta fix) * Allow CORS requests to token endpoint ([@balloob] - [#15519]) ([auth docs]) ([http docs]) (beta fix) * 升级 pymysensors to 0.16.0 ([@MartinHjelmare] - [#15554]) ([mysensors docs]) (beta fix) * Allow auth providers to influence is\_active ([@balloob] - [#15557]) (beta fix) * Remove relative time from 状态 machine ([@balloob] - [#15560]) ([传感器.netatmo docs]) (beta fix) * Reset failed login attempts counter when login success ([@awarecan] - [#15564]) ([http docs]) ([websocket\_api docs][websocket_api docs]) (breaking change) (beta fix) [#14429]: https://github.com/home-assistant/home-assistant/pull/14429 [#14523]: https://github.com/home-assistant/home-assistant/pull/14523 [#14548]: https://github.com/home-assistant/home-assistant/pull/14548 [#14861]: https://github.com/home-assistant/home-assistant/pull/14861 [#14866]: https://github.com/home-assistant/home-assistant/pull/14866 [#14904]: https://github.com/home-assistant/home-assistant/pull/14904 [#14910]: https://github.com/home-assistant/home-assistant/pull/14910 [#14998]: https://github.com/home-assistant/home-assistant/pull/14998 [#15040]: https://github.com/home-assistant/home-assistant/pull/15040 [#15042]: https://github.com/home-assistant/home-assistant/pull/15042 [#15066]: https://github.com/home-assistant/home-assistant/pull/15066 [#15074]: https://github.com/home-assistant/home-assistant/pull/15074 [#15082]: https://github.com/home-assistant/home-assistant/pull/15082 [#15116]: https://github.com/home-assistant/home-assistant/pull/15116 [#15151]: https://github.com/home-assistant/home-assistant/pull/15151 [#15165]: https://github.com/home-assistant/home-assistant/pull/15165 [#15222]: https://github.com/home-assistant/home-assistant/pull/15222 [#15226]: https://github.com/home-assistant/home-assistant/pull/15226 [#15227]: https://github.com/home-assistant/home-assistant/pull/15227 [#15230]: https://github.com/home-assistant/home-assistant/pull/15230 [#15232]: https://github.com/home-assistant/home-assistant/pull/15232 [#15233]: https://github.com/home-assistant/home-assistant/pull/15233 [#15240]: https://github.com/home-assistant/home-assistant/pull/15240 [#15241]: https://github.com/home-assistant/home-assistant/pull/15241 [#15243]: https://github.com/home-assistant/home-assistant/pull/15243 [#15244]: https://github.com/home-assistant/home-assistant/pull/15244 [#15246]: https://github.com/home-assistant/home-assistant/pull/15246 [#15247]: https://github.com/home-assistant/home-assistant/pull/15247 [#15250]: https://github.com/home-assistant/home-assistant/pull/15250 [#15251]: https://github.com/home-assistant/home-assistant/pull/15251 [#15255]: https://github.com/home-assistant/home-assistant/pull/15255 [#15256]: https://github.com/home-assistant/home-assistant/pull/15256 [#15261]: https://github.com/home-assistant/home-assistant/pull/15261 [#15262]: https://github.com/home-assistant/home-assistant/pull/15262 [#15268]: https://github.com/home-assistant/home-assistant/pull/15268 [#15270]: https://github.com/home-assistant/home-assistant/pull/15270 [#15272]: https://github.com/home-assistant/home-assistant/pull/15272 [#15278]: https://github.com/home-assistant/home-assistant/pull/15278 [#15279]: https://github.com/home-assistant/home-assistant/pull/15279 [#15291]: https://github.com/home-assistant/home-assistant/pull/15291 [#15298]: https://github.com/home-assistant/home-assistant/pull/15298 [#15304]: https://github.com/home-assistant/home-assistant/pull/15304 [#15314]: https://github.com/home-assistant/home-assistant/pull/15314 [#15316]: https://github.com/home-assistant/home-assistant/pull/15316 [#15320]: https://github.com/home-assistant/home-assistant/pull/15320 [#15322]: https://github.com/home-assistant/home-assistant/pull/15322 [#15323]: https://github.com/home-assistant/home-assistant/pull/15323 [#15332]: https://github.com/home-assistant/home-assistant/pull/15332 [#15334]: https://github.com/home-assistant/home-assistant/pull/15334 [#15342]: https://github.com/home-assistant/home-assistant/pull/15342 [#15343]: https://github.com/home-assistant/home-assistant/pull/15343 [#15347]: https://github.com/home-assistant/home-assistant/pull/15347 [#15352]: https://github.com/home-assistant/home-assistant/pull/15352 [#15368]: https://github.com/home-assistant/home-assistant/pull/15368 [#15369]: https://github.com/home-assistant/home-assistant/pull/15369 [#15378]: https://github.com/home-assistant/home-assistant/pull/15378 [#15380]: https://github.com/home-assistant/home-assistant/pull/15380 [#15381]: https://github.com/home-assistant/home-assistant/pull/15381 [#15385]: https://github.com/home-assistant/home-assistant/pull/15385 [#15386]: https://github.com/home-assistant/home-assistant/pull/15386 [#15388]: https://github.com/home-assistant/home-assistant/pull/15388 [#15399]: https://github.com/home-assistant/home-assistant/pull/15399 [#15402]: https://github.com/home-assistant/home-assistant/pull/15402 [#15404]: https://github.com/home-assistant/home-assistant/pull/15404 [#15409]: https://github.com/home-assistant/home-assistant/pull/15409 [#15412]: https://github.com/home-assistant/home-assistant/pull/15412 [#15414]: https://github.com/home-assistant/home-assistant/pull/15414 [#15417]: https://github.com/home-assistant/home-assistant/pull/15417 [#15420]: https://github.com/home-assistant/home-assistant/pull/15420 [#15434]: https://github.com/home-assistant/home-assistant/pull/15434 [#15438]: https://github.com/home-assistant/home-assistant/pull/15438 [#15443]: https://github.com/home-assistant/home-assistant/pull/15443 [#15444]: https://github.com/home-assistant/home-assistant/pull/15444 [#15447]: https://github.com/home-assistant/home-assistant/pull/15447 [#15449]: https://github.com/home-assistant/home-assistant/pull/15449 [#15450]: https://github.com/home-assistant/home-assistant/pull/15450 [#15453]: https://github.com/home-assistant/home-assistant/pull/15453 [#15456]: https://github.com/home-assistant/home-assistant/pull/15456 [#15458]: https://github.com/home-assistant/home-assistant/pull/15458 [#15459]: https://github.com/home-assistant/home-assistant/pull/15459 [#15460]: https://github.com/home-assistant/home-assistant/pull/15460 [#15469]: https://github.com/home-assistant/home-assistant/pull/15469 [#15470]: https://github.com/home-assistant/home-assistant/pull/15470 [#15472]: https://github.com/home-assistant/home-assistant/pull/15472 [#15480]: https://github.com/home-assistant/home-assistant/pull/15480 [#15481]: https://github.com/home-assistant/home-assistant/pull/15481 [#15485]: https://github.com/home-assistant/home-assistant/pull/15485 [#15492]: https://github.com/home-assistant/home-assistant/pull/15492 [#15502]: https://github.com/home-assistant/home-assistant/pull/15502 [#15504]: https://github.com/home-assistant/home-assistant/pull/15504 [#15519]: https://github.com/home-assistant/home-assistant/pull/15519 [#15527]: https://github.com/home-assistant/home-assistant/pull/15527 [#15530]: https://github.com/home-assistant/home-assistant/pull/15530 [#15546]: https://github.com/home-assistant/home-assistant/pull/15546 [#15554]: https://github.com/home-assistant/home-assistant/pull/15554 [#15557]: https://github.com/home-assistant/home-assistant/pull/15557 [#15560]: https://github.com/home-assistant/home-assistant/pull/15560 [#15564]: https://github.com/home-assistant/home-assistant/pull/15564 [@Kane610]: https://github.com/Kane610 [@MartinHjelmare]: https://github.com/MartinHjelmare [@NoUsername]: https://github.com/NoUsername [@SConaway]: https://github.com/SConaway [@amelchio]: https://github.com/amelchio [@andrey-git]: https://github.com/andrey-git [@arbreng]: https://github.com/arbreng [@awarecan]: https://github.com/awarecan [@balloob]: https://github.com/balloob [@carlchan]: https://github.com/carlchan [@cdce8p]: https://github.com/cdce8p [@danielperna84]: https://github.com/danielperna84 [@dgomes]: https://github.com/dgomes [@dthulke]: https://github.com/dthulke [@fabaff]: https://github.com/fabaff [@glpatcern]: https://github.com/glpatcern [@hanzoh]: https://github.com/hanzoh [@huangyupeng]: https://github.com/huangyupeng [@iliketoprogram14]: https://github.com/iliketoprogram14 [@jantman]: https://github.com/jantman [@jeradM]: https://github.com/jeradM [@c727]: https://github.com/c727 [@ciotlosm]: https://github.com/ciotlosm [@kstaniek]: https://github.com/kstaniek [@lbschenkel]: https://github.com/lbschenkel [@ludeeus]: https://github.com/ludeeus [@lukiffer]: https://github.com/lukiffer [@mjg59]: https://github.com/mjg59 [@mxworm]: https://github.com/mxworm [@pepeEL]: https://github.com/pepeEL [@pschmitt]: https://github.com/pschmitt [@quazzie]: https://github.com/quazzie [@robmarkcole]: https://github.com/robmarkcole [@scop]: https://github.com/scop [@serhtt]: https://github.com/serhtt [@sgttrs]: https://github.com/sgttrs [@sjabby]: https://github.com/sjabby [@starkillerOG]: https://github.com/starkillerOG [@stenius]: https://github.com/stenius [@tchellomello]: https://github.com/tchellomello [@teharris1]: https://github.com/teharris1 [@w1ll1am23]: https://github.com/w1ll1am23 [alarm_control_panel docs]: /integrations/alarm_control_panel/ [alarm_control_panel.homematicip_cloud docs]: /integrations/homematicip_cloud [alexa docs]: /integrations/alexa/ [auth docs]: /integrations/auth/ [binary_sensor.deconz docs]: /integrations/deconz#binary-传感器 [binary_sensor.homematicip_cloud docs]: /integrations/homematicip_cloud/ [binary_sensor.ring docs]: /integrations/ring#binary-传感器 [日历.google docs]: /integrations/日历.google/ [摄像头.onvif docs]: /integrations/onvif [摄像头.push docs]: /integrations/push [温控.fritzbox docs]: /integrations/fritzbox [cloudflare docs]: /integrations/cloudflare/ [config docs]: /integrations/config/ [遮盖.group docs]: /integrations/遮盖.group/ [遮盖.lutron_caseta docs]: /integrations/lutron_caseta/ [遮盖.MQTT docs]: /integrations/遮盖.MQTT/ [遮盖.rflink docs]: /integrations/遮盖.rflink/ [遮盖.tahoma docs]: /integrations/tahoma [遮盖.模板 docs]: /integrations/遮盖.模板/ [遮盖.velbus docs]: /integrations/遮盖.velbus/ [遮盖.wink docs]: /integrations/wink#遮盖 [deconz docs]: /integrations/deconz/ [device_tracker docs]: /integrations/device_tracker/ [dialogflow docs]: /integrations/dialogflow/ [emulated_hue docs]: /integrations/emulated_hue/ [enocean docs]: /integrations/enocean/ [eufy docs]: /integrations/eufy/ [fritzbox docs]: /integrations/fritzbox/ [前端 docs]: /integrations/frontend/ [google docs]: /integrations/google_translate [google_assistant docs]: /integrations/google_assistant/ [homekit_controller docs]: /integrations/homekit_controller/ [homematic docs]: /integrations/homematic/ [homematicip_cloud docs]: /integrations/homematicip_cloud/ [http docs]: /integrations/http/ [image_processing docs]: /integrations/image_processing/ [image_processing.facebox docs]: /integrations/facebox [灯光.deconz docs]: /integrations/deconz#灯光 [灯光.eufy docs]: /integrations/eufy [灯光.flux_led docs]: /integrations/flux_led [灯光.homematicip_cloud docs]: /integrations/homematicip_cloud/ [灯光.limitlessled docs]: /integrations/limitlessled [灯光.mystrom docs]: /integrations/mystrom#灯光 [灯光.tuya docs]: /integrations/tuya [灯光.xiaomi_aqara docs]: /integrations/灯光.xiaomi_aqara/ [灯光.zwave docs]: /integrations/zwave [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.denonavr docs]: /integrations/denonavr/ [媒体播放器.lg_netcast docs]: /integrations/lg_netcast [媒体播放器.philips_js docs]: /integrations/philips_js [mysensors docs]: /integrations/mysensors/ [onboarding docs]: /integrations/onboarding/ [prometheus docs]: /integrations/prometheus/ [传感器.arlo docs]: /integrations/arlo#传感器 [传感器.deconz docs]: /integrations/deconz#传感器 [传感器.efergy docs]: /integrations/efergy [传感器.fixer docs]: /integrations/fixer [传感器.gtfs docs]: /integrations/gtfs [传感器.homematicip_cloud docs]: /integrations/homematicip_cloud/ [传感器.netatmo docs]: /integrations/netatmo#传感器 [传感器.nut docs]: /integrations/nut [传感器.sql docs]: /integrations/sql [传感器.synologydsm docs]: /integrations/synologydsm [传感器.tibber docs]: /integrations/tibber#传感器 [传感器.waze_travel_time docs]: /integrations/waze_travel_time [传感器.wirelesstag docs]: /integrations/wirelesstag#传感器 [开关.amcrest docs]: /integrations/amcrest [开关.enocean docs]: /integrations/enocean#开关 [开关.eufy docs]: /integrations/eufy [开关.fritzbox docs]: /integrations/fritzbox [开关.insteon_plm docs]: /integrations/insteon/ [开关.tuya docs]: /integrations/tuya [tahoma docs]: /integrations/tahoma/ [tts docs]: /integrations/tts/ [tuya docs]: /integrations/tuya/ [吸尘器.roomba docs]: /integrations/roomba [watson_iot docs]: /integrations/watson_iot/ [天气.openweathermap docs]: /integrations/openweathermap#天气 [websocket_api docs]: /integrations/websocket_api/ [#15600]: https://github.com/home-assistant/home-assistant/pull/15600 [#15604]: https://github.com/home-assistant/home-assistant/pull/15604 [#15606]: https://github.com/home-assistant/home-assistant/pull/15606 [#15630]: https://github.com/home-assistant/home-assistant/pull/15630 [@amelchio]: https://github.com/amelchio [@awarecan]: https://github.com/awarecan [@balloob]: https://github.com/balloob [@cdce8p]: https://github.com/cdce8p [cast docs]: /integrations/cast/ [前端 docs]: /integrations/frontend/ [homekit docs]: /integrations/homekit/ [媒体播放器.sonos docs]: /integrations/sonos [sonos docs]: /integrations/sonos/ --- url: /home-assistant/blog/2018-08-03-release-75.md --- # 0.75: Spider, Tuya, Brunt, Magicseaweed API And just like that, it's August. Time is flying by. People all over the world have been busy to create this 发布 for you. This 发布 again a ton of cool new stuff. First, let's talk 实体 IDs. 实体 IDs are how we identify 实体 in 自动化 and 脚本. They start with the domain and end with an object id, for example: `light.kitchen`. Or, if you're unlucky `light.node_2_2_abc`. With this 发布, it will now be possible to manage 实体 IDs of 实体 via the UI! Just as with changing the name, it requires that the 集成 is able to supply a unique ID for each 实体.

Screenshot of the 用户 interface to change 实体 identifiers. Screenshot of the new 用户 interface to change 实体 IDs.

This 发布 also includes a bunch more Tuya 集成 thanks to [@huangyupeng]. And thanks to [@peternijssen] we're now also able to talk with Spider thermostats and plugs. ## New Platforms * Add Tuya 温控 platform ([@huangyupeng] - [#15500]) ([tuya docs]) ([温控.tuya docs]) (new-platform) * Add Tuya 风扇 support ([@huangyupeng] - [#15525]) ([tuya docs]) ([风扇.tuya docs]) (new-platform) * Add Tuya 遮盖 and 场景 platform ([@huangyupeng] - [#15587]) ([tuya docs]) ([遮盖.tuya docs]) ([场景.tuya docs]) (new-platform) * Add support for Tahoma Smoke 传感器 ([@fucm] - [#15441]) ([tahoma docs]) ([binary\_sensor.tahoma docs][binary_sensor.tahoma docs]) (new-platform) * Add Brunt 遮盖 设备 ([@eavanvalkenburg] - [#15653]) ([遮盖.brunt docs]) (new-platform) * Add spider thermostat ([@peternijssen] - [#15499]) ([温控.spider docs]) (new-platform) * Add spider power plug component ([@peternijssen] - [#15682]) ([spider docs]) ([开关.spider docs]) (new-platform) * Add support for P5 FutureNow 灯光 platform ([@juhaniemi] - [#15662]) ([灯光.futurenow docs]) (new-platform) * Add Magicseaweed API support ([@jcconnell] - [#15132]) ([传感器.magicseaweed docs]) (new-platform) * Add a component for Sisyphus Kinetic Art Tables ([@jkeljo] - [#14472]) ([sisyphus docs]) ([灯光.sisyphus docs]) ([媒体播放器.sisyphus docs]) (new-platform) * Add Genie Aladdin Connect 遮盖 component ([@shoejosh] - [#15699]) ([遮盖.aladdin\_connect docs][遮盖.aladdin_connect docs]) (new-platform) ## 发布 0.75.1 - August 4 * 升级 Adafruit-DHT to 1.3.3 ([@superpuffin] - [#15706]) ([传感器.dht docs]) * Fix rfxtrx 设备 id matching ([@Danielhiversen] - [#15819]) ([rfxtrx docs]) * Fix custom 面板 and Hass.io 面板 ([@balloob]) ## 发布 0.75.2 - August 6 * 升级 voluptuous to 0.11.5 ([@fabaff] - [#15830]) * Fix envisalink reconnect ([@Cinntax] - [#15832]) ([envisalink docs]) ## 发布 0.75.3 - August 9 * Fix downgrade hassio cannot get refresh\_token issue ([@awarecan] - [#15874]) ([hassio docs]) [#15874]: https://github.com/home-assistant/home-assistant/pull/15874 [@awarecan]: https://github.com/awarecan [hassio docs]: /integrations/hassio/ ## If you need help... ...don't hesitate to use our very active [forums](https://community.home-assistant.io/) or join us for a little [chat](https://discord.gg/c5DvZ4e). The 发布 notes have comments enabled but it's preferred if you use the former communication channels. Thanks. ## Reporting Issues Experiencing issues introduced by this 发布? Please report them in our [issue tracker](https://github.com/home-assistant/home-assistant/issues). Make sure to fill in all fields of the issue 模板. ## Backward-incompatible changes * Moon 传感器 状态 are now lowercase with underscores instead of spaces, allowing it to be translated in the 前端. ([@pvizeli] - [#15498]) ([传感器.moon docs]) (breaking change) * Insteon Mini-遥控器 now emit events instead of show as a 二元sensor ([@teharris1] - [#15523]) ([insteon\_plm docs][insteon_plm docs]) ([binary\_sensor.insteon\_plm docs][binary_sensor.insteon_plm docs]) ([开关.insteon\_plm docs][开关.insteon_plm docs]) (breaking change) * Simplisafe to use new API: co, fire, flood, and last\_event are no longer part of the SimpliSafe 报警 object in the new API and are not available in this 升级, making this a breaking change for anyone using those. They will be added back in some fashion at a later date (probably exposed as individual 传感器) ([@w1ll1am23] - [#15542]) ([alarm\_control\_panel.simplisafe docs][alarm_control_panel.simplisafe docs]) (breaking change) * Smappee: The updated library shows the temperature as degrees Celsius instead of centi degrees Celsius. ([@visibilityspots] - [#15636]) ([smappee docs]) (breaking change) ## Beta Fixes * Fix Min/Max Kelvin color temp 属性 for Google ([@bryanyork] - [#15697]) ([google\_assistant docs][google_assistant docs]) (beta fix) * Only report color temp when in the correct color mode ([@Kane610] - [#15791]) ([灯光.deconz docs]) (beta fix) * Allow Nest to 设置 without 配置.yaml entry ([@balloob] - [#15797]) ([nest docs]) (beta fix) ## All changes * Delay 设置 of waze travel time component ([@squirtbrnr] - [#15455]) ([传感器.waze\_travel\_time docs][传感器.waze_travel_time docs]) * Bump pyarlo==0.2.0, fixes #15486 ([@lukiffer] - [#15503]) ([arlo docs]) * Pylint 2 fixes ([@scop] - [#15487]) * Add Tuya 温控 platform ([@huangyupeng] - [#15500]) ([tuya docs]) ([温控.tuya docs]) (new-platform) * Support latest tplink Archer D9 Firmware 版本 / 设备 Scanner ([@JackNova] - [#15356]) ([device\_tracker docs][device_tracker docs]) * Customizable command timeout ([@mu4yu3] - [#15442]) ([传感器.command\_line docs][传感器.command_line docs]) * Add check\_untyped\_defs ([@andrey-git] - [#15510]) * Remove some unused imports ([@scop] - [#15529]) * Moon translate ([@pvizeli] - [#15498]) ([传感器.moon docs]) (breaking change) * More pylint 2 fixes ([@scop] - [#15516]) * Make sure that only pypi dependencies are used ([@andrey-git] - [#15490]) * RFC: Only use supported 灯光 properties ([@amelchio] - [#15484]) ([灯光 docs]) ([灯光.MQTT docs]) * Cleanup of HomematicIP Cloud code ([@mxworm] - [#15475]) ([homematicip\_cloud docs][homematicip_cloud docs]) * Implement locate 服务 for neato ([@dshokouhi] - [#15467]) ([neato docs]) ([吸尘器.neato docs]) * Make RS 房间 thermostat discoverable ([@turbokongen] - [#15451]) ([zwave docs]) * Add support for Tahoma Smoke 传感器 ([@fucm] - [#15441]) ([tahoma docs]) ([binary\_sensor.tahoma docs][binary_sensor.tahoma docs]) (new-platform) * Mini-遥控器 events ([@teharris1] - [#15523]) ([insteon\_plm docs][insteon_plm docs]) ([binary\_sensor.insteon\_plm docs][binary_sensor.insteon_plm docs]) ([开关.insteon\_plm docs][开关.insteon_plm docs]) (breaking change) * 更新 pyatmo ([@gieljnssns] - [#15540]) ([netatmo docs]) * 更新 reading when 设备 is added ([@quthla] - [#15548]) ([传感器.bme280 docs]) * 更新 config entry id in 实体 registry ([@balloob] - [#15531]) * 升级 to simplisafe-python v2 to use new SimpliSafe API ([@w1ll1am23] - [#15542]) ([alarm\_control\_panel.simplisafe docs][alarm_control_panel.simplisafe docs]) (breaking change) * More pylint 2 fixes ([@scop] - [#15565]) * Add Tuya 风扇 support ([@huangyupeng] - [#15525]) ([tuya docs]) ([风扇.tuya docs]) (new-platform) * fix aiohttp InvalidURL exception when fetching media player 图像 ([@azogue] - [#15572]) ([媒体播放器 docs]) * Allow MQTT 开关 to have an optional 状态 配置 ([@PrimusNZ] - [#15430]) ([开关.MQTT docs]) * Add unique\_id to netgear\_lte 传感器 ([@amelchio] - [#15584]) ([netgear\_lte docs][netgear_lte docs]) ([传感器.netgear\_lte docs][传感器.netgear_lte docs]) * Add relay addr & chan config to alarmdecoder 区域 ([@digiblur] - [#15242]) ([alarmdecoder docs]) ([binary\_sensor.alarmdecoder docs][binary_sensor.alarmdecoder docs]) * 更新 pyhomematic, fixes #15054, #15190 ([@danielperna84] - [#15603]) ([homematic docs]) * Throttle unavailability 警告 for tplink 灯光/开关 ([@amelchio] - [#15591]) ([灯光.tplink docs]) ([开关.tplink docs]) * Remove 实体 picture of Tuya 实体 ([@balloob] - [#15611]) ([tuya docs]) * 升级 mypy to 0.620 ([@scop] - [#15612]) * Pylint cleanups ([@scop] - [#15626]) * Add typing to homeassistant/\*.py and homeassistant/util/ ([@andrey-git] - [#15569]) ([rachio docs]) * Refresh Sonos source list on changes ([@amelchio] - [#15605]) ([媒体播放器.sonos docs]) * The tense is wrong ([@sherazlodhi] - [#15614]) * Suppress 错误 between 00:00 and 01:00 ([@starkillerOG] - [#15555]) ([传感器.buienradar docs]) * Use async\_create\_task ([@balloob] - [#15633]) * Allow system 用户 to refresh tokens ([@balloob] - [#15574]) ([auth docs]) * WIP: Hass.io sent token to supervisor ([@balloob] - [#15536]) ([hassio docs]) * Fix aiohttp connection reset 错误 ([@pvizeli] - [#15577]) * Add ability to set Zwave protection commandclass ([@turbokongen] - [#15390]) ([config docs]) * 更新 Neato library to allow for dynamic endpoints ([@dshokouhi] - [#15639]) ([neato docs]) * Fix typo `asayn_init` instead of `async_init` ([@wingy3181] - [#15645]) ([device\_tracker.tile docs][device_tracker.tile docs]) * Add ipban for failed login attempt in new login flow ([@awarecan] - [#15551]) ([auth docs]) * Add Tuya 遮盖 and 场景 platform ([@huangyupeng] - [#15587]) ([tuya docs]) ([遮盖.tuya docs]) ([场景.tuya docs]) (new-platform) * 更新 smappy library 版本 ([@visibilityspots] - [#15636]) ([smappee docs]) (breaking change) * Allow changing 实体 ID ([@balloob] - [#15637]) * Downgrade netatmo 警告 日志 to info ([@glpatcern] - [#15652]) ([传感器.netatmo docs]) * Add turn\_on/off 服务 to 摄像头 ([@awarecan] - [#15051]) ([摄像头 docs]) * Allow defining default turn-on values for 灯光 in the profiles file. ([@kalimaul] - [#15493]) ([灯光 docs]) * Added 用户 credentials to current\_user ws endpoint. ([@jeradM] - [#15558]) ([auth docs]) * Import collections abstract base classes from collections.abc ([@scop] - [#15649]) ([google\_assistant docs][google_assistant docs]) ([通知 docs]) * Auth typing improvements ([@scop] - [#15640]) * Add spider thermostat ([@peternijssen] - [#15499]) ([温控.spider docs]) (new-platform) * Add Brunt 遮盖 设备 ([@eavanvalkenburg] - [#15653]) ([遮盖.brunt docs]) (new-platform) * Pylint 2 useless-return fixes ([@scop] - [#15677]) ([cloud docs]) ([mailgun docs]) ([通知 docs]) ([温控.heatmiser docs]) ([风扇.comfoconnect docs]) ([传感器.fritzbox\_callmonitor docs][传感器.fritzbox_callmonitor docs]) ([传感器.modem\_callerid docs][传感器.modem_callerid docs]) * Allow Nest Cam 打开/off ([@awarecan] - [#15681]) ([摄像头.nest docs]) * 升级 pylint to 2.0.1 ([@scop] - [#15683]) ([apple\_tv docs][apple_tv docs]) ([灯光 docs]) ([日历.todoist docs]) ([媒体播放器.bluesound docs]) ([媒体播放器.pandora docs]) ([传感器.citybikes docs]) ([传感器.nzbget docs]) ([传感器.pyload docs]) * Fixes a bug with showing a subset of Pollen index 条件 ([@bachya] - [#15694]) ([传感器.pollen docs]) * Add spider power plug component ([@peternijssen] - [#15682]) ([spider docs]) ([开关.spider docs]) (new-platform) * Add support for P5 FutureNow 灯光 platform ([@juhaniemi] - [#15662]) ([灯光.futurenow docs]) (new-platform) * Only 日志 change to use access token 警告 once ([@awarecan] - [#15690]) ([http docs]) * Add support for alarm\_control\_panel to MQTT Discovery. ([@rorr73] - [#15689]) ([MQTT docs]) ([alarm\_control\_panel.MQTT docs][alarm_control_panel.MQTT docs]) * Add Magicseaweed API support ([@jcconnell] - [#15132]) ([传感器.magicseaweed docs]) (new-platform) * 升级 pyvera to 0.2.44 ([@alanfischer] - [#15708]) ([vera docs]) * Remove IHC XML Element from discovery data ([@dingusdk] - [#15719]) ([ihc docs]) ([binary\_sensor.ihc docs][binary_sensor.ihc docs]) ([灯光.ihc docs]) ([传感器.ihc docs]) ([开关.ihc docs]) * Context ([@balloob] - [#15674]) ([api docs]) ([http docs]) ([灯光 docs]) ([开关 docs]) ([websocket\_api docs][websocket_api docs]) * Break up components/auth ([@awarecan] - [#15713]) ([auth docs]) * Add a component for Sisyphus Kinetic Art Tables ([@jkeljo] - [#14472]) ([sisyphus docs]) ([灯光.sisyphus docs]) ([媒体播放器.sisyphus docs]) (new-platform) * Command Line 传感器 - json\_attributes ([@alexhardwicke] - [#15679]) ([传感器.command\_line docs][传感器.command_line docs]) * 升级 youtube\_dl to 2018.07.21 ([@fabaff] - [#15718]) ([media\_extractor docs][media_extractor docs]) * 升级 numpy to 1.15.0 ([@fabaff] - [#15722]) ([binary\_sensor.trend docs][binary_sensor.trend docs]) ([image\_processing.opencv docs][image_processing.opencv docs]) * 升级 spiderpy to 1.2.0 ([@peternijssen] - [#15729]) ([spider docs]) * 升级 beautifulsoup4 to 4.6.1 ([@fabaff] - [#15727]) ([device\_tracker docs][device_tracker docs]) ([传感器.geizhals docs]) ([传感器.scrape docs]) * 升级 mutagen to 1.41.0 ([@fabaff] - [#15739]) ([tts docs]) * 升级 sqlalchemy to 1.2.10 ([@fabaff] - [#15737]) ([传感器.sql docs]) * 升级 voluptuous to 0.11.3 ([@fabaff] - [#15735]) * 升级 youtube\_dl to 2018.07.29 ([@fabaff] - [#15734]) ([media\_extractor docs][media_extractor docs]) * 升级 pyowm to 2.9.0 ([@fabaff] - [#15736]) ([传感器.openweathermap docs]) ([天气.openweathermap docs]) * Various updates ([@fabaff] - [#15738]) ([摄像头.proxy docs]) * Denonavr 版本 push to 0.7.5 ([@starkillerOG] - [#15743]) ([媒体播放器.denonavr docs]) * Make FutureNow 灯光 remember last brightness when turning on ([@juhaniemi] - [#15733]) ([灯光.futurenow docs]) * Add Genie Aladdin Connect 遮盖 component ([@shoejosh] - [#15699]) ([遮盖.aladdin\_connect docs][遮盖.aladdin_connect docs]) (new-platform) * Add mvglive option to store multiple departures in 属性 ([@DavidMStraub] - [#15454]) ([传感器.mvglive docs]) * Add other wemo motion 传感器 identifier ([@danielfaulknor] - [#15627]) ([wemo docs]) * Remove self type hints ([@awarecan] - [#15732]) ([风扇 docs]) ([温控.honeywell docs]) ([风扇.dyson docs]) ([风扇.insteon\_local docs][风扇.insteon_local docs]) ([风扇.模板 docs]) ([风扇.wink docs]) ([风扇.zha docs]) * Fix Min/Max Kelvin color temp 属性 for Google ([@bryanyork] - [#15697]) ([google\_assistant docs][google_assistant docs]) (beta fix) * Only report color temp when in the correct color mode ([@Kane610] - [#15791]) ([灯光.deconz docs]) (beta fix) * Return True from Nest 设置 ([@balloob] - [#15797]) ([nest docs]) (beta fix) [#14472]: https://github.com/home-assistant/home-assistant/pull/14472 [#15051]: https://github.com/home-assistant/home-assistant/pull/15051 [#15132]: https://github.com/home-assistant/home-assistant/pull/15132 [#15242]: https://github.com/home-assistant/home-assistant/pull/15242 [#15356]: https://github.com/home-assistant/home-assistant/pull/15356 [#15390]: https://github.com/home-assistant/home-assistant/pull/15390 [#15430]: https://github.com/home-assistant/home-assistant/pull/15430 [#15441]: https://github.com/home-assistant/home-assistant/pull/15441 [#15442]: https://github.com/home-assistant/home-assistant/pull/15442 [#15451]: https://github.com/home-assistant/home-assistant/pull/15451 [#15454]: https://github.com/home-assistant/home-assistant/pull/15454 [#15455]: https://github.com/home-assistant/home-assistant/pull/15455 [#15467]: https://github.com/home-assistant/home-assistant/pull/15467 [#15475]: https://github.com/home-assistant/home-assistant/pull/15475 [#15484]: https://github.com/home-assistant/home-assistant/pull/15484 [#15487]: https://github.com/home-assistant/home-assistant/pull/15487 [#15490]: https://github.com/home-assistant/home-assistant/pull/15490 [#15493]: https://github.com/home-assistant/home-assistant/pull/15493 [#15498]: https://github.com/home-assistant/home-assistant/pull/15498 [#15499]: https://github.com/home-assistant/home-assistant/pull/15499 [#15500]: https://github.com/home-assistant/home-assistant/pull/15500 [#15503]: https://github.com/home-assistant/home-assistant/pull/15503 [#15510]: https://github.com/home-assistant/home-assistant/pull/15510 [#15516]: https://github.com/home-assistant/home-assistant/pull/15516 [#15523]: https://github.com/home-assistant/home-assistant/pull/15523 [#15525]: https://github.com/home-assistant/home-assistant/pull/15525 [#15529]: https://github.com/home-assistant/home-assistant/pull/15529 [#15531]: https://github.com/home-assistant/home-assistant/pull/15531 [#15536]: https://github.com/home-assistant/home-assistant/pull/15536 [#15540]: https://github.com/home-assistant/home-assistant/pull/15540 [#15542]: https://github.com/home-assistant/home-assistant/pull/15542 [#15548]: https://github.com/home-assistant/home-assistant/pull/15548 [#15551]: https://github.com/home-assistant/home-assistant/pull/15551 [#15555]: https://github.com/home-assistant/home-assistant/pull/15555 [#15558]: https://github.com/home-assistant/home-assistant/pull/15558 [#15565]: https://github.com/home-assistant/home-assistant/pull/15565 [#15569]: https://github.com/home-assistant/home-assistant/pull/15569 [#15572]: https://github.com/home-assistant/home-assistant/pull/15572 [#15574]: https://github.com/home-assistant/home-assistant/pull/15574 [#15577]: https://github.com/home-assistant/home-assistant/pull/15577 [#15584]: https://github.com/home-assistant/home-assistant/pull/15584 [#15587]: https://github.com/home-assistant/home-assistant/pull/15587 [#15591]: https://github.com/home-assistant/home-assistant/pull/15591 [#15603]: https://github.com/home-assistant/home-assistant/pull/15603 [#15605]: https://github.com/home-assistant/home-assistant/pull/15605 [#15611]: https://github.com/home-assistant/home-assistant/pull/15611 [#15612]: https://github.com/home-assistant/home-assistant/pull/15612 [#15614]: https://github.com/home-assistant/home-assistant/pull/15614 [#15626]: https://github.com/home-assistant/home-assistant/pull/15626 [#15627]: https://github.com/home-assistant/home-assistant/pull/15627 [#15633]: https://github.com/home-assistant/home-assistant/pull/15633 [#15636]: https://github.com/home-assistant/home-assistant/pull/15636 [#15637]: https://github.com/home-assistant/home-assistant/pull/15637 [#15639]: https://github.com/home-assistant/home-assistant/pull/15639 [#15640]: https://github.com/home-assistant/home-assistant/pull/15640 [#15645]: https://github.com/home-assistant/home-assistant/pull/15645 [#15649]: https://github.com/home-assistant/home-assistant/pull/15649 [#15652]: https://github.com/home-assistant/home-assistant/pull/15652 [#15653]: https://github.com/home-assistant/home-assistant/pull/15653 [#15662]: https://github.com/home-assistant/home-assistant/pull/15662 [#15674]: https://github.com/home-assistant/home-assistant/pull/15674 [#15677]: https://github.com/home-assistant/home-assistant/pull/15677 [#15679]: https://github.com/home-assistant/home-assistant/pull/15679 [#15681]: https://github.com/home-assistant/home-assistant/pull/15681 [#15682]: https://github.com/home-assistant/home-assistant/pull/15682 [#15683]: https://github.com/home-assistant/home-assistant/pull/15683 [#15689]: https://github.com/home-assistant/home-assistant/pull/15689 [#15690]: https://github.com/home-assistant/home-assistant/pull/15690 [#15694]: https://github.com/home-assistant/home-assistant/pull/15694 [#15697]: https://github.com/home-assistant/home-assistant/pull/15697 [#15699]: https://github.com/home-assistant/home-assistant/pull/15699 [#15708]: https://github.com/home-assistant/home-assistant/pull/15708 [#15713]: https://github.com/home-assistant/home-assistant/pull/15713 [#15718]: https://github.com/home-assistant/home-assistant/pull/15718 [#15719]: https://github.com/home-assistant/home-assistant/pull/15719 [#15722]: https://github.com/home-assistant/home-assistant/pull/15722 [#15727]: https://github.com/home-assistant/home-assistant/pull/15727 [#15729]: https://github.com/home-assistant/home-assistant/pull/15729 [#15732]: https://github.com/home-assistant/home-assistant/pull/15732 [#15733]: https://github.com/home-assistant/home-assistant/pull/15733 [#15734]: https://github.com/home-assistant/home-assistant/pull/15734 [#15735]: https://github.com/home-assistant/home-assistant/pull/15735 [#15736]: https://github.com/home-assistant/home-assistant/pull/15736 [#15737]: https://github.com/home-assistant/home-assistant/pull/15737 [#15738]: https://github.com/home-assistant/home-assistant/pull/15738 [#15739]: https://github.com/home-assistant/home-assistant/pull/15739 [#15743]: https://github.com/home-assistant/home-assistant/pull/15743 [#15791]: https://github.com/home-assistant/home-assistant/pull/15791 [#15797]: https://github.com/home-assistant/home-assistant/pull/15797 [@DavidMStraub]: https://github.com/DavidMStraub [@JackNova]: https://github.com/JackNova [@Kane610]: https://github.com/Kane610 [@PrimusNZ]: https://github.com/PrimusNZ [@alanfischer]: https://github.com/alanfischer [@alexhardwicke]: https://github.com/alexhardwicke [@amelchio]: https://github.com/amelchio [@andrey-git]: https://github.com/andrey-git [@awarecan]: https://github.com/awarecan [@azogue]: https://github.com/azogue [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@bryanyork]: https://github.com/bryanyork [@danielfaulknor]: https://github.com/danielfaulknor [@danielperna84]: https://github.com/danielperna84 [@digiblur]: https://github.com/digiblur [@dingusdk]: https://github.com/dingusdk [@dshokouhi]: https://github.com/dshokouhi [@eavanvalkenburg]: https://github.com/eavanvalkenburg [@fabaff]: https://github.com/fabaff [@fucm]: https://github.com/fucm [@gieljnssns]: https://github.com/gieljnssns [@glpatcern]: https://github.com/glpatcern [@huangyupeng]: https://github.com/huangyupeng [@jcconnell]: https://github.com/jcconnell [@jeradM]: https://github.com/jeradM [@jkeljo]: https://github.com/jkeljo [@juhaniemi]: https://github.com/juhaniemi [@kalimaul]: https://github.com/kalimaul [@lukiffer]: https://github.com/lukiffer [@mu4yu3]: https://github.com/mu4yu3 [@mxworm]: https://github.com/mxworm [@peternijssen]: https://github.com/peternijssen [@pvizeli]: https://github.com/pvizeli [@quthla]: https://github.com/quthla [@rorr73]: https://github.com/rorr73 [@scop]: https://github.com/scop [@sherazlodhi]: https://github.com/sherazlodhi [@shoejosh]: https://github.com/shoejosh [@squirtbrnr]: https://github.com/squirtbrnr [@starkillerOG]: https://github.com/starkillerOG [@teharris1]: https://github.com/teharris1 [@turbokongen]: https://github.com/turbokongen [@visibilityspots]: https://github.com/visibilityspots [@w1ll1am23]: https://github.com/w1ll1am23 [@wingy3181]: https://github.com/wingy3181 [alarm_control_panel.MQTT docs]: /integrations/alarm_control_panel.MQTT/ [alarm_control_panel.simplisafe docs]: /integrations/simplisafe [alarmdecoder docs]: /integrations/alarmdecoder/ [api docs]: /integrations/api/ [apple_tv docs]: /integrations/apple_tv/ [arlo docs]: /integrations/arlo/ [auth docs]: /integrations/auth/ [binary_sensor.alarmdecoder docs]: /integrations/alarmdecoder [binary_sensor.ihc docs]: /integrations/ihc#binary-传感器 [binary_sensor.insteon_plm docs]: /integrations/insteon/ [binary_sensor.tahoma docs]: /integrations/tahoma [binary_sensor.trend docs]: /integrations/trend [日历.todoist docs]: /integrations/todoist [摄像头 docs]: /integrations/摄像头/ [摄像头.demo docs]: /integrations/摄像头.demo/ [摄像头.nest docs]: /integrations/nest#摄像头 [摄像头.proxy docs]: /integrations/proxy [温控.heatmiser docs]: /integrations/heatmiser [温控.honeywell docs]: /integrations/honeywell [温控.spider docs]: /integrations/spider#温控 [温控.tuya docs]: /integrations/tuya [cloud docs]: /integrations/cloud/ [config docs]: /integrations/config/ [遮盖.aladdin_connect docs]: /integrations/aladdin_connect [遮盖.brunt docs]: /integrations/brunt [遮盖.tuya docs]: /integrations/tuya [device_tracker docs]: /integrations/device_tracker/ [device_tracker.tile docs]: /integrations/tile [风扇 docs]: /integrations/风扇/ [风扇.comfoconnect docs]: /integrations/comfoconnect [风扇.dyson docs]: /integrations/dyson#风扇 [风扇.insteon_local docs]: /integrations/insteon/ [风扇.模板 docs]: /integrations/风扇.模板/ [风扇.tuya docs]: /integrations/tuya [风扇.wink docs]: /integrations/wink#风扇 [风扇.zha docs]: /integrations/zha [google_assistant docs]: /integrations/google_assistant/ [hassio docs]: /integrations/hassio/ [homematic docs]: /integrations/homematic/ [homematicip_cloud docs]: /integrations/homematicip_cloud/ [http docs]: /integrations/http/ [ihc docs]: /integrations/ihc/ [image_processing.opencv docs]: /integrations/opencv [insteon_plm docs]: /integrations/insteon/ [灯光 docs]: /integrations/灯光/ [灯光.deconz docs]: /integrations/deconz#灯光 [灯光.futurenow docs]: /integrations/futurenow [灯光.ihc docs]: /integrations/ihc#灯光 [灯光.MQTT docs]: /integrations/灯光.MQTT/ [灯光.sisyphus docs]: /integrations/sisyphus [灯光.tplink docs]: /integrations/tplink [mailgun docs]: /integrations/mailgun/ [media_extractor docs]: /integrations/media_extractor/ [媒体播放器 docs]: /integrations/媒体播放器/ [媒体播放器.bluesound docs]: /integrations/bluesound [媒体播放器.denonavr docs]: /integrations/denonavr/ [媒体播放器.pandora docs]: /integrations/pandora [媒体播放器.sisyphus docs]: /integrations/sisyphus [媒体播放器.sonos docs]: /integrations/sonos [MQTT docs]: /integrations/MQTT/ [neato docs]: /integrations/neato/ [nest docs]: /integrations/nest/ [netatmo docs]: /integrations/netatmo/ [netgear_lte docs]: /integrations/netgear_lte/ [通知 docs]: /integrations/通知/ [rachio docs]: /integrations/rachio/ [场景.tuya docs]: /integrations/tuya [传感器.bme280 docs]: /integrations/bme280 [传感器.buienradar docs]: /integrations/传感器.buienradar/ [传感器.citybikes docs]: /integrations/citybikes [传感器.command_line docs]: /integrations/传感器.command_line/ [传感器.fritzbox_callmonitor docs]: /integrations/fritzbox#sensor_callmonitor/ [传感器.geizhals docs]: /integrations/geizhals [传感器.ihc docs]: /integrations/ihc#传感器 [传感器.magicseaweed docs]: /integrations/magicseaweed [传感器.modem_callerid docs]: /integrations/modem_callerid [传感器.moon docs]: /integrations/moon [传感器.mvglive docs]: /integrations/mvglive [传感器.netatmo docs]: /integrations/netatmo#传感器 [传感器.netgear_lte docs]: /integrations/netgear_lte [传感器.nzbget docs]: /integrations/nzbget [传感器.openweathermap docs]: /integrations/openweathermap#传感器 [传感器.pollen docs]: /integrations/iqvia [传感器.pyload docs]: /integrations/pyload [传感器.scrape docs]: /integrations/scrape [传感器.sql docs]: /integrations/sql [传感器.strings.moon.json docs]: /integrations/传感器.strings.moon.json/ [传感器.waze_travel_time docs]: /integrations/waze_travel_time [sisyphus docs]: /integrations/sisyphus/ [smappee docs]: /integrations/smappee/ [spider docs]: /integrations/spider/ [开关 docs]: /integrations/开关/ [开关.ihc docs]: /integrations/ihc#开关 [开关.insteon_plm docs]: /integrations/insteon/ [开关.MQTT docs]: /integrations/开关.MQTT/ [开关.spider docs]: /integrations/spider [开关.tplink docs]: /integrations/tplink [tahoma docs]: /integrations/tahoma/ [tts docs]: /integrations/tts/ [tuya docs]: /integrations/tuya/ [吸尘器.neato docs]: /integrations/neato#吸尘器 [vera docs]: /integrations/vera/ [天气.openweathermap docs]: /integrations/openweathermap#天气 [websocket_api docs]: /integrations/websocket_api/ [wemo docs]: /integrations/wemo/ [zwave docs]: /integrations/zwave/ [#15706]: https://github.com/home-assistant/home-assistant/pull/15706 [#15819]: https://github.com/home-assistant/home-assistant/pull/15819 [@Danielhiversen]: https://github.com/Danielhiversen [@superpuffin]: https://github.com/superpuffin [rfxtrx docs]: /integrations/rfxtrx/ [传感器.dht docs]: /integrations/dht [#15830]: https://github.com/home-assistant/home-assistant/pull/15830 [#15832]: https://github.com/home-assistant/home-assistant/pull/15832 [@Cinntax]: https://github.com/Cinntax [@fabaff]: https://github.com/fabaff [envisalink docs]: /integrations/envisalink/ --- url: /home-assistant/blog/2018-08-17-release-76.md --- # 0.76: Auth almost done, FleetGo, PJLink, RMV public transport :::note This 发布 has a migration, initial startup can take ~20 minutes (depends on size DB) ::: This 发布 includes a database migration to allow us to store context in the database. This will make it possible in the future to introduce attribution. For example, we'll be able to say which 用户 opened the garage door or which 自动化 triggered the party mode at 3am. The auth system is entering 发布 candidate status 🎉. If nothing major is found, it will be enabled by default starting the next 发布 (0.77) with backwards compatibility modus turned on. If you want to get ahead of the pack, you can already easily enable it now: ```yaml homeassistant: # add this part auth_providers: - type: homeassistant # uncomment this to enable backwards compatible API password support # - type: legacy_api_password ``` For iOS 用户, your 前端 should be a lot faster. We had an issue that forced us to serve the 前端 in compatibility mode, which is slower. We haven't been able to solve [the issue](https://bugs.webkit.org/show_bug.cgi?id=174629), but found a workaround. Race on 🏎. 警告. If you are using the internal MQTT broker, we've had to make a change how the 密码 is set. In the past it would automatically start the broker with the 用户 `homeassistant` and a 密码 equal to the API 密码. This is no longer the case and you need to 配置 it yourself now: ```yaml mqtt: password: mypass ``` ## New Platforms * deCONZ - support for power plugs ([@Kane610] - [#15752]) ([deconz docs]) ([灯光.deconz docs]) ([开关.deconz docs]) (breaking change) (new-platform) * RitAssist / FleetGO support ([@depl0y] - [#15780]) ([device\_tracker docs][device_tracker docs]) (new-platform) * Add support for OpenUV 二元sensor and 传感器 ([@bachya] - [#15769]) ([openuv docs]) ([binary\_sensor.openuv docs][binary_sensor.openuv docs]) ([传感器.openuv docs]) (new-platform) * Add Enphase Envoy component ([@jesserizzo] - [#15081]) ([传感器.enphase\_envoy docs][传感器.enphase_envoy docs]) (new-platform) * Add 媒体播放器.dlna\_dmr component ([@StevenLooman] - [#14749]) ([媒体播放器.dlna\_dmr docs][媒体播放器.dlna_dmr docs]) (new-platform) * Add PJLink media player platform ([@benoitlouy] - [#15083]) ([媒体播放器.pjlink docs]) (new-platform) * Add RMV public transport 传感器 ([@cgtobi] - [#15814]) ([传感器.rmvtransport docs]) (new-platform) ## New Features * Add and 恢复 context in recorder ([@balloob] - [#15859]) (new-feature) ## 发布 0.76.1 - August 19 * No longer show "Store login" on each login when using API 密码 ([@balloob]) * Add forgiving add column ([@balloob] - [#16057]) * Tuya fix login problem and add login platform param ([@huangyupeng] - [#16058]) ([tuya docs]) * Add 通知 platforms to loaded components ([@balloob] - [#16063]) ([通知 docs]) * Column syntax fix + Add a file if migration in progress ([@balloob] - [#16061]) [#16057]: https://github.com/home-assistant/home-assistant/pull/16057 [#16058]: https://github.com/home-assistant/home-assistant/pull/16058 [#16061]: https://github.com/home-assistant/home-assistant/pull/16061 [#16063]: https://github.com/home-assistant/home-assistant/pull/16063 [@balloob]: https://github.com/balloob [@huangyupeng]: https://github.com/huangyupeng [通知 docs]: /integrations/通知/ [tuya docs]: /integrations/tuya/ ## 发布 0.76.2 - August 21 * Forgiving add index in migration ([@balloob] - [#16092]) * Fix push 通知 切换 ([@balloob]) [#16092]: https://github.com/home-assistant/home-assistant/pull/16092 [@balloob]: https://github.com/balloob ## If you need help... ...don't hesitate to use our very active [forums](https://community.home-assistant.io/) or join us for a little [chat](https://discord.gg/c5DvZ4e). The 发布 notes have comments enabled but it's preferred if you use the former communication channels. Thanks. ## Reporting Issues Experiencing issues introduced by this 发布? Please report them in our [issue tracker](https://github.com/home-assistant/home-assistant/issues). Make sure to fill in all fields of the issue 模板. ## Backward-incompatible changes * Keenetic NDMS: 用户 needs to have access to the TelNet interface ([@foxel] - [#15511]) ([device\_tracker docs][device_tracker docs]) (breaking change) * openweathermap: wind speed is now correctly in km/h (fixes #15710) ([@fabaff] - [#15740]) ([天气.openweathermap docs]) (breaking change) * Remove Telstra notifiy component: This API has been decommissioned on the 31st of May 2018 by Telstra ([@dgomes] - [#15757]) ([通知 docs]) (breaking change) * deCONZ - support for power plugs. Power plugs that are of type "On/Off plug-in unit" and "Smart plug" (Osram and Innr among others) will now be 开关 instead of 灯光. 实体 will be found as 开关.entity\_id instead of 灯光.entity\_id. ([@Kane610] - [#15752]) ([deconz docs]) ([灯光.deconz docs]) ([开关.deconz docs]) (breaking change) (new-platform) * HTTP: Make sure use\_x\_forward\_for and trusted\_proxies must be configured together ([@awarecan] - [#15804]) ([http docs]) (breaking change) * Velbus: Backward-incompatible changes include auto-discovery support so that you don't need to specify modules manually anymore in the 配置 file, but just load the velbus component which will automatically load the 开关 and binary\_sensor platforms. In addition, the 风扇 and 灯光 platforms are removed since these should be modeled with 模板 platform based on velbus 开关. ([@thomasdelaet] - [#13742]) ([velbus docs]) ([binary\_sensor.velbus docs][binary_sensor.velbus docs]) ([开关.velbus docs]) (breaking change) * Facebox: Events are no longer fired when a face is taught, as these are unnecessary and the info they convey is already in the 日志. ([@robmarkcole] - [#15439]) ([image\_processing.facebox docs][image_processing.facebox docs]) (breaking change) * AMCrest 开关: Fix for multiple 摄像头 开关 naming of 实体. May change 开关 entity\_id. Please check your 自动化 and 更新 the identity-id if you have previously assigned a name to your 摄像头 as it appends the name of the 摄像头 to the 开关 id. ([@rafale77] - [#14028]) ([开关.amcrest docs]) (breaking change) * MQTT embedded broker will no longer rely on HTTP API 密码 to automatically 配置 itself. You need to set own 密码. ([@awarecan] - [#15929]) ([MQTT docs]) (breaking change) (beta fix) * Remove 遥控器.API from 核心.Config. Might break custom components if they rely on hass.config.api ([@awarecan] - [#15951]) ([http docs]) (breaking change) (beta fix) ## Beta Fixes * 升级 pymysensors to 0.17.0 ([@MartinHjelmare] - [#15942]) ([mysensors docs]) (beta fix) * Deprecate 遥控器.api ([@balloob] - [#15955]) (beta fix) * Added 错误 handling for sense API timeouts ([@kbickar] - [#15789]) ([传感器.sense docs]) (beta fix) * Add context to login flow ([@awarecan] - [#15914]) ([auth docs]) (beta fix) * MQTT embedded broker has to set its own 密码. ([@awarecan] - [#15929]) ([MQTT docs]) (breaking change) (beta fix) * Fix issue when reading worxlandroid pin code ([@GotoCode] - [#15930]) ([传感器.worxlandroid docs]) (beta fix) * remove-phantomjs-from-Docker ([@vrih] - [#15936]) (beta fix) * Remove 遥控器.API from 核心.Config ([@awarecan] - [#15951]) ([http docs]) (breaking change) (beta fix) * Allow picking intermediate Mozilla cert profile ([@balloob] - [#15957]) ([http docs]) (beta fix) * Use JWT for access tokens ([@balloob] - [#15972]) ([auth docs]) ([http docs]) ([websocket\_api docs][websocket_api docs]) (beta fix) * Pin crypto ([@balloob] - [#15978]) (beta fix) * Teak MQTT 错误 message for 0.76 发布 ([@awarecan] - [#15983]) ([MQTT docs]) (beta fix) * Fix 0.76 beta2 hassio token issue ([@awarecan] - [#15987]) ([hassio docs]) (beta fix) * Fix mysensors connection task blocking 设置 ([@MartinHjelmare] - [#15938]) ([mysensors docs]) (beta fix) * Fix Nest async from sync ([@balloob] - [#15997]) ([nest docs]) (beta fix) ## All changes * Add kodi unique id based on discovery ([@rytilahti] - [#15093]) ([媒体播放器.kodi docs]) * Better handling of Yi 摄像头 being disconnected ([@bachya] - [#15754]) ([摄像头.yi docs]) * Decouple login flow view and data entry flow view ([@awarecan] - [#15715]) ([auth docs]) * Fixed NDMS for latest firmware ([@foxel] - [#15511]) ([device\_tracker docs][device_tracker docs]) (breaking change) * Add disallow\_untyped\_calls to mypy check. ([@andrey-git] - [#15661]) ([persistent\_notification docs][persistent_notification docs]) * 更新 pyozw to 0.4.9 ([@turbokongen] - [#15758]) ([zwave docs]) * Convert wind speed to km/h (fixes #15710) ([@fabaff] - [#15740]) ([天气.openweathermap docs]) (breaking change) * Round precipitation forecast to 1 decimal place ([@priiduonu] - [#15759]) ([天气.openweathermap docs]) * Add a "Reviewed by Hound" badge ([@salbertson] - [#15767]) * 升级 Mastodon.py to 1.3.1 ([@fabaff] - [#15766]) ([通知 docs]) * This component API has been decommissioned on the 31st of May 2018 by Telstra ([@dgomes] - [#15757]) ([通知 docs]) (breaking change) * Fix docstrings ([@fabaff] - [#15770]) * 更新 pynetgear to 0.4.1 (bugfixes) ([@MatMaul] - [#15768]) ([device\_tracker docs][device_tracker docs]) * Opensky altitude ([@ioangogo] - [#15273]) ([传感器.opensky docs]) * Expose internal 状态 and fixed on/off 状态 of Dyson 风扇 ([@soraxas] - [#15716]) ([风扇.dyson docs]) * deCONZ - support for power plugs ([@Kane610] - [#15752]) ([deconz docs]) ([灯光.deconz docs]) ([开关.deconz docs]) (breaking change) (new-platform) * Add support for 状态 of 吸尘器 ([@cnrd] - [#15573]) ([吸尘器 docs]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) * Add support for STATE\_AUTO of generic\_thermostat ([@niklaswa] - [#15678]) ([温控.generic\_thermostat docs][温控.generic_thermostat docs]) * Revert "Add support for STATE\_AUTO of generic\_thermostat (#15678)" ([@awarecan] - [#15783]) ([温控.generic\_thermostat docs][温控.generic_thermostat docs]) * RitAssist / FleetGO support ([@depl0y] - [#15780]) ([device\_tracker docs][device_tracker docs]) (new-platform) * Add support for OpenUV 二元sensor and 传感器 ([@bachya] - [#15769]) ([openuv docs]) ([binary\_sensor.openuv docs][binary_sensor.openuv docs]) ([传感器.openuv docs]) (new-platform) * 更新 pymediaroom to 0.6.4 ([@dgomes] - [#15786]) ([媒体播放器.mediaroom docs]) * Add Enphase Envoy component ([@jesserizzo] - [#15081]) ([传感器.enphase\_envoy docs][传感器.enphase_envoy docs]) (new-platform) * 吸尘器 component: start\_pause to individual start and pause commands. ([@cnrd] - [#15751]) ([吸尘器 docs]) * Make sure use\_x\_forward\_for and trusted\_proxies must config together ([@awarecan] - [#15804]) ([http docs]) (breaking change) * 升级 voluptuous-serialize to 2.0.0 ([@awarecan] - [#15763]) ([config docs]) * 升级 pylint to 2.1.0 ([@scop] - [#15811]) ([binary\_sensor.bayesian docs][binary_sensor.bayesian docs]) ([binary\_sensor.threshold docs][binary_sensor.threshold docs]) ([日历.todoist docs]) ([灯光.group docs]) ([传感器.min\_max docs][传感器.min_max docs]) ([传感器.statistics docs]) * 升级 pytest to 3.7.1 and pytest-timeout to 1.3.1 ([@scop] - [#15809]) * Add support for 2 Tahoma IO awning 遮盖 ([@fucm] - [#15660]) ([tahoma docs]) ([遮盖.tahoma docs]) * Velbus auto-discovery ([@thomasdelaet] - [#13742]) ([velbus docs]) ([binary\_sensor.velbus docs][binary_sensor.velbus docs]) ([开关.velbus docs]) (breaking change) * 升级 youtube\_dl to 2018.08.04 ([@fabaff] - [#15837]) ([media\_extractor docs][media_extractor docs]) * Add 媒体播放器.dlna\_dmr component ([@StevenLooman] - [#14749]) ([媒体播放器.dlna\_dmr docs][媒体播放器.dlna_dmr docs]) (new-platform) * Remove 'volume' from return dict ([@mattwing] - [#15842]) ([传感器.alpha\_vantage docs][传感器.alpha_vantage docs]) * 升级 shodan to 1.9.0 ([@fabaff] - [#15839]) ([传感器.shodan docs]) * Add max\_gps\_accuracy option to Google Maps ([@PrimusNZ] - [#15833]) ([device\_tracker docs][device_tracker docs]) * Fix bt\_home\_hub\_5 设备 tracker ([@ahobsonsayers] - [#15096]) ([device\_tracker docs][device_tracker docs]) * Change to call\_service async\_stop non-blocking to allow 服务 call finish ([@awarecan] - [#15803]) * Try to fix coveralls unstable result ([@awarecan] - [#15800]) * Add different pop 012501 ID ([@turbokongen] - [#15838]) ([zwave docs]) * Fix 错误 when Series missing 'episodeFileCount' or 'episodeCount' ([@psike] - [#15824]) ([传感器.sonarr docs]) * Add facebox auth ([@robmarkcole] - [#15439]) ([image\_processing.facebox docs][image_processing.facebox docs]) (breaking change) * 升级 holidays to 0.9.6 ([@fabaff] - [#15831]) ([binary\_sensor.workday docs][binary_sensor.workday docs]) * 升级 pysnmp to 4.4.5 ([@fabaff] - [#15854]) ([device\_tracker docs][device_tracker docs]) ([传感器.snmp docs]) ([开关.snmp docs]) * Fix HomeKit test ([@cdce8p] - [#15860]) * Do not make internet connection during tests ([@balloob] - [#15858]) * 升级 pylint to 2.1.1 ([@scop] - [#15872]) * 升级 asynctest to 0.12.2 ([@fabaff] - [#15869]) * 升级 Sphinx to 1.7.6 ([@fabaff] - [#15868]) * 升级 requests\_mock to 1.5.2 ([@fabaff] - [#15867]) * 更新 based upon forum post ([@DubhAd] - [#15876]) ([device\_tracker docs][device_tracker docs]) * 升级 netdisco to 2.0.0 ([@fabaff] - [#15885]) * Follow changes to netdisco, separating DLNA into DLNA\_DMS and DLNA\_DMR ([@StevenLooman] - [#15877]) ([媒体播放器.dlna\_dmr docs][媒体播放器.dlna_dmr docs]) * 升级 pylast to 2.4.0 ([@fabaff] - [#15886]) ([传感器.lastfm docs]) * Add auth/授权 endpoint ([@balloob] - [#15887]) * 升级 locationsharinglib to 2.0.11 ([@fabaff] - [#15902]) ([device\_tracker docs][device_tracker docs]) * Refactor data entry flow ([@awarecan] - [#15883]) * Add HomematicIP Cloud smoke detector 设备 ([@mxworm] - [#15621]) ([binary\_sensor.homematicip\_cloud docs][binary_sensor.homematicip_cloud docs]) * Fix for multiple 摄像头 开关 naming of 实体 ([@rafale77] - [#14028]) ([开关.amcrest docs]) (breaking change) * Add realtime true/false 开关 for Waze ([@mountainsandcode] - [#15228]) ([传感器.waze\_travel\_time docs][传感器.waze_travel_time docs]) * Add PJLink media player platform ([@benoitlouy] - [#15083]) ([媒体播放器.pjlink docs]) (new-platform) * Some typing related fixes ([@scop] - [#15899]) * 更新 August component to use py-august:0.6.0 ([@snjoetw] - [#15916]) ([august docs]) * Misc cleanups ([@scop] - [#15907]) ([device\_tracker docs][device_tracker docs]) ([传感器.irish\_rail\_transport docs][传感器.irish_rail_transport docs]) * 更新 radiotherm to 1.4.1 ([@craftyguy] - [#15910]) ([温控.radiotherm docs]) * Fix bug in translations upload 脚本 ([@armills] - [#15922]) * Add and 恢复 context in recorder ([@balloob] - [#15859]) (new-feature) * Add IndieAuth 4.2.2 redirect uri at client id ([@balloob] - [#15911]) ([auth docs]) * deCONZ - Add support for 警报器 ([@Kane610] - [#15896]) ([deconz docs]) ([开关.deconz docs]) * Add RMV public transport 传感器 ([@cgtobi] - [#15814]) ([传感器.rmvtransport docs]) (new-platform) * :pencil2: Corrects typo in code comments ([@frenck] - [#15923]) ([binary\_sensor.homematicip\_cloud docs][binary_sensor.homematicip_cloud docs]) * 升级 pymysensors to 0.17.0 ([@MartinHjelmare] - [#15942]) ([mysensors docs]) (beta fix) * Deprecate 遥控器.api ([@balloob] - [#15955]) (beta fix) * Added 错误 handling for sense API timeouts ([@kbickar] - [#15789]) ([传感器.sense docs]) (beta fix) * Add context to login flow ([@awarecan] - [#15914]) ([auth docs]) (beta fix) * MQTT embedded broker has to set its own 密码. ([@awarecan] - [#15929]) ([MQTT docs]) (breaking change) (beta fix) * Fix issue when reading worxlandroid pin code ([@GotoCode] - [#15930]) ([传感器.worxlandroid docs]) (beta fix) * remove-phantomjs-from-Docker ([@vrih] - [#15936]) (beta fix) * Remove 遥控器.API from 核心.Config ([@awarecan] - [#15951]) ([http docs]) (breaking change) (beta fix) * Allow picking intermediate Mozilla cert profile ([@balloob] - [#15957]) ([http docs]) (beta fix) * Use JWT for access tokens ([@balloob] - [#15972]) ([auth docs]) ([http docs]) ([websocket\_api docs][websocket_api docs]) (beta fix) * Pin crypto ([@balloob] - [#15978]) (beta fix) * Teak MQTT 错误 message for 0.76 发布 ([@awarecan] - [#15983]) ([MQTT docs]) (beta fix) * Fix 0.76 beta2 hassio token issue ([@awarecan] - [#15987]) ([hassio docs]) (beta fix) * Fix mysensors connection task blocking 设置 ([@MartinHjelmare] - [#15938]) ([mysensors docs]) (beta fix) * Fix Nest async from sync ([@balloob] - [#15997]) ([nest docs]) (beta fix) [#13742]: https://github.com/home-assistant/home-assistant/pull/13742 [#14028]: https://github.com/home-assistant/home-assistant/pull/14028 [#14749]: https://github.com/home-assistant/home-assistant/pull/14749 [#15081]: https://github.com/home-assistant/home-assistant/pull/15081 [#15083]: https://github.com/home-assistant/home-assistant/pull/15083 [#15093]: https://github.com/home-assistant/home-assistant/pull/15093 [#15096]: https://github.com/home-assistant/home-assistant/pull/15096 [#15228]: https://github.com/home-assistant/home-assistant/pull/15228 [#15273]: https://github.com/home-assistant/home-assistant/pull/15273 [#15439]: https://github.com/home-assistant/home-assistant/pull/15439 [#15511]: https://github.com/home-assistant/home-assistant/pull/15511 [#15573]: https://github.com/home-assistant/home-assistant/pull/15573 [#15621]: https://github.com/home-assistant/home-assistant/pull/15621 [#15660]: https://github.com/home-assistant/home-assistant/pull/15660 [#15661]: https://github.com/home-assistant/home-assistant/pull/15661 [#15678]: https://github.com/home-assistant/home-assistant/pull/15678 [#15715]: https://github.com/home-assistant/home-assistant/pull/15715 [#15716]: https://github.com/home-assistant/home-assistant/pull/15716 [#15740]: https://github.com/home-assistant/home-assistant/pull/15740 [#15751]: https://github.com/home-assistant/home-assistant/pull/15751 [#15752]: https://github.com/home-assistant/home-assistant/pull/15752 [#15754]: https://github.com/home-assistant/home-assistant/pull/15754 [#15757]: https://github.com/home-assistant/home-assistant/pull/15757 [#15758]: https://github.com/home-assistant/home-assistant/pull/15758 [#15759]: https://github.com/home-assistant/home-assistant/pull/15759 [#15763]: https://github.com/home-assistant/home-assistant/pull/15763 [#15766]: https://github.com/home-assistant/home-assistant/pull/15766 [#15767]: https://github.com/home-assistant/home-assistant/pull/15767 [#15768]: https://github.com/home-assistant/home-assistant/pull/15768 [#15769]: https://github.com/home-assistant/home-assistant/pull/15769 [#15770]: https://github.com/home-assistant/home-assistant/pull/15770 [#15780]: https://github.com/home-assistant/home-assistant/pull/15780 [#15783]: https://github.com/home-assistant/home-assistant/pull/15783 [#15786]: https://github.com/home-assistant/home-assistant/pull/15786 [#15789]: https://github.com/home-assistant/home-assistant/pull/15789 [#15800]: https://github.com/home-assistant/home-assistant/pull/15800 [#15803]: https://github.com/home-assistant/home-assistant/pull/15803 [#15804]: https://github.com/home-assistant/home-assistant/pull/15804 [#15809]: https://github.com/home-assistant/home-assistant/pull/15809 [#15811]: https://github.com/home-assistant/home-assistant/pull/15811 [#15814]: https://github.com/home-assistant/home-assistant/pull/15814 [#15824]: https://github.com/home-assistant/home-assistant/pull/15824 [#15831]: https://github.com/home-assistant/home-assistant/pull/15831 [#15833]: https://github.com/home-assistant/home-assistant/pull/15833 [#15837]: https://github.com/home-assistant/home-assistant/pull/15837 [#15838]: https://github.com/home-assistant/home-assistant/pull/15838 [#15839]: https://github.com/home-assistant/home-assistant/pull/15839 [#15842]: https://github.com/home-assistant/home-assistant/pull/15842 [#15854]: https://github.com/home-assistant/home-assistant/pull/15854 [#15858]: https://github.com/home-assistant/home-assistant/pull/15858 [#15859]: https://github.com/home-assistant/home-assistant/pull/15859 [#15860]: https://github.com/home-assistant/home-assistant/pull/15860 [#15867]: https://github.com/home-assistant/home-assistant/pull/15867 [#15868]: https://github.com/home-assistant/home-assistant/pull/15868 [#15869]: https://github.com/home-assistant/home-assistant/pull/15869 [#15872]: https://github.com/home-assistant/home-assistant/pull/15872 [#15876]: https://github.com/home-assistant/home-assistant/pull/15876 [#15877]: https://github.com/home-assistant/home-assistant/pull/15877 [#15883]: https://github.com/home-assistant/home-assistant/pull/15883 [#15885]: https://github.com/home-assistant/home-assistant/pull/15885 [#15886]: https://github.com/home-assistant/home-assistant/pull/15886 [#15887]: https://github.com/home-assistant/home-assistant/pull/15887 [#15896]: https://github.com/home-assistant/home-assistant/pull/15896 [#15899]: https://github.com/home-assistant/home-assistant/pull/15899 [#15902]: https://github.com/home-assistant/home-assistant/pull/15902 [#15907]: https://github.com/home-assistant/home-assistant/pull/15907 [#15910]: https://github.com/home-assistant/home-assistant/pull/15910 [#15911]: https://github.com/home-assistant/home-assistant/pull/15911 [#15914]: https://github.com/home-assistant/home-assistant/pull/15914 [#15916]: https://github.com/home-assistant/home-assistant/pull/15916 [#15922]: https://github.com/home-assistant/home-assistant/pull/15922 [#15923]: https://github.com/home-assistant/home-assistant/pull/15923 [#15929]: https://github.com/home-assistant/home-assistant/pull/15929 [#15930]: https://github.com/home-assistant/home-assistant/pull/15930 [#15936]: https://github.com/home-assistant/home-assistant/pull/15936 [#15938]: https://github.com/home-assistant/home-assistant/pull/15938 [#15942]: https://github.com/home-assistant/home-assistant/pull/15942 [#15951]: https://github.com/home-assistant/home-assistant/pull/15951 [#15955]: https://github.com/home-assistant/home-assistant/pull/15955 [#15957]: https://github.com/home-assistant/home-assistant/pull/15957 [#15972]: https://github.com/home-assistant/home-assistant/pull/15972 [#15978]: https://github.com/home-assistant/home-assistant/pull/15978 [#15983]: https://github.com/home-assistant/home-assistant/pull/15983 [#15987]: https://github.com/home-assistant/home-assistant/pull/15987 [#15997]: https://github.com/home-assistant/home-assistant/pull/15997 [@DubhAd]: https://github.com/DubhAd [@GotoCode]: https://github.com/GotoCode [@Kane610]: https://github.com/Kane610 [@MartinHjelmare]: https://github.com/MartinHjelmare [@MatMaul]: https://github.com/MatMaul [@PrimusNZ]: https://github.com/PrimusNZ [@StevenLooman]: https://github.com/StevenLooman [@ahobsonsayers]: https://github.com/ahobsonsayers [@andrey-git]: https://github.com/andrey-git [@armills]: https://github.com/armills [@awarecan]: https://github.com/awarecan [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@benoitlouy]: https://github.com/benoitlouy [@cdce8p]: https://github.com/cdce8p [@cgtobi]: https://github.com/cgtobi [@cnrd]: https://github.com/cnrd [@craftyguy]: https://github.com/craftyguy [@depl0y]: https://github.com/depl0y [@dgomes]: https://github.com/dgomes [@fabaff]: https://github.com/fabaff [@foxel]: https://github.com/foxel [@frenck]: https://github.com/frenck [@fucm]: https://github.com/fucm [@ioangogo]: https://github.com/ioangogo [@jesserizzo]: https://github.com/jesserizzo [@kbickar]: https://github.com/kbickar [@mattwing]: https://github.com/mattwing [@mountainsandcode]: https://github.com/mountainsandcode [@mxworm]: https://github.com/mxworm [@niklaswa]: https://github.com/niklaswa [@priiduonu]: https://github.com/priiduonu [@psike]: https://github.com/psike [@rafale77]: https://github.com/rafale77 [@robmarkcole]: https://github.com/robmarkcole [@rytilahti]: https://github.com/rytilahti [@salbertson]: https://github.com/salbertson [@scop]: https://github.com/scop [@snjoetw]: https://github.com/snjoetw [@soraxas]: https://github.com/soraxas [@thomasdelaet]: https://github.com/thomasdelaet [@turbokongen]: https://github.com/turbokongen [@vrih]: https://github.com/vrih [august docs]: /integrations/august/ [auth docs]: /integrations/auth/ [binary_sensor.bayesian docs]: /integrations/bayesian [binary_sensor.homematicip_cloud docs]: /integrations/homematicip_cloud/ [binary_sensor.openuv docs]: /integrations/openuv [binary_sensor.threshold docs]: /integrations/threshold [binary_sensor.velbus docs]: /integrations/velbus [binary_sensor.workday docs]: /integrations/workday [日历.todoist docs]: /integrations/todoist [摄像头.yi docs]: /integrations/yi [温控.generic_thermostat docs]: /integrations/generic_thermostat [温控.radiotherm docs]: /integrations/radiotherm [config docs]: /integrations/config/ [遮盖.tahoma docs]: /integrations/tahoma [deconz docs]: /integrations/deconz/ [device_tracker docs]: /integrations/device_tracker/ [风扇.dyson docs]: /integrations/dyson#风扇 [风扇.velbus docs]: /integrations/风扇.velbus/ [hassio docs]: /integrations/hassio/ [http docs]: /integrations/http/ [image_processing.facebox docs]: /integrations/facebox [灯光.deconz docs]: /integrations/deconz#灯光 [灯光.group docs]: /integrations/灯光.group/ [灯光.velbus docs]: /integrations/velbus/ [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.dlna_dmr docs]: /integrations/dlna_dmr [媒体播放器.kodi docs]: /integrations/kodi [媒体播放器.mediaroom docs]: /integrations/mediaroom [媒体播放器.pjlink docs]: /integrations/pjlink [MQTT docs]: /integrations/MQTT/ [mysensors docs]: /integrations/mysensors/ [nest docs]: /integrations/nest/ [通知 docs]: /integrations/通知/ [onboarding docs]: /integrations/onboarding/ [openuv docs]: /integrations/openuv/ [persistent_notification docs]: /integrations/persistent_notification/ [传感器.alpha_vantage docs]: /integrations/alpha_vantage [传感器.enphase_envoy docs]: /integrations/enphase_envoy [传感器.irish_rail_transport docs]: /integrations/irish_rail_transport [传感器.lastfm docs]: /integrations/lastfm [传感器.min_max docs]: /integrations/min_max [传感器.opensky docs]: /integrations/opensky [传感器.openuv docs]: /integrations/openuv [传感器.rmvtransport docs]: /integrations/rmvtransport [传感器.sense docs]: /integrations/sense [传感器.shodan docs]: /integrations/shodan [传感器.snmp docs]: /integrations/snmp#传感器 [传感器.sonarr docs]: /integrations/sonarr [传感器.statistics docs]: /integrations/statistics [传感器.waze_travel_time docs]: /integrations/waze_travel_time [传感器.worxlandroid docs]: /integrations/worxlandroid [开关.amcrest docs]: /integrations/amcrest [开关.deconz docs]: /integrations/deconz#开关 [开关.snmp docs]: /integrations/snmp#开关 [开关.velbus docs]: /integrations/velbus [tahoma docs]: /integrations/tahoma/ [吸尘器 docs]: /integrations/吸尘器/ [吸尘器.demo docs]: /integrations/吸尘器.demo/ [吸尘器.xiaomi_miio docs]: /integrations/吸尘器.xiaomi_miio/ [velbus docs]: /integrations/velbus/ [天气.openweathermap docs]: /integrations/openweathermap#天气 [websocket_api docs]: /integrations/websocket_api/ [zwave docs]: /integrations/zwave/ --- url: /home-assistant/blog/2018-08-29-release-77.md --- # 0.77: 认证 system 👮‍♂️ + Hangouts bot 🤖
It's time for a great new 发布 and it includes a big change: the new [authentication system](/home-assistant/docs/authentication/index.md) has been activated! We've worked very hard on this for the last couple of months to make the transition as smooth as possible. Updating to this 发布 is a non-breaking change (unless you had no API 密码 configured). As can be seen in the video above, when you start Home Assistant after the 更新, you will be presented with our new onboarding flow. This will ask you to create a new account after which you will be able to 日志 in to Home Assistant. Once logged in, you will have access to the following new features: * Change your 密码 * 配置 multifactor 认证 (TOTP) * Manage other 用户 (limited to account 创建 during onboarding) Although it's possible to 配置 认证, we strongly recommend to stick with the default 认证 配置. If you had auth providers configured in a previous Home Assistant 发布, we recommend to remove the 配置 and start using the default. It will take some time before all of the Home Assistant ecosystem has been migrated over to the new auth system. Home Assistant will print a 警告 whenever an application connects to Home Assistant with the legacy 认证. This will help 用户 通知 the application 开发者 to transition to use the new [OAuth2](https://开发者.home-assistant.io/docs/en/auth_api.html) 认证. For non-interactive 脚本 or other applications that are unable to 更新, we are planning to introduce a migration path for components to adopt url specific auth tokens and also introduce long lived access tokens to replace API passwords. A list of impacted components can be found [here](https://github.com/home-assistant/home-assistant/issues/15376#issuecomment-415890552). Our [iOS app](/home-assistant/ios) will soon be updated to work with the new auth. It's already in testing. The old app will continue to work with the legacy API 密码 support. It will however require a second login when using the webview. If you are using a proxy server (NGINX etc) in front of Home Assistant to provide 认证, check [this blogpost](https://博客.ceard.tech/2018/08/turbulence-ahead-fasten-your-seatbelt.html) by [@DubhAd] how to make it work. I want to say a biiiig thank you to all the people that have been involved in the development and testing of the new 认证 system. It's been a big project and it's been great to see how we, as a community, have rallied together to tackle it. Especially a big shout out to [@awarecan] who has done an amazing job on this. #### Hangouts And that's not it ! [@hobbypunk90] has contributed a new 集成 for [Google Hangouts][hangouts docs]. You can send messages but can also 配置 intents to handle incoming messages from specific people. Very cool! #### Lovelace You didn't think we would forget about Lovelace, did you? This 发布 include a new 通知 drawer thanks to [@jeradM]. It will collect all persistent 通知 and configurator 实体 and shows it in a new 侧边栏 toggleable from the toolbar. ## New Platforms * Netatmo public ([@colinfrei] - [#15684]) ([传感器.netatmo\_public docs][传感器.netatmo_public docs]) (new-platform) * Add ecovacs component ([@OverloadUT] - [#15520]) ([ecovacs docs]) ([吸尘器.ecovacs docs]) (new-platform) * Add support for NOAA tide information (new PR) ([@jcconnell] - [#15947]) ([传感器.noaa\_tides docs][传感器.noaa_tides docs]) (new-platform) * Hangouts ([@hobbypunk90] - [#16049]) ([hangouts docs]) ([通知 docs]) (new-platform) ## 发布 0.77.1 - August 29 * Fix trusted networks login 错误 ([@awarecan]) * Fix data\_key override by parent class ([@syssi] - [#16278]) ([binary\_sensor.xiaomi\_aqara docs][binary_sensor.xiaomi_aqara docs]) * Fix 错误 when 吸尘器 is idling ([@cnrd] - [#16282]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) [#16278]: https://github.com/home-assistant/home-assistant/pull/16278 [#16282]: https://github.com/home-assistant/home-assistant/pull/16282 [@cnrd]: https://github.com/cnrd [@syssi]: https://github.com/syssi [binary_sensor.xiaomi_aqara docs]: /integrations/binary_sensor.xiaomi_aqara/ [吸尘器.xiaomi_miio docs]: /integrations/吸尘器.xiaomi_miio/ ## 发布 0.77.2 - August 31 * Correct wemo static 设备 discovery issue. ([@lamiskin] - [#16292]) ([wemo docs]) * Fix LIFX effects ([@amelchio] - [#16309]) ([灯光.lifx docs]) * avoid 错误 in 调试 日志 mode and rss entry without title ([@exxamalte] - [#16316]) ([feedreader docs]) * Fix charts for 温控 设备 ([@jeradM]) * Fix header in Lovelace Glance 卡片 ([@balloob]) * Fix Profile page on Safari ([@balloob]) * Fix redirect to login page on offline server ([@balloob]) [#16292]: https://github.com/home-assistant/home-assistant/pull/16292 [#16309]: https://github.com/home-assistant/home-assistant/pull/16309 [#16316]: https://github.com/home-assistant/home-assistant/pull/16316 [@amelchio]: https://github.com/amelchio [@exxamalte]: https://github.com/exxamalte [@lamiskin]: https://github.com/lamiskin [feedreader docs]: /integrations/feedreader/ [灯光.lifx docs]: /integrations/lifx [wemo docs]: /integrations/wemo/ ## 发布 0.77.3 - September 3 前端 changes only: * Ask "save login" after hass connected [PR](https://github.com/home-assistant/home-assistant-polymer/pull/1631) [@awarecan] * Show an 错误 when invalid client id or redirect uri [PR](https://github.com/home-assistant/home-assistant-polymer/pull/1620) [@balloob] * Disable autocapitalization of username field [PR](https://github.com/home-assistant/home-assistant-polymer/pull/1627) [@timmo001] * 升级 MDI icons [PR](https://github.com/home-assistant/home-assistant-polymer/pull/1630) [@balloob] * 更新 translations [@timmo001]: https://github.com/timmo001 ## If you need help... ...don't hesitate to use our very active [forums](https://community.home-assistant.io/) or join us for a little [chat](https://discord.gg/c5DvZ4e). The 发布 notes have comments enabled but it's preferred if you use the former communication channels. Thanks. ## Reporting Issues Experiencing issues introduced by this 发布? Please report them in our [issue tracker](https://github.com/home-assistant/home-assistant/issues). Make sure to fill in all fields of the issue 模板. ## Backward-incompatible changes * Enable auth by default 🙈. It is no longer possible to access Home Assistant without 认证 ([@balloob] - [#16107]) (breaking change) * It's no longer possible to use a trusted network to connect to the websocket API. You need to get a token and use that to connect. ([@awarecan] - [#15812]) ([auth docs]) ([http docs]) ([websocket\_api docs][websocket_api docs]) (breaking change) * 脚本 Syntax: The wait 模板 will now continue to run the remainder of the 脚本 on timeout, the original functionality can be gained by setting `continue_on_timeout: false`. Allow wait 模板 to run the remainder of the 脚本 ([@lhovo] - [#15836]) (breaking change) * 更新 Xiaomi 吸尘器 to new StateVacuumDevice changed some 服务: `turn_on` -> `start`, `turn_off` -> `return_to_dock`, `toggle` has been removed. 状态 'on' and 'off' will also no longer be used. ([@cnrd] - [#15643]) (breaking change) * 更新 neato to support new StateVacuumDevice changed some 服务: `turn_on` -> `start`, `turn_off` -> `return_to_dock`, `toggle` has been removed. 状态 'on' and 'off' will also no longer be used. ([@dshokouhi] - [#16035]) ([吸尘器.neato docs]) (breaking change) * The previously deprecated package `homeassistant.remote` has been removed. ([@balloob] - [#16099]) ([api docs]) ([http docs]) ([mqtt\_eventstream docs][mqtt_eventstream docs]) ([mqtt\_statestream docs][mqtt_statestream docs]) ([通知 docs]) ([splunk docs]) ([websocket\_api docs][websocket_api docs]) (breaking change) * Merge `insteon_plm` and `insteon_local` components to insteon component ([@teharris1] - [#16102]) (breaking change) * Remove unit\_of\_measurement from 温控 实体 ([@jeradM] - [#16012]) ([温控 docs]) ([温控.generic\_thermostat docs][温控.generic_thermostat docs]) ([温控.knx docs]) ([温控.maxcube docs]) ([温控.sensibo docs]) (breaking change) * Upnp component no longer enables port mapping by default ([@dgomes] - [#16108]) ([upnp docs]) (breaking change) * The 实体 registry yaml file has been removed. It is now stored inside `.storage` and should only be managed via the UI ([@balloob] - [#16018]) ## Beta Fixes * deCONZ - Support 设备 registry ([@Kane610] - [#16115]) ([deconz docs]) ([binary\_sensor.deconz docs][binary_sensor.deconz docs]) ([灯光.deconz docs]) ([传感器.deconz docs]) ([开关.deconz docs]) (beta fix) * Add multi-factor auth module 设置 flow ([@awarecan] - [#16141]) ([auth docs]) (beta fix) * Decouple Konnected 实体 设置 from discovery ([@heythisisnate] - [#16146]) ([konnected docs]) ([开关.konnected docs]) (beta fix) * 设备 registry store config entry ([@Kane610] - [#16152]) (beta fix) * fix 错误 message for cv.matches\_regex ([@heythisisnate] - [#16175]) (beta fix) * Fix hangouts ([@balloob] - [#16180]) ([hangouts docs]) (beta fix) * Tweak 日志 level for bearer token 警告 ([@awarecan] - [#16182]) ([http docs]) (beta fix) * Default load trusted\_network auth provider if configured trusted networks ([@awarecan] - [#16184]) (beta fix) * Replace pbkdf2 with bcrypt ([@Eriner] - [#16071]) (beta fix) * Add Time-based Onetime 密码 Multi-factor 认证 Module ([@awarecan] - [#16129]) (beta fix) * Handle exception from pillow ([@PhracturedBlue] - [#16190]) ([摄像头.proxy docs]) (beta fix) * remove hangouts.用户 状态, simplifies hangouts.conversations ([@hobbypunk90] - [#16191]) ([hangouts docs]) (beta fix) * 更新 aiohttp to 版本 3.4.0. ([@Swamp-Ig] - [#16198]) (beta fix) * Revert changes to platforms using self.设备 ([@Kane610] - [#16209]) (beta fix) * homematic: Make 设备 available again when UNREACH becomes False ([@klada] - [#16202]) ([homematic docs]) (beta fix) * Change auth 警告 ([@balloob] - [#16216]) ([http docs]) (beta fix) * rewrite hangouts to use intents instead of commands ([@hobbypunk90] - [#16220]) ([conversation docs]) ([hangouts docs]) (beta fix) * Fix 设备 telldus ([@balloob] - [#16224]) ([tellduslive docs]) (beta fix) * 更新 trusted networks flow ([@balloob] - [#16227]) (beta fix) * Fix hangouts ([@balloob] - [#16232]) ([hangouts docs]) (beta fix) * 警告 missed a space ([@balloob] - [#16233]) ([http docs]) (beta fix) * Package loadable: compare case insensitive ([@balloob] - [#16234]) (beta fix) * Avoid insecure pycryptodome ([@balloob] - [#16238]) (beta fix) * Change 日志 level to 错误 when auth provider failed loading ([@awarecan] - [#16235]) (beta fix) * Blow up startup if init auth providers or modules failed ([@awarecan] - [#16240]) (beta fix) * Tweak MFA login flow ([@awarecan] - [#16254]) (beta fix) * def 设备 should not call it self but self.\_device ([@Kane610] - [#16255]) ([媒体播放器.plex docs]) (beta fix) ## All changes * Eph ember support operation modes ([@ttroy50] - [#15820]) ([温控.ephember docs]) * Fixed race 条件 in Generic Thermostat ([@aronsky] - [#15784]) ([温控.generic\_thermostat docs][温控.generic_thermostat docs]) * Fix magic cube support of the Aqara LAN Protocol V2 ([@syssi] - [#15940]) ([binary\_sensor.xiaomi\_aqara docs][binary_sensor.xiaomi_aqara docs]) * 升级 beautifulsoup4 to 4.6.3 ([@fabaff] - [#15946]) ([device\_tracker docs][device_tracker docs]) ([传感器.geizhals docs]) ([传感器.scrape docs]) * Allow wait 模板 to run the remainder of the 脚本 ([@lhovo] - [#15836]) (breaking change) * Add trusted networks auth provider ([@awarecan] - [#15812]) ([auth docs]) ([http docs]) ([websocket\_api docs][websocket_api docs]) (breaking change) * Add monitored 条件 for Unifi device\_tracker ([@cgarwood] - [#15888]) ([device\_tracker docs][device_tracker docs]) * Netatmo public ([@colinfrei] - [#15684]) ([传感器.netatmo\_public docs][传感器.netatmo_public docs]) (new-platform) * 更新 Xiaomi 吸尘器 to new StateVacuumDevice ([@cnrd] - [#15643]) (breaking change) * HomeMatic: Enable 实体 registry ([@danielperna84] - [#15950]) ([homematic docs]) * Fix google 日历 文档 link. ([@cgtobi] - [#15968]) ([日历.google docs]) * Remove unnecessary 日志 ([@colinfrei] - [#15966]) ([传感器.netatmo\_public docs][传感器.netatmo_public docs]) * Make 设置 fail if location is not available ([@fabaff] - [#15967]) ([传感器.worldtidesinfo docs]) * Remove 警告 ([@balloob] - [#15969]) * 更新 waterfurnace library to 0.7, add reconnect logic ([@sdague] - [#15657]) ([waterfurnace docs]) * adds support for momentary and beep/blink 开关 ([@heythisisnate] - [#15973]) ([konnected docs]) ([开关.konnected docs]) * Add -j$(nproc) make option to speed up build time ([@vrih] - [#15928]) * 更新 Glances 传感器 ([@fabaff] - [#15981]) ([传感器.glances docs]) * 升级 psutil to 5.4.7 ([@fabaff] - [#15982]) ([传感器.systemmonitor docs]) * 升级 aladdin\_connect to 0.3 and provide Unique ID ([@shoejosh] - [#15986]) ([遮盖.aladdin\_connect docs][遮盖.aladdin_connect docs]) * 实体 服务 ([@balloob] - [#15991]) * More 实体 服务 ([@balloob] - [#15998]) ([摄像头 docs]) ([温控 docs]) * Wemo custom ports and network 错误 handling ([@mcspr] - [#14516]) ([wemo docs]) ([binary\_sensor.wemo docs][binary_sensor.wemo docs]) ([灯光.wemo docs]) ([开关.wemo docs]) * Clean up input-datetime ([@balloob] - [#16000]) ([input\_datetime docs][input_datetime docs]) * BMW Connected drive: option to disable the 服务 ([@Alexxander0] - [#15993]) ([bmw\_connected\_drive docs][bmw_connected_drive docs]) ([门锁.bmw\_connected\_drive docs][门锁.bmw_connected_drive docs]) * Add type hints to homeassistant.auth ([@scop] - [#15853]) * Fix check config packages key 错误 ([@MartinHjelmare] - [#15840]) * 更新 SoCo to 0.16 ([@amelchio] - [#16007]) ([sonos docs]) ([媒体播放器.sonos docs]) * 升级 sendgrid to 5.5.0 ([@fabaff] - [#16021]) ([通知 docs]) * Split out storage delay save ([@balloob] - [#16017]) ([hassio docs]) * Disable assuming Optional type for values with None default ([@scop] - [#16029]) * 更新 RitAssist to support maximum speed and current address ([@depl0y] - [#16037]) ([device\_tracker docs][device_tracker docs]) * Handle missing mpd capabilities ([@logic] - [#15945]) ([媒体播放器.mpd docs]) * Storage 实体 registry ([@balloob] - [#16018]) * Attempt to fix flaky TTS test ([@balloob] - [#16025]) * 更新 neato to support new StateVacuumDevice ([@dshokouhi] - [#16035]) ([吸尘器.neato docs]) (breaking change) * 吸尘器/xiaomi\_miio: Expose "sensor\_dirty\_left" 属性 ([@klada] - [#16003]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) * Grammar and spelling fixes ([@scop] - [#16065]) * Use aiohttp web.AppRunner ([@balloob] - [#16020]) ([http docs]) * 更新 pushsafer.py ([@appzer] - [#16060]) ([通知 docs]) * Alexa: context + 日志 events ([@balloob] - [#16023]) ([alexa docs]) * openuv: Add Current UV Level to list of 条件 ([@leppa] - [#16042]) ([openuv docs]) ([传感器.openuv docs]) * TpLink 设备 Tracker 错误 ([@TimBailey-pnk] - [#15918]) ([device\_tracker docs][device_tracker docs]) * Deprecated stuff ([@balloob] - [#16019]) ([device\_tracker docs][device_tracker docs]) ([websocket\_api docs][websocket_api docs]) ([摄像头.push docs]) * Add recent context ([@balloob] - [#15989]) * Add ecovacs component ([@OverloadUT] - [#15520]) ([ecovacs docs]) ([吸尘器.ecovacs docs]) (new-platform) * Bumped NDMS2 client library to 0.0.4 to get compatible with python 3.5 ([@foxel] - [#16077]) ([device\_tracker docs][device_tracker docs]) * fritzdect change to current\_power\_w ([@Danielhiversen] - [#16079]) * 更新 pyhomematic to 0.1.47 ([@danielperna84] - [#16083]) ([homematic docs]) * Get 用户 after login flow finished ([@awarecan] - [#16047]) ([auth docs]) * 升级 pytest to 3.7.2 ([@scop] - [#16091]) * Add verify ssl to generic 摄像头 ([@fliphess] - [#15949]) ([摄像头.generic docs]) * 升级 afsapi to 0.0.4, prevents aiohttp session close message, Fixes #13099 ([@zhelev] - [#16098]) ([媒体播放器.frontier\_silicon docs][媒体播放器.frontier_silicon docs]) * Remove homeassistant.遥控器 ([@balloob] - [#16099]) ([api docs]) ([http docs]) ([mqtt\_eventstream docs][mqtt_eventstream docs]) ([mqtt\_statestream docs][mqtt_statestream docs]) ([通知 docs]) ([splunk docs]) ([websocket\_api docs][websocket_api docs]) (breaking change) * Use new session when fetching 遥控器 urls ([@balloob] - [#16093]) ([auth docs]) * Allow finish\_flow callback to change data entry result type ([@awarecan] - [#16100]) * Add support for revoking refresh tokens ([@balloob] - [#16095]) ([auth docs]) * Refactoring login flow ([@awarecan] - [#16104]) * Minor updates ([@fabaff] - [#16106]) * Bump python-miio 版本 ([@syssi] - [#16110]) ([device\_tracker docs][device_tracker docs]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) ([遥控器.xiaomi\_miio docs][遥控器.xiaomi_miio docs]) ([传感器.xiaomi\_miio docs][传感器.xiaomi_miio docs]) ([开关.xiaomi\_miio docs][开关.xiaomi_miio docs]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) * homematic: Add homematic.put\_paramset 服务 ([@klada] - [#16024]) ([homematic docs]) * 升级 shodan to 1.9.1 ([@fabaff] - [#16113]) ([传感器.shodan docs]) * 升级 sendgrid to 5.6.0 ([@fabaff] - [#16111]) ([通知 docs]) * Merge insteon\_plm and insteon\_local to insteon component ([@teharris1] - [#16102]) (breaking change) * Remove unit\_of\_measurement from 温控 实体 ([@jeradM] - [#16012]) ([温控 docs]) ([温控.generic\_thermostat docs][温控.generic_thermostat docs]) ([温控.knx docs]) ([温控.maxcube docs]) ([温控.sensibo docs]) (breaking change) * Add multi-factor 认证 modules ([@awarecan] - [#15489]) ([config docs]) * 设备 Registry ([@Kane610] - [#15980]) * Check correctly if package is loadable ([@balloob] - [#16121]) * 升级 numpy to 1.15.1 ([@fabaff] - [#16126]) ([binary\_sensor.trend docs][binary_sensor.trend docs]) ([image\_processing.opencv docs][image_processing.opencv docs]) * 升级 youtube\_dl to 2018.08.22 ([@fabaff] - [#16125]) ([media\_extractor docs][media_extractor docs]) * Fix the protocol v2 data\_key of several aqara 设备 ([@syssi] - [#16112]) ([binary\_sensor.xiaomi\_aqara docs][binary_sensor.xiaomi_aqara docs]) * 升级 brunt package ([@eavanvalkenburg] - [#16130]) ([遮盖.brunt docs]) * Add support for NOAA tide information (new PR) ([@jcconnell] - [#15947]) ([传感器.noaa\_tides docs][传感器.noaa_tides docs]) (new-platform) * Adds support for routers implementing IGDv2 ([@dgomes] - [#16108]) ([upnp docs]) (breaking change) * Add support for JS modules in custom 面板 ([@villanyibalint] - [#16096]) ([panel\_custom docs][panel_custom docs]) * Prevent legacy api 密码 with empty 密码 ([@balloob] - [#16127]) * Enable auth by default 🙈 ([@balloob] - [#16107]) (breaking change) * Remove commented out API 密码 from default config ([@balloob] - [#16147]) * Spelling fixes ([@scop] - [#16150]) ([insteon\_local docs][insteon_local docs]) ([insteon\_plm docs][insteon_plm docs]) * 更新 pydocstyle to 2.1.1 and flake8-docstrings to 1.3.0 ([@scop] - [#14557]) * Hangouts ([@hobbypunk90] - [#16049]) ([hangouts docs]) ([通知 docs]) (new-platform) * Hangouts localization typo fix ([@armills] - [#16174]) ([hangouts docs]) * deCONZ - Allow sub second 灯光 transitions ([@Kane610] - [#16170]) ([灯光.deconz docs]) * add\_devices -> add\_entities ([@balloob] - [#16171]) * deCONZ - Support 设备 registry ([@Kane610] - [#16115]) ([deconz docs]) ([binary\_sensor.deconz docs][binary_sensor.deconz docs]) ([灯光.deconz docs]) ([传感器.deconz docs]) ([开关.deconz docs]) (beta fix) * Add multi-factor auth module 设置 flow ([@awarecan] - [#16141]) ([auth docs]) (beta fix) * Decouple Konnected 实体 设置 from discovery ([@heythisisnate] - [#16146]) ([konnected docs]) ([开关.konnected docs]) (beta fix) * 设备 registry store config entry ([@Kane610] - [#16152]) (beta fix) * fix 错误 message for cv.matches\_regex ([@heythisisnate] - [#16175]) (beta fix) * Fix hangouts ([@balloob] - [#16180]) ([hangouts docs]) (beta fix) * Tweak 日志 level for bearer token 警告 ([@awarecan] - [#16182]) ([http docs]) (beta fix) * Default load trusted\_network auth provider if configured trusted networks ([@awarecan] - [#16184]) (beta fix) * Replace pbkdf2 with bcrypt ([@Eriner] - [#16071]) (beta fix) * Add Time-based Onetime 密码 Multi-factor 认证 Module ([@awarecan] - [#16129]) (beta fix) * Handle exception from pillow ([@PhracturedBlue] - [#16190]) ([摄像头.proxy docs]) (beta fix) * remove hangouts.用户 状态, simplifies hangouts.conversations ([@hobbypunk90] - [#16191]) ([hangouts docs]) (beta fix) * 更新 aiohttp to 版本 3.4.0. ([@Swamp-Ig] - [#16198]) (beta fix) * Revert changes to platforms using self.设备 ([@Kane610] - [#16209]) (beta fix) * homematic: Make 设备 available again when UNREACH becomes False ([@klada] - [#16202]) ([homematic docs]) (beta fix) * Change auth 警告 ([@balloob] - [#16216]) ([http docs]) (beta fix) * rewrite hangouts to use intents instead of commands ([@hobbypunk90] - [#16220]) ([conversation docs]) ([hangouts docs]) (beta fix) * Fix 设备 telldus ([@balloob] - [#16224]) ([tellduslive docs]) (beta fix) * 更新 trusted networks flow ([@balloob] - [#16227]) (beta fix) * Fix hangouts ([@balloob] - [#16232]) ([hangouts docs]) (beta fix) * 警告 missed a space ([@balloob] - [#16233]) ([http docs]) (beta fix) * Package loadable: compare case insensitive ([@balloob] - [#16234]) (beta fix) * Avoid insecure pycryptodome ([@balloob] - [#16238]) (beta fix) * Change 日志 level to 错误 when auth provider failed loading ([@awarecan] - [#16235]) (beta fix) * Blow up startup if init auth providers or modules failed ([@awarecan] - [#16240]) (beta fix) * Tweak MFA login flow ([@awarecan] - [#16254]) (beta fix) * def 设备 should not call it self but self.\_device ([@Kane610] - [#16255]) ([媒体播放器.plex docs]) (beta fix) [#14516]: https://github.com/home-assistant/home-assistant/pull/14516 [#14557]: https://github.com/home-assistant/home-assistant/pull/14557 [#15489]: https://github.com/home-assistant/home-assistant/pull/15489 [#15520]: https://github.com/home-assistant/home-assistant/pull/15520 [#15643]: https://github.com/home-assistant/home-assistant/pull/15643 [#15657]: https://github.com/home-assistant/home-assistant/pull/15657 [#15684]: https://github.com/home-assistant/home-assistant/pull/15684 [#15784]: https://github.com/home-assistant/home-assistant/pull/15784 [#15812]: https://github.com/home-assistant/home-assistant/pull/15812 [#15820]: https://github.com/home-assistant/home-assistant/pull/15820 [#15836]: https://github.com/home-assistant/home-assistant/pull/15836 [#15840]: https://github.com/home-assistant/home-assistant/pull/15840 [#15853]: https://github.com/home-assistant/home-assistant/pull/15853 [#15888]: https://github.com/home-assistant/home-assistant/pull/15888 [#15918]: https://github.com/home-assistant/home-assistant/pull/15918 [#15928]: https://github.com/home-assistant/home-assistant/pull/15928 [#15940]: https://github.com/home-assistant/home-assistant/pull/15940 [#15945]: https://github.com/home-assistant/home-assistant/pull/15945 [#15946]: https://github.com/home-assistant/home-assistant/pull/15946 [#15947]: https://github.com/home-assistant/home-assistant/pull/15947 [#15949]: https://github.com/home-assistant/home-assistant/pull/15949 [#15950]: https://github.com/home-assistant/home-assistant/pull/15950 [#15966]: https://github.com/home-assistant/home-assistant/pull/15966 [#15967]: https://github.com/home-assistant/home-assistant/pull/15967 [#15968]: https://github.com/home-assistant/home-assistant/pull/15968 [#15969]: https://github.com/home-assistant/home-assistant/pull/15969 [#15973]: https://github.com/home-assistant/home-assistant/pull/15973 [#15980]: https://github.com/home-assistant/home-assistant/pull/15980 [#15981]: https://github.com/home-assistant/home-assistant/pull/15981 [#15982]: https://github.com/home-assistant/home-assistant/pull/15982 [#15986]: https://github.com/home-assistant/home-assistant/pull/15986 [#15989]: https://github.com/home-assistant/home-assistant/pull/15989 [#15991]: https://github.com/home-assistant/home-assistant/pull/15991 [#15993]: https://github.com/home-assistant/home-assistant/pull/15993 [#15998]: https://github.com/home-assistant/home-assistant/pull/15998 [#16000]: https://github.com/home-assistant/home-assistant/pull/16000 [#16003]: https://github.com/home-assistant/home-assistant/pull/16003 [#16007]: https://github.com/home-assistant/home-assistant/pull/16007 [#16012]: https://github.com/home-assistant/home-assistant/pull/16012 [#16017]: https://github.com/home-assistant/home-assistant/pull/16017 [#16018]: https://github.com/home-assistant/home-assistant/pull/16018 [#16019]: https://github.com/home-assistant/home-assistant/pull/16019 [#16020]: https://github.com/home-assistant/home-assistant/pull/16020 [#16021]: https://github.com/home-assistant/home-assistant/pull/16021 [#16023]: https://github.com/home-assistant/home-assistant/pull/16023 [#16024]: https://github.com/home-assistant/home-assistant/pull/16024 [#16025]: https://github.com/home-assistant/home-assistant/pull/16025 [#16029]: https://github.com/home-assistant/home-assistant/pull/16029 [#16035]: https://github.com/home-assistant/home-assistant/pull/16035 [#16037]: https://github.com/home-assistant/home-assistant/pull/16037 [#16042]: https://github.com/home-assistant/home-assistant/pull/16042 [#16047]: https://github.com/home-assistant/home-assistant/pull/16047 [#16049]: https://github.com/home-assistant/home-assistant/pull/16049 [#16060]: https://github.com/home-assistant/home-assistant/pull/16060 [#16065]: https://github.com/home-assistant/home-assistant/pull/16065 [#16071]: https://github.com/home-assistant/home-assistant/pull/16071 [#16077]: https://github.com/home-assistant/home-assistant/pull/16077 [#16079]: https://github.com/home-assistant/home-assistant/pull/16079 [#16083]: https://github.com/home-assistant/home-assistant/pull/16083 [#16091]: https://github.com/home-assistant/home-assistant/pull/16091 [#16093]: https://github.com/home-assistant/home-assistant/pull/16093 [#16095]: https://github.com/home-assistant/home-assistant/pull/16095 [#16096]: https://github.com/home-assistant/home-assistant/pull/16096 [#16098]: https://github.com/home-assistant/home-assistant/pull/16098 [#16099]: https://github.com/home-assistant/home-assistant/pull/16099 [#16100]: https://github.com/home-assistant/home-assistant/pull/16100 [#16102]: https://github.com/home-assistant/home-assistant/pull/16102 [#16104]: https://github.com/home-assistant/home-assistant/pull/16104 [#16106]: https://github.com/home-assistant/home-assistant/pull/16106 [#16107]: https://github.com/home-assistant/home-assistant/pull/16107 [#16108]: https://github.com/home-assistant/home-assistant/pull/16108 [#16110]: https://github.com/home-assistant/home-assistant/pull/16110 [#16111]: https://github.com/home-assistant/home-assistant/pull/16111 [#16112]: https://github.com/home-assistant/home-assistant/pull/16112 [#16113]: https://github.com/home-assistant/home-assistant/pull/16113 [#16115]: https://github.com/home-assistant/home-assistant/pull/16115 [#16121]: https://github.com/home-assistant/home-assistant/pull/16121 [#16125]: https://github.com/home-assistant/home-assistant/pull/16125 [#16126]: https://github.com/home-assistant/home-assistant/pull/16126 [#16127]: https://github.com/home-assistant/home-assistant/pull/16127 [#16129]: https://github.com/home-assistant/home-assistant/pull/16129 [#16130]: https://github.com/home-assistant/home-assistant/pull/16130 [#16141]: https://github.com/home-assistant/home-assistant/pull/16141 [#16146]: https://github.com/home-assistant/home-assistant/pull/16146 [#16147]: https://github.com/home-assistant/home-assistant/pull/16147 [#16150]: https://github.com/home-assistant/home-assistant/pull/16150 [#16152]: https://github.com/home-assistant/home-assistant/pull/16152 [#16170]: https://github.com/home-assistant/home-assistant/pull/16170 [#16171]: https://github.com/home-assistant/home-assistant/pull/16171 [#16174]: https://github.com/home-assistant/home-assistant/pull/16174 [#16175]: https://github.com/home-assistant/home-assistant/pull/16175 [#16180]: https://github.com/home-assistant/home-assistant/pull/16180 [#16182]: https://github.com/home-assistant/home-assistant/pull/16182 [#16184]: https://github.com/home-assistant/home-assistant/pull/16184 [#16190]: https://github.com/home-assistant/home-assistant/pull/16190 [#16191]: https://github.com/home-assistant/home-assistant/pull/16191 [#16198]: https://github.com/home-assistant/home-assistant/pull/16198 [#16202]: https://github.com/home-assistant/home-assistant/pull/16202 [#16209]: https://github.com/home-assistant/home-assistant/pull/16209 [#16216]: https://github.com/home-assistant/home-assistant/pull/16216 [#16220]: https://github.com/home-assistant/home-assistant/pull/16220 [#16224]: https://github.com/home-assistant/home-assistant/pull/16224 [#16227]: https://github.com/home-assistant/home-assistant/pull/16227 [#16232]: https://github.com/home-assistant/home-assistant/pull/16232 [#16233]: https://github.com/home-assistant/home-assistant/pull/16233 [#16234]: https://github.com/home-assistant/home-assistant/pull/16234 [#16235]: https://github.com/home-assistant/home-assistant/pull/16235 [#16238]: https://github.com/home-assistant/home-assistant/pull/16238 [#16240]: https://github.com/home-assistant/home-assistant/pull/16240 [#16254]: https://github.com/home-assistant/home-assistant/pull/16254 [#16255]: https://github.com/home-assistant/home-assistant/pull/16255 [@Alexxander0]: https://github.com/Alexxander0 [@DubhAd]: https://github.com/DubhAd [@Danielhiversen]: https://github.com/Danielhiversen [@Eriner]: https://github.com/Eriner [@Kane610]: https://github.com/Kane610 [@MartinHjelmare]: https://github.com/MartinHjelmare [@OverloadUT]: https://github.com/OverloadUT [@PhracturedBlue]: https://github.com/PhracturedBlue [@Swamp-Ig]: https://github.com/Swamp-Ig [@TimBailey-pnk]: https://github.com/TimBailey-pnk [@amelchio]: https://github.com/amelchio [@appzer]: https://github.com/appzer [@armills]: https://github.com/armills [@aronsky]: https://github.com/aronsky [@awarecan]: https://github.com/awarecan [@balloob]: https://github.com/balloob [@cgarwood]: https://github.com/cgarwood [@cgtobi]: https://github.com/cgtobi [@cnrd]: https://github.com/cnrd [@colinfrei]: https://github.com/colinfrei [@danielperna84]: https://github.com/danielperna84 [@depl0y]: https://github.com/depl0y [@dgomes]: https://github.com/dgomes [@dshokouhi]: https://github.com/dshokouhi [@eavanvalkenburg]: https://github.com/eavanvalkenburg [@fabaff]: https://github.com/fabaff [@fliphess]: https://github.com/fliphess [@foxel]: https://github.com/foxel [@heythisisnate]: https://github.com/heythisisnate [@hobbypunk90]: https://github.com/hobbypunk90 [@jcconnell]: https://github.com/jcconnell [@jeradM]: https://github.com/jeradM [@klada]: https://github.com/klada [@leppa]: https://github.com/leppa [@lhovo]: https://github.com/lhovo [@logic]: https://github.com/logic [@mcspr]: https://github.com/mcspr [@scop]: https://github.com/scop [@sdague]: https://github.com/sdague [@shoejosh]: https://github.com/shoejosh [@villanyibalint]: https://github.com/villanyibalint [@syssi]: https://github.com/syssi [@teharris1]: https://github.com/teharris1 [@ttroy50]: https://github.com/ttroy50 [@vrih]: https://github.com/vrih [@zhelev]: https://github.com/zhelev [alexa docs]: /integrations/alexa/ [api docs]: /integrations/api/ [auth docs]: /integrations/auth/ [binary_sensor.deconz docs]: /integrations/deconz#binary-传感器 [binary_sensor.trend docs]: /integrations/trend [binary_sensor.wemo docs]: /integrations/wemo [binary_sensor.xiaomi_aqara docs]: /integrations/binary_sensor.xiaomi_aqara/ [bmw_connected_drive docs]: /integrations/bmw_connected_drive/ [日历.google docs]: /integrations/日历.google/ [摄像头 docs]: /integrations/摄像头/ [摄像头.generic docs]: /integrations/generic_ip_camera [摄像头.proxy docs]: /integrations/proxy [摄像头.push docs]: /integrations/push [温控 docs]: /integrations/温控/ [温控.ephember docs]: /integrations/ephember [温控.generic_thermostat docs]: /integrations/generic_thermostat [温控.knx docs]: /integrations/温控.knx/ [温控.maxcube docs]: /integrations/maxcube [温控.sensibo docs]: /integrations/sensibo [config docs]: /integrations/config/ [conversation docs]: /integrations/conversation/ [遮盖.aladdin_connect docs]: /integrations/aladdin_connect [遮盖.brunt docs]: /integrations/brunt [deconz docs]: /integrations/deconz/ [device_tracker docs]: /integrations/device_tracker/ [ecovacs docs]: /integrations/ecovacs/ [风扇.xiaomi_miio docs]: /integrations/风扇.xiaomi_miio/ [hangouts docs]: /integrations/hangouts/ [hassio docs]: /integrations/hassio/ [homematic docs]: /integrations/homematic/ [http docs]: /integrations/http/ [image_processing.opencv docs]: /integrations/opencv [input_datetime docs]: /integrations/input_datetime/ [insteon_local docs]: /integrations/insteon/ [insteon_plm docs]: /integrations/insteon/ [konnected docs]: /integrations/konnected/ [灯光.deconz docs]: /integrations/deconz#灯光 [灯光.wemo docs]: /integrations/wemo [灯光.xiaomi_miio docs]: /integrations/灯光.xiaomi_miio/ [门锁.bmw_connected_drive docs]: /integrations/bmw_connected_drive [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.frontier_silicon docs]: /integrations/frontier_silicon [媒体播放器.mpd docs]: /integrations/mpd [媒体播放器.plex docs]: /integrations/plex#media-player [媒体播放器.sonos docs]: /integrations/sonos [mqtt_eventstream docs]: /integrations/mqtt_eventstream/ [mqtt_statestream docs]: /integrations/mqtt_statestream/ [通知 docs]: /integrations/通知/ [openuv docs]: /integrations/openuv/ [panel_custom docs]: /integrations/panel_custom/ [遥控器.xiaomi_miio docs]: /integrations/遥控器.xiaomi_miio/ [传感器.deconz docs]: /integrations/deconz#传感器 [传感器.geizhals docs]: /integrations/geizhals [传感器.glances docs]: /integrations/glances [传感器.netatmo_public docs]: /integrations/netatmo/#传感器 [传感器.noaa_tides docs]: /integrations/noaa_tides [传感器.openuv docs]: /integrations/openuv [传感器.scrape docs]: /integrations/scrape [传感器.shodan docs]: /integrations/shodan [传感器.systemmonitor docs]: /integrations/systemmonitor [传感器.worldtidesinfo docs]: /integrations/worldtidesinfo [传感器.xiaomi_miio docs]: /integrations/传感器.xiaomi_miio/ [sonos docs]: /integrations/sonos/ [splunk docs]: /integrations/splunk/ [开关.deconz docs]: /integrations/deconz#开关 [开关.konnected docs]: /integrations/konnected#开关 [开关.wemo docs]: /integrations/wemo [开关.xiaomi_miio docs]: /integrations/开关.xiaomi_miio/ [tellduslive docs]: /integrations/tellduslive/ [upnp docs]: /integrations/upnp/ [吸尘器.ecovacs docs]: /integrations/ecovacs#吸尘器 [吸尘器.neato docs]: /integrations/neato#吸尘器 [吸尘器.xiaomi_miio docs]: /integrations/吸尘器.xiaomi_miio/ [waterfurnace docs]: /integrations/waterfurnace/ [websocket_api docs]: /integrations/websocket_api/ [wemo docs]: /integrations/wemo/ --- url: /home-assistant/blog/2018-09-15-release-78.md --- # 0.78: More auth, Switchmate, Yale Smart Alarm, OpenTherm It's time for a new 发布 and oh boy, what a time to be alive! Today marks our 5th (!!!) anniversary. That's 5 years we've been bringing privacy focused and locally controlled home 自动化 to your home. Happy birthday to us. This 发布 includes two new features for the auth system. The first one is long-lived access tokens. These are tokens that don't expire and can be used in your 脚本 instead of API 密码. Instructions on how to create and use them can be found on your profile. Also on your profile page is a new list of existing refresh tokens. These are all the tokens that are currently active for your account. If you ran into issues that the remember login dialog didn't show, you might have a lot. Don't worry, you can delete them all. ## New Platforms * Add temperature 传感器 to the velbus component ([@Cereal2nd] - [#16203]) ([velbus docs]) ([传感器.velbus docs]) (new-platform) * Add Volkszaehler 传感器 ([@fabaff] - [#16188]) ([传感器.volkszaehler docs]) (new-platform) * Switchmate ([@Danielhiversen] - [#15535]) ([开关.switchmate docs]) (new-platform) * Add support for Habitica ([@ASMfreaK] - [#15744]) ([habitica docs]) ([传感器.habitica docs]) (new-platform) * Geo Location component ([@exxamalte] - [#15953]) ([feedreader docs]) ([geo\_location docs][geo_location docs]) (new-platform) * Add 遮盖 to the Insteon component ([@teharris1] - [#16215]) ([insteon docs]) ([遮盖.insteon docs]) (new-platform) * switchbot ([@Danielhiversen] - [#16396]) ([开关.switchbot docs]) (new-platform) * Add Yale Smart 报警 component ([@domwillcode] - [#16377]) ([alarm\_control\_panel.yale\_smart\_alarm docs][alarm_control_panel.yale_smart_alarm docs]) (new-platform) * Add OpenTherm Gateway 温控 platform ([@mvn23] - [#16299]) ([温控.opentherm\_gw docs][温控.opentherm_gw docs]) (new-platform) ## 发布 0.78.1 - September 20 * Updates 文档 repo URL in PR 模板 ([@frenck] - [#16537]) * SnmpSensor: Fix async\_update (#16679) ([@mtdcr] - [#16716]) ([传感器.snmp docs]) * Handle chromecast CONNECTION\_STATUS\_DISCONNECTED event ([@awarecan] - [#16732]) ([媒体播放器.cast docs]) * 升级 netdisco to 2.1.0 ([@awarecan] - [#16735]) [#16537]: https://github.com/home-assistant/home-assistant/pull/16537 [#16716]: https://github.com/home-assistant/home-assistant/pull/16716 [#16732]: https://github.com/home-assistant/home-assistant/pull/16732 [#16735]: https://github.com/home-assistant/home-assistant/pull/16735 [@awarecan]: https://github.com/awarecan [@frenck]: https://github.com/frenck [@mtdcr]: https://github.com/mtdcr [媒体播放器.cast docs]: /integrations/cast [传感器.snmp docs]: /integrations/snmp#传感器 ## 发布 0.78.2 - September 21 * Fix discovery ## 发布 0.78.3 - September 22 * Bump gtts-token to 1.1.2 ([@edif30] - [#16775]) ([tts docs]) [#16537]: https://github.com/home-assistant/home-assistant/pull/16537 [#16775]: https://github.com/home-assistant/home-assistant/pull/16775 [@edif30]: https://github.com/edif30 [@frenck]: https://github.com/frenck [tts docs]: /integrations/tts/ ## If you need help... ...don't hesitate to use our very active [forums](https://community.home-assistant.io/) or join us for a little [chat](https://discord.gg/c5DvZ4e). The 发布 notes have comments enabled but it's preferred if you use the former communication channels. Thanks. ## Reporting Issues Experiencing issues introduced by this 发布? Please report them in our [issue tracker](https://github.com/home-assistant/home-assistant/issues). Make sure to fill in all fields of the issue 模板. ## Backward-incompatible changes * Trafikverket 天气: Instead of having multiple 传感器 配置 per station, add only one 配置 per station and select the type of measurement data to subscribe to using monitored\_conditions. The 配置 value type should no longer be used. ([@endor-force] - [#15935]) ([传感器.trafikverket\_weatherstation docs][传感器.trafikverket_weatherstation docs]) (breaking change) * Geizhals: config has changed. Remove domain and regex, specify locale instead: `AT`, `EU`, `DE`, `UK` or `PL`. ([@JulianKahnert] - [#15990]) ([传感器.geizhals docs]) (breaking change) * 更新 to EnvoyReader 0.2, support for more hardware. Change keys in monitored\_conditions from `7_days_production` and `7_days_consumption` to `seven_days_production` and `seven_days_consumption` ([@jesserizzo] - [#16212]) ([传感器.enphase\_envoy docs][传感器.enphase_envoy docs]) (breaking change) * Fix Mi Flora median calculation. Removed `retries` and `timeout` config parameters, they were not used for several months. Replaced `cache_value` config with `scan_interval` to fix a bug in the PR. ([@PaulAnnekov] - [#16085]) ([传感器.miflora docs]) (breaking change) * Twitch now requires a `client_id` and so the platform got updated. ([@ioangogo] - [#16428]) ([传感器.twitch docs]) (breaking change) * The radiotherm `fan` and `mode` 状态 属性 were updated to reflect the real-time 风扇 and mode 状态 of the thermostat, rather than the overall selected 状态 (automatic, mostly). The mode 属性 still contain the selected modes (风扇 on/auto, heat/cool/auto). ([@cpw] - [#15031]) ([温控.radiotherm docs]) (breaking change) * The `dnsip` 传感器 now uses `myip` as default name. ([@grea09] - [#16205]) ([传感器.dnsip docs]) (breaking change) ## Beta Fixes * Replace api\_password in 摄像头.Push ([@dgomes] - [#16339]) ([摄像头.push docs]) (beta fix) * Fail fetch auth providers if onboarding required ([@balloob] - [#16454]) ([auth docs]) (beta fix) * Fix insteon Hub v1 support ([@teharris1] - [#16472]) ([insteon docs]) (beta fix) * bugfix - incorrect 摄像头 type and missing 传感器 when multiple netatmo 摄像头 ([@vikramgorla] - [#16490]) ([netatmo docs]) (beta fix) * Fix arlo intilization when no base station available ([@zellux] - [#16529]) ([arlo docs]) (beta fix) * Long-lived access token ([@awarecan] - [#16453]) ([auth docs]) (beta fix) * Fix typo ([@balloob] - [#16556]) (beta fix) * Fix invalid 状态 ([@balloob] - [#16558]) (beta fix) * Add websocket commands for refresh tokens ([@balloob] - [#16559]) ([auth docs]) (beta fix) * Return if refresh token is current used one in WS API ([@awarecan] - [#16575]) ([auth docs]) ([websocket\_api docs][websocket_api docs]) (beta fix) * Track refresh token last usage information ([@awarecan] - [#16408]) ([auth docs]) (beta fix) * Increasing python-websockets' 版本 number ([@zoe1337] - [#16578]) ([媒体播放器.webostv docs]) (beta fix) * Add retry limit for chromecast connection ([@awarecan] - [#16471]) ([媒体播放器.cast docs]) (beta fix) * Fix broken 蓝牙 tracker ([@awarecan] - [#16589]) ([device\_tracker docs][device_tracker docs]) (beta fix) * Rewrite 蓝牙 le ([@pvizeli] - [#16592]) ([device\_tracker docs][device_tracker docs]) (beta fix) ## All changes * Add 'moon\_phase' to Dark Sky 传感器 ([@fabaff] - [#16179]) ([传感器.darksky docs]) * Zoneminder SSL fix ([@djm300] - [#16157]) ([zoneminder docs]) * 更新 python-velbus library 版本 ([@thomasdelaet] - [#16194]) ([velbus docs]) * MQTT: 日志 transmitted as well as received messages ([@smurfix] - [#16195]) ([MQTT docs]) * 升级 sqlalchemy to 1.2.11 ([@fabaff] - [#16192]) ([传感器.sql docs]) * Add battery 警告, rssi level and check for availability ([@fucm] - [#16193]) ([传感器.tahoma docs]) * Inconsistent entity\_id when multiple 传感器 ([@grea09] - [#16205]) ([传感器.dnsip docs]) * Add temperature 传感器 to the velbus component ([@Cereal2nd] - [#16203]) ([velbus docs]) ([传感器.velbus docs]) (new-platform) * Rewrite of Trafikverket 天气 - Multiple 传感器 types supported ([@endor-force] - [#15935]) ([传感器.trafikverket\_weatherstation docs][传感器.trafikverket_weatherstation docs]) (breaking change) * Add device\_tracker.bluetooth\_update 服务 ([@kariudo] - [#15252]) ([device\_tracker docs][device_tracker docs]) * Fix geizhals price parsing ([@JulianKahnert] - [#15990]) ([传感器.geizhals docs]) (breaking change) * Add Volkszaehler 传感器 ([@fabaff] - [#16188]) ([传感器.volkszaehler docs]) (new-platform) * openalpr flag `WITH_TEST` should be `WITH_TESTS` ([@vrih] - [#16218]) * 升级 alpha\_vantage to 2.1.0 ([@fabaff] - [#16217]) ([传感器.alpha\_vantage docs][传感器.alpha_vantage docs]) * Store 设备 as dict instead of list ([@Kane610] - [#16229]) * Improve package loadable ([@balloob] - [#16237]) * Switchmate ([@Danielhiversen] - [#15535]) ([开关.switchmate docs]) (new-platform) * Add support for discrete 状态 to MyQ 遮盖 ([@schmittx] - [#16251]) ([遮盖.myq docs]) * bump 版本 ([@dgomes] - [#16262]) ([upnp docs]) * Replace Authorization by 认证 ([@cgtobi] - [#16259]) ([hangouts docs]) * Add 设备 info to Chromecast ([@balloob] - [#16261]) ([媒体播放器.cast docs]) * Add 设备 info for sonos ([@balloob] - [#16263]) ([媒体播放器.sonos docs]) * Add 设备 info Nest ([@balloob] - [#16265]) ([温控.nest docs]) * Add Hue 设备 info ([@balloob] - [#16267]) ([hue docs]) ([灯光.hue docs]) * Nest Thermostat has software 版本 ([@awarecan] - [#16275]) ([温控.nest docs]) * Add support for Habitica ([@ASMfreaK] - [#15744]) ([habitica docs]) ([传感器.habitica docs]) (new-platform) * Fix so that 实体 are properly unloaded with config entry ([@Kane610] - [#16281]) ([deconz docs]) ([binary\_sensor.deconz docs][binary_sensor.deconz docs]) ([灯光.deconz docs]) ([场景.deconz docs]) ([传感器.deconz docs]) ([开关.deconz docs]) * Geo Location component ([@exxamalte] - [#15953]) ([feedreader docs]) ([geo\_location docs][geo_location docs]) (new-platform) * Bump songpal dependency ([@rytilahti] - [#16297]) ([媒体播放器.songpal docs]) * Use asterisk\_mbox 0.5.0 client ([@PhracturedBlue] - [#16296]) ([asterisk\_mbox docs][asterisk_mbox docs]) * 升级 Adafruit-DHT to 1.3.4 ([@thomaslian] - [#16327]) ([传感器.dht docs]) * Add unique ID ([@schmittx] - [#16323]) ([遮盖.myq docs]) * Add 遮盖 to the Insteon component ([@teharris1] - [#16215]) ([insteon docs]) ([遮盖.insteon docs]) (new-platform) * Fix missing humidity 传感器 ([@danielperna84] - [#16337]) ([homematic docs]) * Support Sonos Beam HDMI input ([@phil65] - [#16340]) ([媒体播放器.sonos docs]) * Make last\_seen 属性 a timezone aware datetime in UTC ([@pnbruckner] - [#16348]) ([device\_tracker docs][device_tracker docs]) * Handle netatmo exception ([@Danielhiversen] - [#16344]) ([传感器.netatmo docs]) * Add support for sound\_mode for Yamaha rxv 媒体播放器 ([@Joshi425] - [#16352]) ([媒体播放器.yamaha docs]) * Add unique\_id to MQTT 灯光 ([@bieniu] - [#16303]) ([灯光.MQTT docs]) * 更新 to EnvoyReader 0.2, support for more hardware ([@jesserizzo] - [#16212]) ([传感器.enphase\_envoy docs][传感器.enphase_envoy docs]) (breaking change) * Snips: Added special slot values, session\_id and slotname\_raw ([@tschmidty69] - [#16185]) ([snips docs]) * 升级 hbmqtt to 0.9.4 ([@awarecan] - [#16356]) ([MQTT docs]) * 升级 Sphinx to 1.7.7 ([@fabaff] - [#16359]) * 升级 qnapstats to 0.2.7 ([@fabaff] - [#16360]) ([传感器.qnap docs]) * 升级 mutagen to 1.41.1 ([@fabaff] - [#16361]) ([tts docs]) * 升级 shodan to 1.10.0 ([@fabaff] - [#16363]) ([传感器.shodan docs]) * 升级 to youtube\_dl to 2018.09.01 ([@fabaff] - [#16365]) ([media\_extractor docs][media_extractor docs]) * Added 'nomapnt', 'outcurnt', 'loadapnt' fields ([@MarcSN311] - [#16176]) ([传感器.apcupsd docs]) * Generic Thermostat: add support for 温控.turn\_on/温控.turn\_off ([@aronsky] - [#16080]) ([温控.generic\_thermostat docs][温控.generic_thermostat docs]) * Add support for Tahoma Lighting Receiver on/off io ([@fucm] - [#15925]) ([tahoma docs]) ([开关.tahoma docs]) * 更新 discord.py ([@htotoo] - [#16248]) ([通知 docs]) * 升级 python-telegram-bot to 11.0.0 ([@fabaff] - [#16373]) ([telegram\_bot docs][telegram_bot docs]) * 升级 attrs to 18.2.0 ([@fabaff] - [#16372]) * 更新 server.py ([@awarecan] - [#16375]) ([MQTT docs]) * add\_entities for switchmate ([@Danielhiversen] - [#16368]) ([开关.switchmate docs]) * Support for playing radio preset by Onkyo 媒体播放器 ([@pszafer] - [#16258]) ([遮盖.MQTT docs]) ([媒体播放器.onkyo docs]) * Bug fix for Tibber ([@Danielhiversen] - [#16397]) ([传感器.tibber docs]) * zha: Bump to zigpy 0.2.0/bellows 0.7.0 ([@rcloran] - [#16404]) ([zha docs]) * Fix SystemMonitor IP address 传感器 ([@ReneNulschDE] - [#16394]) ([传感器.systemmonitor docs]) * add ExpressBus icon key to 传感器.mvg ([@9R] - [#16387]) ([传感器.mvglive docs]) * 设备 and 实体 registry remove config entry on unload ([@Kane610] - [#16247]) * Add config flow for OpenUV ([@bachya] - [#16159]) ([openuv docs]) ([binary\_sensor.openuv docs][binary_sensor.openuv docs]) ([传感器.openuv docs]) * 服务 to load new deCONZ 设备 without 重启 ([@Kane610] - [#16308]) ([deconz docs]) * Delegate MQTT topic match validation to the paho MQTT client ([@rohankapoorcom] - [#16403]) ([MQTT docs]) * Clean up dlink and some bug fix ([@Danielhiversen] - [#16346]) ([开关.dlink docs]) * Implement correct 状态 for RFlink 遮盖 ([@nudded] - [#16304]) ([遮盖.rflink docs]) * Fix Mi Flora median calculation ([@PaulAnnekov] - [#16085]) ([传感器.miflora docs]) (breaking change) * Add context to 脚本 and 自动化 ([@balloob] - [#16415]) ([自动化 docs]) ([脚本 docs]) ([自动化.event docs]) ([自动化.homeassistant docs]) ([自动化.numeric\_state docs][自动化.numeric_state docs]) ([自动化.状态 docs]) ([自动化.模板 docs]) ([自动化.区域 docs]) * Fix openuv.config\_flow unit test ([@awarecan] - [#16419]) * 升级 sense library to 0.4.2 ([@kbickar] - [#16429]) ([传感器.sense docs]) * switchbot ([@Danielhiversen] - [#16396]) ([开关.switchbot docs]) (new-platform) * Fix 摄像头 proxy to not require api\_password to function ([@PhracturedBlue] - [#16450]) ([摄像头 docs]) ([摄像头.proxy docs]) * 升级 shodan to 1.10.1 ([@fabaff] - [#16460]) ([传感器.shodan docs]) * 升级 Sphinx to 1.7.8 ([@fabaff] - [#16459]) * 更新 rfxtrx lib ([@Danielhiversen] - [#16463]) ([rfxtrx docs]) * Added Twitch v5 support to the twitch platform ([@ioangogo] - [#16428]) ([传感器.twitch docs]) (breaking change) * Fix waze\_travel\_time component startup ([@tsvi] - [#16465]) ([传感器.waze\_travel\_time docs][传感器.waze_travel_time docs]) * 更新 license to official GitHub 模板 ([@OverloadUT] - [#16470]) * Add Yale Smart 报警 component ([@domwillcode] - [#16377]) ([alarm\_control\_panel.yale\_smart\_alarm docs][alarm_control_panel.yale_smart_alarm docs]) (new-platform) * 更新 radiotherm ([@cpw] - [#15031]) ([温控.radiotherm docs]) (breaking change) * Support SNMPv3 and asyncio in snmp 开关 ([@mtdcr] - [#14754]) ([开关.snmp docs]) * Fix GitHub change to resolve conflicts ([@fabaff] - [#16477]) ([开关.snmp docs]) * Add OpenTherm Gateway 温控 platform ([@mvn23] - [#16299]) ([温控.opentherm\_gw docs][温控.opentherm_gw docs]) (new-platform) * Support SNMPv3 and asyncio in snmp 传感器 ([@mtdcr] - [#14753]) ([传感器.snmp docs]) * Add rate of change to statistics 传感器 ([@flo-wer] - [#15632]) ([传感器.statistics docs]) * 恢复 status 属性 for xiaomi\_vacuum ([@tamasv] - [#16366]) ([吸尘器 docs]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) * Check if API key is valid and 用户 available ([@fabaff] - [#16494]) ([传感器.lastfm docs]) * 更新 name legacy api 密码 ([@balloob] - [#16455]) * Fix Netgear LTESensor docstring ([@scop] - [#16501]) ([传感器.netgear\_lte docs][传感器.netgear_lte docs]) * 更新 pyHS100 to 0.3.3 ([@amelchio] - [#16502]) ([灯光.tplink docs]) ([开关.tplink docs]) * Move voluptuous-serialize to 核心 requirement ([@awarecan] - [#16507]) ([config docs]) * adds listener for OnAVStart and OnAVChange ([@tadly] - [#16495]) ([媒体播放器.kodi docs]) * Order imports ([@fabaff] - [#16515]) * 升级 aiohttp to 3.4.4 ([@awarecan] - [#16486]) * Add a base\_url 配置 setting to tts. ([@lddubeau] - [#16478]) ([tts docs]) * 升级 youtube\_dl to 2018.09.10 ([@fabaff] - [#16534]) ([media\_extractor docs][media_extractor docs]) * 升级 keyring to 15.0.0 ([@fabaff] - [#16536]) * Updates 文档 repo URL in PR 模板 ([@frenck] - [#16537]) * Replace api\_password in 摄像头.Push ([@dgomes] - [#16339]) ([摄像头.push docs]) (beta fix) * Fail fetch auth providers if onboarding required ([@balloob] - [#16454]) ([auth docs]) (beta fix) * Fix insteon Hub v1 support ([@teharris1] - [#16472]) ([insteon docs]) (beta fix) * bugfix - incorrect 摄像头 type and missing 传感器 when multiple netatmo 摄像头 ([@vikramgorla] - [#16490]) ([netatmo docs]) (beta fix) * Fix arlo intilization when no base station available ([@zellux] - [#16529]) ([arlo docs]) (beta fix) * Long-lived access token ([@awarecan] - [#16453]) ([auth docs]) (beta fix) * Fix typo ([@balloob] - [#16556]) (beta fix) * Fix invalid 状态 ([@balloob] - [#16558]) (beta fix) * Add websocket commands for refresh tokens ([@balloob] - [#16559]) ([auth docs]) (beta fix) * Return if refresh token is current used one in WS API ([@awarecan] - [#16575]) ([auth docs]) ([websocket\_api docs][websocket_api docs]) (beta fix) * Track refresh token last usage information ([@awarecan] - [#16408]) ([auth docs]) (beta fix) * Increasing python-websockets' 版本 number ([@zoe1337] - [#16578]) ([媒体播放器.webostv docs]) (beta fix) * Add retry limit for chromecast connection ([@awarecan] - [#16471]) ([媒体播放器.cast docs]) (beta fix) * Fix broken 蓝牙 tracker ([@awarecan] - [#16589]) ([device\_tracker docs][device_tracker docs]) (beta fix) * Rewrite 蓝牙 le ([@pvizeli] - [#16592]) ([device\_tracker docs][device_tracker docs]) (beta fix) [#14753]: https://github.com/home-assistant/home-assistant/pull/14753 [#14754]: https://github.com/home-assistant/home-assistant/pull/14754 [#15031]: https://github.com/home-assistant/home-assistant/pull/15031 [#15252]: https://github.com/home-assistant/home-assistant/pull/15252 [#15535]: https://github.com/home-assistant/home-assistant/pull/15535 [#15632]: https://github.com/home-assistant/home-assistant/pull/15632 [#15744]: https://github.com/home-assistant/home-assistant/pull/15744 [#15925]: https://github.com/home-assistant/home-assistant/pull/15925 [#15935]: https://github.com/home-assistant/home-assistant/pull/15935 [#15953]: https://github.com/home-assistant/home-assistant/pull/15953 [#15990]: https://github.com/home-assistant/home-assistant/pull/15990 [#16080]: https://github.com/home-assistant/home-assistant/pull/16080 [#16085]: https://github.com/home-assistant/home-assistant/pull/16085 [#16157]: https://github.com/home-assistant/home-assistant/pull/16157 [#16159]: https://github.com/home-assistant/home-assistant/pull/16159 [#16176]: https://github.com/home-assistant/home-assistant/pull/16176 [#16179]: https://github.com/home-assistant/home-assistant/pull/16179 [#16185]: https://github.com/home-assistant/home-assistant/pull/16185 [#16188]: https://github.com/home-assistant/home-assistant/pull/16188 [#16192]: https://github.com/home-assistant/home-assistant/pull/16192 [#16193]: https://github.com/home-assistant/home-assistant/pull/16193 [#16194]: https://github.com/home-assistant/home-assistant/pull/16194 [#16195]: https://github.com/home-assistant/home-assistant/pull/16195 [#16203]: https://github.com/home-assistant/home-assistant/pull/16203 [#16205]: https://github.com/home-assistant/home-assistant/pull/16205 [#16212]: https://github.com/home-assistant/home-assistant/pull/16212 [#16215]: https://github.com/home-assistant/home-assistant/pull/16215 [#16217]: https://github.com/home-assistant/home-assistant/pull/16217 [#16218]: https://github.com/home-assistant/home-assistant/pull/16218 [#16229]: https://github.com/home-assistant/home-assistant/pull/16229 [#16237]: https://github.com/home-assistant/home-assistant/pull/16237 [#16247]: https://github.com/home-assistant/home-assistant/pull/16247 [#16248]: https://github.com/home-assistant/home-assistant/pull/16248 [#16251]: https://github.com/home-assistant/home-assistant/pull/16251 [#16258]: https://github.com/home-assistant/home-assistant/pull/16258 [#16259]: https://github.com/home-assistant/home-assistant/pull/16259 [#16261]: https://github.com/home-assistant/home-assistant/pull/16261 [#16262]: https://github.com/home-assistant/home-assistant/pull/16262 [#16263]: https://github.com/home-assistant/home-assistant/pull/16263 [#16265]: https://github.com/home-assistant/home-assistant/pull/16265 [#16267]: https://github.com/home-assistant/home-assistant/pull/16267 [#16275]: https://github.com/home-assistant/home-assistant/pull/16275 [#16281]: https://github.com/home-assistant/home-assistant/pull/16281 [#16296]: https://github.com/home-assistant/home-assistant/pull/16296 [#16297]: https://github.com/home-assistant/home-assistant/pull/16297 [#16299]: https://github.com/home-assistant/home-assistant/pull/16299 [#16303]: https://github.com/home-assistant/home-assistant/pull/16303 [#16304]: https://github.com/home-assistant/home-assistant/pull/16304 [#16308]: https://github.com/home-assistant/home-assistant/pull/16308 [#16323]: https://github.com/home-assistant/home-assistant/pull/16323 [#16327]: https://github.com/home-assistant/home-assistant/pull/16327 [#16337]: https://github.com/home-assistant/home-assistant/pull/16337 [#16339]: https://github.com/home-assistant/home-assistant/pull/16339 [#16340]: https://github.com/home-assistant/home-assistant/pull/16340 [#16344]: https://github.com/home-assistant/home-assistant/pull/16344 [#16346]: https://github.com/home-assistant/home-assistant/pull/16346 [#16348]: https://github.com/home-assistant/home-assistant/pull/16348 [#16352]: https://github.com/home-assistant/home-assistant/pull/16352 [#16356]: https://github.com/home-assistant/home-assistant/pull/16356 [#16359]: https://github.com/home-assistant/home-assistant/pull/16359 [#16360]: https://github.com/home-assistant/home-assistant/pull/16360 [#16361]: https://github.com/home-assistant/home-assistant/pull/16361 [#16363]: https://github.com/home-assistant/home-assistant/pull/16363 [#16365]: https://github.com/home-assistant/home-assistant/pull/16365 [#16366]: https://github.com/home-assistant/home-assistant/pull/16366 [#16368]: https://github.com/home-assistant/home-assistant/pull/16368 [#16372]: https://github.com/home-assistant/home-assistant/pull/16372 [#16373]: https://github.com/home-assistant/home-assistant/pull/16373 [#16375]: https://github.com/home-assistant/home-assistant/pull/16375 [#16377]: https://github.com/home-assistant/home-assistant/pull/16377 [#16387]: https://github.com/home-assistant/home-assistant/pull/16387 [#16394]: https://github.com/home-assistant/home-assistant/pull/16394 [#16396]: https://github.com/home-assistant/home-assistant/pull/16396 [#16397]: https://github.com/home-assistant/home-assistant/pull/16397 [#16403]: https://github.com/home-assistant/home-assistant/pull/16403 [#16404]: https://github.com/home-assistant/home-assistant/pull/16404 [#16408]: https://github.com/home-assistant/home-assistant/pull/16408 [#16415]: https://github.com/home-assistant/home-assistant/pull/16415 [#16419]: https://github.com/home-assistant/home-assistant/pull/16419 [#16428]: https://github.com/home-assistant/home-assistant/pull/16428 [#16429]: https://github.com/home-assistant/home-assistant/pull/16429 [#16450]: https://github.com/home-assistant/home-assistant/pull/16450 [#16453]: https://github.com/home-assistant/home-assistant/pull/16453 [#16454]: https://github.com/home-assistant/home-assistant/pull/16454 [#16455]: https://github.com/home-assistant/home-assistant/pull/16455 [#16459]: https://github.com/home-assistant/home-assistant/pull/16459 [#16460]: https://github.com/home-assistant/home-assistant/pull/16460 [#16463]: https://github.com/home-assistant/home-assistant/pull/16463 [#16465]: https://github.com/home-assistant/home-assistant/pull/16465 [#16470]: https://github.com/home-assistant/home-assistant/pull/16470 [#16471]: https://github.com/home-assistant/home-assistant/pull/16471 [#16472]: https://github.com/home-assistant/home-assistant/pull/16472 [#16477]: https://github.com/home-assistant/home-assistant/pull/16477 [#16478]: https://github.com/home-assistant/home-assistant/pull/16478 [#16486]: https://github.com/home-assistant/home-assistant/pull/16486 [#16490]: https://github.com/home-assistant/home-assistant/pull/16490 [#16494]: https://github.com/home-assistant/home-assistant/pull/16494 [#16495]: https://github.com/home-assistant/home-assistant/pull/16495 [#16501]: https://github.com/home-assistant/home-assistant/pull/16501 [#16502]: https://github.com/home-assistant/home-assistant/pull/16502 [#16507]: https://github.com/home-assistant/home-assistant/pull/16507 [#16515]: https://github.com/home-assistant/home-assistant/pull/16515 [#16529]: https://github.com/home-assistant/home-assistant/pull/16529 [#16534]: https://github.com/home-assistant/home-assistant/pull/16534 [#16536]: https://github.com/home-assistant/home-assistant/pull/16536 [#16537]: https://github.com/home-assistant/home-assistant/pull/16537 [#16556]: https://github.com/home-assistant/home-assistant/pull/16556 [#16558]: https://github.com/home-assistant/home-assistant/pull/16558 [#16559]: https://github.com/home-assistant/home-assistant/pull/16559 [#16575]: https://github.com/home-assistant/home-assistant/pull/16575 [#16578]: https://github.com/home-assistant/home-assistant/pull/16578 [#16589]: https://github.com/home-assistant/home-assistant/pull/16589 [#16592]: https://github.com/home-assistant/home-assistant/pull/16592 [@9R]: https://github.com/9R [@ASMfreaK]: https://github.com/ASMfreaK [@Cereal2nd]: https://github.com/Cereal2nd [@Danielhiversen]: https://github.com/Danielhiversen [@Joshi425]: https://github.com/Joshi425 [@JulianKahnert]: https://github.com/JulianKahnert [@Kane610]: https://github.com/Kane610 [@MarcSN311]: https://github.com/MarcSN311 [@OverloadUT]: https://github.com/OverloadUT [@PaulAnnekov]: https://github.com/PaulAnnekov [@PhracturedBlue]: https://github.com/PhracturedBlue [@ReneNulschDE]: https://github.com/ReneNulschDE [@amelchio]: https://github.com/amelchio [@aronsky]: https://github.com/aronsky [@awarecan]: https://github.com/awarecan [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@bieniu]: https://github.com/bieniu [@cgtobi]: https://github.com/cgtobi [@cpw]: https://github.com/cpw [@danielperna84]: https://github.com/danielperna84 [@dgomes]: https://github.com/dgomes [@djm300]: https://github.com/djm300 [@domwillcode]: https://github.com/domwillcode [@endor-force]: https://github.com/endor-force [@exxamalte]: https://github.com/exxamalte [@fabaff]: https://github.com/fabaff [@flo-wer]: https://github.com/flo-wer [@frenck]: https://github.com/frenck [@fucm]: https://github.com/fucm [@grea09]: https://github.com/grea09 [@htotoo]: https://github.com/htotoo [@ioangogo]: https://github.com/ioangogo [@jesserizzo]: https://github.com/jesserizzo [@kariudo]: https://github.com/kariudo [@kbickar]: https://github.com/kbickar [@lddubeau]: https://github.com/lddubeau [@mtdcr]: https://github.com/mtdcr [@mvn23]: https://github.com/mvn23 [@nudded]: https://github.com/nudded [@phil65]: https://github.com/phil65 [@pnbruckner]: https://github.com/pnbruckner [@pszafer]: https://github.com/pszafer [@pvizeli]: https://github.com/pvizeli [@rcloran]: https://github.com/rcloran [@rohankapoorcom]: https://github.com/rohankapoorcom [@rytilahti]: https://github.com/rytilahti [@schmittx]: https://github.com/schmittx [@scop]: https://github.com/scop [@smurfix]: https://github.com/smurfix [@tadly]: https://github.com/tadly [@tamasv]: https://github.com/tamasv [@teharris1]: https://github.com/teharris1 [@thomasdelaet]: https://github.com/thomasdelaet [@thomaslian]: https://github.com/thomaslian [@tschmidty69]: https://github.com/tschmidty69 [@tsvi]: https://github.com/tsvi [@vikramgorla]: https://github.com/vikramgorla [@vrih]: https://github.com/vrih [@zellux]: https://github.com/zellux [@zoe1337]: https://github.com/zoe1337 [alarm_control_panel.yale_smart_alarm docs]: /integrations/yale_smart_alarm [arlo docs]: /integrations/arlo/ [asterisk_mbox docs]: /integrations/asterisk_mbox/ [auth docs]: /integrations/auth/ [自动化 docs]: /integrations/自动化/ [自动化.event docs]: /docs/自动化/触发器/#event-触发器 [自动化.homeassistant docs]: /docs/自动化/触发器/#home-assistant-触发器 [自动化.numeric_state docs]: /docs/自动化/触发器/#numeric-状态-触发器 [自动化.状态 docs]: /docs/自动化/触发器/#状态-触发器 [自动化.模板 docs]: /docs/自动化/触发器/#模板-触发器 [自动化.区域 docs]: /docs/自动化/触发器/#区域-触发器 [binary_sensor.deconz docs]: /integrations/deconz#binary-传感器 [binary_sensor.openuv docs]: /integrations/openuv [摄像头 docs]: /integrations/摄像头/ [摄像头.proxy docs]: /integrations/proxy [摄像头.push docs]: /integrations/push [温控.generic_thermostat docs]: /integrations/generic_thermostat [温控.nest docs]: /integrations/nest#温控 [温控.opentherm_gw docs]: /integrations/opentherm_gw [温控.radiotherm docs]: /integrations/radiotherm [config docs]: /integrations/config/ [遮盖.insteon docs]: /integrations/insteon [遮盖.MQTT docs]: /integrations/遮盖.MQTT/ [遮盖.myq docs]: /integrations/myq [遮盖.rflink docs]: /integrations/遮盖.rflink/ [deconz docs]: /integrations/deconz/ [device_tracker docs]: /integrations/device_tracker/ [feedreader docs]: /integrations/feedreader/ [geo_location docs]: /integrations/geo_location/ [habitica docs]: /integrations/habitica/ [hangouts docs]: /integrations/hangouts/ [homematic docs]: /integrations/homematic/ [hue docs]: /integrations/hue/ [insteon docs]: /integrations/insteon/ [灯光.deconz docs]: /integrations/deconz#灯光 [灯光.hue docs]: /integrations/hue [灯光.MQTT docs]: /integrations/灯光.MQTT/ [灯光.tplink docs]: /integrations/tplink [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.cast docs]: /integrations/cast [媒体播放器.kodi docs]: /integrations/kodi [媒体播放器.onkyo docs]: /integrations/onkyo [媒体播放器.songpal docs]: /integrations/songpal [媒体播放器.sonos docs]: /integrations/sonos [媒体播放器.webostv docs]: /integrations/webostv#media-player [媒体播放器.yamaha docs]: /integrations/yamaha [MQTT docs]: /integrations/MQTT/ [netatmo docs]: /integrations/netatmo/ [通知 docs]: /integrations/通知/ [openuv docs]: /integrations/openuv/ [rfxtrx docs]: /integrations/rfxtrx/ [场景.deconz docs]: /integrations/deconz#场景 [脚本 docs]: /integrations/脚本/ [传感器.alpha_vantage docs]: /integrations/alpha_vantage [传感器.apcupsd docs]: /integrations/apcupsd#传感器 [传感器.darksky docs]: /integrations/darksky [传感器.deconz docs]: /integrations/deconz#传感器 [传感器.dht docs]: /integrations/dht [传感器.dnsip docs]: /integrations/dnsip [传感器.enphase_envoy docs]: /integrations/enphase_envoy [传感器.geizhals docs]: /integrations/geizhals [传感器.habitica docs]: /integrations/habitica [传感器.lastfm docs]: /integrations/lastfm [传感器.miflora docs]: /integrations/miflora [传感器.mvglive docs]: /integrations/mvglive [传感器.netatmo docs]: /integrations/netatmo#传感器 [传感器.netgear_lte docs]: /integrations/netgear_lte [传感器.openuv docs]: /integrations/openuv [传感器.qnap docs]: /integrations/qnap [传感器.sense docs]: /integrations/sense [传感器.shodan docs]: /integrations/shodan [传感器.snmp docs]: /integrations/snmp#传感器 [传感器.sql docs]: /integrations/sql [传感器.statistics docs]: /integrations/statistics [传感器.systemmonitor docs]: /integrations/systemmonitor [传感器.tahoma docs]: /integrations/tahoma [传感器.tibber docs]: /integrations/tibber#传感器 [传感器.trafikverket_weatherstation docs]: /integrations/trafikverket_weatherstation [传感器.twitch docs]: /integrations/twitch [传感器.velbus docs]: /integrations/velbus [传感器.volkszaehler docs]: /integrations/volkszaehler [传感器.waze_travel_time docs]: /integrations/waze_travel_time [snips docs]: /integrations/snips/ [开关.deconz docs]: /integrations/deconz#开关 [开关.dlink docs]: /integrations/dlink [开关.snmp docs]: /integrations/snmp#开关 [开关.switchbot docs]: /integrations/switchbot [开关.switchmate docs]: /integrations/switchmate [开关.tahoma docs]: /integrations/tahoma [开关.tplink docs]: /integrations/tplink [tahoma docs]: /integrations/tahoma/ [telegram_bot docs]: /integrations/telegram_bot/ [tts docs]: /integrations/tts/ [upnp docs]: /integrations/upnp/ [吸尘器 docs]: /integrations/吸尘器/ [吸尘器.xiaomi_miio docs]: /integrations/吸尘器.xiaomi_miio/ [velbus docs]: /integrations/velbus/ [websocket_api docs]: /integrations/websocket_api/ [zha docs]: /integrations/zha/ [zoneminder docs]: /integrations/zoneminder/ --- url: /home-assistant/blog/2018-09-17-thinking-big.md --- # 放眼未来 今天是 Home Assistant 的 5 周年。我想借这篇文章,不仅回顾过去 5 年,也谈谈我们接下来要走向哪里、希望 Home Assistant 成为什么样的平台。 Home Assistant 不是出于某种意识形态而诞生的。我最初只是买了些智能灯,想写脚本控制它们。后来我把这些脚本开源,项目就这样发展起来了。随着 Home Assistant 成长,周围的世界变了,我自己也变了。 Home Assistant 诞生后,市面上出现了大量 IoT 产品。遗憾的是,主流趋势是把所有数据上传到云端,再从云端管理你的家。我逐渐意识到,大公司并没有动力去做真正重视隐私和本地控制的产品,因为我们的数据对他们太有价值了。 我不喜欢这个趋势。我不愿看到越来越多的数据被少数巨头囤积,集中在少数系统里,再被用来影响我们在网络世界中的处境。这是我们的生活、我们的数据,控制权应当属于我们,而不是某个为“互动率”优化的算法。 因此我想为 Home Assistant 提出一个目标。这个目标将塑造平台未来几年的发展方向。 ## The goal 我们的目标是打造一个以人为中心的家庭自动化平台:开源,并把隐私与本地控制放在优先位置。 * **隐私。** 你的所有数据都存储在本地。 * **本地控制。** 所有逻辑都在本地运行,云只在必要时调用。 * **开源。** 平台对用户和企业都免费开放。越多人选择注重隐私的平台而不是纯云方案,对我们来说就是胜利。 * **互操作性。** 平台提供易于共享数据的 API。我们希望你的数据可以被你想用的任何应用访问。 ## 为实现目标我们将构建什么 有很多!以下是我最期待的一些方向: * **远程连接实例。** 你在外也能控制 Home Assistant。我们会使用端到端加密,确保云端无法读取你的数据。该功能由 Home Assistant Cloud 提供,你只要登录即可使用。这会是云服务下一个重点功能。 * **归因能力。** 我们最近加入了用户和上下文。下一步会在日志中清晰显示“哪个用户触发了哪项变更”。 * **权限体系。** 基于同一套用户与上下文机制,我们也能把实体访问限制到具体用户。 * **更好的设备管理。** 我们最近已在 Home Assistant 中加入设备概念。用户将可以把设备放入区域、查看某设备包含哪些实体,并确保实体状态保持最新。 * **可达性。** 我们希望 Hass.io 能运行在尽可能多的设备上,让任何人都能轻松开启私有化智能家居。 * **集成 Mozilla 的 [Web Things API]。** 让平台更容易与其他家庭自动化平台互通。新引入的设备管理也与 Web Things 数据模型高度契合。 * **云透明度。** 我们希望清晰展示哪些数据被共享到了 Amazon Alexa 和 Google Home 云端。 * **更好的 Z-Wave。** 当前集成还有改进空间。Z-Wave 所有方已经宣布公开 SDK,我们会探索将其集成进 Home Assistant。 ## 实现目标还需要什么 Home Assistant 的规模已经超出“靠业余时间维持”的阶段。我们希望继续保持友好的社区氛围、高质量代码、平滑升级、及时更新文档和可靠的平台安全。 在 Ubiquiti,我们找到了目标一致的合作伙伴。他们在 4 月聘用我全职投入 Home Assistant,已经带来了明显进展,包括上面提到的一些增强。但只有一名全职成员仍然不够。 因此我创立了新公司来筹集资金,帮助 Home Assistant 实现目标:[Nabu Casa, Inc][nabu-home]。公司将以每月 5 美元订阅费运营 Home Assistant Cloud。收入将用于扩展云功能、支持 Home Assistant 网站与社区基础设施,并支付全职员工持续贡献项目。
Logo of Nabu Casa, Inc
Nabu Casa, Inc. 只接受订阅用户的资金支持。这样才能保证我们始终为真正出资的用户负责,做对用户最有利的事。我们不会向投资人融资。大资本通常更在意继续赚钱,而不是人本身与隐私。我们必须保持控制权,才能确保目标不偏移。 如果你在过去 9 个月一直是 Home Assistant Cloud 用户,感谢你参与公开测试。所有公开测试成员会自动进入免费试用,可继续使用 Home Assistant Cloud 至 10 月 17 日,且无需对 Home Assistant 做任何改动。若试用结束前未填写支付信息,你将失去 Home Assistant Cloud 访问权限。 更多信息: * [Nabu Casa, Inc homepage][nabu-home] * [Manage your Home Assistant Cloud account][nabu-account] ## 常见问题 ### Do I have to pay to use Home Assistant and Hass.io? 不需要。Home Assistant 是开源并可免费安装,这一点不会改变。只有云服务是付费订阅。 ### Will Home Assistant and Hass.io remain 开源? 会。Nabu Casa 只负责 Home Assistant Cloud,并会投入资源帮助 Home Assistant 实现目标并承担基础设施成本。 ### Why not take donations? 仅依赖捐赠,无法为员工做可持续预算,也会让他们及家人面临月底拿不到薪水的风险。 ### Is Home Assistant Cloud 开源? Home Assistant Cloud 的大部分代码是开源的。Alexa 技能源码在[这里](https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/integrations/alexa/smart_home.py)(手动配置说明见[这里](https://github.com/mike-grant/haaska/));Google Assistant 源码在[这里](https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/integrations/google_assistant/smart_home.py)(手动配置说明见[这里](/home-assistant/integrations/google_assistant/index.md))。我们的账户页面和中继服务目前不开源。 ### Will you offer a lifetime plan for a one time fee? 不会。云服务的一次性终身计划本质上是庞氏结构,意味着新订阅者在为老订阅者的长期成本买单。 ### I think the price is too high for what I get 未来会持续增加新功能,价格不变。我们计划发布的下一个功能是对实例的加密远程访问。 订阅费用不仅覆盖 Home Assistant Cloud 的运行成本,收入还将用于支持 Home Assistant 与社区论坛的基础设施。 [nabu-home]: https://www.nabucasa.com [nabu-account]: https://account.nabucasa.com [Web Things API]: https://iot.mozilla.org/wot/ --- url: /home-assistant/blog/2018-09-30-hacktoberfest.md --- # 参与 Hacktoberfest 十月将迎来 [Hacktoberfest](https://hacktoberfest.digitalocean.com/)。为了庆祝并支持开源,[DigitalOcean](https://www.digitalocean.com/)、[Twilio](https://www.twilio.com/) 和 [GitHub](https://github.com/) 再次联合举办该活动。和过去两年一样,Home Assistant 也会参与其中。 我们建议优先关注这些仓库。浏览 bug 列表并修复一个,就能用相对轻松的方式开始参与开源项目: * [Home Assistant 前端](https://github.com/home-assistant/home-assistant-polymer) * [Hass.io](https://github.com/home-assistant/hassio) * [HassOS](https://github.com/home-assistant/hassos) * [Hass.io CLI](https://github.com/home-assistant/hassio-cli) 我们还为另外两个仓库整理了一批入门级 bug、功能和文档改进项。当前请优先处理已开放的 issue,我们会在十月持续补充: * [Home Assistant Easyfix collection](https://github.com/home-assistant/home-assistant/projects/2) * [Home Assistant 文档 Easyfix collection](https://github.com/home-assistant/home-assistant.io/projects/2) 如果你在十月提交了五(5)个 Pull Request,就可以获得限量版 Hacktoberfest T 恤;若 PR 提交到 Home Assistant 仓库,还会被写入我们的致谢名单!不用担心,哪怕你提交的 PR 数量不到五个,也同样会被列入名单。 **我们希望重点支持新贡献者,以及想开始参与开源项目的人。** 准备好了吗?[立即报名 Hacktoberfest](https://hacktoberfest.digitalocean.com/profile)! ## Details Hacktoberfest 会给我们带来大量工作。2017 年十月,我们仅在三个主要仓库就处理了 625 个 Pull Request,其他 Home Assistant 相关仓库还有更多。我们的资源仍然有限,所以本届 Hacktoberfest 我们制定了一些规则,既帮助我们协作,也尽量减少大家的挫败感。 ### General * 请完整填写 Pull Request 模板(如有)。 * 提交 Pull Request 前先跑一遍代码检查(lint 与单元测试)。 * 请保持 Pull Request 小而聚焦。一个 PR 做一件事,远比一个 PR 同时改 19 处功能更容易审查。 * 未通过 CI 的 Pull Request 通常会得到更少关注,甚至无人处理。 * 我们无法保证所有 Pull Request 都会在十月内处理,敬请谅解。 * 对于缺少必要内容(见模板中的 Checklist)、信息不足或提交后长期无响应的 Pull Request,我们保留关闭权利。你准备好后可随时补充并重新开启。 ### Home Assistant 前端 * 可以先阅读 [Polymer 文档](https://www.polymer-project.org/)。 * 再看 [Home Assistant 前端文档](https://开发者.home-assistant.io/docs/前端)。 ### Home Assistant * 先熟悉我们的 [Style Guidelines](https://开发者.home-assistant.io/docs/development_guidelines) 和现有代码。 * 通读 [开发者文档](https://开发者.home-assistant.io)。 * 别忘了文档。很多改动都需要同步更新文档,尤其是新增集成。你知道怎么用,但用户不知道。 * [架构层改动](https://github.com/home-assistant/architecture)需先讨论再提变更;此外,这类 Pull Request 十月期间可能不会优先审查。 * 如果你更新依赖,请确保它确实可用,并提供配置示例及相关信息(使用设备、固件版本等)。 ### Home Assistant 文档 * 先熟悉 [Markdown](https://www.markdownguide.org/cheat-sheet)。 * 了解我们的[文档标准与规范](https://开发者.home-assistant.io/docs/documenting/standards)。 * 小改动(如拼写修复、语义澄清)可直接用 GitHub 在线编辑器完成。 * 大改动强烈建议先搭建本地环境构建文档,再提交 Pull Request。 * 注意分支目标:`current` 用于现有文档更新,`next` 用于下个版本才会上线的新功能或集成。 ## Improve our dependencies 对我们而言,Hacktoberfest 不只是提交 Pull Request,更关乎整个生态。Home Assistant 依赖很多 Python 模块,你也可以通过让其他项目更健壮、迁移到 asyncio、适配 Python 3.7 等方式间接帮助 Home Assistant。 记得与代码仓库 owner 或维护者沟通,确保你的贡献能计入 Hacktoberfest。 ## Help us with the workload 如果你愿意帮忙审查其他 Pull Request,也会是巨大的帮助。这会提高你自己和他人 PR 被及时处理的概率。我们目前在大多数仓库都已有 PR 积压。 如果你觉得自己经验不足,也不用担心,社区里会有人协助你。先从容易发现的问题入手完全没问题,先指出最明显的问题,再逐步深入。多一双眼睛总是更有价值。 ## Not a coder? Not a problem! 如果你不是开发者,也完全没问题!你可以[报告 bug](https://github.com/home-assistant/home-assistant/issues/new/choose)、反馈使用体验、向社区分享你的[酷炫设置](https://community.home-assistant.io/c/projects)、用 [Lovelace](/home-assistant/Lovelace) 打造[超赞前端](https://community.home-assistant.io/c/projects/前端),或者在[论坛](https://community.home-assistant.io/)帮助其他用户。 --- url: /home-assistant/blog/2018-10-01-release-79.md --- # 0.79: 设备 Registry, Logi Circle, Huawei LTE routers, GeoJSON :::note In case you missed it two weeks ago, check [our plans for the future](/home-assistant/blog/2018/09/17/thinking-big/). ::: It's time for another great 发布 and we're introducing a brand new feature: 设备 registry. Thanks to [@Kane610] for driving this effort. This allows 集成 to tell Home Assistant not only about 实体, but also which 设备 the 实体 represent. It also allows 集成 to tell Home Assistant how a 设备 is connected to Home Assistant. For example, a Hue 灯光 bulb is connected to Home Assistant via the Hue hub.

Screenshot showing several configured 集成 Screenshot showing several configured 集成 in the 配置 面板.

Adding 设备 to the mix allows us to do a lot of cool things. It allows us to group 实体 and show how they relate to one another. It will also allow us to inform the 用户 if data leaves the home network and shows the firmware 版本 that the 设备 is running on.

Screenshot showing the 设备 of a config entry Screenshot showing the 设备 of the iOS 集成.

设备 can only be added by 集成 that are configured via the 集成 面板 in the config 面板. So we've also been expanding the 集成 that support that. This 发布 brings support to iOS, MQTT and Tradfri.

Screenshot showing how to 配置 MQTT via UI Screenshot showing how to 配置 MQTT via UI

And this is not all! There is so much more. In an effort to make the quality of an 集成 more clear, we've added an [集成 Quality Scale](/home-assistant/docs/quality_scale/index.md). With this scale we'll be able to clearly communicate to the 用户 how good an 集成 is and it gives 开发者 a list on how to improve it. Expect these levels to pop up in the 集成 list soon. And did you think we forgot about auth? We did not. [@awarecan] has added a new multi-factor auth module that will send you a one-time 认证 code to finish your login, **with a 通知 服务 of your choice**. PushBullet, Hangouts, iOS app, some obscure custom 通知 服务 using a shell 脚本? It's possible. Oh, and yes, there is also some cool new 集成. Support has been added for Logi Circle 摄像头's, GeoJSON events and even a bank. More below 👇 ## New Platforms * Add Huawei LTE router platform, 设备 tracker, and 传感器 ([@scop] - [#16498]) ([device\_tracker docs][device_tracker docs]) ([huawei\_lte docs][huawei_lte docs]) ([传感器.huawei\_lte docs][传感器.huawei_lte docs]) (new-platform) * New EDP re:dy component ([@abmantis] - [#16426]) (new-platform) * Jewish 日历 传感器 ([@tsvi] - [#16393]) ([传感器.jewish\_calendar docs][传感器.jewish_calendar docs]) (new-platform) * Added support for Starling Bank ([@Dullage] - [#16522]) ([传感器.starlingbank docs]) (new-platform) * Add Call Data 日志 platform. Mailboxes no longer require media ([@PhracturedBlue] - [#16579]) ([asterisk\_mbox docs][asterisk_mbox docs]) ([mailbox docs]) ([mailbox.asterisk\_cdr docs][mailbox.asterisk_cdr docs]) ([mailbox.asterisk\_mbox docs][mailbox.asterisk_mbox docs]) (new-platform) * Add Logi Circle component, 摄像头 and 传感器 platform ([@evanjd] - [#16540]) ([logi\_circle docs][logi_circle docs]) ([摄像头.logi\_circle docs][摄像头.logi_circle docs]) ([传感器.logi\_circle docs][传感器.logi_circle docs]) (new-platform) * deCONZ 遮盖 support ([@Kane610] - [#16759]) ([遮盖 docs]) ([deconz docs]) ([遮盖.deconz docs]) (new-platform) * GeoJSON platform ([@exxamalte] - [#16610]) ([geo\_location docs][geo_location docs]) (new-platform) * Add linky 传感器 ([@tiste] - [#16468]) (new-platform) ## 发布 0.79.1 - September 30 * Optimize Ring 传感器 platform 设置 ([@awarecan] - [#16886]) ([binary\_sensor.ring docs][binary_sensor.ring docs]) ([传感器.ring docs]) * Fix exception during history\_stats startup ([@amelchio] - [#16932]) ([传感器.history\_stats docs][传感器.history_stats docs]) * Override unique\_id of NestActivityZoneSensor ([@awarecan] - [#16961]) ([binary\_sensor.nest docs][binary_sensor.nest docs]) * Fix ISY blocking bug ([@OverloadUT] - [#16978]) ([灯光.isy994 docs]) * Bump zm-py to 0.0.4 ([@rohankapoorcom] - [#16979]) ([zoneminder docs]) [#16886]: https://github.com/home-assistant/home-assistant/pull/16886 [#16932]: https://github.com/home-assistant/home-assistant/pull/16932 [#16961]: https://github.com/home-assistant/home-assistant/pull/16961 [#16978]: https://github.com/home-assistant/home-assistant/pull/16978 [#16979]: https://github.com/home-assistant/home-assistant/pull/16979 [@OverloadUT]: https://github.com/OverloadUT [@amelchio]: https://github.com/amelchio [@awarecan]: https://github.com/awarecan [@rohankapoorcom]: https://github.com/rohankapoorcom [binary_sensor.nest docs]: /integrations/nest#binary-传感器 [binary_sensor.ring docs]: /integrations/ring#binary-传感器 [灯光.isy994 docs]: /integrations/isy994 [传感器.history_stats docs]: /integrations/history_stats [传感器.ring docs]: /integrations/ring#传感器 [zoneminder docs]: /integrations/zoneminder/ ## 发布 0.79.2 - October 1 * Fix MQTT certificates ([@balloob] - [#16999]) ([MQTT docs]) * Fix 开关.zoneminder name ([@rohankapoorcom] - [#17026]) ([开关.zoneminder docs]) [#16999]: https://github.com/home-assistant/home-assistant/pull/16999 [#17026]: https://github.com/home-assistant/home-assistant/pull/17026 [@balloob]: https://github.com/balloob [@rohankapoorcom]: https://github.com/rohankapoorcom [MQTT docs]: /integrations/MQTT/ [开关.zoneminder docs]: /integrations/zoneminder#开关 ## 发布 0.79.3 - October 2 * Use correct event loop on Windows, fixing SSL and Subprocess requests. ([#16737], [#17066] - [@awarecan], [@balloob]) [#16737]: https://github.com/home-assistant/home-assistant/pull/16737 [#17066]: https://github.com/home-assistant/home-assistant/pull/17066 ## If you need help... ...don't hesitate to use our very active [forums](https://community.home-assistant.io/) or join us for a little [chat](https://discord.gg/c5DvZ4e). The 发布 notes have comments enabled but it's preferred if you use the former communication channels. Thanks. ## Reporting Issues Experiencing issues introduced by this 发布? Please report them in our [issue tracker](https://github.com/home-assistant/home-assistant/issues). Make sure to fill in all fields of the issue 模板. ## Backward-incompatible changes * Netdata 配置 change: Allows multiple elements per group. Specify the `data_group` as part of the 传感器 description. See docs for details. ([@reefab] - [#16656]) ([传感器.netdata docs]) (breaking change) * The Dyson 传感器 Air Quality Index is now named AQI following Dyson's mobile app ([@glpatcern] - [#14550]) ([传感器.dyson docs]) (breaking change) ## Beta Fixes * Don't warn but info when on dev mode ([@balloob] - [#16831]) ([updater docs]) (beta fix) * Bump zm-py to 0.0.3 ([@rohankapoorcom] - [#16835]) ([zoneminder docs]) (beta fix) * Support old tradfri config format ([@balloob] - [#16841]) ([tradfri docs]) (beta fix) * Allow MQTT discovery ([@balloob] - [#16842]) ([MQTT docs]) (beta fix) * Add unique ID and 设备 info to Nest 摄像头 ([@balloob] - [#16846]) ([摄像头.nest docs]) (beta fix) * 设备 Registry Support for iOS 传感器 ([@cgarwood] - [#16862]) ([传感器.ios docs]) (beta fix) * Fix MQTT discovery ([@balloob] - [#16864]) ([MQTT docs]) (beta fix) * Make ring sync again ([@balloob] - [#16866]) ([摄像头.ring docs]) (beta fix) * Add unique\_id to Nest 传感器 ([@cgarwood] - [#16869]) ([binary\_sensor.nest docs][binary_sensor.nest docs]) ([传感器.nest docs]) (beta fix) * Prevent discovered Tradfri while already configured ([@balloob] - [#16891]) ([tradfri docs]) (beta fix) * Handle exception handling websocket command ([@balloob] - [#16927]) ([websocket\_api docs][websocket_api docs]) (beta fix) * The `zoneminder` 开关 platform now uses new names. ([@rohankapoorcom] - [#16527]) ([zoneminder docs]) (breaking change) ## All changes * 升级 wakeonlan to 1.1.6 ([@fabaff] - [#16512]) ([wake\_on\_lan docs][wake_on_lan docs]) ([媒体播放器.panasonic\_viera docs][媒体播放器.panasonic_viera docs]) ([媒体播放器.samsungtv docs]) ([开关.wake\_on\_lan docs][开关.wake_on_lan docs]) * Make the Qnap 传感器 more resilient if server is not reachable ([@mrosseel] - [#16445]) ([传感器.qnap docs]) * 更新 PyRMVtransport 版本 ([@cgtobi] - [#16547]) ([传感器.rmvtransport docs]) * Isort preparations ([@scop] - [#16555]) ([apple\_tv docs][apple_tv docs]) ([geo\_location docs][geo_location docs]) ([google\_assistant docs][google_assistant docs]) ([rachio docs]) ([媒体播放器.cast docs]) ([媒体播放器.webostv docs]) * Store 通知 in component. Add ws endpoint for fetching. ([@jeradM] - [#16503]) ([http docs]) ([persistent\_notification docs][persistent_notification docs]) * Fixes an OpenUV bug with the scan interval ([@bachya] - [#16570]) ([openuv docs]) * Bump pyeconet ([@w1ll1am23] - [#16571]) ([温控.econet docs]) * yr: use async syntax ([@Danielhiversen] - [#16563]) * 通知 for Android TV: Add fontsize and sending 图像 ([@danielperna84] - [#16565]) ([通知 docs]) * 升级 pytest to 3.8.0 and pytest-timeout to 1.3.2 ([@scop] - [#16489]) * Refactor zha/async\_device\_initialized(). ([@Adminiuga] - [#16485]) ([zha docs]) * 更新 风扇.zha platform. ([@Adminiuga] - [#16551]) ([风扇.zha docs]) * Hangouts help "page" and little bugfix ([@hobbypunk90] - [#16464]) ([hangouts docs]) * Konnected component feature updates ([@heythisisnate] - [#16479]) ([konnected docs]) * Add config entry to iOS ([@balloob] - [#16580]) ([ios docs]) ([通知 docs]) * Switchmate ([@Danielhiversen] - [#16395]) ([开关.switchmate docs]) * 更新 pyhomematic to 0.1.48 ([@danielperna84] - [#16588]) ([homematic docs]) * Add configure\_reporting() method to zha component ([@Adminiuga] - [#16487]) ([zha docs]) ([binary\_sensor.zha docs][binary_sensor.zha docs]) ([传感器.zha docs]) * Allow only\_cache parameter in zha.safe\_read() ([@Adminiuga] - [#16553]) ([zha docs]) * 更新 tibber lib 版本 ([@Danielhiversen] - [#16590]) ([传感器.tibber docs]) * xiaomi lib 0.10.0 ([@Danielhiversen] - [#16591]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * Support for the Quirky Nimbus ([@w1ll1am23] - [#16520]) ([wink docs]) ([温控.wink docs]) * Multiple tag managers for Wireless 传感器 Tags. ([@sergeymaysak] - [#16353]) ([wirelesstag docs]) ([binary\_sensor.wirelesstag docs][binary_sensor.wirelesstag docs]) ([传感器.wirelesstag docs]) ([开关.wirelesstag docs]) * Add Huawei LTE router platform, 设备 tracker, and 传感器 ([@scop] - [#16498]) ([device\_tracker docs][device_tracker docs]) ([huawei\_lte docs][huawei_lte docs]) ([传感器.huawei\_lte docs][传感器.huawei_lte docs]) (new-platform) * Changing Z-Wave brightness calculation to respect 0x01 and 0x02 byte values ([@Harvtronix] - [#16420]) ([灯光.zwave docs]) * Add myself to CODEOWNERS for upcloud ([@scop] - [#16599]) * Add websocket list APIs for the registries ([@balloob] - [#16597]) ([config docs]) * MQTT config entry ([@balloob] - [#16594]) ([hangouts docs]) ([homematicip\_cloud docs][homematicip_cloud docs]) ([MQTT docs]) * 升级 python-twitch-client to 0.6.0 ([@fabaff] - [#16602]) ([传感器.twitch docs]) * Improve precision of timer ticks ([@amelchio] - [#16598]) * 开关 components.传感器.zha to await syntax. ([@Adminiuga] - [#16619]) ([传感器.zha docs]) * Adding support for RTDSContactSensor and RTDSMotionSensor in Tahoma … (RTS 报警 传感器 and contacts for Somfy Protexiom 报警) ([@christopheBfr] - [#16609]) ([tahoma docs]) ([传感器.tahoma docs]) * fix bug where momentary 开关 with activation low does not reset ([@heythisisnate] - [#16603]) ([开关.konnected docs]) * Extracting zoneminder to a new library ([@rohankapoorcom] - [#16527]) ([zoneminder docs]) ([摄像头.zoneminder docs]) * Add @rohankapoorcom to CODEOWNERS for the zoneminder platform ([@rohankapoorcom] - [#16627]) * Small huawei\_lte improvements ([@scop] - [#16626]) ([huawei\_lte docs][huawei_lte docs]) ([传感器.huawei\_lte docs][传感器.huawei_lte docs]) * 升级 pwmled to 1.3.0 ([@soldag] - [#16624]) ([灯光.rpi\_gpio\_pwm docs][灯光.rpi_gpio_pwm docs]) * Clean up MjpegCamera by removing unnused hass object in **init** ([@rohankapoorcom] - [#16628]) ([摄像头.axis docs]) ([摄像头.mjpeg docs]) ([摄像头.zoneminder docs]) * 更新 developer doc links to 开发者.home-assistant.io ([@scop] - [#16622]) ([websocket\_api docs][websocket_api docs]) * Add valid\_window=1 to TOTP verify ([@awarecan] - [#16625]) * Add new 设备 to HomematicIP Cloud ([@mxworm] - [#16636]) ([binary\_sensor.homematicip\_cloud docs][binary_sensor.homematicip_cloud docs]) ([传感器.homematicip\_cloud docs][传感器.homematicip_cloud docs]) * New EDP re:dy component ([@abmantis] - [#16426]) (new-platform) * 升级 Switchmate lib ([@Danielhiversen] - [#16637]) ([开关.switchmate docs]) * 更新 pyhomematic to 0.1.49 ([@danielperna84] - [#16649]) ([homematic docs]) * 升级 holidays to 0.9.7 ([@fabaff] - [#16651]) ([binary\_sensor.workday docs][binary_sensor.workday docs]) * Fix link to docs ([@fabaff] - [#16652]) ([吸尘器.ecovacs docs]) * 日志 raw result of configure\_reporting() command. ([@Adminiuga] - [#16655]) ([zha docs]) * Rework timer delays ([@amelchio] - [#16650]) * Add config entries to connection class ([@balloob] - [#16618]) * Add zha 设备 实体 ([@damarco] - [#14579]) ([zha docs]) * Clean up 设备 更新, add via-hub ([@balloob] - [#16659]) * Jewish 日历 传感器 ([@tsvi] - [#16393]) ([传感器.jewish\_calendar docs][传感器.jewish_calendar docs]) (new-platform) * Fixes an AirVisual bug where response data is missing ([@bachya] - [#16673]) ([传感器.airvisual docs]) * Suppress traceback and 日志 错误 ([@fabaff] - [#16669]) ([传感器.scrape docs]) * Fix Ecovacs 吸尘器 showing "None" for name ([@OverloadUT] - [#16654]) ([ecovacs docs]) ([吸尘器.ecovacs docs]) * 升级 paho-MQTT to 1.4.0 ([@fabaff] - [#16688]) ([MQTT docs]) ([shiftr docs]) * Streamline 日志 messages ([@gwww] - [#16243]) * Added velbus counter 传感器, updated to py-velbus 2.0.20 ([@Cereal2nd] - [#16683]) ([velbus docs]) ([传感器.velbus docs]) * Added support for Starling Bank ([@Dullage] - [#16522]) ([传感器.starlingbank docs]) (new-platform) * Netdata 配置 change: Allows multiple elements per group ([@reefab] - [#16656]) ([传感器.netdata docs]) (breaking change) * 升级 mypy to 0.630 ([@scop] - [#16674]) * Use one regex for Hass.io URL check ([@pvizeli] - [#16710]) ([hassio docs]) * Remove usage of "run\_until\_complete" ([@smurfix] - [#16617]) * More isort preparations ([@scop] - [#16633]) * Use posargs in tox lint env ([@scop] - [#16646]) * Make pylint report non-LF linefeeds per the style guidelines ([@scop] - [#16601]) * Config flow tradfri ([@balloob] - [#16665]) * MyQ Open 状态 Fix ([@geekofweek] - [#16681]) ([遮盖.myq docs]) * Save disabled\_by in 实体 registry ([@cgarwood] - [#16699]) * Upgrading librouteros 版本 ([@kunago] - [#16718]) ([device\_tracker docs][device_tracker docs]) * Add unique\_id to mqtt\_json 灯光 ([@nikolaykasyanov] - [#16721]) * On-demand 更新 of swiss public transport 传感器 ([@vikramgorla] - [#16723]) ([传感器.swiss\_public\_transport docs][传感器.swiss_public_transport docs]) * 升级 youtube\_dl to 2018.09.18 ([@fabaff] - [#16729]) ([media\_extractor docs][media_extractor docs]) * Met.no 天气 platform ([@Danielhiversen] - [#16582]) * 升级 keyring to 15.1.0 ([@fabaff] - [#16734]) * Avoid calling yr 更新 every second for a minute ones every hour ([@Danielhiversen] - [#16731]) * 升级 shodan to 1.10.2 ([@fabaff] - [#16736]) ([传感器.shodan docs]) * Add subscription info endpoint ([@balloob] - [#16727]) ([cloud docs]) ([websocket\_api docs][websocket_api docs]) * Small cleanup for slack ([@pvizeli] - [#16743]) ([通知 docs]) * 灯光.zha: Catch exceptions for all commands. ([@Adminiuga] - [#16752]) ([灯光.zha docs]) * Changed save\_on\_change to default to False ([@zoe1337] - [#16744]) ([灯光.yeelight docs]) * Add option to disable specific 集成 ([@balloob] - [#16757]) ([alexa docs]) ([cloud docs]) ([google\_assistant docs][google_assistant docs]) * Use pysonos for Sonos media player ([@amelchio] - [#16753]) ([sonos docs]) ([媒体播放器.sonos docs]) * deCONZ add via\_hub 属性 for 设备 registry ([@Kane610] - [#16760]) ([binary\_sensor.deconz docs][binary_sensor.deconz docs]) ([灯光.deconz docs]) ([传感器.deconz docs]) ([开关.deconz docs]) * 升级 pysonos to 0.0.2 ([@amelchio] - [#16761]) * Fix faulty color temp crashing google ([@balloob] - [#16758]) ([google\_assistant docs][google_assistant docs]) * Add Call Data 日志 platform. Mailboxes no longer require media ([@PhracturedBlue] - [#16579]) ([asterisk\_mbox docs][asterisk_mbox docs]) ([mailbox docs]) ([mailbox.asterisk\_cdr docs][mailbox.asterisk_cdr docs]) ([mailbox.asterisk\_mbox docs][mailbox.asterisk_mbox docs]) (new-platform) * Implement support for complex 模板 in 脚本 delays ([@rohankapoorcom] - [#16442]) * Add Logi Circle component, 摄像头 and 传感器 platform ([@evanjd] - [#16540]) ([logi\_circle docs][logi_circle docs]) ([摄像头.logi\_circle docs][摄像头.logi_circle docs]) ([传感器.logi\_circle docs][传感器.logi_circle docs]) (new-platform) * Zha 开关 schedule 更新 状态 ([@Adminiuga] - [#16621]) ([开关.zha docs]) * Add Carbon Monoxide HomeKit 传感器 ([@cdce8p] - [#16664]) ([homekit docs]) * Add unique\_id to MQTT 摄像头 ([@bieniu] - [#16569]) ([摄像头.MQTT docs]) * Add tradfri 设备 info ([@balloob] - [#16768]) * Make rest 传感器 and 二元sensor more efficient ([@exxamalte] - [#14484]) ([binary\_sensor.rest docs][binary_sensor.rest docs]) ([传感器.rest docs]) * Refactored units and icons for the Dyson 传感器 ([@glpatcern] - [#14550]) ([传感器.dyson docs]) (breaking change) * Add confirmation to Cast/Sonos/iOS config entries ([@balloob] - [#16769]) * deCONZ 遮盖 support ([@Kane610] - [#16759]) ([遮盖 docs]) ([deconz docs]) ([遮盖.deconz docs]) (new-platform) * GeoJSON platform ([@exxamalte] - [#16610]) ([geo\_location docs][geo_location docs]) (new-platform) * 升级 restrictedpython to 4.0b5 ([@fabaff] - [#16779]) ([python\_script docs][python_script docs]) * 升级 bimmer\_connected to 0.5.2 ([@gerard33] - [#16780]) ([bmw\_connected\_drive docs][bmw_connected_drive docs]) * Fix Windows loop ([@balloob] - [#16737]) * Fix return to base logic for neato ([@dshokouhi] - [#16776]) ([吸尘器.neato docs]) * 更新 Tibber lib ([@Danielhiversen] - [#16795]) * Bump pybotvac to 0.0.10 ([@dshokouhi] - [#16799]) ([neato docs]) * Bump zm-py up to 0.0.2 ([@rohankapoorcom] - [#16800]) ([zoneminder docs]) * Bump sucks (Ecovacs) lib to 0.9.3 ([@OverloadUT] - [#16803]) ([ecovacs docs]) ([吸尘器.ecovacs docs]) * 升级 zeroconf to 0.21.3 ([@tadly] - [#16789]) * Add Tuya 遮盖 状态 ([@huangyupeng] - [#16709]) ([遮盖.tuya docs]) * Add configurable host for bbox routers ([@isonet] - [#16778]) * Set botvac 状态 when offline ([@dshokouhi] - [#16805]) ([吸尘器.neato docs]) * Handle netgear\_lte connection 错误 ([@amelchio] - [#16806]) ([netgear\_lte docs][netgear_lte docs]) ([通知 docs]) ([传感器.netgear\_lte docs][传感器.netgear_lte docs]) * Improve opentherm\_gw 状态 detection ([@mvn23] - [#16809]) ([温控.opentherm\_gw docs][温控.opentherm_gw docs]) * Rework chromecast fix ([@awarecan] - [#16804]) ([媒体播放器.cast docs]) * Add linky 传感器 ([@tiste] - [#16468]) (new-platform) * Use pyspcwebgw for SPC component ([@mbrrg] - [#16214]) ([spc docs]) ([alarm\_control\_panel.spc docs][alarm_control_panel.spc docs]) ([binary\_sensor.spc docs][binary_sensor.spc docs]) * Remove discovered MQTT 开关 设备 when discovery topic is cleared ([@emontnemery] - [#16605]) ([MQTT docs]) ([开关.MQTT docs]) * Allow split component definitions in packages ([@thomasloven] - [#16177]) * Add 通知 MFA module ([@awarecan] - [#16314]) * Broadlink 服务 name ([@Danielhiversen] - [#16345]) ([开关.broadlink docs]) * Add Python 3.7 classifier ([@scop] - [#16645]) * Allow soundtouch to play https content too ([@robin13] - [#16713]) ([媒体播放器.soundtouch docs]) * Fix some unhandled exceptions due to missing null checks ([@OverloadUT] - [#16812]) ([遮盖.isy994 docs]) ([灯光.isy994 docs]) * Don't warn but info when on dev mode ([@balloob] - [#16831]) ([updater docs]) (beta fix) * Bump zm-py to 0.0.3 ([@rohankapoorcom] - [#16835]) ([zoneminder docs]) (beta fix) * Support old tradfri config format ([@balloob] - [#16841]) ([tradfri docs]) (beta fix) * Allow MQTT discovery ([@balloob] - [#16842]) ([MQTT docs]) (beta fix) * Add unique ID and 设备 info to Nest 摄像头 ([@balloob] - [#16846]) ([摄像头.nest docs]) (beta fix) * 设备 Registry Support for iOS 传感器 ([@cgarwood] - [#16862]) ([传感器.ios docs]) (beta fix) * Fix MQTT discovery ([@balloob] - [#16864]) ([MQTT docs]) (beta fix) * Make ring sync again ([@balloob] - [#16866]) ([摄像头.ring docs]) (beta fix) * Add unique\_id to Nest 传感器 ([@cgarwood] - [#16869]) ([binary\_sensor.nest docs][binary_sensor.nest docs]) ([传感器.nest docs]) (beta fix) * Prevent discovered Tradfri while already configured ([@balloob] - [#16891]) ([tradfri docs]) (beta fix) * Handle exception handling websocket command ([@balloob] - [#16927]) ([websocket\_api docs][websocket_api docs]) (beta fix) [#14484]: https://github.com/home-assistant/home-assistant/pull/14484 [#14550]: https://github.com/home-assistant/home-assistant/pull/14550 [#14579]: https://github.com/home-assistant/home-assistant/pull/14579 [#16177]: https://github.com/home-assistant/home-assistant/pull/16177 [#16214]: https://github.com/home-assistant/home-assistant/pull/16214 [#16243]: https://github.com/home-assistant/home-assistant/pull/16243 [#16314]: https://github.com/home-assistant/home-assistant/pull/16314 [#16345]: https://github.com/home-assistant/home-assistant/pull/16345 [#16353]: https://github.com/home-assistant/home-assistant/pull/16353 [#16393]: https://github.com/home-assistant/home-assistant/pull/16393 [#16395]: https://github.com/home-assistant/home-assistant/pull/16395 [#16420]: https://github.com/home-assistant/home-assistant/pull/16420 [#16426]: https://github.com/home-assistant/home-assistant/pull/16426 [#16442]: https://github.com/home-assistant/home-assistant/pull/16442 [#16445]: https://github.com/home-assistant/home-assistant/pull/16445 [#16464]: https://github.com/home-assistant/home-assistant/pull/16464 [#16468]: https://github.com/home-assistant/home-assistant/pull/16468 [#16479]: https://github.com/home-assistant/home-assistant/pull/16479 [#16485]: https://github.com/home-assistant/home-assistant/pull/16485 [#16487]: https://github.com/home-assistant/home-assistant/pull/16487 [#16489]: https://github.com/home-assistant/home-assistant/pull/16489 [#16498]: https://github.com/home-assistant/home-assistant/pull/16498 [#16503]: https://github.com/home-assistant/home-assistant/pull/16503 [#16512]: https://github.com/home-assistant/home-assistant/pull/16512 [#16520]: https://github.com/home-assistant/home-assistant/pull/16520 [#16522]: https://github.com/home-assistant/home-assistant/pull/16522 [#16527]: https://github.com/home-assistant/home-assistant/pull/16527 [#16540]: https://github.com/home-assistant/home-assistant/pull/16540 [#16547]: https://github.com/home-assistant/home-assistant/pull/16547 [#16551]: https://github.com/home-assistant/home-assistant/pull/16551 [#16553]: https://github.com/home-assistant/home-assistant/pull/16553 [#16555]: https://github.com/home-assistant/home-assistant/pull/16555 [#16563]: https://github.com/home-assistant/home-assistant/pull/16563 [#16565]: https://github.com/home-assistant/home-assistant/pull/16565 [#16569]: https://github.com/home-assistant/home-assistant/pull/16569 [#16570]: https://github.com/home-assistant/home-assistant/pull/16570 [#16571]: https://github.com/home-assistant/home-assistant/pull/16571 [#16579]: https://github.com/home-assistant/home-assistant/pull/16579 [#16580]: https://github.com/home-assistant/home-assistant/pull/16580 [#16582]: https://github.com/home-assistant/home-assistant/pull/16582 [#16588]: https://github.com/home-assistant/home-assistant/pull/16588 [#16590]: https://github.com/home-assistant/home-assistant/pull/16590 [#16591]: https://github.com/home-assistant/home-assistant/pull/16591 [#16594]: https://github.com/home-assistant/home-assistant/pull/16594 [#16597]: https://github.com/home-assistant/home-assistant/pull/16597 [#16598]: https://github.com/home-assistant/home-assistant/pull/16598 [#16599]: https://github.com/home-assistant/home-assistant/pull/16599 [#16601]: https://github.com/home-assistant/home-assistant/pull/16601 [#16602]: https://github.com/home-assistant/home-assistant/pull/16602 [#16603]: https://github.com/home-assistant/home-assistant/pull/16603 [#16605]: https://github.com/home-assistant/home-assistant/pull/16605 [#16609]: https://github.com/home-assistant/home-assistant/pull/16609 [#16610]: https://github.com/home-assistant/home-assistant/pull/16610 [#16617]: https://github.com/home-assistant/home-assistant/pull/16617 [#16618]: https://github.com/home-assistant/home-assistant/pull/16618 [#16619]: https://github.com/home-assistant/home-assistant/pull/16619 [#16621]: https://github.com/home-assistant/home-assistant/pull/16621 [#16622]: https://github.com/home-assistant/home-assistant/pull/16622 [#16624]: https://github.com/home-assistant/home-assistant/pull/16624 [#16625]: https://github.com/home-assistant/home-assistant/pull/16625 [#16626]: https://github.com/home-assistant/home-assistant/pull/16626 [#16627]: https://github.com/home-assistant/home-assistant/pull/16627 [#16628]: https://github.com/home-assistant/home-assistant/pull/16628 [#16633]: https://github.com/home-assistant/home-assistant/pull/16633 [#16636]: https://github.com/home-assistant/home-assistant/pull/16636 [#16637]: https://github.com/home-assistant/home-assistant/pull/16637 [#16645]: https://github.com/home-assistant/home-assistant/pull/16645 [#16646]: https://github.com/home-assistant/home-assistant/pull/16646 [#16649]: https://github.com/home-assistant/home-assistant/pull/16649 [#16650]: https://github.com/home-assistant/home-assistant/pull/16650 [#16651]: https://github.com/home-assistant/home-assistant/pull/16651 [#16652]: https://github.com/home-assistant/home-assistant/pull/16652 [#16654]: https://github.com/home-assistant/home-assistant/pull/16654 [#16655]: https://github.com/home-assistant/home-assistant/pull/16655 [#16656]: https://github.com/home-assistant/home-assistant/pull/16656 [#16659]: https://github.com/home-assistant/home-assistant/pull/16659 [#16664]: https://github.com/home-assistant/home-assistant/pull/16664 [#16665]: https://github.com/home-assistant/home-assistant/pull/16665 [#16669]: https://github.com/home-assistant/home-assistant/pull/16669 [#16673]: https://github.com/home-assistant/home-assistant/pull/16673 [#16674]: https://github.com/home-assistant/home-assistant/pull/16674 [#16681]: https://github.com/home-assistant/home-assistant/pull/16681 [#16683]: https://github.com/home-assistant/home-assistant/pull/16683 [#16688]: https://github.com/home-assistant/home-assistant/pull/16688 [#16699]: https://github.com/home-assistant/home-assistant/pull/16699 [#16709]: https://github.com/home-assistant/home-assistant/pull/16709 [#16710]: https://github.com/home-assistant/home-assistant/pull/16710 [#16713]: https://github.com/home-assistant/home-assistant/pull/16713 [#16718]: https://github.com/home-assistant/home-assistant/pull/16718 [#16721]: https://github.com/home-assistant/home-assistant/pull/16721 [#16723]: https://github.com/home-assistant/home-assistant/pull/16723 [#16727]: https://github.com/home-assistant/home-assistant/pull/16727 [#16729]: https://github.com/home-assistant/home-assistant/pull/16729 [#16731]: https://github.com/home-assistant/home-assistant/pull/16731 [#16734]: https://github.com/home-assistant/home-assistant/pull/16734 [#16736]: https://github.com/home-assistant/home-assistant/pull/16736 [#16737]: https://github.com/home-assistant/home-assistant/pull/16737 [#16743]: https://github.com/home-assistant/home-assistant/pull/16743 [#16744]: https://github.com/home-assistant/home-assistant/pull/16744 [#16752]: https://github.com/home-assistant/home-assistant/pull/16752 [#16753]: https://github.com/home-assistant/home-assistant/pull/16753 [#16757]: https://github.com/home-assistant/home-assistant/pull/16757 [#16758]: https://github.com/home-assistant/home-assistant/pull/16758 [#16759]: https://github.com/home-assistant/home-assistant/pull/16759 [#16760]: https://github.com/home-assistant/home-assistant/pull/16760 [#16761]: https://github.com/home-assistant/home-assistant/pull/16761 [#16768]: https://github.com/home-assistant/home-assistant/pull/16768 [#16769]: https://github.com/home-assistant/home-assistant/pull/16769 [#16776]: https://github.com/home-assistant/home-assistant/pull/16776 [#16778]: https://github.com/home-assistant/home-assistant/pull/16778 [#16779]: https://github.com/home-assistant/home-assistant/pull/16779 [#16780]: https://github.com/home-assistant/home-assistant/pull/16780 [#16789]: https://github.com/home-assistant/home-assistant/pull/16789 [#16795]: https://github.com/home-assistant/home-assistant/pull/16795 [#16799]: https://github.com/home-assistant/home-assistant/pull/16799 [#16800]: https://github.com/home-assistant/home-assistant/pull/16800 [#16803]: https://github.com/home-assistant/home-assistant/pull/16803 [#16804]: https://github.com/home-assistant/home-assistant/pull/16804 [#16805]: https://github.com/home-assistant/home-assistant/pull/16805 [#16806]: https://github.com/home-assistant/home-assistant/pull/16806 [#16809]: https://github.com/home-assistant/home-assistant/pull/16809 [#16812]: https://github.com/home-assistant/home-assistant/pull/16812 [#16831]: https://github.com/home-assistant/home-assistant/pull/16831 [#16835]: https://github.com/home-assistant/home-assistant/pull/16835 [#16841]: https://github.com/home-assistant/home-assistant/pull/16841 [#16842]: https://github.com/home-assistant/home-assistant/pull/16842 [#16846]: https://github.com/home-assistant/home-assistant/pull/16846 [#16862]: https://github.com/home-assistant/home-assistant/pull/16862 [#16864]: https://github.com/home-assistant/home-assistant/pull/16864 [#16866]: https://github.com/home-assistant/home-assistant/pull/16866 [#16869]: https://github.com/home-assistant/home-assistant/pull/16869 [#16891]: https://github.com/home-assistant/home-assistant/pull/16891 [#16927]: https://github.com/home-assistant/home-assistant/pull/16927 [@Adminiuga]: https://github.com/Adminiuga [@Cereal2nd]: https://github.com/Cereal2nd [@Danielhiversen]: https://github.com/Danielhiversen [@Dullage]: https://github.com/Dullage [@Harvtronix]: https://github.com/Harvtronix [@Kane610]: https://github.com/Kane610 [@OverloadUT]: https://github.com/OverloadUT [@PhracturedBlue]: https://github.com/PhracturedBlue [@abmantis]: https://github.com/abmantis [@amelchio]: https://github.com/amelchio [@awarecan]: https://github.com/awarecan [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@bieniu]: https://github.com/bieniu [@cdce8p]: https://github.com/cdce8p [@cgarwood]: https://github.com/cgarwood [@cgtobi]: https://github.com/cgtobi [@christopheBfr]: https://github.com/christopheBfr [@damarco]: https://github.com/damarco [@danielperna84]: https://github.com/danielperna84 [@dshokouhi]: https://github.com/dshokouhi [@emontnemery]: https://github.com/emontnemery [@evanjd]: https://github.com/evanjd [@exxamalte]: https://github.com/exxamalte [@fabaff]: https://github.com/fabaff [@geekofweek]: https://github.com/geekofweek [@gerard33]: https://github.com/gerard33 [@glpatcern]: https://github.com/glpatcern [@gwww]: https://github.com/gwww [@heythisisnate]: https://github.com/heythisisnate [@hobbypunk90]: https://github.com/hobbypunk90 [@huangyupeng]: https://github.com/huangyupeng [@isonet]: https://github.com/isonet [@jeradM]: https://github.com/jeradM [@kunago]: https://github.com/kunago [@mbrrg]: https://github.com/mbrrg [@mrosseel]: https://github.com/mrosseel [@mvn23]: https://github.com/mvn23 [@mxworm]: https://github.com/mxworm [@nikolaykasyanov]: https://github.com/nikolaykasyanov [@pvizeli]: https://github.com/pvizeli [@reefab]: https://github.com/reefab [@robin13]: https://github.com/robin13 [@rohankapoorcom]: https://github.com/rohankapoorcom [@scop]: https://github.com/scop [@sergeymaysak]: https://github.com/sergeymaysak [@smurfix]: https://github.com/smurfix [@soldag]: https://github.com/soldag [@tadly]: https://github.com/tadly [@thomasloven]: https://github.com/thomasloven [@tiste]: https://github.com/tiste [@tsvi]: https://github.com/tsvi [@vikramgorla]: https://github.com/vikramgorla [@w1ll1am23]: https://github.com/w1ll1am23 [@zoe1337]: https://github.com/zoe1337 [alarm_control_panel.spc docs]: /integrations/spc [alexa docs]: /integrations/alexa/ [apple_tv docs]: /integrations/apple_tv/ [asterisk_mbox docs]: /integrations/asterisk_mbox/ [binary_sensor.deconz docs]: /integrations/deconz#binary-传感器 [binary_sensor.homematicip_cloud docs]: /integrations/homematicip_cloud/ [binary_sensor.nest docs]: /integrations/nest#binary-传感器 [binary_sensor.rest docs]: /integrations/binary_sensor.rest/ [binary_sensor.spc docs]: /integrations/spc#binary-传感器 [binary_sensor.wirelesstag docs]: /integrations/wirelesstag#binary-传感器 [binary_sensor.workday docs]: /integrations/workday [binary_sensor.zha docs]: /integrations/zha [bmw_connected_drive docs]: /integrations/bmw_connected_drive/ [摄像头.axis docs]: /integrations/axis [摄像头.logi_circle docs]: /integrations/logi_circle#摄像头 [摄像头.mjpeg docs]: /integrations/mjpeg [摄像头.MQTT docs]: /integrations/摄像头.MQTT/ [摄像头.nest docs]: /integrations/nest#摄像头 [摄像头.ring docs]: /integrations/ring#摄像头 [摄像头.zoneminder docs]: /integrations/zoneminder#摄像头 [温控.econet docs]: /integrations/econet [温控.opentherm_gw docs]: /integrations/opentherm_gw [温控.wink docs]: /integrations/wink#温控 [cloud docs]: /integrations/cloud/ [config docs]: /integrations/config/ [遮盖 docs]: /integrations/遮盖/ [遮盖.deconz docs]: /integrations/deconz#遮盖 [遮盖.isy994 docs]: /integrations/isy994 [遮盖.myq docs]: /integrations/myq [遮盖.tuya docs]: /integrations/tuya [deconz docs]: /integrations/deconz/ [device_tracker docs]: /integrations/device_tracker/ [ecovacs docs]: /integrations/ecovacs/ [风扇.zha docs]: /integrations/zha [geo_location docs]: /integrations/geo_location/ [google_assistant docs]: /integrations/google_assistant/ [hangouts docs]: /integrations/hangouts/ [hassio docs]: /integrations/hassio/ [homekit docs]: /integrations/homekit/ [homematic docs]: /integrations/homematic/ [homematicip_cloud docs]: /integrations/homematicip_cloud/ [http docs]: /integrations/http/ [huawei_lte docs]: /integrations/huawei_lte/ [ios docs]: /integrations/ios/ [konnected docs]: /integrations/konnected/ [灯光.deconz docs]: /integrations/deconz#灯光 [灯光.isy994 docs]: /integrations/isy994 [灯光.rpi_gpio_pwm docs]: /integrations/rpi_gpio_pwm [灯光.yeelight docs]: /integrations/yeelight [灯光.zha docs]: /integrations/zha [灯光.zwave docs]: /integrations/zwave [logi_circle docs]: /integrations/logi_circle/ [mailbox docs]: /integrations/mailbox/ [mailbox.asterisk_cdr docs]: /integrations/asterisk_cdr [mailbox.asterisk_mbox docs]: /integrations/asterisk_mbox [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.cast docs]: /integrations/cast [媒体播放器.panasonic_viera docs]: /integrations/panasonic_viera [媒体播放器.samsungtv docs]: /integrations/samsungtv [媒体播放器.sonos docs]: /integrations/sonos [媒体播放器.soundtouch docs]: /integrations/soundtouch [媒体播放器.webostv docs]: /integrations/webostv#media-player [MQTT docs]: /integrations/MQTT/ [neato docs]: /integrations/neato/ [netgear_lte docs]: /integrations/netgear_lte/ [通知 docs]: /integrations/通知/ [openuv docs]: /integrations/openuv/ [persistent_notification docs]: /integrations/persistent_notification/ [python_script docs]: /integrations/python_script/ [rachio docs]: /integrations/rachio/ [传感器.airvisual docs]: /integrations/airvisual [传感器.deconz docs]: /integrations/deconz#传感器 [传感器.dyson docs]: /integrations/dyson#传感器 [传感器.homematicip_cloud docs]: /integrations/homematicip_cloud/ [传感器.huawei_lte docs]: /integrations/huawei_lte#传感器 [传感器.ios docs]: /integrations/传感器.ios/ [传感器.jewish_calendar docs]: /integrations/jewish_calendar [传感器.linky docs]: /integrations/linky [传感器.logi_circle docs]: /integrations/logi_circle#传感器 [传感器.nest docs]: /integrations/nest#传感器 [传感器.netdata docs]: /integrations/netdata [传感器.netgear_lte docs]: /integrations/netgear_lte [传感器.qnap docs]: /integrations/qnap [传感器.rest docs]: /integrations/rest [传感器.rmvtransport docs]: /integrations/rmvtransport [传感器.scrape docs]: /integrations/scrape [传感器.shodan docs]: /integrations/shodan [传感器.starlingbank docs]: /integrations/starlingbank [传感器.swiss_public_transport docs]: /integrations/swiss_public_transport [传感器.tahoma docs]: /integrations/tahoma [传感器.tibber docs]: /integrations/tibber#传感器 [传感器.twitch docs]: /integrations/twitch [传感器.velbus docs]: /integrations/velbus [传感器.wirelesstag docs]: /integrations/wirelesstag#传感器 [传感器.zha docs]: /integrations/zha [shiftr docs]: /integrations/shiftr/ [sonos docs]: /integrations/sonos/ [spc docs]: /integrations/spc/ [开关.broadlink docs]: /integrations/broadlink#开关 [开关.deconz docs]: /integrations/deconz#开关 [开关.konnected docs]: /integrations/konnected#开关 [开关.MQTT docs]: /integrations/开关.MQTT/ [开关.switchmate docs]: /integrations/switchmate [开关.wake_on_lan docs]: /integrations/wake_on_lan#开关 [开关.wirelesstag docs]: /integrations/wirelesstag#开关 [开关.zha docs]: /integrations/zha [tahoma docs]: /integrations/tahoma/ [tradfri docs]: /integrations/tradfri/ [updater docs]: /integrations/updater/ [吸尘器.ecovacs docs]: /integrations/ecovacs#吸尘器 [吸尘器.neato docs]: /integrations/neato#吸尘器 [velbus docs]: /integrations/velbus/ [wake_on_lan docs]: /integrations/wake_on_lan/ [websocket_api docs]: /integrations/websocket_api/ [wink docs]: /integrations/wink/ [wirelesstag docs]: /integrations/wirelesstag/ [xiaomi_aqara docs]: /integrations/xiaomi_aqara/ [zha docs]: /integrations/zha/ [zoneminder docs]: /integrations/zoneminder/ --- url: /home-assistant/blog/2018-10-12-release-80.md --- # 0.80:Lovelace 更新、Webhook 与 TRÅDFRI 开关 2018 年 10 月 12 日。Hacktoberfest 进行到第 12 天,各个仓库比以往任何时候都更忙。在主仓库中,43 个打开、104 个关闭。文档团队居然还活着我都很惊讶:26 个打开、234 个关闭。如果你提交的贡献还在等待回复,很可能是因为我们在忙别的事情,或者正在享受来之不易的休息。 好了,新发布来啦,我们带来了一些很酷的内容!先从 [Lovelace UI](/home-assistant/Lovelace) 说起。我们把社区打造的一些自定义卡片集成进了 Lovelace UI,让所有用户都能轻松使用。新增的卡片是 [Gauge][ll-gauge] 和 [传感器][ll-传感器]: [ll-gauge]: /dashboards/gauge/ [ll-传感器]: /dashboards/传感器/ Screenshot of new Gauge and 传感器 卡片 接下来是把数据送进 Home Assistant 的新方式:Webhook。随着认证机制和长期访问令牌的引入,我们发现仅仅为了把一点信息传进 Home Assistant,就要给某个应用完整的 HA 访问权限,依然很麻烦。现在通过 Webhook,我们可以生成几乎不可能被猜中的唯一 URL,而且发送到该 Webhook 的数据只会流向指定的自动化或组件。这个功能既可供组件开发者集成,也可供用户通过新的自动化 [webhook 触发器](/home-assistant/docs/automation/trigger/index.md#webhook-触发器) 使用。

Screenshot of configuring IFTTT 通过集成面板配置 IFTTT。

在设备支持方面,我们为新的 IKEA TRÅDFRI 开关和 Honeywell evohome 控制器(欧洲版)提供了基础支持。如果你想控制泳池,现在也可以通过新的 AquaLogic 集成来实现。 ## 新平台 * GitLab-CI 传感器 集成 addition. ([@DanielWinks] - [#16561]) ([传感器.gitlab\_ci docs][传感器.gitlab_ci docs]) (new-platform) * Add support for Opple 灯光 ([@jedmeng] - [#16765]) ([灯光.opple docs]) (new-platform) * Add (EU-based) Honeywell evohome CH/DHW controller ([@zxdavb] - [#16427]) ([evohome docs]) ([温控.evohome docs]) ([温控.honeywell docs]) (new-platform) * Add Webhook + IFTTT example ([@balloob] - [#16817]) ([ifttt docs]) ([Webhook docs]) (new-platform) * Add basic support for Tradfri 开关 ([@ggravlingen] - [#17007]) ([tradfri docs]) ([开关.tradfri docs]) (new-platform) * Add AquaLogic component ([@swilson] - [#16763]) ([aqualogic docs]) ([传感器.aqualogic docs]) ([开关.aqualogic docs]) (new-platform) * Overhaul of Blink platform ([@fronzbot] - [#16942]) ([blink docs]) ([alarm\_control\_panel.blink docs][alarm_control_panel.blink docs]) ([binary\_sensor.blink docs][binary_sensor.blink docs]) ([摄像头.blink docs]) ([传感器.blink docs]) (breaking change) (new-platform) * Tibber component and 通知 ([@Danielhiversen] - [#17062]) ([通知 docs]) ([tibber docs]) ([传感器.tibber docs]) (breaking change) (new-platform) * Add new component fritzbox binary\_sensor ([@hthiery] - [#17057]) ([fritzbox docs]) ([binary\_sensor.fritzbox docs][binary_sensor.fritzbox docs]) (new-platform) * Add a Webhook 自动化 触发器 ([@balloob] - [#17246]) ([自动化.Webhook docs]) (beta fix) (new-platform) ## 发布 0.80.1 - October 15 * Fix 自动化 editor ([@armills]) * Fix arm/disarm calls. ([@mbrrg] - [#17381]) ([alarm\_control\_panel.spc docs][alarm_control_panel.spc docs]) * Fix hangout.send\_message requiring data key ([@quazzie] - [#17393]) ([hangouts docs]) * Bugfix eventstream with EOF on end ([@pvizeli] - [#17465]) ([api docs]) * Fix websocket API ([@balloob] - [#17471]) ([websocket\_api docs][websocket_api docs]) [#17381]: https://github.com/home-assistant/home-assistant/pull/17381 [#17393]: https://github.com/home-assistant/home-assistant/pull/17393 [#17465]: https://github.com/home-assistant/home-assistant/pull/17465 [#17471]: https://github.com/home-assistant/home-assistant/pull/17471 [@balloob]: https://github.com/balloob [@mbrrg]: https://github.com/mbrrg [@pvizeli]: https://github.com/pvizeli [@quazzie]: https://github.com/quazzie [alarm_control_panel.spc docs]: /integrations/spc [api docs]: /integrations/api/ [hangouts docs]: /integrations/hangouts/ [websocket_api docs]: /integrations/websocket_api/ ## 发布 0.80.2 - October 17 * Lovelace: Fix glance icon not updating * Fix: Connection pool of Request object is smaller than optimal value (8) ([@Anonym-tsk] - [#17483]) ([telegram\_bot docs][telegram_bot docs]) * Blink 更新 - fixes #17316 ([@fronzbot] - [#17538]) ([blink docs]) ([alarm\_control\_panel.blink docs][alarm_control_panel.blink docs]) ([binary\_sensor.blink docs][binary_sensor.blink docs]) ([摄像头.blink docs]) ([传感器.blink docs]) * Home Assistant Cloud: Add another 3 days leeway to give time for payment processing times ([@balloob] - [#17542]) ([cloud docs]) [#17483]: https://github.com/home-assistant/home-assistant/pull/17483 [#17538]: https://github.com/home-assistant/home-assistant/pull/17538 [#17542]: https://github.com/home-assistant/home-assistant/pull/17542 [@Anonym-tsk]: https://github.com/Anonym-tsk [@balloob]: https://github.com/balloob [@fronzbot]: https://github.com/fronzbot [alarm_control_panel.blink docs]: /integrations/blink [binary_sensor.blink docs]: /integrations/blink [blink docs]: /integrations/blink/ [摄像头.blink docs]: /integrations/blink [cloud docs]: /integrations/cloud/ [传感器.blink docs]: /integrations/blink [telegram_bot docs]: /integrations/telegram_bot/ ## 发布 0.80.3 - October 18 * 更新 hangups to 0.4.6 and fix Issue #16593 hangouts reconnects. ([@hobbypunk90] - [#17518]) ([hangouts docs]) * 更新 to async-upnp-client==0.12.5 ([@StevenLooman] - [#17401]) ([upnp docs]) ([媒体播放器.dlna\_dmr docs][媒体播放器.dlna_dmr docs]) * 升级 async\_upnp\_client to 0.12.6 ([@StevenLooman] - [#17560]) ([upnp docs]) ([媒体播放器.dlna\_dmr docs][媒体播放器.dlna_dmr docs]) * 更新 snapcast to 2.0.9 ([@balloob] - [#17573]) ([媒体播放器.snapcast docs]) [#17401]: https://github.com/home-assistant/home-assistant/pull/17401 [#17518]: https://github.com/home-assistant/home-assistant/pull/17518 [#17560]: https://github.com/home-assistant/home-assistant/pull/17560 [#17573]: https://github.com/home-assistant/home-assistant/pull/17573 [@StevenLooman]: https://github.com/StevenLooman [@balloob]: https://github.com/balloob [@hobbypunk90]: https://github.com/hobbypunk90 [hangouts docs]: /integrations/hangouts/ [媒体播放器.dlna_dmr docs]: /integrations/dlna_dmr [媒体播放器.snapcast docs]: /integrations/snapcast [upnp docs]: /integrations/upnp/ ## 新功能 * Add faucet, shower, sprinkler, valve to HomeKit ([@cdce8p] - [#17145]) ([homekit docs]) (new-feature) ## 如果你需要帮助... ...欢迎随时使用我们非常活跃的[论坛](https://community.home-assistant.io/),或加入我们的[聊天频道](https://discord.gg/c5DvZ4e)。发布说明虽然开启了评论,但我们更推荐你使用前面的沟通渠道。谢谢。 ## 问题反馈 遇到了这个发布引入的问题吗?请在我们的 [issue tracker](https://github.com/home-assistant/home-assistant/issues) 中反馈。请确保填写 issue 模板中的所有字段。 ## 不向后兼容的变更 * Add additional Netatmo public data 传感器 ([@GP8x] - [#16671]) ([netatmo docs]) ([传感器.netatmo\_public docs][传感器.netatmo_public docs]) (breaking change) * 开发者 only: we have removed all 服务 助手 (like turn\_on method in 灯光 coponent), as they werent used. ([@cdce8p] - [#16832], [#16879], [#16863], [#16892], [#16920], [#17038], [#17055], [#16917]) * Google Assistant: 配置 has been simplified and relies on HA native OAuth2 flow ([@awarecan] - [#16848]) ([google\_assistant docs][google_assistant docs]) (breaking change) * Rachio component has been modernized. The Rachio component no longer requires you to specify 开关 and binary\_sensor platforms. These platforms will be initialized automatically by the Rachio component. ([@OverloadUT] - [#16911]) ([rachio docs]) ([binary\_sensor.rachio docs][binary_sensor.rachio docs]) ([开关.rachio docs]) (breaking change)

For the end 用户, this means: * Remove 开关 and binary\_sensor entries with platform: rachio * If you configured manual\_run\_mins on the 开关 platform, move that parameter to the rachio: component 配置. * Overhaul of Blink platform ([@fronzbot] - [#16942]) ([blink docs]) ([alarm\_control\_panel.blink docs][alarm_control_panel.blink docs]) ([binary\_sensor.blink docs][binary_sensor.blink docs]) ([摄像头.blink docs]) ([传感器.blink docs]) (breaking change) (new-platform) * No more 通知 传感器, since the Blink API no longer supports it * motion can now be detected either with the blink 传感器 `binary_sensor.blink_nameofcamera_motion_detected` or through a 摄像头's 属性 with the `motion_detected` key. * `blink.snap_picture` 服务 has been renamed to `blink.trigger_camera` * 摄像头 names now prefaced with `blink`, ie. `camera.blink_nameofcamera` * Tibber has moved from 传感器 配置 to component 配置 ([@Danielhiversen] - [#17062]) ([通知 docs]) ([tibber docs]) ([传感器.tibber docs]) (breaking change) (new-platform) * A manually configured Hue component will no longer run a discovery. Set up via config entry if you want to rely on discovery. ([@balloob] - [#17070]) ([hue docs]) (breaking change) ## Beta 修复 * Fix incorrect yaml in hangouts ([@balloob] - [#17169]) (beta fix) * Fix data used for logbook ([@balloob] - [#17172]) ([logbook docs]) (beta fix) * Fix device\_tracker 服务 call & cleanup ([@cdce8p] - [#17173]) ([alert docs]) ([device\_sun\_light\_trigger docs][device_sun_light_trigger docs]) ([device\_tracker docs][device_tracker docs]) ([通知 docs]) ([开关.flux docs]) (beta fix) * Bugfix 开关 flux - 灯光 服务 call ([@cdce8p] - [#17187]) ([开关.flux docs]) (beta fix) * 升级 aiolifx\_effects to 0.2.1 ([@amelchio] - [#17188]) ([灯光.lifx docs]) (beta fix) * Verisure standard config for scan interval ([@persandstrom] - [#17192]) ([verisure docs]) (beta fix) * Init sub-components using global var. ([@mbrrg] - [#17220]) ([spc docs]) ([alarm\_control\_panel.spc docs][alarm_control_panel.spc docs]) ([binary\_sensor.spc docs][binary_sensor.spc docs]) (beta fix) * Prevent accidental 设备 reg override ([@balloob] - [#17136]) (beta fix) * MyQ 遮盖 return unknown 状态 if not available ([@schmittx] - [#17207]) ([遮盖.myq docs]) (beta fix) * Fix potential MQTT discovery race 条件 ([@OttoWinter] - [#17208]) ([MQTT docs]) (beta fix) * Fix SPC ([@balloob] - [#17236]) ([spc docs]) ([alarm\_control\_panel.spc docs][alarm_control_panel.spc docs]) ([binary\_sensor.spc docs][binary_sensor.spc docs]) (beta fix) * Guard for bad 设备 info ([@balloob] - [#17238]) (beta fix) * updated georss-client library to 0.3 ([@exxamalte] - [#17239]) ([传感器.geo\_rss\_events docs][传感器.geo_rss_events docs]) (beta fix) * Add a Webhook 自动化 触发器 ([@balloob] - [#17246]) ([自动化.Webhook docs]) (beta fix) (new-platform) * block external IP ([@balloob] - [#17248]) ([emulated\_hue docs][emulated_hue docs]) (beta fix) * Fix ambient 灯光 状态 of the Philips Eyecare Lamp (Closes: #16269) ([@syssi] - [#17259]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) (beta fix) * Add defaults, fixing #17229 ([@StevenLooman] - [#17261]) ([upnp docs]) (beta fix) * Remove 警告 on 脚本 delay ([@amelchio] - [#17264]) (beta fix) * Hassio auth ([@pvizeli] - [#17274]) ([hassio docs]) (beta fix) (new-platform) * Fix hassio discovery ([@pvizeli] - [#17275]) ([hassio docs]) (beta fix) * fixed 'on\_startup() takes 0 positional arguments but 1 was given' ([@PaulAnnekov] - [#17295]) ([传感器.miflora docs]) (beta fix) * Logbook: filter by 实体 and period ([@Anonym-tsk] - [#17095]) ([logbook docs]) (beta fix) * Fix samsung bug ([@arsaboo] - [#17285]) ([媒体播放器.samsungtv docs]) (beta fix) * Allow tradfri groups for new imported entries ([@MartinHjelmare] - [#17310]) ([tradfri docs]) (beta fix) * Fix auth for hass.io ([@pvizeli] - [#17318]) ([hassio docs]) (beta fix) * Hass.io auth/sso part2 ([@pvizeli] - [#17324]) ([hassio docs]) (beta fix) (new-platform) ## 全部变更 * Add mode (daily/hourly) to darksky ([@randellhodges] - [#16719]) ([天气 docs]) ([天气.darksky docs]) ([天气.openweathermap docs]) * Extract Lovelace to it's own component ([@balloob] - [#16816]) ([前端 docs]) ([Lovelace docs]) * Remove discovered MQTT alarm\_control\_panel 设备 when discovery topic is cleared ([@emontnemery] - [#16825]) ([alarm\_control\_panel.MQTT docs][alarm_control_panel.MQTT docs]) * Remove discovered MQTT 灯光 设备 when discovery topic is cleared ([@emontnemery] - [#16824]) ([灯光.MQTT docs]) * Add unique\_id to homematic\_cloud ([@sander76] - [#16828]) ([homematicip\_cloud docs][homematicip_cloud docs]) * Don't create 实体 registry in tests ([@balloob] - [#16838]) * Add additional Netatmo public data 传感器 ([@GP8x] - [#16671]) ([netatmo docs]) ([传感器.netatmo\_public docs][传感器.netatmo_public docs]) (breaking change) * GitLab-CI 传感器 集成 addition. ([@DanielWinks] - [#16561]) ([传感器.gitlab\_ci docs][传感器.gitlab_ci docs]) (new-platform) * Config entry 更新 data ([@balloob] - [#16843]) * Fix MQTT leaving files behind ([@balloob] - [#16840]) * change unknown to None in Netatmo public ([@Danielhiversen] - [#16845]) ([传感器.netatmo\_public docs][传感器.netatmo_public docs]) * Remove discovered MQTT binary\_sensor 设备 when discovery topic is cleared ([@emontnemery] - [#16826]) ([binary\_sensor.MQTT docs][binary_sensor.MQTT docs]) * On removal, only unload config entry if loaded ([@balloob] - [#16844]) * Add 图像 support to hangouts 通知 ([@quazzie] - [#16560]) ([hangouts docs]) * Remove discovered MQTT 温控 设备 when discovery topic is cleared ([@emontnemery] - [#16856]) ([温控.MQTT docs]) * Fix files left behind ([@balloob] - [#16855]) * Move MQTT discovery removal tests to platform test files ([@emontnemery] - [#16861]) * Remove discovered MQTT 传感器 设备 when discovery topic is cleared ([@emontnemery] - [#16860]) ([传感器.MQTT docs]) * Remove discovered MQTT 门锁 设备 when discovery topic is cleared ([@emontnemery] - [#16859]) ([门锁.MQTT docs]) * Remove discovered MQTT 风扇 设备 when discovery topic is cleared ([@emontnemery] - [#16858]) ([风扇.MQTT docs]) * Remove discovered MQTT 遮盖 设备 when discovery topic is cleared ([@emontnemery] - [#16857]) ([遮盖.MQTT docs]) * Add executor job ([@balloob] - [#16853]) ([Lovelace docs]) * Fail if dirty ([@balloob] - [#16839]) * Add support for Opple 灯光 ([@jedmeng] - [#16765]) ([灯光.opple docs]) (new-platform) * 更新 遮盖 tests ([@cdce8p] - [#16832]) ([遮盖 docs]) (breaking change) * Add missing **init** test files ([@cdce8p] - [#16871]) * Tibber realtime consumption, Tibber pulse ([@Danielhiversen] - [#16870]) ([传感器.tibber docs]) * 升级 to bimmer\_connected 0.5.3 ([@gerard33] - [#16877]) ([bmw\_connected\_drive docs][bmw_connected_drive docs]) ([binary\_sensor.bmw\_connected\_drive docs][binary_sensor.bmw_connected_drive docs]) * aiohttp.ClientSession gets proxy information from HTTP\_PROXY/HTTPS\_PROXY ([@siom79] - [#16874]) * Remove 服务 助手 (3) ([@cdce8p] - [#16879]) ([duckdns docs]) ([google\_assistant docs][google_assistant docs]) ([group docs]) ([homematic docs]) ([image\_processing docs][image_processing docs]) ([input\_boolean docs][input_boolean docs]) ([input\_number docs][input_number docs]) ([input\_select docs][input_select docs]) ([input\_text docs][input_text docs]) (breaking change) * Fix fan\_init test ([@cdce8p] - [#16865]) * Use HA native OAuth2 flow for google assistant components ([@awarecan] - [#16848]) ([google\_assistant docs][google_assistant docs]) (breaking change) * Remove 服务 助手 (2) ([@cdce8p] - [#16863]) ([alarm\_control\_panel docs][alarm_control_panel docs]) ([自动化 docs]) ([摄像头 docs]) ([温控 docs]) ([counter docs]) ([风扇 docs]) (breaking change) * Revert incorrect check ([@balloob] - [#16883]) ([媒体播放器.soundtouch docs]) * Added support for private storage. ([@nickovs] - [#16878]) * Fix example for long-lived access token WS API ([@awarecan] - [#16882]) ([auth docs]) * Add bitwise operations as 模板 助手 ([@blakeblackshear] - [#16833]) * Telegram\_bot polling support proxy\_url and proxy\_params (Fix #15746) ([@Anonym-tsk] - [#16740]) ([telegram\_bot docs][telegram_bot docs]) * 更新 language strings ([@cgtobi] - [#16884]) ([auth docs]) * Don't pass use\_env=True ([@balloob] - [#16896]) * Revert file mode write\_json ([@balloob] - [#16897]) * Remove 服务 助手 (4) ([@cdce8p] - [#16892]) ([门锁 docs]) ([媒体播放器 docs]) ([通知 docs]) ([遥控器 docs]) ([场景 docs]) ([timer docs]) ([吸尘器 docs]) (breaking change) * Remove unused legacy test 助手 methods ([@cdce8p] - [#16893]) * Remove unused import ([@amelchio] - [#16909]) * 升级 aiolifx\_effects to 0.2.0 ([@amelchio] - [#16900]) ([灯光.lifx docs]) * 升级 pysonos to 0.0.3 ([@amelchio] - [#16901]) ([sonos docs]) ([媒体播放器.sonos docs]) * Ignore Xiaomi hub callbacks during 设置 ([@amelchio] - [#16910]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * 更新 new values coming in for dev registry ([@balloob] - [#16852]) * MQTT 灯光 - Do not throw if property is missing from templated MQTT message ([@emontnemery] - [#16720]) ([灯光.MQTT docs]) * Add new 服务 for set/refresh Z-Wave 设备 values ([@blakeblackshear] - [#16638]) ([zwave docs]) * Add (EU-based) Honeywell evohome CH/DHW controller ([@zxdavb] - [#16427]) ([evohome docs]) ([温控.evohome docs]) ([温控.honeywell docs]) (new-platform) * Make MQTT platforms config entries ([@OttoWinter] - [#16904]) ([MQTT docs]) ([传感器.MQTT docs]) * Fix auth redirect ([@balloob] - [#16914]) ([前端 docs]) * Fix MQTT Config Entry Discovery ([@OttoWinter] - [#16919]) ([MQTT docs]) * Remove 服务 助手 (5) ([@cdce8p] - [#16917]) ([config docs]) ([device\_sun\_light\_trigger docs][device_sun_light_trigger docs]) ([灯光 docs]) ([脚本 docs]) ([开关 docs]) ([开关.flux docs]) (breaking change) * Remove 服务 助手 (6) ([@cdce8p] - [#16920]) ([自动化 docs]) ([config docs]) ([device\_tracker docs][device_tracker docs]) ([group docs]) (breaking change) * Rachio component modernization ([@OverloadUT] - [#16911]) ([rachio docs]) ([binary\_sensor.rachio docs][binary_sensor.rachio docs]) ([开关.rachio docs]) (breaking change) * Remove discovered mqtt\_json 灯光 实体 when discovery is cleared ([@OttoWinter] - [#16906]) ([灯光.mqtt\_json docs][灯光.mqtt_json docs]) * Fix race between 脚本 delay and turn\_off ([@amelchio] - [#16923]) * Move more MQTT platforms to config entries ([@OttoWinter] - [#16918]) ([MQTT docs]) ([alarm\_control\_panel.MQTT docs][alarm_control_panel.MQTT docs]) ([binary\_sensor.MQTT docs][binary_sensor.MQTT docs]) ([摄像头.MQTT docs]) ([温控.MQTT docs]) ([遮盖.MQTT docs]) ([灯光.MQTT docs]) ([开关.MQTT docs]) * Add zwave.network\_complete\_some\_dead event ([@janvanhelvoort] - [#16894]) ([zwave docs]) * Convert 风扇 component to config entry ([@OttoWinter] - [#16951]) ([风扇 docs]) * Add unique\_id to MQTT 遮盖 ([@OttoWinter] - [#16950]) ([遮盖.MQTT docs]) * Add unique\_id to MQTT 风扇 ([@OttoWinter] - [#16949]) ([风扇.MQTT docs]) * Add pressure 传感器 设备 class ([@OttoWinter] - [#16965]) ([传感器 docs]) ([传感器.xiaomi\_aqara docs][传感器.xiaomi_aqara docs]) * 升级 pytest to 3.8.1 ([@scop] - [#16980]) * Add Webhook + IFTTT example ([@balloob] - [#16817]) ([ifttt docs]) ([Webhook docs]) (new-platform) * Google Maps supports battery level and charging. ([@htotoo] - [#16969]) ([device\_tracker docs][device_tracker docs]) * Add basic support for Tradfri 开关 ([@ggravlingen] - [#17007]) ([tradfri docs]) ([开关.tradfri docs]) (new-platform) * Homematic cloud 设备 更新 fix ([@sander76] - [#17001]) ([homematicip\_cloud docs][homematicip_cloud docs]) * Async syntax 1, alarm\_control\_panel & 自动化 & binary\_sensor ([@cdce8p] - [#17015]) * Async syntax 2, 摄像头 & 温控 & config ([@cdce8p] - [#17016]) * 更新 Z-Wave 服务 descriptions to point to proper 日志 file ([@cgarwood] - [#17024]) * Async syntax 8/8 ([@cdce8p] - [#17022]) * Async syntax 7, 开关 & tts & 吸尘器 ([@cdce8p] - [#17021]) * Async syntax 6, 传感器 ([@cdce8p] - [#17020]) * Async syntax 5, 灯光 & 门锁 & 遥控器 & 场景 & telegram & 助手 ([@cdce8p] - [#17019]) * Async syntax 4/8 ([@cdce8p] - [#17018]) * Async syntax 3/8 ([@cdce8p] - [#17017]) * Fix MQTT discovery ([@OttoWinter] - [#17004]) ([MQTT docs]) * 升级 huawei-lte-api to 1.0.16 ([@scop] - [#16972]) ([huawei\_lte docs][huawei_lte docs]) * 升级 locationsharinglib to 3.0.3 ([@fabaff] - [#17010]) ([device\_tracker docs][device_tracker docs]) * Break up websocket component ([@balloob] - [#17003]) ([摄像头 docs]) ([config docs]) ([媒体播放器 docs]) ([websocket\_api docs][websocket_api docs]) * :hammer: 更新 错误 ([@timmo001] - [#17029]) ([开关.rest docs]) * Add new 设备 属性 to fritzbox 温控 ([@hthiery] - [#17027]) ([fritzbox docs]) ([温控.fritzbox docs]) * Bump Enphase\_Envoy dependency for older models ([@DavidDeSloovere] - [#17032]) ([传感器.enphase\_envoy docs][传感器.enphase_envoy docs]) * Add Hass.io discovery to MQTT ([@balloob] - [#16962]) ([MQTT docs]) * 更新 coverage to exclude not tested file ([@cdce8p] - [#17039]) * Send headers with REST 开关 GET request ([@andersonshatch] - [#17036]) ([开关.rest docs]) * Async syntax ([@cdce8p] - [#17033]) ([alert docs]) ([binary\_sensor.ffmpeg\_motion docs][binary_sensor.ffmpeg_motion docs]) ([binary\_sensor.ffmpeg\_noise docs][binary_sensor.ffmpeg_noise docs]) ([传感器.mqtt\_room docs][传感器.mqtt_room docs]) * Break up websocket 2 ([@balloob] - [#17028]) * Logbook context ([@balloob] - [#16937]) ([logbook docs]) * Remove 错误 logging when Sonos shuffle\_set is not available ([@amelchio] - [#16921]) ([媒体播放器.sonos docs]) * Fix long 更新 'load\_power' and 'in\_use' for Xiaomi Zegbee Plug ([@Anonym-tsk] - [#16915]) ([开关.xiaomi\_aqara docs][开关.xiaomi_aqara docs]) * Mind the unit system (fixes #16819) ([@fabaff] - [#16823]) ([天气.openweathermap docs]) * Suppress urllib3 header parsing 错误 ([@cgarwood] - [#17042]) ([摄像头.mjpeg docs]) * Support code 7 ([@SNoof85] - [#17047]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) * 更新 pyhomematic to 0.1.50 ([@danielperna84] - [#17048]) ([homematic docs]) * Remove alert 服务 助手 ([@cdce8p] - [#17038]) ([alert docs]) (breaking change) * Add AquaLogic component ([@swilson] - [#16763]) ([aqualogic docs]) ([传感器.aqualogic docs]) ([开关.aqualogic docs]) (new-platform) * 更新 pynetgear to 0.4.2 (fix #14752) ([@MatMaul] - [#17064]) ([device\_tracker docs][device_tracker docs]) * Added working support for private storage ([@nickovs] - [#16903]) * GeoRSS events 传感器 refactored ([@exxamalte] - [#16939]) ([传感器.geo\_rss\_events docs][传感器.geo_rss_events docs]) * Remove 服务 助手 (8) ([@cdce8p] - [#17055]) ([config docs]) ([ffmpeg docs]) ([keyboard docs]) ([logger docs]) ([microsoft\_face docs][microsoft_face docs]) (breaking change) * MJPEG 摄像头 日志 Filter Fixes ([@cgarwood] - [#17050]) ([摄像头.mjpeg docs]) * OpenUV: Fixed issue with missing protection window data ([@bachya] - [#17051]) ([openuv docs]) ([binary\_sensor.openuv docs][binary_sensor.openuv docs]) * async\_create\_task ([@cdce8p] - [#17059]) * De-syncing binary\_sensor.ping ([@thomasloven] - [#17056]) ([binary\_sensor.ping docs][binary_sensor.ping docs]) * Add logging to 灯光 updates ([@balloob] - [#17069]) ([灯光.hue docs]) * Catch possible 错误 from tradfri ([@balloob] - [#17068]) ([tradfri docs]) * Allow no movement in vamera.onvif\_ptz 服务 ([@thomasloven] - [#17065]) ([摄像头.onvif docs]) * 升级 youtube\_dl to 2018.09.26 ([@fabaff] - [#17079]) ([media\_extractor docs][media_extractor docs]) * Overhaul of Blink platform ([@fronzbot] - [#16942]) ([blink docs]) ([alarm\_control\_panel.blink docs][alarm_control_panel.blink docs]) ([binary\_sensor.blink docs][binary_sensor.blink docs]) ([摄像头.blink docs]) ([传感器.blink docs]) (breaking change) (new-platform) * Bump pyenvisalink ([@Cinntax] - [#17086]) ([envisalink docs]) * Async response all the things ([@balloob] - [#17073]) ([config docs]) ([websocket\_api docs][websocket_api docs]) * Add optional headers 配置 for scrape ([@dippysan] - [#17085]) ([传感器.scrape docs]) * Add support for Hass.io discovery feature for 插件 ([@pvizeli] - [#17035]) ([hassio docs]) * Keep the repeat mode when setting Sonos shuffle mode ([@amelchio] - [#17083]) ([媒体播放器.sonos docs]) * Smaller steps for Sonos volume up/down ([@amelchio] - [#17080]) ([媒体播放器.sonos docs]) * Add 天气 条件 code to OpenWeatherMap 传感器 ([@dYalib] - [#17093]) ([传感器.openweathermap docs]) * Adding myself as blink codeowner ([@fronzbot] - [#17096]) * Change Tile icon to view-grid ([@no2chem] - [#17098]) ([device\_tracker docs][device_tracker docs]) * Fix jewish 日历 传感器 with language set to english ([@tsvi] - [#17104]) ([传感器.jewish\_calendar docs][传感器.jewish_calendar docs]) * Fix counter 恢复. ([@mvn23] - [#17101]) ([counter docs]) * Support multiple accounts in Tile, use 设备 identifiers ([@no2chem] - [#17108]) ([device\_tracker.tile docs][device_tracker.tile docs]) * Bumps simplisafe-python to 3.1.2 ([@bachya] - [#16931]) ([alarm\_control\_panel.simplisafe docs][alarm_control_panel.simplisafe docs]) * 升级 pytest to 3.8.2 ([@scop] - [#17125]) * Fix sonos async use ([@MartinHjelmare] - [#17099]) ([媒体播放器.sonos docs]) * Homekit controller reconnect ([@armills] - [#17060]) ([homekit\_controller docs][homekit_controller docs]) * Tibber component and 通知 ([@Danielhiversen] - [#17062]) ([通知 docs]) ([tibber docs]) ([传感器.tibber docs]) (breaking change) (new-platform) * Add time 创建 to persistent 通知. ([@jeradM] - [#17121]) ([persistent\_notification docs][persistent_notification docs]) * Make it easier for auth to consume newer formats ([@balloob] - [#17127]) * Add new component fritzbox binary\_sensor ([@hthiery] - [#17057]) ([fritzbox docs]) ([binary\_sensor.fritzbox docs][binary_sensor.fritzbox docs]) (new-platform) * 更新 xiaomi lib ([@Danielhiversen] - [#17129]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * Add 更新 服务 to Google Travel 传感器 ([@arsaboo] - [#17092]) ([传感器.google\_travel\_time docs][传感器.google_travel_time docs]) * Fix upnp component l10n 错误 ([@awarecan] - [#17132]) ([upnp docs]) * Take timezone into consideration when calulating Zmanim. Partial fix for #16946 ([@tsvi] - [#17131]) ([传感器.jewish\_calendar docs][传感器.jewish_calendar docs]) * Allow config entry 设置 to raise not ready ([@balloob] - [#17135]) * Webhook component - pass headers to Webhook handler ([@kirichkov] - [#17091]) ([Webhook docs]) * Add timeout and fix oscillations on Samsung TV component ([@anapaulagomes] - [#17102]) ([媒体播放器.samsungtv docs]) * Remove discovery ([@balloob] - [#17070]) ([hue docs]) (breaking change) * Bugfix invalid entity\_config parameter HomeKit ([@cdce8p] - [#17143]) ([homekit docs]) * verisure configurable polling ([@persandstrom] - [#17144]) ([verisure docs]) * YesssSMS handling more 错误, 升级 to 版本 0.2.3 ([@flowolf] - [#17052]) ([通知 docs]) * Added OpenUV CODEOWNERS info ([@bachya] - [#17149]) ([openuv docs]) * Fix a typo ([@gerard33] - [#17147]) ([开关.volvooncall docs]) * Cleanly stop tradfri on shutdown ([@lwis] - [#17114]) ([auth docs]) ([tradfri docs]) * Fix zoneminder zms\_url construction ([@rohankapoorcom] - [#17150]) ([zoneminder docs]) * Added 警告 to HomeKit component ([@Julius2342] - [#16807]) ([homekit docs]) * Add faucet, shower, sprinkler, valve to HomeKit ([@cdce8p] - [#17145]) ([homekit docs]) (new-feature) * Fix miflora connection 错误 during platform 设置 ([@PaulAnnekov] - [#16798]) ([传感器.miflora docs]) * Discover Danfoss/devolo RS 房间 传感器 thermostat ([@prophit987] - [#17153]) ([zwave docs]) * @danielhiversen as codeowner for Tibber ([@prophit987] - [#17154]) * Fix incorrect yaml in hangouts ([@balloob] - [#17169]) (beta fix) * Fix data used for logbook ([@balloob] - [#17172]) ([logbook docs]) (beta fix) * Fix device\_tracker 服务 call & cleanup ([@cdce8p] - [#17173]) ([alert docs]) ([device\_sun\_light\_trigger docs][device_sun_light_trigger docs]) ([device\_tracker docs][device_tracker docs]) ([通知 docs]) ([开关.flux docs]) (beta fix) * Bugfix 开关 flux - 灯光 服务 call ([@cdce8p] - [#17187]) ([开关.flux docs]) (beta fix) * 升级 aiolifx\_effects to 0.2.1 ([@amelchio] - [#17188]) ([灯光.lifx docs]) (beta fix) * Verisure standard config for scan interval ([@persandstrom] - [#17192]) ([verisure docs]) (beta fix) * Init sub-components using global var. ([@mbrrg] - [#17220]) ([spc docs]) ([alarm\_control\_panel.spc docs][alarm_control_panel.spc docs]) ([binary\_sensor.spc docs][binary_sensor.spc docs]) (beta fix) * Prevent accidental 设备 reg override ([@balloob] - [#17136]) (beta fix) * MyQ 遮盖 return unknown 状态 if not available ([@schmittx] - [#17207]) ([遮盖.myq docs]) (beta fix) * Fix potential MQTT discovery race 条件 ([@OttoWinter] - [#17208]) ([MQTT docs]) (beta fix) * Fix SPC ([@balloob] - [#17236]) ([spc docs]) ([alarm\_control\_panel.spc docs][alarm_control_panel.spc docs]) ([binary\_sensor.spc docs][binary_sensor.spc docs]) (beta fix) * Guard for bad 设备 info ([@balloob] - [#17238]) (beta fix) * updated georss-client library to 0.3 ([@exxamalte] - [#17239]) ([传感器.geo\_rss\_events docs][传感器.geo_rss_events docs]) (beta fix) * Add a Webhook 自动化 触发器 ([@balloob] - [#17246]) ([自动化.Webhook docs]) (beta fix) (new-platform) * block external IP ([@balloob] - [#17248]) ([emulated\_hue docs][emulated_hue docs]) (beta fix) * Fix ambient 灯光 状态 of the Philips Eyecare Lamp (Closes: #16269) ([@syssi] - [#17259]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) (beta fix) * Add defaults, fixing #17229 ([@StevenLooman] - [#17261]) ([upnp docs]) (beta fix) * Remove 警告 on 脚本 delay ([@amelchio] - [#17264]) (beta fix) * Hassio auth ([@pvizeli] - [#17274]) ([hassio docs]) (beta fix) (new-platform) * Fix hassio discovery ([@pvizeli] - [#17275]) ([hassio docs]) (beta fix) * fixed 'on\_startup() takes 0 positional arguments but 1 was given' ([@PaulAnnekov] - [#17295]) ([传感器.miflora docs]) (beta fix) * Logbook: filter by 实体 and period ([@Anonym-tsk] - [#17095]) ([logbook docs]) (beta fix) * Fix samsung bug ([@arsaboo] - [#17285]) ([媒体播放器.samsungtv docs]) (beta fix) * Allow tradfri groups for new imported entries ([@MartinHjelmare] - [#17310]) ([tradfri docs]) (beta fix) * Fix auth for hass.io ([@pvizeli] - [#17318]) ([hassio docs]) (beta fix) * Hass.io auth/sso part2 ([@pvizeli] - [#17324]) ([hassio docs]) (beta fix) (new-platform) [#16427]: https://github.com/home-assistant/home-assistant/pull/16427 [#16560]: https://github.com/home-assistant/home-assistant/pull/16560 [#16561]: https://github.com/home-assistant/home-assistant/pull/16561 [#16638]: https://github.com/home-assistant/home-assistant/pull/16638 [#16671]: https://github.com/home-assistant/home-assistant/pull/16671 [#16719]: https://github.com/home-assistant/home-assistant/pull/16719 [#16720]: https://github.com/home-assistant/home-assistant/pull/16720 [#16740]: https://github.com/home-assistant/home-assistant/pull/16740 [#16763]: https://github.com/home-assistant/home-assistant/pull/16763 [#16765]: https://github.com/home-assistant/home-assistant/pull/16765 [#16798]: https://github.com/home-assistant/home-assistant/pull/16798 [#16807]: https://github.com/home-assistant/home-assistant/pull/16807 [#16816]: https://github.com/home-assistant/home-assistant/pull/16816 [#16817]: https://github.com/home-assistant/home-assistant/pull/16817 [#16823]: https://github.com/home-assistant/home-assistant/pull/16823 [#16824]: https://github.com/home-assistant/home-assistant/pull/16824 [#16825]: https://github.com/home-assistant/home-assistant/pull/16825 [#16826]: https://github.com/home-assistant/home-assistant/pull/16826 [#16828]: https://github.com/home-assistant/home-assistant/pull/16828 [#16832]: https://github.com/home-assistant/home-assistant/pull/16832 [#16833]: https://github.com/home-assistant/home-assistant/pull/16833 [#16838]: https://github.com/home-assistant/home-assistant/pull/16838 [#16839]: https://github.com/home-assistant/home-assistant/pull/16839 [#16840]: https://github.com/home-assistant/home-assistant/pull/16840 [#16843]: https://github.com/home-assistant/home-assistant/pull/16843 [#16844]: https://github.com/home-assistant/home-assistant/pull/16844 [#16845]: https://github.com/home-assistant/home-assistant/pull/16845 [#16848]: https://github.com/home-assistant/home-assistant/pull/16848 [#16852]: https://github.com/home-assistant/home-assistant/pull/16852 [#16853]: https://github.com/home-assistant/home-assistant/pull/16853 [#16855]: https://github.com/home-assistant/home-assistant/pull/16855 [#16856]: https://github.com/home-assistant/home-assistant/pull/16856 [#16857]: https://github.com/home-assistant/home-assistant/pull/16857 [#16858]: https://github.com/home-assistant/home-assistant/pull/16858 [#16859]: https://github.com/home-assistant/home-assistant/pull/16859 [#16860]: https://github.com/home-assistant/home-assistant/pull/16860 [#16861]: https://github.com/home-assistant/home-assistant/pull/16861 [#16863]: https://github.com/home-assistant/home-assistant/pull/16863 [#16865]: https://github.com/home-assistant/home-assistant/pull/16865 [#16870]: https://github.com/home-assistant/home-assistant/pull/16870 [#16871]: https://github.com/home-assistant/home-assistant/pull/16871 [#16874]: https://github.com/home-assistant/home-assistant/pull/16874 [#16877]: https://github.com/home-assistant/home-assistant/pull/16877 [#16878]: https://github.com/home-assistant/home-assistant/pull/16878 [#16879]: https://github.com/home-assistant/home-assistant/pull/16879 [#16882]: https://github.com/home-assistant/home-assistant/pull/16882 [#16883]: https://github.com/home-assistant/home-assistant/pull/16883 [#16884]: https://github.com/home-assistant/home-assistant/pull/16884 [#16892]: https://github.com/home-assistant/home-assistant/pull/16892 [#16893]: https://github.com/home-assistant/home-assistant/pull/16893 [#16894]: https://github.com/home-assistant/home-assistant/pull/16894 [#16896]: https://github.com/home-assistant/home-assistant/pull/16896 [#16897]: https://github.com/home-assistant/home-assistant/pull/16897 [#16900]: https://github.com/home-assistant/home-assistant/pull/16900 [#16901]: https://github.com/home-assistant/home-assistant/pull/16901 [#16903]: https://github.com/home-assistant/home-assistant/pull/16903 [#16904]: https://github.com/home-assistant/home-assistant/pull/16904 [#16906]: https://github.com/home-assistant/home-assistant/pull/16906 [#16909]: https://github.com/home-assistant/home-assistant/pull/16909 [#16910]: https://github.com/home-assistant/home-assistant/pull/16910 [#16911]: https://github.com/home-assistant/home-assistant/pull/16911 [#16914]: https://github.com/home-assistant/home-assistant/pull/16914 [#16915]: https://github.com/home-assistant/home-assistant/pull/16915 [#16917]: https://github.com/home-assistant/home-assistant/pull/16917 [#16918]: https://github.com/home-assistant/home-assistant/pull/16918 [#16919]: https://github.com/home-assistant/home-assistant/pull/16919 [#16920]: https://github.com/home-assistant/home-assistant/pull/16920 [#16921]: https://github.com/home-assistant/home-assistant/pull/16921 [#16923]: https://github.com/home-assistant/home-assistant/pull/16923 [#16931]: https://github.com/home-assistant/home-assistant/pull/16931 [#16937]: https://github.com/home-assistant/home-assistant/pull/16937 [#16939]: https://github.com/home-assistant/home-assistant/pull/16939 [#16942]: https://github.com/home-assistant/home-assistant/pull/16942 [#16949]: https://github.com/home-assistant/home-assistant/pull/16949 [#16950]: https://github.com/home-assistant/home-assistant/pull/16950 [#16951]: https://github.com/home-assistant/home-assistant/pull/16951 [#16962]: https://github.com/home-assistant/home-assistant/pull/16962 [#16965]: https://github.com/home-assistant/home-assistant/pull/16965 [#16969]: https://github.com/home-assistant/home-assistant/pull/16969 [#16972]: https://github.com/home-assistant/home-assistant/pull/16972 [#16980]: https://github.com/home-assistant/home-assistant/pull/16980 [#17001]: https://github.com/home-assistant/home-assistant/pull/17001 [#17003]: https://github.com/home-assistant/home-assistant/pull/17003 [#17004]: https://github.com/home-assistant/home-assistant/pull/17004 [#17007]: https://github.com/home-assistant/home-assistant/pull/17007 [#17010]: https://github.com/home-assistant/home-assistant/pull/17010 [#17015]: https://github.com/home-assistant/home-assistant/pull/17015 [#17016]: https://github.com/home-assistant/home-assistant/pull/17016 [#17017]: https://github.com/home-assistant/home-assistant/pull/17017 [#17018]: https://github.com/home-assistant/home-assistant/pull/17018 [#17019]: https://github.com/home-assistant/home-assistant/pull/17019 [#17020]: https://github.com/home-assistant/home-assistant/pull/17020 [#17021]: https://github.com/home-assistant/home-assistant/pull/17021 [#17022]: https://github.com/home-assistant/home-assistant/pull/17022 [#17024]: https://github.com/home-assistant/home-assistant/pull/17024 [#17027]: https://github.com/home-assistant/home-assistant/pull/17027 [#17028]: https://github.com/home-assistant/home-assistant/pull/17028 [#17029]: https://github.com/home-assistant/home-assistant/pull/17029 [#17032]: https://github.com/home-assistant/home-assistant/pull/17032 [#17033]: https://github.com/home-assistant/home-assistant/pull/17033 [#17035]: https://github.com/home-assistant/home-assistant/pull/17035 [#17036]: https://github.com/home-assistant/home-assistant/pull/17036 [#17038]: https://github.com/home-assistant/home-assistant/pull/17038 [#17039]: https://github.com/home-assistant/home-assistant/pull/17039 [#17042]: https://github.com/home-assistant/home-assistant/pull/17042 [#17047]: https://github.com/home-assistant/home-assistant/pull/17047 [#17048]: https://github.com/home-assistant/home-assistant/pull/17048 [#17050]: https://github.com/home-assistant/home-assistant/pull/17050 [#17051]: https://github.com/home-assistant/home-assistant/pull/17051 [#17052]: https://github.com/home-assistant/home-assistant/pull/17052 [#17055]: https://github.com/home-assistant/home-assistant/pull/17055 [#17056]: https://github.com/home-assistant/home-assistant/pull/17056 [#17057]: https://github.com/home-assistant/home-assistant/pull/17057 [#17059]: https://github.com/home-assistant/home-assistant/pull/17059 [#17060]: https://github.com/home-assistant/home-assistant/pull/17060 [#17062]: https://github.com/home-assistant/home-assistant/pull/17062 [#17064]: https://github.com/home-assistant/home-assistant/pull/17064 [#17065]: https://github.com/home-assistant/home-assistant/pull/17065 [#17068]: https://github.com/home-assistant/home-assistant/pull/17068 [#17069]: https://github.com/home-assistant/home-assistant/pull/17069 [#17070]: https://github.com/home-assistant/home-assistant/pull/17070 [#17073]: https://github.com/home-assistant/home-assistant/pull/17073 [#17079]: https://github.com/home-assistant/home-assistant/pull/17079 [#17080]: https://github.com/home-assistant/home-assistant/pull/17080 [#17083]: https://github.com/home-assistant/home-assistant/pull/17083 [#17085]: https://github.com/home-assistant/home-assistant/pull/17085 [#17086]: https://github.com/home-assistant/home-assistant/pull/17086 [#17091]: https://github.com/home-assistant/home-assistant/pull/17091 [#17092]: https://github.com/home-assistant/home-assistant/pull/17092 [#17093]: https://github.com/home-assistant/home-assistant/pull/17093 [#17095]: https://github.com/home-assistant/home-assistant/pull/17095 [#17096]: https://github.com/home-assistant/home-assistant/pull/17096 [#17098]: https://github.com/home-assistant/home-assistant/pull/17098 [#17099]: https://github.com/home-assistant/home-assistant/pull/17099 [#17101]: https://github.com/home-assistant/home-assistant/pull/17101 [#17102]: https://github.com/home-assistant/home-assistant/pull/17102 [#17104]: https://github.com/home-assistant/home-assistant/pull/17104 [#17108]: https://github.com/home-assistant/home-assistant/pull/17108 [#17114]: https://github.com/home-assistant/home-assistant/pull/17114 [#17121]: https://github.com/home-assistant/home-assistant/pull/17121 [#17125]: https://github.com/home-assistant/home-assistant/pull/17125 [#17127]: https://github.com/home-assistant/home-assistant/pull/17127 [#17129]: https://github.com/home-assistant/home-assistant/pull/17129 [#17131]: https://github.com/home-assistant/home-assistant/pull/17131 [#17132]: https://github.com/home-assistant/home-assistant/pull/17132 [#17135]: https://github.com/home-assistant/home-assistant/pull/17135 [#17136]: https://github.com/home-assistant/home-assistant/pull/17136 [#17143]: https://github.com/home-assistant/home-assistant/pull/17143 [#17144]: https://github.com/home-assistant/home-assistant/pull/17144 [#17145]: https://github.com/home-assistant/home-assistant/pull/17145 [#17147]: https://github.com/home-assistant/home-assistant/pull/17147 [#17149]: https://github.com/home-assistant/home-assistant/pull/17149 [#17150]: https://github.com/home-assistant/home-assistant/pull/17150 [#17153]: https://github.com/home-assistant/home-assistant/pull/17153 [#17154]: https://github.com/home-assistant/home-assistant/pull/17154 [#17169]: https://github.com/home-assistant/home-assistant/pull/17169 [#17172]: https://github.com/home-assistant/home-assistant/pull/17172 [#17173]: https://github.com/home-assistant/home-assistant/pull/17173 [#17187]: https://github.com/home-assistant/home-assistant/pull/17187 [#17188]: https://github.com/home-assistant/home-assistant/pull/17188 [#17192]: https://github.com/home-assistant/home-assistant/pull/17192 [#17207]: https://github.com/home-assistant/home-assistant/pull/17207 [#17208]: https://github.com/home-assistant/home-assistant/pull/17208 [#17220]: https://github.com/home-assistant/home-assistant/pull/17220 [#17236]: https://github.com/home-assistant/home-assistant/pull/17236 [#17238]: https://github.com/home-assistant/home-assistant/pull/17238 [#17239]: https://github.com/home-assistant/home-assistant/pull/17239 [#17246]: https://github.com/home-assistant/home-assistant/pull/17246 [#17248]: https://github.com/home-assistant/home-assistant/pull/17248 [#17259]: https://github.com/home-assistant/home-assistant/pull/17259 [#17261]: https://github.com/home-assistant/home-assistant/pull/17261 [#17264]: https://github.com/home-assistant/home-assistant/pull/17264 [#17274]: https://github.com/home-assistant/home-assistant/pull/17274 [#17275]: https://github.com/home-assistant/home-assistant/pull/17275 [#17285]: https://github.com/home-assistant/home-assistant/pull/17285 [#17295]: https://github.com/home-assistant/home-assistant/pull/17295 [#17310]: https://github.com/home-assistant/home-assistant/pull/17310 [#17318]: https://github.com/home-assistant/home-assistant/pull/17318 [#17324]: https://github.com/home-assistant/home-assistant/pull/17324 [@Anonym-tsk]: https://github.com/Anonym-tsk [@Cinntax]: https://github.com/Cinntax [@DanielWinks]: https://github.com/DanielWinks [@Danielhiversen]: https://github.com/Danielhiversen [@DavidDeSloovere]: https://github.com/DavidDeSloovere [@GP8x]: https://github.com/GP8x [@Julius2342]: https://github.com/Julius2342 [@MartinHjelmare]: https://github.com/MartinHjelmare [@MatMaul]: https://github.com/MatMaul [@OttoWinter]: https://github.com/OttoWinter [@OverloadUT]: https://github.com/OverloadUT [@PaulAnnekov]: https://github.com/PaulAnnekov [@SNoof85]: https://github.com/SNoof85 [@StevenLooman]: https://github.com/StevenLooman [@amelchio]: https://github.com/amelchio [@anapaulagomes]: https://github.com/anapaulagomes [@andersonshatch]: https://github.com/andersonshatch [@armills]: https://github.com/armills [@arsaboo]: https://github.com/arsaboo [@awarecan]: https://github.com/awarecan [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@blakeblackshear]: https://github.com/blakeblackshear [@cdce8p]: https://github.com/cdce8p [@cgarwood]: https://github.com/cgarwood [@cgtobi]: https://github.com/cgtobi [@danielperna84]: https://github.com/danielperna84 [@dYalib]: https://github.com/dYalib [@dippysan]: https://github.com/dippysan [@emontnemery]: https://github.com/emontnemery [@exxamalte]: https://github.com/exxamalte [@fabaff]: https://github.com/fabaff [@flowolf]: https://github.com/flowolf [@fronzbot]: https://github.com/fronzbot [@gerard33]: https://github.com/gerard33 [@ggravlingen]: https://github.com/ggravlingen [@hthiery]: https://github.com/hthiery [@htotoo]: https://github.com/htotoo [@janvanhelvoort]: https://github.com/janvanhelvoort [@jedmeng]: https://github.com/jedmeng [@jeradM]: https://github.com/jeradM [@kirichkov]: https://github.com/kirichkov [@lwis]: https://github.com/lwis [@mbrrg]: https://github.com/mbrrg [@mvn23]: https://github.com/mvn23 [@nickovs]: https://github.com/nickovs [@no2chem]: https://github.com/no2chem [@persandstrom]: https://github.com/persandstrom [@prophit987]: https://github.com/prophit987 [@pvizeli]: https://github.com/pvizeli [@quazzie]: https://github.com/quazzie [@randellhodges]: https://github.com/randellhodges [@rohankapoorcom]: https://github.com/rohankapoorcom [@sander76]: https://github.com/sander76 [@schmittx]: https://github.com/schmittx [@scop]: https://github.com/scop [@siom79]: https://github.com/siom79 [@swilson]: https://github.com/swilson [@syssi]: https://github.com/syssi [@thomasloven]: https://github.com/thomasloven [@timmo001]: https://github.com/timmo001 [@tsvi]: https://github.com/tsvi [@zxdavb]: https://github.com/zxdavb [alarm_control_panel docs]: /integrations/alarm_control_panel/ [alarm_control_panel.blink docs]: /integrations/blink [alarm_control_panel.MQTT docs]: /integrations/alarm_control_panel.MQTT/ [alarm_control_panel.simplisafe docs]: /integrations/simplisafe [alarm_control_panel.spc docs]: /integrations/spc [alert docs]: /integrations/alert/ [aqualogic docs]: /integrations/aqualogic/ [auth docs]: /integrations/auth/ [自动化 docs]: /integrations/自动化/ [自动化.Webhook docs]: /docs/自动化/触发器/#Webhook-触发器 [binary_sensor.blink docs]: /integrations/blink [binary_sensor.bmw_connected_drive docs]: /integrations/bmw_connected_drive [binary_sensor.ffmpeg_motion docs]: /integrations/ffmpeg_motion/ [binary_sensor.ffmpeg_noise docs]: /integrations/ffmpeg_noise/ [binary_sensor.fritzbox docs]: /integrations/fritzbox [binary_sensor.MQTT docs]: /integrations/binary_sensor.MQTT/ [binary_sensor.openuv docs]: /integrations/openuv [binary_sensor.ping docs]: /integrations/ping#binary-传感器 [binary_sensor.rachio docs]: /integrations/rachio [binary_sensor.spc docs]: /integrations/spc#binary-传感器 [blink docs]: /integrations/blink/ [bmw_connected_drive docs]: /integrations/bmw_connected_drive/ [摄像头 docs]: /integrations/摄像头/ [摄像头.blink docs]: /integrations/blink [摄像头.mjpeg docs]: /integrations/mjpeg [摄像头.MQTT docs]: /integrations/摄像头.MQTT/ [摄像头.onvif docs]: /integrations/onvif [温控 docs]: /integrations/温控/ [温控.evohome docs]: /integrations/evohome [温控.fritzbox docs]: /integrations/fritzbox [温控.honeywell docs]: /integrations/honeywell [温控.MQTT docs]: /integrations/温控.MQTT/ [config docs]: /integrations/config/ [counter docs]: /integrations/counter/ [遮盖 docs]: /integrations/遮盖/ [遮盖.MQTT docs]: /integrations/遮盖.MQTT/ [遮盖.myq docs]: /integrations/myq [device_sun_light_trigger docs]: /integrations/device_sun_light_trigger/ [device_tracker docs]: /integrations/device_tracker/ [device_tracker.tile docs]: /integrations/tile [duckdns docs]: /integrations/duckdns/ [emulated_hue docs]: /integrations/emulated_hue/ [envisalink docs]: /integrations/envisalink/ [evohome docs]: /integrations/evohome/ [风扇 docs]: /integrations/风扇/ [风扇.MQTT docs]: /integrations/风扇.MQTT/ [ffmpeg docs]: /integrations/ffmpeg/ [fritzbox docs]: /integrations/fritzbox/ [前端 docs]: /integrations/frontend/ [google_assistant docs]: /integrations/google_assistant/ [group docs]: /integrations/group/ [hangouts docs]: /integrations/hangouts/ [hassio docs]: /integrations/hassio/ [homekit docs]: /integrations/homekit/ [homekit_controller docs]: /integrations/homekit_controller/ [homematic docs]: /integrations/homematic/ [homematicip_cloud docs]: /integrations/homematicip_cloud/ [huawei_lte docs]: /integrations/huawei_lte/ [hue docs]: /integrations/hue/ [ifttt docs]: /integrations/ifttt/ [image_processing docs]: /integrations/image_processing/ [input_boolean docs]: /integrations/input_boolean/ [input_number docs]: /integrations/input_number/ [input_select docs]: /integrations/input_select/ [input_text docs]: /integrations/input_text/ [keyboard docs]: /integrations/keyboard/ [灯光 docs]: /integrations/灯光/ [灯光.hue docs]: /integrations/hue [灯光.lifx docs]: /integrations/lifx [灯光.MQTT docs]: /integrations/灯光.MQTT/ [灯光.mqtt_json docs]: /integrations/灯光.MQTT [灯光.opple docs]: /integrations/opple [灯光.xiaomi_miio docs]: /integrations/灯光.xiaomi_miio/ [门锁 docs]: /integrations/门锁/ [门锁.MQTT docs]: /integrations/门锁.MQTT/ [logbook docs]: /integrations/logbook/ [logger docs]: /integrations/logger/ [Lovelace docs]: /integrations/Lovelace/ [media_extractor docs]: /integrations/media_extractor/ [媒体播放器 docs]: /integrations/媒体播放器/ [媒体播放器.samsungtv docs]: /integrations/samsungtv [媒体播放器.sonos docs]: /integrations/sonos [媒体播放器.soundtouch docs]: /integrations/soundtouch [microsoft_face docs]: /integrations/microsoft_face/ [MQTT docs]: /integrations/MQTT/ [netatmo docs]: /integrations/netatmo/ [通知 docs]: /integrations/通知/ [onboarding docs]: /integrations/onboarding/ [openuv docs]: /integrations/openuv/ [persistent_notification docs]: /integrations/persistent_notification/ [rachio docs]: /integrations/rachio/ [遥控器 docs]: /integrations/遥控器/ [场景 docs]: /integrations/场景/ [脚本 docs]: /integrations/脚本/ [传感器 docs]: /integrations/传感器/ [传感器.aqualogic docs]: /integrations/aqualogic#传感器 [传感器.blink docs]: /integrations/blink [传感器.enphase_envoy docs]: /integrations/enphase_envoy [传感器.geo_rss_events docs]: /integrations/geo_rss_events [传感器.gitlab_ci docs]: /integrations/gitlab_ci [传感器.google_travel_time docs]: /integrations/google_travel_time [传感器.jewish_calendar docs]: /integrations/jewish_calendar [传感器.miflora docs]: /integrations/miflora [传感器.MQTT docs]: /integrations/传感器.MQTT/ [传感器.mqtt_room docs]: /integrations/mqtt_room [传感器.netatmo_public docs]: /integrations/netatmo/#传感器 [传感器.openweathermap docs]: /integrations/openweathermap#传感器 [传感器.scrape docs]: /integrations/scrape [传感器.tibber docs]: /integrations/tibber#传感器 [传感器.xiaomi_aqara docs]: /integrations/传感器.xiaomi_aqara/ [sonos docs]: /integrations/sonos/ [spc docs]: /integrations/spc/ [开关 docs]: /integrations/开关/ [开关.aqualogic docs]: /integrations/aqualogic#开关 [开关.flux docs]: /integrations/flux [开关.MQTT docs]: /integrations/开关.MQTT/ [开关.rachio docs]: /integrations/rachio#开关 [开关.rest docs]: /integrations/开关.rest/ [开关.tradfri docs]: /integrations/tradfri [开关.volvooncall docs]: /integrations/volvooncall [开关.xiaomi_aqara docs]: /integrations/开关.xiaomi_aqara/ [telegram_bot docs]: /integrations/telegram_bot/ [tibber docs]: /integrations/tibber/ [timer docs]: /integrations/timer/ [tradfri docs]: /integrations/tradfri/ [upnp docs]: /integrations/upnp/ [吸尘器 docs]: /integrations/吸尘器/ [吸尘器.xiaomi_miio docs]: /integrations/吸尘器.xiaomi_miio/ [verisure docs]: /integrations/verisure/ [天气 docs]: /integrations/天气/ [天气.darksky docs]: /integrations/天气.darksky/ [天气.openweathermap docs]: /integrations/openweathermap#天气 [Webhook docs]: /integrations/Webhook/ [websocket_api docs]: /integrations/websocket_api/ [xiaomi_aqara docs]: /integrations/xiaomi_aqara/ [zoneminder docs]: /integrations/zoneminder/ [zwave docs]: /integrations/zwave/ --- url: /home-assistant/blog/2018-10-29-release-81.md --- # 0.81:全新 Lovelace 卡片、LG Soundbar、Dyson 风扇与 Elk-M1 这次发布是一个重要里程碑——过去两周里有 100 位贡献者参与。非常感谢每一位做出贡献的人,无论是老朋友还是第一次参与的新朋友。 随着配置条目支持的到来,MQTT 现在也已集成设备注册表。LIFX、SimpliSafe 和 Z-Wave 也不甘落后,它们同样同时获得了设备注册表支持和配置条目支持。 Lovelace 又新增了三张卡片:报警面板卡片、按钮卡片和恒温器卡片:

Screenshot of the thermostat 卡片 恒温器卡片截图。

现在 glance 卡片和按钮卡片也可以应用主题了,同时 glance 卡片的列布局方式也发生了变化。此外还加入了长按支持、自定义 UI 支持等更多改进(没错,这个版本 Lovelace 真是备受关爱)。 另外还有几件值得注意的事: * 我们新增了 `homeassistant.update_entity` 服务,可主动请求更新某个实体,而不必等到下一次计划更新。这意味着你可以在 [platform\_options][platform_options] 中设置更长的 `scan_interval`,然后按需更新,非常适合 API 调用额度较低的服务。 * 如果我们在模板中找不到相关实体,模板传感器将不再自动更新。你可能需要检查自己的模板传感器,考虑添加相关的 `entity_id` 条目,或使用新的 `homeassistant.update_entity` 服务。 * 热水器现在有了独立于 `climate` 的平台,毕竟你不是住在热水箱里的鱼。 ## 新平台 * Add support for ElkM1 报警/自动化 面板 ([@gwww] - [#16952]) ([elkm1 docs]) ([alarm\_control\_panel.elkm1 docs][alarm_control_panel.elkm1 docs]) (new-platform) * 热水器 support ([@w1ll1am23] - [#17058]) ([water\_heater docs][water_heater docs]) (new-platform) * Thermoworks Smoke 传感器 ([@nhorvath] - [#16139]) ([传感器.thermoworks\_smoke docs][传感器.thermoworks_smoke docs]) (new-platform) * Swedish 天气 institute 天气 component ([@helto4real] - [#16717]) ([smhi docs]) ([天气 docs]) ([天气.smhi docs]) (new-platform) * Added lumitek/ankuoo recswitch component ([@marcolertora] - [#15764]) ([开关.recswitch docs]) (new-platform) * Rewrite opentherm\_gw to a component ([@mvn23] - [#17133]) ([opentherm\_gw docs][opentherm_gw docs]) ([温控.opentherm\_gw docs][温控.opentherm_gw docs]) (breaking change) (new-platform) * Add Verizon Fios Quantum Gateway device\_tracker platform ([@cisasteelersfan] - [#17023]) ([device\_tracker docs][device_tracker docs]) (new-platform) * Add Elk-M1 开关 and 场景 platforms ([@gwww] - [#17256]) ([elkm1 docs]) ([开关.elkm1 docs]) (new-platform) * Transport NSW ([@Dav0815] - [#17242]) ([传感器.transport\_nsw docs][传感器.transport_nsw docs]) (new-platform) * 模板 门锁 ([@Anonym-tsk] - [#17288]) ([门锁.模板 docs]) (new-platform) * 通知.homematic ([@siom79] - [#16973]) ([通知 docs]) (new-platform) * Add AWS Route53 Dynamic DNS support ([@keirans] - [#17072]) ([route53 docs]) (new-platform) * NSW Rural Fire 服务 platform ([@exxamalte] - [#16802]) ([geo\_location docs][geo_location docs]) (new-platform) * Mill 温控 设备 ([@Danielhiversen] - [#17313]) ([温控.mill docs]) (new-platform) * Add support for LG soundbars ([@mjg59] - [#17570]) ([媒体播放器.lg\_soundbar docs][媒体播放器.lg_soundbar docs]) (new-platform) * Add binary\_sensor support to RFlink ([@emontnemery] - [#17146]) ([rflink docs]) ([binary\_sensor.rflink docs][binary_sensor.rflink docs]) ([传感器.rflink docs]) (new-platform) * Add 传感器 support to opentherm\_gw ([@mvn23] - [#17314]) ([opentherm\_gw docs][opentherm_gw docs]) ([传感器.opentherm\_gw docs][传感器.opentherm_gw docs]) (new-platform) * Add Elk-M1 传感器 platform ([@gwww] - [#17342]) ([elkm1 docs]) ([传感器.elkm1 docs]) (new-platform) * Add opentherm\_gw 二元sensor support ([@mvn23] - [#17625]) ([opentherm\_gw docs][opentherm_gw docs]) ([binary\_sensor.opentherm\_gw docs][binary_sensor.opentherm_gw docs]) (new-platform) * Add support for Dyson Hot+Cool 风扇 as a 温控 设备 ([@soraxas] - [#14598]) ([dyson docs]) ([温控.dyson docs]) (new-platform) * Add new rtorrent 传感器 ([@terorie] - [#17421]) ([传感器.rtorrent docs]) (new-platform) * Elk-M1 温控 ([@gwww] - [#17679]) ([elkm1 docs]) ([温控.elkm1 docs]) (beta fix) (new-platform) ## 新功能 * Add LogBook support to HomeKit ([@ehendrix23] - [#17180]) ([homekit docs]) ([logbook docs]) (new-feature) * Add water\_heater support to HomeKit ([@cdce8p] - [#17614]) ([homekit docs]) (new-feature) ## 发布 0.81.1 - October 27 * 开关 to using Client from twilio.rest rather than the deleted TwilioRestClient ([@rohankapoorcom] - [#17885]) ([twilio docs]) * Fixes an issue with OpenUV config import failing ([@bachya] - [#17831]) ([openuv docs]) (breaking change) * Allow a list ofr 更新 实体 ([@balloob] - [#17860]) * Move migrate to separate WS command ([@balloob] - [#17890]) ([Lovelace docs]) [#17831]: https://github.com/home-assistant/home-assistant/pull/17831 [#17860]: https://github.com/home-assistant/home-assistant/pull/17860 [#17885]: https://github.com/home-assistant/home-assistant/pull/17885 [#17890]: https://github.com/home-assistant/home-assistant/pull/17890 [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@rohankapoorcom]: https://github.com/rohankapoorcom [Lovelace docs]: /integrations/Lovelace/ [openuv docs]: /integrations/openuv/ [twilio docs]: /integrations/twilio/ ## 发布 0.81.2 - October 29 * Fix controller not being stored when 设置 fails and sequentially fails the retry functionality ([@Kane610] - [#17927]) ([unifi docs]) * Pass hass\_config to load\_platform ([@balloob] - [#17952]) * 更新 requests to 2.20.0 ([@balloob] - [#17978]) * Don't use keyset ([@balloob] - [#17984]) ([cloud docs]) [#17927]: https://github.com/home-assistant/home-assistant/pull/17927 [#17952]: https://github.com/home-assistant/home-assistant/pull/17952 [#17978]: https://github.com/home-assistant/home-assistant/pull/17978 [#17984]: https://github.com/home-assistant/home-assistant/pull/17984 [@Kane610]: https://github.com/Kane610 [@balloob]: https://github.com/balloob [cloud docs]: /integrations/cloud/ [unifi docs]: /integrations/unifi/ *0.81.3 已跳过,因为它会破坏 LL。* ## 发布 0.81.4 - November 2 * fix naming bug ([@helto4real] - [#17976]) ([天气.smhi docs]) * Konnected: Pass hass\_config to load\_platform ([@heythisisnate] - [#18027]) ([konnected docs]) * Change cv.string to \[cv.string] ([@awarecan] - [#18050]) ([nest docs]) * Revert HomeKit 更新 to 2.2.2 ([@cdce8p] - [#18069]) ([homekit docs]) * Fix time 区域 for flux 开关 ([@amelchio] - [#18102]) ([开关.flux docs]) * Bunch of 前端 fixes ([link](https://github.com/home-assistant/home-assistant-polymer/releases/tag/20181026.2)) * 升级 pyipma [#17976]: https://github.com/home-assistant/home-assistant/pull/17976 [#18027]: https://github.com/home-assistant/home-assistant/pull/18027 [#18050]: https://github.com/home-assistant/home-assistant/pull/18050 [#18069]: https://github.com/home-assistant/home-assistant/pull/18069 [#18102]: https://github.com/home-assistant/home-assistant/pull/18102 [@amelchio]: https://github.com/amelchio [@awarecan]: https://github.com/awarecan [@cdce8p]: https://github.com/cdce8p [@helto4real]: https://github.com/helto4real [@heythisisnate]: https://github.com/heythisisnate [homekit docs]: /integrations/homekit/ [konnected docs]: /integrations/konnected/ [nest docs]: /integrations/nest/ [开关.flux docs]: /integrations/flux [天气.smhi docs]: /integrations/smhi ## 发布 0.81.5 - November 3 * Fix Lovelace * Remove FFmpeg input tests (@jjlawren - #18131) ## 发布 0.81.6 - November 4 * Bugfix discovery (delete/MQTT) call for Hass.io #18159 ## 如果你需要帮助... ...欢迎随时使用我们非常活跃的[论坛](https://community.home-assistant.io/),或加入我们的[聊天频道](https://discord.gg/c5DvZ4e)。发布说明虽然开启了评论,但我们更推荐你使用前面的沟通渠道。谢谢。 ## 问题反馈 遇到了这个发布引入的问题吗?请在我们的 [issue tracker](https://github.com/home-assistant/home-assistant/issues) 中反馈。请确保填写 issue 模板中的所有字段。 ## 不向后兼容的变更 * LIFX can now be configured from the 集成 page in the config 面板 and advanced 配置 is available through the `lifx:` component 配置. Configuring LIFX via 灯光 platform config no longer works. ([@amelchio] - [#17201]) ([lifx docs]) ([灯光.lifx docs]) (breaking change) * Daikin 温控 now follows the official operating modes, making it compatible with Google Assistant, Alexa and HomeKit. ([@MatteGary] - [#16913]) ([温控.daikin docs]) (breaking change) * Rewrite opentherm\_gw to a component. This changes the config. ([@mvn23] - [#17133]) ([opentherm\_gw docs][opentherm_gw docs]) ([温控.opentherm\_gw docs][温控.opentherm_gw docs]) (breaking change) (new-platform) * 模板 传感器 for which we could not determine what 状态 to track to re-render will now only be updated when manually refreshed using the new `homeassistant.update_entity` 服务. ([@balloob] - [#17276]) ([传感器.模板 docs]) (breaking change) * Changed config to make it possible to define multiple Octoprint printers ([@reefab] - [#16519]) ([octoprint docs]) ([binary\_sensor.octoprint docs][binary_sensor.octoprint docs]) ([传感器.octoprint docs]) (breaking change) * SimpliSafe has a new 配置 format ([docs][simplisafe docs]). And instead of defaulting each system's name to "SimpliSafe", the address of the system is used. ([@bachya] - [#17148]) ([simplisafe docs]) ([alarm\_control\_panel.simplisafe docs][alarm_control_panel.simplisafe docs]) (breaking change) * Econet is now part of the new 热水器 component, changing 实体 from `climate.*` to `water_heater.*` ([@w1ll1am23] - [#17322]) ([water\_heater docs][water_heater docs]) (breaking change) * Remove day as a conf option as it's no longer supported ([@kennedyshead] - [#17452]) ([传感器.speedtest docs]) (breaking change) * Wink 热水器 were moved to the new 热水器 implementation. All Wink 热水器 will automatically be moved from 温控.wate\_heater to water\_heater.water\_heater Please 更新 your 配置 to use water\_heater now. ([@w1ll1am23] - [#17504]) ([温控 docs]) ([water\_heater docs][water_heater docs]) ([wink docs]) ([温控.wink docs]) (breaking change) (new-platform) * Toon "comfort" setting is now available as 'auto' instead of 'performance' ([@balloob] - [#17504]) (breaking change) * Removing ryobi gdo as API is no longer available. ([@guillaume1410] - [#17637]) (breaking change) * The way columns are handled in the glance 卡片 has changed ([#1832]) (breaking change) ## Beta 修复 * Geo location 触发器 added ([@exxamalte] - [#16967]) ([自动化.区域 docs]) (beta fix) * Add Lovelace websocket get and set 卡片 ([@bramkragten] - [#17600]) ([Lovelace docs]) (beta fix) * Fixed issue #16903 re exception with multiple simultanious writes ([@nickovs] - [#17636]) (beta fix) * 更新 flux library 版本 ([@oblogic7] - [#17677]) ([灯光.flux\_led docs][灯光.flux_led docs]) (beta fix) * 更新 limitlessled to 1.1.3 ([@amelchio] - [#17703]) ([灯光.limitlessled docs]) (beta fix) * Bug fix for clicksend ([@JaxomCS] - [#17713]) ([通知 docs]) (beta fix) * Elk-M1 温控 ([@gwww] - [#17679]) ([elkm1 docs]) ([温控.elkm1 docs]) (beta fix) (new-platform) * Add 遮盖 to supported platforms ([@cgarwood] - [#17725]) ([zwave docs]) (beta fix) * Lovelace ws: add 卡片 ([@bramkragten] - [#17730]) ([Lovelace docs]) (beta fix) * Remove day (fixes #17741) ([@fabaff] - [#17743]) ([传感器.fastdotcom docs]) (beta fix) * Fixed an incorrect reference in the 实体 registry ([@bachya] - [#17775]) (beta fix) * 更新 HAP-python to 2.3.0 ([@cdce8p] - [#17778]) ([homekit docs]) (beta fix) * SMHI 天气 component not showing correct values in current forecast ([@helto4real] - [#17783]) ([smhi docs]) ([天气.smhi docs]) (beta fix) * Fix unloading an entry can leave 状态 around ([@balloob] - [#17786]) (beta fix) ## 全部变更 * Adding myself as melissa owner ([@kennedyshead] - [#17157]) * 更新 核心, add myself and introduce grouping ([@fabaff] - [#17175]) * Add myself to more 传感器 ([@fabaff] - [#17185]) * 升级 boto3 to 1.9.16 ([@GuyKh] - [#17140]) ([通知 docs]) ([tts docs]) * Fix Todoist custom project 更新 ([@PhilRW] - [#17115]) ([日历.todoist docs]) * vsure 版本 1.5.0 ([@persandstrom] - [#17209]) ([verisure docs]) * Disallow list/dict for string 配置 ([@amelchio] - [#17202]) * Enable new registry rename for Insteon ([@wonderslug] - [#17171]) ([insteon docs]) * Fix aliases support for RFLink 传感器 ([@emontnemery] - [#17190]) ([传感器.rflink docs]) * Add forecast for Met.no ([@Danielhiversen] - [#17109]) ([天气.met docs]) * Add support for ElkM1 报警/自动化 面板 ([@gwww] - [#16952]) ([elkm1 docs]) ([alarm\_control\_panel.elkm1 docs][alarm_control_panel.elkm1 docs]) (new-platform) * Add config entry for LIFX ([@amelchio] - [#17201]) ([lifx docs]) ([灯光.lifx docs]) (breaking change) * danielhiversen as codeowner for met.no ([@Danielhiversen] - [#17232]) * Add some new model names of Xiaomi Aqara 设备 ([@syssi] - [#17234]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) ([binary\_sensor.xiaomi\_aqara docs][binary_sensor.xiaomi_aqara docs]) * Pushed to 版本 0.7.6 of denonavr library to add more sound modes ([@scarface-4711] - [#17227]) ([媒体播放器.denonavr docs]) * Fix data\_key and power\_consumed 属性 of the Aqara Wall 开关 (Closes: #16457) ([@syssi] - [#17235]) ([开关.xiaomi\_aqara docs][开关.xiaomi_aqara docs]) * 热水器 support ([@w1ll1am23] - [#17058]) ([water\_heater docs][water_heater docs]) (new-platform) * Daikin 温控 - Better 集成 with 温控 base component ([@MatteGary] - [#16913]) ([温控.daikin docs]) (breaking change) * Add Support for Xiaomi Vibration 传感器 ([@dlashua] - [#16422]) ([binary\_sensor.xiaomi\_aqara docs][binary_sensor.xiaomi_aqara docs]) ([传感器.xiaomi\_aqara docs][传感器.xiaomi_aqara docs]) * Implement base for MQTT 设备 registry 集成 ([@OttoWinter] - [#16943]) ([MQTT docs]) ([传感器.MQTT docs]) * Add 设备 registry to MQTT 二元sensor ([@OttoWinter] - [#17243]) ([binary\_sensor.MQTT docs][binary_sensor.MQTT docs]) * Add 设备 registry to MQTT 开关 ([@OttoWinter] - [#17244]) ([开关.MQTT docs]) * Convert MQTT 风扇 to config entry ([@OttoWinter] - [#17247]) ([MQTT docs]) ([风扇.MQTT docs]) * Add support for HS color to MQTT 灯光 ([@emontnemery] - [#16958]) ([灯光.MQTT docs]) * emptying 设备 状态 属性 if the 更新 from the feed fails ([@exxamalte] - [#17249]) ([传感器.geo\_rss\_events docs][传感器.geo_rss_events docs]) * Add 设备 registry to MQTT 遮盖 ([@OttoWinter] - [#17245]) ([遮盖.MQTT docs]) * Add group foundation ([@balloob] - [#16935]) ([config docs]) ([websocket\_api docs][websocket_api docs]) * Add Elk 灯光 platform ([@gwww] - [#17222]) ([elkm1 docs]) * Use only\_cache parameter in binary\_sensor.zha.遥控器 ([@damarco] - [#16711]) ([binary\_sensor.zha docs][binary_sensor.zha docs]) * Add configurable temperature step for MQTT 温控 component ([@JariInc] - [#16201]) ([温控 docs]) ([温控.MQTT docs]) * Thermoworks Smoke 传感器 ([@nhorvath] - [#16139]) ([传感器.thermoworks\_smoke docs][传感器.thermoworks_smoke docs]) (new-platform) * Bump python-miio requirement ([@rytilahti] - [#17260]) ([device\_tracker docs][device_tracker docs]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) ([遥控器.xiaomi\_miio docs][遥控器.xiaomi_miio docs]) ([传感器.xiaomi\_miio docs][传感器.xiaomi_miio docs]) ([开关.xiaomi\_miio docs][开关.xiaomi_miio docs]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) * Swedish 天气 institute 天气 component ([@helto4real] - [#16717]) ([smhi docs]) ([天气 docs]) ([天气.smhi docs]) (new-platform) * Add basic support of the Philips Zhirui desk lamp (philips.灯光.mono1) ([@syssi] - [#17258]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) * Added lumitek/ankuoo recswitch component ([@marcolertora] - [#15764]) ([开关.recswitch docs]) (new-platform) * Add 设备 registry to MQTT 风扇 ([@OttoWinter] - [#17250]) ([风扇.MQTT docs]) * Make async\_track\_time\_change smarter ([@OttoWinter] - [#17199]) * Add optional "all" parameter for groups ([@danielperna84] - [#17179]) ([group docs]) * Fix mpd timeout 错误 ([@definitio] - [#17254]) ([媒体播放器.mpd docs]) * Add support for zha custom cluster mappings ([@damarco] - [#16714]) ([zha docs]) ([传感器.zha docs]) * Z-Wave Config Entry Support ([@cgarwood] - [#17119]) ([zwave docs]) * Manual updates ([@balloob] - [#17278]) * Bumped fints component to 版本 1.0.1 ([@mnigbur] - [#17280]) ([传感器.fints docs]) * Fixed Temperature for HMIP-WeatherStation Plus/Basic ([@dickesW] - [#17216]) ([homematic docs]) * Rewrite opentherm\_gw to a component ([@mvn23] - [#17133]) ([opentherm\_gw docs][opentherm_gw docs]) ([温控.opentherm\_gw docs][温控.opentherm_gw docs]) (breaking change) (new-platform) * 升级 shodan to 1.10.4 ([@fabaff] - [#17292]) ([传感器.shodan docs]) * 升级 locationsharinglib to 3.0.6 ([@fabaff] - [#17294]) ([device\_tracker docs][device_tracker docs]) * Add valve level to HmIP thermostat 属性 ([@hanzoh] - [#17297]) ([homematic docs]) * Make rmvtransport async ([@cgtobi] - [#17225]) ([传感器.rmvtransport docs]) * Add Verizon Fios Quantum Gateway device\_tracker platform ([@cisasteelersfan] - [#17023]) ([device\_tracker docs][device_tracker docs]) (new-platform) * Added resolve\_state to 模板 distance function ([@mnigbur] - [#17290]) * Xiaomi 吸尘器: keep 错误 状态 active after erroring ([@rytilahti] - [#16562]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) * Narrow scope of various pylint inline disables ([@scop] - [#15364]) * Fix and clean haveibeenpwned ([@MartinHjelmare] - [#17306]) ([传感器.haveibeenpwned docs]) * 模板 传感器 to not track all 状态 changes ([@balloob] - [#17276]) ([传感器.模板 docs]) (breaking change) * WIP: Don't set initial values for MQTT HVAC in non-optimistic mode ([@definitio] - [#17268]) ([温控.MQTT docs]) * Yamaha AVR 更新 and change Sound Mode only on main\_zone ([@Joshi425] - [#17241]) ([媒体播放器.yamaha docs]) * ABC config entries ([@balloob] - [#17309]) * Add direction 配置 ([@cgtobi] - [#17308]) ([传感器.rmvtransport docs]) * fix\_broadlink\_sp2\_show\_energy ([@zhumuht] - [#17271]) ([开关.broadlink docs]) * Add Elk-M1 开关 and 场景 platforms ([@gwww] - [#17256]) ([elkm1 docs]) ([开关.elkm1 docs]) (new-platform) * 升级 construct to 2.9.45 ([@fabaff] - [#16362]) * 更新 file header ([@fabaff] - [#17317]) ([传感器.gitlab\_ci docs][传感器.gitlab_ci docs]) * Implement ZoneMinder run 状态 ([@rohankapoorcom] - [#17198]) ([zoneminder docs]) ([传感器.zoneminder docs]) * Transport NSW ([@Dav0815] - [#17242]) ([传感器.transport\_nsw docs][传感器.transport_nsw docs]) (new-platform) * Made it possible to define multiple Octoprint printers ([@reefab] - [#16519]) ([octoprint docs]) ([binary\_sensor.octoprint docs][binary_sensor.octoprint docs]) ([传感器.octoprint docs]) (breaking change) * 更新 python\_openzwave==0.4.10 ([@georgemarshall] - [#17323]) ([zwave docs]) * Enable BMW component to be unit system aware ([@uchagani] - [#17197]) ([bmw\_connected\_drive docs][bmw_connected_drive docs]) ([binary\_sensor.bmw\_connected\_drive docs][binary_sensor.bmw_connected_drive docs]) ([传感器.bmw\_connected\_drive docs][传感器.bmw_connected_drive docs]) * still 更新 传感器 on startup ([@balloob] - [#17319]) ([传感器.模板 docs]) * 模板 门锁 ([@Anonym-tsk] - [#17288]) ([门锁.模板 docs]) (new-platform) * Implement turn\_off and turn\_on 动作 for eq3btsmart ([@KarimGeiger] - [#17168]) ([温控.eq3btsmart docs]) * Add 用户 events ([@balloob] - [#17328]) * Add support for off\_delay to MQTT binary\_sensor ([@emontnemery] - [#16993]) ([binary\_sensor.MQTT docs][binary_sensor.MQTT docs]) * Add permissions foundation ([@balloob] - [#16890]) * Bump 版本 of abodepy to 0.14.0 ([@MisterWil] - [#17336]) ([abode docs]) * Fix motion 传感器 in Aqara LAN protocol V2 ([@azuwis] - [#17240]) ([binary\_sensor.xiaomi\_aqara docs][binary_sensor.xiaomi_aqara docs]) * Set botvac availability ([@dshokouhi] - [#17350]) ([吸尘器.neato docs]) * Color control for Abode RGB 灯光 ([@shred86] - [#17347]) ([灯光.abode docs]) * Support abbreviations in discovery topic ([@emontnemery] - [#16635]) ([MQTT docs]) * Add exception handling to dnsip 传感器 ([@danielperna84] - [#17332]) ([传感器.dnsip docs]) * 通知.homematic ([@siom79] - [#16973]) ([通知 docs]) (new-platform) * Provide an individual color temperature range per Yeelight model ([@syssi] - [#17305]) ([灯光.yeelight docs]) * Fix setting opple 灯光 color temperature ([@jedmeng] - [#17359]) ([灯光.opple docs]) * The ping command will not detect 设备 in standby as off ([@kennedyshead] - [#17358]) ([媒体播放器.samsungtv docs]) * Adding source 属性 to geo location platforms ([@exxamalte] - [#17339]) ([geo\_location docs][geo_location docs]) * Add config entry for SimpliSafe ([@bachya] - [#17148]) ([simplisafe docs]) ([alarm\_control\_panel.simplisafe docs][alarm_control_panel.simplisafe docs]) (breaking change) * Added option to use a location other than home ([@TomAFrench] - [#17340]) ([传感器.geo\_rss\_events docs][传感器.geo_rss_events docs]) * Add unique\_id for Lightify ([@dshokouhi] - [#17377]) ([灯光.osramlightify docs]) * Add unique\_id for Neato ([@dshokouhi] - [#17369]) ([摄像头.neato docs]) ([开关.neato docs]) ([吸尘器.neato docs]) * Add unique\_id for Bloomsky ([@dshokouhi] - [#17383]) ([binary\_sensor.bloomsky docs][binary_sensor.bloomsky docs]) ([传感器.bloomsky docs]) * Bump insteonplm 版本 to 0.15.0 ([@teharris1] - [#17384]) ([insteon docs]) * XMPP async ([@flowolf] - [#17283]) ([通知 docs]) * Add unique id to syncthru 传感器 ([@scop] - [#17399]) ([传感器.syncthru docs]) * Add AWS Route53 Dynamic DNS support ([@keirans] - [#17072]) ([route53 docs]) (new-platform) * Added ssl and verify\_ssl parameters in ddwrt 设备 tracker component ([@psyhomb] - [#17406]) ([device\_tracker docs][device_tracker docs]) * homematic: Support additional property for sabotage detection ([@klada] - [#17407]) ([homematic docs]) * Fix netio component ([@J4nsen] - [#17411]) ([开关.netio docs]) * Adding support for HmIP-SLO (outdoor brightness 传感器) ([@noxhirsch] - [#17413]) ([homematic docs]) ([传感器.homematic docs]) * 更新 Vagrant Windows support ([@fredrikbaberg] - [#17205]) * Moved econet from 温控 to 热水器 ([@w1ll1am23] - [#17322]) ([water\_heater docs][water_heater docs]) (breaking change) * Bump Totalconnect ([@333ryan18] - [#17418]) ([alarm\_control\_panel.totalconnect docs][alarm_control_panel.totalconnect docs]) * 升级 pyvera to 0.2.45 ([@brantlk] - [#17419]) ([vera docs]) * NSW Rural Fire 服务 platform ([@exxamalte] - [#16802]) ([geo\_location docs][geo_location docs]) (new-platform) * 升级 python-telegram-bot to 11.1.0 ([@fabaff] - [#17441]) ([telegram\_bot docs][telegram_bot docs]) * Minor updates ([@fabaff] - [#17437]) ([geo\_location docs][geo_location docs]) * Minor updates ([@fabaff] - [#17436]) ([habitica docs]) * 更新 docstrings ([@fabaff] - [#17435]) ([传感器.api\_streams docs][传感器.api_streams docs]) * 升级 numpy to 1.15.2 ([@fabaff] - [#17431]) ([binary\_sensor.trend docs][binary_sensor.trend docs]) ([image\_processing.opencv docs][image_processing.opencv docs]) * 升级 youtube\_dl to 2018.10.05 ([@fabaff] - [#17429]) ([media\_extractor docs][media_extractor docs]) * New 温控 设备 ([@Danielhiversen] - [#17313]) ([温控.mill docs]) (new-platform) * Remove day as a conf option ([@kennedyshead] - [#17452]) ([传感器.speedtest docs]) (breaking change) * Bumped simplisafe-python to 3.1.11 ([@bachya] - [#17454]) ([simplisafe docs]) * 更新 pysher 版本 ([@craigjmidwinter] - [#17455]) ([goalfeed docs]) * Show torah reading during weekdays ([@tsvi] - [#17447]) ([传感器.jewish\_calendar docs][传感器.jewish_calendar docs]) * Fix NoEntitySpecifiedError during knx startup ([@Julius2342] - [#17366]) ([binary\_sensor.knx docs][binary_sensor.knx docs]) ([温控.knx docs]) ([遮盖.knx docs]) ([灯光.knx docs]) ([传感器.knx docs]) ([开关.knx docs]) * refactored to make its code structure similar to nsw\_rural\_fire\_service\_feed platform ([@exxamalte] - [#17461]) ([geo\_location docs][geo_location docs]) * Migrate CONF\_WEBHOOK\_ID to homeassistant.const ([@rohankapoorcom] - [#17460]) ([ifttt docs]) ([自动化.Webhook docs]) * Add RSRQ, RSRP, and SINR to huawei\_lte default 传感器 ([@scop] - [#17425]) ([传感器.huawei\_lte docs][传感器.huawei_lte docs]) * Make dicttoxml logging less verbose ([@scop] - [#17446]) ([huawei\_lte docs][huawei_lte docs]) * Fire an event when timer gets out of sync ([@amelchio] - [#17398]) * Add context to 脚本 run by 模板 实体 ([@balloob] - [#17329]) ([遮盖.模板 docs]) ([风扇.模板 docs]) ([灯光.模板 docs]) ([门锁.模板 docs]) ([开关.模板 docs]) * 状态 is set to UNKNOWN rather than ON in order to make UI have an play/pause 按钮 ([@kennedyshead] - [#17357]) ([媒体播放器.samsungtv docs]) * Re-assign 条件 ([@SilvrrGIT] - [#17364]) * Switched to async\_fire ([@Julius2342] - [#17472]) ([knx docs]) * Fix rangefilter ([@nielstron] - [#17473]) ([传感器.filter docs]) * Cleanup HM 通知 platform ([@pvizeli] - [#17355]) ([通知 docs]) * Refactor RFLink component ([@emontnemery] - [#17402]) ([rflink docs]) ([遮盖.rflink docs]) ([灯光.rflink docs]) ([传感器.rflink docs]) ([开关.rflink docs]) * Include the name of the Volumio media player in 错误 ([@d0ugal] - [#17481]) ([媒体播放器.volumio docs]) * Fix HomeMatic availability detection ([@danielperna84] - [#17341]) ([homematic docs]) * Add 设备 info for LIFX ([@amelchio] - [#17330]) ([灯光.lifx docs]) * 更新 pyhomematic to 0.1.51 ([@danielperna84] - [#17491]) ([homematic docs]) * Clean up OpenUV config flow ([@bachya] - [#17349]) ([openuv docs]) * Fix the sabnzbd component api 错误 ([@arlyon] - [#17014]) ([sabnzbd docs]) * Bumps simplisafe-python to 3.1.12 ([@bachya] - [#17509]) ([simplisafe docs]) * Add unique\_id for Ring ([@dshokouhi] - [#17497]) ([binary\_sensor.ring docs][binary_sensor.ring docs]) ([摄像头.ring docs]) ([传感器.ring docs]) * UniFi POE control ([@Kane610] - [#17011]) ([unifi docs]) ([开关.unifi docs]) * Moved Wink 热水器 from 温控 to 热水器. ([@w1ll1am23] - [#17504]) ([温控 docs]) ([water\_heater docs][water_heater docs]) ([wink docs]) ([温控.wink docs]) (breaking change) (new-platform) * Add LogBook support to HomeKit ([@ehendrix23] - [#17180]) ([homekit docs]) ([logbook docs]) (new-feature) * Bump hdate 版本 to 0.6.5 ([@tsvi] - [#17510]) ([传感器.jewish\_calendar docs][传感器.jewish_calendar docs]) * Z-Wave 设备 Registry Support ([@cgarwood] - [#17291]) ([zwave docs]) ([灯光.zwave docs]) ([传感器.zwave docs]) ([开关.zwave docs]) * Fix unhandled exception which creates many useless 日志 ([@benleb] - [#17508]) ([媒体播放器.horizon docs]) * 更新 mill library ([@Danielhiversen] - [#17520]) ([温控.mill docs]) * 更新 switchmate library ([@Danielhiversen] - [#17519]) * Add unique\_id to Vera 实体 ([@brantlk] - [#17450]) ([vera docs]) * Manual IP & port 配置 for Konnected 设备 ([@heythisisnate] - [#17120]) ([konnected docs]) * Huawei LTE 传感器 improvements ([@scop] - [#17533]) ([传感器.huawei\_lte docs][传感器.huawei_lte docs]) * Tweak 传感器 comments in default config ([@scop] - [#17526]) * Scan all network interfaces for LIFX bulbs ([@amelchio] - [#17530]) ([lifx docs]) ([灯光.lifx docs]) * Remove unnecessary call ([@cgtobi] - [#17514]) ([媒体播放器.volumio docs]) * Adding id to Lovelace 卡片 in ui-Lovelace.yaml ([@bramkragten] - [#17498]) ([Lovelace docs]) * Fix mold\_indicator 错误 at startup ([@ehendrix23] - [#17346]) ([传感器.mold\_indicator docs][传感器.mold_indicator docs]) * Updated package to fix #16960 ([@eavanvalkenburg] - [#17555]) ([通知 docs]) ([媒体播放器.webostv docs]) * Validate ports as a port ([@tjorim] - [#17549]) ([upnp docs]) * danielhiversen as mill codeowner ([@Danielhiversen] - [#17571]) * 升级 twilio package to 版本 6.19.1 (#17395) ([@bgianfo] - [#17424]) ([twilio docs]) * Add support for LG soundbars ([@mjg59] - [#17570]) ([媒体播放器.lg\_soundbar docs][媒体播放器.lg_soundbar docs]) (new-platform) * Fixing race 条件 in geo location platforms ([@exxamalte] - [#17581]) ([geo\_location docs][geo_location docs]) * Fix: Xiaomi Plug 状态 is set twice ([@Anonym-tsk] - [#17482]) ([开关.xiaomi\_aqara docs][开关.xiaomi_aqara docs]) * Bump blinkpy 版本 to 0.10.1 ([@fronzbot] - [#17595]) ([blink docs]) * 升级 pytest to 3.9.1 ([@scop] - [#17598]) * Add binary\_sensor support to RFlink ([@emontnemery] - [#17146]) ([rflink docs]) ([binary\_sensor.rflink docs][binary_sensor.rflink docs]) ([传感器.rflink docs]) (new-platform) * Fix flux 开关 更新 interval ([@amelchio] - [#17458]) ([开关.flux docs]) * Add 传感器 support to opentherm\_gw ([@mvn23] - [#17314]) ([opentherm\_gw docs][opentherm_gw docs]) ([传感器.opentherm\_gw docs][传感器.opentherm_gw docs]) (new-platform) * Add missing await for coroutine ([@jjlawren] - [#17609]) ([摄像头.ffmpeg docs]) * Tuya 灯光 icon fix ([@thomasloven] - [#17605]) ([灯光.tuya docs]) * Add doorsense 传感器 for August 3rd Gen Smart 门锁 Pro ([@ehendrix23] - [#17299]) ([august docs]) ([binary\_sensor.august docs][binary_sensor.august docs]) ([门锁.august docs]) * Bump thermoworks 版本 to fix conflict from upstream pyrebase sseclient ([@nhorvath] - [#17620]) ([传感器.thermoworks\_smoke docs][传感器.thermoworks_smoke docs]) * 升级 async\_upnp\_client to 0.12.7 ([@StevenLooman] - [#17601]) ([upnp docs]) ([媒体播放器.dlna\_dmr docs][媒体播放器.dlna_dmr docs]) * 升级 gstreamer-player to 1.1.2 ([@partofthething] - [#17568]) * Add water\_heater support to HomeKit ([@cdce8p] - [#17614]) ([homekit docs]) (new-feature) * Add Elk-M1 传感器 platform ([@gwww] - [#17342]) ([elkm1 docs]) ([传感器.elkm1 docs]) (new-platform) * Homekit component cleanup ([@cdce8p] - [#17627]) ([homekit docs]) * Use cached robot serial for Neato 更新 ([@dshokouhi] - [#17633]) ([吸尘器.neato docs]) * deCONZ - Add support for Xiaomi window 遮盖 ([@Kane610] - [#17337]) ([deconz docs]) ([遮盖.deconz docs]) * Fix linky 传感器 login 错误 ([@Debaru] - [#17110]) * Fix MQTT 灯光 brightness slider ([@thinkl33t] - [#17075]) ([灯光.MQTT docs]) * Add opentherm\_gw 二元sensor support ([@mvn23] - [#17625]) ([opentherm\_gw docs][opentherm_gw docs]) ([binary\_sensor.opentherm\_gw docs][binary_sensor.opentherm_gw docs]) (new-platform) * 升级 dsmr\_parser to 0.12 ([@raymondelooff] - [#17634]) ([传感器.dsmr docs]) * Removing ryobi gdo ([@guillaume1410] - [#17637]) (breaking change) * Remove ryobi from .coveragerc ([@Danielhiversen] - [#17647]) * Reconnect if sub info comes in that is valid again ([@balloob] - [#17651]) ([cloud docs]) * Very minor cleanup of RFLink components ([@emontnemery] - [#17649]) ([灯光.rflink docs]) ([传感器.rflink docs]) ([开关.rflink docs]) * available to switchmate ([@Danielhiversen] - [#17640]) ([开关.switchmate docs]) * 升级 async\_timeout to 3.0.1 ([@fabaff] - [#17655]) * 升级 holidays to 0.9.8 ([@fabaff] - [#17656]) ([binary\_sensor.workday docs][binary_sensor.workday docs]) * Add support for Dyson Hot+Cool 风扇 as a 温控 设备 ([@soraxas] - [#14598]) ([dyson docs]) ([温控.dyson docs]) (new-platform) * 更新 pynetgear to 0.5.0 ([@MatMaul] - [#17652]) ([device\_tracker docs][device_tracker docs]) * Bump pyarlo==0.2.2 ([@lukiffer] - [#17673]) ([arlo docs]) * Add new rtorrent 传感器 ([@terorie] - [#17421]) ([传感器.rtorrent docs]) (new-platform) * Geo location 触发器 added ([@exxamalte] - [#16967]) ([自动化.区域 docs]) (beta fix) * Add Lovelace websocket get and set 卡片 ([@bramkragten] - [#17600]) ([Lovelace docs]) (beta fix) * Fixed issue #16903 re exception with multiple simultanious writes ([@nickovs] - [#17636]) (beta fix) * 更新 flux library 版本 ([@oblogic7] - [#17677]) ([灯光.flux\_led docs][灯光.flux_led docs]) (beta fix) * 更新 limitlessled to 1.1.3 ([@amelchio] - [#17703]) ([灯光.limitlessled docs]) (beta fix) * Bug fix for clicksend ([@JaxomCS] - [#17713]) ([通知 docs]) (beta fix) * Elk-M1 温控 ([@gwww] - [#17679]) ([elkm1 docs]) ([温控.elkm1 docs]) (beta fix) (new-platform) * Add 遮盖 to supported platforms ([@cgarwood] - [#17725]) ([zwave docs]) (beta fix) * Lovelace ws: add 卡片 ([@bramkragten] - [#17730]) ([Lovelace docs]) (beta fix) * Remove day (fixes #17741) ([@fabaff] - [#17743]) ([传感器.fastdotcom docs]) (beta fix) * Fixed an incorrect reference in the 实体 registry ([@bachya] - [#17775]) (beta fix) * 更新 HAP-python to 2.3.0 ([@cdce8p] - [#17778]) ([homekit docs]) (beta fix) * SMHI 天气 component not showing correct values in current forecast ([@helto4real] - [#17783]) ([smhi docs]) ([天气.smhi docs]) (beta fix) * Fix unloading an entry can leave 状态 around ([@balloob] - [#17786]) (beta fix) * The way columns are handled in the glance 卡片 has changed ([#1832]) (breaking change) * 报警 control 面板 卡片 ([#1758]) * Lovelace 按钮 卡片 ([#1766]) * Lovelace 现已支持长按操作 ([#1848]) * Lovelace 已支持自定义 UI ([#1824]) [#1758]: https://github.com/home-assistant/home-assistant-polymer/pull/1758 [#1766]: https://github.com/home-assistant/home-assistant-polymer/pull/1766 [#1832]: https://github.com/home-assistant/home-assistant-polymer/pull/1832 [#1824]: https://github.com/home-assistant/home-assistant-polymer/pull/1824 [#1848]: https://github.com/home-assistant/home-assistant-polymer/pull/1848 [#14598]: https://github.com/home-assistant/home-assistant/pull/14598 [#15364]: https://github.com/home-assistant/home-assistant/pull/15364 [#15764]: https://github.com/home-assistant/home-assistant/pull/15764 [#16139]: https://github.com/home-assistant/home-assistant/pull/16139 [#16201]: https://github.com/home-assistant/home-assistant/pull/16201 [#16362]: https://github.com/home-assistant/home-assistant/pull/16362 [#16422]: https://github.com/home-assistant/home-assistant/pull/16422 [#16519]: https://github.com/home-assistant/home-assistant/pull/16519 [#16562]: https://github.com/home-assistant/home-assistant/pull/16562 [#16635]: https://github.com/home-assistant/home-assistant/pull/16635 [#16711]: https://github.com/home-assistant/home-assistant/pull/16711 [#16714]: https://github.com/home-assistant/home-assistant/pull/16714 [#16717]: https://github.com/home-assistant/home-assistant/pull/16717 [#16802]: https://github.com/home-assistant/home-assistant/pull/16802 [#16890]: https://github.com/home-assistant/home-assistant/pull/16890 [#16913]: https://github.com/home-assistant/home-assistant/pull/16913 [#16935]: https://github.com/home-assistant/home-assistant/pull/16935 [#16943]: https://github.com/home-assistant/home-assistant/pull/16943 [#16952]: https://github.com/home-assistant/home-assistant/pull/16952 [#16958]: https://github.com/home-assistant/home-assistant/pull/16958 [#16967]: https://github.com/home-assistant/home-assistant/pull/16967 [#16973]: https://github.com/home-assistant/home-assistant/pull/16973 [#16993]: https://github.com/home-assistant/home-assistant/pull/16993 [#17011]: https://github.com/home-assistant/home-assistant/pull/17011 [#17014]: https://github.com/home-assistant/home-assistant/pull/17014 [#17023]: https://github.com/home-assistant/home-assistant/pull/17023 [#17058]: https://github.com/home-assistant/home-assistant/pull/17058 [#17072]: https://github.com/home-assistant/home-assistant/pull/17072 [#17075]: https://github.com/home-assistant/home-assistant/pull/17075 [#17109]: https://github.com/home-assistant/home-assistant/pull/17109 [#17110]: https://github.com/home-assistant/home-assistant/pull/17110 [#17115]: https://github.com/home-assistant/home-assistant/pull/17115 [#17119]: https://github.com/home-assistant/home-assistant/pull/17119 [#17120]: https://github.com/home-assistant/home-assistant/pull/17120 [#17133]: https://github.com/home-assistant/home-assistant/pull/17133 [#17140]: https://github.com/home-assistant/home-assistant/pull/17140 [#17146]: https://github.com/home-assistant/home-assistant/pull/17146 [#17148]: https://github.com/home-assistant/home-assistant/pull/17148 [#17157]: https://github.com/home-assistant/home-assistant/pull/17157 [#17168]: https://github.com/home-assistant/home-assistant/pull/17168 [#17171]: https://github.com/home-assistant/home-assistant/pull/17171 [#17175]: https://github.com/home-assistant/home-assistant/pull/17175 [#17179]: https://github.com/home-assistant/home-assistant/pull/17179 [#17180]: https://github.com/home-assistant/home-assistant/pull/17180 [#17185]: https://github.com/home-assistant/home-assistant/pull/17185 [#17190]: https://github.com/home-assistant/home-assistant/pull/17190 [#17197]: https://github.com/home-assistant/home-assistant/pull/17197 [#17198]: https://github.com/home-assistant/home-assistant/pull/17198 [#17199]: https://github.com/home-assistant/home-assistant/pull/17199 [#17201]: https://github.com/home-assistant/home-assistant/pull/17201 [#17202]: https://github.com/home-assistant/home-assistant/pull/17202 [#17205]: https://github.com/home-assistant/home-assistant/pull/17205 [#17209]: https://github.com/home-assistant/home-assistant/pull/17209 [#17216]: https://github.com/home-assistant/home-assistant/pull/17216 [#17222]: https://github.com/home-assistant/home-assistant/pull/17222 [#17225]: https://github.com/home-assistant/home-assistant/pull/17225 [#17227]: https://github.com/home-assistant/home-assistant/pull/17227 [#17232]: https://github.com/home-assistant/home-assistant/pull/17232 [#17234]: https://github.com/home-assistant/home-assistant/pull/17234 [#17235]: https://github.com/home-assistant/home-assistant/pull/17235 [#17240]: https://github.com/home-assistant/home-assistant/pull/17240 [#17241]: https://github.com/home-assistant/home-assistant/pull/17241 [#17242]: https://github.com/home-assistant/home-assistant/pull/17242 [#17243]: https://github.com/home-assistant/home-assistant/pull/17243 [#17244]: https://github.com/home-assistant/home-assistant/pull/17244 [#17245]: https://github.com/home-assistant/home-assistant/pull/17245 [#17247]: https://github.com/home-assistant/home-assistant/pull/17247 [#17249]: https://github.com/home-assistant/home-assistant/pull/17249 [#17250]: https://github.com/home-assistant/home-assistant/pull/17250 [#17254]: https://github.com/home-assistant/home-assistant/pull/17254 [#17256]: https://github.com/home-assistant/home-assistant/pull/17256 [#17258]: https://github.com/home-assistant/home-assistant/pull/17258 [#17260]: https://github.com/home-assistant/home-assistant/pull/17260 [#17268]: https://github.com/home-assistant/home-assistant/pull/17268 [#17271]: https://github.com/home-assistant/home-assistant/pull/17271 [#17276]: https://github.com/home-assistant/home-assistant/pull/17276 [#17278]: https://github.com/home-assistant/home-assistant/pull/17278 [#17280]: https://github.com/home-assistant/home-assistant/pull/17280 [#17283]: https://github.com/home-assistant/home-assistant/pull/17283 [#17288]: https://github.com/home-assistant/home-assistant/pull/17288 [#17290]: https://github.com/home-assistant/home-assistant/pull/17290 [#17291]: https://github.com/home-assistant/home-assistant/pull/17291 [#17292]: https://github.com/home-assistant/home-assistant/pull/17292 [#17294]: https://github.com/home-assistant/home-assistant/pull/17294 [#17297]: https://github.com/home-assistant/home-assistant/pull/17297 [#17299]: https://github.com/home-assistant/home-assistant/pull/17299 [#17305]: https://github.com/home-assistant/home-assistant/pull/17305 [#17306]: https://github.com/home-assistant/home-assistant/pull/17306 [#17308]: https://github.com/home-assistant/home-assistant/pull/17308 [#17309]: https://github.com/home-assistant/home-assistant/pull/17309 [#17313]: https://github.com/home-assistant/home-assistant/pull/17313 [#17314]: https://github.com/home-assistant/home-assistant/pull/17314 [#17317]: https://github.com/home-assistant/home-assistant/pull/17317 [#17319]: https://github.com/home-assistant/home-assistant/pull/17319 [#17322]: https://github.com/home-assistant/home-assistant/pull/17322 [#17323]: https://github.com/home-assistant/home-assistant/pull/17323 [#17328]: https://github.com/home-assistant/home-assistant/pull/17328 [#17329]: https://github.com/home-assistant/home-assistant/pull/17329 [#17330]: https://github.com/home-assistant/home-assistant/pull/17330 [#17332]: https://github.com/home-assistant/home-assistant/pull/17332 [#17336]: https://github.com/home-assistant/home-assistant/pull/17336 [#17337]: https://github.com/home-assistant/home-assistant/pull/17337 [#17339]: https://github.com/home-assistant/home-assistant/pull/17339 [#17340]: https://github.com/home-assistant/home-assistant/pull/17340 [#17341]: https://github.com/home-assistant/home-assistant/pull/17341 [#17342]: https://github.com/home-assistant/home-assistant/pull/17342 [#17346]: https://github.com/home-assistant/home-assistant/pull/17346 [#17347]: https://github.com/home-assistant/home-assistant/pull/17347 [#17349]: https://github.com/home-assistant/home-assistant/pull/17349 [#17350]: https://github.com/home-assistant/home-assistant/pull/17350 [#17355]: https://github.com/home-assistant/home-assistant/pull/17355 [#17357]: https://github.com/home-assistant/home-assistant/pull/17357 [#17358]: https://github.com/home-assistant/home-assistant/pull/17358 [#17359]: https://github.com/home-assistant/home-assistant/pull/17359 [#17364]: https://github.com/home-assistant/home-assistant/pull/17364 [#17366]: https://github.com/home-assistant/home-assistant/pull/17366 [#17369]: https://github.com/home-assistant/home-assistant/pull/17369 [#17377]: https://github.com/home-assistant/home-assistant/pull/17377 [#17383]: https://github.com/home-assistant/home-assistant/pull/17383 [#17384]: https://github.com/home-assistant/home-assistant/pull/17384 [#17398]: https://github.com/home-assistant/home-assistant/pull/17398 [#17399]: https://github.com/home-assistant/home-assistant/pull/17399 [#17402]: https://github.com/home-assistant/home-assistant/pull/17402 [#17406]: https://github.com/home-assistant/home-assistant/pull/17406 [#17407]: https://github.com/home-assistant/home-assistant/pull/17407 [#17411]: https://github.com/home-assistant/home-assistant/pull/17411 [#17413]: https://github.com/home-assistant/home-assistant/pull/17413 [#17418]: https://github.com/home-assistant/home-assistant/pull/17418 [#17419]: https://github.com/home-assistant/home-assistant/pull/17419 [#17421]: https://github.com/home-assistant/home-assistant/pull/17421 [#17424]: https://github.com/home-assistant/home-assistant/pull/17424 [#17425]: https://github.com/home-assistant/home-assistant/pull/17425 [#17429]: https://github.com/home-assistant/home-assistant/pull/17429 [#17431]: https://github.com/home-assistant/home-assistant/pull/17431 [#17435]: https://github.com/home-assistant/home-assistant/pull/17435 [#17436]: https://github.com/home-assistant/home-assistant/pull/17436 [#17437]: https://github.com/home-assistant/home-assistant/pull/17437 [#17441]: https://github.com/home-assistant/home-assistant/pull/17441 [#17446]: https://github.com/home-assistant/home-assistant/pull/17446 [#17447]: https://github.com/home-assistant/home-assistant/pull/17447 [#17450]: https://github.com/home-assistant/home-assistant/pull/17450 [#17452]: https://github.com/home-assistant/home-assistant/pull/17452 [#17454]: https://github.com/home-assistant/home-assistant/pull/17454 [#17455]: https://github.com/home-assistant/home-assistant/pull/17455 [#17458]: https://github.com/home-assistant/home-assistant/pull/17458 [#17460]: https://github.com/home-assistant/home-assistant/pull/17460 [#17461]: https://github.com/home-assistant/home-assistant/pull/17461 [#17472]: https://github.com/home-assistant/home-assistant/pull/17472 [#17473]: https://github.com/home-assistant/home-assistant/pull/17473 [#17481]: https://github.com/home-assistant/home-assistant/pull/17481 [#17482]: https://github.com/home-assistant/home-assistant/pull/17482 [#17491]: https://github.com/home-assistant/home-assistant/pull/17491 [#17497]: https://github.com/home-assistant/home-assistant/pull/17497 [#17498]: https://github.com/home-assistant/home-assistant/pull/17498 [#17504]: https://github.com/home-assistant/home-assistant/pull/17504 [#17508]: https://github.com/home-assistant/home-assistant/pull/17508 [#17509]: https://github.com/home-assistant/home-assistant/pull/17509 [#17510]: https://github.com/home-assistant/home-assistant/pull/17510 [#17514]: https://github.com/home-assistant/home-assistant/pull/17514 [#17519]: https://github.com/home-assistant/home-assistant/pull/17519 [#17520]: https://github.com/home-assistant/home-assistant/pull/17520 [#17526]: https://github.com/home-assistant/home-assistant/pull/17526 [#17530]: https://github.com/home-assistant/home-assistant/pull/17530 [#17533]: https://github.com/home-assistant/home-assistant/pull/17533 [#17549]: https://github.com/home-assistant/home-assistant/pull/17549 [#17555]: https://github.com/home-assistant/home-assistant/pull/17555 [#17568]: https://github.com/home-assistant/home-assistant/pull/17568 [#17570]: https://github.com/home-assistant/home-assistant/pull/17570 [#17571]: https://github.com/home-assistant/home-assistant/pull/17571 [#17581]: https://github.com/home-assistant/home-assistant/pull/17581 [#17595]: https://github.com/home-assistant/home-assistant/pull/17595 [#17598]: https://github.com/home-assistant/home-assistant/pull/17598 [#17600]: https://github.com/home-assistant/home-assistant/pull/17600 [#17601]: https://github.com/home-assistant/home-assistant/pull/17601 [#17605]: https://github.com/home-assistant/home-assistant/pull/17605 [#17609]: https://github.com/home-assistant/home-assistant/pull/17609 [#17614]: https://github.com/home-assistant/home-assistant/pull/17614 [#17620]: https://github.com/home-assistant/home-assistant/pull/17620 [#17625]: https://github.com/home-assistant/home-assistant/pull/17625 [#17627]: https://github.com/home-assistant/home-assistant/pull/17627 [#17633]: https://github.com/home-assistant/home-assistant/pull/17633 [#17634]: https://github.com/home-assistant/home-assistant/pull/17634 [#17636]: https://github.com/home-assistant/home-assistant/pull/17636 [#17637]: https://github.com/home-assistant/home-assistant/pull/17637 [#17640]: https://github.com/home-assistant/home-assistant/pull/17640 [#17647]: https://github.com/home-assistant/home-assistant/pull/17647 [#17649]: https://github.com/home-assistant/home-assistant/pull/17649 [#17651]: https://github.com/home-assistant/home-assistant/pull/17651 [#17652]: https://github.com/home-assistant/home-assistant/pull/17652 [#17655]: https://github.com/home-assistant/home-assistant/pull/17655 [#17656]: https://github.com/home-assistant/home-assistant/pull/17656 [#17673]: https://github.com/home-assistant/home-assistant/pull/17673 [#17677]: https://github.com/home-assistant/home-assistant/pull/17677 [#17679]: https://github.com/home-assistant/home-assistant/pull/17679 [#17703]: https://github.com/home-assistant/home-assistant/pull/17703 [#17713]: https://github.com/home-assistant/home-assistant/pull/17713 [#17725]: https://github.com/home-assistant/home-assistant/pull/17725 [#17730]: https://github.com/home-assistant/home-assistant/pull/17730 [#17743]: https://github.com/home-assistant/home-assistant/pull/17743 [#17775]: https://github.com/home-assistant/home-assistant/pull/17775 [#17778]: https://github.com/home-assistant/home-assistant/pull/17778 [#17783]: https://github.com/home-assistant/home-assistant/pull/17783 [#17786]: https://github.com/home-assistant/home-assistant/pull/17786 [@333ryan18]: https://github.com/333ryan18 [@Anonym-tsk]: https://github.com/Anonym-tsk [@Danielhiversen]: https://github.com/Danielhiversen [@Dav0815]: https://github.com/Dav0815 [@Debaru]: https://github.com/Debaru [@GuyKh]: https://github.com/GuyKh [@J4nsen]: https://github.com/J4nsen [@JariInc]: https://github.com/JariInc [@JaxomCS]: https://github.com/JaxomCS [@Joshi425]: https://github.com/Joshi425 [@Julius2342]: https://github.com/Julius2342 [@Kane610]: https://github.com/Kane610 [@KarimGeiger]: https://github.com/KarimGeiger [@MartinHjelmare]: https://github.com/MartinHjelmare [@MatMaul]: https://github.com/MatMaul [@MatteGary]: https://github.com/MatteGary [@MisterWil]: https://github.com/MisterWil [@OttoWinter]: https://github.com/OttoWinter [@PhilRW]: https://github.com/PhilRW [@SilvrrGIT]: https://github.com/SilvrrGIT [@TomAFrench]: https://github.com/TomAFrench [@StevenLooman]: https://github.com/StevenLooman [@amelchio]: https://github.com/amelchio [@arlyon]: https://github.com/arlyon [@azuwis]: https://github.com/azuwis [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@benleb]: https://github.com/benleb [@bgianfo]: https://github.com/bgianfo [@bramkragten]: https://github.com/bramkragten [@brantlk]: https://github.com/brantlk [@cdce8p]: https://github.com/cdce8p [@cgarwood]: https://github.com/cgarwood [@cgtobi]: https://github.com/cgtobi [@cisasteelersfan]: https://github.com/cisasteelersfan [@craigjmidwinter]: https://github.com/craigjmidwinter [@d0ugal]: https://github.com/d0ugal [@damarco]: https://github.com/damarco [@danielperna84]: https://github.com/danielperna84 [@definitio]: https://github.com/definitio [@dickesW]: https://github.com/dickesW [@dlashua]: https://github.com/dlashua [@dshokouhi]: https://github.com/dshokouhi [@eavanvalkenburg]: https://github.com/eavanvalkenburg [@ehendrix23]: https://github.com/ehendrix23 [@emontnemery]: https://github.com/emontnemery [@exxamalte]: https://github.com/exxamalte [@fabaff]: https://github.com/fabaff [@flowolf]: https://github.com/flowolf [@fredrikbaberg]: https://github.com/fredrikbaberg [@fronzbot]: https://github.com/fronzbot [@georgemarshall]: https://github.com/georgemarshall [@guillaume1410]: https://github.com/guillaume1410 [@gwww]: https://github.com/gwww [@hanzoh]: https://github.com/hanzoh [@helto4real]: https://github.com/helto4real [@heythisisnate]: https://github.com/heythisisnate [@jedmeng]: https://github.com/jedmeng [@jjlawren]: https://github.com/jjlawren [@keirans]: https://github.com/keirans [@kennedyshead]: https://github.com/kennedyshead [@klada]: https://github.com/klada [@lukiffer]: https://github.com/lukiffer [@marcolertora]: https://github.com/marcolertora [@mjg59]: https://github.com/mjg59 [@mnigbur]: https://github.com/mnigbur [@mvn23]: https://github.com/mvn23 [@nhorvath]: https://github.com/nhorvath [@nickovs]: https://github.com/nickovs [@nielstron]: https://github.com/nielstron [@noxhirsch]: https://github.com/noxhirsch [@oblogic7]: https://github.com/oblogic7 [@partofthething]: https://github.com/partofthething [@persandstrom]: https://github.com/persandstrom [@psyhomb]: https://github.com/psyhomb [@pvizeli]: https://github.com/pvizeli [@raymondelooff]: https://github.com/raymondelooff [@reefab]: https://github.com/reefab [@rohankapoorcom]: https://github.com/rohankapoorcom [@rytilahti]: https://github.com/rytilahti [@scarface-4711]: https://github.com/scarface-4711 [@scop]: https://github.com/scop [@shred86]: https://github.com/shred86 [@siom79]: https://github.com/siom79 [@soraxas]: https://github.com/soraxas [@syssi]: https://github.com/syssi [@teharris1]: https://github.com/teharris1 [@terorie]: https://github.com/terorie [@thinkl33t]: https://github.com/thinkl33t [@thomasloven]: https://github.com/thomasloven [@tjorim]: https://github.com/tjorim [@tsvi]: https://github.com/tsvi [@uchagani]: https://github.com/uchagani [@w1ll1am23]: https://github.com/w1ll1am23 [@wonderslug]: https://github.com/wonderslug [@zhumuht]: https://github.com/zhumuht [abode docs]: /integrations/abode/ [alarm_control_panel.elkm1 docs]: /integrations/elkm1 [alarm_control_panel.simplisafe docs]: /integrations/simplisafe [alarm_control_panel.totalconnect docs]: /integrations/totalconnect [arlo docs]: /integrations/arlo/ [august docs]: /integrations/august/ [自动化.Webhook docs]: /docs/自动化/触发器/#Webhook-触发器 [自动化.区域 docs]: /docs/自动化/触发器/#区域-触发器 [binary_sensor.august docs]: /integrations/august#binary-传感器 [binary_sensor.bloomsky docs]: /integrations/bloomsky#binary-传感器 [binary_sensor.bmw_connected_drive docs]: /integrations/bmw_connected_drive [binary_sensor.knx docs]: /integrations/binary_sensor.knx/ [binary_sensor.MQTT docs]: /integrations/binary_sensor.MQTT/ [binary_sensor.octoprint docs]: /integrations/octoprint#binary-传感器 [binary_sensor.opentherm_gw docs]: /integrations/opentherm_gw#binary-传感器 [binary_sensor.rflink docs]: /integrations/binary_sensor.rflink/ [binary_sensor.ring docs]: /integrations/ring#binary-传感器 [binary_sensor.trend docs]: /integrations/trend [binary_sensor.workday docs]: /integrations/workday [binary_sensor.xiaomi_aqara docs]: /integrations/binary_sensor.xiaomi_aqara/ [binary_sensor.zha docs]: /integrations/zha [blink docs]: /integrations/blink/ [bmw_connected_drive docs]: /integrations/bmw_connected_drive/ [日历.todoist docs]: /integrations/todoist [摄像头.ffmpeg docs]: /integrations/摄像头.ffmpeg/ [摄像头.neato docs]: /integrations/neato#摄像头 [摄像头.ring docs]: /integrations/ring#摄像头 [温控 docs]: /integrations/温控/ [温控.daikin docs]: /integrations/daikin#温控 [温控.dyson docs]: /integrations/dyson#温控 [温控.elkm1 docs]: /integrations/elkm1 [温控.eq3btsmart docs]: /integrations/eq3btsmart [温控.knx docs]: /integrations/温控.knx/ [温控.mill docs]: /integrations/mill [温控.MQTT docs]: /integrations/温控.MQTT/ [温控.opentherm_gw docs]: /integrations/opentherm_gw [温控.wink docs]: /integrations/wink#温控 [cloud docs]: /integrations/cloud/ [config docs]: /integrations/config/ [遮盖.deconz docs]: /integrations/deconz#遮盖 [遮盖.knx docs]: /integrations/遮盖.knx/ [遮盖.MQTT docs]: /integrations/遮盖.MQTT/ [遮盖.rflink docs]: /integrations/遮盖.rflink/ [遮盖.ryobi_gdo docs]: /integrations/遮盖.ryobi_gdo/ [遮盖.模板 docs]: /integrations/遮盖.模板/ [deconz docs]: /integrations/deconz/ [device_tracker docs]: /integrations/device_tracker/ [dyson docs]: /integrations/dyson/ [elkm1 docs]: /integrations/elkm1/ [风扇.MQTT docs]: /integrations/风扇.MQTT/ [风扇.模板 docs]: /integrations/风扇.模板/ [风扇.xiaomi_miio docs]: /integrations/风扇.xiaomi_miio/ [geo_location docs]: /integrations/geo_location/ [goalfeed docs]: /integrations/goalfeed/ [group docs]: /integrations/group/ [habitica docs]: /integrations/habitica/ [homekit docs]: /integrations/homekit/ [homematic docs]: /integrations/homematic/ [huawei_lte docs]: /integrations/huawei_lte/ [ifttt docs]: /integrations/ifttt/ [image_processing.opencv docs]: /integrations/opencv [insteon docs]: /integrations/insteon/ [knx docs]: /integrations/knx/ [konnected docs]: /integrations/konnected/ [lifx docs]: /integrations/lifx/ [灯光.abode docs]: /integrations/abode#灯光 [灯光.flux_led docs]: /integrations/flux_led [灯光.knx docs]: /integrations/灯光.knx/ [灯光.lifx docs]: /integrations/lifx [灯光.limitlessled docs]: /integrations/limitlessled [灯光.MQTT docs]: /integrations/灯光.MQTT/ [灯光.opple docs]: /integrations/opple [灯光.osramlightify docs]: /integrations/osramlightify [灯光.rflink docs]: /integrations/灯光.rflink/ [灯光.模板 docs]: /integrations/灯光.模板/ [灯光.tuya docs]: /integrations/tuya [灯光.xiaomi_miio docs]: /integrations/灯光.xiaomi_miio/ [灯光.yeelight docs]: /integrations/yeelight [灯光.zwave docs]: /integrations/zwave [门锁.august docs]: /integrations/august [门锁.模板 docs]: /integrations/门锁.模板/ [logbook docs]: /integrations/logbook/ [Lovelace docs]: /integrations/Lovelace/ [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.denonavr docs]: /integrations/denonavr/ [媒体播放器.dlna_dmr docs]: /integrations/dlna_dmr [媒体播放器.horizon docs]: /integrations/horizon [媒体播放器.lg_soundbar docs]: /integrations/lg_soundbar [媒体播放器.mpd docs]: /integrations/mpd [媒体播放器.samsungtv docs]: /integrations/samsungtv [媒体播放器.volumio docs]: /integrations/volumio [媒体播放器.webostv docs]: /integrations/webostv#media-player [媒体播放器.yamaha docs]: /integrations/yamaha [MQTT docs]: /integrations/MQTT/ [通知 docs]: /integrations/通知/ [octoprint docs]: /integrations/octoprint/ [opentherm_gw docs]: /integrations/opentherm_gw/ [openuv docs]: /integrations/openuv/ [recswitch docs]: /integrations/recswitch/ [遥控器.xiaomi_miio docs]: /integrations/遥控器.xiaomi_miio/ [rflink docs]: /integrations/rflink/ [route53 docs]: /integrations/route53/ [sabnzbd docs]: /integrations/sabnzbd/ [传感器.api_streams docs]: /integrations/传感器.websocket_api/ [传感器.bloomsky docs]: /integrations/bloomsky/#传感器 [传感器.bmw_connected_drive docs]: /integrations/bmw_connected_drive [传感器.dnsip docs]: /integrations/dnsip [传感器.dsmr docs]: /integrations/dsmr [传感器.elkm1 docs]: /integrations/elkm1 [传感器.fastdotcom docs]: /integrations/fastdotcom [传感器.filter docs]: /integrations/filter [传感器.fints docs]: /integrations/fints [传感器.geo_rss_events docs]: /integrations/geo_rss_events [传感器.gitlab_ci docs]: /integrations/gitlab_ci [传感器.haveibeenpwned docs]: /integrations/haveibeenpwned [传感器.homematic docs]: /integrations/homematic [传感器.huawei_lte docs]: /integrations/huawei_lte#传感器 [传感器.jewish_calendar docs]: /integrations/jewish_calendar [传感器.knx docs]: /integrations/传感器.knx/ [传感器.linky docs]: /integrations/linky [传感器.mold_indicator docs]: /integrations/mold_indicator [传感器.MQTT docs]: /integrations/传感器.MQTT/ [传感器.octoprint docs]: /integrations/octoprint#传感器 [传感器.opentherm_gw docs]: /integrations/opentherm_gw#传感器 [传感器.rflink docs]: /integrations/传感器.rflink/ [传感器.ring docs]: /integrations/ring#传感器 [传感器.rmvtransport docs]: /integrations/rmvtransport [传感器.rtorrent docs]: /integrations/rtorrent [传感器.shodan docs]: /integrations/shodan [传感器.speedtest docs]: /integrations/speedtestdotnet [传感器.syncthru docs]: /integrations/syncthru [传感器.模板 docs]: /integrations/模板 [传感器.thermoworks_smoke docs]: /integrations/thermoworks_smoke [传感器.transport_nsw docs]: /integrations/transport_nsw [传感器.xiaomi_aqara docs]: /integrations/传感器.xiaomi_aqara/ [传感器.xiaomi_miio docs]: /integrations/传感器.xiaomi_miio/ [传感器.zha docs]: /integrations/zha [传感器.zoneminder docs]: /integrations/zoneminder#传感器 [传感器.zwave docs]: /integrations/zwave [simplisafe docs]: /integrations/simplisafe/ [smhi docs]: /integrations/smhi/ [开关.broadlink docs]: /integrations/broadlink#开关 [开关.elkm1 docs]: /integrations/elkm1 [开关.flux docs]: /integrations/flux [开关.knx docs]: /integrations/开关.knx/ [开关.MQTT docs]: /integrations/开关.MQTT/ [开关.neato docs]: /integrations/neato#开关 [开关.netio docs]: /integrations/netio [开关.recswitch docs]: /integrations/recswitch [开关.rflink docs]: /integrations/开关.rflink/ [开关.switchmate docs]: /integrations/switchmate [开关.模板 docs]: /integrations/开关.模板/ [开关.unifi docs]: /integrations/unifi#开关 [开关.xiaomi_aqara docs]: /integrations/开关.xiaomi_aqara/ [开关.xiaomi_miio docs]: /integrations/开关.xiaomi_miio/ [开关.zwave docs]: /integrations/zwave [telegram_bot docs]: /integrations/telegram_bot/ [tts docs]: /integrations/tts/ [twilio docs]: /integrations/twilio/ [unifi docs]: /integrations/unifi/ [upnp docs]: /integrations/upnp/ [吸尘器.neato docs]: /integrations/neato#吸尘器 [吸尘器.xiaomi_miio docs]: /integrations/吸尘器.xiaomi_miio/ [vera docs]: /integrations/vera/ [verisure docs]: /integrations/verisure/ [water_heater docs]: /integrations/water_heater/ [天气 docs]: /integrations/天气/ [天气.demo docs]: /integrations/天气.demo/ [天气.met docs]: /integrations/met [天气.smhi docs]: /integrations/smhi [websocket_api docs]: /integrations/websocket_api/ [wink docs]: /integrations/wink/ [xiaomi_aqara docs]: /integrations/xiaomi_aqara/ [zha docs]: /integrations/zha/ [zoneminder docs]: /integrations/zoneminder/ [zwave docs]: /integrations/zwave/ [platform_options]: /docs/配置/platform_options/#scan-interval --- url: /home-assistant/blog/2018-11-08-release-82.md --- # 0.82:TensorFlow、Lovelace UI 编辑与 Z-Wave Barrier 类 又到了发布时间。这次覆盖了 HacktoberFest 的收尾阶段,所以内容依然非常充实。希望你会喜欢这些更新。 我要特别感谢所有帮助文档工作的人。自 HacktoberFest 开始以来,我们已经合并了 [953 个 PR](https://github.com/home-assistant/home-assistant.io/pulls?utf8=%E2%9C%93\&q=is%3Apr+is%3Aopen+closed%3A%3E2018-10-01),整整 953 个!尤其要感谢 [@klaasnicolaas],他把 240 个页面迁移到了新的配置格式,太强了。 我们这次也带来了一些很酷的新功能。首先,感谢 [@hunterjm] 的辛勤工作,你现在可以使用机器学习框架 TensorFlow 在摄像头画面中检测物体了。更多信息请查看[文档][image_processing.tensorflow docs]。 接下来,[@rohankapoorcom] 一直在努力把更多集成迁移到 Webhook 格式。这样不仅可以通过 UI 轻松设置,还会生成难以猜测的 URL。这个版本包含了 Mailgun、Twilio 和 DialogFlow。 前端团队一直[非常忙](https://github.com/home-assistant/home-assistant-polymer/pull/1974)。我们正在为 Lovelace 的正式发布做准备,各个部分也在逐步完善。本次发布引入了一个实验性的、Alpha 阶段、还很原始(警告够多了吧?)的 Lovelace 卡片 UI 编辑器。它要求你的卡片带有 ID,但满足后就能直接使用,并且支持你正在编辑配置的实时预览。

Screenshot of editing a Lovelace 卡片 编辑 Lovelace 卡片的截图。

另外一个前端相关改进是:在 0.81 版本中我们移除了 `ui-lovelace.yaml` 的所有配置拆分功能,现在很高兴告诉你,我们已经重新加入了 `!secret` 和 `!include` 支持。你在 `configuration.yaml` 中常用的其他配置拆分命令仍不会在 Lovelace 中可用。请注意,目前无法在 UI 中编辑 `!include` 的内容,`!secret` 也暂时不能在 UI 或预览中使用。 还有最后一件事……我们对 Open Z-Wave 做了一个轻量分叉,并加入了 barrier 命令类支持!这意味着你现在无需自己编译 Open Z-Wave,也可以通过 Z-Wave 控制车库门。我们会继续关注还能在保持与 OZW 项目接近的前提下,为这个分叉加入哪些功能。 ## 新平台 * Add 设备 tracking for the BT Smart Hub router ([@jxwolstenholme] - [#17158]) ([device\_tracker docs][device_tracker docs]) (new-platform) * Météo-france 传感器 : current 天气 and 1 hour rain forecast ([@victorcerutti] - [#17773]) ([传感器.meteo\_france docs][传感器.meteo_france docs]) (new-platform) * Support for WeMo 加湿器 ([@sqldiablo] - [#17996]) ([wemo docs]) ([风扇.wemo docs]) (new-platform) * Add a component for GreenEye Monitor ([@jkeljo] - [#16378]) ([greeneye\_monitor docs][greeneye_monitor docs]) (new-platform) * TensorFlow image\_processing component ([@hunterjm] - [#17795]) ([image\_processing.tensorflow docs][image_processing.tensorflow docs]) (new-platform) ## 发布 0.82.1 - November 15 * catch key 错误 when saving 图像 ([@hunterjm] - [#18365]) ([image\_processing.tensorflow docs][image_processing.tensorflow docs]) * Fix hangouts 通知 ([@MartinHjelmare] - [#18372]) ([通知 docs]) * Fix including from sub dir ([@bramkragten] - [#18378]) * Fix default value for optional Sense 配置 parameter ([@claytonjn] - [#18379]) ([sense docs]) * cancel off\_delay 动作 ([@dgomes] - [#18389]) ([binary\_sensor.MQTT docs][binary_sensor.MQTT docs]) * Changed checking of 遮盖 状态 closed from 0 to closed\_position variable. ([@pszafer] - [#18407]) ([遮盖.MQTT docs]) * updated pydaikin 版本 ([@fredrike] - [#18413]) ([daikin docs]) ([温控.daikin docs]) * edp\_redy: increase UPDATE\_INTERVAL ([@abmantis] - [#18429]) * 更新 pyozw to 0.1.1 ([@pvizeli] - [#18436]) ([zwave docs]) * Fix AsusWRT ([@kennedyshead] - [#18400]) [#18365]: https://github.com/home-assistant/home-assistant/pull/18365 [#18372]: https://github.com/home-assistant/home-assistant/pull/18372 [#18378]: https://github.com/home-assistant/home-assistant/pull/18378 [#18379]: https://github.com/home-assistant/home-assistant/pull/18379 [#18389]: https://github.com/home-assistant/home-assistant/pull/18389 [#18407]: https://github.com/home-assistant/home-assistant/pull/18407 [#18413]: https://github.com/home-assistant/home-assistant/pull/18413 [#18429]: https://github.com/home-assistant/home-assistant/pull/18429 [#18436]: https://github.com/home-assistant/home-assistant/pull/18436 [#18400]: https://github.com/home-assistant/home-assistant/pull/18400 [@MartinHjelmare]: https://github.com/MartinHjelmare [@abmantis]: https://github.com/abmantis [@bramkragten]: https://github.com/bramkragten [@claytonjn]: https://github.com/claytonjn [@dgomes]: https://github.com/dgomes [@fredrike]: https://github.com/fredrike [@hunterjm]: https://github.com/hunterjm [@pszafer]: https://github.com/pszafer [@pvizeli]: https://github.com/pvizeli [binary_sensor.MQTT docs]: /integrations/binary_sensor.MQTT/ [温控.daikin docs]: /integrations/daikin#温控 [遮盖.MQTT docs]: /integrations/遮盖.MQTT/ [daikin docs]: /integrations/daikin/ [image_processing.tensorflow docs]: /integrations/tensorflow [通知 docs]: /integrations/通知/ [sense docs]: /integrations/sense/ [zwave docs]: /integrations/zwave/ ## 如果你需要帮助... ...欢迎随时使用我们非常活跃的[论坛](https://community.home-assistant.io/),或加入我们的[聊天频道](https://discord.gg/c5DvZ4e)。发布说明虽然开启了评论,但我们更推荐你使用前面的沟通渠道。谢谢。 ## 问题反馈 遇到了这个发布引入的问题吗?请在我们的 [issue tracker](https://github.com/home-assistant/home-assistant/issues) 中反馈。请确保填写 issue 模板中的所有字段。 ## 不向后兼容的变更 * Migrate Mailgun to use the Webhook component ([@rohankapoorcom] - [#17464]) ([ifttt docs]) ([mailgun docs]) ([通知 docs]) ([自动化.Webhook docs]) (breaking change) * Migrate twilio webhooks to the Webhook component ([@rohankapoorcom] - [#17715]) ([twilio docs]) (breaking change) * Fix Vera 温控 component to use correct 状态 ([@sqldiablo] - [#17892]) ([温控.vera docs]) (breaking change) * Migrate dialogflow over to the new Webhook component ([@rohankapoorcom] - [#17804]) ([dialogflow docs]) ([http docs]) (breaking change) * 更新 to DoorBirdPy v2 (again) ([@Klikini] - [#14933]) ([doorbird docs]) ([开关.doorbird docs]) (breaking change) * Add 二元sensor for sense energy monitor ([@kbickar] - [#17645]) ([传感器.sense docs]) (breaking change) * 更新 Pollen.com to use numpy for trend analysis ([@bachya] - [#18107]) ([传感器.pollen docs]) (breaking change) * Remove config (breaking change) ([@jjlawren] - [#18153]) ([ffmpeg docs]) (breaking change) (beta fix) ## Beta 修复 * SMA: Optional import in schema & backoff fix ([@kellerza] - [#18099]) (beta fix) * Remove config (breaking change) ([@jjlawren] - [#18153]) ([ffmpeg docs]) (breaking change) (beta fix) * Handle TensorFlow like OpenCV ([@pvizeli] - [#18185]) ([image\_processing.tensorflow docs][image_processing.tensorflow docs]) (beta fix) * Add support for TensorFlow in official Docker ([@pvizeli] - [#18191]) (beta fix) * Cloud conf ([@balloob] - [#18216]) ([cloud docs]) (beta fix) * Check if os has chown ([@bramkragten] - [#18229]) (beta fix) * 更新 pynetgear to 0.5.1 ([@Arkkimaagi] - [#18238]) ([device\_tracker docs][device_tracker docs]) (beta fix) * Migrate python-openzwave to homeassistant-pyozw ([@pvizeli] - [#18268]) (beta fix) * SMA Guard against older pysma ([@kellerza] - [#18278]) ([传感器.sma docs]) (beta fix) * Bump pyotgw to 0.3b1 ([@mvn23] - [#18286]) ([opentherm\_gw docs][opentherm_gw docs]) (beta fix) * Fix 日志 错误 message ([@pvizeli] - [#18305]) ([hassio docs]) (beta fix) * Bump pyhaversion to 2.0.2 ([@ludeeus] - [#18318]) ([传感器.版本 docs]) (beta fix) * Fix xiaomi binary\_sensor 警告 ([@Danielhiversen] - [#18280]) ([binary\_sensor.xiaomi\_aqara docs][binary_sensor.xiaomi_aqara docs]) (beta fix) * Remove Velbus 温控 platform ([@balloob] - [#18319]) ([velbus docs]) (beta fix) * fix last 设备 ignored ([@abmantis] - [#18329]) ([device\_tracker docs][device_tracker docs]) (beta fix) ## 全部变更 * Mill, support more heater types ([@Danielhiversen] - [#17676]) ([温控.mill docs]) * Add missing hangouts data/图像 to 通知 服务 ([@quazzie] - [#17576]) ([通知 docs]) * Fix Mexican Spanish identifier ([@manuel-jrs] - [#17674]) ([tts docs]) * Add readthedoc.yml file to specify the 版本 of python to run during 文档 building. ([@tmonck] - [#17642]) * All supported domains should be exposed by default ([@doudz] - [#17579]) ([google\_assistant docs][google_assistant docs]) * Updated simplisafe-python to 3.1.13 ([@bachya] - [#17696]) ([simplisafe docs]) * 升级 Sphinx to 1.8.1 ([@fabaff] - [#17701]) * Away mode temperature fix for generic thermostat ([@estevez-dev] - [#17641]) ([温控.generic\_thermostat docs][温控.generic_thermostat docs]) * Async 版本 for asuswrt ([@kennedyshead] - [#17692]) ([device\_tracker docs][device_tracker docs]) * Migrate Mailgun to use the Webhook component ([@rohankapoorcom] - [#17464]) ([ifttt docs]) ([mailgun docs]) ([通知 docs]) ([自动化.Webhook docs]) (breaking change) * Only strip from the 蓝牙 name if it isn't None ([@d0ugal] - [#17719]) ([device\_tracker docs][device_tracker docs]) * Just use 调试 instead of 错误 if the binary\_sensor does not get data ([@kennedyshead] - [#17720]) ([openuv docs]) * clean up clicksend ([@Danielhiversen] - [#17723]) ([通知 docs]) * Set available property ([@ehendrix23] - [#17706]) ([august docs]) ([binary\_sensor.august docs][binary_sensor.august docs]) ([门锁.august docs]) * Removes re-init ([@kennedyshead] - [#17724]) ([device\_tracker docs][device_tracker docs]) * Don't call off\_delay\_listener if not needed ([@foxel] - [#17712]) ([binary\_sensor.MQTT docs][binary_sensor.MQTT docs]) * Rename readthedocs file ([@fabaff] - [#17718]) * Add 设备 tracking for the BT Smart Hub router ([@jxwolstenholme] - [#17158]) ([device\_tracker docs][device_tracker docs]) (new-platform) * 升级 pytest to 3.9.2 ([@scop] - [#17736]) * 升级 mypy to 0.641 ([@scop] - [#17734]) * IGD review fixes ([@StevenLooman] - [#17400]) ([upnp docs]) * Pytest tests ([@balloob] - [#17750]) * Remove webhook\_id from yaml config for mailgun ([@rohankapoorcom] - [#17732]) ([mailgun docs]) * 更新 zha **init**.py to reflect new Zigbee name stylization by the Zigbee Alliance ([@Hedda] - [#17751]) ([zha docs]) * Clean up clicksend\_tts ([@Danielhiversen] - [#17749]) ([通知 docs]) * Convert auth websocket commands to use async\_response decorator ([@balloob] - [#17755]) ([auth docs]) * 更新 name (fixes #17752) ([@fabaff] - [#17756]) ([Zigbee docs]) ([binary\_sensor.zha docs][binary_sensor.zha docs]) ([binary\_sensor.Zigbee docs][binary_sensor.Zigbee docs]) ([开关.xiaomi\_aqara docs][开关.xiaomi_aqara docs]) ([开关.Zigbee docs]) * Async tests for MQTT 门锁 ([@kennedyshead] - [#17763]) * Async MQTT 传感器 房间 ([@kennedyshead] - [#17765]) * Add Mexican Spanish language ([@manuel-jrs] - [#17735]) ([tts docs]) * Add wind gust (fixes #17766) ([@fabaff] - [#17774]) ([传感器.darksky docs]) * Remove username from 日志 entry ([@fabaff] - [#17777]) ([吸尘器.roomba docs]) * Migrate twilio webhooks to the Webhook component ([@rohankapoorcom] - [#17715]) ([twilio docs]) (breaking change) * Testing async in MQTT\_json 灯光 ([@kennedyshead] - [#17768]) * This makes mqtt\_template tests async ([@kennedyshead] - [#17784]) * 恢复 manual 报警-control-面板 状态 using async\_get\_last\_state ([@liaanvdm] - [#17521]) ([alarm\_control\_panel.manual docs][alarm_control_panel.manual docs]) * typo ([@janvanhelvoort] - [#17787]) ([zwave docs]) * Fix 设备 reg considered changed ([@balloob] - [#17764]) * Allow creating signed urls ([@balloob] - [#17759]) ([auth docs]) ([http docs]) * Add contact 传感器 to alexa smart home ([@abmantis] - [#17704]) ([alexa docs]) * 升级 flake8 to 3.6.0 ([@scop] - [#17770]) * 安装 face\_recognition on Docker build ([@lights0123] - [#17502]) * Delete 传感器.yahoo\_finance ([@rohankapoorcom] - [#17805]) * deCONZ: 配置 服务 can now use 'field' as a subpath together with '实体' ([@lbschenkel] - [#17722]) ([deconz docs]) * Bumped NDMS2 client to 0.0.5 to fix unicode characters support ([@foxel] - [#17803]) ([device\_tracker docs][device_tracker docs]) * 升级 numpy to 1.15.3 ([@fabaff] - [#17796]) ([binary\_sensor.trend docs][binary_sensor.trend docs]) ([image\_processing.opencv docs][image_processing.opencv docs]) * MQTT 吸尘器 now passes 错误 messages. ([@jeroenterheerdt] - [#17685]) ([吸尘器.MQTT docs]) * Convert 自动化 tests to async ([@balloob] - [#17794]) * Lovelace ws: add move command ([@bramkragten] - [#17806]) ([Lovelace docs]) * Convert MQTT 灯光 tests to async ([@balloob] - [#17754]) * Bumping aioasuswrt 版本 ([@kennedyshead] - [#17814]) ([device\_tracker docs][device_tracker docs]) * Minor changes ([@fabaff] - [#17812]) ([开关.dlink docs]) * Add snow to Openweathermap precipitation forecast ([@sgttrs] - [#17551]) ([天气.openweathermap docs]) * Add delete command ([@bramkragten] - [#17816]) ([Lovelace docs]) * Raise PlatformNotReady for RMVtransport if API not available ([@cgtobi] - [#17635]) ([传感器.rmvtransport docs]) * Added 吸尘器 dock and pause/unpause traits ([@mariuszluciow] - [#17657]) ([google\_assistant docs][google_assistant docs]) * Minor changes to the config validation ([@fabaff] - [#17808]) ([传感器.sma docs]) * Alexa motion 传感器 ([@abmantis] - [#17798]) ([alexa docs]) * Mill 设备 状态 属性 ([@Danielhiversen] - [#17834]) ([温控.mill docs]) * Fix Alexa unsupported operation\_mode off ([@rwagoner] - [#17844]) ([alexa docs]) * adding myself as yessssms codeowner ([@flowolf] - [#17862]) * 开关 to using Client from twilio.rest rather than the deleted TwilioRestClient ([@rohankapoorcom] - [#17883]) ([twilio docs]) * Fix Vera 温控 component to use correct 状态 ([@sqldiablo] - [#17892]) ([温控.vera docs]) (breaking change) * Add myself to CODEOWNERS for Yeelight Sunflower 灯光 platform ([@lindsaymarkward] - [#17896]) * Fix logi\_circle 传感器 更新 method naming ([@evanjd] - [#17909]) ([传感器.logi\_circle docs][传感器.logi_circle docs]) * Fix RFLink issue #17875 ([@emontnemery] - [#17889]) ([rflink docs]) * Corrected 风扇 设备 type in google assistant to 风扇 ([@mariuszluciow] - [#17792]) ([google\_assistant docs][google_assistant docs]) * Migrate dialogflow over to the new Webhook component ([@rohankapoorcom] - [#17804]) ([dialogflow docs]) ([http docs]) (breaking change) * Fixes Telegram webhooks ([@luca-angemi] - [#17554]) ([telegram\_bot docs][telegram_bot docs]) * Start type annotating/testing 助手 ([@scop] - [#17858]) * updated 版本 of xknx ([@Julius2342] - [#17912]) ([knx docs]) * Updated Brunt code owner ([@eavanvalkenburg] - [#17854]) * Monitor all 传感器 types by default to rtorrent ([@terorie] - [#17894]) ([传感器.rtorrent docs]) * Merge conflicting changes ([@kennedyshead] - [#17761]) * Axis - prepare for config entry ([@Kane610] - [#17566]) ([axis docs]) ([binary\_sensor.axis docs][binary_sensor.axis docs]) * 升级 pytest to 3.9.3 ([@scop] - [#17921]) * Extract 实体 ids from all 模板 ([@amelchio] - [#17902]) ([binary\_sensor.模板 docs][binary_sensor.模板 docs]) * Make 灯光.yeelight stop doing IO when accessing properties ([@rohankapoorcom] - [#17917]) ([灯光.yeelight docs]) * Fixes for upnp-component/#17753 and missing hass-data when only 设置 from config entry ([@StevenLooman] - [#17868]) ([upnp docs]) ([媒体播放器.dlna\_dmr docs][媒体播放器.dlna_dmr docs]) * Fix for verify\_ssl in the pi\_hole 传感器. ([@ludeeus] - [#17910]) ([传感器.pi\_hole docs][传感器.pi_hole docs]) * Permissions improv ([@balloob] - [#17811]) * Fix incorrect chevy discovery ([@balloob] - [#17942]) ([mychevy docs]) * Fix venv check ([@balloob] - [#17939]) ([updater docs]) * Disable upnp from being discovered ([@balloob] - [#17937]) * Added codeowner for bt\_smarthub ([@jxwolstenholme] - [#17947]) * Fixed copy-paste 错误 ([@mariuszluciow] - [#17948]) * Fix spelling 错误 in 日志 output ([@bitglue] - [#17963]) * Fix operation mode for Alexa thermostat ([@balloob] - [#17972]) ([alexa docs]) * Change source, add 属性, and improve 状态 of DirecTV ([@ehendrix23] - [#17536]) ([媒体播放器.directv docs]) * 更新 Alexa tests to async syntax ([@bitglue] - [#17965]) * Météo-france 传感器 : current 天气 and 1 hour rain forecast ([@victorcerutti] - [#17773]) ([传感器.meteo\_france docs][传感器.meteo_france docs]) (new-platform) * Updated ring\_doorbell dependency to 0.2.2 ([@evanjd] - [#17945]) ([ring docs]) * 更新 Avi-On to work with latest API ([@antsar] - [#17780]) ([灯光.avion docs]) * Mill 服务 ([@Danielhiversen] - [#17971]) ([温控.mill docs]) * Refactor Alexa API, fix thermostats ([@bitglue] - [#17969]) ([alexa docs]) * 升级 aiofreepybox ([@stilllman] - [#17989]) ([device\_tracker docs][device_tracker docs]) * Reverse out change #14234 BOM 天气 throttle fix ([@nickw444] - [#17468]) * RFC: Static 模板 match no 实体, not all ([@amelchio] - [#17991]) * 开关 mailgun webhooks to the new Mailgun Webhook api ([@rohankapoorcom] - [#17919]) ([mailgun docs]) * Change hebrew date at sunset ([@tsvi] - [#17449]) ([传感器.jewish\_calendar docs][传感器.jewish_calendar docs]) * Import homeassistant domain instead of hardcoding it ([@scop] - [#17985]) ([websocket\_api docs][websocket_api docs]) * Allow jinja namespace command to work. ([@NeilCrosby] - [#18011]) * Support for WeMo 加湿器 ([@sqldiablo] - [#17996]) ([wemo docs]) ([风扇.wemo docs]) (new-platform) * Fix Bloomsky api call ([@dshokouhi] - [#18016]) ([bloomsky docs]) * Async 版本 of melissa ([@kennedyshead] - [#17721]) * 升级 to asuswrt 1.1.1 to better handle mac addresses with letters in them ([@halkeye] - [#18030]) ([device\_tracker docs][device_tracker docs]) * Add SMA 传感器 SSL verification option ([@PhilRW] - [#18033]) ([传感器.sma docs]) * Use const.SUN\_EVENT\_\* more ([@scop] - [#18039]) ([device\_sun\_light\_trigger docs][device_sun_light_trigger docs]) ([sun docs]) ([传感器.jewish\_calendar docs][传感器.jewish_calendar docs]) ([开关.flux docs]) * Bumping aioasuswrt to 1.1.2 ([@kennedyshead] - [#18042]) ([device\_tracker docs][device_tracker docs]) * Add 服务.yaml entry for new WeMo 加湿器 platform 服务 ([@sqldiablo] - [#18032]) * Add opentherm\_gw 服务 ([@mvn23] - [#17762]) ([opentherm\_gw docs][opentherm_gw docs]) * Extract ruamel.yaml to util with secrets, Lovelace ws decorators ([@bramkragten] - [#17958]) ([Lovelace docs]) * Report correct thermostat mode to Alexa ([@bitglue] - [#18053]) ([alexa docs]) * 更新 SMA 传感器 to pysma 0.2.2 ([@kellerza] - [#17988]) ([传感器.sma docs]) * Mill, support opeation mode ([@Danielhiversen] - [#18059]) ([温控.mill docs]) * deCONZ - retry if 设置 fails ([@Kane610] - [#17772]) ([deconz docs]) ([binary\_sensor.deconz docs][binary_sensor.deconz docs]) ([遮盖.deconz docs]) ([灯光.deconz docs]) ([场景.deconz docs]) ([传感器.deconz docs]) ([开关.deconz docs]) * Add functionality to the 版本 传感器 ([@ludeeus] - [#18067]) ([传感器.版本 docs]) * remove schedule\_update\_ha\_state from mill ([@Danielhiversen] - [#18080]) ([温控.mill docs]) * Fix 摄像头 mjpeg stream handling ([@awarecan] - [#18076]) ([摄像头 docs]) ([摄像头.amcrest docs]) ([摄像头.arlo docs]) ([摄像头.canary docs]) ([摄像头.mjpeg docs]) ([摄像头.onvif docs]) ([摄像头.ring docs]) ([摄像头.synology docs]) ([摄像头.xiaomi docs]) ([摄像头.yi docs]) * Change test to parametrized test using pytest ([@tsvi] - [#18047]) * Add view commands to Lovelace ([@bramkragten] - [#18063]) ([Lovelace docs]) * Add message 模板 support for alert component ([@thoscut] - [#17516]) ([alert docs]) * Added identifier and name to connect/disconnect events ([@jaredquinn] - [#18078]) ([keyboard\_remote docs][keyboard_remote docs]) * Fix in Daikin.py for set swing\_mode and speed ([@MatteGary] - [#18013]) ([温控.daikin docs]) * Allow different types to match in pilight ([@akloeckner] - [#17922]) ([binary\_sensor.pilight docs][binary_sensor.pilight docs]) * Add a component for GreenEye Monitor ([@jkeljo] - [#16378]) ([greeneye\_monitor docs][greeneye_monitor docs]) (new-platform) * HomematicIP\_Cloud fix test ([@mxworm] - [#17376]) ([homematicip\_cloud docs][homematicip_cloud docs]) * 升级 locationsharinglib to 3.0.7 ([@fabaff] - [#18083]) ([device\_tracker docs][device_tracker docs]) * 升级 sqlalchemy to 1.2.13 ([@fabaff] - [#18084]) ([传感器.sql docs]) * 升级 youtube\_dl to 2018.10.29 ([@fabaff] - [#18085]) ([media\_extractor docs][media_extractor docs]) * Pass though file\_url from extended data attrs ([@cmsimike] - [#17801]) ([通知 docs]) * 升级 psutil to 5.4.8 ([@fabaff] - [#18086]) ([传感器.systemmonitor docs]) * 传感器/wunderground add device\_class ([@simonvanderveldt] - [#18072]) ([传感器.wunderground docs]) * 升级 restrictedpython to 4.0b6 ([@fabaff] - [#18087]) ([python\_script docs][python_script docs]) * 升级 georss\_client to 0.4 ([@exxamalte] - [#18088]) ([geo\_location docs][geo_location docs]) * Catch KeyError if data is not available (fixes #18082) ([@fabaff] - [#18089]) ([传感器.openweathermap docs]) * Bump python-miio 版本 ([@syssi] - [#18095]) ([device\_tracker docs][device_tracker docs]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) ([遥控器.xiaomi\_miio docs][遥控器.xiaomi_miio docs]) ([传感器.xiaomi\_miio docs][传感器.xiaomi_miio docs]) ([开关.xiaomi\_miio docs][开关.xiaomi_miio docs]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) * 更新 Pollen.com 传感器 platform to include asthma info ([@bachya] - [#18024]) ([传感器.pollen docs]) * Use a fixture for dialogflow calls in unit tests ([@rohankapoorcom] - [#17999]) * Don't try to re-add existing Z-Wave 实体 ([@cgarwood] - [#17995]) ([zwave docs]) * Always save current position if payload is numeric value ([@pszafer] - [#16148]) ([遮盖.MQTT docs]) * Darksky: Fetch summary for daily forecasts ([@leppa] - [#18031]) ([传感器.darksky docs]) * 更新 to DoorBirdPy v2 (again) ([@Klikini] - [#14933]) ([doorbird docs]) ([开关.doorbird docs]) (breaking change) * Ignore min\_cycle\_duration when manually controlling the thermostat. ([@aronsky] - [#16128]) ([温控.generic\_thermostat docs][温控.generic_thermostat docs]) * Add surround programs to 区域 2+ ([@Petro31] - [#17445]) ([媒体播放器.yamaha docs]) * Removed assumptions about provided upnp data ([@WoLpH] - [#17604]) ([upnp docs]) * Add 二元sensor for sense energy monitor ([@kbickar] - [#17645]) ([传感器.sense docs]) (breaking change) * Use ssdp udn uuid as Samsung TV unique id ([@scop] - [#18022]) ([媒体播放器.samsungtv docs]) * Allow MS face detection to handle updating 实体 when no face is detected ([@NeilCrosby] - [#17593]) ([image\_processing.microsoft\_face\_detect docs][image_processing.microsoft_face_detect docs]) ([image\_processing.microsoft\_face\_identify docs][image_processing.microsoft_face_identify docs]) * Added 服务 select\_video\_output and video\_out 属性 ([@leothlon] - [#18081]) ([媒体播放器.onkyo docs]) * Darksky: Round all temperatures to 1 decimal place ([@leppa] - [#18119]) ([传感器.darksky docs]) * Convert nsw rural fire tests to async ([@armills] - [#18112]) * Adding 温控.velbus support ([@Cereal2nd] - [#18100]) ([velbus docs]) * Changed from pifacecommon 4.1.2 to 4.2.2 to make the piface digital i/o boards work on rpi like 3 ([@vacumet] - [#18101]) ([rpi\_pfio docs][rpi_pfio docs]) * 更新 Pollen.com to use numpy for trend analysis ([@bachya] - [#18107]) ([传感器.pollen docs]) (breaking change) * Exposes initial 属性 on the 实体. ([@ludeeus] - [#18123]) ([input\_number docs][input_number docs]) * Async generic thermostat tests ([@armills] - [#18111]) * 更新 风扇/demo tests to async ([@armills] - [#18109]) * Don't create a 开关 for POE 设备 if said 设备 is Cloud key ([@Kane610] - [#18117]) ([开关.unifi docs]) * TensorFlow image\_processing component ([@hunterjm] - [#17795]) ([image\_processing.tensorflow docs][image_processing.tensorflow docs]) (new-platform) * Fix DTE Energy Bridge V2 scaling issue. (#18124) ([@mtl010957] - [#18129]) ([传感器.dte\_energy\_bridge docs][传感器.dte_energy_bridge docs]) * Add optional ttl config to route53 component ([@pascal-de-ladurantaye] - [#18135]) ([route53 docs]) * Allow disabling WeMo Discovery ([@sqldiablo] - [#18079]) ([wemo docs]) * Fix typos and 更新 docstrings ([@fabaff] - [#18137]) ([Lovelace docs]) * Fix hassio command timeout ([@alex9446] - [#17567]) ([hassio docs]) * SMA: Optional import in schema & backoff fix ([@kellerza] - [#18099]) (beta fix) * Remove config (breaking change) ([@jjlawren] - [#18153]) ([ffmpeg docs]) (breaking change) (beta fix) * Handle TensorFlow like OpenCV ([@pvizeli] - [#18185]) ([image\_processing.tensorflow docs][image_processing.tensorflow docs]) (beta fix) * Add support for TensorFlow in official Docker ([@pvizeli] - [#18191]) (beta fix) * Cloud conf ([@balloob] - [#18216]) ([cloud docs]) (beta fix) * Check if os has chown ([@bramkragten] - [#18229]) (beta fix) * 更新 pynetgear to 0.5.1 ([@Arkkimaagi] - [#18238]) ([device\_tracker docs][device_tracker docs]) (beta fix) * Migrate python-openzwave to homeassistant-pyozw ([@pvizeli] - [#18268]) (beta fix) * SMA Guard against older pysma ([@kellerza] - [#18278]) ([传感器.sma docs]) (beta fix) * Bump pyotgw to 0.3b1 ([@mvn23] - [#18286]) ([opentherm\_gw docs][opentherm_gw docs]) (beta fix) * Fix 日志 错误 message ([@pvizeli] - [#18305]) ([hassio docs]) (beta fix) * Bump pyhaversion to 2.0.2 ([@ludeeus] - [#18318]) ([传感器.版本 docs]) (beta fix) * Fix xiaomi binary\_sensor 警告 ([@Danielhiversen] - [#18280]) ([binary\_sensor.xiaomi\_aqara docs][binary_sensor.xiaomi_aqara docs]) (beta fix) * Remove Velbus 温控 platform ([@balloob] - [#18319]) ([velbus docs]) (beta fix) * fix last 设备 ignored ([@abmantis] - [#18329]) ([device\_tracker docs][device_tracker docs]) (beta fix) [#14933]: https://github.com/home-assistant/home-assistant/pull/14933 [#16128]: https://github.com/home-assistant/home-assistant/pull/16128 [#16148]: https://github.com/home-assistant/home-assistant/pull/16148 [#16378]: https://github.com/home-assistant/home-assistant/pull/16378 [#17158]: https://github.com/home-assistant/home-assistant/pull/17158 [#17376]: https://github.com/home-assistant/home-assistant/pull/17376 [#17400]: https://github.com/home-assistant/home-assistant/pull/17400 [#17445]: https://github.com/home-assistant/home-assistant/pull/17445 [#17449]: https://github.com/home-assistant/home-assistant/pull/17449 [#17464]: https://github.com/home-assistant/home-assistant/pull/17464 [#17468]: https://github.com/home-assistant/home-assistant/pull/17468 [#17502]: https://github.com/home-assistant/home-assistant/pull/17502 [#17516]: https://github.com/home-assistant/home-assistant/pull/17516 [#17521]: https://github.com/home-assistant/home-assistant/pull/17521 [#17536]: https://github.com/home-assistant/home-assistant/pull/17536 [#17551]: https://github.com/home-assistant/home-assistant/pull/17551 [#17554]: https://github.com/home-assistant/home-assistant/pull/17554 [#17566]: https://github.com/home-assistant/home-assistant/pull/17566 [#17567]: https://github.com/home-assistant/home-assistant/pull/17567 [#17576]: https://github.com/home-assistant/home-assistant/pull/17576 [#17579]: https://github.com/home-assistant/home-assistant/pull/17579 [#17593]: https://github.com/home-assistant/home-assistant/pull/17593 [#17604]: https://github.com/home-assistant/home-assistant/pull/17604 [#17635]: https://github.com/home-assistant/home-assistant/pull/17635 [#17641]: https://github.com/home-assistant/home-assistant/pull/17641 [#17642]: https://github.com/home-assistant/home-assistant/pull/17642 [#17645]: https://github.com/home-assistant/home-assistant/pull/17645 [#17657]: https://github.com/home-assistant/home-assistant/pull/17657 [#17674]: https://github.com/home-assistant/home-assistant/pull/17674 [#17676]: https://github.com/home-assistant/home-assistant/pull/17676 [#17685]: https://github.com/home-assistant/home-assistant/pull/17685 [#17692]: https://github.com/home-assistant/home-assistant/pull/17692 [#17696]: https://github.com/home-assistant/home-assistant/pull/17696 [#17701]: https://github.com/home-assistant/home-assistant/pull/17701 [#17704]: https://github.com/home-assistant/home-assistant/pull/17704 [#17706]: https://github.com/home-assistant/home-assistant/pull/17706 [#17712]: https://github.com/home-assistant/home-assistant/pull/17712 [#17715]: https://github.com/home-assistant/home-assistant/pull/17715 [#17718]: https://github.com/home-assistant/home-assistant/pull/17718 [#17719]: https://github.com/home-assistant/home-assistant/pull/17719 [#17720]: https://github.com/home-assistant/home-assistant/pull/17720 [#17721]: https://github.com/home-assistant/home-assistant/pull/17721 [#17722]: https://github.com/home-assistant/home-assistant/pull/17722 [#17723]: https://github.com/home-assistant/home-assistant/pull/17723 [#17724]: https://github.com/home-assistant/home-assistant/pull/17724 [#17732]: https://github.com/home-assistant/home-assistant/pull/17732 [#17734]: https://github.com/home-assistant/home-assistant/pull/17734 [#17735]: https://github.com/home-assistant/home-assistant/pull/17735 [#17736]: https://github.com/home-assistant/home-assistant/pull/17736 [#17749]: https://github.com/home-assistant/home-assistant/pull/17749 [#17750]: https://github.com/home-assistant/home-assistant/pull/17750 [#17751]: https://github.com/home-assistant/home-assistant/pull/17751 [#17754]: https://github.com/home-assistant/home-assistant/pull/17754 [#17755]: https://github.com/home-assistant/home-assistant/pull/17755 [#17756]: https://github.com/home-assistant/home-assistant/pull/17756 [#17759]: https://github.com/home-assistant/home-assistant/pull/17759 [#17761]: https://github.com/home-assistant/home-assistant/pull/17761 [#17762]: https://github.com/home-assistant/home-assistant/pull/17762 [#17763]: https://github.com/home-assistant/home-assistant/pull/17763 [#17764]: https://github.com/home-assistant/home-assistant/pull/17764 [#17765]: https://github.com/home-assistant/home-assistant/pull/17765 [#17768]: https://github.com/home-assistant/home-assistant/pull/17768 [#17770]: https://github.com/home-assistant/home-assistant/pull/17770 [#17772]: https://github.com/home-assistant/home-assistant/pull/17772 [#17773]: https://github.com/home-assistant/home-assistant/pull/17773 [#17774]: https://github.com/home-assistant/home-assistant/pull/17774 [#17777]: https://github.com/home-assistant/home-assistant/pull/17777 [#17780]: https://github.com/home-assistant/home-assistant/pull/17780 [#17784]: https://github.com/home-assistant/home-assistant/pull/17784 [#17787]: https://github.com/home-assistant/home-assistant/pull/17787 [#17792]: https://github.com/home-assistant/home-assistant/pull/17792 [#17794]: https://github.com/home-assistant/home-assistant/pull/17794 [#17795]: https://github.com/home-assistant/home-assistant/pull/17795 [#17796]: https://github.com/home-assistant/home-assistant/pull/17796 [#17798]: https://github.com/home-assistant/home-assistant/pull/17798 [#17801]: https://github.com/home-assistant/home-assistant/pull/17801 [#17803]: https://github.com/home-assistant/home-assistant/pull/17803 [#17804]: https://github.com/home-assistant/home-assistant/pull/17804 [#17805]: https://github.com/home-assistant/home-assistant/pull/17805 [#17806]: https://github.com/home-assistant/home-assistant/pull/17806 [#17808]: https://github.com/home-assistant/home-assistant/pull/17808 [#17811]: https://github.com/home-assistant/home-assistant/pull/17811 [#17812]: https://github.com/home-assistant/home-assistant/pull/17812 [#17814]: https://github.com/home-assistant/home-assistant/pull/17814 [#17816]: https://github.com/home-assistant/home-assistant/pull/17816 [#17834]: https://github.com/home-assistant/home-assistant/pull/17834 [#17844]: https://github.com/home-assistant/home-assistant/pull/17844 [#17854]: https://github.com/home-assistant/home-assistant/pull/17854 [#17858]: https://github.com/home-assistant/home-assistant/pull/17858 [#17862]: https://github.com/home-assistant/home-assistant/pull/17862 [#17868]: https://github.com/home-assistant/home-assistant/pull/17868 [#17883]: https://github.com/home-assistant/home-assistant/pull/17883 [#17889]: https://github.com/home-assistant/home-assistant/pull/17889 [#17892]: https://github.com/home-assistant/home-assistant/pull/17892 [#17894]: https://github.com/home-assistant/home-assistant/pull/17894 [#17896]: https://github.com/home-assistant/home-assistant/pull/17896 [#17902]: https://github.com/home-assistant/home-assistant/pull/17902 [#17909]: https://github.com/home-assistant/home-assistant/pull/17909 [#17910]: https://github.com/home-assistant/home-assistant/pull/17910 [#17912]: https://github.com/home-assistant/home-assistant/pull/17912 [#17917]: https://github.com/home-assistant/home-assistant/pull/17917 [#17919]: https://github.com/home-assistant/home-assistant/pull/17919 [#17921]: https://github.com/home-assistant/home-assistant/pull/17921 [#17922]: https://github.com/home-assistant/home-assistant/pull/17922 [#17937]: https://github.com/home-assistant/home-assistant/pull/17937 [#17939]: https://github.com/home-assistant/home-assistant/pull/17939 [#17942]: https://github.com/home-assistant/home-assistant/pull/17942 [#17945]: https://github.com/home-assistant/home-assistant/pull/17945 [#17947]: https://github.com/home-assistant/home-assistant/pull/17947 [#17948]: https://github.com/home-assistant/home-assistant/pull/17948 [#17958]: https://github.com/home-assistant/home-assistant/pull/17958 [#17963]: https://github.com/home-assistant/home-assistant/pull/17963 [#17965]: https://github.com/home-assistant/home-assistant/pull/17965 [#17969]: https://github.com/home-assistant/home-assistant/pull/17969 [#17971]: https://github.com/home-assistant/home-assistant/pull/17971 [#17972]: https://github.com/home-assistant/home-assistant/pull/17972 [#17985]: https://github.com/home-assistant/home-assistant/pull/17985 [#17988]: https://github.com/home-assistant/home-assistant/pull/17988 [#17989]: https://github.com/home-assistant/home-assistant/pull/17989 [#17991]: https://github.com/home-assistant/home-assistant/pull/17991 [#17995]: https://github.com/home-assistant/home-assistant/pull/17995 [#17996]: https://github.com/home-assistant/home-assistant/pull/17996 [#17999]: https://github.com/home-assistant/home-assistant/pull/17999 [#18011]: https://github.com/home-assistant/home-assistant/pull/18011 [#18013]: https://github.com/home-assistant/home-assistant/pull/18013 [#18016]: https://github.com/home-assistant/home-assistant/pull/18016 [#18022]: https://github.com/home-assistant/home-assistant/pull/18022 [#18024]: https://github.com/home-assistant/home-assistant/pull/18024 [#18030]: https://github.com/home-assistant/home-assistant/pull/18030 [#18031]: https://github.com/home-assistant/home-assistant/pull/18031 [#18032]: https://github.com/home-assistant/home-assistant/pull/18032 [#18033]: https://github.com/home-assistant/home-assistant/pull/18033 [#18039]: https://github.com/home-assistant/home-assistant/pull/18039 [#18042]: https://github.com/home-assistant/home-assistant/pull/18042 [#18047]: https://github.com/home-assistant/home-assistant/pull/18047 [#18053]: https://github.com/home-assistant/home-assistant/pull/18053 [#18059]: https://github.com/home-assistant/home-assistant/pull/18059 [#18063]: https://github.com/home-assistant/home-assistant/pull/18063 [#18067]: https://github.com/home-assistant/home-assistant/pull/18067 [#18072]: https://github.com/home-assistant/home-assistant/pull/18072 [#18076]: https://github.com/home-assistant/home-assistant/pull/18076 [#18078]: https://github.com/home-assistant/home-assistant/pull/18078 [#18079]: https://github.com/home-assistant/home-assistant/pull/18079 [#18080]: https://github.com/home-assistant/home-assistant/pull/18080 [#18081]: https://github.com/home-assistant/home-assistant/pull/18081 [#18083]: https://github.com/home-assistant/home-assistant/pull/18083 [#18084]: https://github.com/home-assistant/home-assistant/pull/18084 [#18085]: https://github.com/home-assistant/home-assistant/pull/18085 [#18086]: https://github.com/home-assistant/home-assistant/pull/18086 [#18087]: https://github.com/home-assistant/home-assistant/pull/18087 [#18088]: https://github.com/home-assistant/home-assistant/pull/18088 [#18089]: https://github.com/home-assistant/home-assistant/pull/18089 [#18095]: https://github.com/home-assistant/home-assistant/pull/18095 [#18099]: https://github.com/home-assistant/home-assistant/pull/18099 [#18100]: https://github.com/home-assistant/home-assistant/pull/18100 [#18101]: https://github.com/home-assistant/home-assistant/pull/18101 [#18107]: https://github.com/home-assistant/home-assistant/pull/18107 [#18109]: https://github.com/home-assistant/home-assistant/pull/18109 [#18111]: https://github.com/home-assistant/home-assistant/pull/18111 [#18112]: https://github.com/home-assistant/home-assistant/pull/18112 [#18117]: https://github.com/home-assistant/home-assistant/pull/18117 [#18119]: https://github.com/home-assistant/home-assistant/pull/18119 [#18123]: https://github.com/home-assistant/home-assistant/pull/18123 [#18129]: https://github.com/home-assistant/home-assistant/pull/18129 [#18135]: https://github.com/home-assistant/home-assistant/pull/18135 [#18137]: https://github.com/home-assistant/home-assistant/pull/18137 [#18153]: https://github.com/home-assistant/home-assistant/pull/18153 [#18185]: https://github.com/home-assistant/home-assistant/pull/18185 [#18191]: https://github.com/home-assistant/home-assistant/pull/18191 [#18216]: https://github.com/home-assistant/home-assistant/pull/18216 [#18229]: https://github.com/home-assistant/home-assistant/pull/18229 [#18238]: https://github.com/home-assistant/home-assistant/pull/18238 [#18268]: https://github.com/home-assistant/home-assistant/pull/18268 [#18278]: https://github.com/home-assistant/home-assistant/pull/18278 [#18280]: https://github.com/home-assistant/home-assistant/pull/18280 [#18286]: https://github.com/home-assistant/home-assistant/pull/18286 [#18305]: https://github.com/home-assistant/home-assistant/pull/18305 [#18318]: https://github.com/home-assistant/home-assistant/pull/18318 [#18319]: https://github.com/home-assistant/home-assistant/pull/18319 [#18329]: https://github.com/home-assistant/home-assistant/pull/18329 [@klaasnicolaas]: https://github.com/klaasnicolaas [@Arkkimaagi]: https://github.com/Arkkimaagi [@Cereal2nd]: https://github.com/Cereal2nd [@Danielhiversen]: https://github.com/Danielhiversen [@Hedda]: https://github.com/Hedda [@Julius2342]: https://github.com/Julius2342 [@Kane610]: https://github.com/Kane610 [@Klikini]: https://github.com/Klikini [@MatteGary]: https://github.com/MatteGary [@NeilCrosby]: https://github.com/NeilCrosby [@Petro31]: https://github.com/Petro31 [@PhilRW]: https://github.com/PhilRW [@StevenLooman]: https://github.com/StevenLooman [@WoLpH]: https://github.com/WoLpH [@abmantis]: https://github.com/abmantis [@akloeckner]: https://github.com/akloeckner [@alex9446]: https://github.com/alex9446 [@amelchio]: https://github.com/amelchio [@antsar]: https://github.com/antsar [@armills]: https://github.com/armills [@aronsky]: https://github.com/aronsky [@awarecan]: https://github.com/awarecan [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@bitglue]: https://github.com/bitglue [@bramkragten]: https://github.com/bramkragten [@cgarwood]: https://github.com/cgarwood [@cgtobi]: https://github.com/cgtobi [@cmsimike]: https://github.com/cmsimike [@d0ugal]: https://github.com/d0ugal [@doudz]: https://github.com/doudz [@dshokouhi]: https://github.com/dshokouhi [@eavanvalkenburg]: https://github.com/eavanvalkenburg [@ehendrix23]: https://github.com/ehendrix23 [@emontnemery]: https://github.com/emontnemery [@estevez-dev]: https://github.com/estevez-dev [@evanjd]: https://github.com/evanjd [@exxamalte]: https://github.com/exxamalte [@fabaff]: https://github.com/fabaff [@flowolf]: https://github.com/flowolf [@foxel]: https://github.com/foxel [@halkeye]: https://github.com/halkeye [@hunterjm]: https://github.com/hunterjm [@janvanhelvoort]: https://github.com/janvanhelvoort [@jaredquinn]: https://github.com/jaredquinn [@jeroenterheerdt]: https://github.com/jeroenterheerdt [@jjlawren]: https://github.com/jjlawren [@jkeljo]: https://github.com/jkeljo [@jxwolstenholme]: https://github.com/jxwolstenholme [@kbickar]: https://github.com/kbickar [@kellerza]: https://github.com/kellerza [@kennedyshead]: https://github.com/kennedyshead [@lbschenkel]: https://github.com/lbschenkel [@leothlon]: https://github.com/leothlon [@leppa]: https://github.com/leppa [@liaanvdm]: https://github.com/liaanvdm [@lights0123]: https://github.com/lights0123 [@lindsaymarkward]: https://github.com/lindsaymarkward [@luca-angemi]: https://github.com/luca-angemi [@ludeeus]: https://github.com/ludeeus [@manuel-jrs]: https://github.com/manuel-jrs [@mariuszluciow]: https://github.com/mariuszluciow [@mtl010957]: https://github.com/mtl010957 [@mvn23]: https://github.com/mvn23 [@mxworm]: https://github.com/mxworm [@nickw444]: https://github.com/nickw444 [@pascal-de-ladurantaye]: https://github.com/pascal-de-ladurantaye [@pszafer]: https://github.com/pszafer [@pvizeli]: https://github.com/pvizeli [@quazzie]: https://github.com/quazzie [@rohankapoorcom]: https://github.com/rohankapoorcom [@rwagoner]: https://github.com/rwagoner [@scop]: https://github.com/scop [@sgttrs]: https://github.com/sgttrs [@simonvanderveldt]: https://github.com/simonvanderveldt [@sqldiablo]: https://github.com/sqldiablo [@stilllman]: https://github.com/stilllman [@syssi]: https://github.com/syssi [@terorie]: https://github.com/terorie [@thoscut]: https://github.com/thoscut [@tmonck]: https://github.com/tmonck [@tsvi]: https://github.com/tsvi [@vacumet]: https://github.com/vacumet [@victorcerutti]: https://github.com/victorcerutti [alarm_control_panel.manual docs]: /integrations/manual [alert docs]: /integrations/alert/ [alexa docs]: /integrations/alexa/ [august docs]: /integrations/august/ [auth docs]: /integrations/auth/ [自动化.Webhook docs]: /docs/自动化/触发器/#Webhook-触发器 [axis docs]: /integrations/axis/ [binary_sensor.august docs]: /integrations/august#binary-传感器 [binary_sensor.axis docs]: /integrations/axis#binary-传感器 [binary_sensor.deconz docs]: /integrations/deconz#binary-传感器 [binary_sensor.MQTT docs]: /integrations/binary_sensor.MQTT/ [binary_sensor.pilight docs]: /integrations/pilight#binary-传感器 [binary_sensor.模板 docs]: /integrations/binary_sensor.模板/ [binary_sensor.trend docs]: /integrations/trend [binary_sensor.xiaomi_aqara docs]: /integrations/binary_sensor.xiaomi_aqara/ [binary_sensor.zha docs]: /integrations/zha [binary_sensor.Zigbee docs]: /integrations/Zigbee#binary-传感器 [bloomsky docs]: /integrations/bloomsky/ [摄像头 docs]: /integrations/摄像头/ [摄像头.amcrest docs]: /integrations/amcrest [摄像头.arlo docs]: /integrations/arlo#摄像头 [摄像头.canary docs]: /integrations/canary#摄像头 [摄像头.mjpeg docs]: /integrations/mjpeg [摄像头.onvif docs]: /integrations/onvif [摄像头.ring docs]: /integrations/ring#摄像头 [摄像头.synology docs]: /integrations/synology [摄像头.xiaomi docs]: /integrations/xiaomi_aqara [摄像头.yi docs]: /integrations/yi [温控.daikin docs]: /integrations/daikin#温控 [温控.generic_thermostat docs]: /integrations/generic_thermostat [温控.mill docs]: /integrations/mill [温控.velbus docs]: /integrations/velbus [温控.vera docs]: /integrations/vera [cloud docs]: /integrations/cloud/ [遮盖.deconz docs]: /integrations/deconz#遮盖 [遮盖.MQTT docs]: /integrations/遮盖.MQTT/ [deconz docs]: /integrations/deconz/ [device_sun_light_trigger docs]: /integrations/device_sun_light_trigger/ [device_tracker docs]: /integrations/device_tracker/ [dialogflow docs]: /integrations/dialogflow/ [doorbird docs]: /integrations/doorbird/ [风扇.wemo docs]: /integrations/wemo#风扇 [风扇.xiaomi_miio docs]: /integrations/风扇.xiaomi_miio/ [ffmpeg docs]: /integrations/ffmpeg/ [geo_location docs]: /integrations/geo_location/ [google_assistant docs]: /integrations/google_assistant/ [greeneye_monitor docs]: /integrations/greeneye_monitor/ [hassio docs]: /integrations/hassio/ [homematicip_cloud docs]: /integrations/homematicip_cloud/ [http docs]: /integrations/http/ [ifttt docs]: /integrations/ifttt/ [image_processing.microsoft_face_detect docs]: /integrations/microsoft_face_detect [image_processing.microsoft_face_identify docs]: /integrations/microsoft_face_identify [image_processing.opencv docs]: /integrations/opencv [image_processing.tensorflow docs]: /integrations/tensorflow [input_number docs]: /integrations/input_number/ [keyboard_remote docs]: /integrations/keyboard_remote/ [knx docs]: /integrations/knx/ [灯光.avion docs]: /integrations/avion [灯光.deconz docs]: /integrations/deconz#灯光 [灯光.xiaomi_miio docs]: /integrations/灯光.xiaomi_miio/ [灯光.yeelight docs]: /integrations/yeelight [门锁.august docs]: /integrations/august [Lovelace docs]: /integrations/Lovelace/ [mailgun docs]: /integrations/mailgun/ [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.directv docs]: /integrations/directv [媒体播放器.dlna_dmr docs]: /integrations/dlna_dmr [媒体播放器.onkyo docs]: /integrations/onkyo [媒体播放器.samsungtv docs]: /integrations/samsungtv [媒体播放器.yamaha docs]: /integrations/yamaha [mychevy docs]: /integrations/mychevy/ [通知 docs]: /integrations/通知/ [opentherm_gw docs]: /integrations/opentherm_gw/ [openuv docs]: /integrations/openuv/ [python_script docs]: /integrations/python_script/ [遥控器.xiaomi_miio docs]: /integrations/遥控器.xiaomi_miio/ [rflink docs]: /integrations/rflink/ [ring docs]: /integrations/ring/ [route53 docs]: /integrations/route53/ [rpi_pfio docs]: /integrations/rpi_pfio/ [场景.deconz docs]: /integrations/deconz#场景 [传感器.darksky docs]: /integrations/darksky [传感器.deconz docs]: /integrations/deconz#传感器 [传感器.dte_energy_bridge docs]: /integrations/dte_energy_bridge [传感器.greeneye_monitor_current docs]: /integrations/greeneye_monitor_current/ [传感器.greeneye_monitor_pulse docs]: /integrations/greeneye_monitor_pulse/ [传感器.greeneye_monitor_temperature docs]: /integrations/greeneye_monitor_temperature/ [传感器.igd docs]: /integrations/传感器.igd/ [传感器.jewish_calendar docs]: /integrations/jewish_calendar [传感器.logi_circle docs]: /integrations/logi_circle#传感器 [传感器.meteo_france docs]: /integrations/meteo_france [传感器.openweathermap docs]: /integrations/openweathermap#传感器 [传感器.pi_hole docs]: /integrations/pi_hole [传感器.pollen docs]: /integrations/iqvia [传感器.rmvtransport docs]: /integrations/rmvtransport [传感器.rtorrent docs]: /integrations/rtorrent [传感器.sense docs]: /integrations/sense [传感器.sma docs]: /integrations/sma#传感器 [传感器.sql docs]: /integrations/sql [传感器.systemmonitor docs]: /integrations/systemmonitor [传感器.版本 docs]: /integrations/版本 [传感器.wunderground docs]: /integrations/wunderground [传感器.xiaomi_miio docs]: /integrations/传感器.xiaomi_miio/ [simplisafe docs]: /integrations/simplisafe/ [sun docs]: /integrations/sun/ [开关.deconz docs]: /integrations/deconz#开关 [开关.dlink docs]: /integrations/dlink [开关.doorbird docs]: /integrations/doorbird#开关 [开关.flux docs]: /integrations/flux [开关.unifi docs]: /integrations/unifi#开关 [开关.xiaomi_aqara docs]: /integrations/开关.xiaomi_aqara/ [开关.xiaomi_miio docs]: /integrations/开关.xiaomi_miio/ [开关.Zigbee docs]: /integrations/Zigbee#开关 [telegram_bot docs]: /integrations/telegram_bot/ [tts docs]: /integrations/tts/ [twilio docs]: /integrations/twilio/ [updater docs]: /integrations/updater/ [upnp docs]: /integrations/upnp/ [吸尘器.MQTT docs]: /integrations/吸尘器.MQTT/ [吸尘器.roomba docs]: /integrations/roomba [吸尘器.xiaomi_miio docs]: /integrations/吸尘器.xiaomi_miio/ [velbus docs]: /integrations/velbus/ [天气.openweathermap docs]: /integrations/openweathermap#天气 [websocket_api docs]: /integrations/websocket_api/ [wemo docs]: /integrations/wemo/ [zha docs]: /integrations/zha/ [Zigbee docs]: /integrations/Zigbee/ [zwave docs]: /integrations/zwave/ --- url: /home-assistant/blog/2018-11-16-state-of-the-union.md --- # 现状与展望

Photo of Paulus Schoutsen presenting the 状态 of the union.

上周三(11 月 14 日),我们在阿姆斯特丹举办了一场由 ING 主办的线下聚会。80 多位 Home Assistant 爱好者到场,听我(Home Assistant 创始人 Paulus Schoutsen)分享。我讲了 Home Assistant 是如何起步的、它为什么能成功(社区!),以及我们正在努力的方向。
特别感谢: * Jeroen Joosse:发起并组织活动 * Erik-Jan Riemers:联合组织并把活动做大 * ING:提供活动场地 * Franck Nijhof:提供 Hass.io 演示 * Klaas Schoute:提供 TensorFlow 演示 * Frank Kuiper:剪辑演讲视频 更多照片见下方。

Crowd talking Home Assistant 现场交流 Home Assistant

Frenck showing all the ins and outs of Hass.io Frenck 讲解 Hass.io 的方方面面

The Z-Wave table Z-Wave 展台

Presentation selfie! 演讲自拍!

--- url: /home-assistant/blog/2018-11-28-release-83.md --- --- url: /home-assistant/blog/2018-12-12-release-84.md --- # 0.84:Cloud Webhook、Wunderlist 与 USGS 地震信息 到了一年中最后一次发布的时间。我们原本希望以一场大更新收官,并让 Lovelace 成为默认 UI。不过在最后冲刺阶段,我们意识到为了达到理想体验,需要做的临时变更比我们能接受的还多。如果你是 Lovelace 测试用户,请务必阅读下方“现有测试用户”部分。 在此祝大家节日快乐,也感谢所有在代码、文档和聊天社区中做出贡献的朋友,正是你们组成了这个了不起的社区。过去一年我们收获颇丰,也很期待在 2019 年看到大家带来的更多精彩内容。干杯! Paulus *我们会跳过下一次双周发布,计划在 1 月 9 日回归。到时见!* ## 云 Webhook 这次发布带来了 Home Assistant Cloud 的一项新功能:云 Webhook。通过云 Webhook,你可以让 Home Assistant 中任何支持 Webhook 的集成或自动化通过云端唯一 URL 访问,而无需在路由器上开放端口。 这意味着你可以把数据回传到自己的实例,用于 OwnTracks、IFTTT 或带有 Webhook 触发器的自动化。可前往配置面板中的云页面开始使用,或在 [Nabu Casa 网站](https://www.nabucasa.com/config/webhooks/) 了解更多新功能信息。 ## 改进的状态恢复 [@armills] 引入了一种新的、更可靠的状态恢复方式。它不再依赖数据库,而是利用 storage 助手来跟踪需要恢复的状态。这将提升可靠性和启动速度。 这也有一个代价:你第一次启动 0.84 时将无法恢复状态。 这意味着升级到 0.84 后,任何未定义 `initial_state` 的自动化都**会被禁用**。 ## 改进的服务调用 我们改进了服务调用流程,增加了更严格的数据校验。这意味着如果你的自动化或脚本发送了无效数据,我们现在会停止执行,并更准确地指出错误调用来源。 ## 给现有 Lovelace 测试用户的说明 如果你正在测试 Lovelace,请仔细阅读以下说明,因为变化很多。首先,我们现在有三种 Lovelace 模式:自动生成、storage,以及 yaml(Lovelace 的旧方式)。UI 编辑器仅适用于 storage 模式,因为该模式下配置存储方式由我们控制。 如果你在 0.84 之前就在使用 Lovelace,现在有两个选择。第一种是使用新的 storage 模式并导入你现有的文件。操作方式是打开 Lovelace UI,选择“配置 UI”,系统会提示你切换到 storage 模式。切换后,菜单中会出现一个名为“raw config editor”的新选项。打开后将 `ui-lovelace.yaml` 的内容粘贴进去并保存即可。请注意,YAML 注释不会被保留,而且在 storage 模式下不支持 `!include`/`!secret`。 如果你想继续管理 YAML 文件,请[查看这里了解如何启用 YAML 模式](/home-assistant/dashboards/yaml-mode/)。现在 `ui-lovelace.yaml` 将遵循与 `configuration.yaml` 相同的规则。这意味着 Lovelace YAML 配置将使用 YAML 1.1 而不是 YAML 1.2 进行解析。最大的变化是:请确保在配置中将 `on` 和 `off` 用引号包起来! 我们还统一了所有卡片的配置方式,因此带来了一些不向后兼容的变更。重点变化主要集中在短按和长按动作的定义方式上。更多信息请查看[文档](/home-assistant/dashboards/changelog/)。 编辑器 UI 也进一步完善了。现在你无需离开浏览器就能管理 Lovelace UI!你可以添加、编辑、删除视图,也可以添加、编辑、移动和删除卡片,包括自定义卡片。 ## 新平台 * Refactor ZHA ([@dmulcahey] - [#18629]) ([zha docs]) ([binary\_sensor.zha docs][binary_sensor.zha docs]) ([风扇.zha docs]) ([灯光.zha docs]) ([传感器.zha docs]) ([开关.zha docs]) (new-platform) * Add Awair 传感器 platform ([@ahayworth] - [#18570]) ([传感器.awair docs]) (new-platform) * Allow managing cloud Webhook ([@balloob] - [#18672]) ([cloud docs]) (new-platform) * U.S. Geological Survey Earthquake Hazards Program Feed platform ([@exxamalte] - [#18207]) ([geo\_location docs][geo_location docs]) (new-platform) * MQTT 灯光 refactor ([@emontnemery] - [#18227]) ([MQTT docs]) ([灯光.MQTT docs]) (breaking change) (new-platform) * Added qbittorrent 传感器 platform ([@eliseomartelli] - [#18618]) ([传感器.qbittorrent docs]) (new-platform) * Add Entur departure information 传感器 ([@hfurubotten] - [#17286]) ([传感器.entur\_public\_transport docs][传感器.entur_public_transport docs]) (new-platform) * Add lightwave components for 开关 and 灯光 ([@GeoffAtHome] - [#18026]) ([lightwave docs]) ([灯光.lightwave docs]) ([开关.lightwave docs]) (new-platform) * Initial hlk-sw16 relay 开关 support ([@jameshilliard] - [#17855]) ([hlk\_sw16 docs][hlk_sw16 docs]) ([开关.hlk\_sw16 docs][开关.hlk_sw16 docs]) (new-platform) * Initial 场景 support for Fibaro hubs ([@pbalogh77] - [#18779]) ([fibaro docs]) ([场景.fibaro docs]) (new-platform) ## 发布 0.84.1 - December 12 * Add 自动化 and 脚本 events to logbook event types ([@hunterjm] - [#19219]) ([logbook docs]) * Fix owntracks topic in encrypted ios ([@balloob] - [#19220]) ([device\_tracker docs][device_tracker docs]) ([owntracks docs]) [#19219]: https://github.com/home-assistant/home-assistant/pull/19219 [#19220]: https://github.com/home-assistant/home-assistant/pull/19220 [@balloob]: https://github.com/balloob [@hunterjm]: https://github.com/hunterjm [device_tracker docs]: /integrations/device_tracker/ [logbook docs]: /integrations/logbook/ [owntracks docs]: /integrations/owntracks/ ## 发布 0.84.2 - December 14 * Don't avoid async\_schedule\_update\_ha\_state by returning false ([@syssi] - [#19102]) ([binary\_sensor.xiaomi\_aqara docs][binary_sensor.xiaomi_aqara docs]) * Always add friendly name 属性 to ZHA 实体 ([@damarco] - [#19141]) ([zha docs]) * Bump aioasuswrt ([@kennedyshead] - [#19229]) ([asuswrt docs]) * Add 自动化 and 脚本 events to logbook filter events ([@luca-angemi] - [#19253]) ([logbook docs]) * Fix list (fixes #19235) ([@fabaff] - [#19258]) ([tts docs]) * Fix OwnTracks deadlocking ([@balloob] - [#19260]) ([owntracks docs]) * Fix call to super() ([@marchingphoenix] - [#19279]) ([灯光.lutron docs]) * Improve check for duplicated entity\_id ([@emontnemery] - [#19194]) * Fix race in entity\_platform.async\_add\_entities ([@emontnemery] - [#19222]) [#19102]: https://github.com/home-assistant/home-assistant/pull/19102 [#19141]: https://github.com/home-assistant/home-assistant/pull/19141 [#19222]: https://github.com/home-assistant/home-assistant/pull/19222 [#19229]: https://github.com/home-assistant/home-assistant/pull/19229 [#19253]: https://github.com/home-assistant/home-assistant/pull/19253 [#19258]: https://github.com/home-assistant/home-assistant/pull/19258 [#19260]: https://github.com/home-assistant/home-assistant/pull/19260 [#19279]: https://github.com/home-assistant/home-assistant/pull/19279 [#19194]: https://github.com/home-assistant/home-assistant/pull/19194 [@balloob]: https://github.com/balloob [@damarco]: https://github.com/damarco [@emontnemery]: https://github.com/emontnemery [@fabaff]: https://github.com/fabaff [@kennedyshead]: https://github.com/kennedyshead [@luca-angemi]: https://github.com/luca-angemi [@marchingphoenix]: https://github.com/marchingphoenix [@syssi]: https://github.com/syssi [asuswrt docs]: /integrations/asuswrt/ [binary_sensor.xiaomi_aqara docs]: /integrations/binary_sensor.xiaomi_aqara/ [灯光.lutron docs]: /integrations/lutron [logbook docs]: /integrations/logbook/ [owntracks docs]: /integrations/owntracks/ [tts docs]: /integrations/tts/ [zha docs]: /integrations/zha/ ## 发布 0.84.3 - December 17 * Set 门锁 status correctly for Schlage BE469 Z-Wave 门锁 ([@ahayworth] - [#18737]) ([门锁.zwave docs]) * Fix 恢复 状态 for manual 报警 control 面板 ([@liaanvdm] - [#19284]) ([alarm\_control\_panel.manual docs][alarm_control_panel.manual docs]) * Fix not being able to 更新 实体 ([@glentakahashi] - [#19344]) ([config docs]) ## 发布 0.84.4 - December 19 * Fix parts of the 前端 not picking up translations ([@balloob]) * Fix IHC config schema ([@mopolus] - [#19415]) ([ihc docs]) * Use web sockets for Harmony HUB ([@ehendrix23] - [#19440]) ([遥控器.harmony docs]) [#19415]: https://github.com/home-assistant/home-assistant/pull/19415 [#19440]: https://github.com/home-assistant/home-assistant/pull/19440 [@ehendrix23]: https://github.com/ehendrix23 [@mopolus]: https://github.com/mopolus [ihc docs]: /integrations/ihc/ [遥控器.harmony docs]: /integrations/harmony ## 发布 0.84.5 - December 19 * Fix Harmony for people not running Home Assistant in Docker ([@ehendrix23]) ## 发布 0.84.6 - December 21 * Fix incorrect local check when creating webhooks via a config flow (impacted all but Owntracks) ([@balloob] - [#19494]) [#19494]: https://github.com/home-assistant/home-assistant/pull/19494 [@balloob]: https://github.com/balloob #### 前端 * 修复以百分比设置宽高比的问题 ([#2289](https://github.com/home-assistant/home-assistant-polymer/pull/2289)) [@balloob] * 修复点击遮罩关闭时编辑对话框会打开两次的问题 ([#2290](https://github.com/home-assistant/home-assistant-polymer/pull/2290)) [@balloob] * 修复首次加载时翻译未加载的问题 ([#2293](https://github.com/home-assistant/home-assistant-polymer/pull/2293)) [@balloob] * 移除恒温器和灯光的动画效果 ([#2303](https://github.com/home-assistant/home-assistant-polymer/pull/2303)) [@zsarnett] * 修复图片元素定位问题 ([#2335](https://github.com/home-assistant/home-assistant-polymer/pull/2335)) [@iantrich] * 修复 plant/天气 卡片中出现 undefined 的问题 ([#2339](https://github.com/home-assistant/home-assistant-polymer/pull/2339)) [@balloob] * 修复服务按钮元素 ([#2343](https://github.com/home-assistant/home-assistant-polymer/pull/2343)) [@balloob] [#18737]: https://github.com/home-assistant/home-assistant/pull/18737 [#19284]: https://github.com/home-assistant/home-assistant/pull/19284 [#19344]: https://github.com/home-assistant/home-assistant/pull/19344 [@ahayworth]: https://github.com/ahayworth [@glentakahashi]: https://github.com/glentakahashi [@zsarnett]: https://github.com/zsarnett [@iantrich]: https://github.com/iantrich [@liaanvdm]: https://github.com/liaanvdm [alarm_control_panel.manual docs]: /integrations/manual [config docs]: /integrations/config/ [门锁.zwave docs]: /integrations/zwave#门锁 ## 如果你需要帮助... ...欢迎随时使用我们非常活跃的[论坛](https://community.home-assistant.io/),或加入我们的[聊天频道](https://discord.gg/c5DvZ4e)。发布说明虽然开启了评论,但我们更推荐你使用前面的沟通渠道。谢谢。 ## 问题反馈 遇到了这个发布引入的问题吗?请在我们的 [issue tracker](https://github.com/home-assistant/home-assistant/issues) 中反馈。请确保填写 issue 模板中的所有字段。 ## 不向后兼容的变更 * 状态 restoration will not work the first time you start 0.84. ([@armills] - [#17270]) ([history docs]) * Support for multiple IHC controllers added. Manual IHC 设备 配置 must be moved from platform sections to controller 配置 section under the ihc component section. ([@mopolus] - [#18058]) ([ihc docs]) ([binary\_sensor.ihc docs][binary_sensor.ihc docs]) ([灯光.ihc docs]) ([开关.ihc docs]) (breaking change) * Lutron: Change device\_state\_attributes() to use lowercase snakecase (Rename 'Lutron 集成 ID' to 'lutron\_integration\_id') ([@cdheiser] - [#18650]) ([灯光.lutron docs]) (breaking change) * Remove "since last boot" from systemmonitor 传感器, use `last_boot` instead. ([@balloob] - [#18644]) ([传感器.systemmonitor docs]) (breaking change) * All MQTT 灯光 are merged into a single platform: `light.mqtt` ([@emontnemery] - [#18227]) ([MQTT docs]) ([灯光.MQTT docs]) (breaking change) (new-platform) * Use a Webhook to send data to push 摄像头 ([@dgomes] - [#18380]) ([摄像头.push docs]) (breaking change) * Call 服务 directly. 自动化 and 脚本 will now stop executing when a 服务 call fails. The `service_executed` event is no longer being fired when a 服务 is done. ([@balloob] - [#18720]) (breaking change) * Fix issues with 17track.net 传感器 names. See PR for details. ([@bachya] - [#18860]) ([传感器.seventeentrack docs]) (breaking change) * rtorrent: Changed the returned 状态 of 传感器.rtorrent from `Up`/`Down`, `Downloading` and `Seeding` to `up_down`, `downloading` and `seeding` to reflect the guidelines. Hence by 自动化 relying on the 状态 of this 传感器 should be updated. ([@eliseomartelli] - [#18778]) ([传感器.rtorrent docs]) (breaking change) * Blink 报警 control 面板 now inherits the name of the actual sync module rather than defaulting to blink\_sync ([@fronzbot] - [#18663]) ([blink docs]) ([alarm\_control\_panel.blink docs][alarm_control_panel.blink docs]) ([binary\_sensor.blink docs][binary_sensor.blink docs]) ([摄像头.blink docs]) ([传感器.blink docs]) (breaking change) * Fix toon operation mode to follow our 温控 standard so it will work with Google Assistant / Alexa. ([@balloob] - [#18966]) ([温控.toon docs]) (breaking change) * Waterfurnace: the unit parameter is removed from config. ([@sdague] - [#19040]) ([waterfurnace docs]) (breaking change) * RainMachine: `configuration.yaml` format has changed to add support for multiple RainMachine controllers ([@bachya] - [#18989]) ([rainmachine docs]) (breaking change) * Fibaro: the `id` 属性 has been renamed to `fibaro_id` ([@pbalogh77] - [#19055]) ([fibaro docs]) (breaking change) * Remove Instapush 通知 platform ([@fabaff] - [#19051]) ([通知 docs]) (breaking change) ## Beta 修复 * Revert #17745 ([@balloob] - [#19064]) ([google\_assistant docs][google_assistant docs]) (beta fix) * Fix missing colorTemperatureInKelvin from Alexa responses ([@mikeage] - [#19069]) ([alexa docs]) (beta fix) * Force refresh Lovelace ([@bramkragten] - [#19073]) ([Lovelace docs]) (beta fix) * 升级 aiolifx to 0.6.7 ([@amelchio] - [#19077]) ([lifx docs]) (beta fix) * 升级 pyatv to 0.3.12 ([@postlund] - [#19085]) ([apple\_tv docs][apple_tv docs]) (beta fix) * 升级 Tibber lib ([@Danielhiversen] - [#19098]) ([tibber docs]) (beta fix) * Bump skybellpy 版本 to fix api issue ([@nhorvath] - [#19100]) ([skybell docs]) (beta fix) * Lovelace using storage ([@balloob] - [#19101]) ([前端 docs]) ([Lovelace docs]) (beta fix) * Remove marking 设备 tracker stale if 状态 is stale ([@arigilder] - [#19133]) ([device\_tracker docs][device_tracker docs]) (beta fix) * Google assistant fix target temp for \*F values. ([@marchingphoenix] - [#19083]) ([google\_assistant docs][google_assistant docs]) (beta fix) * Drop OwnTracks bad packets ([@balloob] - [#19161]) ([owntracks docs]) (beta fix) * Fix Lovelace save ([@balloob] - [#19162]) ([Lovelace docs]) (beta fix) * Add raw 服务 data to event ([@balloob] - [#19163]) (beta fix) * Fix cloud defaults ([@balloob] - [#19172]) ([cloud docs]) (beta fix) * Revert PR #18602 ([@balloob] - [#19188]) ([摄像头.mjpeg docs]) (beta fix) ## 全部变更 * Add /sbin to launchd PATH ([@andersonshatch] - [#18601]) * Minor change to still 图像 on mjpeg ([@nragon] - [#18602]) ([摄像头.mjpeg docs]) * Cleanup BOM dependencies + add basic test + IDEA autoformat ([@nickw444] - [#18462]) * Add support for multiple IHC controllers ([@mopolus] - [#18058]) ([ihc docs]) ([binary\_sensor.ihc docs][binary_sensor.ihc docs]) ([灯光.ihc docs]) ([开关.ihc docs]) (breaking change) * Add support for cropping pictures in proxy 摄像头 ([@glpatcern] - [#18431]) ([摄像头.proxy docs]) * Refactor ZHA ([@dmulcahey] - [#18629]) ([zha docs]) ([binary\_sensor.zha docs][binary_sensor.zha docs]) ([风扇.zha docs]) ([灯光.zha docs]) ([传感器.zha docs]) ([开关.zha docs]) (new-platform) * IPMA 天气 服务 - 版本 bump ([@dgomes] - [#18626]) ([天气.ipma docs]) * \[Breaking Change] Cleanup Lutron 灯光 component ([@cdheiser] - [#18650]) ([灯光.lutron docs]) (breaking change) * Convert 设备 tracker init tests to async ([@armills] - [#18640]) * Remove since last boot from systemmonitor 传感器 ([@balloob] - [#18644]) ([传感器.systemmonitor docs]) (breaking change) * Added deviceclass timestamp constant ([@eliseomartelli] - [#18652]) * Add save command to Lovelace ([@bramkragten] - [#18655]) ([Lovelace docs]) * converted majority of effects from ifs to dict map, which makes it easier to extend in the future. Also, added LSD effect! ([@pagenoare] - [#18656]) ([灯光.yeelight docs]) * Dict -> dict ([@bramkragten] - [#18665]) ([Lovelace docs]) * Reconfigure MQTT 温控 component if discovery info is changed ([@emontnemery] - [#18174]) ([MQTT docs]) ([binary\_sensor.MQTT docs][binary_sensor.MQTT docs]) ([温控.MQTT docs]) * Reconfigure MQTT 报警 component if discovery info is changed ([@emontnemery] - [#18173]) ([MQTT docs]) ([alarm\_control\_panel.MQTT docs][alarm_control_panel.MQTT docs]) ([binary\_sensor.MQTT docs][binary_sensor.MQTT docs]) * Async tests for 设备 tracker MQTT ([@armills] - [#18680]) * Async tests for remaining 设备 trackers ([@armills] - [#18682]) * Async timer tests ([@armills] - [#18683]) * Async tests for counter ([@armills] - [#18684]) * Async tests for MQTT 开关 ([@armills] - [#18685]) * Add Awair 传感器 platform ([@ahayworth] - [#18570]) ([传感器.awair docs]) (new-platform) * 更新 mill lib, handle bad data from mill server ([@Danielhiversen] - [#18693]) ([温控.mill docs]) * 升级 youtube\_dl to 2018.11.23 ([@fabaff] - [#18694]) ([media\_extractor docs][media_extractor docs]) * Fix false 日志 message on CAPsMAN only 设备 ([@soosp] - [#18687]) ([device\_tracker docs][device_tracker docs]) * Adds SomfyContactIOSystemSensor to TaHoma ([@jensihnow] - [#18560]) * Async 设备 sun 灯光 触发器 tests ([@armills] - [#18689]) * Async 遮盖 模板 tests ([@armills] - [#18690]) * 升级 pysnmp to 4.4.6 ([@fabaff] - [#18695]) ([device\_tracker docs][device_tracker docs]) ([传感器.snmp docs]) ([开关.snmp docs]) * :arrow\_up: Upgrades InfluxDB dependency to 5.2.0 ([@frenck] - [#18668]) ([influxdb docs]) ([传感器.influxdb docs]) * Small refactoring of MQTT binary\_sensor ([@emontnemery] - [#18674]) ([binary\_sensor.MQTT docs][binary_sensor.MQTT docs]) * Allow managing cloud Webhook ([@balloob] - [#18672]) ([cloud docs]) (new-platform) * 升级 pytest and -timeout ([@scop] - [#18722]) * Remove some unused imports ([@scop] - [#18732]) * Enforce permissions for Websocket API ([@balloob] - [#18719]) ([websocket\_api docs][websocket_api docs]) * remove pbkdf2 升级 path ([@Eriner] - [#18736]) * Reconfigure MQTT 遮盖 component if discovery info is changed ([@emontnemery] - [#18175]) ([MQTT docs]) ([binary\_sensor.MQTT docs][binary_sensor.MQTT docs]) ([遮盖.MQTT docs]) * Reconfigure MQTT 风扇 component if discovery info is changed ([@emontnemery] - [#18177]) ([MQTT docs]) ([binary\_sensor.MQTT docs][binary_sensor.MQTT docs]) ([风扇.MQTT docs]) * Reconfigure MQTT 传感器 component if discovery info is changed ([@emontnemery] - [#18178]) ([MQTT docs]) ([binary\_sensor.MQTT docs][binary_sensor.MQTT docs]) ([传感器.MQTT docs]) * Add 区域 to evohome component ([@zxdavb] - [#18428]) ([evohome docs]) ([温控.evohome docs]) * U.S. Geological Survey Earthquake Hazards Program Feed platform ([@exxamalte] - [#18207]) ([geo\_location docs][geo_location docs]) (new-platform) * Geo Location platform code clean up ([@exxamalte] - [#18717]) ([geo\_location docs][geo_location docs]) * Fix remaining issues ([@fabaff] - [#18416]) ([灯光.niko\_home\_control docs][灯光.niko_home_control docs]) * 更新 librouteros and re-connect to api if connection is lost ([@slackr31337] - [#18421]) ([device\_tracker docs][device_tracker docs]) * MQTT 灯光 refactor ([@emontnemery] - [#18227]) ([MQTT docs]) ([灯光.MQTT docs]) (breaking change) (new-platform) * Supports the new Netatmo Home Coach ([@lasote] - [#18308]) ([netatmo docs]) ([传感器.netatmo docs]) * Fix google assistant request sync 服务 call ([@awarecan] - [#17415]) ([google\_assistant docs][google_assistant docs]) * Updated codeowners ([@fredrike] - [#18746]) * Add unique\_id for tellduslive ([@fredrike] - [#18744]) ([tellduslive docs]) ([传感器.tellduslive docs]) * Add unique\_id for Daikin 实体 ([@fredrike] - [#18747]) ([daikin docs]) ([温控.daikin docs]) ([传感器.daikin docs]) * Wunderlist component ([@lasote] - [#18339]) * Fix decora\_wifi residences ([@trainman419] - [#17228]) ([灯光.decora\_wifi docs][灯光.decora_wifi docs]) * Enable Google Assistant OnOffTrait for 温控 设备 that support them ([@bryanyork] - [#18544]) ([google\_assistant docs][google_assistant docs]) * Fix typo in 日志 ([@anton-johansson] - [#18751]) * Bumped simplisafe-python to 3.1.14 ([@bachya] - [#18752]) ([simplisafe docs]) * Moved stop method and registering STOP\_EVENT outside of init ([@ehendrix23] - [#18582]) ([august docs]) * Add config entry for ZHA ([@damarco] - [#18352]) ([zha docs]) ([binary\_sensor.zha docs][binary_sensor.zha docs]) ([风扇.zha docs]) ([灯光.zha docs]) ([传感器.zha docs]) ([开关.zha docs]) * 更新 lupupy 版本 to 0.0.13 ([@majuss] - [#18754]) ([lupusec docs]) * Replace token in 摄像头.push with Webhook ([@dgomes] - [#18380]) ([摄像头.push docs]) (breaking change) * 恢复 状态 through a JSON store instead of recorder ([@armills] - [#17270]) ([history docs]) * Forbid float NaN in JSON ([@balloob] - [#18757]) ([http docs]) ([websocket\_api docs][websocket_api docs]) * 升级 Adafruit-DHT to 1.4.0 (fixes #15847) ([@fabaff] - [#18614]) ([传感器.dht docs]) * Add block after setting up component ([@ehendrix23] - [#18756]) * Fix statistics for 二元sensor ([@ehendrix23] - [#18764]) ([传感器.statistics docs]) * Convert shopping-list clear to WebSockets ([@iantrich] - [#18769]) ([shopping\_list docs][shopping_list docs]) * Add more waterfurnace 传感器 ([@mdallaire] - [#18451]) ([传感器.waterfurnace docs]) * Round average price for Tibber ([@Danielhiversen] - [#18784]) ([传感器.tibber docs]) * Raise NotImplementedError ([@balloob] - [#18777]) ([owntracks docs]) * 更新 switchmate lib ([@Danielhiversen] - [#18785]) ([开关.switchmate docs]) * 更新 lang list (fixes #18768) ([@fabaff] - [#18773]) ([tts docs]) * Added qbittorrent 传感器 platform ([@eliseomartelli] - [#18618]) ([传感器.qbittorrent docs]) (new-platform) * Add support for Mode trait in Google Assistant. ([@marchingphoenix] - [#18772]) ([google\_assistant docs][google_assistant docs]) * 服务 already discovered 日志 entry ([@ehendrix23] - [#18800]) * Increase pyatv to 0.3.11 ([@ehendrix23] - [#18801]) ([apple\_tv docs][apple_tv docs]) * Store 状态 last seen time separately ([@armills] - [#18806]) * Bump python\_awair to 0.0.3 ([@ahayworth] - [#18819]) ([传感器.awair docs]) * Add Entur departure information 传感器 ([@hfurubotten] - [#17286]) ([传感器.entur\_public\_transport docs][传感器.entur_public_transport docs]) (new-platform) * 更新 netatmo library ([@Danielhiversen] - [#18823]) ([netatmo docs]) * Add 服务 description ([@schmittx] - [#18839]) * 更新 of volvooncall component ([@molobrakos] - [#18702]) ([device\_tracker docs][device_tracker docs]) ([volvooncall docs]) ([binary\_sensor.volvooncall docs][binary_sensor.volvooncall docs]) ([门锁.volvooncall docs]) ([传感器.volvooncall docs]) ([开关.volvooncall docs]) * Fix flaky geofency test ([@balloob] - [#18855]) * RFC: Call 服务 directly ([@balloob] - [#18720]) (breaking change) * Bump py17track to 2.1.1 ([@bachya] - [#18861]) ([传感器.seventeentrack docs]) * Fix issues with 17track.net 传感器 names ([@bachya] - [#18860]) ([传感器.seventeentrack docs]) (breaking change) * Add tests for directv platform ([@ehendrix23] - [#18590]) * Add support for zha 设备 registry ([@damarco] - [#18755]) ([zha docs]) * Added new filters for 模板 ([@skalavala] - [#18125]) * Updated UVC 摄像头 component to support SSL connections ([@carlos-sarmiento] - [#18829]) ([摄像头.uvc docs]) * fixed 状态 case for rtorrent ([@eliseomartelli] - [#18778]) ([传感器.rtorrent docs]) (breaking change) * Fix ordinal filter in 模板 ([@ludeeus] - [#18878]) * Reintroduce unique\_id for Netatmo 传感器 ([@heinemml] - [#18774]) ([传感器.netatmo docs]) * 升级 keyring to 17.0.0 ([@fabaff] - [#18901]) * 升级 sphinx-autodoc-typehints to 1.5.1 ([@fabaff] - [#18893]) * Small refactoring of MQTT 遮盖 ([@emontnemery] - [#18850]) ([遮盖.MQTT docs]) * Small refactoring of MQTT 报警 ([@emontnemery] - [#18813]) ([alarm\_control\_panel.MQTT docs][alarm_control_panel.MQTT docs]) * Small refactoring of MQTT 温控 ([@emontnemery] - [#18814]) ([温控.MQTT docs]) * Optionally do not 日志 模板 rendering 错误 ([@emontnemery] - [#18724]) * 恢复 状态 when removing/adding 实体 ([@armills] - [#18890]) * Fibaro ubs ([@pbalogh77] - [#18889]) ([fibaro docs]) ([binary\_sensor.fibaro docs][binary_sensor.fibaro docs]) * Use string formatting ([@fabaff] - [#18886]) ([sense docs]) ([binary\_sensor.sense docs][binary_sensor.sense docs]) ([传感器.sense docs]) * Show ANSI color codes in 日志 in Hass.io ([@OttoWinter] - [#18834]) ([hassio docs]) * Fix hdmi\_cec 实体 race ([@yottatsa] - [#18753]) ([hdmi\_cec docs][hdmi_cec docs]) ([媒体播放器.hdmi\_cec docs][媒体播放器.hdmi_cec docs]) ([开关.hdmi\_cec docs][开关.hdmi_cec docs]) * Set 传感器 to unavailable if battery is dead. ([@fucm] - [#18802]) ([binary\_sensor.tahoma docs][binary_sensor.tahoma docs]) * Reconfigure MQTT 灯光 component if discovery info is changed ([@emontnemery] - [#18176]) ([MQTT docs]) ([binary\_sensor.MQTT docs][binary_sensor.MQTT docs]) ([灯光.MQTT docs]) * Reconfigure MQTT 开关 component if discovery info is changed ([@emontnemery] - [#18179]) ([MQTT docs]) ([binary\_sensor.MQTT docs][binary_sensor.MQTT docs]) ([开关.MQTT docs]) * No more opt-out auth ([@balloob] - [#18854]) ([config docs]) ([前端 docs]) ([hassio docs]) ([http docs]) ([通知 docs]) ([websocket\_api docs][websocket_api docs]) * Remove commented out code ([@emontnemery] - [#18925]) ([温控.MQTT docs]) * Add lightwave components for 开关 and 灯光 ([@GeoffAtHome] - [#18026]) ([lightwave docs]) ([灯光.lightwave docs]) ([开关.lightwave docs]) (new-platform) * Allow verisure 门锁 to be configured with a default code ([@ahayworth] - [#18873]) ([verisure docs]) ([门锁.verisure docs]) * Initial hlk-sw16 relay 开关 support ([@jameshilliard] - [#17855]) ([hlk\_sw16 docs][hlk_sw16 docs]) ([开关.hlk\_sw16 docs][开关.hlk_sw16 docs]) (new-platform) * Push to 版本 0.7.7 of denonavr ([@scarface-4711] - [#18917]) ([媒体播放器.denonavr docs]) * Extend partial 重载 to include packages ([@cdce8p] - [#18884]) * Initial 场景 support for Fibaro hubs ([@pbalogh77] - [#18779]) ([fibaro docs]) ([场景.fibaro docs]) (new-platform) * Add id when not exist and fix dup id check ([@bramkragten] - [#18960]) ([Lovelace docs]) * Refactor 脚本 助手 动作 into their own methods ([@balloob] - [#18962]) * Point fix for multiple 设备 ([@fredrike] - [#18959]) ([point docs]) ([binary\_sensor.point docs][binary_sensor.point docs]) ([传感器.point docs]) * VOC: 更新 library 版本. Moved method one step out. Instruments can be a set as well ([@molobrakos] - [#18967]) * Support for mulitple Blink sync modules ([@fronzbot] - [#18663]) ([blink docs]) ([alarm\_control\_panel.blink docs][alarm_control_panel.blink docs]) ([binary\_sensor.blink docs][binary_sensor.blink docs]) ([摄像头.blink docs]) ([传感器.blink docs]) (breaking change) * no ordered dict ([@bramkragten] - [#18982]) ([Lovelace docs]) * 更新 CODEOWNERS ([@ludeeus] - [#18976]) * Add @danielhiversen as codeowner ([@Danielhiversen] - [#18979]) * 升级 switchbot lib ([@Danielhiversen] - [#18980]) ([开关.switchbot docs]) * New Events and Context Fixes ([@hunterjm] - [#18765]) ([自动化 docs]) ([image\_processing docs][image_processing docs]) ([logbook docs]) ([脚本 docs]) * Updated Yale Smart 报警 platform to new Yale API ([@domwillcode] - [#18990]) ([alarm\_control\_panel.yale\_smart\_alarm docs][alarm_control_panel.yale_smart_alarm docs]) * Lovelace fix: badges are removed from view after 更新 ([@bramkragten] - [#18983]) ([Lovelace docs]) * remove the need to have query feature support ([@ticapix] - [#18942]) ([influxdb docs]) * Tellduslive refactoring ([@fredrike] - [#18780]) ([tellduslive docs]) ([binary\_sensor.tellduslive docs][binary_sensor.tellduslive docs]) ([遮盖.tellduslive docs]) ([灯光.tellduslive docs]) ([传感器.tellduslive docs]) ([开关.tellduslive docs]) (new-platform) * Add unnecessary-pass for pylint-更新 ([@cdce8p] - [#18985]) * Mock out 设备 tracker 配置 loading funcs in Geofency + OwnTracks ([@balloob] - [#18968]) * Fibaro 灯光 fixes ([@pbalogh77] - [#18972]) ([fibaro docs]) ([灯光.fibaro docs]) * Sort import order of zha component. ([@Adminiuga] - [#18993]) ([zha docs]) ([binary\_sensor.zha docs][binary_sensor.zha docs]) ([风扇.zha docs]) ([灯光.zha docs]) ([传感器.zha docs]) ([开关.zha docs]) * Fix VOC 配置 resource list ([@bratanon] - [#18992]) ([volvooncall docs]) * Fix toon operation mode ([@balloob] - [#18966]) ([温控.toon docs]) (breaking change) * Remove stale 用户 salts code ([@Eriner] - [#19004]) * Lupupy 版本 push to 0.0.17 - will now transmitted state\_alarm\_triggered ([@majuss] - [#19008]) ([lupusec docs]) ([alarm\_control\_panel.lupusec docs][alarm_control_panel.lupusec docs]) * 更新 requirement btsmarthub\_devicelist==0.1.3 ([@jxwolstenholme] - [#18961]) ([device\_tracker docs][device_tracker docs]) * Allow checking 实体 permissions based on 设备 ([@balloob] - [#19007]) * Add 状态 to 面板 ([@bramkragten] - [#19026]) ([前端 docs]) * Fix CI by pinning IDNA ([@balloob] - [#19038]) * Bump waterfurnace to 1.0 ([@sdague] - [#19040]) ([waterfurnace docs]) (breaking change) * Don't wait for answer for Webhook register ([@balloob] - [#19025]) ([cloud docs]) * Small refactoring of MQTT 灯光 ([@emontnemery] - [#19009]) ([灯光.MQTT docs]) * Small refactoring of MQTT 开关 ([@emontnemery] - [#19010]) ([开关.MQTT docs]) * Bump 版本 of elkm1\_lib ([@gwww] - [#19030]) ([elkm1 docs]) * Change 错误 to 警告 ([@doudz] - [#19035]) ([媒体播放器.plex docs]) * Catch 'BrokenPipeError' exceptions for ADB commands ([@JeffLIrion] - [#19011]) ([媒体播放器.firetv docs]) * Bump python-miio to 0.4.4 ([@rytilahti] - [#19042]) ([device\_tracker docs][device_tracker docs]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) ([灯光.xiaomi\_miio docs][灯光.xiaomi_miio docs]) ([遥控器.xiaomi\_miio docs][遥控器.xiaomi_miio docs]) ([传感器.xiaomi\_miio docs][传感器.xiaomi_miio docs]) ([开关.xiaomi\_miio docs][开关.xiaomi_miio docs]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) * Add last clean times to xiaomi 吸尘器 ([@rytilahti] - [#19043]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) * Add support for multiple RainMachine controllers ([@bachya] - [#18989]) ([rainmachine docs]) (breaking change) * Remove unsupported strong mode of the Xiaomi Air 加湿器 CA1 ([@syssi] - [#18926]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) * Bump pyvizio 版本 ([@photinus] - [#19048]) ([媒体播放器.vizio docs]) * Fix cloud const ([@balloob] - [#19052]) ([cloud docs]) * VOC: 更新 external dependency to fix engine start issue ([@molobrakos] - [#19062]) ([volvooncall docs]) * Fix saving YAML as JSON with empty array ([@bramkragten] - [#19057]) ([Lovelace docs]) * 更新 pyhomematic to 0.1.53 ([@danielperna84] - [#19056]) ([homematic docs]) * Implemented unique ID support for Fibaro hub 集成 ([@pbalogh77] - [#19055]) ([fibaro docs]) (breaking change) * Remove Instapush 通知 platform ([@fabaff] - [#19051]) ([通知 docs]) (breaking change) * 更新 locationsharinglib to 3.0.9 ([@pc-coholic] - [#19045]) ([device\_tracker docs][device_tracker docs]) * Add support for more Tibber Pulse data ([@Danielhiversen] - [#19033]) ([tibber docs]) ([传感器.tibber docs]) * Revert #17745 ([@balloob] - [#19064]) ([google\_assistant docs][google_assistant docs]) (beta fix) * Fix missing colorTemperatureInKelvin from Alexa responses ([@mikeage] - [#19069]) ([alexa docs]) (beta fix) * Force refresh Lovelace ([@bramkragten] - [#19073]) ([Lovelace docs]) (beta fix) * 升级 aiolifx to 0.6.7 ([@amelchio] - [#19077]) ([lifx docs]) (beta fix) * 升级 pyatv to 0.3.12 ([@postlund] - [#19085]) ([apple\_tv docs][apple_tv docs]) (beta fix) * 升级 Tibber lib ([@Danielhiversen] - [#19098]) ([tibber docs]) (beta fix) * Bump skybellpy 版本 to fix api issue ([@nhorvath] - [#19100]) ([skybell docs]) (beta fix) * Lovelace using storage ([@balloob] - [#19101]) ([前端 docs]) ([Lovelace docs]) (beta fix) * Remove marking 设备 tracker stale if 状态 is stale ([@arigilder] - [#19133]) ([device\_tracker docs][device_tracker docs]) (beta fix) * Google assistant fix target temp for \*F values. ([@marchingphoenix] - [#19083]) ([google\_assistant docs][google_assistant docs]) (beta fix) * Drop OwnTracks bad packets ([@balloob] - [#19161]) ([owntracks docs]) (beta fix) * Fix Lovelace save ([@balloob] - [#19162]) ([Lovelace docs]) (beta fix) * Add raw 服务 data to event ([@balloob] - [#19163]) (beta fix) * Fix cloud defaults ([@balloob] - [#19172]) ([cloud docs]) (beta fix) * Revert PR #18602 ([@balloob] - [#19188]) ([摄像头.mjpeg docs]) (beta fix) [#17228]: https://github.com/home-assistant/home-assistant/pull/17228 [#17270]: https://github.com/home-assistant/home-assistant/pull/17270 [#17286]: https://github.com/home-assistant/home-assistant/pull/17286 [#17415]: https://github.com/home-assistant/home-assistant/pull/17415 [#17855]: https://github.com/home-assistant/home-assistant/pull/17855 [#18026]: https://github.com/home-assistant/home-assistant/pull/18026 [#18058]: https://github.com/home-assistant/home-assistant/pull/18058 [#18125]: https://github.com/home-assistant/home-assistant/pull/18125 [#18173]: https://github.com/home-assistant/home-assistant/pull/18173 [#18174]: https://github.com/home-assistant/home-assistant/pull/18174 [#18175]: https://github.com/home-assistant/home-assistant/pull/18175 [#18176]: https://github.com/home-assistant/home-assistant/pull/18176 [#18177]: https://github.com/home-assistant/home-assistant/pull/18177 [#18178]: https://github.com/home-assistant/home-assistant/pull/18178 [#18179]: https://github.com/home-assistant/home-assistant/pull/18179 [#18207]: https://github.com/home-assistant/home-assistant/pull/18207 [#18227]: https://github.com/home-assistant/home-assistant/pull/18227 [#18308]: https://github.com/home-assistant/home-assistant/pull/18308 [#18339]: https://github.com/home-assistant/home-assistant/pull/18339 [#18352]: https://github.com/home-assistant/home-assistant/pull/18352 [#18380]: https://github.com/home-assistant/home-assistant/pull/18380 [#18416]: https://github.com/home-assistant/home-assistant/pull/18416 [#18421]: https://github.com/home-assistant/home-assistant/pull/18421 [#18428]: https://github.com/home-assistant/home-assistant/pull/18428 [#18431]: https://github.com/home-assistant/home-assistant/pull/18431 [#18451]: https://github.com/home-assistant/home-assistant/pull/18451 [#18462]: https://github.com/home-assistant/home-assistant/pull/18462 [#18544]: https://github.com/home-assistant/home-assistant/pull/18544 [#18560]: https://github.com/home-assistant/home-assistant/pull/18560 [#18570]: https://github.com/home-assistant/home-assistant/pull/18570 [#18582]: https://github.com/home-assistant/home-assistant/pull/18582 [#18590]: https://github.com/home-assistant/home-assistant/pull/18590 [#18601]: https://github.com/home-assistant/home-assistant/pull/18601 [#18602]: https://github.com/home-assistant/home-assistant/pull/18602 [#18614]: https://github.com/home-assistant/home-assistant/pull/18614 [#18618]: https://github.com/home-assistant/home-assistant/pull/18618 [#18626]: https://github.com/home-assistant/home-assistant/pull/18626 [#18629]: https://github.com/home-assistant/home-assistant/pull/18629 [#18640]: https://github.com/home-assistant/home-assistant/pull/18640 [#18644]: https://github.com/home-assistant/home-assistant/pull/18644 [#18650]: https://github.com/home-assistant/home-assistant/pull/18650 [#18652]: https://github.com/home-assistant/home-assistant/pull/18652 [#18655]: https://github.com/home-assistant/home-assistant/pull/18655 [#18656]: https://github.com/home-assistant/home-assistant/pull/18656 [#18663]: https://github.com/home-assistant/home-assistant/pull/18663 [#18665]: https://github.com/home-assistant/home-assistant/pull/18665 [#18668]: https://github.com/home-assistant/home-assistant/pull/18668 [#18672]: https://github.com/home-assistant/home-assistant/pull/18672 [#18674]: https://github.com/home-assistant/home-assistant/pull/18674 [#18680]: https://github.com/home-assistant/home-assistant/pull/18680 [#18682]: https://github.com/home-assistant/home-assistant/pull/18682 [#18683]: https://github.com/home-assistant/home-assistant/pull/18683 [#18684]: https://github.com/home-assistant/home-assistant/pull/18684 [#18685]: https://github.com/home-assistant/home-assistant/pull/18685 [#18687]: https://github.com/home-assistant/home-assistant/pull/18687 [#18689]: https://github.com/home-assistant/home-assistant/pull/18689 [#18690]: https://github.com/home-assistant/home-assistant/pull/18690 [#18693]: https://github.com/home-assistant/home-assistant/pull/18693 [#18694]: https://github.com/home-assistant/home-assistant/pull/18694 [#18695]: https://github.com/home-assistant/home-assistant/pull/18695 [#18702]: https://github.com/home-assistant/home-assistant/pull/18702 [#18717]: https://github.com/home-assistant/home-assistant/pull/18717 [#18719]: https://github.com/home-assistant/home-assistant/pull/18719 [#18720]: https://github.com/home-assistant/home-assistant/pull/18720 [#18722]: https://github.com/home-assistant/home-assistant/pull/18722 [#18724]: https://github.com/home-assistant/home-assistant/pull/18724 [#18732]: https://github.com/home-assistant/home-assistant/pull/18732 [#18736]: https://github.com/home-assistant/home-assistant/pull/18736 [#18744]: https://github.com/home-assistant/home-assistant/pull/18744 [#18746]: https://github.com/home-assistant/home-assistant/pull/18746 [#18747]: https://github.com/home-assistant/home-assistant/pull/18747 [#18751]: https://github.com/home-assistant/home-assistant/pull/18751 [#18752]: https://github.com/home-assistant/home-assistant/pull/18752 [#18753]: https://github.com/home-assistant/home-assistant/pull/18753 [#18754]: https://github.com/home-assistant/home-assistant/pull/18754 [#18755]: https://github.com/home-assistant/home-assistant/pull/18755 [#18756]: https://github.com/home-assistant/home-assistant/pull/18756 [#18757]: https://github.com/home-assistant/home-assistant/pull/18757 [#18764]: https://github.com/home-assistant/home-assistant/pull/18764 [#18765]: https://github.com/home-assistant/home-assistant/pull/18765 [#18769]: https://github.com/home-assistant/home-assistant/pull/18769 [#18772]: https://github.com/home-assistant/home-assistant/pull/18772 [#18773]: https://github.com/home-assistant/home-assistant/pull/18773 [#18774]: https://github.com/home-assistant/home-assistant/pull/18774 [#18777]: https://github.com/home-assistant/home-assistant/pull/18777 [#18778]: https://github.com/home-assistant/home-assistant/pull/18778 [#18779]: https://github.com/home-assistant/home-assistant/pull/18779 [#18780]: https://github.com/home-assistant/home-assistant/pull/18780 [#18784]: https://github.com/home-assistant/home-assistant/pull/18784 [#18785]: https://github.com/home-assistant/home-assistant/pull/18785 [#18800]: https://github.com/home-assistant/home-assistant/pull/18800 [#18801]: https://github.com/home-assistant/home-assistant/pull/18801 [#18802]: https://github.com/home-assistant/home-assistant/pull/18802 [#18806]: https://github.com/home-assistant/home-assistant/pull/18806 [#18813]: https://github.com/home-assistant/home-assistant/pull/18813 [#18814]: https://github.com/home-assistant/home-assistant/pull/18814 [#18819]: https://github.com/home-assistant/home-assistant/pull/18819 [#18823]: https://github.com/home-assistant/home-assistant/pull/18823 [#18829]: https://github.com/home-assistant/home-assistant/pull/18829 [#18834]: https://github.com/home-assistant/home-assistant/pull/18834 [#18839]: https://github.com/home-assistant/home-assistant/pull/18839 [#18850]: https://github.com/home-assistant/home-assistant/pull/18850 [#18854]: https://github.com/home-assistant/home-assistant/pull/18854 [#18855]: https://github.com/home-assistant/home-assistant/pull/18855 [#18860]: https://github.com/home-assistant/home-assistant/pull/18860 [#18861]: https://github.com/home-assistant/home-assistant/pull/18861 [#18873]: https://github.com/home-assistant/home-assistant/pull/18873 [#18878]: https://github.com/home-assistant/home-assistant/pull/18878 [#18884]: https://github.com/home-assistant/home-assistant/pull/18884 [#18886]: https://github.com/home-assistant/home-assistant/pull/18886 [#18889]: https://github.com/home-assistant/home-assistant/pull/18889 [#18890]: https://github.com/home-assistant/home-assistant/pull/18890 [#18893]: https://github.com/home-assistant/home-assistant/pull/18893 [#18901]: https://github.com/home-assistant/home-assistant/pull/18901 [#18917]: https://github.com/home-assistant/home-assistant/pull/18917 [#18925]: https://github.com/home-assistant/home-assistant/pull/18925 [#18926]: https://github.com/home-assistant/home-assistant/pull/18926 [#18942]: https://github.com/home-assistant/home-assistant/pull/18942 [#18959]: https://github.com/home-assistant/home-assistant/pull/18959 [#18960]: https://github.com/home-assistant/home-assistant/pull/18960 [#18961]: https://github.com/home-assistant/home-assistant/pull/18961 [#18962]: https://github.com/home-assistant/home-assistant/pull/18962 [#18966]: https://github.com/home-assistant/home-assistant/pull/18966 [#18967]: https://github.com/home-assistant/home-assistant/pull/18967 [#18968]: https://github.com/home-assistant/home-assistant/pull/18968 [#18972]: https://github.com/home-assistant/home-assistant/pull/18972 [#18976]: https://github.com/home-assistant/home-assistant/pull/18976 [#18979]: https://github.com/home-assistant/home-assistant/pull/18979 [#18980]: https://github.com/home-assistant/home-assistant/pull/18980 [#18982]: https://github.com/home-assistant/home-assistant/pull/18982 [#18983]: https://github.com/home-assistant/home-assistant/pull/18983 [#18985]: https://github.com/home-assistant/home-assistant/pull/18985 [#18989]: https://github.com/home-assistant/home-assistant/pull/18989 [#18990]: https://github.com/home-assistant/home-assistant/pull/18990 [#18992]: https://github.com/home-assistant/home-assistant/pull/18992 [#18993]: https://github.com/home-assistant/home-assistant/pull/18993 [#19004]: https://github.com/home-assistant/home-assistant/pull/19004 [#19007]: https://github.com/home-assistant/home-assistant/pull/19007 [#19008]: https://github.com/home-assistant/home-assistant/pull/19008 [#19009]: https://github.com/home-assistant/home-assistant/pull/19009 [#19010]: https://github.com/home-assistant/home-assistant/pull/19010 [#19011]: https://github.com/home-assistant/home-assistant/pull/19011 [#19025]: https://github.com/home-assistant/home-assistant/pull/19025 [#19026]: https://github.com/home-assistant/home-assistant/pull/19026 [#19030]: https://github.com/home-assistant/home-assistant/pull/19030 [#19033]: https://github.com/home-assistant/home-assistant/pull/19033 [#19035]: https://github.com/home-assistant/home-assistant/pull/19035 [#19038]: https://github.com/home-assistant/home-assistant/pull/19038 [#19040]: https://github.com/home-assistant/home-assistant/pull/19040 [#19042]: https://github.com/home-assistant/home-assistant/pull/19042 [#19043]: https://github.com/home-assistant/home-assistant/pull/19043 [#19045]: https://github.com/home-assistant/home-assistant/pull/19045 [#19048]: https://github.com/home-assistant/home-assistant/pull/19048 [#19051]: https://github.com/home-assistant/home-assistant/pull/19051 [#19052]: https://github.com/home-assistant/home-assistant/pull/19052 [#19055]: https://github.com/home-assistant/home-assistant/pull/19055 [#19056]: https://github.com/home-assistant/home-assistant/pull/19056 [#19057]: https://github.com/home-assistant/home-assistant/pull/19057 [#19062]: https://github.com/home-assistant/home-assistant/pull/19062 [#19064]: https://github.com/home-assistant/home-assistant/pull/19064 [#19069]: https://github.com/home-assistant/home-assistant/pull/19069 [#19073]: https://github.com/home-assistant/home-assistant/pull/19073 [#19077]: https://github.com/home-assistant/home-assistant/pull/19077 [#19083]: https://github.com/home-assistant/home-assistant/pull/19083 [#19085]: https://github.com/home-assistant/home-assistant/pull/19085 [#19098]: https://github.com/home-assistant/home-assistant/pull/19098 [#19100]: https://github.com/home-assistant/home-assistant/pull/19100 [#19101]: https://github.com/home-assistant/home-assistant/pull/19101 [#19133]: https://github.com/home-assistant/home-assistant/pull/19133 [#19161]: https://github.com/home-assistant/home-assistant/pull/19161 [#19162]: https://github.com/home-assistant/home-assistant/pull/19162 [#19163]: https://github.com/home-assistant/home-assistant/pull/19163 [#19172]: https://github.com/home-assistant/home-assistant/pull/19172 [#19188]: https://github.com/home-assistant/home-assistant/pull/19188 [@Adminiuga]: https://github.com/Adminiuga [@Danielhiversen]: https://github.com/Danielhiversen [@Eriner]: https://github.com/Eriner [@GeoffAtHome]: https://github.com/GeoffAtHome [@JeffLIrion]: https://github.com/JeffLIrion [@OttoWinter]: https://github.com/OttoWinter [@ahayworth]: https://github.com/ahayworth [@amelchio]: https://github.com/amelchio [@andersonshatch]: https://github.com/andersonshatch [@anton-johansson]: https://github.com/anton-johansson [@arigilder]: https://github.com/arigilder [@armills]: https://github.com/armills [@awarecan]: https://github.com/awarecan [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@bramkragten]: https://github.com/bramkragten [@bratanon]: https://github.com/bratanon [@bryanyork]: https://github.com/bryanyork [@carlos-sarmiento]: https://github.com/carlos-sarmiento [@cdce8p]: https://github.com/cdce8p [@cdheiser]: https://github.com/cdheiser [@damarco]: https://github.com/damarco [@danielperna84]: https://github.com/danielperna84 [@dgomes]: https://github.com/dgomes [@dmulcahey]: https://github.com/dmulcahey [@domwillcode]: https://github.com/domwillcode [@doudz]: https://github.com/doudz [@ehendrix23]: https://github.com/ehendrix23 [@eliseomartelli]: https://github.com/eliseomartelli [@emontnemery]: https://github.com/emontnemery [@exxamalte]: https://github.com/exxamalte [@fabaff]: https://github.com/fabaff [@fredrike]: https://github.com/fredrike [@frenck]: https://github.com/frenck [@fronzbot]: https://github.com/fronzbot [@fucm]: https://github.com/fucm [@glpatcern]: https://github.com/glpatcern [@gwww]: https://github.com/gwww [@heinemml]: https://github.com/heinemml [@hfurubotten]: https://github.com/hfurubotten [@hunterjm]: https://github.com/hunterjm [@iantrich]: https://github.com/iantrich [@jameshilliard]: https://github.com/jameshilliard [@jensihnow]: https://github.com/jensihnow [@jxwolstenholme]: https://github.com/jxwolstenholme [@lasote]: https://github.com/lasote [@ludeeus]: https://github.com/ludeeus [@majuss]: https://github.com/majuss [@marchingphoenix]: https://github.com/marchingphoenix [@mdallaire]: https://github.com/mdallaire [@mikeage]: https://github.com/mikeage [@molobrakos]: https://github.com/molobrakos [@mopolus]: https://github.com/mopolus [@nhorvath]: https://github.com/nhorvath [@nickw444]: https://github.com/nickw444 [@nragon]: https://github.com/nragon [@pagenoare]: https://github.com/pagenoare [@pbalogh77]: https://github.com/pbalogh77 [@pc-coholic]: https://github.com/pc-coholic [@photinus]: https://github.com/photinus [@postlund]: https://github.com/postlund [@rytilahti]: https://github.com/rytilahti [@scarface-4711]: https://github.com/scarface-4711 [@schmittx]: https://github.com/schmittx [@scop]: https://github.com/scop [@sdague]: https://github.com/sdague [@skalavala]: https://github.com/skalavala [@slackr31337]: https://github.com/slackr31337 [@soosp]: https://github.com/soosp [@syssi]: https://github.com/syssi [@ticapix]: https://github.com/ticapix [@trainman419]: https://github.com/trainman419 [@yottatsa]: https://github.com/yottatsa [@zxdavb]: https://github.com/zxdavb [alarm_control_panel.blink docs]: /integrations/blink [alarm_control_panel.lupusec docs]: /integrations/lupusec [alarm_control_panel.MQTT docs]: /integrations/alarm_control_panel.MQTT/ [alarm_control_panel.yale_smart_alarm docs]: /integrations/yale_smart_alarm [alexa docs]: /integrations/alexa/ [apple_tv docs]: /integrations/apple_tv/ [august docs]: /integrations/august/ [自动化 docs]: /integrations/自动化/ [binary_sensor.blink docs]: /integrations/blink [binary_sensor.fibaro docs]: /integrations/fibaro [binary_sensor.ihc docs]: /integrations/ihc#binary-传感器 [binary_sensor.MQTT docs]: /integrations/binary_sensor.MQTT/ [binary_sensor.point docs]: /integrations/point#binary-传感器 [binary_sensor.sense docs]: /integrations/sense [binary_sensor.tahoma docs]: /integrations/tahoma [binary_sensor.tellduslive docs]: /integrations/tellduslive [binary_sensor.volvooncall docs]: /integrations/volvooncall [binary_sensor.zha docs]: /integrations/zha [blink docs]: /integrations/blink/ [摄像头.blink docs]: /integrations/blink [摄像头.mjpeg docs]: /integrations/mjpeg [摄像头.proxy docs]: /integrations/proxy [摄像头.push docs]: /integrations/push [摄像头.uvc docs]: /integrations/uvc [温控.daikin docs]: /integrations/daikin#温控 [温控.evohome docs]: /integrations/evohome [温控.mill docs]: /integrations/mill [温控.MQTT docs]: /integrations/温控.MQTT/ [温控.toon docs]: /integrations/toon#温控 [cloud docs]: /integrations/cloud/ [config docs]: /integrations/config/ [遮盖.MQTT docs]: /integrations/遮盖.MQTT/ [遮盖.tellduslive docs]: /integrations/tellduslive [daikin docs]: /integrations/daikin/ [device_tracker docs]: /integrations/device_tracker/ [elkm1 docs]: /integrations/elkm1/ [evohome docs]: /integrations/evohome/ [风扇.MQTT docs]: /integrations/风扇.MQTT/ [风扇.xiaomi_miio docs]: /integrations/风扇.xiaomi_miio/ [风扇.zha docs]: /integrations/zha [fibaro docs]: /integrations/fibaro/ [前端 docs]: /integrations/frontend/ [geo_location docs]: /integrations/geo_location/ [google_assistant docs]: /integrations/google_assistant/ [hassio docs]: /integrations/hassio/ [hdmi_cec docs]: /integrations/hdmi_cec/ [history docs]: /integrations/history/ [hlk_sw16 docs]: /integrations/hlk_sw16/ [homematic docs]: /integrations/homematic/ [http docs]: /integrations/http/ [ihc docs]: /integrations/ihc/ [image_processing docs]: /integrations/image_processing/ [influxdb docs]: /integrations/influxdb/ [lifx docs]: /integrations/lifx/ [灯光.decora_wifi docs]: /integrations/decora_wifi/ [灯光.fibaro docs]: /integrations/fibaro [灯光.ihc docs]: /integrations/ihc#灯光 [灯光.lightwave docs]: /integrations/lightwave [灯光.lutron docs]: /integrations/lutron [灯光.MQTT docs]: /integrations/灯光.MQTT/ [灯光.niko_home_control docs]: /integrations/niko_home_control [灯光.tellduslive docs]: /integrations/tellduslive [灯光.xiaomi_miio docs]: /integrations/灯光.xiaomi_miio/ [灯光.yeelight docs]: /integrations/yeelight [灯光.zha docs]: /integrations/zha [lightwave docs]: /integrations/lightwave/ [门锁.verisure docs]: /integrations/verisure [门锁.volvooncall docs]: /integrations/volvooncall [logbook docs]: /integrations/logbook/ [Lovelace docs]: /integrations/Lovelace/ [lupusec docs]: /integrations/lupusec/ [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.demo docs]: /integrations/媒体播放器.demo/ [媒体播放器.denonavr docs]: /integrations/denonavr/ [媒体播放器.firetv docs]: /integrations/androidtv [媒体播放器.hdmi_cec docs]: /integrations/hdmi_cec [媒体播放器.plex docs]: /integrations/plex#media-player [媒体播放器.vizio docs]: /integrations/vizio [MQTT docs]: /integrations/MQTT/ [netatmo docs]: /integrations/netatmo/ [通知 docs]: /integrations/通知/ [onboarding docs]: /integrations/onboarding/ [owntracks docs]: /integrations/owntracks/ [point docs]: /integrations/point/ [rainmachine docs]: /integrations/rainmachine/ [遥控器.xiaomi_miio docs]: /integrations/遥控器.xiaomi_miio/ [场景.fibaro docs]: /integrations/fibaro [脚本 docs]: /integrations/脚本/ [sense docs]: /integrations/sense/ [传感器.awair docs]: /integrations/awair [传感器.blink docs]: /integrations/blink [传感器.daikin docs]: /integrations/daikin#传感器 [传感器.dht docs]: /integrations/dht [传感器.entur_public_transport docs]: /integrations/entur_public_transport [传感器.influxdb docs]: /integrations/influxdb#传感器 [传感器.MQTT docs]: /integrations/传感器.MQTT/ [传感器.netatmo docs]: /integrations/netatmo#传感器 [传感器.point docs]: /integrations/point#传感器 [传感器.qbittorrent docs]: /integrations/qbittorrent [传感器.rtorrent docs]: /integrations/rtorrent [传感器.sense docs]: /integrations/sense [传感器.seventeentrack docs]: /integrations/seventeentrack [传感器.snmp docs]: /integrations/snmp#传感器 [传感器.statistics docs]: /integrations/statistics [传感器.systemmonitor docs]: /integrations/systemmonitor [传感器.tellduslive docs]: /integrations/tellduslive [传感器.tibber docs]: /integrations/tibber#传感器 [传感器.volvooncall docs]: /integrations/volvooncall [传感器.waterfurnace docs]: /integrations/waterfurnace [传感器.xiaomi_miio docs]: /integrations/传感器.xiaomi_miio/ [传感器.zha docs]: /integrations/zha [shopping_list docs]: /integrations/shopping_list/ [simplisafe docs]: /integrations/simplisafe/ [skybell docs]: /integrations/skybell/ [开关.hdmi_cec docs]: /integrations/hdmi_cec [开关.hlk_sw16 docs]: /integrations/hlk_sw16 [开关.ihc docs]: /integrations/ihc#开关 [开关.lightwave docs]: /integrations/lightwave [开关.MQTT docs]: /integrations/开关.MQTT/ [开关.snmp docs]: /integrations/snmp#开关 [开关.switchbot docs]: /integrations/switchbot [开关.switchmate docs]: /integrations/switchmate [开关.tellduslive docs]: /integrations/tellduslive [开关.volvooncall docs]: /integrations/volvooncall [开关.xiaomi_miio docs]: /integrations/开关.xiaomi_miio/ [开关.zha docs]: /integrations/zha [tellduslive docs]: /integrations/tellduslive/ [tibber docs]: /integrations/tibber/ [tts docs]: /integrations/tts/ [吸尘器.xiaomi_miio docs]: /integrations/吸尘器.xiaomi_miio/ [verisure docs]: /integrations/verisure/ [volvooncall docs]: /integrations/volvooncall/ [waterfurnace docs]: /integrations/waterfurnace/ [天气.ipma docs]: /integrations/ipma [websocket_api docs]: /integrations/websocket_api/ [zha docs]: /integrations/zha/ --- url: /home-assistant/blog/2018-12-17-logitech-harmony-removes-local-api.md --- # \[更新:问题已解决,API 已恢复并承诺持续保留] Logitech Harmony 移除本地 API \*\*更新 6(12 月 21 日):\*\*好消息!Logitech 在[论坛公告](https://community.logitech.com/s/question/0D55A00008D4bZ4SAJ/harmony-hub-firmware-更新-fixes-vulnerabilities)中表示,他们推出了 XMPP Beta Program,可安装开发者固件版本以恢复原有 XMPP API(包括其中的安全漏洞行为)。请注意,安装该版本会导致保修失效。 Logitech 也在开发新的 Hub 固件版本来修复这些漏洞。这是非常积极的进展,也让我们重建了对 Logitech 的信任。感谢 Logitech 调整方向并与用户协作。

Screenshot of the developer-only firmware reinstating the local XMPP API. Also includes a disclaimer that it voids your warranty. 仅开发者可用的固件可恢复本地 XMPP API;安装后保修失效。

发现这些安全漏洞的网络安全公司 Tenable 也发布了[研究通告](https://www.tenable.com/security/research/tra-2018-47),详细说明了问题及披露时间线。 \*\*更新 7(12 月 21 日):\*\*更好的消息!Harmony 团队成员在[我们的论坛](https://community.home-assistant.io/t/logitechs-stance-on-local-apis/85842/18?u=balloob)发帖表示,他们现已承诺持续维护本地 XMPP API。 我们会向 Logitech 核实该帖子是否为官方立场;若确认属实,我们会把 Home Assistant 实现切回 XMPP API。在此之前,我们预计自 0.84.3 起使用的 websocket API 不会在迁回前突然下线或变更,所以如果你的 Harmony 目前运行正常,请先不要改动。(已核实:发帖账号绑定了 logitech.com 邮箱)

Screenshot of someone from Harmony stating that they are going to keep the local XMPP API around. Harmony 员工在 Home Assistant 论坛的帖子。

*Original Post:* Logitech 在 Harmony Hub 最新软件更新(v4.15.206)中禁用了本地 API。出于隐私和速度考虑,家庭自动化设备应当在本地通信,避免数据离开网络。随着此次更新,这一点已无法实现。 我们希望这只是对方的疏忽,并会很快回滚。我们已联系 Logitech 请求说明,一旦有新信息会更新本文。在问题解决前,我们不再建议购买或使用 Logitech 产品。 \*\*更新 1(12 月 17 日):\*\*我们仍未收到正式回复,但 Twitter 用户 [@FlorianNoack](https://twitter.com/FlorianNoack/status/1074744105002037248?s=09) 在 Logitech [论坛帖子](https://community.logitech.com/s/question/0D55A00008D1oIoSAJ/firmware-更新-blocked-api-access)中找到了官方回应(需要多次点击“More answers”才能看到):

Screenshot of a forum post by a Logitech employee saying that the Harmony team is aware of the feedback and it will provide an 更新 shortly. Harmony 团队成员的论坛帖子。

\*\*更新 2(12 月 18 日):\*\*同一位员工又在论坛[新开了一个帖子](https://community.logitech.com/s/question/0D55A00008D2zYDSAZ/harmony-hub-fw-415206)(推测是为了提高可见度),核心信息仍是“更多细节很快会公布”。

Screenshot of a forum post by a Logitech employee saying that a few customers are experiencing issues with certain 配置 and that they follow up soon with more details. Harmony 团队成员发起的帖子。

\*\*更新 3(12 月 18 日):\*\*Twitter 用户 [@ChadBeattie](https://twitter.com/ChadBeattie/status/1074770135121125376) 发现 Logitech Harmony iOS 应用似乎使用了第二套未文档化的本地 API。Home Assistant 开发者 [@ehendrix23] 正在尝试更新 PyHarmony 库以支持这套接口。如果你想参与开发,欢迎加入[聊天频道](/home-assistant/join-chat/)中的 `#devs_backend`。我们不能保证一定可行,但若验证成功,将发布热修复版本。 [@ehendrix23]: https://github.com/ehendrix23 \*\*更新 4(12 月 18 日):\*\*Logitech 仍未就基于 XMPP 的本地 API 未来给出明确说法。Home Assistant 开发者 [@ehendrix23] 在 [@chadcb] 与评论区其他热心贡献者帮助下,已经基本搞清 Logitech Harmony 本地 websocket API 的工作方式(Harmony iOS 应用也在用它)。目前已有一个针对 Home Assistant 的[pull request](https://github.com/home-assistant/home-assistant/pull/19440),用于把 Harmony 集成切换到该接口。这个 PR 正在测试中,若一切顺利,会在 19 日以热修复发布。

Screenshot of GitHub.com showing a pull request to Home Assistant to 更新 their Logitech Harmony 集成 to use the local websocket API. [@ehendrix23] 提交的 Pull Request:改用本地 websocket API。

[@chadcb]: https://github.com/chadcb \*\*更新 5(12 月 19 日):\*\*Logitech 在[论坛](https://community.logitech.com/s/question/0D55A00008D4bZ4SAJ/harmony-hub-firmware-更新-fixes-vulnerabilities)发布了官方回应。他们称在收到第三方网络安全公司的报告后移除了本地 XMPP API。我们目前无法独立核实该说法。XMPP API 至少从 [2013 年](https://github.com/jterrace/pyharmony)就已存在,并被全球大量智能家居系统采用。他们在帖子里承认知道有人在使用该 API,却没有任何提前告知,这再次证明其在我们智能家居体系中并不可靠。 我们今天会发布热修复,把集成迁移到他们 iOS 应用正在使用的另一套本地 API。这个接口未来同样可能遭遇类似命运。

Screenshot of a forum post by a Logitech employee saying that the local API was removed after a report from a third-party cyber security firm. Harmony 团队成员发起的帖子。

\*\*更新 6(12 月 19 日):\*\*Home Assistant `0.84.4` 已发布修复。Logitech Harmony 集成已恢复可用(至少目前如此)。我们已切换到其本地 websocket API。 ### Reverting the software 更新 :::note If you're using Home Assistant, consider upgrading to 0.84.4 instead of downgrading your hub. ::: 如果你的 Harmony Hub 已升级到 `v4.15.206`,你可能已经发现 Home Assistant 以及其他依赖本地 API 的产品都停止工作了。别担心,按下面步骤仍(大概率)可以降级到旧版本(来源:[Reddit 1](https://www.reddit.com/r/homeassistant/comments/a6u6ep/psa_harmony_hub_firmware_v415206_breaksremoves/)、[Reddit 2](https://www.reddit.com/r/homeassistant/comments/a6u6ep/psa_harmony_hub_firmware_v415206_breaksremoves/eby89t8/)): 1. 下载 [MyHarmony 电脑客户端](https://support.myharmony.com/en-us/download)。 2. 启动 MyHarmony 应用。 3. 在窗口内点击任何内容之前: * Windows 用户:按 `Alt+F9`。 * Mac 用户:按 `Fn+Option+F9` 或 `Option+F9`(取决于机型,任一组合可能有效)。 4. 在列表中找到你的 Harmony 型号。 5. 选择对应型号的 "Factory Reset"。此时不会立即执行任何操作。 6. 界面会显示完成 Factory Reset 的 1-4 步,我们只执行第 1 步。这里的“恢复”实际指“回滚”。 7. 通过 micro-USB 将 Harmony Hub 连接到电脑。 几分钟后,MyHarmony 会识别并显示遥控器型号、固件版本和硬件修订号,随后“恢复第 1 步”按钮会变为可用。 8. 点击“恢复”并等待。(这是第一次明确提示它实际上是回滚) 9. 完成后,固件应回到 `4.15.193`。断开 Hub 与电脑连接,并放回原位置。 最后且非常重要的一步:阻止 Harmony Hub 访问以下域名,或彻底阻断其外网访问。我使用的是 DD-WRT 的 Access Restrictions 功能禁用全部互联网访问,因为我的实现完全基于内网。请按你的环境评估。 * svcs.myharmony.com * content.dhg.myharmony.com * logging.dhg.myharmony.com * myharmony.com * sus.dhg.myharmony.com --- url: /home-assistant/blog/2018-12-19-logitech-stance-on-local-api.md --- # Logitech 对本地 API 的立场 #### 本文最初讨论的是 Logitech 在移除其私有但被广泛使用的本地 API 后,不愿继续支持本地 API。该决定现已撤回,因此本文结论已不再适用于 Logitech。事件详情可见[这篇博客][博客-remove-api]。 Logitech 曾决定移除其 Harmony Hub 上一个被广泛使用的本地 API。我们在[这里][博客-remove-api]持续追踪了整个事件。这一变动在我们的用户以及其他接入 Harmony Hub 的智能家居用户中引发了大量讨论:很多人突然发现家里的自动化失效了。在本就忙碌的假期季,这显然不是一个好的开始。 在 2018 年,这类讨论大多发生在 Twitter 上。我们浏览讨论时,看到了 Logitech Smart Home 产品营销高级经理 [Todd Walker] 的这段表态: 我们对此也有很多看法,但 Home Assistant 贡献者 [Jon Maddox] 在 Twitter 上已经做了很到位的表达: [博客-remove-api]: /博客/2018/12/17/logitech-harmony-removes-local-api/ [Todd Walker]: https://twitter.com/ToddW_Logitech [Jon Maddox]: https://twitter.com/maddox --- url: /home-assistant/blog/2018-12-27-data-science-portal.md --- # 数据科学门户上线 今天我们正式发布全新的[数据科学门户][post],帮助你从自己的智能家居数据中获得洞察。你可以了解 Home Assistant 在本地存储了哪些数据,也能学习如何探索这些数据。只需 15 分钟,你就能搭建本地数据科学环境,并开始对自己的数据生成报告。 我们为流畅体验做了很多工作。基于 Jupyter 的本地数据科学环境可以一键搭建,并且预装了 Home Assistant 入门 notebook,能自动连接你的数据库并一键生成报告。 这一切由 [@frenck] 提供的全新 JupyterLab Hass.io 插件,以及 [@robmarkcole] 提供的全新 HASS Data Detective Python 包共同驱动。 今天只是开始。我们会持续为 Home Assistant 打造数据工具。我们的目标是让 Home Assistant 成为家庭自动化数据科学从业者最易用的平台。 * [上线博客文章][post] * [Data Science Portal][portal] [post]: https://data.home-assistant.io/博客/2018/12/27/data-science-for-home-assistant-launched [portal]: https://data.home-assistant.io [@robmarkcole]: https://github.com/frenck [@frenck]: https://github.com/frenck --- url: /home-assistant/blog/2019-01-09-release-85.md --- --- url: /home-assistant/blog/2019-01-23-lovelace-released.md --- # Lovelace UI released! Today we're happy to announce that our new Lovelace UI, which has been in beta for the last 8 months, is becoming the new default interface of [Home Assistant 0.86](/home-assistant/blog/2019/01/23/release-86/). With Lovelace we're taking a new approach to building 用户 interfaces for Home Assistant. We're no longer storing the look and feel of your UI in your 配置.yaml, requiring restarts for changes. With Lovelace we're keeping the UI concerns in the UI1, unlocking a whole new set of features: * [24 卡片](/home-assistant/dashboards/alarm-panel/index.md) to place and 配置 as you like. * UI Editor. A 配置 UI to manage your Lovelace UI including live preview when editing 卡片. * Fast. Using a static config allows us to build up the UI once. * Customizable. * 卡片 have numerous options to 配置 how your data is presented. * Themes; even at a per 卡片 basis. * Ability to override names and icons of 实体. * Custom 卡片 from our amazing community are fully supported.
In case you're reading this and want to give it a try right now: we've updated [the Home Assistant demo](https://demo.home-assistant.io). It now features multiple Lovelace 配置 examples. The demo is fully interactive, including the 配置 UI (accessible via the menu in the top right). You can also access it by updating to Home Assistant 0.86. For a deep dive into all the new features, check out the [latest episode of the Home Assistant podcast](https://hasspodcast.io/ha042/), featuring an interview with [Zack Arnett][@zsarnett] from the Lovelace team. For an 概述 of all the different features, check out the [Lovelace 文档](/home-assistant/dashboards/index.md). 1: If you prefer to write your 仪表盘 config in YAML, Home Assistant also includes an optional [YAML mode](/home-assistant/dashboards/yaml-mode/). ## Migrating to Lovelace You have to do… nothing! If not configured, Lovelace will use the same algorithm to built-up the UI as the old UI did. ## History With Lovelace we've built a foundation that not only provides a lean and sleek interface, but will also allow us to add many new exciting features in the future. The main difference with the old UI is that we no longer store any UI concerns in the 状态 machine. When Home Assistant was started, I came up with an algorithm that would automatically organize the available 实体 in badges, 卡片 and tabs; and then show that on the screen. 用户 demanded more influence; so over time, we've added a bunch of components and features of the 后端 whose main or sole purpose were to influence how the algorithm in the UI shows and organizes 实体. As this kept growing, I realized that we were on the wrong path. It was impossible to get an algorithm that would fulfill all needs and the 后端 shouldn't be aware of anything in the 前端. It should just deliver the 实体 and the 前端 should figure out how to display things together with the 用户. At the same time as this was happening, we also had some discussions about the development of the 前端. 用户 wanted more control on what is shown, when it's shown and how it's shown. Eventually, [@andrey-git] came up with Custom UI for the old interface. This allowed 用户 to do whatever they wanted. However, it was limited to power 用户. Lovelace was built [from the start](https://github.com/home-assistant/architecture/issues/14) to tackle these problems. The initial 版本 completely dropped the algorithm and required 用户 to add each 卡片 to their 配置. We went from a fully automatic UI to nothing. We launched it under the nomer "experimental UI" and it quickly gained traction. People loved the control and the ability to inject custom 卡片 or 实体 rows at will. The enthusiasm was great among our power 用户, however by switching away from an automatic UI, we were no longer beginner-friendly. A new 用户 would open Home Assistant and they would see a blank, unconfigured UI. We realized that this had to be solved if we were to make Lovelace the default. To solve this, we re-introduced our automatic algorithm. However, this time the algorithm generates a Lovelace 配置. If a 用户 doesn't like the automatic 配置, they can take control and 配置 it to their liking. When you take control, the automatic generated 配置 will no longer be updated by Home Assistant, allowing the 用户 to change each detail. To make configuring your UI as easy as possible, Lovelace UI allows (custom) 卡片 to include a config editor. This way the 用户 will be able to quickly edit a 卡片 while a live preview shows how the changes look. If a 卡片 does not include an editor (yet), the 用户 will be presented with a text editor in the browser. Because of the ease to customize and share customizations, we've already seen a big community get 创建 around Lovelace. They are very active in the #Lovelace channel on [our chat](/home-assistant/join-chat/), and work is shared on [ShareTheLove.io](https://sharethelove.io/) and the [Lovelace section on Awesome HA](https://www.awesome-ha.com/#Lovelace-ui). ## Credits Lovelace UI has been 8 months in the making and it has been a big undertaking. We've worked hard and are proud of being able to ship this first 版本. Lovelace UI would not have been possible without the following current and former members of the Lovelace team: * [@balloob] / Paulus Schoutsen * [@bramkragten] / Bram Kragten * [@c727] * [@ciotlosm] / Marius Ciotloș * [@iantrich] / Ian Richardson * [@jeradM] / Jerad Meisner * [@thomasloven] / Thomas Lovén * [@zsarnett] / Zack Arnett I also want to thank the community for adopting this so eagerly, building a ton of helpful tooling and examples and helping one another to create beautiful UIs for their homes. ## Old UI The transition to Lovelace should be painless for most 用户. If you are encountering issues, please [let us know](https://github.com/home-assistant/home-assistant-polymer/issues). For the time being, you will be able to still change back to the old 用户 interface on a per-设备 basis by going to the info developer tool and following the instructions. [@andrey-git]: https://github.com/andrey-git [@balloob]: https://github.com/balloob [@bramkragten]: https://github.com/bramkragten [@c727]: https://github.com/c727 [@ciotlosm]: https://github.com/ciotlosm [@iantrich]: https://github.com/iantrich [@jeradM]: https://github.com/jeradM [@thomasloven]: https://github.com/thomasloven [@zsarnett]: https://github.com/zsarnett --- url: /home-assistant/blog/2019-01-23-release-86.md --- # 0.86:全新 Lovelace UI 与 Zigbee 管理面板! 今天我们发布 Home Assistant 0.86。哇,这真是一次令人惊艳的发布。第一个重磅亮点是:我们过去 8 个月一直在打造的 Lovelace 用户界面,现在已经成为 Home Assistant 的默认界面。关于它我们有很多想说的,所以专门写了一篇博客文章来介绍这次 Lovelace 发布,见[这里](/home-assistant/blog/2019/01/23/Lovelace-released/)。 接下来,我们更新了 [Home Assistant 演示站点](https://demo.home-assistant.io)。它更流畅、更漂亮,最棒的是:其中包含 4 套可完全交互的 Lovelace 用户界面供你体验!你可以修改状态,或者进入配置模式添加、编辑和重新组织卡片。我们现在还把它设置成会随着 Home Assistant 的最新版本自动更新,因此它始终会展示最新功能。

Screenshot of the new demo. 新演示站点中的 Lovelace 截图。

## Zigbee 管理面板 本次发布包含一个全新的 Zigbee 管理面板,让你可以更轻松地管理 Zigbee 网络。这要感谢 [@dmulcahey] 的辛勤工作,以及 [@Adminiuga] 和 [@damarco] 的协助。这个新面板可以轻松实现: * 执行允许加入和移除操作 * 重新配置节点,为设备重新绑定并重新设置上报配置,这有助于解决一些问题 * 读取和设置 cluster 属性,可用于查看和调整设备灵敏度等设置 * 查看并发送 cluster 命令。关于这一功能:对带参数命令的支持很快就会到来 Zigbee 团队也为 2019 年规划了许多很酷的内容。直接设备绑定(把遥控器直接配对到灯光)已经在开发中,他们也计划加入群组管理支持。定向加入和广播加入同样近在眼前(我们正在等待新的 Zigpy 版本)。对 Zigbee 用户来说,真是令人兴奋的时刻!

Screenshot of the Zigbee management 面板. Zigbee 管理面板截图。

## 值得注意的向后不兼容变更 更新:实体 ID 那项改动过于激进,现在改为仅发出警告。 本次发布还包含两项值得注意的向后不兼容变更。其一是对上个版本 slugify 破坏性变更的后续处理。我们之前没有更新那些要求为合法 slug 的配置项校验,这意味着你的一些配置值现在可能无效。请留意控制台,我们加入了新的提示信息来告诉你哪些配置有问题。 实体 ID 中不再允许以下情况: * 不允许大写字母 * 不允许以下划线开头或结尾 * 不允许连续两个下划线 这个问题也会影响实体注册表,因为其中某些实体 ID 可能是不合法的。如果实体 ID 含有双下划线(会变成 1 个)或以下划线开头/结尾(会被移除),请预期它们会发生变化。 另一项值得注意的破坏性变更(抱歉!)是自动化 `time` 触发器现在被拆分为 `time` 和 `time_pattern` 两种。如果你原本的 time 触发器里包含 `hours`、`minutes` 或 `seconds` 键,请把平台从 `time` 更新为 `time_pattern`。 ## 新平台 * Support for Homekit controller/报警 control 面板 ([@adrum] - [#19612]) ([homekit\_controller docs][homekit_controller docs]) ([alarm\_control\_panel.homekit\_controller docs][alarm_control_panel.homekit_controller docs]) (new-platform) * Add support for HomeKit Controller 门锁 ([@adrum] - [#19867]) ([homekit\_controller docs][homekit_controller docs]) ([门锁.homekit\_controller docs][门锁.homekit_controller docs]) (new-platform) * Add support for HomeKit Controller 遮盖 ([@adrum] - [#19866]) ([homekit\_controller docs][homekit_controller docs]) ([遮盖.homekit\_controller docs][遮盖.homekit_controller docs]) (new-platform) * Add Roku hub and 遥控器 ([@soberstadt] - [#17548]) ([roku docs]) ([媒体播放器.roku docs]) ([遥控器.roku docs]) (breaking change) (new-platform) * Add emulated\_roku component ([@mindigmarton] - [#17596]) ([emulated\_roku docs][emulated_roku docs]) ## 发布 0.86.1 - January 23 * Hotfix for blink initialization failure. Fixes #20335 ([@fronzbot] - [#20351]) ([blink docs]) * \[FIX] Time reporting incorrect in 传感器.gtt ([@eliseomartelli] - [#20362]) * Fix 错误 when API doesn't return a forecast. ([@dgomes] - [#20365]) * Fix 恢复 状态 crashing invalid 实体 ID ([@balloob] - [#20367]) * Calling save before load would crash Lovelace storage ([@balloob] - [#20368]) [#20351]: https://github.com/home-assistant/home-assistant/pull/20351 [#20362]: https://github.com/home-assistant/home-assistant/pull/20362 [#20365]: https://github.com/home-assistant/home-assistant/pull/20365 [#20367]: https://github.com/home-assistant/home-assistant/pull/20367 [#20368]: https://github.com/home-assistant/home-assistant/pull/20368 [@balloob]: https://github.com/balloob [@dgomes]: https://github.com/dgomes [@eliseomartelli]: https://github.com/eliseomartelli [@fronzbot]: https://github.com/fronzbot [blink docs]: /integrations/blink/ ## 发布 0.86.2 - January 24 * Philips Hue - Remove unnessesary 警告 ([@starkillerOG] - [#20394]) ([hue docs]) * history allowed to load 状态 with invalid 实体 IDs ([@balloob] - [#20399]) [#20394]: https://github.com/home-assistant/home-assistant/pull/20394 [#20399]: https://github.com/home-assistant/home-assistant/pull/20399 [@balloob]: https://github.com/balloob [@starkillerOG]: https://github.com/starkillerOG [hue docs]: /integrations/hue/ ## 发布 0.86.3 - January 26 * Philips Hue, include 调试 message for color gamut ([@starkillerOG] - [#20455]) ([hue docs]) * Warn instead of break for old slugs/实体 ids ([@balloob] - [#20478]) [#20455]: https://github.com/home-assistant/home-assistant/pull/20455 [#20478]: https://github.com/home-assistant/home-assistant/pull/20478 [@balloob]: https://github.com/balloob [@starkillerOG]: https://github.com/starkillerOG [hue docs]: /integrations/hue/ ## 发布 0.86.4 - January 28 * Bumps aioasuswrt ([@kennedyshead] - [#20432]) ([asuswrt docs]) * Add check to validate gamut ([@starkillerOG] - [#20518]) * fix #20387 设备 without model/protocol ([@fredrike] - [#20530]) ([tellduslive docs]) [#20432]: https://github.com/home-assistant/home-assistant/pull/20432 [#20518]: https://github.com/home-assistant/home-assistant/pull/20518 [#20530]: https://github.com/home-assistant/home-assistant/pull/20530 [@fredrike]: https://github.com/fredrike [@kennedyshead]: https://github.com/kennedyshead [@starkillerOG]: https://github.com/starkillerOG [asuswrt docs]: /integrations/asuswrt/ [tellduslive docs]: /integrations/tellduslive/ ## 如果你需要帮助…… 欢迎使用我们非常活跃的[论坛](https://community.home-assistant.io/),或者加入我们的[聊天频道](https://discord.gg/c5DvZ4e)。虽然发布说明开放评论,但我们更希望你使用前面这些沟通渠道。谢谢。 ## 反馈问题 如果你遇到了这个版本引入的问题,请在我们的 [issue tracker](https://github.com/home-assistant/home-assistant/issues) 中报告。请务必填写 issue 模板中的所有字段。 ## 向后不兼容的变更 * 自动化: Split time\_pattern 触发器 from time 触发器 ([@armills] - [#19825]) ([自动化.interval docs]) ([自动化.time docs]) (breaking change) * Each instance of Home Assistant will now generate it's own unique Webhook url for Geofencyto use. One will need to be generated and provided to the iOS app to replace the existing url: `https://myhome.duckdns.org/api/geofency?api_password=HA_PASSWORD` ([@rohankapoorcom] - [#18951]) ([geofency docs]) (breaking change) * Nest 传感器: Correctly map hvac\_state to Home Assistant 状态. Heating -> heat, Cooling -> cool. ([@mitchellrj] - [#19895]) ([传感器.nest docs]) (breaking change) * Add nad telnet media player and merge nadtcp into 媒体播放器.nad ([@rymsha] - [#19704]) ([媒体播放器.nad docs]) (breaking change) * Prezzi Benzina: Added the 服务 type to the name of the 传感器 to better differentiate between different 服务 tiers. ([@eliseomartelli] - [#19980]) (breaking change) * PostNL 属性 are updated, contain now more information ([@basbl] - [#18334]) (breaking change) * Support for multiple Fibaro gateways. A list of gateways is expected instead of a single config. ([@pbalogh77] - [#19705]) ([fibaro docs]) ([binary\_sensor.fibaro docs][binary_sensor.fibaro docs]) ([遮盖.fibaro docs]) ([灯光.fibaro docs]) ([场景.fibaro docs]) ([传感器.fibaro docs]) ([开关.fibaro docs]) (breaking change) * 升级 greeneye\_monitor to 1.0. It now requires the full 8 digit serial number. ([@jkeljo] - [#19631]) ([greeneye\_monitor docs][greeneye_monitor docs]) (breaking change) * Previous "manual" registration of roku 设备 will need to be updated or removed (discovery should discover all rokus on your network). ([@soberstadt] - [#17548]) ([roku docs]) ([媒体播放器.roku docs]) ([遥控器.roku docs]) (breaking change) (new-platform) * 报警 control 面板 实体 will now use `number` as their code\_format instead of `Number` ([@balloob] - [#20077]) ([alarm\_control\_panel docs][alarm_control_panel docs]) (breaking change) * OpenUV: 用户 will now need to use the openuv.update\_data 服务 to request new data from the API. ([@bachya] - [#19949]) ([openuv docs]) (breaking change) * Add support for connecting to multiple zoneminder instances ([@rohankapoorcom] - [#19955]) ([zoneminder docs]) ([摄像头.zoneminder docs]) ([传感器.zoneminder docs]) ([开关.zoneminder docs]) (breaking change) * The gpslogger device\_tracker platform no longer takes any 配置. The 配置 needs to be applied to the component gpslogger instead. The platform will be automatically loaded with the component and should not be specified in 配置.yaml. Each instance of Home Assistant will now generate it's own unique Webhook for GPSLogger to use. One will need to be generated and provided to the mobile app to the replace the existing url: `https://myhome.duckdns.org/api/gpslogger?api_password=HA_PASSWORD`. Home Assistant only supports using POST (no longer GET) for GPSLogger. The long lived access token is also no longer needed. ([@rohankapoorcom] - [#20044] - [#20079]) ([device\_tracker docs][device_tracker docs]) ([gpslogger docs]) (breaking change) * The locative device\_tracker platform no longer takes any 配置. The 配置 needs to be applied to the component locative instead. The platform will be automatically loaded with the component and should not be specified in 配置.yaml. Each instance of Home Assistant will now generate it's own unique Webhook url for Locative to use. One will need to be generated and provided to the mobile app to replace the existing url: https://myhome.duckdns.org/api/locative?api\_password=HA\_PASSWORD. Home Assistant only supports using POST (no longer GET) for Locative. ([@rohankapoorcom] - [#19964] - [#20043]) ([device\_tracker docs][device_tracker docs]) ([locative docs]) (breaking change) * Sensibo to adhere to the operation mode 状态 in HA 温控 component. ([@balloob] - [#20180]) ([温控.sensibo docs]) (breaking change) (beta fix) * Any registered 实体 that started/ended with an underscore (will be removed) or had 2 subsequent underscores (1 will be removed) will be updated. ([@balloob] - [#20328]) (breaking change) (beta fix) * The SMA 传感器 can monitor several new 传感器. Unfortunately some of the existing 传感器 were renamed: `current_power` is now `grid_power` and `grid_voltage` is now `voltage_l1` (the voltage from all three phases are available). The 传感器 also support the 实体 registry, making editing their names a breeze from the 前端. ([@kellerza] - [#19753]) ([传感器.sma docs]) ## Beta 修复 * Sensibo to use HA operation modes ([@balloob] - [#20180]) ([温控.sensibo docs]) (breaking change) (beta fix) * Distribute reconnect ([@balloob] - [#20181]) ([cloud docs]) (beta fix) * Add command to refresh auth ([@balloob] - [#20183]) ([cloud docs]) (beta fix) * Improve Sonos discovery ([@amelchio] - [#20196]) ([sonos docs]) (beta fix) * Handle non-string values in JSON renderer ([@pnbruckner] - [#20233]) (beta fix) * Bump aioesphomeapi to 1.4.2 ([@OttoWinter] - [#20247]) ([esphome docs]) (beta fix) * Remove double logging of 自动化 动作 ([@amelchio] - [#20264]) (beta fix) * Allow 'all' entity\_id in 服务 schema ([@amelchio] - [#20278]) (beta fix) * Fix 'all' entity\_id in 服务 call extraction ([@amelchio] - [#20281]) (beta fix) * Align valid\_entity\_id with new slugify ([@kellerza] - [#20231]) (beta fix) * Config Validator: schema\_with\_slug\_keys ([@kellerza] - [#20298]) (beta fix) * Bugfix: prevent 错误 通知 when octoprint server auto detected but no 配置 present. ([@reefab] - [#20303]) ([octoprint docs]) (beta fix) * Should require the 'GATTOOL' 设置 extras which includes pexpect. ([@mitchellrj] - [#20263]) ([device\_tracker docs][device_tracker docs]) (beta fix) * Fix xiaomi speed 属性 name clash ([@syssi] - [#20312]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) (beta fix) * 更新 locationsharinglib to 版本 3.0.11 ([@rolfberkenbosch] - [#20322]) ([device\_tracker docs][device_tracker docs]) (beta fix) * Fix invalid 实体 ID in 实体 registry ([@balloob] - [#20328]) (breaking change) (beta fix) ## 所有变更 * Support for Homekit controller/报警 control 面板 ([@adrum] - [#19612]) ([homekit\_controller docs][homekit_controller docs]) ([alarm\_control\_panel.homekit\_controller docs][alarm_control_panel.homekit_controller docs]) (new-platform) * 更新 powerview 场景 component to latest api. ([@sander76] - [#19717]) ([场景.hunterdouglas\_powerview docs][场景.hunterdouglas_powerview docs]) * Add support for Kwikset 914 Convert - 门锁.zwave id0446 (#19710) ([@cdkonecny] - [#19722]) ([门锁.zwave docs]) * Added zwave 门锁 状态 from 报警 type workaround ([@adrum] - [#18996]) ([门锁.zwave docs]) * 升级 pwmled to 1.4.0 ([@soldag] - [#19783]) ([灯光.rpi\_gpio\_pwm docs][灯光.rpi_gpio_pwm docs]) * HomematicIP 更新 版本 to 0.10.1 ([@mxworm] - [#19788]) ([homematicip\_cloud docs][homematicip_cloud docs]) * Remove duplicated MQTT 开关 test case ([@emontnemery] - [#19799]) * \[1/3] Refactor MQTT-吸尘器 in preparation for discovery and 设备 registry ([@quazzie] - [#19462]) ([吸尘器.MQTT docs]) * \[2/3] 吸尘器 MQTT-discovery ([@quazzie] - [#19478]) ([MQTT docs]) ([吸尘器 docs]) ([吸尘器.MQTT docs]) * SMA 传感器 - updated library ([@kellerza] - [#19753]) ([传感器.sma docs]) * \[3/3] MQTT-吸尘器 设备-registry ([@quazzie] - [#19479]) ([MQTT docs]) ([吸尘器 docs]) ([吸尘器.MQTT docs]) * Remove temperature from the list of available forecast 传感器 ([@ReneNulschDE] - [#19818]) ([传感器.darksky docs]) * This makes the vasttrafik platform stop spamming the 日志 with 警告 ([@kennedyshead] - [#19792]) ([传感器.vasttrafik docs]) * Bump pybotvac ([@dshokouhi] - [#19831]) ([neato docs]) * Cleanup if discovered MQTT 开关 can't be added ([@emontnemery] - [#19721]) ([开关.MQTT docs]) * adding more dimmer components ([@sander76] - [#19843]) ([灯光.homematicip\_cloud docs][灯光.homematicip_cloud docs]) * bump watefurnace 版本 to 1.1.0 ([@sdague] - [#19847]) ([waterfurnace docs]) * Fix 2 ResourceWarning: unclosed file in test\_ruamel\_yaml.py ([@BoboTiG] - [#19780]) * 升级 tahoma-api to 0.0.14 ([@koomik] - [#19840]) ([tahoma docs]) * Fix french Amazon Polly voice 'Léa'. ([@vincent-k] - [#19852]) ([tts docs]) * 升级 holidays to 0.9.9 ([@fabaff] - [#19851]) ([binary\_sensor.workday docs][binary_sensor.workday docs]) * Small cleanup of MQTT 灯光 ([@emontnemery] - [#19816]) ([灯光.MQTT docs]) * Fix 状态 and 属性 fetching in vasttrafik ([@kennedyshead] - [#19856]) * Geo Location -> Geolocation (comments and default group name) ([@exxamalte] - [#19865]) ([geo\_location docs][geo_location docs]) ([自动化.geo\_location docs][自动化.geo_location docs]) * Replace MyChevy persistant\_notification with 错误 日志 entry ([@ReneNulschDE] - [#19804]) ([传感器.mychevy docs]) * 升级 bcrypt to 3.1.5 ([@fabaff] - [#19854]) * Cleanup if discovered MQTT 门锁 can't be added ([@emontnemery] - [#19746]) ([门锁.MQTT docs]) * Cleanup if discovered MQTT 传感器 can't be added ([@emontnemery] - [#19745]) ([传感器.MQTT docs]) * Cleanup if discovered MQTT 遮盖 can't be added ([@emontnemery] - [#19743]) ([遮盖.MQTT docs]) * Cleanup if discovered MQTT 报警 can't be added ([@emontnemery] - [#19742]) ([alarm\_control\_panel.MQTT docs][alarm_control_panel.MQTT docs]) * Cleanup if discovered MQTT 风扇 can't be added ([@emontnemery] - [#19741]) ([风扇.MQTT docs]) * Cleanup if discovered MQTT 温控 can't be added ([@emontnemery] - [#19739]) ([温控.MQTT docs]) * Relay events for onoff and levelcontrol output clusters in ZHA ([@dmulcahey] - [#19863]) ([zha docs]) * Replace influxdb query by another query that is more lightweight ([@BaQs] - [#19880]) ([传感器.influxdb docs]) * Allow other icon prefixes than mdi: ([@thomasloven] - [#19872]) * Geo Location -> Geolocation (class names and unit test comments) ([@exxamalte] - [#19877]) ([geo\_location docs][geo_location docs]) * add 实体 support to hive ([@Rendili] - [#19879]) ([binary\_sensor.hive docs][binary_sensor.hive docs]) ([温控.hive docs]) ([灯光.hive docs]) ([传感器.hive docs]) ([开关.hive docs]) * Migrate geofency over to the Webhook component ([@rohankapoorcom] - [#18951]) ([geofency docs]) (breaking change) * Refactor motion 传感器 of the xiaomi\_aqara platform ([@syssi] - [#19805]) ([binary\_sensor.xiaomi\_aqara docs][binary_sensor.xiaomi_aqara docs]) * Fix deprecation 警告 ([@balloob] - [#19882]) * Bug fix with getting a 设备 battery level when API unavailable for Hive ([@Rendili] - [#19841]) ([hive docs]) ([binary\_sensor.hive docs][binary_sensor.hive docs]) ([温控.hive docs]) ([灯光.hive docs]) ([传感器.hive docs]) ([开关.hive docs]) * Bump pyflunearyou to 1.0.1 ([@bachya] - [#19899]) ([传感器.flunearyou docs]) * Removed mkdir, If the WORKDIR doesn’t exist, it will be 创建. ([@RealArtemiy] - [#19892]) * Plant monitor defaults ([@royduin] - [#19891]) ([plant docs]) * Correctly map Nest hvac\_state to Home Assistant 状态. ([@mitchellrj] - [#19895]) ([传感器.nest docs]) (breaking change) * Add btle\_name 属性 to 设备 ([@cliffordwhansen] - [#19915]) ([device\_tracker docs][device_tracker docs]) * Add Alexa's EndpointHealth reporting ([@abmantis] - [#19784]) ([alexa docs]) * Remove Discovery dependency from konnected.py ([@so3n] - [#19910]) ([konnected docs]) * Add 传感器 to jewish\_calendar for upcoming Shabbat times ([@arigilder] - [#19278]) ([传感器.jewish\_calendar docs][传感器.jewish_calendar docs]) * add\_entities -> async\_add\_entities ([@SNoof85] - [#19943]) ([传感器.freebox docs]) * Add nad telnet ([@rymsha] - [#19704]) ([媒体播放器.nad docs]) (breaking change) * 升级 blinkpy and use calibrated temperature for 传感器 ([@fronzbot] - [#19723]) ([blink docs]) ([传感器.blink docs]) * Small refactoring for the alexa component ([@abmantis] - [#19782]) ([alexa docs]) * 升级 pylast to 3.0.0 ([@fabaff] - [#19938]) ([传感器.lastfm docs]) * Remove spurious libzwave 错误 ([@therve] - [#19928]) ([zwave docs]) * Add emulated\_roku component ([@mindigmarton] - [#17596]) ([emulated\_roku docs][emulated_roku docs]) * Change 状态() to try/except to catch KeyError ([@iamtpage] - [#19935]) ([传感器.tautulli docs]) * 升级 mutagen to 1.42.0 ([@fabaff] - [#19956]) ([tts docs]) * 升级 pillow to 5.4.1 ([@fabaff] - [#19958]) ([摄像头.proxy docs]) ([image\_processing.tensorflow docs][image_processing.tensorflow docs]) * 升级 ruamel.yaml to 0.15.85 ([@fabaff] - [#19960]) * 升级 pysnmp to 4.4.8 ([@fabaff] - [#19961]) ([device\_tracker docs][device_tracker docs]) ([传感器.snmp docs]) ([开关.snmp docs]) * 升级 keyring to 17.1.1 ([@fabaff] - [#19962]) * Add support for restoring 状态 to rpi\_gpio\_pwm ([@soldag] - [#19944]) * min\_max 传感器 support for STATE\_UNAVAILABLE ([@RomRider] - [#19914]) ([传感器.min\_max docs][传感器.min_max docs]) * add 服务 type in name ([@eliseomartelli] - [#19980]) (breaking change) * Add support for spot cleaning that was introduced in pybotvac 0.12 ([@larsvinc] - [#19857]) ([吸尘器.neato docs]) * Support next generation of the Xiaomi Mi Smart Plug (chuangmi.plug.m3) ([@syssi] - [#19972]) ([开关.xiaomi\_miio docs][开关.xiaomi_miio docs]) * When tradfri experience communication 错误 make the 灯光/设备 unavailable. ([@jarlebh] - [#19288]) ([灯光.tradfri docs]) ([开关.tradfri docs]) * Allow embedded platforms ([@balloob] - [#19948]) * Add 服务 and 助手 functions to support a config 面板 for ZHA ([@dmulcahey] - [#19664]) ([zha docs]) * Adding IPv6 to fail2ban 传感器 ([@grea09] - [#19457]) ([传感器.fail2ban docs]) * Always use datetime and timedelta in 摄像头.proxy instead of int/float ([@mikeage] - [#19571]) ([摄像头.proxy docs]) * Include 脚本/ directory to .gitignore - this is 创建 by virtualenv on Windows ([@scarface-4711] - [#18918]) * Add mysensors 状态 更新 delay ([@MartinHjelmare] - [#18891]) ([device\_tracker docs][device_tracker docs]) ([mysensors docs]) * Add ability to monitor relay events ([@oblogic7] - [#18730]) ([doorbird docs]) * Add support for 'via\_hub' for device\_info ([@fredrike] - [#19454]) ([MQTT docs]) * Fix the anthemav component by removing a debugging line. ([@achatham] - [#19979]) ([媒体播放器.anthemav docs]) * Expose more information about shipments by PostNL ([@basbl] - [#18334]) (breaking change) * Split locative to a separate component ([@rohankapoorcom] - [#19964]) ([device\_tracker docs][device_tracker docs]) ([locative docs]) (breaking change) * Support for multiple Fibaro gateways ([@pbalogh77] - [#19705]) ([fibaro docs]) ([binary\_sensor.fibaro docs][binary_sensor.fibaro docs]) ([遮盖.fibaro docs]) ([灯光.fibaro docs]) ([场景.fibaro docs]) ([传感器.fibaro docs]) ([开关.fibaro docs]) (breaking change) * Add Hass.io 用户 headers to supervisor proxy ([@balloob] - [#19395]) ([hassio docs]) * 升级 huawei-lte-api to 1.1.3 ([@scop] - [#19987]) * 升级 pytest-cov to 2.6.1 ([@scop] - [#19988]) * Wink: 更新 pubnubsub-handler 版本 to make it compatible with python 3.7 ([@ledor473] - [#19625]) ([wink docs]) * Don't set friendly\_name in Zha 实体. ([@Adminiuga] - [#19991]) ([zha docs]) * Add support for HomeKit Controller 门锁 ([@adrum] - [#19867]) ([homekit\_controller docs][homekit_controller docs]) ([门锁.homekit\_controller docs][门锁.homekit_controller docs]) (new-platform) * Repackage ZHA component ([@dmulcahey] - [#19989]) ([zha docs]) * 'latest\_dir' referenced before assignment ([@vaidyasr] - [#19952]) ([摄像头.xiaomi docs]) * catch TypeError's in addition to ValueError's for unifi direct 设备 tracker ([@thomasdelaet] - [#19994]) * Support for html5 通知 to suggest their names ([@quazzie] - [#19965]) ([通知 docs]) * 更新 doorbird events to include URLs on event\_data ([@oblogic7] - [#19262]) ([doorbird docs]) * 升级 greeneye\_monitor to 1.0 ([@jkeljo] - [#19631]) ([greeneye\_monitor docs][greeneye_monitor docs]) (breaking change) * 版本 bump for zha-quirks ([@dmulcahey] - [#20019]) ([zha docs]) * Enable bool type for ADS 服务 ([@carstenschroeder] - [#20011]) ([ads docs]) * UniFi - Fix issue with POE 开关 reset 开关 config ([@Kane610] - [#20021]) ([unifi docs]) * Add 服务 change\_channel to Harmony component ([@ehendrix23] - [#19649]) ([遥控器.harmony docs]) * mychevy: Fix wrong 属性 on battery level selector ([@sdague] - [#20016]) ([传感器.mychevy docs]) * Add harmony 服务 to 遥控器 服务.yaml ([@ehendrix23] - [#20031]) * 更新 to pyunifi 2.16 ([@finish06] - [#20042]) ([device\_tracker docs][device_tracker docs]) * 升级 pytest to 4.1.0 ([@scop] - [#20013]) * Change 报警 面板 code format ([@arsaboo] - [#20037]) ([alarm\_control\_panel.elkm1 docs][alarm_control_panel.elkm1 docs]) * ADS 服务: Enable use of 模板 for value ([@carstenschroeder] - [#20024]) ([ads docs]) * Fix 遥控器.harmony\_change\_channel 服务.yaml indentation ([@amelchio] - [#20051]) * Show persistent 通知 on Doorbird schedule failure ([@oblogic7] - [#20033]) ([doorbird docs]) * Add support for HomeKit Controller 遮盖 ([@adrum] - [#19866]) ([homekit\_controller docs][homekit_controller docs]) ([遮盖.homekit\_controller docs][遮盖.homekit_controller docs]) (new-platform) * 警告 -> 调试, this should not have been visible to 用户 ([@rytilahti] - [#20061]) ([媒体播放器.songpal docs]) * Split out gpslogger into a separate component and platform ([@rohankapoorcom] - [#20044]) ([device\_tracker docs][device_tracker docs]) ([gpslogger docs]) (breaking change) * Add Roku hub and 遥控器 ([@soberstadt] - [#17548]) ([roku docs]) ([媒体播放器.roku docs]) ([遥控器.roku docs]) (breaking change) (new-platform) * 升级 pytest to 4.1.1 ([@scop] - [#20088]) * Lowercase code format ([@balloob] - [#20077]) ([alarm\_control\_panel docs][alarm_control_panel docs]) (breaking change) * fix logic 错误 in dubln bus ([@ttroy50] - [#20075]) ([传感器.dublin\_bus\_transport docs][传感器.dublin_bus_transport docs]) * Bump abode to 0.15.0 ([@shred86] - [#20064]) ([abode docs]) * Change return text code for 报警 control 面板 ([@arsaboo] - [#20055]) * Adjust OpenUV 集成 for upcoming API limit changes ([@bachya] - [#19949]) ([openuv docs]) (breaking change) * Fix ihc issues caused by 更新 to defusedxml ([@mopolus] - [#20091]) ([ihc docs]) * Move ESPHome Source Files ([@OttoWinter] - [#20092]) ([esphome docs]) * Embed RainMachine platforms into the component ([@bachya] - [#20066]) ([rainmachine docs]) * Embed SimpliSafe platforms into the component ([@bachya] - [#20069]) ([simplisafe docs]) * Embed OpenUV platforms into the component ([@bachya] - [#20072]) ([openuv docs]) * Reconfigure MQTT 门锁 component if discovery info is changed ([@emontnemery] - [#19468]) ([门锁.MQTT docs]) * Added partial detection to async\_add\_job ([@andrewsayre] - [#20119]) * Fix tellduslive discovery and auth issues ([@fredrike] - [#20023]) ([tellduslive docs]) * Use voluptuous to perform validation for the geofency Webhook ([@rohankapoorcom] - [#20067]) ([geofency docs]) * fixed gtt to report isotime ([@eliseomartelli] - [#20128]) * Move MQTT platforms under the component ([@emontnemery] - [#20050]) ([MQTT docs]) * Split time\_pattern 触发器 from time 触发器 ([@armills] - [#19825]) ([自动化.interval docs]) ([自动化.time docs]) (breaking change) * Change deCONZ to embedded platforms ([@Kane610] - [#20113]) ([deconz docs]) * Improve Philips Hue color conversion 2 ([@starkillerOG] - [#20118]) * Minor refactoring of MQTT availability ([@emontnemery] - [#20136]) ([MQTT docs]) * Add 通知.html5\_dismiss 服务 ([@quazzie] - [#19912]) ([通知 docs]) * Fix loading translations for embedded platforms ([@balloob] - [#20122]) * 开关 geofency tests to using an unauthenticated HTTP client ([@rohankapoorcom] - [#20080]) * Zha 灯光.turn\_on 服务 fixes. ([@Adminiuga] - [#20085]) ([zha docs]) * 开关 to ipapi.co (fixes #19846) ([@fabaff] - [#19886]) * Accept both domains and 实体 in influxdb include ([@amelchio] - [#19927]) ([influxdb docs]) * Make all deCONZ platforms use a common base ([@Kane610] - [#20137]) * Reconnect and 设备 name fix for harmony platform ([@ehendrix23] - [#20108]) ([遥控器.harmony docs]) * Fix TTS say config validation ([@balloob] - [#20145]) ([tts docs]) * Use the correct Unicode degree symbol ([@tgerla] - [#20058]) ([传感器.ambient\_station docs][传感器.ambient_station docs]) * Add support for connecting to multiple zoneminder instances ([@rohankapoorcom] - [#19955]) ([zoneminder docs]) ([摄像头.zoneminder docs]) ([传感器.zoneminder docs]) ([开关.zoneminder docs]) (breaking change) * Embed geofency platform into component ([@rohankapoorcom] - [#20083]) ([geofency docs]) * Remove .isort because we use the config from 设置.cfg ([@pvizeli] - [#20158]) * Fix link to 文档 link, select read-only ([@cvwillegen] - [#20155]) ([传感器.imap\_email\_content docs][传感器.imap_email_content docs]) * Embed mailgun platform into component ([@rohankapoorcom] - [#20147]) ([mailgun docs]) * Enable setting 报警 mode night for arlo platform ([@keslerm] - [#20143]) ([alarm\_control\_panel.arlo docs][alarm_control_panel.arlo docs]) * Support device\_class for rest 传感器 ([@Anonym-tsk] - [#20132]) ([传感器.rest docs]) * Migrate gpslogger to the automatically generated Webhook ([@rohankapoorcom] - [#20079]) ([gpslogger docs]) (breaking change) * imap\_email\_content: allow configuring folder to read. ([@cvwillegen] - [#20160]) * Make imports relative in ZHA component ([@dmulcahey] - [#20020]) ([zha docs]) * 开关 locative to use the Webhook component ([@rohankapoorcom] - [#20043]) ([locative docs]) (breaking change) * 日志 exceptions thrown by MQTT message callbacks ([@emontnemery] - [#19977]) ([MQTT docs]) * 升级 aiohttp to 3.5.3 ([@fabaff] - [#19957]) * Strip login username in 后端 ([@balloob] - [#20150]) * Bump pynuki to 1.3.2 ([@damarco] - [#20173]) ([门锁.nuki docs]) * Add Xiaomi Airpurifier Pro V7 support ([@syssi] - [#20093]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) * Add support for deconz radios to zha component ([@damarco] - [#20167]) ([zha docs]) * Sensibo to use HA operation modes ([@balloob] - [#20180]) ([温控.sensibo docs]) (breaking change) (beta fix) * Distribute reconnect ([@balloob] - [#20181]) ([cloud docs]) (beta fix) * Add command to refresh auth ([@balloob] - [#20183]) ([cloud docs]) (beta fix) * Improve Sonos discovery ([@amelchio] - [#20196]) ([sonos docs]) (beta fix) * Handle non-string values in JSON renderer ([@pnbruckner] - [#20233]) (beta fix) * Bump aioesphomeapi to 1.4.2 ([@OttoWinter] - [#20247]) ([esphome docs]) (beta fix) * Remove double logging of 自动化 动作 ([@amelchio] - [#20264]) (beta fix) * Allow 'all' entity\_id in 服务 schema ([@amelchio] - [#20278]) (beta fix) * Fix 'all' entity\_id in 服务 call extraction ([@amelchio] - [#20281]) (beta fix) * Align valid\_entity\_id with new slugify ([@kellerza] - [#20231]) (beta fix) * Config Validator: schema\_with\_slug\_keys ([@kellerza] - [#20298]) (beta fix) * Bugfix: prevent 错误 通知 when octoprint server auto detected but no 配置 present. ([@reefab] - [#20303]) ([octoprint docs]) (beta fix) * Should require the 'GATTOOL' 设置 extras which includes pexpect. ([@mitchellrj] - [#20263]) ([device\_tracker docs][device_tracker docs]) (beta fix) * Fix xiaomi speed 属性 name clash ([@syssi] - [#20312]) ([风扇.xiaomi\_miio docs][风扇.xiaomi_miio docs]) (beta fix) * 更新 locationsharinglib to 版本 3.0.11 ([@rolfberkenbosch] - [#20322]) ([device\_tracker docs][device_tracker docs]) (beta fix) * Fix invalid 实体 ID in 实体 registry ([@balloob] - [#20328]) (breaking change) (beta fix) [#17548]: https://github.com/home-assistant/home-assistant/pull/17548 [#17596]: https://github.com/home-assistant/home-assistant/pull/17596 [#18334]: https://github.com/home-assistant/home-assistant/pull/18334 [#18730]: https://github.com/home-assistant/home-assistant/pull/18730 [#18891]: https://github.com/home-assistant/home-assistant/pull/18891 [#18918]: https://github.com/home-assistant/home-assistant/pull/18918 [#18951]: https://github.com/home-assistant/home-assistant/pull/18951 [#18996]: https://github.com/home-assistant/home-assistant/pull/18996 [#19262]: https://github.com/home-assistant/home-assistant/pull/19262 [#19278]: https://github.com/home-assistant/home-assistant/pull/19278 [#19288]: https://github.com/home-assistant/home-assistant/pull/19288 [#19395]: https://github.com/home-assistant/home-assistant/pull/19395 [#19454]: https://github.com/home-assistant/home-assistant/pull/19454 [#19457]: https://github.com/home-assistant/home-assistant/pull/19457 [#19462]: https://github.com/home-assistant/home-assistant/pull/19462 [#19468]: https://github.com/home-assistant/home-assistant/pull/19468 [#19478]: https://github.com/home-assistant/home-assistant/pull/19478 [#19479]: https://github.com/home-assistant/home-assistant/pull/19479 [#19571]: https://github.com/home-assistant/home-assistant/pull/19571 [#19612]: https://github.com/home-assistant/home-assistant/pull/19612 [#19625]: https://github.com/home-assistant/home-assistant/pull/19625 [#19631]: https://github.com/home-assistant/home-assistant/pull/19631 [#19649]: https://github.com/home-assistant/home-assistant/pull/19649 [#19664]: https://github.com/home-assistant/home-assistant/pull/19664 [#19704]: https://github.com/home-assistant/home-assistant/pull/19704 [#19705]: https://github.com/home-assistant/home-assistant/pull/19705 [#19717]: https://github.com/home-assistant/home-assistant/pull/19717 [#19721]: https://github.com/home-assistant/home-assistant/pull/19721 [#19722]: https://github.com/home-assistant/home-assistant/pull/19722 [#19723]: https://github.com/home-assistant/home-assistant/pull/19723 [#19739]: https://github.com/home-assistant/home-assistant/pull/19739 [#19741]: https://github.com/home-assistant/home-assistant/pull/19741 [#19742]: https://github.com/home-assistant/home-assistant/pull/19742 [#19743]: https://github.com/home-assistant/home-assistant/pull/19743 [#19745]: https://github.com/home-assistant/home-assistant/pull/19745 [#19746]: https://github.com/home-assistant/home-assistant/pull/19746 [#19753]: https://github.com/home-assistant/home-assistant/pull/19753 [#19780]: https://github.com/home-assistant/home-assistant/pull/19780 [#19782]: https://github.com/home-assistant/home-assistant/pull/19782 [#19783]: https://github.com/home-assistant/home-assistant/pull/19783 [#19784]: https://github.com/home-assistant/home-assistant/pull/19784 [#19788]: https://github.com/home-assistant/home-assistant/pull/19788 [#19792]: https://github.com/home-assistant/home-assistant/pull/19792 [#19799]: https://github.com/home-assistant/home-assistant/pull/19799 [#19804]: https://github.com/home-assistant/home-assistant/pull/19804 [#19805]: https://github.com/home-assistant/home-assistant/pull/19805 [#19816]: https://github.com/home-assistant/home-assistant/pull/19816 [#19818]: https://github.com/home-assistant/home-assistant/pull/19818 [#19825]: https://github.com/home-assistant/home-assistant/pull/19825 [#19831]: https://github.com/home-assistant/home-assistant/pull/19831 [#19840]: https://github.com/home-assistant/home-assistant/pull/19840 [#19841]: https://github.com/home-assistant/home-assistant/pull/19841 [#19843]: https://github.com/home-assistant/home-assistant/pull/19843 [#19847]: https://github.com/home-assistant/home-assistant/pull/19847 [#19851]: https://github.com/home-assistant/home-assistant/pull/19851 [#19852]: https://github.com/home-assistant/home-assistant/pull/19852 [#19854]: https://github.com/home-assistant/home-assistant/pull/19854 [#19856]: https://github.com/home-assistant/home-assistant/pull/19856 [#19857]: https://github.com/home-assistant/home-assistant/pull/19857 [#19863]: https://github.com/home-assistant/home-assistant/pull/19863 [#19865]: https://github.com/home-assistant/home-assistant/pull/19865 [#19866]: https://github.com/home-assistant/home-assistant/pull/19866 [#19867]: https://github.com/home-assistant/home-assistant/pull/19867 [#19872]: https://github.com/home-assistant/home-assistant/pull/19872 [#19877]: https://github.com/home-assistant/home-assistant/pull/19877 [#19879]: https://github.com/home-assistant/home-assistant/pull/19879 [#19880]: https://github.com/home-assistant/home-assistant/pull/19880 [#19882]: https://github.com/home-assistant/home-assistant/pull/19882 [#19886]: https://github.com/home-assistant/home-assistant/pull/19886 [#19891]: https://github.com/home-assistant/home-assistant/pull/19891 [#19892]: https://github.com/home-assistant/home-assistant/pull/19892 [#19895]: https://github.com/home-assistant/home-assistant/pull/19895 [#19899]: https://github.com/home-assistant/home-assistant/pull/19899 [#19910]: https://github.com/home-assistant/home-assistant/pull/19910 [#19912]: https://github.com/home-assistant/home-assistant/pull/19912 [#19914]: https://github.com/home-assistant/home-assistant/pull/19914 [#19915]: https://github.com/home-assistant/home-assistant/pull/19915 [#19927]: https://github.com/home-assistant/home-assistant/pull/19927 [#19928]: https://github.com/home-assistant/home-assistant/pull/19928 [#19935]: https://github.com/home-assistant/home-assistant/pull/19935 [#19938]: https://github.com/home-assistant/home-assistant/pull/19938 [#19943]: https://github.com/home-assistant/home-assistant/pull/19943 [#19944]: https://github.com/home-assistant/home-assistant/pull/19944 [#19948]: https://github.com/home-assistant/home-assistant/pull/19948 [#19949]: https://github.com/home-assistant/home-assistant/pull/19949 [#19952]: https://github.com/home-assistant/home-assistant/pull/19952 [#19955]: https://github.com/home-assistant/home-assistant/pull/19955 [#19956]: https://github.com/home-assistant/home-assistant/pull/19956 [#19957]: https://github.com/home-assistant/home-assistant/pull/19957 [#19958]: https://github.com/home-assistant/home-assistant/pull/19958 [#19960]: https://github.com/home-assistant/home-assistant/pull/19960 [#19961]: https://github.com/home-assistant/home-assistant/pull/19961 [#19962]: https://github.com/home-assistant/home-assistant/pull/19962 [#19964]: https://github.com/home-assistant/home-assistant/pull/19964 [#19965]: https://github.com/home-assistant/home-assistant/pull/19965 [#19972]: https://github.com/home-assistant/home-assistant/pull/19972 [#19977]: https://github.com/home-assistant/home-assistant/pull/19977 [#19979]: https://github.com/home-assistant/home-assistant/pull/19979 [#19980]: https://github.com/home-assistant/home-assistant/pull/19980 [#19987]: https://github.com/home-assistant/home-assistant/pull/19987 [#19988]: https://github.com/home-assistant/home-assistant/pull/19988 [#19989]: https://github.com/home-assistant/home-assistant/pull/19989 [#19991]: https://github.com/home-assistant/home-assistant/pull/19991 [#19994]: https://github.com/home-assistant/home-assistant/pull/19994 [#20011]: https://github.com/home-assistant/home-assistant/pull/20011 [#20013]: https://github.com/home-assistant/home-assistant/pull/20013 [#20016]: https://github.com/home-assistant/home-assistant/pull/20016 [#20019]: https://github.com/home-assistant/home-assistant/pull/20019 [#20020]: https://github.com/home-assistant/home-assistant/pull/20020 [#20021]: https://github.com/home-assistant/home-assistant/pull/20021 [#20023]: https://github.com/home-assistant/home-assistant/pull/20023 [#20024]: https://github.com/home-assistant/home-assistant/pull/20024 [#20031]: https://github.com/home-assistant/home-assistant/pull/20031 [#20033]: https://github.com/home-assistant/home-assistant/pull/20033 [#20037]: https://github.com/home-assistant/home-assistant/pull/20037 [#20042]: https://github.com/home-assistant/home-assistant/pull/20042 [#20043]: https://github.com/home-assistant/home-assistant/pull/20043 [#20044]: https://github.com/home-assistant/home-assistant/pull/20044 [#20050]: https://github.com/home-assistant/home-assistant/pull/20050 [#20051]: https://github.com/home-assistant/home-assistant/pull/20051 [#20055]: https://github.com/home-assistant/home-assistant/pull/20055 [#20058]: https://github.com/home-assistant/home-assistant/pull/20058 [#20061]: https://github.com/home-assistant/home-assistant/pull/20061 [#20064]: https://github.com/home-assistant/home-assistant/pull/20064 [#20066]: https://github.com/home-assistant/home-assistant/pull/20066 [#20067]: https://github.com/home-assistant/home-assistant/pull/20067 [#20069]: https://github.com/home-assistant/home-assistant/pull/20069 [#20072]: https://github.com/home-assistant/home-assistant/pull/20072 [#20075]: https://github.com/home-assistant/home-assistant/pull/20075 [#20077]: https://github.com/home-assistant/home-assistant/pull/20077 [#20079]: https://github.com/home-assistant/home-assistant/pull/20079 [#20080]: https://github.com/home-assistant/home-assistant/pull/20080 [#20083]: https://github.com/home-assistant/home-assistant/pull/20083 [#20085]: https://github.com/home-assistant/home-assistant/pull/20085 [#20088]: https://github.com/home-assistant/home-assistant/pull/20088 [#20091]: https://github.com/home-assistant/home-assistant/pull/20091 [#20092]: https://github.com/home-assistant/home-assistant/pull/20092 [#20093]: https://github.com/home-assistant/home-assistant/pull/20093 [#20108]: https://github.com/home-assistant/home-assistant/pull/20108 [#20113]: https://github.com/home-assistant/home-assistant/pull/20113 [#20118]: https://github.com/home-assistant/home-assistant/pull/20118 [#20119]: https://github.com/home-assistant/home-assistant/pull/20119 [#20122]: https://github.com/home-assistant/home-assistant/pull/20122 [#20128]: https://github.com/home-assistant/home-assistant/pull/20128 [#20132]: https://github.com/home-assistant/home-assistant/pull/20132 [#20136]: https://github.com/home-assistant/home-assistant/pull/20136 [#20137]: https://github.com/home-assistant/home-assistant/pull/20137 [#20143]: https://github.com/home-assistant/home-assistant/pull/20143 [#20145]: https://github.com/home-assistant/home-assistant/pull/20145 [#20147]: https://github.com/home-assistant/home-assistant/pull/20147 [#20150]: https://github.com/home-assistant/home-assistant/pull/20150 [#20155]: https://github.com/home-assistant/home-assistant/pull/20155 [#20158]: https://github.com/home-assistant/home-assistant/pull/20158 [#20160]: https://github.com/home-assistant/home-assistant/pull/20160 [#20167]: https://github.com/home-assistant/home-assistant/pull/20167 [#20173]: https://github.com/home-assistant/home-assistant/pull/20173 [#20180]: https://github.com/home-assistant/home-assistant/pull/20180 [#20181]: https://github.com/home-assistant/home-assistant/pull/20181 [#20183]: https://github.com/home-assistant/home-assistant/pull/20183 [#20196]: https://github.com/home-assistant/home-assistant/pull/20196 [#20231]: https://github.com/home-assistant/home-assistant/pull/20231 [#20233]: https://github.com/home-assistant/home-assistant/pull/20233 [#20247]: https://github.com/home-assistant/home-assistant/pull/20247 [#20263]: https://github.com/home-assistant/home-assistant/pull/20263 [#20264]: https://github.com/home-assistant/home-assistant/pull/20264 [#20278]: https://github.com/home-assistant/home-assistant/pull/20278 [#20281]: https://github.com/home-assistant/home-assistant/pull/20281 [#20298]: https://github.com/home-assistant/home-assistant/pull/20298 [#20303]: https://github.com/home-assistant/home-assistant/pull/20303 [#20312]: https://github.com/home-assistant/home-assistant/pull/20312 [#20322]: https://github.com/home-assistant/home-assistant/pull/20322 [#20328]: https://github.com/home-assistant/home-assistant/pull/20328 [@Adminiuga]: https://github.com/Adminiuga [@Anonym-tsk]: https://github.com/Anonym-tsk [@BaQs]: https://github.com/BaQs [@BoboTiG]: https://github.com/BoboTiG [@Kane610]: https://github.com/Kane610 [@MartinHjelmare]: https://github.com/MartinHjelmare [@OttoWinter]: https://github.com/OttoWinter [@RealArtemiy]: https://github.com/RealArtemiy [@Rendili]: https://github.com/Rendili [@ReneNulschDE]: https://github.com/ReneNulschDE [@RomRider]: https://github.com/RomRider [@SNoof85]: https://github.com/SNoof85 [@abmantis]: https://github.com/abmantis [@achatham]: https://github.com/achatham [@adrum]: https://github.com/adrum [@amelchio]: https://github.com/amelchio [@andrewsayre]: https://github.com/andrewsayre [@arigilder]: https://github.com/arigilder [@armills]: https://github.com/armills [@arsaboo]: https://github.com/arsaboo [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@basbl]: https://github.com/basbl [@carstenschroeder]: https://github.com/carstenschroeder [@cdkonecny]: https://github.com/cdkonecny [@cliffordwhansen]: https://github.com/cliffordwhansen [@cvwillegen]: https://github.com/cvwillegen [@damarco]: https://github.com/damarco [@dmulcahey]: https://github.com/dmulcahey [@dshokouhi]: https://github.com/dshokouhi [@ehendrix23]: https://github.com/ehendrix23 [@eliseomartelli]: https://github.com/eliseomartelli [@emontnemery]: https://github.com/emontnemery [@exxamalte]: https://github.com/exxamalte [@fabaff]: https://github.com/fabaff [@finish06]: https://github.com/finish06 [@fredrike]: https://github.com/fredrike [@fronzbot]: https://github.com/fronzbot [@grea09]: https://github.com/grea09 [@iamtpage]: https://github.com/iamtpage [@jarlebh]: https://github.com/jarlebh [@jkeljo]: https://github.com/jkeljo [@kellerza]: https://github.com/kellerza [@kennedyshead]: https://github.com/kennedyshead [@keslerm]: https://github.com/keslerm [@koomik]: https://github.com/koomik [@larsvinc]: https://github.com/larsvinc [@ledor473]: https://github.com/ledor473 [@mikeage]: https://github.com/mikeage [@mindigmarton]: https://github.com/mindigmarton [@mitchellrj]: https://github.com/mitchellrj [@mopolus]: https://github.com/mopolus [@mxworm]: https://github.com/mxworm [@oblogic7]: https://github.com/oblogic7 [@pbalogh77]: https://github.com/pbalogh77 [@pnbruckner]: https://github.com/pnbruckner [@pvizeli]: https://github.com/pvizeli [@quazzie]: https://github.com/quazzie [@reefab]: https://github.com/reefab [@rohankapoorcom]: https://github.com/rohankapoorcom [@rolfberkenbosch]: https://github.com/rolfberkenbosch [@royduin]: https://github.com/royduin [@rymsha]: https://github.com/rymsha [@rytilahti]: https://github.com/rytilahti [@sander76]: https://github.com/sander76 [@scarface-4711]: https://github.com/scarface-4711 [@scop]: https://github.com/scop [@sdague]: https://github.com/sdague [@shred86]: https://github.com/shred86 [@so3n]: https://github.com/so3n [@soberstadt]: https://github.com/soberstadt [@soldag]: https://github.com/soldag [@starkillerOG]: https://github.com/starkillerOG [@syssi]: https://github.com/syssi [@tgerla]: https://github.com/tgerla [@therve]: https://github.com/therve [@thomasdelaet]: https://github.com/thomasdelaet [@thomasloven]: https://github.com/thomasloven [@ttroy50]: https://github.com/ttroy50 [@vaidyasr]: https://github.com/vaidyasr [@vincent-k]: https://github.com/vincent-k [abode docs]: /integrations/abode/ [ads docs]: /integrations/ads/ [alarm_control_panel docs]: /integrations/alarm_control_panel/ [alarm_control_panel.arlo docs]: /integrations/arlo [alarm_control_panel.elkm1 docs]: /integrations/elkm1 [alarm_control_panel.homekit_controller docs]: /integrations/homekit_controller [alarm_control_panel.MQTT docs]: /integrations/alarm_control_panel.MQTT/ [alexa docs]: /integrations/alexa/ [自动化.geo_location docs]: /docs/自动化/触发器/#geo_location-触发器 [自动化.interval docs]: /docs/自动化/触发器/#interval-触发器 [自动化.time docs]: /docs/自动化/触发器/#time-触发器 [binary_sensor.fibaro docs]: /integrations/fibaro [binary_sensor.hive docs]: /integrations/hive#binary-传感器 [binary_sensor.workday docs]: /integrations/workday [binary_sensor.xiaomi_aqara docs]: /integrations/binary_sensor.xiaomi_aqara/ [blink docs]: /integrations/blink/ [摄像头.proxy docs]: /integrations/proxy [摄像头.xiaomi docs]: /integrations/xiaomi_aqara [摄像头.zoneminder docs]: /integrations/zoneminder#摄像头 [温控.hive docs]: /integrations/hive#温控 [温控.MQTT docs]: /integrations/温控.MQTT/ [温控.sensibo docs]: /integrations/sensibo [cloud docs]: /integrations/cloud/ [遮盖.fibaro docs]: /integrations/fibaro [遮盖.homekit_controller docs]: /integrations/homekit_controller [遮盖.MQTT docs]: /integrations/遮盖.MQTT/ [deconz docs]: /integrations/deconz/ [device_tracker docs]: /integrations/device_tracker/ [doorbird docs]: /integrations/doorbird/ [emulated_roku docs]: /integrations/emulated_roku/ [esphome docs]: /integrations/esphome/ [风扇.MQTT docs]: /integrations/风扇.MQTT/ [风扇.xiaomi_miio docs]: /integrations/风扇.xiaomi_miio/ [fibaro docs]: /integrations/fibaro/ [geo_location docs]: /integrations/geo_location/ [geofency docs]: /integrations/geofency/ [gpslogger docs]: /integrations/gpslogger/ [greeneye_monitor docs]: /integrations/greeneye_monitor/ [hassio docs]: /integrations/hassio/ [hive docs]: /integrations/hive/ [homekit_controller docs]: /integrations/homekit_controller/ [homematicip_cloud docs]: /integrations/homematicip_cloud/ [ihc docs]: /integrations/ihc/ [image_processing.tensorflow docs]: /integrations/tensorflow [influxdb docs]: /integrations/influxdb/ [konnected docs]: /integrations/konnected/ [灯光.fibaro docs]: /integrations/fibaro [灯光.hive docs]: /integrations/hive#灯光 [灯光.homematicip_cloud docs]: /integrations/homematicip_cloud/ [灯光.MQTT docs]: /integrations/灯光.MQTT/ [灯光.rpi_gpio_pwm docs]: /integrations/rpi_gpio_pwm [灯光.tradfri docs]: /integrations/tradfri [locative docs]: /integrations/locative/ [门锁.homekit_controller docs]: /integrations/homekit_controller [门锁.MQTT docs]: /integrations/门锁.MQTT/ [门锁.nuki docs]: /integrations/nuki [门锁.zwave docs]: /integrations/zwave#门锁 [mailgun docs]: /integrations/mailgun/ [媒体播放器.anthemav docs]: /integrations/anthemav [媒体播放器.nad docs]: /integrations/nad [媒体播放器.roku docs]: /integrations/roku#media-player [媒体播放器.songpal docs]: /integrations/songpal [MQTT docs]: /integrations/MQTT/ [mysensors docs]: /integrations/mysensors/ [neato docs]: /integrations/neato/ [通知 docs]: /integrations/通知/ [octoprint docs]: /integrations/octoprint/ [openuv docs]: /integrations/openuv/ [plant docs]: /integrations/plant/ [rainmachine docs]: /integrations/rainmachine/ [遥控器.harmony docs]: /integrations/harmony [遥控器.roku docs]: /integrations/roku#遥控器 [roku docs]: /integrations/roku/ [场景.fibaro docs]: /integrations/fibaro [场景.hunterdouglas_powerview docs]: /integrations/hunterdouglas_powerview [传感器.ambient_station docs]: /integrations/ambient_station [传感器.blink docs]: /integrations/blink [传感器.darksky docs]: /integrations/darksky [传感器.dublin_bus_transport docs]: /integrations/dublin_bus_transport [传感器.fail2ban docs]: /integrations/fail2ban [传感器.fibaro docs]: /integrations/fibaro [传感器.flunearyou docs]: /integrations/flunearyou [传感器.freebox docs]: /integrations/freebox#传感器 [传感器.hive docs]: /integrations/hive#传感器 [传感器.imap_email_content docs]: /integrations/imap_email_content/ [传感器.influxdb docs]: /integrations/influxdb#传感器 [传感器.jewish_calendar docs]: /integrations/jewish_calendar [传感器.lastfm docs]: /integrations/lastfm [传感器.min_max docs]: /integrations/min_max [传感器.MQTT docs]: /integrations/传感器.MQTT/ [传感器.mychevy docs]: /integrations/mychevy [传感器.nest docs]: /integrations/nest#传感器 [传感器.rest docs]: /integrations/rest [传感器.sma docs]: /integrations/sma#传感器 [传感器.snmp docs]: /integrations/snmp#传感器 [传感器.tautulli docs]: /integrations/tautulli [传感器.vasttrafik docs]: /integrations/vasttrafik [传感器.zoneminder docs]: /integrations/zoneminder#传感器 [simplisafe docs]: /integrations/simplisafe/ [sonos docs]: /integrations/sonos/ [开关.fibaro docs]: /integrations/fibaro [开关.hive docs]: /integrations/hive#开关 [开关.MQTT docs]: /integrations/开关.MQTT/ [开关.snmp docs]: /integrations/snmp#开关 [开关.tradfri docs]: /integrations/tradfri [开关.xiaomi_miio docs]: /integrations/开关.xiaomi_miio/ [开关.zoneminder docs]: /integrations/zoneminder#开关 [tahoma docs]: /integrations/tahoma/ [tellduslive docs]: /integrations/tellduslive/ [tts docs]: /integrations/tts/ [unifi docs]: /integrations/unifi/ [吸尘器 docs]: /integrations/吸尘器/ [吸尘器.MQTT docs]: /integrations/吸尘器.MQTT/ [吸尘器.neato docs]: /integrations/neato#吸尘器 [waterfurnace docs]: /integrations/waterfurnace/ [wink docs]: /integrations/wink/ [zha docs]: /integrations/zha/ [zoneminder docs]: /integrations/zoneminder/ [zwave docs]: /integrations/zwave/ --- url: /home-assistant/blog/2019-01-24-nest-cannot-access-data.md --- # \[Update: we are wrong] Nest 门锁 用户 out of their own data **更新 1 (Jan 24):** 我们收到一些反馈,表示用户仍然可以创建账号并生成所需密钥。我们刚刚也验证过,情况确实如此。所以目前你依然可以访问自己的数据,这算是个好消息。只是他们对我们那条推文的回复,依然让我们摸不着头脑。也感谢 Reddit 用户 /u/lefos123 [指出](https://www.reddit.com/r/homeassistant/comments/ajgiz2/nest_locks_users_out_of_their_own_data/eevh8on/),Nest 其实早在 2018 年 11 月就 ~~宣布了这件事~~ [更新了相关链接](https://开发者.nest.com/)。 虽然目前还能用,但我们依然对 Nest API 的未来感到担忧。 *** 对于 Nest 产品用户来说,这是个令人难过的消息:Nest 不再接受新的开发者账号申请。这意味着如果你购买了 Nest 温控器,你将无法再访问属于你自己的数据。 新的 Home Assistant 用户将无法再集成他们的 Nest 产品。已经把 Home Assistant 与 Nest 完成集成的现有用户则暂时不受影响。 我们希望 Nest 后续能推出新的开发者计划,或者增加对 Nest 温控器本地控制的支持;如果他们这么做了,我们会更新这篇文章。在那之前,我们已经无法继续推荐大家购买或使用任何 Nest 产品。 --- url: /home-assistant/blog/2019-02-04-introducing-home-assistant-cli.md --- # Introducing Home Assistant CLI aka. hass-cli 当我刚开始使用 Home Assistant(HA)时,我一直觉得少了一个可以通过命令行(CLI)与 HA 交互的方式。CLI 能让你充分利用自动补全、脚本化以及直接访问带来的强大能力。 于是我开始着手开发 [Home Assistant CLI][github-hass-cli],这是一个最初由 [Fabian Affolter][@fabaff] 发起的项目。 `hass-cli` 最棒的一点在于,它使用的正是其他 UI 和集成所使用的同一套 API,因此它能很好地补充 Home Assistant 工具生态。 上周我们发布了 0.4 版本,它已经提供了我最初希望在 CLI 中实现的大部分功能。 ## 功能亮点 * Get 配置 info (`hass-cli config`) * List, get, edit and delete 状态 for 实体 (`hass-cli entity`') * Query history with relative time ('hass-cli 实体 history') * List and run 服务 (`hass-cli services`) * Execute 模板 locally and remotely (`hass-cli template`) * Control over columns, sorting, etc. (`hass-cli --columns attr1,attr2 --sort-by attr3`) * Shell completion for most commands and arguments (`hass-cli completion zsh`) * Get 日志 (`hass-cli system log`) * Run discovery (`hass-cli discover`) * Show map for 区域 (`hass-cli map`) * Call raw api directly (`hass-cli raw`) * ... and more ## 用法 关于 `hass-cli` 的基础介绍,请查看 [GitHub][github-hass-cli] 上的文档。 ## 安装 使用 pip 安装最新版 `homeassistant-cli`: ``` $ pip3 安装 homeassistant-cli ``` 如果要升级,请使用: ``` $ pip3 安装 --升级 homeassistant-cli ``` 如果你更喜欢隔离式安装,也可以使用 [pipsi][pipsi]: ``` $ pipsi 安装 --python python3 homeassistant-cli ``` 如果你喜欢折腾,也可以直接从 [source][github-hass-cli] 自行构建。 ## 相比 0.1-0.3 的变化 首先,命令体系经过了清理,整体变得更清晰,也更明确。 ``` $ hass-cli ... ... Commands: completion Output shell completion code for the specified shell (bash or... config Get 配置 from a Home Assistant instance. discover Discovery for the local network. 实体 Get info and operate on 实体 from Home Assistant. event Interact with events. info Get basic info from Home Assistant. map Print the current location on a map. raw Call the raw API (advanced). 服务 Call and work with 服务. system System details and operations for Home Assistant. 模板 Render 模板 on server or locally. ``` 现在的命令不再使用笼统的通用词(例如 get、list),而是采用更明确的命名,并提供进一步的子命令层级。 最大的变化是,大多数操作现在默认使用“table”模式。也就是说,你拿到的不再是一大段 YAML 或 JSON 导出结果,而是更简洁清晰的表格视图: ``` $ hass-cli 实体 list winter 实体 DESCRIPTION 状态 timer.timer_winter_garden idle group.winter_garden_lights Winter Garden 灯光 off group.winter_garden_motionview winter garden off 灯光.winter_garden_light_2 Winter Garden 灯光 2 off 灯光.winter_garden_light_5 Winter Garden 灯光 5 off 灯光.winter_garden_light_1 Winter Garden 灯光 1 off 灯光.winter_garden_light_3 Winter Garden 灯光 3 off 灯光.winter_garden_light_4 Winter Garden 灯光 4 off 媒体播放器.winter_garden Winter Garden paused 传感器.lightlevel_winter_garden Winter Garden Motion 1.0 传感器.temperature_winter_garden Winter Garden Temperature 5.0 ``` 除了更好的表格展示外,你还可以通过 `--sort-by` 按某个属性排序,也可以用 `--columns` 控制要显示哪些属性。 你还可以把这些能力组合起来,做类似下面这样的历史记录查询: ``` $ hass-cli --sort-by last_changed 实体 history \ --since 50m 灯光.kitchen_light_1 binary_sensor.presence_kitchen 实体 DESCRIPTION 状态 binary_sensor.presence_kitchen Kitchen Motion off 灯光.kitchen_light_1 Kitchen 灯光 1 on binary_sensor.presence_kitchen Kitchen Motion on binary_sensor.presence_kitchen Kitchen Motion off 灯光.kitchen_light_1 Kitchen 灯光 1 off ``` 如果你仍然希望查看完整细节,也可以使用 `-o yaml` 输出全部内容。 ## 常见问题 下面是过去几个月里我们经常遇到的一些问题: ### 为什么会有人使用它? 它并不是为了取代现有访问 Home Assistant 的方式,也不是来和它们竞争的;它只是一个补充选项。如果你喜欢 CLI 以及自动补全带来的效率,你会觉得 `hass-cli` 非常好用;如果你更喜欢浏览器中的 UI,那就继续照常使用即可。我们自己平时也会继续使用 UI,但在追求效率或者需要脚本化操作时,`hass-cli` 就特别合适。 ### 为什么不直接用 `curl` 之类的工具调用 REST API? 你当然可以直接用 `curl` 或类似工具访问 REST API——这本质上也是 `hass-cli` 在幕后所做的事情。不过 `hass-cli` 还是有一些优势。首先,你不需要死记每个精确命令,因为 `hass-cli` 提供了上下文帮助和自动补全,输入起来会轻松很多。其次,随着未来 `hass-cli` 逐步支持更完整的 WebSocket API,相比用 `curl` 做“原始访问”,它会变得更一致,也更易用。 ### 它只能配合 HTTPS 和 hass.io 使用吗? 不是,它适用于 *任何* 暴露了 REST API 的 Home Assistant,而这本来就是默认行为。简单来说,只要你能在浏览器中打开 Home Assistant 并看到 UI,`hass-cli` 就也能与它通信并进行控制。 所以无论是 HTTP、HTTPS、hass.io,还是非 hass.io 方式,`hass-cli` 都支持。 ### 使用它之前,我需要先在本机安装 Home Assistant 吗? 不需要,`hass-cli` 并不要求你运行它的那台电脑上已经安装了 Home Assistant。只要系统装有 Python 3.5 或更高版本,它就应该能在主流操作系统上运行。 ### 它支持客户端生成的证书吗? 理论上应该支持,但我们目前还没有完成验证。如果你愿意帮忙测试,可以使用 `--cert ` 运行,并在 issue [#66][client-cert-git] 中告诉我们结果。 ## 下一步计划 就我个人而言,接下来最想加入的功能,是对系统控制命令提供更具体的支持(例如刷新分组、重启等),以及支持访问 hass.io 插件。同时,我也希望能提供一种简单方式,让用户接入事件总线(通过 WebSocket),实时查看系统里正在发生的事情。 你最希望看到什么功能? ## 反馈 如果你有问题或反馈,可以直接在这篇博文下留言,或者前往 [hass-cli 论坛主题][forum-Thread-hasscli],也可以在 [GitHub][github-hass-cli] 提交 issue 或 pull request。 祝你玩得开心! [Max Rydahl Andersen][@maxandersen] [pipsi]: https://github.com/mitsuhiko/pipsi [github-hass-cli]: https://github.com/home-assistant/home-assistant-cli [github-hass-issues]: https://github.com/home-assistant/home-assistant-cli/issues [@fabaff]: https://github.com/fabaff [forum-Thread-hasscli]: https://community.home-assistant.io/t/resurrected-feature-home-assistant-cli/84107 [client-cert-git]: https://github.com/home-assistant/home-assistant-cli/issues/66 [@maxandersen]: https://xam.dk/about --- url: /home-assistant/blog/2019-02-06-release-87.md --- --- url: /home-assistant/blog/2019-02-11-hass-cli-0-dot-5-area-entity-registry-and-event-cli.md --- # hass-cli 0.5: 区域, 设备 Registry and event CLI With [Home Assistant 0.87][hass-087] out we got 区域 and 设备 Registry UI thus it is time to do a 发布 of `hass-cli` that allows you to operate on these in a terminal. This 发布 adds the following features: * 区域 `list`, `create`, `delete`, and `rename` * 设备 `list` and `assign` * Event `watch` To get it run: ``` $ pip3 安装 homeassistant-cli ``` And once you have configured some of the new things you can like: Create an 区域: ``` $ hass-cli 区域 create Attic - id: 1 type: result success: true result: area_id: 83977bdb16524579a856560925a791a7 name: Attic ``` List all your 区域: ``` $ hass-cli 区域 list ID NAME 295afc88012341ecb897cd12d3fbc6b4 Bathroom 9e08d89203804d5db995c3d0d5dbd91b Winter Garden 8816ee92b7b84f54bbb30a68b877e739 Office e6ebd3e6f6e04b63a0e4a109b4748584 Kitchen f7f5412a9f47436da669a537e0c0c10f Livingroom bc98c209249f452f8d074e8384780e15 Hallway 83977bdb16524579a856560925a791a7 Attic ``` List 设备 matching a pattern: ``` $ hass-cli 设备 list "Kitchen.*灯光*" ID NAME MODEL MANUFACTURER 区域 f9cad07069c74d519fbe84811c91f1fb Kitchen 灯光 2 LCT003 Philips e6ebd3e6f6e04b63a0e4a109b4748584 d02ec64623ae4407a80b903cbc061511 Kitchen 灯光 3 LCT003 Philips e6ebd3e6f6e04b63a0e4a109b4748584 820c9e511fce42ea92b228c18710aa56 Kitchen 灯光 1 LCT003 Philips e6ebd3e6f6e04b63a0e4a109b4748584 417dd42c0c764765aa29580d77b8b7ad Kitchen 灯光 5 LCT003 Philips e6ebd3e6f6e04b63a0e4a109b4748584 ``` Like with `entity list` you can filter and pipe results to get interesting things. How about a inventory count? ``` $ hass-cli --no-headers --columns manufacturer,model 设备 list | sort | uniq -c | sort -nr 10 IKEA of Sweden TRADFRI bulb GU10 WS 400lm 8 Philips SML001 7 LUMI lumi.sensor_magnet.aq2 6 Sonos Play:1 6 Philips LTW012 6 Philips LCT003 6 Philips Hue color spot 6 Philips Hue ambiance candle 5 Philips LWG001 5 Philips LCT012 5 Philips Hue color candle 5 IKEA of Sweden TRADFRI bulb E14 W op/ch 400lm 4 Sonos One 4 Philips RWL021 4 Philips Hue color lamp 4 IKEA of Sweden TRADFRI 遥控器 control 3 Philips Hue lightstrip plus 3 OSRAM Color temperature 灯光 3 LUMI lumi.vibration.aq1 3 IKEA of Sweden TRADFRI transformer 30W .... ``` And then my favorite feature, assign of 区域 to a 设备: ``` $ hass-cli 设备 assign Kitchen "Kitchen 灯光 2" ``` or even more powerful, bulk-assign to any 实体 matching a certain pattern: ``` $ hass-cli 设备 assign --match "Kitchen" Kitchen Successfully assigned 'Kitchen' to 'Kitchen' Successfully assigned 'Kitchen' to 'Kitchen table left' Successfully assigned 'Kitchen' to 'Kitchen table right' Successfully assigned 'Kitchen' to 'Kitchen left middle at window' Successfully assigned 'Kitchen' to 'Kitchen front right at fridge' Successfully assigned 'Kitchen' to 'Kitchen left back at hub' Successfully assigned 'Kitchen' to 'Kitchen left back at bar' Successfully assigned 'Kitchen' to 'Kitchen right back at sink' Successfully assigned 'Kitchen' to 'Kitchen right middle at oven' Successfully assigned 'Kitchen' to 'Kitchen 灯光 2' Successfully assigned 'Kitchen' to 'Kitchen 灯光 3' .... ``` And finally as a little bonus feature you can now watch the event bus from the CLI: All events: ``` $ hass-cli event watch ``` or specific events: ``` $ hass-cli event watch call_service ``` At the moment the output is raw JSON, that will improve in a future 发布. The full change list including bugfixes from community is as follows: ## What's Changed New features: * 设备, 区域 and event support [237ade8](http://github.com/home-assistant/home-assistant-cli/commit/237ade81372d25bfb3655c6a9f10d4aa697cad2e) @maxandersen * add minimal dockerfile [2b00bd7](http://github.com/home-assistant/home-assistant-cli/commit/2b00bd7e5b865775e7787c9cedf8d9c17d5f68cb) Ben Lebherz Bug fixes: * fix(实体): honor --columns in 实体 get [67397a1](http://github.com/home-assistant/home-assistant-cli/commit/67397a102295381d5d9101a51764643a3668e1e6) @maxandersen * Fix result reporting from 服务 calls [14fc952](http://github.com/home-assistant/home-assistant-cli/commit/14fc9527ec0861a7dd26e185f4937bf9aace7f07) @maxandersen * Remove pyaml and move to ruamel only for yaml [df9f8c2](http://github.com/home-assistant/home-assistant-cli/commit/df9f8c23fa9993f16c735159634f29d2a50e1a43) @maxandersen Minor fixes: * fix: 发布 0.5.0 版本 [200a099](http://github.com/home-assistant/home-assistant-cli/commit/200a099d066f2f5b34cce986e29952f4b6bb6594) @maxandersen * fix: be pep440 complant [98320f8](http://github.com/home-assistant/home-assistant-cli/commit/98320f888b75c8a091c5d19b154cac5b2946ac7b) @maxandersen * fix: fix lint 错误 [eca26fa](http://github.com/home-assistant/home-assistant-cli/commit/eca26fa4c2ebd0637a75a221dc17af60210bd0b3) @maxandersen * fix: fix lint 错误 [ffd2369](http://github.com/home-assistant/home-assistant-cli/commit/ffd23695cace01e872590fba06dedab63a56693f) @maxandersen * enable deploy of git timestamped build [4b27a65](http://github.com/home-assistant/home-assistant-cli/commit/4b27a65a2ddab302d97253b677df55739696c6d7) @maxandersen * Merge branch 'master' into dev [caaf7b1](http://github.com/home-assistant/home-assistant-cli/commit/caaf7b160f1bc7f7854d82ecdb35d0954c5e7ea8) @maxandersen * add Docker reference [d3b64e8](http://github.com/home-assistant/home-assistant-cli/commit/d3b64e886f2a3380e0c4dceb0ea5a5c7d8e7eedc) @maxandersen * docs: add docs for 区域, 设备 and event watch [ee4f74a](http://github.com/home-assistant/home-assistant-cli/commit/ee4f74af87ec810a135c66d0d193a14242213328) @maxandersen * Make dockerfile build from source + entrypoint [b7f8764](http://github.com/home-assistant/home-assistant-cli/commit/b7f876420df65b07a6b2a99c0e7dc7635711c1cd) @maxandersen * Fix lint issue [8bb0c9e](http://github.com/home-assistant/home-assistant-cli/commit/8bb0c9e4d62ff364f54e1561573e37c7517a46c9) @fabaff * Fix lint issues [58fdc83](http://github.com/home-assistant/home-assistant-cli/commit/58fdc835978f0448d43e43595379c32c161f3af3) @fabaff * fix bad typing [499b544](http://github.com/home-assistant/home-assistant-cli/commit/499b5449b0441b546ea48aff212754433457dbd5) @maxandersen * fix editor formatting [86d9bf8](http://github.com/home-assistant/home-assistant-cli/commit/86d9bf8bf6bfb5bec1a9f28177c105f84912a91b) @maxandersen * Fix 版本 [3765a03](http://github.com/home-assistant/home-assistant-cli/commit/3765a03ccf11f0865baa7e70937279bcaa245352) @maxandersen * Fix 版本 marker [edbe4bf](http://github.com/home-assistant/home-assistant-cli/commit/edbe4bf42e7d0993d68a367ca04ad80217aac395) @maxandersen Have fun! [Max Rydahl Andersen][@maxandersen] [@maxandersen]: https://xam.dk/about [hass-087]: /博客/2019/02/06/发布-87/ --- url: /home-assistant/blog/2019-02-20-release-88.md --- --- url: /home-assistant/blog/2019-03-13-release-89.md --- # 0.89:Nissan Leaf、PlayStation 4、Point 报警控制、Owlet 婴儿监护器 0.89 发布时间到!这又是一次精彩的新版本,带来了不少酷炫的新功能、bug 修复和改进。第一个亮点是,又有一款汽车接入了 Home Assistant:Nissan Leaf。deConz 和 SmartThings 集成也继续扩展,覆盖了更多设备。 本次发布引入了一个新的 mobile\_app 集成。也参与 iOS 应用开发的 [@robbiet480] 提取了 Home Assistant iOS app 集成中最优秀的部分,并将其改造成一个任何移动应用都可以构建于其上的标准化 API。这将让各种移动应用都能以优秀的用户体验集成 Home Assistant。如果你是移动应用开发者,请查看更新后的 [app integrations docs](https://开发者.home-assistant.io/docs/api/native-app-integrations/)。我们会在后续版本中继续打磨这个 API,也欢迎反馈。 ## 值得注意的向后不兼容变更 **自定义组件文件结构变更:** Home Assistant 底层工作方式发生了一项重要变化,现在如果组件路径存在,平台解析将被强制基于该组件路径进行。 目前,如果你愿意,你可以覆写 Hue 的灯光平台,但不能覆写 Hue 集成的其他部分。如果未来的更新改动了 Hue 组件,移除了或更改了自定义平台所依赖的内部方法,那么你的自定义平台就会开始失效([就像这个报告里描述的情况](https://github.com/home-assistant/home-assistant/issues/17943#issuecomment-462014778))。 为避免这种情况,我们将\_\_不再允许自定义组件只局部覆写\_\_(仅覆写某个平台)。换句话说,如果你想覆写内置平台,**你需要覆写整个组件**。 这一点通过优先把平台解析为组件来实现;如果该组件存在,就会把查找路径限制在该组件路径下。 举个例子:如果我查找 `hue` 组件,而它来自某个自定义组件,那么该组件下的所有平台查找也都会在这个自定义组件目录中进行。反过来也是一样:如果用户只想覆写 `hue/light.py`,却没有提供 `hue/__init__.py`,那么这个自定义平台会被忽略。 如果你想了解更多,Paulus 已经在开发者博客上详细介绍了这项变更:[The Great Migration by Paulus](https://开发者.home-assistant.io/博客/2019/02/19/the-great-migration.html) **Existing SmartThings 配置 entries will be removed,** including the SmartApp/自动化 from the SmartThings app. Home Assistant will prompt you to 配置 the 集成 again or it can be invoked from the 集成 page. The 配置 process is the same as before. To prepare, have your *personal access token and a mobile 设备 with the SmartThings Classic App handy.* This will not affect the naming of 设备 or 实体 and is a **one-time inconvenience.** The implementation 开关 over to the SmartApp access token to synchronize subscriptions during 设置 of the config entry, which cannot be done using the personal access token. ## 新平台 * Météo-France platform for the 天气 component ([@victorcerutti] - [#18404]) ([传感器.meteo\_france docs][传感器.meteo_france docs]) ([天气.meteo\_france docs][天气.meteo_france docs]) (new-platform) * Point 报警 control ([@fredrike] - [#20972]) ([point docs]) (new-platform) * Nissan Leaf 集成 (Carwings / NissanConnect EV) ([@filcole] - [#19786]) ([device\_tracker docs][device_tracker docs]) ([nissan\_leaf docs][nissan_leaf docs]) ([binary\_sensor.nissan\_leaf docs][binary_sensor.nissan_leaf docs]) ([传感器.nissan\_leaf docs][传感器.nissan_leaf docs]) ([开关.nissan\_leaf docs][开关.nissan_leaf docs]) (new-platform) * Rewrite of Toon component ([@frenck] - [#21186]) ([toon docs]) (breaking change) (new-platform) * Times of The Day 二元sensor ([@kstaniek] - [#20068]) ([binary\_sensor.tod docs][binary_sensor.tod docs]) (new-platform) * Add 开关 platform for Danfoss Air and additional 传感器. ([@JonasPed] - [#21046]) ([danfoss\_air docs][danfoss_air docs]) (new-platform) * Owlet baby monitor component ([@oblogic7] - [#21108]) (new-platform) * deCONZ thermostat support ([@Kane610] - [#20586]) ([deconz docs]) (new-platform) * Added 设备 tracker support for Ubee Router ([@mzdrale] - [#19586]) ([device\_tracker docs][device_tracker docs]) (new-platform) * Add LCN 遮盖 platform ([@alengwenus] - [#20288]) ([lcn docs]) ([遮盖.lcn docs]) (new-platform) * Add initial support for Sony SDCP projector control ([@alistairg] - [#20269]) ([开关.sony\_projector docs][开关.sony_projector docs]) (new-platform) * Add SmartThings 遮盖 platform and add 遮盖 设备 classes ([@andrewsayre] - [#21192]) ([遮盖 docs]) ([smartthings docs]) (breaking change) (new-platform) * Add SmartThings 场景 platform ([@andrewsayre] - [#21405]) ([smartthings docs]) (new-platform) * Reddit 传感器 ([@ljmerza] - [#21344]) ([传感器.reddit docs]) (new-platform) * mobile\_app component ([@robbiet480] - [#21475]) ([mobile\_app docs][mobile_app docs]) (beta fix) (new-platform) * Add component media player.ps4 ([@ktnrg45] - [#21074]) ([ps4 docs]) ## 发布 0.89.1 - March 8 * 升级 blinkpy==0.13.1 (Fixes #21559) ([@fronzbot] - [#21578]) ([blink docs]) * Fix Name of Homematic IP accesspoint in 设备, if name is configured ([@SukramJ] - [#21617]) ([homematicip\_cloud docs][homematicip_cloud docs]) * Fix group-开关 availability for Homematic IP ([@SukramJ] - [#21640]) ([homematicip\_cloud docs][homematicip_cloud docs]) * automated commit 07/03/2019 10:47:38 ([@ljmerza] - [#21749]) ([传感器.google\_travel\_time docs][传感器.google_travel_time docs]) * Fix botvac connected maps call as it is not a supported model ([@dshokouhi] - [#21752]) ([neato docs]) * Fix colorlog import 错误 ([@awarecan] - [#21754]) * Fix 脚本 load module issue ([@awarecan] - [#21763]) * Bump PyXiaomiGateway 版本 to 0.12.2 (Closes: #21731) ([@syssi] - [#21764]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * adds missing SUPPORT\_VOLUME\_SET flag to webos 媒体播放器 ([@dthulke] - [#21766]) ([webostv docs]) * Updated to newest pyeconet ([@w1ll1am23] - [#21772]) ([water\_heater docs][water_heater docs]) [#21578]: https://github.com/home-assistant/home-assistant/pull/21578 [#21617]: https://github.com/home-assistant/home-assistant/pull/21617 [#21640]: https://github.com/home-assistant/home-assistant/pull/21640 [#21749]: https://github.com/home-assistant/home-assistant/pull/21749 [#21752]: https://github.com/home-assistant/home-assistant/pull/21752 [#21754]: https://github.com/home-assistant/home-assistant/pull/21754 [#21763]: https://github.com/home-assistant/home-assistant/pull/21763 [#21764]: https://github.com/home-assistant/home-assistant/pull/21764 [#21766]: https://github.com/home-assistant/home-assistant/pull/21766 [#21772]: https://github.com/home-assistant/home-assistant/pull/21772 [@SukramJ]: https://github.com/SukramJ [@awarecan]: https://github.com/awarecan [@dshokouhi]: https://github.com/dshokouhi [@dthulke]: https://github.com/dthulke [@fronzbot]: https://github.com/fronzbot [@ljmerza]: https://github.com/ljmerza [@syssi]: https://github.com/syssi [@w1ll1am23]: https://github.com/w1ll1am23 [blink docs]: /integrations/blink/ [homematicip_cloud docs]: /integrations/homematicip_cloud/ [neato docs]: /integrations/neato/ [传感器.google_travel_time docs]: /integrations/google_travel_time [water_heater docs]: /integrations/water_heater/ [webostv docs]: /integrations/webostv/ [xiaomi_aqara docs]: /integrations/xiaomi_aqara/ ## 发布 0.89.2 - March 12 * 更新 dependencies to receive data on Webhook callbacks ([@andrewsayre] - [#21838]) ([smartthings docs]) * Override http.trusted\_networks by auth\_provider.trusted\_networks ([@awarecan] - [#21844]) ([http docs]) * Fix botvac when no map exists ([@dshokouhi] - [#21877]) ([neato docs]) * Fixes issues #21821 and #21819 ([@kstaniek] - [#21911]) ([binary\_sensor.tod docs][binary_sensor.tod docs]) [#21838]: https://github.com/home-assistant/home-assistant/pull/21838 [#21844]: https://github.com/home-assistant/home-assistant/pull/21844 [#21877]: https://github.com/home-assistant/home-assistant/pull/21877 [#21911]: https://github.com/home-assistant/home-assistant/pull/21911 [@andrewsayre]: https://github.com/andrewsayre [@awarecan]: https://github.com/awarecan [@dshokouhi]: https://github.com/dshokouhi [@kstaniek]: https://github.com/kstaniek [binary_sensor.tod docs]: /integrations/tod [http docs]: /integrations/http/ [neato docs]: /integrations/neato/ [smartthings docs]: /integrations/smartthings/ ## 如果你需要帮助…… 欢迎使用我们非常活跃的[论坛](https://community.home-assistant.io/),或者加入我们的[聊天频道](https://discord.gg/c5DvZ4e)。虽然发布说明开放评论,但我们更希望你使用前面这些沟通渠道。谢谢。 ## 反馈问题 如果你遇到了这个版本引入的问题,请在我们的 [issue tracker](https://github.com/home-assistant/home-assistant/issues) 中报告。请务必填写 issue 模板中的所有字段。 ## 向后不兼容的变更 * **HomeMatic component's wireless actors** are having two RSSI values. The way the component was programmed one of them was being overwritten. With this new change, the **`rssi` 属性 of HomeMatic 实体 has been removed.** As a replacement the 属性 rssi\_device and rssi\_peer have been added. The 属性 of `rssi` will no longer be available, you'll need to **update to `rssi_device`,** and you can add `rssi_peer` now as well! (fixes #20900) ([@dagobert] - [#20902]) ([homematic docs]) (breaking change) * You can now specifiy an 动作 when calling the **yeelight\_start\_flow service** on your yeelights. The **default 动作 will be 'recover'** if you do not specify something else. This 动作 will be taken after the flow stops. ([@zewelor] - [#21195]) ([灯光.yeelight docs]) (breaking change) * Custom platforms that override a built-in platform that has a component, should now also include the component in the custom\_components/ folder. So if you want to override `hue/light.py` with a custom 版本, **you will also need to provide/copy over `hue/__init__.py`.** See details in main section about this change. ([@balloob] - [#21070]) (breaking change) * Automatic discovery of **TP-Link 开关, bulbs and dimmers.** This is a continuation of #15329 and adds support for automatic discovery of TP-Link bulbs, 开关, and dimmers based on the new config flow. The 集成 needs to be enabled either in the **integration 配置 or** alternatively by **adding tplink component** to the 配置 file. As the 设备 are now configured on the component, this is a **breaking change for 灯光.tplink and 开关.tplink.** ([@rytilahti] - [#18091]) ([tplink docs]) ([灯光.tplink docs]) ([开关.tplink docs]) (breaking change) * Enhance **SmartThings component** subscription. See details in main section about this change. ([@andrewsayre] - [#21124]) ([smartthings docs]) (breaking change) (new-feature) * The **iperf3 传感器 platform** has been **separated** into a component and a 传感器 to remove the 服务 from the 传感器 platform. 配置 options have changed, **please review the documentation** and select the correct options. ([@rohankapoorcom] - [#21138]) ([iperf3 docs]) **([传感器.iperf3 docs])** (breaking change) (new-platform) * The **`google_travel_time`** platform no longer has an 更新 服务, use **homeassistant.更新 with the appropriate entity\_id(s) instead.** ([@rohankapoorcom] - [#21153]) ([传感器.google\_travel\_time docs][传感器.google_travel_time docs]) (breaking change) * Add ADB server functionality to **Fire TV.** This change **removes the `get_source`** 配置 option. ([@JeffLIrion] - [#21221]) ([媒体播放器.firetv docs]) (breaking change) * With the addition of the **SmartThings Cover** platform, the SmartThings **Sensor platform will no longer represent Door, Garage Door and Window Share 属性.** Additionally, if the 遮盖 设备 reports battery status, the value will be present as a **state attribute** (battery\_level) and not a discrete 传感器. ([@andrewsayre] - [#21192]) ([遮盖 docs]) ([smartthings docs]) (breaking change) (new-platform) * The **Toon component** was broken some time ago, so now requires a Toon API developer account and **can be configured using the Home Assistant 集成.** Support for 开关 & Smoke detectors has been removed. ([@frenck] - [#21186]) ([toon docs]) (breaking change) (new-platform) * Addition of config for **trusted networks auth provider.** It is a backward-incompatible changes for 用户 who **manually configured** trusted network auth provider. An invalid config 错误 will be thrown and HA won't be able to fully started. (It is NOT a backward-incompatible changes for 用户 who didn't manual configured trusted network auth provider.) ([@awarecan] - [#21111]) (breaking change) * For some **HomeMatic 设备 the `sabotage` 属性 is replaced by `error`.** The value (if not 0) is a 设备 specific 错误 code. ([@dagobert] - [#21009]) ([homematic docs]) (breaking change) ## Beta 修复 * Add PLATFORM\_SCHEMA\_BASE to telegram\_bot component ([@veleek] - [#21155]) ([telegram\_bot docs][telegram_bot docs]) (beta fix) * Add watchdog to Ambient PWS ([@bachya] - [#21507]) ([ambient\_station docs][ambient_station docs]) (beta fix) * Improve new Sonos snapshot/恢复 ([@amelchio] - [#21509]) ([sonos docs]) (beta fix) * Fix lint ([@balloob] - [#21520]) ([person docs]) ([传感器.airvisual docs]) (beta fix) * Only use a single store instance ([@balloob] - [#21521]) ([前端 docs]) (beta fix) * Allow skip-pip applied to HA 核心 ([@awarecan] - [#21527]) (beta fix) * Updated variable name for readability ([@gorynychzmey] - [#21528]) ([person docs]) (beta fix) * Add missing retain option to MQTT.温控 配置 schema ([@emontnemery] - [#21536]) ([MQTT docs]) (beta fix) * Fix 警告 ([@awarecan] - [#21538]) ([http docs]) (beta fix) * Fix incorrect pyairvisual call ([@bachya] - [#21542]) ([传感器.airvisual docs]) (beta fix) * mobile\_app component ([@robbiet480] - [#21475]) ([mobile\_app docs][mobile_app docs]) (beta fix) (new-platform) * Make time 触发器 data 触发器.now local ([@emontnemery] - [#21544]) (beta fix) * Bump zigpy-deconz ([@damarco] - [#21566]) ([zha docs]) (beta fix) * Re-thrown exception occurred in the blocking 服务 call ([@awarecan] - [#21573]) ([websocket\_api docs][websocket_api docs]) (beta fix) * 升级 PyXiaomiGateway library ([@Danielhiversen] - [#21582]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) (beta fix) * 日志 exception occurred in WS 服务 call command ([@awarecan] - [#21584]) ([websocket\_api docs][websocket_api docs]) (beta fix) * Word the tplink deprecation 警告 more strongly ([@amelchio] - [#21586]) ([tplink docs]) (beta fix) * Handle when 已安装 app has already been removed ([@andrewsayre] - [#21595]) ([smartthings docs]) (beta fix) * Resolve race 条件 when HA auth provider is loading ([@awarecan] - [#21619]) (beta fix) * 升级 pysonos to 0.0.8 ([@amelchio] - [#21624]) ([sonos docs]) (beta fix) * Fix calc next ([@balloob] - [#21630]) (beta fix) * Cast displaytime to int for JSON RPC ([@GGeezes] - [#21649]) ([通知 docs]) (beta fix) * :shirt: Corrects unit of measurement symbol for Watt ([@frenck] - [#21654]) ([toon docs]) (beta fix) * Rename Google Assistant events ([@balloob] - [#21655]) ([google\_assistant docs][google_assistant docs]) (beta fix) * :ambulance: Fixes Toon doing I/O in coroutines ([@frenck] - [#21657]) ([toon docs]) (beta fix) * 升级 toonapilib to 3.1.0 ([@frenck] - [#21661]) ([toon docs]) (beta fix) * Avoid recorder Thread crashing ([@balloob] - [#21668]) (beta fix) * check we have a tb ([@dgomes] - [#21670]) ([system\_log docs][system_log docs]) (beta fix) * Fix ADS race 条件 ([@carstenschroeder] - [#21677]) ([ads docs]) (beta fix) * resync hass that changes have occurred ([@fredrike] - [#21705]) ([tellduslive docs]) (beta fix) * 升级 toonapilib to 3.2.1 ([@frenck] - [#21706]) ([toon docs]) (beta fix) ## 所有变更 * Météo-France platform for the 天气 component ([@victorcerutti] - [#18404]) ([传感器.meteo\_france docs][传感器.meteo_france docs]) ([天气.meteo\_france docs][天气.meteo_france docs]) (new-platform) * 更新 file header ([@fabaff] - [#21061]) * 温控 const.py move ([@elupus] - [#20945]) * 更新 file header ([@fabaff] - [#21067]) * Rename CONF\_ATTRIBUTION to ATTRIBUTION ([@fabaff] - [#21069]) * Bump pyHik library to 0.2.2, improve connections, add 传感器 ([@mezz64] - [#21086]) ([binary\_sensor.hikvision docs][binary_sensor.hikvision docs]) * Meteo france ([@fabaff] - [#21065]) ([meteo\_france docs][meteo_france docs]) * Fix "Unable to find 实体" at Waze component ([@VirtualL] - [#21087]) ([传感器.waze\_travel\_time docs][传感器.waze_travel_time docs]) * Point 报警 control ([@fredrike] - [#20972]) ([point docs]) (new-platform) * Times of The Day 二元sensor ([@kstaniek] - [#20068]) ([binary\_sensor.tod docs][binary_sensor.tod docs]) (new-platform) * Nissan Leaf 集成 (Carwings / NissanConnect EV) ([@filcole] - [#19786]) ([device\_tracker docs][device_tracker docs]) ([nissan\_leaf docs][nissan_leaf docs]) ([binary\_sensor.nissan\_leaf docs][binary_sensor.nissan_leaf docs]) ([传感器.nissan\_leaf docs][传感器.nissan_leaf docs]) ([开关.nissan\_leaf docs][开关.nissan_leaf docs]) (new-platform) * Add 开关 platform for Danfoss Air and additional 传感器. ([@JonasPed] - [#21046]) ([danfoss\_air docs][danfoss_air docs]) (new-platform) * Config Entry migrations ([@andrewsayre] - [#20888]) * Refactor http CachingStaticResource ([@awarecan] - [#21062]) ([http docs]) * Add index parameter to scrape 传感器 ([@davidbb] - [#21084]) ([传感器.scrape docs]) * Owlet baby monitor component ([@oblogic7] - [#21108]) (new-platform) * Order imports ([@fabaff] - [#21117]) * Add Groups to Homematic IP ([@SukramJ] - [#21076]) ([homematicip\_cloud docs][homematicip_cloud docs]) * Remove outdated url pattern match support for static file hosting ([@awarecan] - [#21109]) ([http docs]) * 升级 pytest to 4.2.1 ([@scop] - [#21112]) * Make Netatmo able to discover both 天气 station and Health Coach ([@msvinth] - [#20274]) * Add Webhook support for Netatmo 摄像头 ([@danielperna84] - [#20755]) ([netatmo docs]) * Logging to find what deCONZ events get 创建 ([@Kane610] - [#20551]) * Add traccar scan\_interval 配置 option ([@lapy] - [#21079]) ([device\_tracker docs][device_tracker docs]) * Add component media player.ps4 ([@ktnrg45] - [#21074]) ([ps4 docs]) * Add traccar monitored\_conditions option ([@lapy] - [#21149]) ([device\_tracker docs][device_tracker docs]) * RSSI\_PEER and RSSI\_DEVICE are different things (fixes #20900) ([@dagobert] - [#20902]) ([homematic docs]) (breaking change) * 升级 voluptuous-serialize to 2.1.0 ([@fabaff] - [#21166]) * 升级 youtube\_dl to 2019.02.18 ([@fabaff] - [#21164]) ([media\_extractor docs][media_extractor docs]) * 升级 sqlalchemy to 1.2.18 ([@fabaff] - [#21162]) ([传感器.sql docs]) * 升级 psutil to 5.5.1 ([@fabaff] - [#21171]) ([传感器.systemmonitor docs]) * Fix HomematicIP Cloud fix 遮盖 position property ([@mxworm] - [#21154]) ([homematicip\_cloud docs][homematicip_cloud docs]) * Clean up upc\_connect tests ([@MartinHjelmare] - [#21150]) * deCONZ thermostat support ([@Kane610] - [#20586]) ([deconz docs]) (new-platform) * Add context to 服务 call event ([@balloob] - [#21181]) * Expose effect\_list 属性 for turned off 灯光 ([@OleksandrBerchenko] - [#20750]) * Philips Hue: Add bridge 更新 prompt ([@starkillerOG] - [#21119]) ([hue docs]) * 升级 crimereports to 1.0.1 ([@fabaff] - [#21187]) ([传感器.crimereports docs]) * Netatmo, address comments from #20755 ([@danielperna84] - [#21157]) ([netatmo docs]) * Use constants from const.py ([@fabaff] - [#21068]) ([insteon docs]) ([knx docs]) ([raspihats docs]) ([灯光.rpi\_gpio\_pwm docs][灯光.rpi_gpio_pwm docs]) ([传感器.etherscan docs]) ([传感器.ripple docs]) ([传感器.sochain docs]) * Bump Synology SRM dependency to 版本 0.0.6 ([@aerialls] - [#21212]) ([device\_tracker docs][device_tracker docs]) * 升级 numpy to 1.16.1 ([@fabaff] - [#21190]) ([binary\_sensor.trend docs][binary_sensor.trend docs]) ([image\_processing.tensorflow docs][image_processing.tensorflow docs]) ([传感器.pollen docs]) * Fix Homematic IP Cloud 配置 ([@bauerj] - [#21202]) ([homematicip\_cloud docs][homematicip_cloud docs]) * Add yeelight flow 动作 support ([@zewelor] - [#21195]) ([灯光.yeelight docs]) (breaking change) * Fix the build ([@balloob] - [#21229]) * 更新 pyhomematic to 0.1.56 ([@danielperna84] - [#21227]) ([homematic docs]) * Add self to 集成 传感器 and utility\_meter ([@dgomes] - [#21226]) * Add 区域 and reps for Xiaomi 吸尘器 ([@marcogazzola] - [#19777]) ([吸尘器.xiaomi\_miio docs][吸尘器.xiaomi_miio docs]) * Bump zigpy ([@damarco] - [#21203]) ([zha docs]) * Support OpenWRT 18.06 in luci 设备 tracker ([@fbradyirl] - [#21236]) ([device\_tracker docs][device_tracker docs]) * Remove constraint from regex ([@balloob] - [#21239]) * 升级 opensensemap-api to 0.1.4 ([@fabaff] - [#21240]) ([air\_quality docs][air_quality docs]) * 报警 触发器 support for Point ([@fredrike] - [#21207]) ([point docs]) * Prevent partial custom component overlays ([@balloob] - [#21070]) (breaking change) * Correctly detect 设备, which went offline during HA 重启 ([@OleksandrBerchenko] - [#20933]) ([device\_tracker docs][device_tracker docs]) * 更新 rova component with suffix for house number ([@GidoHakvoort] - [#21182]) ([传感器.rova docs]) * Added 设备 tracker support for Ubee Router ([@mzdrale] - [#19586]) ([device\_tracker docs][device_tracker docs]) (new-platform) * account specific cookies file to enable multiple accounts ([@ToSa27] - [#19811]) ([device\_tracker docs][device_tracker docs]) * Add support for automatic discovery of TP-Link 开关, bulbs and dimmers ([@rytilahti] - [#18091]) ([tplink docs]) ([灯光.tplink docs]) ([开关.tplink docs]) (breaking change) * 版本 bump: python-anthemav to v1.1.9 ([@nugget] - [#21273]) ([媒体播放器.anthemav docs]) * Do not warn for internally loaded components ([@balloob] - [#21287]) * Remove index ([@fabaff] - [#21304]) * Adding myself as codeowner for Freebox component ([@SNoof85] - [#21288]) * Nissanleaf ([@filcole] - [#21145]) ([nissan\_leaf docs][nissan_leaf docs]) (new-platform) * Config entry options ([@Kane610] - [#18929]) ([deconz docs]) * Enhance SmartThings component subscription ([@andrewsayre] - [#21124]) ([smartthings docs]) (breaking change) (new-feature) * Add more ads plc types ([@philipperequile] - [#19801]) ([ads docs]) * Add note to issue 模板 regarding iOS issues ([@robbiet480] - [#21342]) * Allow google home component 设备 tracker to be optional ([@dshokouhi] - [#21335]) (googlehome docs) * Add LCN 遮盖 platform ([@alengwenus] - [#20288]) ([lcn docs]) ([遮盖.lcn docs]) (new-platform) * Add location to Norway airquality ([@Danielhiversen] - [#21347]) ([air\_quality docs][air_quality docs]) ([天气.met docs]) * Updated pyvlx from 0.2.8 to 0.2.9. This 版本 has slightly improved logging ([@Julius2342] - [#21349]) ([velux docs]) * 更新 buienradar.py ([@hmmbob] - [#21351]) ([传感器.buienradar docs]) * Fixes the 传感器.filter outlier filter (handle step-changes correctly) ([@siberx] - [#21332]) ([传感器.filter docs]) * Allows the utility\_meter to net meter rather than only allow increases. ([@JBassett] - [#21204]) ([utility\_meter docs][utility_meter docs]) * implementing freedaily mode ([@tmechen] - [#21314]) ([天气.openweathermap docs]) * Add voltage per phase ([@leeuwte] - [#21319]) ([传感器.dsmr docs]) * Add conf\_key check for LCN platform load ([@alengwenus] - [#21354]) ([lcn docs]) * 更新 luci 设备 tracker ([@fbradyirl] - [#21321]) ([device\_tracker docs][device_tracker docs]) * Support the person component in Prometheus ([@mitchellrj] - [#21363]) ([prometheus docs]) * 更新 Starling Bank 集成 to v2 API ([@Dullage] - [#21358]) ([传感器.starlingbank docs]) * Split out iperf3 into a component with a 传感器 platform ([@rohankapoorcom] - [#21138]) ([iperf3 docs]) ([传感器.iperf3 docs]) (breaking change) (new-platform) * Add custom and 区域 cleaning to Neato 吸尘器 ([@RomRider] - [#20779]) ([neato docs]) * Add initial support for Sony SDCP projector control ([@alistairg] - [#20269]) ([开关.sony\_projector docs][开关.sony_projector docs]) (new-platform) * Check for 属性 existence for HS220 support ([@rytilahti] - [#21309]) ([tplink docs]) * Generate new Discogs 传感器 + fix scan interval ([@thibmaek] - [#19443]) ([传感器.discogs docs]) * 更新 panasonic\_viera.py ([@Tony763] - [#21365]) ([媒体播放器.panasonic\_viera docs][媒体播放器.panasonic_viera docs]) * Handle connection issue for netatmo ([@Danielhiversen] - [#21346]) ([netatmo docs]) * Refactoring. Moved LCN constants to const.py ([@alengwenus] - [#21376]) ([lcn docs]) (new-platform) * Clean up owntracks tests ([@MartinHjelmare] - [#21378]) * Remove the google travel time 更新 服务 ([@rohankapoorcom] - [#21153]) ([传感器.google\_travel\_time docs][传感器.google_travel_time docs]) (breaking change) * SmartThings 门锁 platform 状态 属性 enhancement ([@andrewsayre] - [#21379]) ([smartthings docs]) (new-feature) * 升级 shodan to 1.11.0 ([@fabaff] - [#21384]) ([传感器.shodan docs]) * 更新 ordering ([@fabaff] - [#21377]) ([modbus docs]) * Bump nessclient 版本 to 0.9.10 ([@nickw444] - [#21388]) ([ness\_alarm docs][ness_alarm docs]) * Handle capitalized HomeKit property names ([@koreth] - [#21382]) ([homekit\_controller docs][homekit_controller docs]) * 更新 WazeTravelSensor to 0.9 ([@hmmbob] - [#21130]) ([传感器.waze\_travel\_time docs][传感器.waze_travel_time docs]) * Clean up geofency test ([@MartinHjelmare] - [#21397]) * Clean up locative tests ([@MartinHjelmare] - [#21400]) * Add Sonos discovery of multiple households ([@amelchio] - [#21337]) ([sonos docs]) * Philips js 状态 ([@elupus] - [#21407]) ([媒体播放器.philips\_js docs][媒体播放器.philips_js docs]) * Add ADB server functionality to Fire TV ([@JeffLIrion] - [#21221]) ([媒体播放器.firetv docs]) (breaking change) * 升级 pytest to 4.3.0 ([@scop] - [#21412]) * 升级 mypy to 0.670 ([@scop] - [#20934]) * 更新 pylinky ([@tiste] - [#21416]) * Mark water\_heater as significant domain ([@elupus] - [#21390]) ([history docs]) * Add power and energy 属性 to SmartThings 开关 ([@andrewsayre] - [#21375]) ([smartthings docs]) (new-feature) * Add SmartThings 遮盖 platform and add 遮盖 设备 classes ([@andrewsayre] - [#21192]) ([遮盖 docs]) ([smartthings docs]) (breaking change) (new-platform) * Add ESPHome 用户-Defined 服务 ([@OttoWinter] - [#21409]) ([esphome docs]) * Handle GA Disconnect intent ([@balloob] - [#21387]) ([google\_assistant docs][google_assistant docs]) * Fix double events on Lutron Pico keypads ([@koreth] - [#21408]) ([lutron docs]) * Fix Sonos snapshot/恢复 ([@amelchio] - [#21411]) ([sonos docs]) * Increase travis timeout ([@andrewsayre] - [#21447]) * Rewrite of Toon component ([@frenck] - [#21186]) ([toon docs]) (breaking change) (new-platform) * Check if a 脚本 requirement is available before 安装 ([@kellerza] - [#20517]) * Add timeout option to 传感器.rest and binary\_sensor.rest. ([@glogiotatidis] - [#20065]) ([binary\_sensor.rest docs][binary_sensor.rest docs]) ([传感器.rest docs]) * Clean up codeowners file ([@amelchio] - [#21442]) * 升级 flake8 to 3.7.7 ([@scop] - [#21452]) * Clean up ZHA post rewrite ([@dmulcahey] - [#21448]) ([zha docs]) * Add friendly name to 设备 in the 设备 registry ([@dmulcahey] - [#21318]) ([config docs]) * Fix ESPHome nodes being auto-added without 用户 confirmation ([@OttoWinter] - [#21444]) ([esphome docs]) * Fix for Snips platform 更新 that breaks hermes api. ([@ptc] - [#21443]) ([snips docs]) * Remove launching a server in a test ([@balloob] - [#21445]) * Add SmartThings 场景 platform ([@andrewsayre] - [#21405]) ([smartthings docs]) (new-platform) * Adjust GTFS dates when crossing midnight ([@renemarc] - [#20916]) ([传感器.gtfs docs]) * Reddit 传感器 ([@ljmerza] - [#21344]) ([传感器.reddit docs]) (new-platform) * Add config for trusted networks auth provider ([@awarecan] - [#21111]) (breaking change) * Add HomematicIP HmIP-OC8 module ([@mxworm] - [#21401]) ([homematicip\_cloud docs][homematicip_cloud docs]) * Added new econet 状态 ([@w1ll1am23] - [#21420]) ([water\_heater docs][water_heater docs]) * Comment out bluepy libraries from requirements\_all.txt ([@Danielhiversen] - [#20856]) ([开关.switchbot docs]) ([开关.switchmate docs]) * 更新 传感器.nmbs to support vias better + show on map ([@thibmaek] - [#20063]) ([传感器.nmbs docs]) * Add mitemp bt 传感器 设备 class ([@blackray12] - [#20293]) ([传感器.mitemp\_bt docs][传感器.mitemp_bt docs]) * Add Somfy IO Garage door ([@dfournie] - [#21320]) ([tahoma docs]) * Add person support for Waze Travel Time ([@Petro31] - [#21471]) ([传感器.waze\_travel\_time docs][传感器.waze_travel_time docs]) * Add cpu\_use\_percent as a new resource to the Glances 传感器. ([@kevintuhumury] - [#21455]) ([传感器.glances docs]) * Added a digit for precipitation ([@helto4real] - [#21439]) ([smhi docs]) * 升级 bcrypt to 3.1.6 ([@fabaff] - [#21476]) * 升级 shodan to 1.11.1 ([@fabaff] - [#21478]) ([传感器.shodan docs]) * 升级 astral to 1.10.1 ([@fabaff] - [#21474]) * Refactor async\_turn\_on() for ZHA 灯光. ([@Adminiuga] - [#21156]) ([zha docs]) * Add device\_info to enable HA-设备 for Homematic IP ([@SukramJ] - [#21241]) ([homematicip\_cloud docs][homematicip_cloud docs]) * Fire events when Google Assistant commands come in #15139 ([@Swamp-Ig] - [#20204]) ([google\_assistant docs][google_assistant docs]) * pylint 2.3.0 ([@Danielhiversen] - [#21485]) * HomeMatic: Add 错误-属性 ([@dagobert] - [#21009]) ([homematic docs]) (breaking change) * Avoid unnecessary commands in Vizio 更新 function ([@JeffLIrion] - [#20867]) * 升级 pyairvisual to 3.0.1 ([@bachya] - [#21512]) ([传感器.airvisual docs]) * Bump simplisafe-python to 3.4.1 ([@bachya] - [#21511]) ([simplisafe docs]) * 升级 aioambient to 0.1.3 ([@bachya] - [#21510]) ([ambient\_station docs][ambient_station docs]) * 升级 tibber lib ([@Danielhiversen] - [#21486]) ([tibber docs]) * ness\_alarm: Bump nessclient 版本 to 0.9.13 ([@nickw444] - [#21466]) ([ness\_alarm docs][ness_alarm docs]) * Bump ihc to 2.3.0 ([@msvinth] - [#21494]) ([ihc docs]) * Changed source priority for Person ([@gorynychzmey] - [#21479]) * Add PLATFORM\_SCHEMA\_BASE to telegram\_bot component ([@veleek] - [#21155]) ([telegram\_bot docs][telegram_bot docs]) (beta fix) * Add watchdog to Ambient PWS ([@bachya] - [#21507]) ([ambient\_station docs][ambient_station docs]) (beta fix) * Improve new Sonos snapshot/恢复 ([@amelchio] - [#21509]) ([sonos docs]) (beta fix) * Fix lint ([@balloob] - [#21520]) ([person docs]) ([传感器.airvisual docs]) (beta fix) * Only use a single store instance ([@balloob] - [#21521]) ([前端 docs]) (beta fix) * Allow skip-pip applied to HA 核心 ([@awarecan] - [#21527]) (beta fix) * Updated variable name for readability ([@gorynychzmey] - [#21528]) ([person docs]) (beta fix) * Add missing retain option to MQTT.温控 配置 schema ([@emontnemery] - [#21536]) ([MQTT docs]) (beta fix) * Fix 警告 ([@awarecan] - [#21538]) ([http docs]) (beta fix) * Fix incorrect pyairvisual call ([@bachya] - [#21542]) ([传感器.airvisual docs]) (beta fix) * mobile\_app component ([@robbiet480] - [#21475]) ([mobile\_app docs][mobile_app docs]) (beta fix) (new-platform) * Make time 触发器 data 触发器.now local ([@emontnemery] - [#21544]) (beta fix) * Bump zigpy-deconz ([@damarco] - [#21566]) ([zha docs]) (beta fix) * Re-thrown exception occurred in the blocking 服务 call ([@awarecan] - [#21573]) ([websocket\_api docs][websocket_api docs]) (beta fix) * 升级 PyXiaomiGateway library ([@Danielhiversen] - [#21582]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) (beta fix) * 日志 exception occurred in WS 服务 call command ([@awarecan] - [#21584]) ([websocket\_api docs][websocket_api docs]) (beta fix) * Word the tplink deprecation 警告 more strongly ([@amelchio] - [#21586]) ([tplink docs]) (beta fix) * Handle when 已安装 app has already been removed ([@andrewsayre] - [#21595]) ([smartthings docs]) (beta fix) * Resolve race 条件 when HA auth provider is loading ([@awarecan] - [#21619]) (beta fix) * 升级 pysonos to 0.0.8 ([@amelchio] - [#21624]) ([sonos docs]) (beta fix) * Fix calc next ([@balloob] - [#21630]) (beta fix) * Cast displaytime to int for JSON RPC ([@GGeezes] - [#21649]) ([通知 docs]) (beta fix) * :shirt: Corrects unit of measurement symbol for Watt ([@frenck] - [#21654]) ([toon docs]) (beta fix) * Rename Google Assistant evenets ([@balloob] - [#21655]) ([google\_assistant docs][google_assistant docs]) (beta fix) * :ambulance: Fixes Toon doing I/O in coroutines ([@frenck] - [#21657]) ([toon docs]) (beta fix) * 升级 toonapilib to 3.1.0 ([@frenck] - [#21661]) ([toon docs]) (beta fix) * Avoid recorder Thread crashing ([@balloob] - [#21668]) (beta fix) * check we have a tb ([@dgomes] - [#21670]) ([system\_log docs][system_log docs]) (beta fix) * Fix ADS race 条件 ([@carstenschroeder] - [#21677]) ([ads docs]) (beta fix) * resync hass that changes have occurred ([@fredrike] - [#21705]) ([tellduslive docs]) (beta fix) * 升级 toonapilib to 3.2.1 ([@frenck] - [#21706]) ([toon docs]) (beta fix) [#18091]: https://github.com/home-assistant/home-assistant/pull/18091 [#18404]: https://github.com/home-assistant/home-assistant/pull/18404 [#18929]: https://github.com/home-assistant/home-assistant/pull/18929 [#19443]: https://github.com/home-assistant/home-assistant/pull/19443 [#19586]: https://github.com/home-assistant/home-assistant/pull/19586 [#19777]: https://github.com/home-assistant/home-assistant/pull/19777 [#19786]: https://github.com/home-assistant/home-assistant/pull/19786 [#19801]: https://github.com/home-assistant/home-assistant/pull/19801 [#19811]: https://github.com/home-assistant/home-assistant/pull/19811 [#20063]: https://github.com/home-assistant/home-assistant/pull/20063 [#20065]: https://github.com/home-assistant/home-assistant/pull/20065 [#20068]: https://github.com/home-assistant/home-assistant/pull/20068 [#20204]: https://github.com/home-assistant/home-assistant/pull/20204 [#20269]: https://github.com/home-assistant/home-assistant/pull/20269 [#20274]: https://github.com/home-assistant/home-assistant/pull/20274 [#20288]: https://github.com/home-assistant/home-assistant/pull/20288 [#20293]: https://github.com/home-assistant/home-assistant/pull/20293 [#20517]: https://github.com/home-assistant/home-assistant/pull/20517 [#20551]: https://github.com/home-assistant/home-assistant/pull/20551 [#20586]: https://github.com/home-assistant/home-assistant/pull/20586 [#20750]: https://github.com/home-assistant/home-assistant/pull/20750 [#20755]: https://github.com/home-assistant/home-assistant/pull/20755 [#20779]: https://github.com/home-assistant/home-assistant/pull/20779 [#20856]: https://github.com/home-assistant/home-assistant/pull/20856 [#20867]: https://github.com/home-assistant/home-assistant/pull/20867 [#20888]: https://github.com/home-assistant/home-assistant/pull/20888 [#20902]: https://github.com/home-assistant/home-assistant/pull/20902 [#20916]: https://github.com/home-assistant/home-assistant/pull/20916 [#20933]: https://github.com/home-assistant/home-assistant/pull/20933 [#20934]: https://github.com/home-assistant/home-assistant/pull/20934 [#20945]: https://github.com/home-assistant/home-assistant/pull/20945 [#20972]: https://github.com/home-assistant/home-assistant/pull/20972 [#21009]: https://github.com/home-assistant/home-assistant/pull/21009 [#21046]: https://github.com/home-assistant/home-assistant/pull/21046 [#21061]: https://github.com/home-assistant/home-assistant/pull/21061 [#21062]: https://github.com/home-assistant/home-assistant/pull/21062 [#21065]: https://github.com/home-assistant/home-assistant/pull/21065 [#21067]: https://github.com/home-assistant/home-assistant/pull/21067 [#21068]: https://github.com/home-assistant/home-assistant/pull/21068 [#21069]: https://github.com/home-assistant/home-assistant/pull/21069 [#21070]: https://github.com/home-assistant/home-assistant/pull/21070 [#21074]: https://github.com/home-assistant/home-assistant/pull/21074 [#21076]: https://github.com/home-assistant/home-assistant/pull/21076 [#21079]: https://github.com/home-assistant/home-assistant/pull/21079 [#21084]: https://github.com/home-assistant/home-assistant/pull/21084 [#21086]: https://github.com/home-assistant/home-assistant/pull/21086 [#21087]: https://github.com/home-assistant/home-assistant/pull/21087 [#21108]: https://github.com/home-assistant/home-assistant/pull/21108 [#21109]: https://github.com/home-assistant/home-assistant/pull/21109 [#21111]: https://github.com/home-assistant/home-assistant/pull/21111 [#21112]: https://github.com/home-assistant/home-assistant/pull/21112 [#21117]: https://github.com/home-assistant/home-assistant/pull/21117 [#21119]: https://github.com/home-assistant/home-assistant/pull/21119 [#21124]: https://github.com/home-assistant/home-assistant/pull/21124 [#21130]: https://github.com/home-assistant/home-assistant/pull/21130 [#21138]: https://github.com/home-assistant/home-assistant/pull/21138 [#21145]: https://github.com/home-assistant/home-assistant/pull/21145 [#21149]: https://github.com/home-assistant/home-assistant/pull/21149 [#21150]: https://github.com/home-assistant/home-assistant/pull/21150 [#21153]: https://github.com/home-assistant/home-assistant/pull/21153 [#21154]: https://github.com/home-assistant/home-assistant/pull/21154 [#21155]: https://github.com/home-assistant/home-assistant/pull/21155 [#21156]: https://github.com/home-assistant/home-assistant/pull/21156 [#21157]: https://github.com/home-assistant/home-assistant/pull/21157 [#21162]: https://github.com/home-assistant/home-assistant/pull/21162 [#21164]: https://github.com/home-assistant/home-assistant/pull/21164 [#21166]: https://github.com/home-assistant/home-assistant/pull/21166 [#21171]: https://github.com/home-assistant/home-assistant/pull/21171 [#21181]: https://github.com/home-assistant/home-assistant/pull/21181 [#21182]: https://github.com/home-assistant/home-assistant/pull/21182 [#21186]: https://github.com/home-assistant/home-assistant/pull/21186 [#21187]: https://github.com/home-assistant/home-assistant/pull/21187 [#21190]: https://github.com/home-assistant/home-assistant/pull/21190 [#21192]: https://github.com/home-assistant/home-assistant/pull/21192 [#21195]: https://github.com/home-assistant/home-assistant/pull/21195 [#21202]: https://github.com/home-assistant/home-assistant/pull/21202 [#21203]: https://github.com/home-assistant/home-assistant/pull/21203 [#21204]: https://github.com/home-assistant/home-assistant/pull/21204 [#21207]: https://github.com/home-assistant/home-assistant/pull/21207 [#21212]: https://github.com/home-assistant/home-assistant/pull/21212 [#21221]: https://github.com/home-assistant/home-assistant/pull/21221 [#21226]: https://github.com/home-assistant/home-assistant/pull/21226 [#21227]: https://github.com/home-assistant/home-assistant/pull/21227 [#21229]: https://github.com/home-assistant/home-assistant/pull/21229 [#21236]: https://github.com/home-assistant/home-assistant/pull/21236 [#21239]: https://github.com/home-assistant/home-assistant/pull/21239 [#21240]: https://github.com/home-assistant/home-assistant/pull/21240 [#21241]: https://github.com/home-assistant/home-assistant/pull/21241 [#21273]: https://github.com/home-assistant/home-assistant/pull/21273 [#21287]: https://github.com/home-assistant/home-assistant/pull/21287 [#21288]: https://github.com/home-assistant/home-assistant/pull/21288 [#21304]: https://github.com/home-assistant/home-assistant/pull/21304 [#21309]: https://github.com/home-assistant/home-assistant/pull/21309 [#21314]: https://github.com/home-assistant/home-assistant/pull/21314 [#21318]: https://github.com/home-assistant/home-assistant/pull/21318 [#21319]: https://github.com/home-assistant/home-assistant/pull/21319 [#21320]: https://github.com/home-assistant/home-assistant/pull/21320 [#21321]: https://github.com/home-assistant/home-assistant/pull/21321 [#21332]: https://github.com/home-assistant/home-assistant/pull/21332 [#21335]: https://github.com/home-assistant/home-assistant/pull/21335 [#21337]: https://github.com/home-assistant/home-assistant/pull/21337 [#21342]: https://github.com/home-assistant/home-assistant/pull/21342 [#21344]: https://github.com/home-assistant/home-assistant/pull/21344 [#21346]: https://github.com/home-assistant/home-assistant/pull/21346 [#21347]: https://github.com/home-assistant/home-assistant/pull/21347 [#21349]: https://github.com/home-assistant/home-assistant/pull/21349 [#21351]: https://github.com/home-assistant/home-assistant/pull/21351 [#21354]: https://github.com/home-assistant/home-assistant/pull/21354 [#21358]: https://github.com/home-assistant/home-assistant/pull/21358 [#21363]: https://github.com/home-assistant/home-assistant/pull/21363 [#21365]: https://github.com/home-assistant/home-assistant/pull/21365 [#21375]: https://github.com/home-assistant/home-assistant/pull/21375 [#21376]: https://github.com/home-assistant/home-assistant/pull/21376 [#21377]: https://github.com/home-assistant/home-assistant/pull/21377 [#21378]: https://github.com/home-assistant/home-assistant/pull/21378 [#21379]: https://github.com/home-assistant/home-assistant/pull/21379 [#21382]: https://github.com/home-assistant/home-assistant/pull/21382 [#21384]: https://github.com/home-assistant/home-assistant/pull/21384 [#21387]: https://github.com/home-assistant/home-assistant/pull/21387 [#21388]: https://github.com/home-assistant/home-assistant/pull/21388 [#21390]: https://github.com/home-assistant/home-assistant/pull/21390 [#21397]: https://github.com/home-assistant/home-assistant/pull/21397 [#21400]: https://github.com/home-assistant/home-assistant/pull/21400 [#21401]: https://github.com/home-assistant/home-assistant/pull/21401 [#21405]: https://github.com/home-assistant/home-assistant/pull/21405 [#21407]: https://github.com/home-assistant/home-assistant/pull/21407 [#21408]: https://github.com/home-assistant/home-assistant/pull/21408 [#21409]: https://github.com/home-assistant/home-assistant/pull/21409 [#21411]: https://github.com/home-assistant/home-assistant/pull/21411 [#21412]: https://github.com/home-assistant/home-assistant/pull/21412 [#21416]: https://github.com/home-assistant/home-assistant/pull/21416 [#21420]: https://github.com/home-assistant/home-assistant/pull/21420 [#21439]: https://github.com/home-assistant/home-assistant/pull/21439 [#21442]: https://github.com/home-assistant/home-assistant/pull/21442 [#21443]: https://github.com/home-assistant/home-assistant/pull/21443 [#21444]: https://github.com/home-assistant/home-assistant/pull/21444 [#21445]: https://github.com/home-assistant/home-assistant/pull/21445 [#21447]: https://github.com/home-assistant/home-assistant/pull/21447 [#21448]: https://github.com/home-assistant/home-assistant/pull/21448 [#21452]: https://github.com/home-assistant/home-assistant/pull/21452 [#21455]: https://github.com/home-assistant/home-assistant/pull/21455 [#21466]: https://github.com/home-assistant/home-assistant/pull/21466 [#21471]: https://github.com/home-assistant/home-assistant/pull/21471 [#21474]: https://github.com/home-assistant/home-assistant/pull/21474 [#21475]: https://github.com/home-assistant/home-assistant/pull/21475 [#21476]: https://github.com/home-assistant/home-assistant/pull/21476 [#21478]: https://github.com/home-assistant/home-assistant/pull/21478 [#21479]: https://github.com/home-assistant/home-assistant/pull/21479 [#21485]: https://github.com/home-assistant/home-assistant/pull/21485 [#21486]: https://github.com/home-assistant/home-assistant/pull/21486 [#21494]: https://github.com/home-assistant/home-assistant/pull/21494 [#21507]: https://github.com/home-assistant/home-assistant/pull/21507 [#21509]: https://github.com/home-assistant/home-assistant/pull/21509 [#21510]: https://github.com/home-assistant/home-assistant/pull/21510 [#21511]: https://github.com/home-assistant/home-assistant/pull/21511 [#21512]: https://github.com/home-assistant/home-assistant/pull/21512 [#21520]: https://github.com/home-assistant/home-assistant/pull/21520 [#21521]: https://github.com/home-assistant/home-assistant/pull/21521 [#21527]: https://github.com/home-assistant/home-assistant/pull/21527 [#21528]: https://github.com/home-assistant/home-assistant/pull/21528 [#21536]: https://github.com/home-assistant/home-assistant/pull/21536 [#21538]: https://github.com/home-assistant/home-assistant/pull/21538 [#21542]: https://github.com/home-assistant/home-assistant/pull/21542 [#21544]: https://github.com/home-assistant/home-assistant/pull/21544 [#21566]: https://github.com/home-assistant/home-assistant/pull/21566 [#21573]: https://github.com/home-assistant/home-assistant/pull/21573 [#21582]: https://github.com/home-assistant/home-assistant/pull/21582 [#21584]: https://github.com/home-assistant/home-assistant/pull/21584 [#21586]: https://github.com/home-assistant/home-assistant/pull/21586 [#21595]: https://github.com/home-assistant/home-assistant/pull/21595 [#21619]: https://github.com/home-assistant/home-assistant/pull/21619 [#21624]: https://github.com/home-assistant/home-assistant/pull/21624 [#21630]: https://github.com/home-assistant/home-assistant/pull/21630 [#21649]: https://github.com/home-assistant/home-assistant/pull/21649 [#21654]: https://github.com/home-assistant/home-assistant/pull/21654 [#21655]: https://github.com/home-assistant/home-assistant/pull/21655 [#21657]: https://github.com/home-assistant/home-assistant/pull/21657 [#21661]: https://github.com/home-assistant/home-assistant/pull/21661 [#21668]: https://github.com/home-assistant/home-assistant/pull/21668 [#21670]: https://github.com/home-assistant/home-assistant/pull/21670 [#21677]: https://github.com/home-assistant/home-assistant/pull/21677 [#21705]: https://github.com/home-assistant/home-assistant/pull/21705 [#21706]: https://github.com/home-assistant/home-assistant/pull/21706 [@Adminiuga]: https://github.com/Adminiuga [@Danielhiversen]: https://github.com/Danielhiversen [@Dullage]: https://github.com/Dullage [@GGeezes]: https://github.com/GGeezes [@GidoHakvoort]: https://github.com/GidoHakvoort [@JBassett]: https://github.com/JBassett [@JeffLIrion]: https://github.com/JeffLIrion [@JonasPed]: https://github.com/JonasPed [@Julius2342]: https://github.com/Julius2342 [@Kane610]: https://github.com/Kane610 [@MartinHjelmare]: https://github.com/MartinHjelmare [@OleksandrBerchenko]: https://github.com/OleksandrBerchenko [@OttoWinter]: https://github.com/OttoWinter [@Petro31]: https://github.com/Petro31 [@RomRider]: https://github.com/RomRider [@SNoof85]: https://github.com/SNoof85 [@SukramJ]: https://github.com/SukramJ [@Swamp-Ig]: https://github.com/Swamp-Ig [@ToSa27]: https://github.com/ToSa27 [@Tony763]: https://github.com/Tony763 [@VirtualL]: https://github.com/VirtualL [@aerialls]: https://github.com/aerialls [@alengwenus]: https://github.com/alengwenus [@alistairg]: https://github.com/alistairg [@amelchio]: https://github.com/amelchio [@andrewsayre]: https://github.com/andrewsayre [@awarecan]: https://github.com/awarecan [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@bauerj]: https://github.com/bauerj [@blackray12]: https://github.com/blackray12 [@carstenschroeder]: https://github.com/carstenschroeder [@dagobert]: https://github.com/dagobert [@damarco]: https://github.com/damarco [@danielperna84]: https://github.com/danielperna84 [@davidbb]: https://github.com/davidbb [@dfournie]: https://github.com/dfournie [@dgomes]: https://github.com/dgomes [@dmulcahey]: https://github.com/dmulcahey [@dshokouhi]: https://github.com/dshokouhi [@elupus]: https://github.com/elupus [@emontnemery]: https://github.com/emontnemery [@fabaff]: https://github.com/fabaff [@fbradyirl]: https://github.com/fbradyirl [@filcole]: https://github.com/filcole [@fredrike]: https://github.com/fredrike [@frenck]: https://github.com/frenck [@glogiotatidis]: https://github.com/glogiotatidis [@gorynychzmey]: https://github.com/gorynychzmey [@helto4real]: https://github.com/helto4real [@hmmbob]: https://github.com/hmmbob [@kellerza]: https://github.com/kellerza [@kevintuhumury]: https://github.com/kevintuhumury [@koreth]: https://github.com/koreth [@kstaniek]: https://github.com/kstaniek [@ktnrg45]: https://github.com/ktnrg45 [@lapy]: https://github.com/lapy [@leeuwte]: https://github.com/leeuwte [@ljmerza]: https://github.com/ljmerza [@marcogazzola]: https://github.com/marcogazzola [@mezz64]: https://github.com/mezz64 [@mitchellrj]: https://github.com/mitchellrj [@msvinth]: https://github.com/msvinth [@mxworm]: https://github.com/mxworm [@mzdrale]: https://github.com/mzdrale [@nickw444]: https://github.com/nickw444 [@nugget]: https://github.com/nugget [@oblogic7]: https://github.com/oblogic7 [@philipperequile]: https://github.com/philipperequile [@ptc]: https://github.com/ptc [@renemarc]: https://github.com/renemarc [@robbiet480]: https://github.com/robbiet480 [@rohankapoorcom]: https://github.com/rohankapoorcom [@rytilahti]: https://github.com/rytilahti [@scop]: https://github.com/scop [@siberx]: https://github.com/siberx [@starkillerOG]: https://github.com/starkillerOG [@thibmaek]: https://github.com/thibmaek [@tiste]: https://github.com/tiste [@tmechen]: https://github.com/tmechen [@veleek]: https://github.com/veleek [@victorcerutti]: https://github.com/victorcerutti [@w1ll1am23]: https://github.com/w1ll1am23 [@zewelor]: https://github.com/zewelor [ads docs]: /integrations/ads/ [air_quality docs]: /integrations/air_quality/ [ambient_station docs]: /integrations/ambient_station/ [binary_sensor.hikvision docs]: /integrations/hikvision [binary_sensor.nissan_leaf docs]: /integrations/nissan_leaf [binary_sensor.rest docs]: /integrations/binary_sensor.rest/ [binary_sensor.tod docs]: /integrations/tod [binary_sensor.trend docs]: /integrations/trend [config docs]: /integrations/config/ [遮盖 docs]: /integrations/遮盖/ [遮盖.lcn docs]: /integrations/lcn#遮盖 [danfoss_air docs]: /integrations/danfoss_air/ [deconz docs]: /integrations/deconz/ [device_tracker docs]: /integrations/device_tracker/ [esphome docs]: /integrations/esphome/ [前端 docs]: /integrations/frontend/ [google_assistant docs]: /integrations/google_assistant/ [history docs]: /integrations/history/ [homekit_controller docs]: /integrations/homekit_controller/ [homematic docs]: /integrations/homematic/ [homematicip_cloud docs]: /integrations/homematicip_cloud/ [http docs]: /integrations/http/ [hue docs]: /integrations/hue/ [ihc docs]: /integrations/ihc/ [image_processing.tensorflow docs]: /integrations/tensorflow [insteon docs]: /integrations/insteon/ [iperf3 docs]: /integrations/iperf3/ [knx docs]: /integrations/knx/ [lcn docs]: /integrations/lcn/ [灯光.rpi_gpio_pwm docs]: /integrations/rpi_gpio_pwm [灯光.tplink docs]: /integrations/tplink [灯光.yeelight docs]: /integrations/yeelight [lutron docs]: /integrations/lutron/ [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.anthemav docs]: /integrations/anthemav [媒体播放器.firetv docs]: /integrations/androidtv [媒体播放器.panasonic_viera docs]: /integrations/panasonic_viera [媒体播放器.philips_js docs]: /integrations/philips_js [meteo_france docs]: /integrations/meteo_france/ [mobile_app docs]: /integrations/mobile_app/ [modbus docs]: /integrations/modbus/ [MQTT docs]: /integrations/MQTT/ [neato docs]: /integrations/neato/ [ness_alarm docs]: /integrations/ness_alarm/ [netatmo docs]: /integrations/netatmo/ [nissan_leaf docs]: /integrations/nissan_leaf/ [通知 docs]: /integrations/通知/ [person docs]: /integrations/person/ [point docs]: /integrations/point/ [prometheus docs]: /integrations/prometheus/ [ps4 docs]: /integrations/ps4/ [raspihats docs]: /integrations/raspihats/ [传感器.airvisual docs]: /integrations/airvisual [传感器.buienradar docs]: /integrations/传感器.buienradar/ [传感器.crimereports docs]: /integrations/crimereports [传感器.discogs docs]: /integrations/discogs [传感器.dsmr docs]: /integrations/dsmr [传感器.etherscan docs]: /integrations/etherscan [传感器.filter docs]: /integrations/filter [传感器.glances docs]: /integrations/glances [传感器.google_travel_time docs]: /integrations/google_travel_time [传感器.gtfs docs]: /integrations/gtfs [传感器.iperf3 docs]: /integrations/iperf3 [传感器.linky docs]: /integrations/linky [传感器.meteo_france docs]: /integrations/meteo_france [传感器.mitemp_bt docs]: /integrations/mitemp_bt [传感器.nissan_leaf docs]: /integrations/nissan_leaf [传感器.nmbs docs]: /integrations/nmbs [传感器.pollen docs]: /integrations/iqvia [传感器.reddit docs]: /integrations/reddit [传感器.rest docs]: /integrations/rest [传感器.ripple docs]: /integrations/ripple [传感器.rova docs]: /integrations/rova [传感器.scrape docs]: /integrations/scrape [传感器.shodan docs]: /integrations/shodan [传感器.sochain docs]: /integrations/sochain [传感器.sql docs]: /integrations/sql [传感器.starlingbank docs]: /integrations/starlingbank [传感器.systemmonitor docs]: /integrations/systemmonitor [传感器.waze_travel_time docs]: /integrations/waze_travel_time [simplisafe docs]: /integrations/simplisafe/ [smartthings docs]: /integrations/smartthings/ [smhi docs]: /integrations/smhi/ [snips docs]: /integrations/snips/ [sonos docs]: /integrations/sonos/ [开关.nissan_leaf docs]: /integrations/nissan_leaf [开关.sony_projector docs]: /integrations/sony_projector [开关.switchbot docs]: /integrations/switchbot [开关.switchmate docs]: /integrations/switchmate [开关.tplink docs]: /integrations/tplink [system_log docs]: /integrations/system_log/ [tahoma docs]: /integrations/tahoma/ [telegram_bot docs]: /integrations/telegram_bot/ [tellduslive docs]: /integrations/tellduslive/ [tibber docs]: /integrations/tibber/ [toon docs]: /integrations/toon/ [tplink docs]: /integrations/tplink/ [utility_meter docs]: /integrations/utility_meter/ [吸尘器.xiaomi_miio docs]: /integrations/吸尘器.xiaomi_miio/ [velux docs]: /integrations/velux/ [water_heater docs]: /integrations/water_heater/ [天气.met docs]: /integrations/met [天气.meteo_france docs]: /integrations/meteo_france/ [天气.openweathermap docs]: /integrations/openweathermap#天气 [websocket_api docs]: /integrations/websocket_api/ [xiaomi_aqara docs]: /integrations/xiaomi_aqara/ [zha docs]: /integrations/zha/ --- url: /home-assistant/blog/2019-03-20-release-90.md --- # 0.90:远程 UI、流媒体与用户分组 Home Assistant 0.90 来了,只能说:太强了。这次发布塞满了各种酷炫内容,多到都不知道该从哪里开始,那我们就直接进入正题吧。 第一个重磅功能是,Home Assistant Cloud 现在支持远程控制了。这让你即使不在家,也能查看家里的情况。收到“检测到移动”的通知?现在你可以立刻查看发生了什么,并在外出时直接采取行动。它采用端到端加密。想开始使用?只需要启用它,就这么简单。 想了解它的工作方式,请查看[文档](https://www.nabucasa.com/config/remote/),或收听 [Home Assistant Podcast 最新一期](https://hasspodcast.io/ha046/)。

Screenshot of the 遥控器 UI preference. Screenshot of the 遥控器 UI preference.

## 人人可用的摄像头流媒体 在这个版本里,我们开始认真打磨摄像头能力。[ @hunterjm ] 为此投入了数月时间,现在终于可以首次公开展示了。借助 stream 集成,我们可以转发家中摄像头的视频流,并重新封装成你的显示设备能够理解的格式。此前,摄像头流媒体仅限前端使用,而且只有每秒 2 帧。第一版我们重点支持的是 HLS 格式,现代浏览器和 Chromecast 都支持它。每个摄像头集成都需要单独适配,而在首个版本中,我们目前只为 generic 摄像头集成加入了支持。 那现在能做到什么?比如门铃响起时,你可以立刻把前门摄像头画面投到电视上;又或者在婴儿房安装一个摄像头,把 Google Home Hub 变成婴儿监视器。 要开始使用,请在 `configuration.yaml` 中加入 `stream:`,配置 [generic 摄像头][摄像头.generic docs],然后开始使用新的 `camera.play_stream` 服务。
## 用户分组 这是一个酝酿和开发了很久的功能:你现在可以把用户加入分组,从而阻止他们通过 UI 修改配置。被放入新“用户”组的用户将不会看到配置面板或开发者工具的入口。当前这还只是一个 UI 层面的功能,并不是安全特性。[我们正在努力](https://开发者.home-assistant.io/博客/2019/03/11/user-permissions.html)把它扩展为真正的安全能力,也就是在 API 层面限制访问。 ## 更聪明的 SmartThings 如果你使用 Home Assistant Cloud,设置 SmartThings 时现在会自动利用 Cloudhooks。这意味着你无需把实例暴露到互联网就能开始使用 SmartThings。设置更简单了,感谢 [@andrewsayre]!SmartThings 现在还新增了对三轴传感器和空调设备的支持。 ## 区域增强 这个版本也进一步增强了区域功能。感谢 [@Swamp-Ig],当你把 Home Assistant 同步到 Google Assistant 时,区域现在会作为房间提示一并带过去,这会让设置变得更加轻松。 区域 can now also be used as targets in 服务. Just specify `area_id` instead of `entity_id` in your 脚本 or 自动化. 我们还把区域整合进了集成的设置流程。添加集成时,我们会检查新增了哪些设备,并立即提示你进行配置,这样你就不会忘记了。
## VSCode 扩展 如果你错过了这个消息,本周早些时候 Kees Schollaart 发布了他的 [VSCode](https://code.visualstudio.com/) Home Assistant 扩展首个版本。它可以连接到你的实例,并在你编辑配置时提供实体 ID 自动补全! ## 新平台 * Live Streams Component ([@hunterjm] - [#21473]) ([摄像头 docs]) ([stream docs]) (new-platform) * Add support for homekit controller 传感器 ([@cpopp] - [#21535]) ([homekit\_controller docs][homekit_controller docs]) (new-platform) * Add SmartThingsAccelCluster to ZHA binary\_sensor ([@roblandry] - [#21609]) ([zha docs]) (new-platform) * Xfinity Gateway device\_tracker platform ([@cisasteelersfan] - [#21026]) ([device\_tracker docs][device_tracker docs]) (new-platform) * Add Time of Flight 传感器 using VL53L1X ([@josemotta] - [#21230]) ([tof docs]) (new-platform) * Adding enigma2 media player ([@fbradyirl] - [#21271]) ([媒体播放器.enigma2 docs]) (new-platform) * Add support for Cisco Mobility Express ([@fbradyirl] - [#21531]) ([cisco\_mobility\_express docs][cisco_mobility_express docs]) (new-platform) * Add ClearPass Policy Manger 设备 tracker ([@zemerick1] - [#21673]) ([device\_tracker docs][device_tracker docs]) (new-platform) * Add 天气 传感器 to Homematic IP ([@SukramJ] - [#21887]) ([homematicip\_cloud docs][homematicip_cloud docs]) (new-platform) ## 发布 0.90.1 - March 21 * Fix ZHA force polled 实体. ([@Adminiuga] - [#22222]) * Bump total-connect-client to 0.25, fixing issue with Total Connect ([@kkr16] - [#22230]) * Stream fixes ([@hunterjm] - [#22238]) ([stream docs]) * Allow on/off on tado 温控 component. ([@michaelarnauts] - [#22242]) ([tado docs]) * Fix validate Webhook requirements ([@andrewsayre] - [#22248]) ([smartthings docs]) * 更新 Hass-NabuCasa 0.9 ([@pvizeli] - [#22258]) ([cloud docs]) [#22222]: https://github.com/home-assistant/home-assistant/pull/22222 [#22230]: https://github.com/home-assistant/home-assistant/pull/22230 [#22238]: https://github.com/home-assistant/home-assistant/pull/22238 [#22242]: https://github.com/home-assistant/home-assistant/pull/22242 [#22248]: https://github.com/home-assistant/home-assistant/pull/22248 [#22258]: https://github.com/home-assistant/home-assistant/pull/22258 [@Adminiuga]: https://github.com/Adminiuga [@andrewsayre]: https://github.com/andrewsayre [@hunterjm]: https://github.com/hunterjm [@kkr16]: https://github.com/kkr16 [@michaelarnauts]: https://github.com/michaelarnauts [@pvizeli]: https://github.com/pvizeli [cloud docs]: /integrations/cloud/ [smartthings docs]: /integrations/smartthings/ [stream docs]: /integrations/stream/ [tado docs]: /integrations/tado/ ## 发布 0.90.2 - March 26 * Fix ps4 no creds with additional 设备 ([@ktnrg45] - [#22300]) * Prefer TCP for RTSP streams ([@hunterjm] - [#22338]) * 更新 hass-nabucasa & fix 状态 ([@pvizeli] - [#22385]) * Enable hass.io 面板 without ping ([@pvizeli] - [#22388]) * reset unsub to None on timeout ([@hunterjm] - [#22404]) * Bump pyotgw to 0.4b2 ([@mvn23] - [#21973]) * Fix opentherm\_gw blocks HA startup when gateway unreachable. ([@mvn23] - [#22106]) * Fix TypeError in current\_temperature if no temperature is known. ([@mvn23] - [#22112]) * Improve opentherm gw startup ([@mvn23] - [#22121]) [#21973]: https://github.com/home-assistant/home-assistant/pull/21973 [#22106]: https://github.com/home-assistant/home-assistant/pull/22106 [#22112]: https://github.com/home-assistant/home-assistant/pull/22112 [#22121]: https://github.com/home-assistant/home-assistant/pull/22121 [#22300]: https://github.com/home-assistant/home-assistant/pull/22300 [#22338]: https://github.com/home-assistant/home-assistant/pull/22338 [#22385]: https://github.com/home-assistant/home-assistant/pull/22385 [#22388]: https://github.com/home-assistant/home-assistant/pull/22388 [#22404]: https://github.com/home-assistant/home-assistant/pull/22404 [@hunterjm]: https://github.com/hunterjm [@ktnrg45]: https://github.com/ktnrg45 [@mvn23]: https://github.com/mvn23 [@pvizeli]: https://github.com/pvizeli ## 如果你需要帮助…… 欢迎使用我们非常活跃的[论坛](https://community.home-assistant.io/),或者加入我们的[聊天频道](https://discord.gg/c5DvZ4e)。虽然发布说明开放评论,但我们更希望你使用前面这些沟通渠道。谢谢。 ## 反馈问题 如果你遇到了这个版本引入的问题,请在我们的 [issue tracker](https://github.com/home-assistant/home-assistant/issues) 中报告。请务必填写 issue 模板中的所有字段。 ## 向后不兼容的变更 * **http.api\_password** - **Deprecated** - 用户 who are still using api\_password for 认证 will need to move its 配置 under auth\_providers. Please see the [updated 文档](/home-assistant/docs/authentication/providers/index.md#legacy-api-password) for further details. Those who don't make this change will see an INFO level reminder in the Home Assistant 日志 until the fix is made for a time, but please note, **api\_password 认证 will eventually be removed completely** and we advise 用户 to change to use one of the [other authentication methods](/home-assistant/docs/authentication/providers/index.md#available-auth-providers). If you manually specify auth providers in your `configuration.yaml`, you will need to migrate your API 密码 from the http section to the auth provider section to continue using it. ([@awarecan] - [#21884]) ([api docs]) ([前端 docs]) ([hassio docs]) ([http docs]) ([MQTT docs]) ([websocket\_api docs][websocket_api docs]) ([zeroconf docs]) ([摄像头.proxy docs]) * **Default Config** - Default config no longer contains the discovery component. That is now part of the initial written 配置.yaml. If you rely on default config and want to use discovery, add `discovery:` back to your 配置.yaml. * **Netatmo** * Added support for multiple Netatmo thermostats/valves allowing the 用户 to specify different homes or 房间! Please check the [updated 文档](/home-assistant/integrations/netatmo.md#温控) for 配置 details. ([@shanbs] - [#19407]) ([netatmo docs]) ([温控.netatmo docs]) * `current_operation` will no longer return the the boiler status, but the operation\_mode. For example, heat, cool, or idle. Please check the [updated 文档](/home-assistant/integrations/netatmo.md#温控) for more details. ([@shanbs] - [#21633]) ([netatmo docs]) * **Utility Meter** - Currently the offset 配置 parameter is an integer that limits daily cycles to have offsets in days, monthly cycles to have offsets in months, etc. This change increases the flexibility of offset by making it a more flexible time period that can be described in a combination of hours, days, months, etc. This makes it possible for a yearly cycle to start at a given day of a given month. Please see the [updated 文档](/home-assistant/integrations/utility_meter/index.md) for the new 配置 options. ([@dgomes] - [#20926]) ([utility\_meter docs][utility_meter docs]) * **KNX** - An 更新 for xknx to 版本 0.10.0 requires 用户 to 更新 their 配置 by changing `target_temperature_address` to `target_temperature_state_address`. Other fixes and features: * Connection config can now be configured in xknx.yml. * Introduce a configurable rate limit which limits the number of KNX telegrams sent to the bus per second. * 用户 who configured their 灯光 via xknx.yml no longer need to manually set min\_kelvin and max\_kelvin (fixes #21251) ([@marvin-w] - [#21541]) ([knx docs]) * **Nanoleaf** - The Nanoleaf component now supports *both* nanoleaf 灯光, Aurora and Canvas. As a result of this change the 用户 needs to change the platform from `nanoleaf_aurora` to `nanoleaf` ([@Oro] - [#21913]) ([灯光.nanoleaf docs]) * **FireTV**- is now androidtv. Instead of having near-duplicate 集成 for androidtv and firetv, the decision was made to combine them into one. 用户 will need to change `- platform: firetv` to `- platform: androidtv` in their 配置. ([@JeffLIrion] - [#21944]) * **Tellstick** - Some 配置 cleanup. The way Tellsick 传感器 配置 was set up using dynamic values for named 传感器 will not be supported in future versions of Home Assistant. 用户 that have configured the optional named 传感器 initiated with only\_named will have to 更新 their 配置. Make sure to check the updated 文档 for further details. ([@endor-force] - [#21402]) ([tellstick docs]) * **MQTT** - Pass `Message` object to MQTT message callbacks instead of `topic`, `message` and `qos`. 用户 of custom components please take note, these values are now available on the passed in message object: `msg.topic`, `msg.message`, `msg.qos`. The old method will continue to work for now but will print 警告. ([@emontnemery] - [#21959]) ([MQTT docs]) ## Beta 修复 * mobile\_app component ([@robbiet480] - [#21475]) ([mobile\_app docs][mobile_app docs]) (beta fix) (new-platform) * Remove UTF8 decoding for Waze ([@philhawthorne] - [#22020]) ([传感器.waze\_travel\_time docs][传感器.waze_travel_time docs]) (beta fix) * Bring back the boiler status ([@cgtobi] - [#22021]) ([netatmo docs]) (beta fix) * 更新 additional platforms to use new MQTT message callback ([@emontnemery] - [#22030]) ([device\_tracker docs][device_tracker docs]) ([mqtt\_eventstream docs][mqtt_eventstream docs]) ([owntracks docs]) ([snips docs]) ([alarm\_control\_panel.manual\_mqtt docs][alarm_control_panel.manual_mqtt docs]) ([自动化.MQTT docs]) ([传感器.arwn docs]) ([传感器.mqtt\_room docs][传感器.mqtt_room docs]) (beta fix) * Fix lifx 灯光 async 错误 ([@awarecan] - [#22031]) ([lifx docs]) (beta fix) * Fix Google Assistant 用户 with Cloud ([@pvizeli] - [#22042]) ([cloud docs]) (beta fix) * Mobile App: Require encryption for registrations that support it ([@robbiet480] - [#21852]) ([mobile\_app docs][mobile_app docs]) (beta fix) * Mobile App: Support rendering multiple 模板 at once ([@robbiet480] - [#21851]) ([mobile\_app docs][mobile_app docs]) (beta fix) * Mobile App: 更新 Location schema updates & 设备 ID generation ([@robbiet480] - [#21849]) ([mobile\_app docs][mobile_app docs]) (beta fix) * Mobile App: Register 设备 into the registry ([@robbiet480] - [#21856]) ([mobile\_app docs][mobile_app docs]) (beta fix) * Mobile App: 传感器 ([@robbiet480] - [#21854]) ([mobile\_app docs][mobile_app docs]) (beta fix) (new-platform) * Bump androidtv to 0.0.11 ([@JeffLIrion] - [#22025]) ([androidtv docs]) (beta fix) * Mobile App: Enable loading via discovery (surprise inside!) ([@robbiet480] - [#22027]) ([mobile\_app docs][mobile_app docs]) (beta fix) * Mobile App: Discovery to default 配置.yaml, zeroconf to default\_config ([@robbiet480] - [#22028]) ([default\_config docs][default_config docs]) ([mobile\_app docs][mobile_app docs]) (beta fix) * Mobile App: Expose Cloud 遥控器 UI FQDN in registration response ([@robbiet480] - [#22055]) ([cloud docs]) ([mobile\_app docs][mobile_app docs]) (beta fix) * Return config entry ID after creation ([@balloob] - [#22060]) ([config docs]) (beta fix) * Correct context ([@awarecan] - [#22061]) ([alexa docs]) (beta fix) * 二元sensor for 遥控器 UI & Fix timezone ([@pvizeli] - [#22076]) (beta fix) * Bump androidtv to 0.0.12 ([@JeffLIrion] - [#22072]) ([androidtv docs]) (beta fix) * Prevent cloud 遥控器 UI when using 127.0.0.1 as trusted network ([@balloob] - [#22093]) ([cloud docs]) (beta fix) * Beta Fix: FFMPEG and Stream component ([@hunterjm] - [#22091]) ([摄像头.ffmpeg docs]) ([摄像头.generic docs]) ([摄像头.onvif docs]) (beta fix) * delete previously removed 服务 option from 服务 yaml ([@hunterjm] - [#22123]) (beta fix) * Remove hass.config from aws\_lambda 通知 payload ([@awarecan] - [#22125]) (breaking change) (beta fix) * Allow non-admins to listen to certain events ([@balloob] - [#22137]) ([websocket\_api docs][websocket_api docs]) (beta fix) * Bump tado 版本 ([@WebSpider] - [#22145]) ([tado docs]) (beta fix) * Fix resetting access token on streams with keepalive ([@hunterjm] - [#22148]) ([stream docs]) (beta fix) * Remove config check over supervisor ([@pvizeli] - [#22156]) ([hassio docs]) (beta fix) * 升级 toonapilib to 3.2.2 + lower interval ([@frenck] - [#22160]) ([toon docs]) (beta fix) * bump total\_connect\_client to 0.24 ([@uchagani] - [#22166]) ([totalconnect docs]) (beta fix) * 更新 Hass-NabuCasa 0.8 ([@pvizeli] - [#22177]) ([cloud docs]) (beta fix) * Always load Hass.io component on Hass.io ([@balloob] - [#22185]) (beta fix) * Fixed typing 错误 ([@Swamp-Ig] - [#22207]) (beta fix) ## 所有变更 * 升级 pyopenuv to 1.0.9 ([@bachya] - [#21513]) ([openuv docs]) * 升级 pypollencom to 2.2.3 ([@bachya] - [#21517]) ([传感器.pollen docs]) * 升级 pytile to 2.0.6 ([@bachya] - [#21516]) ([device\_tracker docs][device_tracker docs]) * Upgraded py17track to 2.2.2 ([@bachya] - [#21515]) ([传感器.seventeentrack docs]) * 升级 pyflunearyou to 1.0.2 ([@bachya] - [#21514]) ([传感器.flunearyou docs]) * Bump starlingbank 版本 to 3.1 ([@Dullage] - [#21501]) ([传感器.starlingbank docs]) * 升级 opensensemap-api to 0.1.5 ([@fabaff] - [#21524]) ([air\_quality docs][air_quality docs]) * Register 'firetv.adb\_command' 服务 ([@JeffLIrion] - [#21419]) ([媒体播放器.firetv docs]) * Add arm night for 报警 decoder ([@koolsb] - [#21488]) ([alarmdecoder docs]) * 升级 numpy to 1.16.2 ([@fabaff] - [#21525]) ([binary\_sensor.trend docs][binary_sensor.trend docs]) ([image\_processing.opencv docs][image_processing.opencv docs]) ([image\_processing.tensorflow docs][image_processing.tensorflow docs]) ([传感器.pollen docs]) * 升级 python-mystrom to 0.5.0 ([@fabaff] - [#21523]) ([灯光.mystrom docs]) ([开关.mystrom docs]) * MQTT 报警 added value\_template and code\_arm\_required ([@ToRvaLDz] - [#19558]) ([alarm\_control\_panel.MQTT docs][alarm_control_panel.MQTT docs]) * Add direct binding for 遥控器 and 灯光 for ZHA ([@dmulcahey] - [#21498]) ([zha docs]) * Add support for homekit controller 传感器 ([@cpopp] - [#21535]) ([homekit\_controller docs][homekit_controller docs]) (new-platform) * 更新 CODEOWNERS ([@dgomes] - [#21545]) * Clean up gpslogger tests ([@MartinHjelmare] - [#21543]) * new websocket api way ([@dmulcahey] - [#21533]) ([zha docs]) * Add pause/unpause 服务 to RainMachine ([@bachya] - [#21548]) ([rainmachine docs]) * prevent duplicate event channel registration ([@dmulcahey] - [#21534]) ([zha docs]) * Allow config entry reloading ([@balloob] - [#21502]) * Add separate on/off ids on manual configured IHC 灯光 ([@msvinth] - [#20253]) ([ihc docs]) ([灯光.ihc docs]) (new-platform) * add friendly name to 设备 in the 设备 registry ([@dmulcahey] - [#21499]) ([zha docs]) * Allow chaining contexts ([@balloob] - [#21028]) ([自动化 docs]) * bump pyxeoma to 1.4.1 to fix and close #19306 ([@trunet] - [#21568]) ([摄像头.xeoma docs]) * fix exception ([@dmulcahey] - [#21571]) ([zha docs]) * Add config entry remove callback ([@andrewsayre] - [#21576]) * mobile\_app component ([@robbiet480] - [#21475]) ([mobile\_app docs][mobile_app docs]) (beta fix) (new-platform) * Memory optimization for logbook ([@amelchio] - [#21549]) ([logbook docs]) * Get 房间 hints from 区域 ([@Swamp-Ig] - [#21519]) ([google\_assistant docs][google_assistant docs]) * Centrally define Watt ([@dgomes] - [#21570]) * Add network throughput statistics to systemmonitor 传感器 ([@dgomes] - [#21575]) ([传感器.systemmonitor docs]) * 更新 for new pyvesyncv\_v2 library and vesync 开关 support ([@webdjoe] - [#21449]) ([开关.vesync docs]) * ZHA fixes ([@dmulcahey] - [#21592]) ([zha docs]) * 更新 pyhomematic ([@danielperna84] - [#21600]) ([homematic docs]) * Add parameter hold\_secs for Harmony 遥控器 send command ([@ehendrix23] - [#19650]) ([遥控器 docs]) ([遥控器.harmony docs]) * 升级 motorparts to 1.1.0 ([@rohankapoorcom] - [#21602]) * Further Yale ZWave 门锁 设备 mapping cleanup ([@mw-white] - [#21128]) ([zwave docs]) * Added support for multiple Netatmo thermostats/valves ([@shanbs] - [#19407]) ([netatmo docs]) ([温控.netatmo docs]) (breaking change) * Add the velbus sync clock 服务 ([@Cereal2nd] - [#21308]) ([velbus docs]) * SmartThings remove SmartApp/自动化 on 集成 removal ([@andrewsayre] - [#21594]) ([smartthings docs]) (new-feature) * Bumping aioasuswrt ([@kennedyshead] - [#21627]) ([asuswrt docs]) * Add 设备 HMIP-eTRV-C to HomematicIP ([@SukramJ] - [#21612]) * Add 'app\_name' property and 'apps' config entry to Fire TV ([@JeffLIrion] - [#21601]) ([androidtv docs]) * Add optional sender name for SendGrid ([@srirams] - [#21610]) ([通知.sendgrid docs]) * fix derived rate, fixes #20097 ([@wburgers] - [#21620]) ([传感器.dsmr docs]) * Bump pyflunearyou to 1.0.3 ([@bachya] - [#21634]) ([传感器.flunearyou docs]) * Return Netatmo 温控 operation\_mode instead of boiler status ([@shanbs] - [#21633]) ([netatmo docs]) (breaking change) * Expose create/delete cloudhook ([@balloob] - [#21606]) ([cloud docs]) * Add storage 助手 to ZHA and use it for the 设备 node descriptor ([@dmulcahey] - [#21500]) ([zha docs]) (new-platform) * Allow 配置 of 更新 interval for ness\_alarm ([@nickw444] - [#21415]) ([ness\_alarm docs][ness_alarm docs]) * Replace travis ([@pvizeli] - [#21641]) * Fix 动作 with tox ([@pvizeli] - [#21642]) * GitHub Workflow ([@pvizeli] - [#21643]) * 升级 youtube\_dl to 2019.03.01 ([@fabaff] - [#21647]) ([media\_extractor docs][media_extractor docs]) * Add support for DHT and DS18B20 传感器 via Konnected firmware ([@heythisisnate] - [#21189]) ([konnected docs]) * Allow targeting 区域 in 服务 calls ([@balloob] - [#21472]) ([alert docs]) ([自动化 docs]) ([group docs]) ([image\_processing docs][image_processing docs]) ([灯光 docs]) ([场景 docs]) ([脚本 docs]) * Add 摄像头 name to 日志 ([@arsaboo] - [#21653]) ([摄像头.generic docs]) * Netatmo, handle missing thermostat 设备 ([@Danielhiversen] - [#21651]) ([netatmo docs]) * Add SmartThingsAccelCluster to ZHA binary\_sensor ([@roblandry] - [#21609]) ([zha docs]) (new-platform) * Add support for multiple 设备 for PS4 component ([@ktnrg45] - [#21302]) ([ps4 docs]) * Xfinity Gateway device\_tracker platform ([@cisasteelersfan] - [#21026]) ([device\_tracker docs][device_tracker docs]) (new-platform) * Adds option in UPnP component to override callback url ([@StevenLooman] - [#21583]) ([媒体播放器.dlna\_dmr docs][媒体播放器.dlna_dmr docs]) * Serialize amcrest snapshot commands and bump PyPI package to 1.2.4 ([@pnbruckner] - [#21664]) ([amcrest docs]) * Bump nessclient 版本 to 0.9.14 ([@nickw444] - [#21679]) ([ness\_alarm docs][ness_alarm docs]) * Allow 202 status code as a successful REST 通知 response ([@u1f35c] - [#21678]) ([通知 docs]) * Bump teslajsonpy to 0.0.24 ([@alandtse] - [#21675]) ([tesla docs]) * Fix Z-Wave relative imports ([@balloob] - [#21693]) ([zwave docs]) * Use new style for built-in ws commmands ([@balloob] - [#21694]) ([websocket\_api docs][websocket_api docs]) * Google Assistant: Create and pass context to 服务 calls ([@Swamp-Ig] - [#21551]) ([google\_assistant docs][google_assistant docs]) * 更新 to teslajsonpy v0.0.25 ([@alandtse] - [#21702]) ([tesla docs]) * Utility Meter offset defined by a time\_period ([@dgomes] - [#20926]) ([utility\_meter docs][utility_meter docs]) (breaking change) * Change amcrest camera\_image to async ([@pnbruckner] - [#21720]) ([amcrest docs]) * Start preparing for homekit\_controller config entries ([@Jc2k] - [#21564]) ([homekit\_controller docs][homekit_controller docs]) * Support multiple keys in ifttt 触发器 ([@zeehio] - [#21454]) ([ifttt docs]) * Fix initialization and add "pending" status of Satel integra ([@c-soft] - [#21194]) ([satel\_integra docs][satel_integra docs]) * Fix pylint 警告 on python 3.7 ([@awarecan] - [#21714]) ([温控.eq3btsmart docs]) * Make pytest in tox quite ([@awarecan] - [#21727]) * tplink - catch SmartDeviceException on is\_dimmable call ([@ljmerza] - [#21726]) ([tplink docs]) * Remove pytest 警告 message ([@awarecan] - [#21713]) * 更新 .travis.yml ([@pvizeli] - [#21736]) * Revert Travis until github 动作 work better for PR ([@pvizeli] - [#21746]) * Allow 灯光 切换 服务 to accept all 打开 params ([@zewelor] - [#20912]) ([灯光 docs]) * Introduce target\_temperature\_state\_address for 温控 设备 ([@marvin-w] - [#21541]) ([knx docs]) (breaking change) * 升级 pylint to 2.3.1 ([@scop] - [#21789]) * Add Time of Flight 传感器 using VL53L1X ([@josemotta] - [#21230]) ([tof docs]) (new-platform) * 升级 huawei-lte-api to 1.1.5 ([@scop] - [#21791]) ([huawei\_lte docs][huawei_lte docs]) * Adding enigma2 media player ([@fbradyirl] - [#21271]) ([媒体播放器.enigma2 docs]) (new-platform) * Bump loopenergy to 0.1.0. Loop updated their socket.io server from 0.9 to 2.0 - which required a library 更新. ([@pavoni] - [#21809]) ([传感器.loopenergy docs]) * remove occupancy, as it is not available at this level in the iRail api ([@nudded] - [#21810]) ([传感器.nmbs docs]) * Onboarding to generate auth code ([@balloob] - [#21777]) ([auth docs]) ([onboarding docs]) * Remove stub from config component ([@balloob] - [#21822]) ([config docs]) * change paths to be relative ([@uchagani] - [#21827]) ([zwave docs]) * Change how we import config modules ([@balloob] - [#21824]) ([config docs]) * Load logger and system\_log components as soon as possible ([@awarecan] - [#21799]) * Resolve auth\_store loading race 条件 ([@awarecan] - [#21794]) * 日志 if aiohttp hits 错误 during IndieAuth ([@robbiet480] - [#21780]) ([auth docs]) * Add support for Cisco Mobility Express ([@fbradyirl] - [#21531]) ([cisco\_mobility\_express docs][cisco_mobility_express docs]) (new-platform) * Synology 传感器 quick return if attr is null ([@cmsimike] - [#21709]) ([传感器.synologydsm docs]) * fix empty TOPIC\_BASE issue ([@engrbm87] - [#21740]) ([MQTT docs]) * Updated to pyeconet 0.0.10 ([@w1ll1am23] - [#21837]) ([water\_heater docs][water_heater docs]) * Fix config entry exception in Ambient PWS ([@bachya] - [#21836]) ([ambient\_station docs][ambient_station docs]) * Fixed a misspelling in a docstring ([@bachya] - [#21846]) ([ambient\_station docs][ambient_station docs]) * mobile\_app improvements ([@robbiet480] - [#21607]) ([mobile\_app docs][mobile_app docs]) * 更新 honeywell.py to read current humidity for US Thermostats ([@Hackashaq666] - [#21728]) ([温控.honeywell docs]) * Fix TypeError ([@wburgers] - [#21734]) ([传感器.dsmr docs]) * Introduce 实体.async\_write\_ha\_state() to not miss 状态 transition ([@emontnemery] - [#21590]) * Fix authorization header in cors ([@piitaya] - [#21662]) ([http docs]) * Only commit if need. ([@awarecan] - [#21848]) * Bump quirks for ZHA and handle resulting battery % change ([@dmulcahey] - [#21869]) ([zha docs]) * Better cloud check ([@balloob] - [#21875]) ([cloud docs]) ([mobile\_app docs][mobile_app docs]) * Add ClearPass Policy Manger 设备 tracker ([@zemerick1] - [#21673]) ([device\_tracker docs][device_tracker docs]) (new-platform) * Add SmartThings 温控 support for Air Conditioners ([@andrewsayre] - [#21840]) ([smartthings docs]) (new-feature) * Add SmartThings 传感器 support for Three Axis ([@andrewsayre] - [#21841]) ([smartthings docs]) (new-feature) * Add 用户 group ([@balloob] - [#21832]) * 更新 ZHA 状态 handling ([@dmulcahey] - [#21866]) ([zha docs]) * Change lib for whois 传感器 ([@ludeeus] - [#21878]) ([传感器.whois docs]) * Don't wait until final position of Velux 遮盖 is reached ([@Julius2342] - [#21558]) ([velux docs]) * Fix missing code\_required check in async\_alarm\_arm\_night ([@ToRvaLDz] - [#21858]) ([MQTT docs]) * Fix icon for 传感器.discogs\_random\_record ([@thibmaek] - [#21891]) ([传感器.discogs docs]) * Add myself to CODEOWNERS for NMBS code ([@thibmaek] - [#21892]) * Modbus write\_register accept single value and array ([@gertdb] - [#21621]) ([modbus docs]) * Add custom holidays to workday 传感器 ([@epleypa] - [#21718]) ([binary\_sensor.workday docs][binary_sensor.workday docs]) * Return time based 属性 as datetime in Unifi module ([@ndonegan] - [#21146]) ([device\_tracker docs][device_tracker docs]) * Allow emulated hue to set 温控 component temperature ([@chilicheech] - [#19034]) ([emulated\_hue docs][emulated_hue docs]) * bump netdisco to 2.4.0 ([@fbradyirl] - [#21914]) * Deprecate http.api\_password ([@awarecan] - [#21884]) ([api docs]) ([前端 docs]) ([hassio docs]) ([http docs]) ([MQTT docs]) ([websocket\_api docs][websocket_api docs]) ([zeroconf docs]) ([摄像头.proxy docs]) (breaking change) * Don't hang forever if manually added cast is down ([@emontnemery] - [#21565]) ([cast docs]) * Add WS subscription command for MQTT ([@balloob] - [#21696]) ([MQTT docs]) ([websocket\_api docs][websocket_api docs]) * Add 'ssl' parameter for FiOS Quantum Gateway and 升级 Pypi ([@cisasteelersfan] - [#21669]) ([device\_tracker docs][device_tracker docs]) * Add as\_timestamp() to Jinja filters. ([@rbdixon] - [#21910]) * HomeKit controller config flow fixes ([@Jc2k] - [#21898]) ([homekit\_controller docs][homekit_controller docs]) * 更新 enigma2 based on review comments ([@fbradyirl] - [#21890]) ([enigma2 docs]) * Remove confusing 警告 for TTS without entity\_id ([@amelchio] - [#21927]) ([tts docs]) * Fixes Modbus 服务.yaml validity ([@gertdb] - [#21923]) * Add cloudhook support to SmartThings component ([@andrewsayre] - [#21905]) ([smartthings docs]) * If registration supports encryption then return encrypted payloads ([@robbiet480] - [#21853]) ([mobile\_app docs][mobile_app docs]) * Allow inverting netdata 传感器 values ([@michaelarnauts] - [#21711]) ([传感器.netdata docs]) * Changed from nanoleaf\_aurora to nanoleaf ([@Oro] - [#21913]) ([灯光.nanoleaf docs]) (breaking change) * Minor 版本 bump for anthemav package ([@nugget] - [#21932]) ([媒体播放器.anthemav docs]) * Add 区域 permission check ([@balloob] - [#21835]) * Add an asyncio 门锁 around pairing, which cant be used concurrently ([@Jc2k] - [#21933]) ([homekit\_controller docs][homekit_controller docs]) * Add 更新 用户 command ([@balloob] - [#21922]) ([config docs]) * Offload Cloud component ([@pvizeli] - [#21937]) ([cloud docs]) * 升级 schiene to 0.23 ([@fabaff] - [#21940]) ([传感器.deutsche\_bahn docs][传感器.deutsche_bahn docs]) * Live Streams Component ([@hunterjm] - [#21473]) ([摄像头 docs]) ([stream docs]) (new-platform) * 更新 lametric icon to be HA logo ([@robbiet480] - [#21957]) ([lametric docs]) * Avoid playing queue pollution when restoring Sonos snapshots ([@amelchio] - [#21963]) ([sonos docs]) * 更新 to sense component to fully be async ([@kbickar] - [#21698]) ([sense docs]) * fix ephember doing http call from property ([@ttroy50] - [#21855]) ([温控.ephember docs]) * Add 天气 传感器 to Homematic IP ([@SukramJ] - [#21887]) ([homematicip\_cloud docs][homematicip_cloud docs]) (new-platform) * Add cloud status ([@balloob] - [#21960]) ([cloud docs]) * Fix MagicHome LEDs with flux\_led component ([@autinerd] - [#20733]) ([灯光.flux\_led docs][灯光.flux_led docs]) * Stream: Only add base url when needed ([@balloob] - [#21979]) ([摄像头 docs]) ([stream docs]) * Allow changing 密码 without being admin ([@balloob] - [#21978]) ([config docs]) * Fix some cloud things ([@balloob] - [#21977]) * homekit\_controller: Bump homekit to 0.13.0 ([@Jc2k] - [#21965]) ([homekit\_controller docs][homekit_controller docs]) * skip flaky test ([@balloob] - [#21981]) * Write 状态 directly in all MQTT platforms ([@emontnemery] - [#21971]) ([MQTT docs]) * Use .get to ensure we dont get KeyError ([@robbiet480] - [#21993]) ([mobile\_app docs][mobile_app docs]) * Fix 错误 introduced by #21933 ([@Jc2k] - [#21988]) ([homekit\_controller docs][homekit_controller docs]) * Add stream source for amcrest component ([@dshokouhi] - [#21983]) ([amcrest docs]) * Set homekit controller 实体 as unavailable if new connections fail ([@Jc2k] - [#21901]) ([homekit\_controller docs][homekit_controller docs]) * Centrally define Energy Units (kWh and Wh) ([@dgomes] - [#21719]) * Mobile App: Registration schema improvements ([@robbiet480] - [#21850]) ([mobile\_app docs][mobile_app docs]) * Add a 服务 require\_admin wrapper ([@balloob] - [#21953]) * 更新 pyhomematic to 0.1.58 ([@danielperna84] - [#21989]) ([homematic docs]) * Use asyncio 门锁 ([@amelchio] - [#21985]) ([sonos docs]) * Add breaking change section to PR 模板 ([@awarecan] - [#21994]) * Rename 'firetv' to 'androidtv' and add Android TV functionality ([@JeffLIrion] - [#21944]) (breaking change) * Tellstick 传感器 配置 cleanup ([@endor-force] - [#21402]) ([tellstick docs]) (breaking change) * Add availability and next run datetime to RainMachine 开关 ([@bachya] - [#21786]) ([rainmachine docs]) * Add program/区域 enable/disable 服务 to RainMachine ([@bachya] - [#21785]) ([rainmachine docs]) * Bump NabuCasa library to 0.5 ([@pvizeli] - [#22010]) ([cloud docs]) * Avoid playing queue pollution with Sonos unjoin ([@amelchio] - [#22004]) ([sonos docs]) * Wait for Sonos regrouping in 服务 calls ([@amelchio] - [#22006]) ([sonos docs]) * fix 错误 in LutronButton init if 按钮 doesn't have a type ([@beavis9k] - [#21921]) ([lutron docs]) * HomeKit controller 灯光 - remove code that can never execute ([@Jc2k] - [#21951]) ([homekit\_controller docs][homekit_controller docs]) * Nanoleaf availability check ([@Oro] - [#21945]) ([灯光.nanoleaf docs]) * Pass Message object to MQTT message callbacks ([@emontnemery] - [#21959]) ([MQTT docs]) (breaking change) * Remove default temp unit ([@andrewsayre] - [#22012]) ([smartthings docs]) * Allow all success status codes in REST 通知 response ([@isabellaalstrom] - [#22011]) ([通知 docs]) * Check updated\_date for list and pick first ([@GGeezes] - [#22008]) * Remove UTF8 decoding for Waze ([@philhawthorne] - [#22020]) ([传感器.waze\_travel\_time docs][传感器.waze_travel_time docs]) (beta fix) * Bring back the boiler status ([@cgtobi] - [#22021]) ([netatmo docs]) (beta fix) * 更新 additional platforms to use new MQTT message callback ([@emontnemery] - [#22030]) ([device\_tracker docs][device_tracker docs]) ([mqtt\_eventstream docs][mqtt_eventstream docs]) ([owntracks docs]) ([snips docs]) ([alarm\_control\_panel.manual\_mqtt docs][alarm_control_panel.manual_mqtt docs]) ([自动化.MQTT docs]) ([传感器.arwn docs]) ([传感器.mqtt\_room docs][传感器.mqtt_room docs]) (beta fix) * Fix lifx 灯光 async 错误 ([@awarecan] - [#22031]) ([lifx docs]) (beta fix) * Fix Google Assistant 用户 with Cloud ([@pvizeli] - [#22042]) ([cloud docs]) (beta fix) * Mobile App: Require encryption for registrations that support it ([@robbiet480] - [#21852]) ([mobile\_app docs][mobile_app docs]) (beta fix) * Mobile App: Support rendering multiple 模板 at once ([@robbiet480] - [#21851]) ([mobile\_app docs][mobile_app docs]) (beta fix) * Mobile App: 更新 Location schema updates & 设备 ID generation ([@robbiet480] - [#21849]) ([mobile\_app docs][mobile_app docs]) (beta fix) * Mobile App: Register 设备 into the registry ([@robbiet480] - [#21856]) ([mobile\_app docs][mobile_app docs]) (beta fix) * Mobile App: 传感器 ([@robbiet480] - [#21854]) ([mobile\_app docs][mobile_app docs]) (beta fix) (new-platform) * Bump androidtv to 0.0.11 ([@JeffLIrion] - [#22025]) ([androidtv docs]) (beta fix) * Mobile App: Enable loading via discovery (surprise inside!) ([@robbiet480] - [#22027]) ([mobile\_app docs][mobile_app docs]) (beta fix) * Mobile App: Discovery to default 配置.yaml, zeroconf to default\_config ([@robbiet480] - [#22028]) ([default\_config docs][default_config docs]) ([mobile\_app docs][mobile_app docs]) (beta fix) * Mobile App: Expose Cloud 遥控器 UI FQDN in registration response ([@robbiet480] - [#22055]) ([cloud docs]) ([mobile\_app docs][mobile_app docs]) (beta fix) * Return config entry ID after creation ([@balloob] - [#22060]) ([config docs]) (beta fix) * Correct context ([@awarecan] - [#22061]) ([alexa docs]) (beta fix) * 二元sensor for 遥控器 UI & Fix timezone ([@pvizeli] - [#22076]) (beta fix) * Bump androidtv to 0.0.12 ([@JeffLIrion] - [#22072]) ([androidtv docs]) (beta fix) * Prevent cloud 遥控器 UI when using 127.0.0.1 as trusted network ([@balloob] - [#22093]) ([cloud docs]) (beta fix) * Beta Fix: FFMPEG and Stream component ([@hunterjm] - [#22091]) ([摄像头.ffmpeg docs]) ([摄像头.generic docs]) ([摄像头.onvif docs]) (beta fix) * delete previously removed 服务 option from 服务 yaml ([@hunterjm] - [#22123]) (beta fix) * Remove hass.config from aws\_lambda 通知 payload ([@awarecan] - [#22125]) (breaking change) (beta fix) * Allow non-admins to listen to certain events ([@balloob] - [#22137]) ([websocket\_api docs][websocket_api docs]) (beta fix) * Bump tado 版本 ([@WebSpider] - [#22145]) ([tado docs]) (beta fix) * Fix resetting access token on streams with keepalive ([@hunterjm] - [#22148]) ([stream docs]) (beta fix) * Remove config check over supervisor ([@pvizeli] - [#22156]) ([hassio docs]) (beta fix) * 升级 toonapilib to 3.2.2 + lower interval ([@frenck] - [#22160]) ([toon docs]) (beta fix) * bump total\_connect\_client to 0.24 ([@uchagani] - [#22166]) ([totalconnect docs]) (beta fix) * 更新 Hass-NabuCasa 0.8 ([@pvizeli] - [#22177]) ([cloud docs]) (beta fix) * Always load Hass.io component on Hass.io ([@balloob] - [#22185]) (beta fix) * Fixed typing 错误 ([@Swamp-Ig] - [#22207]) (beta fix) [#19034]: https://github.com/home-assistant/home-assistant/pull/19034 [#19407]: https://github.com/home-assistant/home-assistant/pull/19407 [#19558]: https://github.com/home-assistant/home-assistant/pull/19558 [#19650]: https://github.com/home-assistant/home-assistant/pull/19650 [#20253]: https://github.com/home-assistant/home-assistant/pull/20253 [#20733]: https://github.com/home-assistant/home-assistant/pull/20733 [#20912]: https://github.com/home-assistant/home-assistant/pull/20912 [#20926]: https://github.com/home-assistant/home-assistant/pull/20926 [#21026]: https://github.com/home-assistant/home-assistant/pull/21026 [#21028]: https://github.com/home-assistant/home-assistant/pull/21028 [#21128]: https://github.com/home-assistant/home-assistant/pull/21128 [#21146]: https://github.com/home-assistant/home-assistant/pull/21146 [#21189]: https://github.com/home-assistant/home-assistant/pull/21189 [#21194]: https://github.com/home-assistant/home-assistant/pull/21194 [#21230]: https://github.com/home-assistant/home-assistant/pull/21230 [#21271]: https://github.com/home-assistant/home-assistant/pull/21271 [#21302]: https://github.com/home-assistant/home-assistant/pull/21302 [#21308]: https://github.com/home-assistant/home-assistant/pull/21308 [#21402]: https://github.com/home-assistant/home-assistant/pull/21402 [#21415]: https://github.com/home-assistant/home-assistant/pull/21415 [#21419]: https://github.com/home-assistant/home-assistant/pull/21419 [#21449]: https://github.com/home-assistant/home-assistant/pull/21449 [#21454]: https://github.com/home-assistant/home-assistant/pull/21454 [#21472]: https://github.com/home-assistant/home-assistant/pull/21472 [#21473]: https://github.com/home-assistant/home-assistant/pull/21473 [#21475]: https://github.com/home-assistant/home-assistant/pull/21475 [#21488]: https://github.com/home-assistant/home-assistant/pull/21488 [#21498]: https://github.com/home-assistant/home-assistant/pull/21498 [#21499]: https://github.com/home-assistant/home-assistant/pull/21499 [#21500]: https://github.com/home-assistant/home-assistant/pull/21500 [#21501]: https://github.com/home-assistant/home-assistant/pull/21501 [#21502]: https://github.com/home-assistant/home-assistant/pull/21502 [#21513]: https://github.com/home-assistant/home-assistant/pull/21513 [#21514]: https://github.com/home-assistant/home-assistant/pull/21514 [#21515]: https://github.com/home-assistant/home-assistant/pull/21515 [#21516]: https://github.com/home-assistant/home-assistant/pull/21516 [#21517]: https://github.com/home-assistant/home-assistant/pull/21517 [#21519]: https://github.com/home-assistant/home-assistant/pull/21519 [#21523]: https://github.com/home-assistant/home-assistant/pull/21523 [#21524]: https://github.com/home-assistant/home-assistant/pull/21524 [#21525]: https://github.com/home-assistant/home-assistant/pull/21525 [#21531]: https://github.com/home-assistant/home-assistant/pull/21531 [#21533]: https://github.com/home-assistant/home-assistant/pull/21533 [#21534]: https://github.com/home-assistant/home-assistant/pull/21534 [#21535]: https://github.com/home-assistant/home-assistant/pull/21535 [#21541]: https://github.com/home-assistant/home-assistant/pull/21541 [#21543]: https://github.com/home-assistant/home-assistant/pull/21543 [#21545]: https://github.com/home-assistant/home-assistant/pull/21545 [#21548]: https://github.com/home-assistant/home-assistant/pull/21548 [#21549]: https://github.com/home-assistant/home-assistant/pull/21549 [#21551]: https://github.com/home-assistant/home-assistant/pull/21551 [#21558]: https://github.com/home-assistant/home-assistant/pull/21558 [#21564]: https://github.com/home-assistant/home-assistant/pull/21564 [#21565]: https://github.com/home-assistant/home-assistant/pull/21565 [#21568]: https://github.com/home-assistant/home-assistant/pull/21568 [#21570]: https://github.com/home-assistant/home-assistant/pull/21570 [#21571]: https://github.com/home-assistant/home-assistant/pull/21571 [#21575]: https://github.com/home-assistant/home-assistant/pull/21575 [#21576]: https://github.com/home-assistant/home-assistant/pull/21576 [#21583]: https://github.com/home-assistant/home-assistant/pull/21583 [#21590]: https://github.com/home-assistant/home-assistant/pull/21590 [#21592]: https://github.com/home-assistant/home-assistant/pull/21592 [#21594]: https://github.com/home-assistant/home-assistant/pull/21594 [#21600]: https://github.com/home-assistant/home-assistant/pull/21600 [#21601]: https://github.com/home-assistant/home-assistant/pull/21601 [#21602]: https://github.com/home-assistant/home-assistant/pull/21602 [#21606]: https://github.com/home-assistant/home-assistant/pull/21606 [#21607]: https://github.com/home-assistant/home-assistant/pull/21607 [#21609]: https://github.com/home-assistant/home-assistant/pull/21609 [#21610]: https://github.com/home-assistant/home-assistant/pull/21610 [#21612]: https://github.com/home-assistant/home-assistant/pull/21612 [#21620]: https://github.com/home-assistant/home-assistant/pull/21620 [#21621]: https://github.com/home-assistant/home-assistant/pull/21621 [#21627]: https://github.com/home-assistant/home-assistant/pull/21627 [#21633]: https://github.com/home-assistant/home-assistant/pull/21633 [#21634]: https://github.com/home-assistant/home-assistant/pull/21634 [#21641]: https://github.com/home-assistant/home-assistant/pull/21641 [#21642]: https://github.com/home-assistant/home-assistant/pull/21642 [#21643]: https://github.com/home-assistant/home-assistant/pull/21643 [#21647]: https://github.com/home-assistant/home-assistant/pull/21647 [#21651]: https://github.com/home-assistant/home-assistant/pull/21651 [#21653]: https://github.com/home-assistant/home-assistant/pull/21653 [#21662]: https://github.com/home-assistant/home-assistant/pull/21662 [#21664]: https://github.com/home-assistant/home-assistant/pull/21664 [#21669]: https://github.com/home-assistant/home-assistant/pull/21669 [#21673]: https://github.com/home-assistant/home-assistant/pull/21673 [#21675]: https://github.com/home-assistant/home-assistant/pull/21675 [#21678]: https://github.com/home-assistant/home-assistant/pull/21678 [#21679]: https://github.com/home-assistant/home-assistant/pull/21679 [#21693]: https://github.com/home-assistant/home-assistant/pull/21693 [#21694]: https://github.com/home-assistant/home-assistant/pull/21694 [#21696]: https://github.com/home-assistant/home-assistant/pull/21696 [#21698]: https://github.com/home-assistant/home-assistant/pull/21698 [#21702]: https://github.com/home-assistant/home-assistant/pull/21702 [#21709]: https://github.com/home-assistant/home-assistant/pull/21709 [#21711]: https://github.com/home-assistant/home-assistant/pull/21711 [#21713]: https://github.com/home-assistant/home-assistant/pull/21713 [#21714]: https://github.com/home-assistant/home-assistant/pull/21714 [#21718]: https://github.com/home-assistant/home-assistant/pull/21718 [#21719]: https://github.com/home-assistant/home-assistant/pull/21719 [#21720]: https://github.com/home-assistant/home-assistant/pull/21720 [#21726]: https://github.com/home-assistant/home-assistant/pull/21726 [#21727]: https://github.com/home-assistant/home-assistant/pull/21727 [#21728]: https://github.com/home-assistant/home-assistant/pull/21728 [#21734]: https://github.com/home-assistant/home-assistant/pull/21734 [#21736]: https://github.com/home-assistant/home-assistant/pull/21736 [#21740]: https://github.com/home-assistant/home-assistant/pull/21740 [#21746]: https://github.com/home-assistant/home-assistant/pull/21746 [#21777]: https://github.com/home-assistant/home-assistant/pull/21777 [#21780]: https://github.com/home-assistant/home-assistant/pull/21780 [#21785]: https://github.com/home-assistant/home-assistant/pull/21785 [#21786]: https://github.com/home-assistant/home-assistant/pull/21786 [#21789]: https://github.com/home-assistant/home-assistant/pull/21789 [#21791]: https://github.com/home-assistant/home-assistant/pull/21791 [#21794]: https://github.com/home-assistant/home-assistant/pull/21794 [#21799]: https://github.com/home-assistant/home-assistant/pull/21799 [#21809]: https://github.com/home-assistant/home-assistant/pull/21809 [#21810]: https://github.com/home-assistant/home-assistant/pull/21810 [#21822]: https://github.com/home-assistant/home-assistant/pull/21822 [#21824]: https://github.com/home-assistant/home-assistant/pull/21824 [#21827]: https://github.com/home-assistant/home-assistant/pull/21827 [#21832]: https://github.com/home-assistant/home-assistant/pull/21832 [#21835]: https://github.com/home-assistant/home-assistant/pull/21835 [#21836]: https://github.com/home-assistant/home-assistant/pull/21836 [#21837]: https://github.com/home-assistant/home-assistant/pull/21837 [#21840]: https://github.com/home-assistant/home-assistant/pull/21840 [#21841]: https://github.com/home-assistant/home-assistant/pull/21841 [#21846]: https://github.com/home-assistant/home-assistant/pull/21846 [#21848]: https://github.com/home-assistant/home-assistant/pull/21848 [#21849]: https://github.com/home-assistant/home-assistant/pull/21849 [#21850]: https://github.com/home-assistant/home-assistant/pull/21850 [#21851]: https://github.com/home-assistant/home-assistant/pull/21851 [#21852]: https://github.com/home-assistant/home-assistant/pull/21852 [#21853]: https://github.com/home-assistant/home-assistant/pull/21853 [#21854]: https://github.com/home-assistant/home-assistant/pull/21854 [#21855]: https://github.com/home-assistant/home-assistant/pull/21855 [#21856]: https://github.com/home-assistant/home-assistant/pull/21856 [#21858]: https://github.com/home-assistant/home-assistant/pull/21858 [#21866]: https://github.com/home-assistant/home-assistant/pull/21866 [#21869]: https://github.com/home-assistant/home-assistant/pull/21869 [#21875]: https://github.com/home-assistant/home-assistant/pull/21875 [#21878]: https://github.com/home-assistant/home-assistant/pull/21878 [#21884]: https://github.com/home-assistant/home-assistant/pull/21884 [#21887]: https://github.com/home-assistant/home-assistant/pull/21887 [#21890]: https://github.com/home-assistant/home-assistant/pull/21890 [#21891]: https://github.com/home-assistant/home-assistant/pull/21891 [#21892]: https://github.com/home-assistant/home-assistant/pull/21892 [#21898]: https://github.com/home-assistant/home-assistant/pull/21898 [#21901]: https://github.com/home-assistant/home-assistant/pull/21901 [#21905]: https://github.com/home-assistant/home-assistant/pull/21905 [#21910]: https://github.com/home-assistant/home-assistant/pull/21910 [#21913]: https://github.com/home-assistant/home-assistant/pull/21913 [#21914]: https://github.com/home-assistant/home-assistant/pull/21914 [#21921]: https://github.com/home-assistant/home-assistant/pull/21921 [#21922]: https://github.com/home-assistant/home-assistant/pull/21922 [#21923]: https://github.com/home-assistant/home-assistant/pull/21923 [#21927]: https://github.com/home-assistant/home-assistant/pull/21927 [#21932]: https://github.com/home-assistant/home-assistant/pull/21932 [#21933]: https://github.com/home-assistant/home-assistant/pull/21933 [#21937]: https://github.com/home-assistant/home-assistant/pull/21937 [#21940]: https://github.com/home-assistant/home-assistant/pull/21940 [#21944]: https://github.com/home-assistant/home-assistant/pull/21944 [#21945]: https://github.com/home-assistant/home-assistant/pull/21945 [#21951]: https://github.com/home-assistant/home-assistant/pull/21951 [#21953]: https://github.com/home-assistant/home-assistant/pull/21953 [#21957]: https://github.com/home-assistant/home-assistant/pull/21957 [#21959]: https://github.com/home-assistant/home-assistant/pull/21959 [#21960]: https://github.com/home-assistant/home-assistant/pull/21960 [#21963]: https://github.com/home-assistant/home-assistant/pull/21963 [#21965]: https://github.com/home-assistant/home-assistant/pull/21965 [#21971]: https://github.com/home-assistant/home-assistant/pull/21971 [#21977]: https://github.com/home-assistant/home-assistant/pull/21977 [#21978]: https://github.com/home-assistant/home-assistant/pull/21978 [#21979]: https://github.com/home-assistant/home-assistant/pull/21979 [#21981]: https://github.com/home-assistant/home-assistant/pull/21981 [#21983]: https://github.com/home-assistant/home-assistant/pull/21983 [#21985]: https://github.com/home-assistant/home-assistant/pull/21985 [#21988]: https://github.com/home-assistant/home-assistant/pull/21988 [#21989]: https://github.com/home-assistant/home-assistant/pull/21989 [#21993]: https://github.com/home-assistant/home-assistant/pull/21993 [#21994]: https://github.com/home-assistant/home-assistant/pull/21994 [#22004]: https://github.com/home-assistant/home-assistant/pull/22004 [#22006]: https://github.com/home-assistant/home-assistant/pull/22006 [#22008]: https://github.com/home-assistant/home-assistant/pull/22008 [#22010]: https://github.com/home-assistant/home-assistant/pull/22010 [#22011]: https://github.com/home-assistant/home-assistant/pull/22011 [#22012]: https://github.com/home-assistant/home-assistant/pull/22012 [#22020]: https://github.com/home-assistant/home-assistant/pull/22020 [#22021]: https://github.com/home-assistant/home-assistant/pull/22021 [#22025]: https://github.com/home-assistant/home-assistant/pull/22025 [#22027]: https://github.com/home-assistant/home-assistant/pull/22027 [#22028]: https://github.com/home-assistant/home-assistant/pull/22028 [#22030]: https://github.com/home-assistant/home-assistant/pull/22030 [#22031]: https://github.com/home-assistant/home-assistant/pull/22031 [#22042]: https://github.com/home-assistant/home-assistant/pull/22042 [#22055]: https://github.com/home-assistant/home-assistant/pull/22055 [#22060]: https://github.com/home-assistant/home-assistant/pull/22060 [#22061]: https://github.com/home-assistant/home-assistant/pull/22061 [#22072]: https://github.com/home-assistant/home-assistant/pull/22072 [#22076]: https://github.com/home-assistant/home-assistant/pull/22076 [#22091]: https://github.com/home-assistant/home-assistant/pull/22091 [#22093]: https://github.com/home-assistant/home-assistant/pull/22093 [#22123]: https://github.com/home-assistant/home-assistant/pull/22123 [#22125]: https://github.com/home-assistant/home-assistant/pull/22125 [#22137]: https://github.com/home-assistant/home-assistant/pull/22137 [#22145]: https://github.com/home-assistant/home-assistant/pull/22145 [#22148]: https://github.com/home-assistant/home-assistant/pull/22148 [#22156]: https://github.com/home-assistant/home-assistant/pull/22156 [#22160]: https://github.com/home-assistant/home-assistant/pull/22160 [#22166]: https://github.com/home-assistant/home-assistant/pull/22166 [#22177]: https://github.com/home-assistant/home-assistant/pull/22177 [#22185]: https://github.com/home-assistant/home-assistant/pull/22185 [#22207]: https://github.com/home-assistant/home-assistant/pull/22207 [@Cereal2nd]: https://github.com/Cereal2nd [@Danielhiversen]: https://github.com/Danielhiversen [@Dullage]: https://github.com/Dullage [@GGeezes]: https://github.com/GGeezes [@Hackashaq666]: https://github.com/Hackashaq666 [@Jc2k]: https://github.com/Jc2k [@JeffLIrion]: https://github.com/JeffLIrion [@Julius2342]: https://github.com/Julius2342 [@MartinHjelmare]: https://github.com/MartinHjelmare [@Oro]: https://github.com/Oro [@StevenLooman]: https://github.com/StevenLooman [@SukramJ]: https://github.com/SukramJ [@Swamp-Ig]: https://github.com/Swamp-Ig [@ToRvaLDz]: https://github.com/ToRvaLDz [@WebSpider]: https://github.com/WebSpider [@alandtse]: https://github.com/alandtse [@amelchio]: https://github.com/amelchio [@andrewsayre]: https://github.com/andrewsayre [@arsaboo]: https://github.com/arsaboo [@autinerd]: https://github.com/autinerd [@awarecan]: https://github.com/awarecan [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@beavis9k]: https://github.com/beavis9k [@c-soft]: https://github.com/c-soft [@cgtobi]: https://github.com/cgtobi [@chilicheech]: https://github.com/chilicheech [@cisasteelersfan]: https://github.com/cisasteelersfan [@cmsimike]: https://github.com/cmsimike [@cpopp]: https://github.com/cpopp [@danielperna84]: https://github.com/danielperna84 [@dgomes]: https://github.com/dgomes [@dmulcahey]: https://github.com/dmulcahey [@dshokouhi]: https://github.com/dshokouhi [@ehendrix23]: https://github.com/ehendrix23 [@emontnemery]: https://github.com/emontnemery [@endor-force]: https://github.com/endor-force [@engrbm87]: https://github.com/engrbm87 [@epleypa]: https://github.com/epleypa [@fabaff]: https://github.com/fabaff [@fbradyirl]: https://github.com/fbradyirl [@frenck]: https://github.com/frenck [@gertdb]: https://github.com/gertdb [@heythisisnate]: https://github.com/heythisisnate [@hunterjm]: https://github.com/hunterjm [@isabellaalstrom]: https://github.com/isabellaalstrom [@josemotta]: https://github.com/josemotta [@kbickar]: https://github.com/kbickar [@kennedyshead]: https://github.com/kennedyshead [@koolsb]: https://github.com/koolsb [@ktnrg45]: https://github.com/ktnrg45 [@ljmerza]: https://github.com/ljmerza [@ludeeus]: https://github.com/ludeeus [@marvin-w]: https://github.com/marvin-w [@michaelarnauts]: https://github.com/michaelarnauts [@msvinth]: https://github.com/msvinth [@mw-white]: https://github.com/mw-white [@ndonegan]: https://github.com/ndonegan [@nickw444]: https://github.com/nickw444 [@nudded]: https://github.com/nudded [@nugget]: https://github.com/nugget [@pavoni]: https://github.com/pavoni [@philhawthorne]: https://github.com/philhawthorne [@piitaya]: https://github.com/piitaya [@pnbruckner]: https://github.com/pnbruckner [@pvizeli]: https://github.com/pvizeli [@rbdixon]: https://github.com/rbdixon [@robbiet480]: https://github.com/robbiet480 [@roblandry]: https://github.com/roblandry [@rohankapoorcom]: https://github.com/rohankapoorcom [@scop]: https://github.com/scop [@shanbs]: https://github.com/shanbs [@srirams]: https://github.com/srirams [@thibmaek]: https://github.com/thibmaek [@trunet]: https://github.com/trunet [@ttroy50]: https://github.com/ttroy50 [@u1f35c]: https://github.com/u1f35c [@uchagani]: https://github.com/uchagani [@w1ll1am23]: https://github.com/w1ll1am23 [@wburgers]: https://github.com/wburgers [@webdjoe]: https://github.com/webdjoe [@zeehio]: https://github.com/zeehio [@zemerick1]: https://github.com/zemerick1 [@zewelor]: https://github.com/zewelor [air_quality docs]: /integrations/air_quality/ [alarm_control_panel.manual_mqtt docs]: /integrations/manual_mqtt/ [alarm_control_panel.MQTT docs]: /integrations/alarm_control_panel.MQTT/ [alarmdecoder docs]: /integrations/alarmdecoder/ [alert docs]: /integrations/alert/ [alexa docs]: /integrations/alexa/ [ambient_station docs]: /integrations/ambient_station/ [amcrest docs]: /integrations/amcrest/ [androidtv docs]: /integrations/androidtv/ [api docs]: /integrations/api/ [asuswrt docs]: /integrations/asuswrt/ [auth docs]: /integrations/auth/ [自动化 docs]: /integrations/自动化/ [自动化.MQTT docs]: /docs/自动化/触发器/#MQTT-触发器 [binary_sensor.trend docs]: /integrations/trend [binary_sensor.workday docs]: /integrations/workday [摄像头 docs]: /integrations/摄像头/ [摄像头.ffmpeg docs]: /integrations/摄像头.ffmpeg/ [摄像头.generic docs]: /integrations/generic_ip_camera [摄像头.onvif docs]: /integrations/onvif [摄像头.proxy docs]: /integrations/proxy [摄像头.xeoma docs]: /integrations/xeoma [cast docs]: /integrations/cast/ [cisco_mobility_express docs]: /integrations/cisco_mobility_express/ [温控.ephember docs]: /integrations/ephember [温控.eq3btsmart docs]: /integrations/eq3btsmart [温控.honeywell docs]: /integrations/honeywell [温控.netatmo docs]: /integrations/netatmo#温控 [cloud docs]: /integrations/cloud/ [config docs]: /integrations/config/ [default_config docs]: /integrations/default_config/ [device_tracker docs]: /integrations/device_tracker/ [emulated_hue docs]: /integrations/emulated_hue/ [enigma2 docs]: /integrations/enigma2/ [前端 docs]: /integrations/frontend/ [google_assistant docs]: /integrations/google_assistant/ [group docs]: /integrations/group/ [hassio docs]: /integrations/hassio/ [homekit_controller docs]: /integrations/homekit_controller/ [homematic docs]: /integrations/homematic/ [homematicip_cloud docs]: /integrations/homematicip_cloud/ [http docs]: /integrations/http/ [huawei_lte docs]: /integrations/huawei_lte/ [ifttt docs]: /integrations/ifttt/ [ihc docs]: /integrations/ihc/ [image_processing docs]: /integrations/image_processing/ [image_processing.opencv docs]: /integrations/opencv [image_processing.tensorflow docs]: /integrations/tensorflow [knx docs]: /integrations/knx/ [konnected docs]: /integrations/konnected/ [lametric docs]: /integrations/lametric/ [lifx docs]: /integrations/lifx/ [灯光 docs]: /integrations/灯光/ [灯光.flux_led docs]: /integrations/flux_led [灯光.ihc docs]: /integrations/ihc#灯光 [灯光.mystrom docs]: /integrations/mystrom#灯光 [灯光.nanoleaf docs]: /integrations/nanoleaf [logbook docs]: /integrations/logbook/ [lutron docs]: /integrations/lutron/ [media_extractor docs]: /integrations/media_extractor/ [媒体播放器.anthemav docs]: /integrations/anthemav [媒体播放器.dlna_dmr docs]: /integrations/dlna_dmr [媒体播放器.enigma2 docs]: /integrations/enigma2 [媒体播放器.firetv docs]: /integrations/androidtv [mobile_app docs]: /integrations/mobile_app/ [modbus docs]: /integrations/modbus/ [MQTT docs]: /integrations/MQTT/ [mqtt_eventstream docs]: /integrations/mqtt_eventstream/ [ness_alarm docs]: /integrations/ness_alarm/ [netatmo docs]: /integrations/netatmo/ [通知 docs]: /integrations/通知/ [通知.sendgrid docs]: /integrations/sendgrid [onboarding docs]: /integrations/onboarding/ [openuv docs]: /integrations/openuv/ [owntracks docs]: /integrations/owntracks/ [ps4 docs]: /integrations/ps4/ [rainmachine docs]: /integrations/rainmachine/ [遥控器 docs]: /integrations/遥控器/ [遥控器.harmony docs]: /integrations/harmony [satel_integra docs]: /integrations/satel_integra/ [场景 docs]: /integrations/场景/ [脚本 docs]: /integrations/脚本/ [sense docs]: /integrations/sense/ [传感器.arwn docs]: /integrations/arwn [传感器.deutsche_bahn docs]: /integrations/deutsche_bahn [传感器.discogs docs]: /integrations/discogs [传感器.dsmr docs]: /integrations/dsmr [传感器.flunearyou docs]: /integrations/flunearyou [传感器.loopenergy docs]: /integrations/loopenergy [传感器.mqtt_room docs]: /integrations/mqtt_room [传感器.netdata docs]: /integrations/netdata [传感器.nmbs docs]: /integrations/nmbs [传感器.pollen docs]: /integrations/iqvia [传感器.seventeentrack docs]: /integrations/seventeentrack [传感器.starlingbank docs]: /integrations/starlingbank [传感器.synologydsm docs]: /integrations/synologydsm [传感器.systemmonitor docs]: /integrations/systemmonitor [传感器.waze_travel_time docs]: /integrations/waze_travel_time [传感器.whois docs]: /integrations/whois [smartthings docs]: /integrations/smartthings/ [snips docs]: /integrations/snips/ [sonos docs]: /integrations/sonos/ [stream docs]: /integrations/stream/ [开关.mystrom docs]: /integrations/mystrom#开关 [开关.vesync docs]: /integrations/vesync#开关 [tado docs]: /integrations/tado/ [tellstick docs]: /integrations/tellstick/ [tesla docs]: /integrations/tesla/ [tof docs]: /integrations/tof/ [toon docs]: /integrations/toon/ [totalconnect docs]: /integrations/totalconnect/ [tplink docs]: /integrations/tplink/ [tts docs]: /integrations/tts/ [utility_meter docs]: /integrations/utility_meter/ [velbus docs]: /integrations/velbus/ [velux docs]: /integrations/velux/ [water_heater docs]: /integrations/water_heater/ [websocket_api docs]: /integrations/websocket_api/ [zeroconf docs]: /integrations/zeroconf/ [zha docs]: /integrations/zha/ [zwave docs]: /integrations/zwave/ --- url: /home-assistant/blog/2019-04-01-android.md --- # 官方 Home Assistant Android 应用到底什么时候来??? 1 年 11 个月 17 天前,也就是 716 天前,我在这个[博客](/home-assistant/blog/2017/04/15/ios/)上宣布了 Home Assistant Companion for iOS。 从那以后,至少每周一次,有时甚至频繁得多,我都会被问到一个直到今天才终于能真正回答的问题。 这个问题几乎每次出现都会让我有点抓狂。我能理解,为什么大家想要一款能够与 iOS 应用功能对应的官方 Android 应用。 但我从来不觉得自己会是最适合把这个想法变成现实的人。 最近,这类请求的声音已经大到震耳欲聋,而我也受够了。快两年过去了,官方应用依然没有出现。现在是我出手的时候了。 于是我买了一台 Pixel 3,重新投入 Android 的世界。自从用过 Nexus 5 之后,这些年我几乎没怎么真正使用过 Android。它变化很大,而且在我看来是变得更好了。 我知道我能做到这件事。我以前已经做过一次。这意味着我要学习一门新语言 Kotlin,但我当初为了开发 iOS 应用学了 Swift,而结果也相当不错。 所以现在,我在这里正式向大家宣布:官方的 Home Assistant Companion for Android 即将开始开发。 我会尽量复刻 iOS 应用当初的时间线,不过初期各版本之间的间隔会更短一些。1.0 版本将包含三个核心功能: 1. 可与 iOS 应用媲美的位置引擎。这意味着无论你在外出途中,还是进入特定区域,都能获得位置更新。 2. 目标是做到和 iOS 一样强大的推送通知。动作和声音会优先加入,之后我希望还能加入嵌入式内容,比如摄像头画面和地图。不再需要 HTML5 通知。 3. 一个全屏展示精美 Web UI 的视图,也就是 Paulus 和其他人打造的那个界面。没错,至少目前不会有原生 UI。 从长期来看,我希望 Android 也能提供和 iOS 相近的功能集。这意味着 Android Wear 支持、传感器,以及小部件。 如果你是正在阅读这篇文章的 iOS 用户,也不用担心。下面是我目前规划的时间线: * 2019 年 4 月 1 日:宣布 Android 应用 * 不晚于 2019 年 4 月 31 日:向 App Store 发布 iOS 2.0 * 2019 年初夏到仲夏:发布 Android 应用首个测试版 * 2019 年仲夏到夏末:向 Play Store 发布 Android 应用 1.0 * 2019 年夏末到初秋:把 iOS 13 的新功能带入 iOS 应用,发布 2.5 版本 我已经先在 Home Assistant 本体中打下了基础,实现了极其出色的 `mobile_app` 组件,为移动应用提供了一个非常安全且功能丰富的集成系统。 现在,我想花一点时间谈谈房间里的那头大象:对于那些在官方应用长期缺席期间出现、用来填补空白的其他 Android 应用,我们会怎么做?答案是,不会怎么样。 第三方应用的作者依然可以继续构建他们的应用,并带来把手机与 Home Assistant 结合起来的创新功能。他们同样可以利用我们为他们打下的基础:`mobile_app` 组件。 这些应用是我们生态系统的一部分,我们无意把它们排挤出去,而是希望拥抱它们。它们能做得越好,我们的用户就拥有越多选择,这对整个 Home Assistant 生态系统来说都会更好。 你也许会想,除了前面提到的那些持续不断的问题之外,我们为什么现在才决定这样做。原因是,最近我们发现越来越多应用做出了令人担忧的集成选择,甚至出现了相当可怕的安全决策。 此外,Home Assistant 将始终保持免费,而隐私也是我们使命中的关键部分。正因为这个核心理念,我们不愿看到 Home Assistant 移动应用里出现广告,因为过往已经证明,这类做法往往并不在乎你的隐私,有些情况下甚至相当危险。 我们希望提供一个功能完整、开源,并且真正重视你隐私的解决方案。 就是这样。这就是 74.15% 的你一直在等待的应用。它很快就会来到你身边的 Play Store。你也会很快通过这个博客、Twitter、Facebook、Discord 等渠道,听到并看到它的开发进展。 最后,我也想公开为自己的 [Patreon](https://patreon.com/robbiet480) 做个小小宣传,希望它很快能让我在 2019 年余下时间里,把 100% 的精力都投入到 Home Assistant 上。 这意味着可以全职投入 iOS、Android,以及更多有趣的东西。提前感谢你一直以来的支持。 --- url: /home-assistant/blog/2019-04-03-release-91.md --- # 0.91:更多流媒体、更好的 Zigbee、ESPHome 摄像头 0.91 发布来了,而这次发布的核心主题就是摄像头流媒体。Home Assistant 0.90 已经允许用户在前端播放摄像头流,也能把摄像头画面投到 Chromecast 上。本次发布新增支持: * 通过摄像头集成新增的录制服务,将摄像头流保存到磁盘 * 支持通过 Google Assistant 让你的摄像头画面显示在智能屏幕或 Chromecast 上 * 支持预加载流媒体,让设备打开视频流时几乎瞬间完成;这可以在每个摄像头的更多信息对话框中单独配置 Thanks to [@hunterjm] for all this work on this! ❤️ Check the latest 发布 of the [Home Assistant podcast](https://hasspodcast.io/home-assistant-podcast-47-0-91-and-streaming-摄像头-everywhere-with-jason/) for an interview with [@hunterjm] about streams in Home Assistant. 我们仍在持续更新更多摄像头集成,以支持 stream 组件。如果你今天就想试用,最简单的方式是配置一个带 `stream_source` 的 [generic 摄像头][generic docs],或者购买一台支持标准 ONVIF 协议的摄像头。 还要特别感谢 [@awarecan],他把我们的 CI 基础设施迁移到了 [CircleCI](https://www.circleci.com) 和 [Codecov](https://codecov.io/)。CircleCI 的高级缓存和代码拆分控制显著加快了测试速度,而 Codecov 会跟踪代码覆盖率,并为每次贡献生成详细报告,以查看测试覆盖情况。 如果你错过了公告,我们也即将开始着手开发[官方 Android 应用](/home-assistant/blog/2019/04/01/android/)。另外,如果你还不确定,我们此前说会[偶尔在 UI 中展示广告](https://twitter.com/home_assistant/status/1112752645763223552) 的那条消息,其实只是愚人节玩笑 😁。 ## 值得注意的破坏性变更 我们已经完成了这次大迁移。所有内置平台现在都位于各自独立的文件夹中。这意味着,如果你的自定义组件或平台与内置组件同名,就必须重命名。如果你的 `custom_components/` 目录中仍保留旧格式的平台文件,比如 `sensor/my_platform.py`,请把它改成 `my_platform/sensor.py`。目前它仍然可用,但未来版本将不再支持。 Thanks to [@Swamp-Ig], [@robbiet480] and [@cgtobi] for their work on this! ## Trusted networks 现已支持受信任用户 [@awarecan] 更新了 trusted networks,现在可以指定特定 IP 地址允许登录哪些用户。如果某个用户通过 trusted networks 登录,且系统中只有一个用户,你现在还可以配置为跳过登录表单并自动登录。更多信息请查看[文档](/home-assistant/docs/authentication/providers/index.md#trusted-networks)。 ## ESPHome 摄像头 This 发布 adds 摄像头 support to the ESPHome 集成. If you haven't heard about [ESPHome](https://www.esphome.io) yet, it allows you to create your own 传感器 and smart 设备 and 配置 them using YAML. With Home Assistant 0.91, it is now possible to integrate 摄像头. This means that you can have a WiFi enabled 摄像头 that integrates automatically into Home Assistant for as little as $9 😲. Check this cool demo, part of [this 博客 post](https://www.dopebuild.com/i-am-sorry-dave-i-am-unable-to-do-that/):
## Zigbee ZHA 配对体验 在 [@dmulcahey]、[@damarco] 和 [@Adminiuga] 的努力下,我们的 Zigbee 集成每个版本都在进步。本次发布带来了全新的配对体验。启用配对模式后,任何正在加入的设备都会立刻显示出来,让用户可以马上配置名称和区域。
## VSCode Hass.io 插件 If you run hass.io on an Intel NUC and haven't seen it yet, check out the VS Code 插件 by Frenck. ## 新平台 * Add LCN 传感器 platform ([@alengwenus] - [#21440]) ([lcn docs]) (new-platform) * Add ESPHome 摄像头 ([@OttoWinter] - [#22107]) ([esphome docs]) (new-platform) * Add Freebox 开关 platform ([@SNoof85] - [#21710]) ([freebox docs]) (new-platform) * Add support for Tfiac 温控 component ([@fredrike] - [#21823]) ([tfiac docs]) (new-platform) * Add 开关 to control Daikin Airbase 区域 ([@fredrike] - [#22417]) ([daikin docs]) (new-platform) ## 发布 0.91.1 - April 4 * Change URL handling ([@pvizeli] - [#22713]) ([hassio docs]) * fix 设备 class lookup for 二元sensor ([@dmulcahey] - [#22724]) ([zha docs]) * Fix ingress routing with / ([@pvizeli] - [#22728]) ([hassio docs]) * Fix chunk streaming ([@pvizeli] - [#22730]) ([hassio docs]) * Fix incorrect "Unavailable" Ambient 传感器 ([@bachya] - [#22734]) ([ambient\_station docs][ambient_station docs]) * Bump aioambient to 0.2.0 ([@bachya] - [#22736]) ([ambient\_station docs][ambient_station docs]) * 更新 Foscam stream for newer models ([@cwhits] - [#22744]) ([foscam docs]) * use the input stream codec as the 模板 for the output streams ([@hunterjm] - [#22747]) ([stream docs]) * fixes 配置 flow #22706 ([@fredrike] - [#22754]) ([daikin docs]) [#22713]: https://github.com/home-assistant/home-assistant/pull/22713 [#22724]: https://github.com/home-assistant/home-assistant/pull/22724 [#22728]: https://github.com/home-assistant/home-assistant/pull/22728 [#22730]: https://github.com/home-assistant/home-assistant/pull/22730 [#22734]: https://github.com/home-assistant/home-assistant/pull/22734 [#22736]: https://github.com/home-assistant/home-assistant/pull/22736 [#22744]: https://github.com/home-assistant/home-assistant/pull/22744 [#22747]: https://github.com/home-assistant/home-assistant/pull/22747 [#22754]: https://github.com/home-assistant/home-assistant/pull/22754 [@bachya]: https://github.com/bachya [@cwhits]: https://github.com/cwhits [@dmulcahey]: https://github.com/dmulcahey [@fredrike]: https://github.com/fredrike [@hunterjm]: https://github.com/hunterjm [@pvizeli]: https://github.com/pvizeli [ambient_station docs]: /integrations/ambient_station/ [daikin docs]: /integrations/daikin/ [foscam docs]: /integrations/foscam/ [hassio docs]: /integrations/hassio/ [stream docs]: /integrations/stream/ [zha docs]: /integrations/zha/ ## 发布 0.91.2 - April 8 * Correctly load Mopar's config ([@rohankapoorcom] - [#22771]) * Fix konnected unique\_id computation for 开关 ([@heythisisnate] - [#22777]) ([konnected docs]) (breaking change) * make the custom polling actually request 状态 ([@dmulcahey] - [#22778]) ([zha docs]) * ZHA 灯光 调试 logging. ([@Adminiuga] - [#22776]) ([zha docs]) * Fix tado 打开 off ([@wmalgadey] - [#22291]) ([tado docs]) * Add new mobile\_app Webhook command: get\_zones ([@robbiet480] - [#22604]) ([mobile\_app docs][mobile_app docs]) * Add optional rtsp\_port for Foscam ([@cwhits] - [#22786]) ([foscam docs]) * Improve yeelight imports ([@zewelor] - [#22804]) ([yeelight docs]) * Add a new mobile\_app Webhook command to get config ([@robbiet480] - [#22813]) ([mobile\_app docs][mobile_app docs]) * Fix for optional values in the update\_location Webhook call ([@robbiet480] - [#22817]) ([mobile\_app docs][mobile_app docs]) * coerce duration and lookback to int so they can be used in 模板 自动化 ([@hunterjm] - [#22819]) ([摄像头 docs]) * Fix for rate limits should be optional ([@robbiet480] - [#22823]) ([mobile\_app docs][mobile_app docs]) * Use relative imports in yeelight ([@zewelor] - [#22839]) ([yeelight docs]) * Fix yeelight possible array change during iteration ([@zewelor] - [#22849]) ([yeelight docs]) * Fix content\_type handling ingress ([@pvizeli] - [#22864]) ([hassio docs]) * Improve mobile\_app 传感器 responses and expected values ([@robbiet480] - [#22884]) ([mobile\_app docs][mobile_app docs]) [#22291]: https://github.com/home-assistant/home-assistant/pull/22291 [#22604]: https://github.com/home-assistant/home-assistant/pull/22604 [#22771]: https://github.com/home-assistant/home-assistant/pull/22771 [#22776]: https://github.com/home-assistant/home-assistant/pull/22776 [#22777]: https://github.com/home-assistant/home-assistant/pull/22777 [#22778]: https://github.com/home-assistant/home-assistant/pull/22778 [#22786]: https://github.com/home-assistant/home-assistant/pull/22786 [#22804]: https://github.com/home-assistant/home-assistant/pull/22804 [#22813]: https://github.com/home-assistant/home-assistant/pull/22813 [#22817]: https://github.com/home-assistant/home-assistant/pull/22817 [#22819]: https://github.com/home-assistant/home-assistant/pull/22819 [#22823]: https://github.com/home-assistant/home-assistant/pull/22823 [#22839]: https://github.com/home-assistant/home-assistant/pull/22839 [#22849]: https://github.com/home-assistant/home-assistant/pull/22849 [#22864]: https://github.com/home-assistant/home-assistant/pull/22864 [#22884]: https://github.com/home-assistant/home-assistant/pull/22884 [@Adminiuga]: https://github.com/Adminiuga [@cwhits]: https://github.com/cwhits [@dmulcahey]: https://github.com/dmulcahey [@heythisisnate]: https://github.com/heythisisnate [@hunterjm]: https://github.com/hunterjm [@pvizeli]: https://github.com/pvizeli [@robbiet480]: https://github.com/robbiet480 [@rohankapoorcom]: https://github.com/rohankapoorcom [@wmalgadey]: https://github.com/wmalgadey [@zewelor]: https://github.com/zewelor [摄像头 docs]: /integrations/摄像头/ [foscam docs]: /integrations/foscam/ [hassio docs]: /integrations/hassio/ [konnected docs]: /integrations/konnected/ [mobile_app docs]: /integrations/mobile_app/ [tado docs]: /integrations/tado/ [yeelight docs]: /integrations/yeelight/ [zha docs]: /integrations/zha/ ## 发布 0.91.3 - April 10 * Fix position of add\_entities of 二元sensor ([@AZDane] - [#22866]) ([concord232 docs]) * More Mobile app 传感器 fixes ([@robbiet480] - [#22914]) ([mobile\_app docs][mobile_app docs]) * Add cloudhook and 遥控器 UI vals to get\_config ([@robbiet480] - [#22921]) ([mobile\_app docs][mobile_app docs]) * Bugfix: pass protocol out of header to application layer ([@pvizeli] - [#22955]) ([hassio docs]) [#22866]: https://github.com/home-assistant/home-assistant/pull/22866 [#22914]: https://github.com/home-assistant/home-assistant/pull/22914 [#22921]: https://github.com/home-assistant/home-assistant/pull/22921 [#22955]: https://github.com/home-assistant/home-assistant/pull/22955 [@AZDane]: https://github.com/AZDane [@pvizeli]: https://github.com/pvizeli [@robbiet480]: https://github.com/robbiet480 [concord232 docs]: /integrations/concord232/ [hassio docs]: /integrations/hassio/ [mobile_app docs]: /integrations/mobile_app/ ## 发布 0.91.4 - April 16 * Fix ingress bug with Firefox ([@pvizeli] - [#23121]) ([hassio docs]) ([http docs]) [#23121]: https://github.com/home-assistant/home-assistant/pull/23121 [@pvizeli]: https://github.com/pvizeli [hassio docs]: /integrations/hassio/ [http docs]: /integrations/http/ ## 如果你需要帮助…… 欢迎使用我们非常活跃的[论坛](https://community.home-assistant.io/),或者加入我们的[聊天频道](https://discord.gg/c5DvZ4e)。虽然发布说明开放评论,但我们更希望你使用前面这些沟通渠道。谢谢。 ## 反馈问题 如果你遇到了这个版本引入的问题,请在我们的 [issue tracker](https://github.com/home-assistant/home-assistant/issues) 中报告。请务必填写 issue 模板中的所有字段。 ## 向后不兼容的变更 * **Z-Wave** - The usb\_path in 配置.yaml now overrides config entry usb\_path. This is potentially a breaking change if people have a stale usb\_path setting in 配置.yaml that's no longer accurate. This should help reduce the number of people that need to manually edit the storage/核心.config\_entries file if their usb\_path changes. ([@cgarwood] - [#22038]) ([zwave docs]) * **iOS** - Improves the text description of ATTR\_BATTERY\_STATE\_UNPLUGGED from Unplugged to Not Charging as many new iOS 设备 now use Wireless charging and there is no concept of "Plugging In". This is potentially a breaking change if you have 自动化 making use of "unplugged". ([@FattusMannus] - [#22152]) ([ios docs]) * **Iliad Italy** - **Removed** - This was removed because it uses webscraping. ([@eliseomartelli] - [#22175]) * **Netgear lte** - The previous three components (network, 通知, and 传感器) now fall under one netgear\_lte component. Check the [updated 文档](/home-assistant/integrations/netgear_lte/index.md) 更多信息. ([@amelchio] - [#22105]) ([netgear\_lte docs][netgear_lte docs]) * **API streams sensor** - **Removed** - This 传感器 component was designed to count connected front-end clients. However, it depended on the implementation details of other components, and has therefore been broken since 0.80, so it has been removed. The replacement 传感器 is now the [websocket\_api 传感器](/home-assistant/integrations/websocket_api/index.md), which does basically the same thing apart from the rename. ([@Swamp-Ig] - [#22200]) ([websocket\_api docs][websocket_api docs]) * **Public Transit (GTFS)** * The 状态 for this 传感器 component was a countdown in minutes. If the next departure was in a few hours, this number became quite large and a tad harder to rapidly calculate mentally (463 minutes anyone?). The 传感器's 状态 output has been changed from minutes to an ISO 8601 UTC timestamp, which allows the UI to interpret the 状态 as needed. ([@renemarc] - [#21053]) ([gtfs docs]) * 传感器 updates were running many database queries to populate 属性, on top of the bus schedule queries themselves. This is doubled with two 传感器. That led to a lot of slowdowns for everything else when using an SD 卡片! Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, now we fetch such metadata at first and then only when relevant changes do occur. GTFS 传感器 属性 are now named using the standard snake\_case format. ([@renemarc] - [#20966]) ([gtfs docs]) * **Yeelight** - This is now its own component and has been broken out from the 灯光 platform. More Yeelights are being released with more features and this will make if possible to support them. Examples would be adding 传感器 for a ceiling 灯光, getting the current power mode (daylight/nightlight), or supporting 开关 to turn moonlight on or off without having to use a 服务 call. Make sure to visit the updated 文档. ([@zewelor] - [#21593]) ([yeelight docs]) * **Axis** - Events supplied from component might differ. Events will not be configurable in the beginning but will instead provide a subset set of events supported per 设备. This will be configurable in a later stage when config entry options are available. 配置.yaml support for Axis component will be removed in the future so make sure to remove references to Axis component after 升级. ([@Kane610] - [#18543]) ([axis docs]) * **HTTP** - Lower severity level of 日志 messages from http.view ([@thomasloven] - [#21091]) ([http docs]) * **Dark Sky** - Dark Sky provides hourly forecasts for various monitored 条件. This change creates new 传感器 for each hourly forecasted 条件 with suffix `_h` while adding the suffix `_d` to the daily forecasted 条件. For example, now a `sensor.dark_sky_summary_d` and `sensor.dark_sky_summary_h` will be 创建 if the forecast and hourly\_forecast parameters are populated. ([@rtclauss] - [#21820]) ([darksky docs]) * **Konnected** - This will change the internal unique\_id for Konnected 开关 (i.e., 警报器, buzzer, generic 开关). 用户 will need to manually remove the orphaned 开关 实体 from the 实体 registry after updating and re-配置 any changes stored in the 实体 registry (i.e., name and entity\_id), as their unique IDs will change. ([@heythisisnate] - [#22389]) ([konnected docs]) * **Mopar** - The mopar 传感器 platform has been broken up into a base component with 传感器, 开关, and 门锁 platforms. The 传感器.mopar\_remote\_command 服务 has been removed since the functionality has been folded into the new platforms and the new mopar.sound\_horn 服务. Please view the 文档 to see the new 设置 instructions. ([@rohankapoorcom] - [#21526]) ## Beta 修复 * Fix regression of the xiaomi\_aqara config validation ([@syssi] - [#22435]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) (breaking change) (beta fix) * Fix dev branch ([@awarecan] - [#22493]) ([homekit\_controller docs][homekit_controller docs]) (beta fix) * 更新 pyotgw to 0.4b3 ([@mvn23] - [#22496]) ([opentherm\_gw docs][opentherm_gw docs]) (beta fix) * Fixes for yeelight availbility 状态 ([@zewelor] - [#22502]) ([yeelight docs]) (beta fix) * Remove botocore dependency from credstash 脚本 ([@awarecan] - [#22511]) (beta fix) * Fix lint on dev ([@awarecan] - [#22512]) (beta fix) * Do not use zha default 灯光 polling ([@dmulcahey] - [#22513]) ([zha docs]) (beta fix) * PS4 bump to 0.5.2 ([@ktnrg45] - [#22523]) ([ps4 docs]) (beta fix) * clean up channel 配置 ([@dmulcahey] - [#22534]) ([zha docs]) (beta fix) * Fix tts Great Migration issue ([@awarecan] - [#22539]) ([amazon\_polly docs][amazon_polly docs]) ([baidu docs]) ([marytts docs]) ([microsoft docs]) ([picotts docs]) ([voicerss docs]) ([yandextts docs]) (beta fix) * 升级 to async\_upnp\_client==0.14.7 ([@StevenLooman] - [#22543]) ([dlna\_dmr docs][dlna_dmr docs]) ([upnp docs]) (beta fix) * Bump zigpy ([@damarco] - [#22545]) ([zha docs]) (beta fix) * Add support for streaming to ffmpeg ([@balloob] - [#22549]) ([ffmpeg docs]) (beta fix) * Fix platform 警告 ([@balloob] - [#22551]) (beta fix) * Google assistant: add blinds trait for 遮盖 ([@giefca] - [#22336]) ([google\_assistant docs][google_assistant docs]) (breaking change) (beta fix) * 更新 Amcrest component to SUPPORT\_STREAM ([@drjared88] - [#22553]) ([amcrest docs]) (beta fix) * Fix name conflict in tests ([@awarecan] - [#22556]) (beta fix) * 更新 ONVIF component to SUPPORT\_STREAM ([@drjared88] - [#22569]) ([onvif docs]) (beta fix) * Add stream to the default config ([@balloob] - [#22602]) ([default\_config docs][default_config docs]) (beta fix) * Add trusted networks deprecating 警告 ([@awarecan] - [#22487]) ([http docs]) (beta fix) * Hass.io ingress ([@pvizeli] - [#22505]) ([hassio docs]) (beta fix) * 更新 Foscam component to support stream source ([@cwhits] - [#22568]) ([foscam docs]) (beta fix) * 更新 face\_recognition to 1.2.3 ([@pvizeli] - [#22622]) ([dlib\_face\_detect docs][dlib_face_detect docs]) ([dlib\_face\_identify docs][dlib_face_identify docs]) (beta fix) * Disable Z-Wave autoheal ([@balloob] - [#22628]) ([zwave docs]) (beta fix) * Handle disonnect bug in Tibber library ([@Danielhiversen] - [#22629]) ([tibber docs]) (beta fix) * Support GET params for websocket ingress path ([@pvizeli] - [#22638]) ([hassio docs]) (beta fix) * Return 0 for failed Foscam streams ([@cwhits] - [#22651]) ([foscam docs]) (beta fix) * Fix racy homekit\_controller platform 设置 caused by #22368 ([@Jc2k] - [#22655]) ([homekit\_controller docs][homekit_controller docs]) (beta fix) ## 所有变更 * Add sense guard clause ([@kbickar] - [#22014]) ([sense docs]) * 升级 prefetched tox env to py37 ([@awarecan] - [#22029]) * change logging to 调试 for nmap ([@Danielhiversen] - [#22036]) * Refactor ZHA gateway into modules and add admin protections to API ([@dmulcahey] - [#22023]) ([zha docs]) (new-platform) * Ps4 remove throttling ([@ktnrg45] - [#21961]) ([ps4 docs]) * 升级 youtube\_dl to 2019.03.09 ([@fabaff] - [#22041]) ([media\_extractor docs][media_extractor docs]) * Async support for Daikin ([@fredrike] - [#21638]) ([daikin docs]) * Bump amcrest to 1.2.6 & use new exceptions ([@pnbruckner] - [#22040]) ([amcrest docs]) * Z-Wave usb\_path in 配置.yaml overrides config entry usb\_path ([@cgarwood] - [#22038]) ([zwave docs]) (breaking change) * Minor ZHA consts fixes ([@Adminiuga] - [#22049]) ([zha docs]) * Cleanup remaining constants stuff in ZHA ([@dmulcahey] - [#22050]) ([zha docs]) * Add HTTP auth and SSL verification to REST 通知 ([@escoand] - [#22016]) ([rest docs]) * 升级 ruamel.yaml to 0.15.89 ([@fabaff] - [#22064]) * 更新 rest.py ([@isabellaalstrom] - [#22077]) ([通知 docs]) * Telegram\_bot: Allow fetching data from unverified SSL endpoints (#22067) ([@nbarrientos] - [#22069]) ([telegram\_bot docs][telegram_bot docs]) * Add LCN 传感器 platform ([@alengwenus] - [#21440]) ([lcn docs]) (new-platform) * 升级 pytest to 4.3.1 ([@scop] - [#22088]) * Bump amcrest to 1.2.7 for correct RTSP port ([@pnbruckner] - [#22099]) ([amcrest docs]) * Add available property to Ambient PWS ([@bachya] - [#22092]) ([ambient\_station docs][ambient_station docs]) * Restricted temperature units for Celsius and Fahrenheit to the standardized units ([@alengwenus] - [#22108]) ([lcn docs]) * Consolidate all platforms that have no tests ([@balloob] - [#22096]) * Add ESPHome 摄像头 ([@OttoWinter] - [#22107]) ([esphome docs]) (new-platform) * Tibber, Add price level ([@Danielhiversen] - [#22085]) ([tibber docs]) * Fix AttributeError traceback with darksky ([@iamtpage] - [#22101]) ([darksky docs]) * Add 服务 description for 服务. ([@cgtobi] - [#21897]) * Handle occasional 502 Bad Gateway from SimpliSafe ([@bachya] - [#22131]) ([simplisafe docs]) * Loosen field retrieval from Pollen.com ([@bachya] - [#22132]) ([pollen docs]) * Handle possible exception during Ambient PWS reconnect ([@bachya] - [#22134]) ([ambient\_station docs][ambient_station docs]) * Additional 传感器 and fixed icons, 属性 and 设备 classes. ([@endor-force] - [#22139]) ([trafikverket\_weatherstation docs][trafikverket_weatherstation docs]) * Fix hlk-sw16 inverted 开关 状态 ([@jameshilliard] - [#22059]) ([hlk\_sw16 docs][hlk_sw16 docs]) * replace einder lib with horimote ([@benleb] - [#22135]) ([horizon docs]) * Fixx yeelight flow 动作 param for declared effects ([@zewelor] - [#22159]) ([yeelight docs]) * Add dynamic subscription for ZHA add 设备 page ([@dmulcahey] - [#22164]) ([zha docs]) * Consolidate all platforms that have tests ([@Swamp-Ig] - [#22109]) * Change ATTR\_BATTERY\_STATE\_UNPLUGGED for ios component ([@FattusMannus] - [#22152]) ([ios docs]) (breaking change) * Add some tests for Koogeek LS1 ([@Jc2k] - [#22141]) ([homekit\_controller docs][homekit_controller docs]) * Move platforms patch ([@Swamp-Ig] - [#22168]) ([mold\_indicator docs][mold_indicator docs]) ([moon docs]) * 恢复 实体 for switchbot ([@Danielhiversen] - [#22087]) ([switchbot docs]) * removed iliad ([@eliseomartelli] - [#22175]) (breaking change) * 升级 youtube\_dl to 2019.03.18 ([@fabaff] - [#22181]) ([media\_extractor docs][media_extractor docs]) * 升级 Sphinx to 1.8.5 ([@fabaff] - [#22180]) * Better handling of HomeKit accessory-information 服务 ([@Jc2k] - [#22171]) ([homekit\_controller docs][homekit_controller docs]) * Fix breaking on HTML email without 图像 ([@dagobert] - [#22143]) ([通知 docs]) * 更新 codeowners ([@oblogic7] - [#22198]) * 升级 psutil to 5.6.1 ([@fabaff] - [#22183]) ([systemmonitor docs]) * 升级 holidays to 0.9.10 ([@fabaff] - [#22182]) * Removed overly broad exception handling for nanoleaf 灯光 ([@Oro] - [#22189]) ([nanoleaf docs]) * Use relative imports inside 集成 ([@balloob] - [#22235]) * Make !include\_dir\_list use alphanumeric order ([@quentinsf] - [#21902]) * add date\_time\_iso to time\_date 传感器 ([@uchagani] - [#22199]) ([time\_date docs][time_date docs]) * Bump python-miio 版本 ([@syssi] - [#22202]) ([xiaomi\_miio docs][xiaomi_miio docs]) * 升级 to async\_upnp\_client==0.14.6 ([@StevenLooman] - [#22223]) ([dlna\_dmr docs][dlna_dmr docs]) ([upnp docs]) * Fix build issue ([@awarecan] - [#22251]) ([buienradar docs]) * add ZHA channel name property ([@Adminiuga] - [#22218]) ([zha docs]) * Handle on/off through TemperatrureSetting trait. ([@Swamp-Ig] - [#21842]) ([google\_assistant docs][google_assistant docs]) * Change .now() to .utcnow() ([@rdbahm] - [#22233]) ([season docs]) * 升级 tibber library, support solar production ([@Danielhiversen] - [#22261]) ([tibber docs]) * 升级 sqlalchemy to 1.3.0 ([@fabaff] - [#22269]) ([recorder docs]) ([sql docs]) * Plex: Avoid refreshing by both 设备 and session methods ([@jjlawren] - [#22266]) ([plex docs]) * Bump androidtv to 0.0.13 ([@JeffLIrion] - [#22279]) ([androidtv docs]) * Improved exception handling and logging ([@JeffLIrion] - [#22268]) ([androidtv docs]) * Consolidate the netgear\_lte 配置 ([@amelchio] - [#22105]) ([netgear\_lte docs][netgear_lte docs]) (breaking change) * Fixing the api\_streams 传感器 ([@Swamp-Ig] - [#22200]) ([websocket\_api docs][websocket_api docs]) (breaking change) * Fix progress for Plex 媒体播放器 ([@jjlawren] - [#22224]) ([plex docs]) * Add sort by config and tests for Reddit 集成 ([@ljmerza] - [#22081]) ([reddit docs]) * Fix Prometheus casting issues ([@robbiet480] - [#22282]) ([prometheus docs]) * 更新 trait to support auto without ranges. ([@Swamp-Ig] - [#21847]) ([google\_assistant docs][google_assistant docs]) * Sort code owners alphabetically ([@cgtobi] - [#22304]) * 更新 srpenergy library ([@robbiet480] - [#22307]) * 开关 from using Google Maps API for elevation to Open Elevation API ([@robbiet480] - [#22306]) * Fix for embedded MQTT server 配置 ([@robbiet480] - [#22305]) ([MQTT docs]) * 升级 pylast to 3.1.0 ([@fabaff] - [#22302]) ([lastfm docs]) * 升级 py-cpuinfo to 5.0.0 ([@fabaff] - [#22287]) * 更新 abbreviation ([@fabaff] - [#22317]) ([hp\_ilo docs][hp_ilo docs]) * Add homematicip cloud connection quality related 属性 ([@SukramJ] - [#21990]) ([homematicip\_cloud docs][homematicip_cloud docs]) * Add Freebox 开关 platform ([@SNoof85] - [#21710]) ([freebox docs]) (new-platform) * Google Assistant: Add 摄像头 stream trait ([@balloob] - [#22278]) ([摄像头 docs]) ([generic docs]) ([google\_assistant docs][google_assistant docs]) * Remove occupancy as it is not available in API ([@thibmaek] - [#22320]) ([nmbs docs]) * 更新 file header ([@fabaff] - [#22318]) ([hyperion docs]) * Consolidate more platforms ([@balloob] - [#22308]) ([demo docs]) ([generic\_thermostat docs][generic_thermostat docs]) ([group docs]) ([manual docs]) ([manual\_mqtt docs][manual_mqtt docs]) ([开关 docs]) * fix where PLATFORM\_SCHEMA gets pulled from ([@hunterjm] - [#22334]) ([familyhub docs]) * show which component is causing translation 错误 ([@uchagani] - [#22340]) * Define GTFS 传感器 as a timestamp 设备 class ([@renemarc] - [#21053]) ([gtfs docs]) (breaking change) * Move yeelight into component ([@zewelor] - [#21593]) ([discovery docs]) ([yeelight docs]) (breaking change) * Axis config flow ([@Kane610] - [#18543]) ([axis docs]) ([discovery docs]) (breaking change) * Fix pressure in dark sky and openweathermap and add pressure utility ([@MatthewFlamm] - [#21210]) ([darksky docs]) ([openweathermap docs]) * Fix xiaomi aqara cube with lumi.acpartner.v3 gateway ([@GuryYu] - [#22130]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * Support deCONZ library with exception handling ([@Kane610] - [#21952]) ([deconz docs]) * Do not warn when creating an empty database ([@amelchio] - [#22343]) ([recorder docs]) * Add color support to Philips Moonlight ([@syssi] - [#22204]) ([xiaomi\_miio docs][xiaomi_miio docs]) * Add support for the power socket of the Xiaomi AC Partner V3 ([@syssi] - [#22205]) * Set Onkyo reset 日志 to 调试 instead of info ([@robbiet480] - [#22369]) ([onkyo docs]) * 升级 netatmo smart\_home module ([@cgtobi] - [#22365]) ([netatmo docs]) * Fix the crash due to absence of the "default\_home" in HomeData from pyatmo (netatmo/温控) ([@shanbs] - [#22363]) ([netatmo docs]) * Add support for '图像' media type ([@StevenLooman] - [#22353]) ([dlna\_dmr docs][dlna_dmr docs]) ([媒体播放器 docs]) * Warn 用户 about HTML5 GCM deprecation ([@hmmbob] - [#22351]) ([通知 docs]) * Turn Panasonic Viera TV on without WOL ([@dilruacs] - [#22084]) ([panasonic\_viera docs][panasonic_viera docs]) * Properly connect 传感器 to hub ([@StevenLooman] - [#21414]) ([upnp docs]) * Add support for Tfiac 温控 component ([@fredrike] - [#21823]) ([tfiac docs]) (new-platform) * Add aws component and consolidate aws 通知 platform ([@awarecan] - [#22240]) ([aws docs]) * Check if mac is set when more than 2 gateways ([@karlkar] - [#21834]) * Add 'method' parameter to forgiving\_round method ([@Mofeywalker] - [#21708]) * Expose detailed Ecobee equipment status ([@nhorvath] - [#20767]) ([ecobee docs]) * Add ClickSend "caller" option ([@fabtesta] - [#20780]) ([通知 docs]) * Give HomeKit 门锁 better names by default ([@Jc2k] - [#22333]) ([homekit\_controller docs][homekit_controller docs]) * Improve yeelight component ([@zewelor] - [#22347]) ([yeelight docs]) * Improve PS4 media art fetching and config flow ([@ktnrg45] - [#22167]) ([ps4 docs]) * Allow for custom 打开/off commands ([@JeffLIrion] - [#22354]) ([androidtv docs]) * Remove unused const ([@Jc2k] - [#22383]) ([homekit\_controller docs][homekit_controller docs]) * 前端 indicate require admin ([@balloob] - [#22272]) ([config docs]) ([前端 docs]) ([hassio docs]) ([panel\_custom docs][panel_custom docs]) ([panel\_iframe docs][panel_iframe docs]) * Fix TpLink 设备 Tracker initialize 错误 ([@a005] - [#22349]) ([tplink docs]) * Add traccar events ([@lapy] - [#22348]) ([traccar docs]) * 更新 python yeelight and add nightlight mode 传感器 ([@zewelor] - [#22345]) ([discovery docs]) ([yeelight docs]) * updated pydaikin ([@fredrike] - [#22382]) ([daikin docs]) * Support for Plex 传感器 with enforced SSL ([@nmaggioni] - [#21432]) ([plex docs]) * Search GTFS departures across midnight ([@renemarc] - [#20992]) ([gtfs docs]) * remove config sections from hass.config.components ([@uchagani] - [#22370]) ([config docs]) * 更新 ring\_doorbell to 0.2.3 ([@dshokouhi] - [#22395]) ([ring docs]) * Fix unavailable 状态 for homekit 门锁 and 遮盖 ([@Jc2k] - [#22390]) ([homekit\_controller docs][homekit_controller docs]) * Add infer\_arming\_state option to ness 报警 ([@nickw444] - [#22379]) ([ness\_alarm docs][ness_alarm docs]) * deCONZ support Xiaomi vibration 传感器 ([@Kane610] - [#22366]) ([deconz docs]) * Fix data\_key of the xiaomi\_aqara 遮盖 for LAN protocol v2 ([@syssi] - [#22358]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * Remove get\_serial 助手 that is no longer needed. ([@Jc2k] - [#22368]) ([homekit\_controller docs][homekit_controller docs]) * Set default parallel\_update value should base on async\_update ([@awarecan] - [#22149]) * 摄像头 Preferences + Preload Stream ([@hunterjm] - [#22339]) ([摄像头 docs]) ([local\_file docs][local_file docs]) ([logi\_circle docs][logi_circle docs]) ([onvif docs]) ([push docs]) * Move 核心 stuff into Home Assistant 集成 ([@balloob] - [#22407]) ([config docs]) ([hassio docs]) ([homeassistant docs]) * Tibber add support for Watty ([@Danielhiversen] - [#22397]) ([tibber docs]) * zha fixes ([@dmulcahey] - [#22381]) ([zha docs]) * Fix yeelight 状态 更新 ([@zewelor] - [#22373]) ([yeelight docs]) * Changed busy 错误 to 警告 ([@fronzbot] - [#22398]) * Migrate tts ([@cgtobi] - [#22403]) * Add missing append ([@Jc2k] - [#22414]) ([homekit\_controller docs][homekit_controller docs]) * 更新 translate, fix dev build 错误 ([@awarecan] - [#22419]) ([axis docs]) ([ps4 docs]) ([tellduslive docs]) ([upnp docs]) ([zha docs]) * Use dispatcher for netgear\_lte 状态 updates ([@amelchio] - [#22328]) ([netgear\_lte docs][netgear_lte docs]) * ciscomobilityexpress pypi 版本 更新 ([@fbradyirl] - [#22431]) ([cisco\_mobility\_express docs][cisco_mobility_express docs]) * 更新 homeassistant-pyozw to 0.1.3 ([@pvizeli] - [#22433]) ([zwave docs]) * Adding conf for deep standby, wake and specific source bouquet of Enigma2 ([@fbradyirl] - [#22393]) ([enigma2 docs]) * Fix test name ([@balloob] - [#22421]) * Lower severity level of 日志 messages from http.view ([@thomasloven] - [#21091]) ([http docs]) (breaking change) * 更新 ha-ffmpeg 2.0 ([@pvizeli] - [#22427]) * Add myself as codeowner for yeelight component ([@zewelor] - [#22438]) * 更新 ZHA component CODEOWNERS ([@Adminiuga] - [#22452]) * Add support for yeelight ceiling ambilight ([@zewelor] - [#22346]) ([discovery docs]) ([yeelight docs]) * Bootstrap to start registry loading early ([@Swamp-Ig] - [#22321]) * Axis 设备 support 设备 registry ([@Kane610] - [#22367]) ([axis docs]) * Use voluptuous 错误 string for websocket validation 错误 ([@ljmerza] - [#21883]) ([websocket\_api docs][websocket_api docs]) * Add hourly forecasts to Dark Sky ([@rtclauss] - [#21820]) ([darksky docs]) (breaking change) * Add 开关 to control Daikin Airbase 区域 ([@fredrike] - [#22417]) ([daikin docs]) (new-platform) * better algorithm for computing unique\_id ([@heythisisnate] - [#22389]) ([konnected docs]) (breaking change) * Solaredge new 传感器 ([@GidoHakvoort] - [#21047]) ([solaredge docs]) * Fix aws.通知 platform schema ([@awarecan] - [#22374]) ([aws docs]) * Do data extraction in 传感器 ([@amelchio] - [#22444]) ([netgear\_lte docs][netgear_lte docs]) * Remove homekit\_controller duplicate legacy pairing loader code ([@Jc2k] - [#22442]) ([homekit\_controller docs][homekit_controller docs]) * Cache GTFS metadata and expose utility 属性 (breaking change) ([@renemarc] - [#20966]) ([gtfs docs]) (breaking change) * Modify check for ADB public key ([@dilruacs] - [#22378]) ([androidtv docs]) * Centralize all usages of `host` as a 配置 param to the constant CONF\_HOST ([@rohankapoorcom] - [#22458]) * Don't return 遮盖 position when not supported ([@andrewsayre] - [#22484]) ([smartthings docs]) * Targeted ZHA permit joins. ([@Adminiuga] - [#22482]) * Fix auto discovery of yeelights ([@syssi] - [#22481]) ([yeelight docs]) * fix inverse 状态 changes for 二元sensor ([@heythisisnate] - [#22479]) ([konnected docs]) * Fix events so they work with multiple 设备 ([@Kane610] - [#22477]) ([axis docs]) * Improve Sensibo 错误 handling ([@Danielhiversen] - [#22475]) ([sensibo docs]) * Add new data fields and bump python-join-api ([@bieniu] - [#22472]) ([joaoapps\_join docs][joaoapps_join docs]) * Bump pypi again for Cisco Mobility Express ([@fbradyirl] - [#22467]) ([cisco\_mobility\_express docs][cisco_mobility_express docs]) * Return percentage information in Alexa Smart Home response ([@jackwilsdon] - [#22440]) ([alexa docs]) * Move HKDevice into connection ([@Jc2k] - [#22430]) ([homekit\_controller docs][homekit_controller docs]) * Incoming SMS handling for netgear\_lte ([@amelchio] - [#22402]) ([netgear\_lte docs][netgear_lte docs]) * Entur 升级 to v0.2.0: async polling, number of departures, omit non boarding departures ([@hfurubotten] - [#22001]) ([entur\_public\_transport docs][entur_public_transport docs]) * Mopar split ([@rohankapoorcom] - [#21526]) (breaking change) * Fix too-abrubt SimpliSafe data refresh termination on 错误 ([@bachya] - [#22466]) ([simplisafe docs]) * Great migration 通知 ([@robbiet480] - [#22406]) * Print 错误 instead of 警告 for custom platforms in legacy format ([@balloob] - [#22486]) * Add game and app media types ([@cliffordwhansen] - [#22459]) ([媒体播放器 docs]) ([ps4 docs]) * Stream Record 服务 ([@hunterjm] - [#22456]) ([摄像头 docs]) ([stream docs]) * Add trusted\_users in trusted networks auth provider ([@awarecan] - [#22478]) ([auth docs]) * Fix regression of the xiaomi\_aqara config validation ([@syssi] - [#22435]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) (breaking change) (beta fix) * Fix dev branch ([@awarecan] - [#22493]) ([homekit\_controller docs][homekit_controller docs]) (beta fix) * 更新 pyotgw to 0.4b3 ([@mvn23] - [#22496]) ([opentherm\_gw docs][opentherm_gw docs]) (beta fix) * Fixes for yeelight availbility 状态 ([@zewelor] - [#22502]) ([yeelight docs]) (beta fix) * Remove botocore dependency from credstash 脚本 ([@awarecan] - [#22511]) (beta fix) * Fix lint on dev ([@awarecan] - [#22512]) (beta fix) * Do not use zha default 灯光 polling ([@dmulcahey] - [#22513]) ([zha docs]) (beta fix) * PS4 bump to 0.5.2 ([@ktnrg45] - [#22523]) ([ps4 docs]) (beta fix) * clean up channel 配置 ([@dmulcahey] - [#22534]) ([zha docs]) (beta fix) * Fix tts Great Migration issue ([@awarecan] - [#22539]) ([amazon\_polly docs][amazon_polly docs]) ([baidu docs]) ([marytts docs]) ([microsoft docs]) ([picotts docs]) ([voicerss docs]) ([yandextts docs]) (beta fix) * 升级 to async\_upnp\_client==0.14.7 ([@StevenLooman] - [#22543]) ([dlna\_dmr docs][dlna_dmr docs]) ([upnp docs]) (beta fix) * Bump zigpy ([@damarco] - [#22545]) ([zha docs]) (beta fix) * Add support for streaming to ffmpeg ([@balloob] - [#22549]) ([ffmpeg docs]) (beta fix) * Fix platform 警告 ([@balloob] - [#22551]) (beta fix) * Google assistant: add blinds trait for 遮盖 ([@giefca] - [#22336]) ([google\_assistant docs][google_assistant docs]) (breaking change) (beta fix) * 更新 Amcrest component to SUPPORT\_STREAM ([@drjared88] - [#22553]) ([amcrest docs]) (beta fix) * Fix name conflict in tests ([@awarecan] - [#22556]) (beta fix) * 更新 ONVIF component to SUPPORT\_STREAM ([@drjared88] - [#22569]) ([onvif docs]) (beta fix) * Add stream to the default config ([@balloob] - [#22602]) ([default\_config docs][default_config docs]) (beta fix) * Add trusted networks deprecating 警告 ([@awarecan] - [#22487]) ([http docs]) (beta fix) * Hass.io ingress ([@pvizeli] - [#22505]) ([hassio docs]) (beta fix) * 更新 Foscam component to support stream source ([@cwhits] - [#22568]) ([foscam docs]) (beta fix) * 更新 face\_recognition to 1.2.3 ([@pvizeli] - [#22622]) ([dlib\_face\_detect docs][dlib_face_detect docs]) ([dlib\_face\_identify docs][dlib_face_identify docs]) (beta fix) * Disable Z-Wave autoheal ([@balloob] - [#22628]) ([zwave docs]) (beta fix) * Handle disonnect bug in Tibber library ([@Danielhiversen] - [#22629]) ([tibber docs]) (beta fix) * Support GET params for websocket ingress path ([@pvizeli] - [#22638]) ([hassio docs]) (beta fix) * Return 0 for failed Foscam streams ([@cwhits] - [#22651]) ([foscam docs]) (beta fix) * Fix racy homekit\_controller platform 设置 caused by #22368 ([@Jc2k] - [#22655]) ([homekit\_controller docs][homekit_controller docs]) (beta fix) [#18543]: https://github.com/home-assistant/home-assistant/pull/18543 [#20767]: https://github.com/home-assistant/home-assistant/pull/20767 [#20780]: https://github.com/home-assistant/home-assistant/pull/20780 [#20966]: https://github.com/home-assistant/home-assistant/pull/20966 [#20992]: https://github.com/home-assistant/home-assistant/pull/20992 [#21047]: https://github.com/home-assistant/home-assistant/pull/21047 [#21053]: https://github.com/home-assistant/home-assistant/pull/21053 [#21091]: https://github.com/home-assistant/home-assistant/pull/21091 [#21210]: https://github.com/home-assistant/home-assistant/pull/21210 [#21414]: https://github.com/home-assistant/home-assistant/pull/21414 [#21432]: https://github.com/home-assistant/home-assistant/pull/21432 [#21440]: https://github.com/home-assistant/home-assistant/pull/21440 [#21526]: https://github.com/home-assistant/home-assistant/pull/21526 [#21593]: https://github.com/home-assistant/home-assistant/pull/21593 [#21638]: https://github.com/home-assistant/home-assistant/pull/21638 [#21708]: https://github.com/home-assistant/home-assistant/pull/21708 [#21710]: https://github.com/home-assistant/home-assistant/pull/21710 [#21820]: https://github.com/home-assistant/home-assistant/pull/21820 [#21823]: https://github.com/home-assistant/home-assistant/pull/21823 [#21834]: https://github.com/home-assistant/home-assistant/pull/21834 [#21842]: https://github.com/home-assistant/home-assistant/pull/21842 [#21847]: https://github.com/home-assistant/home-assistant/pull/21847 [#21883]: https://github.com/home-assistant/home-assistant/pull/21883 [#21897]: https://github.com/home-assistant/home-assistant/pull/21897 [#21902]: https://github.com/home-assistant/home-assistant/pull/21902 [#21952]: https://github.com/home-assistant/home-assistant/pull/21952 [#21961]: https://github.com/home-assistant/home-assistant/pull/21961 [#21990]: https://github.com/home-assistant/home-assistant/pull/21990 [#22001]: https://github.com/home-assistant/home-assistant/pull/22001 [#22014]: https://github.com/home-assistant/home-assistant/pull/22014 [#22016]: https://github.com/home-assistant/home-assistant/pull/22016 [#22023]: https://github.com/home-assistant/home-assistant/pull/22023 [#22029]: https://github.com/home-assistant/home-assistant/pull/22029 [#22036]: https://github.com/home-assistant/home-assistant/pull/22036 [#22038]: https://github.com/home-assistant/home-assistant/pull/22038 [#22040]: https://github.com/home-assistant/home-assistant/pull/22040 [#22041]: https://github.com/home-assistant/home-assistant/pull/22041 [#22049]: https://github.com/home-assistant/home-assistant/pull/22049 [#22050]: https://github.com/home-assistant/home-assistant/pull/22050 [#22059]: https://github.com/home-assistant/home-assistant/pull/22059 [#22064]: https://github.com/home-assistant/home-assistant/pull/22064 [#22069]: https://github.com/home-assistant/home-assistant/pull/22069 [#22077]: https://github.com/home-assistant/home-assistant/pull/22077 [#22081]: https://github.com/home-assistant/home-assistant/pull/22081 [#22084]: https://github.com/home-assistant/home-assistant/pull/22084 [#22085]: https://github.com/home-assistant/home-assistant/pull/22085 [#22087]: https://github.com/home-assistant/home-assistant/pull/22087 [#22088]: https://github.com/home-assistant/home-assistant/pull/22088 [#22092]: https://github.com/home-assistant/home-assistant/pull/22092 [#22096]: https://github.com/home-assistant/home-assistant/pull/22096 [#22099]: https://github.com/home-assistant/home-assistant/pull/22099 [#22101]: https://github.com/home-assistant/home-assistant/pull/22101 [#22105]: https://github.com/home-assistant/home-assistant/pull/22105 [#22107]: https://github.com/home-assistant/home-assistant/pull/22107 [#22108]: https://github.com/home-assistant/home-assistant/pull/22108 [#22109]: https://github.com/home-assistant/home-assistant/pull/22109 [#22130]: https://github.com/home-assistant/home-assistant/pull/22130 [#22131]: https://github.com/home-assistant/home-assistant/pull/22131 [#22132]: https://github.com/home-assistant/home-assistant/pull/22132 [#22134]: https://github.com/home-assistant/home-assistant/pull/22134 [#22135]: https://github.com/home-assistant/home-assistant/pull/22135 [#22139]: https://github.com/home-assistant/home-assistant/pull/22139 [#22141]: https://github.com/home-assistant/home-assistant/pull/22141 [#22143]: https://github.com/home-assistant/home-assistant/pull/22143 [#22149]: https://github.com/home-assistant/home-assistant/pull/22149 [#22152]: https://github.com/home-assistant/home-assistant/pull/22152 [#22159]: https://github.com/home-assistant/home-assistant/pull/22159 [#22164]: https://github.com/home-assistant/home-assistant/pull/22164 [#22167]: https://github.com/home-assistant/home-assistant/pull/22167 [#22168]: https://github.com/home-assistant/home-assistant/pull/22168 [#22171]: https://github.com/home-assistant/home-assistant/pull/22171 [#22175]: https://github.com/home-assistant/home-assistant/pull/22175 [#22180]: https://github.com/home-assistant/home-assistant/pull/22180 [#22181]: https://github.com/home-assistant/home-assistant/pull/22181 [#22182]: https://github.com/home-assistant/home-assistant/pull/22182 [#22183]: https://github.com/home-assistant/home-assistant/pull/22183 [#22189]: https://github.com/home-assistant/home-assistant/pull/22189 [#22198]: https://github.com/home-assistant/home-assistant/pull/22198 [#22199]: https://github.com/home-assistant/home-assistant/pull/22199 [#22200]: https://github.com/home-assistant/home-assistant/pull/22200 [#22202]: https://github.com/home-assistant/home-assistant/pull/22202 [#22204]: https://github.com/home-assistant/home-assistant/pull/22204 [#22205]: https://github.com/home-assistant/home-assistant/pull/22205 [#22218]: https://github.com/home-assistant/home-assistant/pull/22218 [#22223]: https://github.com/home-assistant/home-assistant/pull/22223 [#22224]: https://github.com/home-assistant/home-assistant/pull/22224 [#22233]: https://github.com/home-assistant/home-assistant/pull/22233 [#22235]: https://github.com/home-assistant/home-assistant/pull/22235 [#22240]: https://github.com/home-assistant/home-assistant/pull/22240 [#22251]: https://github.com/home-assistant/home-assistant/pull/22251 [#22261]: https://github.com/home-assistant/home-assistant/pull/22261 [#22266]: https://github.com/home-assistant/home-assistant/pull/22266 [#22268]: https://github.com/home-assistant/home-assistant/pull/22268 [#22269]: https://github.com/home-assistant/home-assistant/pull/22269 [#22272]: https://github.com/home-assistant/home-assistant/pull/22272 [#22278]: https://github.com/home-assistant/home-assistant/pull/22278 [#22279]: https://github.com/home-assistant/home-assistant/pull/22279 [#22282]: https://github.com/home-assistant/home-assistant/pull/22282 [#22287]: https://github.com/home-assistant/home-assistant/pull/22287 [#22302]: https://github.com/home-assistant/home-assistant/pull/22302 [#22304]: https://github.com/home-assistant/home-assistant/pull/22304 [#22305]: https://github.com/home-assistant/home-assistant/pull/22305 [#22306]: https://github.com/home-assistant/home-assistant/pull/22306 [#22307]: https://github.com/home-assistant/home-assistant/pull/22307 [#22308]: https://github.com/home-assistant/home-assistant/pull/22308 [#22317]: https://github.com/home-assistant/home-assistant/pull/22317 [#22318]: https://github.com/home-assistant/home-assistant/pull/22318 [#22320]: https://github.com/home-assistant/home-assistant/pull/22320 [#22321]: https://github.com/home-assistant/home-assistant/pull/22321 [#22328]: https://github.com/home-assistant/home-assistant/pull/22328 [#22333]: https://github.com/home-assistant/home-assistant/pull/22333 [#22334]: https://github.com/home-assistant/home-assistant/pull/22334 [#22336]: https://github.com/home-assistant/home-assistant/pull/22336 [#22339]: https://github.com/home-assistant/home-assistant/pull/22339 [#22340]: https://github.com/home-assistant/home-assistant/pull/22340 [#22343]: https://github.com/home-assistant/home-assistant/pull/22343 [#22345]: https://github.com/home-assistant/home-assistant/pull/22345 [#22346]: https://github.com/home-assistant/home-assistant/pull/22346 [#22347]: https://github.com/home-assistant/home-assistant/pull/22347 [#22348]: https://github.com/home-assistant/home-assistant/pull/22348 [#22349]: https://github.com/home-assistant/home-assistant/pull/22349 [#22351]: https://github.com/home-assistant/home-assistant/pull/22351 [#22353]: https://github.com/home-assistant/home-assistant/pull/22353 [#22354]: https://github.com/home-assistant/home-assistant/pull/22354 [#22358]: https://github.com/home-assistant/home-assistant/pull/22358 [#22363]: https://github.com/home-assistant/home-assistant/pull/22363 [#22365]: https://github.com/home-assistant/home-assistant/pull/22365 [#22366]: https://github.com/home-assistant/home-assistant/pull/22366 [#22367]: https://github.com/home-assistant/home-assistant/pull/22367 [#22368]: https://github.com/home-assistant/home-assistant/pull/22368 [#22369]: https://github.com/home-assistant/home-assistant/pull/22369 [#22370]: https://github.com/home-assistant/home-assistant/pull/22370 [#22373]: https://github.com/home-assistant/home-assistant/pull/22373 [#22374]: https://github.com/home-assistant/home-assistant/pull/22374 [#22378]: https://github.com/home-assistant/home-assistant/pull/22378 [#22379]: https://github.com/home-assistant/home-assistant/pull/22379 [#22381]: https://github.com/home-assistant/home-assistant/pull/22381 [#22382]: https://github.com/home-assistant/home-assistant/pull/22382 [#22383]: https://github.com/home-assistant/home-assistant/pull/22383 [#22389]: https://github.com/home-assistant/home-assistant/pull/22389 [#22390]: https://github.com/home-assistant/home-assistant/pull/22390 [#22393]: https://github.com/home-assistant/home-assistant/pull/22393 [#22395]: https://github.com/home-assistant/home-assistant/pull/22395 [#22397]: https://github.com/home-assistant/home-assistant/pull/22397 [#22398]: https://github.com/home-assistant/home-assistant/pull/22398 [#22402]: https://github.com/home-assistant/home-assistant/pull/22402 [#22403]: https://github.com/home-assistant/home-assistant/pull/22403 [#22406]: https://github.com/home-assistant/home-assistant/pull/22406 [#22407]: https://github.com/home-assistant/home-assistant/pull/22407 [#22414]: https://github.com/home-assistant/home-assistant/pull/22414 [#22417]: https://github.com/home-assistant/home-assistant/pull/22417 [#22419]: https://github.com/home-assistant/home-assistant/pull/22419 [#22421]: https://github.com/home-assistant/home-assistant/pull/22421 [#22427]: https://github.com/home-assistant/home-assistant/pull/22427 [#22430]: https://github.com/home-assistant/home-assistant/pull/22430 [#22431]: https://github.com/home-assistant/home-assistant/pull/22431 [#22433]: https://github.com/home-assistant/home-assistant/pull/22433 [#22435]: https://github.com/home-assistant/home-assistant/pull/22435 [#22438]: https://github.com/home-assistant/home-assistant/pull/22438 [#22440]: https://github.com/home-assistant/home-assistant/pull/22440 [#22442]: https://github.com/home-assistant/home-assistant/pull/22442 [#22444]: https://github.com/home-assistant/home-assistant/pull/22444 [#22452]: https://github.com/home-assistant/home-assistant/pull/22452 [#22456]: https://github.com/home-assistant/home-assistant/pull/22456 [#22458]: https://github.com/home-assistant/home-assistant/pull/22458 [#22459]: https://github.com/home-assistant/home-assistant/pull/22459 [#22466]: https://github.com/home-assistant/home-assistant/pull/22466 [#22467]: https://github.com/home-assistant/home-assistant/pull/22467 [#22472]: https://github.com/home-assistant/home-assistant/pull/22472 [#22475]: https://github.com/home-assistant/home-assistant/pull/22475 [#22477]: https://github.com/home-assistant/home-assistant/pull/22477 [#22478]: https://github.com/home-assistant/home-assistant/pull/22478 [#22479]: https://github.com/home-assistant/home-assistant/pull/22479 [#22481]: https://github.com/home-assistant/home-assistant/pull/22481 [#22482]: https://github.com/home-assistant/home-assistant/pull/22482 [#22484]: https://github.com/home-assistant/home-assistant/pull/22484 [#22486]: https://github.com/home-assistant/home-assistant/pull/22486 [#22487]: https://github.com/home-assistant/home-assistant/pull/22487 [#22493]: https://github.com/home-assistant/home-assistant/pull/22493 [#22496]: https://github.com/home-assistant/home-assistant/pull/22496 [#22502]: https://github.com/home-assistant/home-assistant/pull/22502 [#22505]: https://github.com/home-assistant/home-assistant/pull/22505 [#22511]: https://github.com/home-assistant/home-assistant/pull/22511 [#22512]: https://github.com/home-assistant/home-assistant/pull/22512 [#22513]: https://github.com/home-assistant/home-assistant/pull/22513 [#22523]: https://github.com/home-assistant/home-assistant/pull/22523 [#22534]: https://github.com/home-assistant/home-assistant/pull/22534 [#22539]: https://github.com/home-assistant/home-assistant/pull/22539 [#22543]: https://github.com/home-assistant/home-assistant/pull/22543 [#22545]: https://github.com/home-assistant/home-assistant/pull/22545 [#22549]: https://github.com/home-assistant/home-assistant/pull/22549 [#22551]: https://github.com/home-assistant/home-assistant/pull/22551 [#22553]: https://github.com/home-assistant/home-assistant/pull/22553 [#22556]: https://github.com/home-assistant/home-assistant/pull/22556 [#22568]: https://github.com/home-assistant/home-assistant/pull/22568 [#22569]: https://github.com/home-assistant/home-assistant/pull/22569 [#22602]: https://github.com/home-assistant/home-assistant/pull/22602 [#22622]: https://github.com/home-assistant/home-assistant/pull/22622 [#22628]: https://github.com/home-assistant/home-assistant/pull/22628 [#22629]: https://github.com/home-assistant/home-assistant/pull/22629 [#22638]: https://github.com/home-assistant/home-assistant/pull/22638 [#22651]: https://github.com/home-assistant/home-assistant/pull/22651 [#22655]: https://github.com/home-assistant/home-assistant/pull/22655 [@Adminiuga]: https://github.com/Adminiuga [@Danielhiversen]: https://github.com/Danielhiversen [@FattusMannus]: https://github.com/FattusMannus [@GidoHakvoort]: https://github.com/GidoHakvoort [@GuryYu]: https://github.com/GuryYu [@Jc2k]: https://github.com/Jc2k [@JeffLIrion]: https://github.com/JeffLIrion [@Kane610]: https://github.com/Kane610 [@MatthewFlamm]: https://github.com/MatthewFlamm [@Mofeywalker]: https://github.com/Mofeywalker [@Oro]: https://github.com/Oro [@OttoWinter]: https://github.com/OttoWinter [@SNoof85]: https://github.com/SNoof85 [@StevenLooman]: https://github.com/StevenLooman [@SukramJ]: https://github.com/SukramJ [@Swamp-Ig]: https://github.com/Swamp-Ig [@a005]: https://github.com/a005 [@alengwenus]: https://github.com/alengwenus [@amelchio]: https://github.com/amelchio [@andrewsayre]: https://github.com/andrewsayre [@awarecan]: https://github.com/awarecan [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@benleb]: https://github.com/benleb [@bieniu]: https://github.com/bieniu [@cgarwood]: https://github.com/cgarwood [@cgtobi]: https://github.com/cgtobi [@cliffordwhansen]: https://github.com/cliffordwhansen [@cwhits]: https://github.com/cwhits [@dagobert]: https://github.com/dagobert [@damarco]: https://github.com/damarco [@dilruacs]: https://github.com/dilruacs [@dmulcahey]: https://github.com/dmulcahey [@drjared88]: https://github.com/drjared88 [@dshokouhi]: https://github.com/dshokouhi [@eliseomartelli]: https://github.com/eliseomartelli [@endor-force]: https://github.com/endor-force [@escoand]: https://github.com/escoand [@fabaff]: https://github.com/fabaff [@fabtesta]: https://github.com/fabtesta [@fbradyirl]: https://github.com/fbradyirl [@fredrike]: https://github.com/fredrike [@fronzbot]: https://github.com/fronzbot [@giefca]: https://github.com/giefca [@heythisisnate]: https://github.com/heythisisnate [@hfurubotten]: https://github.com/hfurubotten [@hmmbob]: https://github.com/hmmbob [@hunterjm]: https://github.com/hunterjm [@iamtpage]: https://github.com/iamtpage [@isabellaalstrom]: https://github.com/isabellaalstrom [@jackwilsdon]: https://github.com/jackwilsdon [@jameshilliard]: https://github.com/jameshilliard [@jjlawren]: https://github.com/jjlawren [@karlkar]: https://github.com/karlkar [@kbickar]: https://github.com/kbickar [@ktnrg45]: https://github.com/ktnrg45 [@lapy]: https://github.com/lapy [@ljmerza]: https://github.com/ljmerza [@mvn23]: https://github.com/mvn23 [@nbarrientos]: https://github.com/nbarrientos [@nhorvath]: https://github.com/nhorvath [@nickw444]: https://github.com/nickw444 [@nmaggioni]: https://github.com/nmaggioni [@oblogic7]: https://github.com/oblogic7 [@pnbruckner]: https://github.com/pnbruckner [@pvizeli]: https://github.com/pvizeli [@quentinsf]: https://github.com/quentinsf [@rdbahm]: https://github.com/rdbahm [@renemarc]: https://github.com/renemarc [@robbiet480]: https://github.com/robbiet480 [@rohankapoorcom]: https://github.com/rohankapoorcom [@rtclauss]: https://github.com/rtclauss [@scop]: https://github.com/scop [@shanbs]: https://github.com/shanbs [@syssi]: https://github.com/syssi [@thibmaek]: https://github.com/thibmaek [@thomasloven]: https://github.com/thomasloven [@uchagani]: https://github.com/uchagani [@zewelor]: https://github.com/zewelor [alexa docs]: /integrations/alexa/ [amazon_polly docs]: /integrations/amazon_polly/ [ambient_station docs]: /integrations/ambient_station/ [amcrest docs]: /integrations/amcrest/ [androidtv docs]: /integrations/androidtv/ [api_streams docs]: /integrations/api_streams/ [auth docs]: /integrations/auth/ [aws docs]: /integrations/aws/ [axis docs]: /integrations/axis/ [baidu docs]: /integrations/baidu/ [buienradar docs]: /integrations/buienradar/ [摄像头 docs]: /integrations/摄像头/ [cisco_mobility_express docs]: /integrations/cisco_mobility_express/ [config docs]: /integrations/config/ [daikin docs]: /integrations/daikin/ [darksky docs]: /integrations/darksky/ [deconz docs]: /integrations/deconz/ [default_config docs]: /integrations/default_config/ [demo docs]: /integrations/demo/ [discovery docs]: /integrations/discovery/ [dlib_face_detect docs]: /integrations/dlib_face_detect/ [dlib_face_identify docs]: /integrations/dlib_face_identify/ [dlna_dmr docs]: /integrations/dlna_dmr/ [ecobee docs]: /integrations/ecobee/ [enigma2 docs]: /integrations/enigma2/ [entur_public_transport docs]: /integrations/entur_public_transport/ [esphome docs]: /integrations/esphome/ [familyhub docs]: /integrations/familyhub/ [ffmpeg docs]: /integrations/ffmpeg/ [foscam docs]: /integrations/foscam/ [freebox docs]: /integrations/freebox/ [前端 docs]: /integrations/frontend/ [generic docs]: /integrations/generic_ip_camera/ [generic_thermostat docs]: /integrations/generic_thermostat/ [google_assistant docs]: /integrations/google_assistant/ [group docs]: /integrations/group/ [gtfs docs]: /integrations/gtfs/ [hassio docs]: /integrations/hassio/ [hlk_sw16 docs]: /integrations/hlk_sw16/ [homeassistant docs]: /integrations/homeassistant/ [homekit_controller docs]: /integrations/homekit_controller/ [homematicip_cloud docs]: /integrations/homematicip_cloud/ [horizon docs]: /integrations/horizon/ [hp_ilo docs]: /integrations/hp_ilo/ [http docs]: /integrations/http/ [hyperion docs]: /integrations/hyperion/ [iliad_italy docs]: /integrations/iliad_italy/ [ios docs]: /integrations/ios/ [joaoapps_join docs]: /integrations/joaoapps_join/ [konnected docs]: /integrations/konnected/ [lastfm docs]: /integrations/lastfm/ [lcn docs]: /integrations/lcn/ [local_file docs]: /integrations/local_file/ [logi_circle docs]: /integrations/logi_circle/ [manual docs]: /integrations/manual/ [manual_mqtt docs]: /integrations/manual_mqtt/ [marytts docs]: /integrations/marytts/ [media_extractor docs]: /integrations/media_extractor/ [媒体播放器 docs]: /integrations/媒体播放器/ [microsoft docs]: /integrations/microsoft/ [mold_indicator docs]: /integrations/mold_indicator/ [moon docs]: /integrations/moon/ [MQTT docs]: /integrations/MQTT/ [nanoleaf docs]: /integrations/nanoleaf/ [ness_alarm docs]: /integrations/ness_alarm/ [netatmo docs]: /integrations/netatmo/ [netgear_lte docs]: /integrations/netgear_lte/ [nmbs docs]: /integrations/nmbs/ [通知 docs]: /integrations/通知/ [onkyo docs]: /integrations/onkyo/ [onvif docs]: /integrations/onvif/ [opentherm_gw docs]: /integrations/opentherm_gw/ [openweathermap docs]: /integrations/openweathermap/ [panasonic_viera docs]: /integrations/panasonic_viera/ [panel_custom docs]: /integrations/panel_custom/ [panel_iframe docs]: /integrations/panel_iframe/ [picotts docs]: /integrations/picotts/ [plex docs]: /integrations/plex/ [pollen docs]: /integrations/iqvia [prometheus docs]: /integrations/prometheus/ [ps4 docs]: /integrations/ps4/ [push docs]: /integrations/push/ [recorder docs]: /integrations/recorder/ [reddit docs]: /integrations/reddit/ [rest docs]: /integrations/rest/ [ring docs]: /integrations/ring/ [season docs]: /integrations/season/ [sense docs]: /integrations/sense/ [sensibo docs]: /integrations/sensibo/ [simplisafe docs]: /integrations/simplisafe/ [smartthings docs]: /integrations/smartthings/ [solaredge docs]: /integrations/solaredge/ [sql docs]: /integrations/sql/ [stream docs]: /integrations/stream/ [开关 docs]: /integrations/开关/ [switchbot docs]: /integrations/switchbot/ [systemmonitor docs]: /integrations/systemmonitor/ [telegram_bot docs]: /integrations/telegram_bot/ [tellduslive docs]: /integrations/tellduslive/ [tfiac docs]: /integrations/tfiac/ [tibber docs]: /integrations/tibber/ [time_date docs]: /integrations/time_date/ [tplink docs]: /integrations/tplink/ [traccar docs]: /integrations/traccar/ [trafikverket_weatherstation docs]: /integrations/trafikverket_weatherstation/ [upnp docs]: /integrations/upnp/ [voicerss docs]: /integrations/voicerss/ [websocket_api docs]: /integrations/websocket_api/ [xiaomi_aqara docs]: /integrations/xiaomi_aqara/ [xiaomi_miio docs]: /integrations/xiaomi_miio/ [yandextts docs]: /integrations/yandextts/ [yeelight docs]: /integrations/yeelight/ [zha docs]: /integrations/zha/ [zwave docs]: /integrations/zwave/ --- url: /home-assistant/blog/2019-04-15-hassio-ingress.md --- # Introducing Hass.io Ingress Today we are proud to introduce a new feature for Hass.io called Ingress. Ingress allows Hass.io 插件 to seamlessly integrate their 用户 interface with Home Assistant. Home Assistant will take care of the 认证 and the secure connection, so 用户 can start using the 插件 directly, without any 配置 necessary by the 用户. It just works. Even with Nabu Casa’s Home Assistant Cloud 遥控器 UI!

Ingress demo on Hass.io Demo with an 插件 on Ingress.

## 插件 that already support Ingress Some 插件 already have been upgraded to support the new Ingress feature. Here are a couple of 插件 that support Ingress and are available on the 插件 store right now: 核心 插件: * [Configurator](/home-assistant/addons/configurator/) * [deCONZ](https://github.com/home-assistant/hassio-addons/tree/master/deconz#readme) Community 插件: * [Node-RED](https://github.com/hassio-addons/addon-node-red#readme) * [Visual Studio Code](https://github.com/hassio-addons/addon-vscode#readme) * [InfluxDB](https://github.com/hassio-addons/addon-influxdb#readme) * [SSH & Web Terminal](https://github.com/hassio-addons/addon-ssh#readme) * [AdGuard Home](https://github.com/hassio-addons/addon-adguard-home#readme) You can recognize 插件 that support the Ingress feature by the Ingress icon on the 插件 information tab:

插件 view with Ingress support Screenshot of an 插件 view with ingress support.

Please note, that in order to 升级 or 安装 these Ingress enabled 插件, you need to be running Home Assistant 0.91.3. ## What’s next Releasing the Ingress feature is just a start. It allows us to make even better 集成 in the future. For the upcoming Home Assistant 0.92 发布, we will be adding support to add links to your 插件 to the Home Assistant 侧边栏 via a 切换 on the 插件 details page. The link will open the 插件 Ingress interface, embedding the 插件 in the Home Assistant UI. This will make it look and feel like a single system. ## Other new things While adding Ingress support, we have tweaked and polished some other things in the Hass.io 用户 interface: * Network ports in the 插件 view now have a description, so you know what they are being used for. * Reloading the 插件 store will now show a spinner to indicate that reloading is being done. ## For 插件 开发者 Ingress is added as an additional feature that 插件 authors can choose to support starting today, granted that the application in the 插件 supports it. The old approach of exposing 插件 on different ports will remain available. It will be up to 插件 authors to choose what to support, including an option to support both. If an 插件 is going to support both, you should not have the 插件 exposed on a port enabled by default. Instead, allow 用户 to enable the port access by assigning a port number in the “Network” section of the 插件 配置 面板. Are you an 插件 developer looking to support Ingress on your 插件? [Check the developer 文档][dev-docs]. ## 常见问题 & 已知问题 Hass.io Ingress is a new and complex technology. Without a doubt, now that everybody starts using it, we will discover new issues. Here are some frequently asked questions and some currently 已知问题 with the Ingress feature. * **After upgrading the 插件, I’m unable to access it directly.**
Direct access to the 插件 might now be disabled by default by the 插件 developer. If the 插件 supports running Ingress + direct access, you can re-enable direct access by setting a port number in the “Network” section of the 插件 配置. * **After upgrading the 插件, my `panel_iframe` doesn’t work anymore.**
This is related to the question above. Once you enable direct access again, your iFrame 面板 will start working again. Until the automated 面板 集成 lands in 0.92, you can also manually add a 面板 that points at Ingress. * **I cannot 升级 my 插件: “This 更新 is no longer compatible with your system.”**
Please 更新 your Home Assistant 安装 to 0.91.3 or higher. * **I cannot access the 插件 via Ingress using the Tor Browser or Firefox.**
We found a last minute issue impacting Firefox based browsers (including the Tor Browser). There are some issues accessing 插件 that use WebSockets. We have identified the issue and expect it to be solved with the 发布 of Home Assistant 0.91.4. [Configurator]: /插件/configurator/ [deCONZ]: https://github.com/home-assistant/hassio-addons/tree/master/deconz#readme [Node-RED]: https://github.com/hassio-addons/addon-node-red#readme [Visual Studio Code]: https://github.com/hassio-addons/addon-vscode#readme [InfluxDB]: https://github.com/hassio-addons/addon-influxdb#readme [SSH & Web Terminal]: https://github.com/hassio-addons/addon-ssh#readme [AdGuard Home]: https://github.com/hassio-addons/addon-adguard-home#readme [dev-docs]: https://开发者.home-assistant.io/docs/apps/presentation/#ingress --- url: /home-assistant/blog/2019-04-24-release-92.md --- --- url: /home-assistant/blog/2019-05-03-update-from-the-field.md --- # 一线近况更新 TL;DR: * Nabu Casa 已成为 Let’s Encrypt 的赞助方,以支持安全家庭所需的基础设施。 * Ubiquiti 决定不再赞助 Home Assistant。我们是友好结束合作的。Paulus 已从 Ubiquiti 转为受雇于 Nabu Casa。 * 当前的开发目标是迈向 Home Assistant 1.0。 * 我们正在与制造商建立合作关系:努力让我们的集成获得认证,并让制造商更容易为自家产品贡献和维护集成。 我们已经有一段时间没有聊过我们“征服世界”的计划了,所以现在是时候从 Home Assistant 总部带来一次简短更新。 去年,Ubiquiti Networks 聘请了我,也就是 Home Assistant 的创始人 Paulus Schoutsen,全职投入到改进 Home Assistant 的工作中。这极大地帮助项目朝着 1.0 迈进。期间,Home Assistant 增加了认证系统、设备与区域的概念、用于配置集成的 UI,以及全新的 Lovelace UI,等等。 去年 9 月,在我们五周年之际,我们推出了 Nabu Casa。Nabu Casa 是一家为让 Home Assistant 变得更好而成立的公司。它通过提供 Home Assistant Cloud 服务,并将收入用于支持 Home Assistant 项目来实现这一目标。借助 Home Assistant Cloud,你只需一次选择,就可以为 Home Assistant 安装启用安全的远程访问,并集成 Google Assistant 与 Amazon Alexa。 作为对 Home Assistant 持续支持的一部分,Nabu Casa 为 Home Assistant 提供了托管社区和部分构建系统所需的基础设施。今年年初,我们聘请了 Hass.io 的创始人 Pascal Vizeli,全职投入 Home Assistant。就在这个月,我们还开始赞助 Let’s Encrypt,也就是那个为安全远程访问 Home Assistant 提供免费 SSL 安全证书的服务。 这个月也标志着 Ubiquiti 参与项目整整一年,同时也是他们参与的最后一个月,因为他们的计划发生了变化,决定结束这项合作。我们是在友好的氛围中分开的,我想感谢 Ubiquiti 提供了这样一个难得的机会,它给 Home Assistant 项目带来了巨大的推动。接下来,我将由 Nabu Casa 支付薪资,从而继续投身于 Home Assistant 的工作。 ## 重点方向 在过去一年里,Home Assistant 社区一直在努力打造一个对用户友好的 Home Assistant 版本,也就是 Home Assistant 1.0。 我们的目标是在今年发布 Home Assistant 1.0。在 Home Assistant 1.0 中,安装和基础功能可以通过用户界面完成。高级选项则需要进入高级模式,或者通过 `configuration.yaml` 设置。更多细节可以查看去年的[年度状况更新](/home-assistant/blog/2018/11/16/状态-of-the-union/)。我们已经开始使用[这个项目看板](https://github.com/orgs/home-assistant/projects/1)来跟踪进展。 在全力推进 Home Assistant 1.0 的同时,我们也已经开始为 1.0 发布之后的下一项目标做准备:为制造商和集成提供更好的支持路径。 我们已经开始与合作伙伴一起为集成做认证,同时也在努力让制造商更容易改进或维护他们自己的集成。如果你是制造商,并且希望尽早参与,欢迎通过 联系我们。我们计划很快公布更多相关信息。 ## 最后 这是一段令人兴奋的时期,我对未来充满期待。Home Assistant 在成长,我们的社区在成长,我们的影响力也在成长。就在本周,有人分享了[Home Assistant 如何拯救生命的证词](https://news.ycombinator.com/item?id=19806159),我们还发现西雅图的 [Living Computers Museum](https://livingcomputers.org/) 正在使用 Home Assistant 向人们讲解物联网: --- url: /home-assistant/blog/2019-05-08-nest-data-bye-bye.md --- # \[Update: new 用户 only] Nest to turn off their API **更新 May 16:** Nest 刚刚在[一篇博文](https://博客.google/products/google-nest/updates-works-with-nest/)中宣布调整计划。它仍会在 8 月底关闭 Works with Nest 项目,但不会再切断现有 API 用户的访问权限。不过,它依然会在 8 月底停止接收新用户。 目前,每位 Home Assistant 用户都需要自行创建开发者账号,才能配置自己的 Nest 集成。我们会联系 Nest,看看是否能成为合作伙伴,好让 8 月之后加入 Home Assistant 的用户仍然可以继续使用 Nest。 *** 唉,又来一个。而且这次还不是小事:Nest 正在关闭他们的 API。 我们早在 1 月时就已经[看到了这个危险信号](/home-assistant/blog/2019/01/24/nest-cannot-access-data/),而现在它已经[正式确认](https://开发者.nest.com/):Google 宣布 Nest API 将于 2019 年 8 月底关闭。这意味着再过三个多月,你将无法再取回那些 Google 在你家中收集的数据,也无法按自己的意愿使用这些数据。

Screenshot of the Nest developer website. Notice posted on the Nest developer website.

Nest 给出的关闭 API 理由是,他们要把重心放在打造“Works with Google Assistant”这个更有帮助、也更智能的家庭生态系统上。然而最关键的问题在于:Google Assistant 生态是一条单行道。你可以把数据送进去,却永远拿不出来。他们也在[官方常见问题](https://nest.com/whats-happening/)中承认了这一点:

Screenshot of the 常见问题 on the Nest developer website. 常见问题 Nest developer website.

## 雪上加霜 Google 还[宣布](https://nest.com/博客/2019/05/07/introducing-google-nest/),他们将把 Nest 生态全面并入 Google 体系,要求你把所有 Nest 设备都绑定到 Google 账号上。这会怎么运作?我们就把 [《金融时报》这篇文章](https://www.ft.com/content/d8cbd5e6-70de-11e9-bf5c-6eeb837566c5) 里的这段内容放在这里,大家自行体会: 我们的建议始终不变:购买那些支持本地通信的设备。 --- url: /home-assistant/blog/2019-05-16-release-93.md --- # 0.93: Essent, AmbiClimate, VS Code debugging 又到了 0.93 发布,这次内容相当精彩。因为我在出差,所以比平时晚了一天发布。[Frenck](https://www.github.com/frenck) 每周二和周五都会直播他在 Home Assistant / Hass.io 上的工作,而上周二我决定给他一个惊喜,在直播时直接去他家 😛。结果我们和观众一起聊了超过 3 个小时的 Home Assistant 相关话题。完整对话可以查看 [Frenck 的博客](https://frenck.dev/home-assistant-paulus-invaded-my-live-stream/)。下面是我走进直播时的片段:
上周我们还写了一篇关于 Home Assistant 今年[更新后规划](/home-assistant/blog/2019/05/03/更新-from-the-field/)的文章。如果你还没读过,值得一看! 如果你是 Nest 用户,这里有个坏消息:Google 宣布他们将在 8 月底[关闭 Nest API](/home-assistant/blog/2019/05/08/nest-data-bye-bye/)。这将导致 Nest 硬件无法再与 Home Assistant 配合使用 (╯°□°)╯︵ ┻━┻。**更新:** 他们后来调整了计划,现在只会影响新用户。 和往常一样,本次发布也伴随着 [Home Assistant Podcast 的新一期节目](https://hasspodcast.io/ha050/)。Rohan 和 Phil 讨论了这次发布、Nest API 以及更多内容。这已经是他们的第 50 期节目了,恭喜达成这个里程碑! Pascal 更新了我们构建 Hass.io 的方式。现在在开发 Home Assistant 的同时,构建流程也会保持最新,这意味着 Hass.io 的构建版本在发布博客发出之前就已经准备好了! ## Home Assistant 1.0 As we mentioned in [our updated plans post](/home-assistant/blog/2019/05/03/更新-from-the-field/), we're working hard on Home Assistant 1.0. Over the next releases we will work on polishing the UI, the 后端 architecture, and everything in between. One of the new things that we introduced is a new step in our onboarding allowing 用户 to set up 集成. We will automatically highlight discovered 集成. Once the 用户 finishes the onboarding flow, 实体 will be automatically grouped by the 区域 that they are in. Neat!
We've also been working on polishing parts of our config UI. The 自动化 editor will now show all 自动化, the last time they got triggered, and allow 用户 to enable/disable them.

Screenshot of the updated 自动化 editor. Screenshot of the updated 自动化 editor.

## Sonos The Sonos 集成 has a number of changes in this 发布, some of them breaking existing 配置. First, the Sonos custom 服务 have been moved to the `sonos` domain. The new 服务 names are as follows: * `sonos.join` (before: `media_player.sonos_join`) * `sonos.unjoin` (before: `media_player.sonos_unjoin`) * `sonos.snapshot` (before: `media_player.sonos_snapshot`) * `sonos.restore` (before: `media_player.sonos_restore`) * `sonos.set_sleep_timer` (before: `media_player.sonos_set_sleep_timer`) * `sonos.clear_sleep_timer` (before: `media_player.sonos_clear_sleep_timer`) * `sonos.update_alarm` (before: `media_player.sonos_update_alarm`) * `sonos.set_option` (before: `media_player.sonos_set_option`) The last four of those 服务 no longer target all 实体 by default since that is usually a mistake. The `entity_id` 属性 is thus becoming mandatory for those 服务. If you really do want to target all you can use `entity_id: all`. Next, YAML 配置 of Sonos under the `media_player:` key is no longer accepted. While auto-配置 through the 集成 UI is now the preferred way, static 配置 can still be specified under a `sonos:` key, for example: ```yaml sonos: media_player: hosts: - 192.0.2.25 - 192.0.2.26 ``` For those of you that like to power down your Sonos, Home Assistant should now handle that without logging 错误. Also, speakers that are powered on will be added to Home Assistant without needing a 重启. ## New 集成 * Adds Orange Pi GPIO platform ([@pascallj] - [#22541]) ([orangepi\_gpio docs][orangepi_gpio docs]) (new-集成) (new-platform) * Essent 传感器 ([@TheLastProject] - [#23513]) ([essent docs]) (new-集成) (new-platform) * Ptvsd debugger component. ([@Swamp-Ig] - [#23336]) (new-集成) * Ambiclimate ([@Danielhiversen] - [#22827]) ([ambiclimate docs]) (new-集成) (new-platform) * Add Intergas InComfort Lan2RF gateway ([@zxdavb] - [#23736]) ([incomfort docs]) (new-集成) (new-platform) ## New Platforms * Adds Orange Pi GPIO platform ([@pascallj] - [#22541]) ([orangepi\_gpio docs][orangepi_gpio docs]) (new-集成) (new-platform) * Added component named switcher\_kis switcher 热水器 集成. ([@TomerFi] - [#22325]) ([switcher\_kis docs][switcher_kis docs]) (new-platform) * MQTT 吸尘器 状态 设备 ([@pszafer] - [#23171]) ([MQTT docs]) (new-platform) * Add new nextbus 传感器 ([@ViViDboarder] - [#20197]) ([nextbus docs]) (new-platform) * Add 传感器 support for dyson 2018 models ([@etheralm] - [#22578]) ([dyson docs]) (new-platform) * Add Bizkaibus, Biscays (Spain) bus 服务 component ([@UgaitzEtxebarria] - [#22934]) ([bizkaibus docs]) (new-platform) * Added new 二元sensor meteoalarm to get 天气 alerts in Europe ([@rolfberkenbosch] - [#23663]) ([meteoalarm docs]) (new-集成) (new-platform) * Add water\_heater to geniushub, bump client library ([@zxdavb] - [#23384]) ([geniushub docs]) (new-platform) * New 遮盖 platform for ADS 集成 ([@carstenschroeder] - [#23377]) ([ads docs]) (new-platform) ## 发布 0.93.1 - May 17 * Fix Hassio-版本 for Azure Pipelines ([@pvizeli] - [#23895]) * 更新 Honeywell 警告 ([@balloob] - [#23913]) ([honeywell docs]) * 开关 media player to 开关 type ([@elupus] - [#23914]) ([google\_assistant docs][google_assistant docs]) * Fix problem with 摄像头 that don't support time ([@karlkar] - [#23924]) ([onvif docs]) [#23895]: https://github.com/home-assistant/home-assistant/pull/23895 [#23913]: https://github.com/home-assistant/home-assistant/pull/23913 [#23914]: https://github.com/home-assistant/home-assistant/pull/23914 [#23924]: https://github.com/home-assistant/home-assistant/pull/23924 [@balloob]: https://github.com/balloob [@elupus]: https://github.com/elupus [@karlkar]: https://github.com/karlkar [@pvizeli]: https://github.com/pvizeli [google_assistant docs]: /integrations/google_assistant/ [honeywell docs]: /integrations/honeywell/ [onvif docs]: /integrations/onvif/ ## 发布 0.93.2 - May 22 * Fix auto 版本 更新 Hass.io ([@pvizeli] - [#23935]) * Bump pytraccar ([@ludeeus] - [#23939]) ([traccar docs]) * Fixes issue with multiple alerts ([@ludeeus] - [#23945]) ([alert docs]) * 设置 集成 dependencies before loading it ([@aerialls] - [#23957]) * Make Discord payload data key not required ([@cyrosy] - [#23964]) ([discord docs]) * 升级 broadlink library ([@Danielhiversen] - [#23966]) ([broadlink docs]) [#23935]: https://github.com/home-assistant/home-assistant/pull/23935 [#23939]: https://github.com/home-assistant/home-assistant/pull/23939 [#23945]: https://github.com/home-assistant/home-assistant/pull/23945 [#23957]: https://github.com/home-assistant/home-assistant/pull/23957 [#23964]: https://github.com/home-assistant/home-assistant/pull/23964 [#23966]: https://github.com/home-assistant/home-assistant/pull/23966 [@Danielhiversen]: https://github.com/Danielhiversen [@aerialls]: https://github.com/aerialls [@cyrosy]: https://github.com/cyrosy [@ludeeus]: https://github.com/ludeeus [@pvizeli]: https://github.com/pvizeli [alert docs]: /integrations/alert/ [broadlink docs]: /integrations/broadlink/ [discord docs]: /integrations/discord/ [traccar docs]: /integrations/traccar/ ## 如果你需要帮助…… ……欢迎随时使用我们非常活跃的[论坛](https://community.home-assistant.io/),或者加入我们的 [聊天频道](https://discord.gg/c5DvZ4e)。虽然发布说明也开放评论,但我们更希望你优先使用前面的沟通渠道。谢谢。 ## 反馈问题 如果这次发布引入了问题,请前往我们的 [issue tracker](https://github.com/home-assistant/home-assistant/issues) 提交反馈。请务必填写 issue 模板中的所有字段。 ## Backward-incompatible changes * **Homematic IP Cloud** - Adds homematicip cloud temperature 传感器 from thermostats. 实体 IDs of HmIP-SLO (灯光 传感器 Outdoor) will change and stale 实体 will need to be removed from the 实体 registry. ([@SukramJ] - [#23263]) ([homematicip\_cloud docs][homematicip_cloud docs]) * **Pollen.com** * IQVIA is the parent company which hosts a variety of sites (https://pollen.com, https://flustar.com, etc.) from which valid data can come. To accommodate this, the Pollen.com 传感器 platform is now the IQVIA component and the 配置.yaml schema has changed accordingly. ([@bachya] - [#22986]) ([iqvia docs]) ([pollen docs]) * The IQVIA component no longer provides historical data for allergen and asthma 条件. Tactically, this means all historical 传感器 – including "Yesterday" 传感器 – will no longer appear; 用户 will need to 更新 any 自动化 that previously relied on these 传感器. ([@bachya] - [#23258]) ([iqvia docs]) Example 配置: ```yaml iqvia: zip_code: "12345" ``` * **Sonos** * Configuring the Sonos 集成 as a 媒体播放器: platform in 配置.yaml was deprecated in 0.72 and has now been removed. Please see the notes above in this 发布 post as well as the component 文档 for further info. ([@amelchio] - [#23385]) ([sonos docs]) * Sonos-specific 服务 have been moved from the 媒体播放器 domain to the sonos domain. For example, 媒体播放器.sonos\_join has become sonos.join. 服务 sonos.set\_sleep\_timer, sonos.clear\_sleep\_timer, sonos.update\_alarm and sonos.set\_option now require the entity\_id parameter and will not target all when it is missing. You can use all to target all. ([@amelchio] - [#23670]) ([sonos docs]) * **Nmap** - In Linux, and when running a setuid nmap, MAC addresses are reported with a leading zero in each byte. Under Mac OS X, when running the arp command, there is no leading zero. This makes it annoying to share config files between a Mac and Linux 设置. This change fixes this by forcing MAC addresses to be zero padded, "breaking" Mac detection on a Mac by aligning it to the convention on Linux ([@mikeage] - [#23492]) ([nmap\_tracker docs][nmap_tracker docs]) * **Frontend** - This change converts the 前端 to do client-side modern JS detection. It is no longer possible to force the 前端 版本 that is shown to a browser by specifying a javascript\_version option. Instead, we use feature detection to make sure that each browser receives the latest supported 版本. Because of feature detection, we no longer have ES5 specific index pages, which means the option extra\_html\_url\_es5 no longer does anything. All usages of extra\_html\_url should be migrated to use Lovelace imports.([@balloob] - [#23618]) ([前端 docs]) * **Epson Workforce** - This change adds the option to add photo black cartridge as a setting. It also corrects the spelling of "Inklevel" to "Ink level"([@ThaStealth] - [#23433]) ([epsonworkforce docs]) Example 配置: ```yaml - platform: epsonworkforce host: IP_ADDRESS monitored_conditions: - black - photoblack - yellow - magenta - cyan - clean ``` * **SNMP** - The 配置 of the SNMP 设备 tracker was aligned with the other SNMP 开关 and the 传感器 配置. If you are using 认证 key and private key then change your 配置 to auth\_key: and priv\_key:. ([@fabaff] - [#23678]) ([snmp docs]) * **Netatmo** The netatmo\_public 传感器 will be merged into the netatmo 集成. In the config platform: netatmo\_public becomes platform: netatmo, everything else stays the same. ([@cgtobi] - [#23531]) ([netatmo docs]) * **Sesame Smart Lock** - The Sesame smart 门锁's 1.0 API uses a username/密码 pair to authenticate, and may be deprecated in the future. The V3 API uses an API key, so it will require 用户 to 更新 their HA config. ([@zanglang] - [#23621]) ([sesame docs]) Example 配置: ```yaml lock: - platform: sesame api_key: !secret sesame_api_key ``` * **Z-Wave** - Not a breaking change perse, just a note: Open Z-Wave has released 版本 1.6. The 配置 files are not compatible with Open Z-Wave 1.4, the 版本 that we are currently using. Don't copy config files over! We're waiting for Open Z-Wave Python bindings to 更新 before we can 更新 our code. ## Beta Fixes * Sort discovered entries by 'st' to ensure getting the same 设备 each discovery ([@StevenLooman] - [#23763]) ([upnp docs]) (beta fix) * Bump pyatmo to v1.11 ([@cgtobi] - [#23766]) ([netatmo docs]) (beta fix) * Fix for issue #23739. Added unique\_id property so ([@dreed47] - [#23769]) ([zestimate docs]) (beta fix) * Beta Fix: ONVIF ([@hunterjm] - [#23787]) ([onvif docs]) (beta fix) * Synchronize Sonos 服务 calls ([@amelchio] - [#23791]) ([sonos docs]) (beta fix) * Do not add coordinator to the ZHA 实体. ([@Adminiuga] - [#23803]) ([zha docs]) (beta fix) * fix onvif wsdl import - take 2 ([@hunterjm] - [#23807]) ([onvif docs]) (beta fix) * Correct ZHA illumination conversion ([@dmulcahey] - [#23853]) ([zha docs]) (beta fix) * Fix ZHA battery when readings produce an unknown value ([@dmulcahey] - [#23854]) ([zha docs]) (beta fix) * bump zha-quirks ([@dmulcahey] - [#23855]) ([zha docs]) (beta fix) * Fix improper usage of body 属性 on web.Response. Should be text since we arent sending bytes ([@robbiet480] - [#23857]) ([geofency docs]) ([locative docs]) ([mobile\_app docs][mobile_app docs]) (beta fix) ## All changes * Pass configured host string instead of always forcing an ip-address ([@itn3rd77] - [#23164]) ([homematic docs]) * Make less imports from yeelight ([@zewelor] - [#23124]) ([yeelight docs]) * Add @Jc2k to codeowners for homekit\_controller ([@Jc2k] - [#23173]) ([homekit\_controller docs][homekit_controller docs]) * Add minimum/maximum to counter ([@rohankapoorcom] - [#22608]) ([counter docs]) * Adds Orange Pi GPIO platform ([@pascallj] - [#22541]) ([orangepi\_gpio docs][orangepi_gpio docs]) (new-集成) (new-platform) * Potential None ([@Swamp-Ig] - [#23187]) ([自动化 docs]) * Add storage for cacheable homekit 实体 maps. ([@Jc2k] - [#23191]) ([homekit\_controller docs][homekit_controller docs]) * Misc. ZHA changes ([@dmulcahey] - [#23190]) ([zha docs]) * set myself as codeowner of xmpp, removed me from 通知/\* ([@flowolf] - [#23207]) ([通知 docs]) ([xmpp docs]) * 更新 vizio component to support latest pyvizio with soundbar support ([@raman325] - [#22294]) ([vizio docs]) * Add json\_attributes\_template ([@emontnemery] - [#22981]) ([MQTT docs]) * Only comment with changed coverage on 发布 PRs \[skip-ci] ([@balloob] - [#23224]) * Fix optimistic mode + other bugs, tests ([@emontnemery] - [#22976]) ([MQTT docs]) * Set default value for input\_datetime ([@tsvi] - [#21919]) ([input\_datetime docs][input_datetime docs]) * Remove archived 17track packages from the 实体 registry ([@bachya] - [#23049]) ([seventeentrack docs]) * Change 配置 for orangepi ([@pascallj] - [#23231]) ([orangepi\_gpio docs][orangepi_gpio docs]) * Add and use an async\_fire\_service\_discovered 助手 ([@Jc2k] - [#23232]) * Review feedback from #23191 ([@Jc2k] - [#23233]) ([homekit\_controller docs][homekit_controller docs]) * Add missing 服务 for persistent\_notification ([@bieniu] - [#23230]) * Add more CPU temp. labels to Glances ([@Chris-V] - [#23179]) ([glances docs]) * Add accuracy and status for Traccar ([@GoNzCiD] - [#23180]) ([traccar docs]) * Avoid calling async code in sync context ([@Jc2k] - [#23235]) ([homekit\_controller docs][homekit_controller docs]) * Drop unnecessary block\_till\_done, improve tests ([@emontnemery] - [#23246]) * Drop unnecessary block\_till\_done, improve tests ([@emontnemery] - [#23247]) * Drop unnecessary block\_till\_done, improve tests ([@emontnemery] - [#23248]) * Drop unnecessary block\_till\_done, improve tests ([@emontnemery] - [#23249]) * Drop unnecessary block\_till\_done ([@emontnemery] - [#23250]) * Drop unnecessary block\_till\_done ([@emontnemery] - [#23251]) * Drop unnecessary block\_till\_done, improve tests ([@emontnemery] - [#23252]) * Added component named switcher\_kis switcher 热水器 集成. ([@TomerFi] - [#22325]) ([switcher\_kis docs][switcher_kis docs]) (new-platform) * Drop unnecessary block\_till\_done for MQTT 风扇 tests ([@emontnemery] - [#23253]) * Drop unnecessary block\_till\_done for MQTT tests ([@emontnemery] - [#23254]) * Drop unnecessary block\_till\_done, improve tests for MQTT 遮盖 tests ([@emontnemery] - [#23255]) * Drop unnecessary block\_till\_done ([@emontnemery] - [#23256]) * Add ctags file to .gitignore ([@bachya] - [#23279]) * 升级 xmltodict to 0.12.0 ([@BKPepe] - [#23277]) ([bluesound docs]) ([startca docs]) ([ted5000 docs]) ([zestimate docs]) * 升级 pyotp to 2.2.7 ([@BKPepe] - [#23274]) ([otp docs]) * Add homematicip cloud temperature 传感器 from thermostats ([@SukramJ] - [#23263]) ([homematicip\_cloud docs][homematicip_cloud docs]) (breaking change) * Improve MQTT tests ([@emontnemery] - [#23296]) * Add support to play url ([@andrewsayre] - [#23273]) ([heos docs]) * RFC: 升级 philips\_js component 版本 and support channels and sources ([@elupus] - [#23061]) ([philips\_js docs][philips_js docs]) * MQTT 吸尘器 状态 设备 ([@pszafer] - [#23171]) ([MQTT docs]) (new-platform) * Add connection control for netgear\_lte ([@amelchio] - [#22946]) ([netgear\_lte docs][netgear_lte docs]) * Set placeholders in homekit config flow title ([@Jc2k] - [#23311]) ([homekit\_controller docs][homekit_controller docs]) * Random hassfest fixes ([@balloob] - [#23314]) * Add get\_states faster ([@balloob] - [#23315]) ([websocket\_api docs][websocket_api docs]) * Handle traccar connection 错误 ([@ludeeus] - [#23289]) ([traccar docs]) * 升级 attrs to 19.1.0 ([@BKPepe] - [#23323]) * Fix ps4 not able to use different PSN accounts ([@ktnrg45] - [#22799]) ([ps4 docs]) * Reorg Homematic IP Cloud imports and minor fixes ([@SukramJ] - [#23330]) ([homematicip\_cloud docs][homematicip_cloud docs]) * Changes due to manifest.json. Awaiting coroutines instead of creating tasks ([@alengwenus] - [#23321]) ([lcn docs]) * Fix Switchbot 恢复 状态 ([@Danielhiversen] - [#23325]) ([switchbot docs]) * Added override for kwikset 888. ([@sowelie] - [#23327]) ([zwave docs]) * 升级 youtube\_dl to 2019.04.17 ([@fabaff] - [#23342]) ([media\_extractor docs][media_extractor docs]) * Fix Homematic IP Cloud remaining 灯光 imports ([@SukramJ] - [#23339]) ([homematicip\_cloud docs][homematicip_cloud docs]) * Volume trait for google assistant ([@elupus] - [#23237]) ([google\_assistant docs][google_assistant docs]) * 升级 ruamel.yaml to 0.15.94 ([@fabaff] - [#23344]) * Netatmo 5min fetch interval ([@pvizeli] - [#23341]) ([netatmo docs]) * Fixed test ([@Swamp-Ig] - [#23343]) * 设备 type garage for 二元sensor garage\_door ([@elupus] - [#23345]) ([google\_assistant docs][google_assistant docs]) * Fix non-syncthru supporting printers ([@nielstron] - [#21482]) ([syncthru docs]) * Add support for a wider variety of EnOcean 设备 ([@bdurrer] - [#22052]) ([enocean docs]) * Convert Pollen.com 传感器 into IQVIA component ([@bachya] - [#22986]) ([iqvia docs]) ([pollen docs]) (breaking change) (new-集成) (new-platform) * 升级 to pyubee==0.6 ([@StevenLooman] - [#23355]) * Fix tox.ini lint target ([@ViViDboarder] - [#23359]) * Add media player external url ([@balloob] - [#23337]) ([媒体播放器 docs]) * Fix race 条件. ([@mitchellrj] - [#21244]) ([plex docs]) * Add amcrest 摄像头 服务 and deprecate 开关 ([@pnbruckner] - [#22949]) ([amcrest docs]) * Convert some test 助手 to coroutines and adjust tests ([@emontnemery] - [#23352]) * 更新 xiaomi library ([@Danielhiversen] - [#23391]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * Add 设备 classes for media player and map to google types ([@elupus] - [#23236]) ([google\_assistant docs][google_assistant docs]) ([媒体播放器 docs]) * Bump youtube-dl 版本 to 2019.04.24 ([@cgtobi] - [#23398]) ([media\_extractor docs][media_extractor docs]) * add key parameter ([@panosmz] - [#23381]) ([oasa\_telematics docs][oasa_telematics docs]) * check if sabotage attr is in 设备 ([@SukramJ] - [#23397]) ([homematicip\_cloud docs][homematicip_cloud docs]) * Add Types to Homematic IP ([@SukramJ] - [#23401]) ([homematicip\_cloud docs][homematicip_cloud docs]) * Add 设备 info for Logi Circle 摄像头 and 传感器 实体 ([@evanjd] - [#23373]) ([logi\_circle docs][logi_circle docs]) * Bump requirement to v55 ([@Kane610] - [#23410]) ([deconz docs]) * 恢复 battery\_quantity for zha 设备 ([@vigonotion] - [#23320]) ([zha docs]) * Remove support for deprecated Sonos 配置 ([@amelchio] - [#23385]) ([sonos docs]) (breaking change) * Additional cleanup of IQVIA 集成 ([@bachya] - [#23403]) ([iqvia docs]) * Add new nextbus 传感器 ([@ViViDboarder] - [#20197]) ([nextbus docs]) (new-platform) * Remove historical allergen and asthma 传感器 from IQVIA ([@bachya] - [#23258]) ([iqvia docs]) (breaking change) * Return of travis ([@amelchio] - [#23409]) * Fix broken forecast trend 属性 in IQVIA ([@bachya] - [#23454]) ([iqvia docs]) * Bump amcrest to 1.4.0 and use new storage\_all method ([@pnbruckner] - [#23446]) ([amcrest docs]) * Added option to use self-signed certificates ([@anrudolph] - [#23139]) ([caldav docs]) * No longer promote imports inside methods ([@amelchio] - [#23471]) * Improve handling of unavailable Sonos speakers ([@amelchio] - [#23472]) ([sonos docs]) * Use 遥控器 图像 for HEOS ([@andrewsayre] - [#23420]) ([heos docs]) * Add a 警告 that honeywell/EU is to be deprecated ([@zxdavb] - [#23469]) ([honeywell docs]) * Skip flaky stream tests ([@amelchio] - [#23493]) * Display person component as occupancy 传感器 HomeKit ([@chmielowiec] - [#23451]) ([homekit docs]) * Fixes local\_file 摄像头 服务 ([@robmarkcole] - [#23479]) ([local\_file docs][local_file docs]) * 更新 aiolifx\_effects to 0.2.2 ([@arsaboo] - [#23473]) ([lifx docs]) * Catch RequestException in influxdb writer ([@amelchio] - [#23508]) ([influxdb docs]) * Fixed bug with max\_result ([@atomic7777] - [#23507]) ([google docs]) * Return 状态 when changing optimistic 遮盖 ([@balloob] - [#23498]) ([google\_assistant docs][google_assistant docs]) * 更新 Philips js to v0.0.8 ([@elupus] - [#23462]) ([philips\_js docs][philips_js docs]) * Fixed AlexaPowerController to report power 状态 for thermostats ([@mcc05] - [#23468]) ([alexa docs]) * Continuous discovery of Sonos speakers ([@amelchio] - [#23484]) ([sonos docs]) * Ignore stale directories ([@amelchio] - [#23464]) * Do not 日志 tracebacks for influxdb write 错误 ([@amelchio] - [#23522]) ([influxdb docs]) * limit concurrent updates to avoid network flood ([@dmulcahey] - [#23534]) ([zha docs]) * Add current disease data to IQVIA ([@bachya] - [#23052]) ([iqvia docs]) * Allow direct binding via ZHA for the ZLL profile ([@dmulcahey] - [#23536]) ([zha docs]) * Improve logging of exceptions in async\_create\_task ([@emontnemery] - [#22689]) ([cast docs]) * 安装 requirements when checking config ([@balloob] - [#23500]) * Always print invalid 配置 data ([@emontnemery] - [#21972]) * Don't use zigpy profiles for ZHA 实体 ([@dmulcahey] - [#22844]) ([zha docs]) * Add HomeKit low battery threshold config ([@adrum] - [#23363]) ([homekit docs]) * Add 传感器 support for dyson 2018 models ([@etheralm] - [#22578]) ([dyson docs]) (new-platform) * Bump homekit\_python to 0.14.0 ([@Jc2k] - [#23562]) ([homekit\_controller docs][homekit_controller docs]) * 升级 pysonos to 0.0.12 ([@amelchio] - [#23560]) ([sonos docs]) * Clean up ZHA discovery logic ([@dmulcahey] - [#23563]) ([zha docs]) * Migrate tests to pytest ([@emontnemery] - [#23544]) * bump zha-quirks 版本 ([@dmulcahey] - [#23568]) ([zha docs]) * Add 核心 APIs to migrate 设备 identifiers and 实体 unique\_id ([@andrewsayre] - [#23481]) * Essent 传感器 ([@TheLastProject] - [#23513]) ([essent docs]) (new-集成) (new-platform) * 升级 discord.py to v1.0.1 ([@cyrosy] - [#23523]) ([discord docs]) * Always pad mac addresses from nmap tracker with leading zeros ([@mikeage] - [#23492]) ([nmap\_tracker docs][nmap_tracker docs]) (breaking change) * 更新 mysensors 传感器 icons ([@MartinHjelmare] - [#23491]) ([mysensors docs]) * Add bypass and automatic bypass 开关 for Danfor Air. ([@JonasPed] - [#23572]) ([danfoss\_air docs][danfoss_air docs]) * Ptvsd debugger component. ([@Swamp-Ig] - [#23336]) (new-集成) * Fix min/max temp and humidity for homekit\_controller 温控 ([@Jc2k] - [#23421]) ([homekit\_controller docs][homekit_controller docs]) * Fix failing 状态 更新 tests ([@etheralm] - [#23575]) * render\_with\_collect method for 模板 ([@Swamp-Ig] - [#23283]) * 升级 youtube\_dl to 2019.04.30 ([@fabaff] - [#23579]) ([media\_extractor docs][media_extractor docs]) * Bumpped the pyeconet 版本 ([@w1ll1am23] - [#23578]) ([econet docs]) * Simplify Travis cache config ([@scop] - [#23592]) * Fix low\_battery\_threshold issue HomeKit ([@cdce8p] - [#23593]) ([homekit docs]) * Redesign AlarmControlPanel for Homematic IP ([@SukramJ] - [#23565]) ([homematicip\_cloud docs][homematicip_cloud docs]) * Ambiclimate ([@Danielhiversen] - [#22827]) ([ambiclimate docs]) (new-集成) (new-platform) * Move I/O to executor Thread pool ([@cyrosy] - [#23589]) ([discord docs]) * 更新 bomradarloop to v0.1.3 ([@maddenp] - [#23599]) * updated manifest.json with correct 版本 of hangup ([@teliov] - [#23596]) ([hangouts docs]) * Add and improve Homekit controller pairing messages and 错误 ([@Jc2k] - [#23532]) ([homekit\_controller docs][homekit_controller docs]) * Added message to data\_template at 通知 REST ([@4lloyd] - [#23108]) ([rest docs]) * Fixed unhandled exception in OpenUV data 更新 ([@bachya] - [#23611]) ([openuv docs]) * Support STATE\_AUTO in homekit\_controller 温控 ([@Jc2k] - [#23583]) ([homekit\_controller docs][homekit_controller docs]) * Add support for flow 传感器 metrics in RainMachine ([@bachya] - [#23221]) ([rainmachine docs]) * Clean caldav 日历 tests ([@MartinHjelmare] - [#23609]) * Improve sun 自动化 tests ([@emontnemery] - [#23588]) * 更新 pyvesync\_v2 版本 to 0.9.7 ([@bwarden] - [#23603]) ([vesync docs]) * Prevent turning on tellduslive 灯光 with 0 brightness ([@brange] - [#23135]) ([tellduslive docs]) * 更新 docstrings ([@fabaff] - [#23624]) ([panasonic\_bluray docs][panasonic_bluray docs]) * Order imports ([@fabaff] - [#23623]) ([opple docs]) * Polling is default ([@fabaff] - [#23622]) ([serial\_pm docs][serial_pm docs]) * Loosen discovery config validation to avoid backward-incompatible changes ([@Jc2k] - [#23625]) ([discovery docs]) * Clean up redundant same-package ..package imports ([@scop] - [#23587]) ([greeneye\_monitor docs][greeneye_monitor docs]) ([huawei\_lte docs][huawei_lte docs]) ([tplink\_lte docs][tplink_lte docs]) * 升级 pytest to 4.4.1 ([@scop] - [#23584]) * 升级 mypy ([@scop] - [#23586]) * Allow removing Telegram reply keyboard ([@max-te] - [#23467]) ([telegram\_bot docs][telegram_bot docs]) * Convert 前端 to do client-side modern JS detection ([@balloob] - [#23618]) ([前端 docs]) (breaking change) * Refactor evohome to prepare for water\_heater ([@zxdavb] - [#23489]) ([evohome docs]) * Extend play\_media support ([@andrewsayre] - [#23580]) ([heos docs]) * 更新 switchbot library ([@Danielhiversen] - [#23643]) ([switchbot docs]) * Add "soc-thermal 1" as CPU Temp label to Glances ([@phdelodder] - [#23635]) ([glances docs]) * deCONZ - Retry on BridgeBusy 错误 ([@Kane610] - [#23436]) ([deconz docs]) * Added option to select photoblack cartridge ([@ThaStealth] - [#23433]) ([epsonworkforce docs]) (breaking change) * Fix bad request for some IP ONVIF 摄像头 ([@GeertvanHorrik] - [#22972]) ([onvif docs]) * Bump pyteleloisirs 版本 ([@SNoof85] - [#23661]) * 升级 psutil to 5.6.2 ([@fabaff] - [#23671]) ([systemmonitor docs]) * 升级 shodan to 1.13.0 ([@fabaff] - [#23675]) ([shodan docs]) * 升级 slacker to 0.13.0 ([@fabaff] - [#23672]) ([slack docs]) * 升级 tapsaff to 0.2.1 ([@fabaff] - [#23676]) ([tapsaff docs]) * 升级 sqlalchemy to 1.3.3 ([@fabaff] - [#23674]) ([recorder docs]) ([sql docs]) * Remove extraneous 更新 call in SimpliSafe ([@bachya] - [#23680]) ([simplisafe docs]) * 升级 pysnmp to 4.4.9 ([@fabaff] - [#23677]) ([snmp docs]) * 升级 spotcrime to 1.0.4 (fixes #13189) ([@fabaff] - [#23679]) ([spotcrime docs]) * Add Bizkaibus, Biscays (Spain) bus 服务 component ([@UgaitzEtxebarria] - [#22934]) ([bizkaibus docs]) (new-platform) * Add HomeKit Television functionality ([@adrum] - [#22968]) ([homekit docs]) * Clean and fix google 日历 tests ([@MartinHjelmare] - [#23608]) ([google docs]) * 更新 requirements for pyvlx. ([@Julius2342] - [#23694]) ([velux docs]) * Clean up MQTT 设备 tracker tests ([@MartinHjelmare] - [#23700]) * Clean up 设备 tracker tests ([@MartinHjelmare] - [#23695]) * Move Sonos 服务 to sonos domain ([@amelchio] - [#23670]) ([sonos docs]) (breaking change) * Move owntracks 设备 tracker test under owntracks ([@MartinHjelmare] - [#23701]) * Add support for SET\_AWAY\_MODE and TURN\_ON/OFF on Daikin 温控 ([@fredrike] - [#23585]) ([daikin docs]) * Bump ZHA modules versions. ([@Adminiuga] - [#23705]) ([zha docs]) * Add additional single input cluster entries - ZHA ([@dmulcahey] - [#23697]) ([zha docs]) * Add media\_type\_app to 媒体播放器 ([@ktnrg45] - [#23666]) ([媒体播放器 docs]) ([ps4 docs]) * Add a TCP timeout of 5 seconds to ffmpeg ([@droopanu] - [#23617]) ([stream docs]) * Catch thethingsnetwork TypeError ([@fabaff] - [#23667]) ([thethingsnetwork docs]) * Use local constant in Daikin for STATE\_OFF ([@fredrike] - [#23712]) ([daikin docs]) * 升级 sendgrid to 6.0.5 ([@fabaff] - [#23711]) ([sendgrid docs]) * bump zha-quirks ([@dmulcahey] - [#23714]) ([zha docs]) * 更新 IDs after firmware 升级 in HEOS ([@andrewsayre] - [#23641]) ([heos docs]) * huawei\_lte: handle icons for None 传感器 values gracefully ([@scop] - [#23649]) ([huawei\_lte docs][huawei_lte docs]) * 升级 switchbot , fixes #23702 ([@Danielhiversen] - [#23716]) ([switchbot docs]) * Share snmp constants across all platforms ([@fabaff] - [#23678]) ([snmp docs]) (breaking change) * Add TTL support and custom headers support. ([@pszafer] - [#22988]) ([html5 docs]) * Added new 二元sensor meteoalarm to get 天气 alerts in Europe ([@rolfberkenbosch] - [#23663]) ([meteoalarm docs]) (new-集成) (new-platform) * add abbreviation for current\_temperature\_template ([@unixko] - [#23733]) ([MQTT docs]) * Add water\_heater to geniushub, bump client library ([@zxdavb] - [#23384]) ([geniushub docs]) (new-platform) * Add 调试 prints to sun ([@emontnemery] - [#23598]) ([sun docs]) * Add HEOS sign-in/out 服务 ([@andrewsayre] - [#23729]) ([heos docs]) * Fix Hue 传感器 集成 with multiple bridges. ([@mitchellrj] - [#23713]) ([hue docs]) * Fix effects on HUE 集成 for Osram bulbs ([@SukramJ] - [#22789]) ([hue docs]) * 升级 aiodns to 2.0.0 ([@fabaff] - [#23743]) ([dnsip docs]) * Add abbreviation for position\_topic ([@bieniu] - [#23740]) ([MQTT docs]) * 更新 PR 模板 ([@balloob] - [#23520]) * Add Intergas InComfort Lan2RF gateway ([@zxdavb] - [#23736]) ([incomfort docs]) (new-集成) (new-platform) * Fix upnp logger name ([@StevenLooman] - [#23724]) ([upnp docs]) * Add 更新 events to registries ([@balloob] - [#23746]) ([websocket\_api docs][websocket_api docs]) * Add 集成 step to onboarding ([@balloob] - [#23732]) ([onboarding docs]) * Merge netatmo\_public 传感器 into the netatmo 集成 ([@cgtobi] - [#23531]) ([netatmo docs]) (breaking change) * 升级 numpy to 1.16.3 ([@fabaff] - [#23673]) ([iqvia docs]) ([opencv docs]) ([tensorflow docs]) ([trend docs]) * 升级 Mastodon.py to 1.4.0 ([@fabaff] - [#23753]) ([mastodon docs]) * New 遮盖 platform for ADS 集成 ([@carstenschroeder] - [#23377]) ([ads docs]) (new-platform) * Prompt for pin only on open / unlock ([@Swamp-Ig] - [#23751]) ([google\_assistant docs][google_assistant docs]) * 升级 defusedxml to 0.6.0 ([@scop] - [#23651]) ([ihc docs]) ([namecheapdns docs]) ([ohmconnect docs]) ([upc\_connect docs][upc_connect docs]) * Refactor child validation ([@MartinHjelmare] - [#23482]) ([mysensors docs]) * 更新 Sesame component to use Candy House's library using the V3 API ([@zanglang] - [#23621]) ([sesame docs]) (breaking change) * 升级 zeroconf to 0.22.0 ([@BKPepe] - [#23524]) ([zeroconf docs]) * No longer rely on requests ([@balloob] - [#23685]) ([ps4 docs]) * Sort discovered entries by 'st' to ensure getting the same 设备 each discovery ([@StevenLooman] - [#23763]) ([upnp docs]) (beta fix) * Bump pyatmo to v1.11 ([@cgtobi] - [#23766]) ([netatmo docs]) (beta fix) * Fix for issue #23739. Added unique\_id property so ([@dreed47] - [#23769]) ([zestimate docs]) (beta fix) * Beta Fix: ONVIF ([@hunterjm] - [#23787]) ([onvif docs]) (beta fix) * Synchronize Sonos 服务 calls ([@amelchio] - [#23791]) ([sonos docs]) (beta fix) * Do not add coordinator to the ZHA 实体. ([@Adminiuga] - [#23803]) ([zha docs]) (beta fix) * fix onvif wsdl import - take 2 ([@hunterjm] - [#23807]) ([onvif docs]) (beta fix) * Correct ZHA illumination conversion ([@dmulcahey] - [#23853]) ([zha docs]) (beta fix) * Fix ZHA battery when readings produce an unknown value ([@dmulcahey] - [#23854]) ([zha docs]) (beta fix) * bump zha-quirks ([@dmulcahey] - [#23855]) ([zha docs]) (beta fix) * Fix improper usage of body 属性 on web.Response. Should be text since we arent sending bytes ([@robbiet480] - [#23857]) ([geofency docs]) ([locative docs]) ([mobile\_app docs][mobile_app docs]) (beta fix) [#20197]: https://github.com/home-assistant/home-assistant/pull/20197 [#21244]: https://github.com/home-assistant/home-assistant/pull/21244 [#21482]: https://github.com/home-assistant/home-assistant/pull/21482 [#21919]: https://github.com/home-assistant/home-assistant/pull/21919 [#21972]: https://github.com/home-assistant/home-assistant/pull/21972 [#22052]: https://github.com/home-assistant/home-assistant/pull/22052 [#22294]: https://github.com/home-assistant/home-assistant/pull/22294 [#22325]: https://github.com/home-assistant/home-assistant/pull/22325 [#22541]: https://github.com/home-assistant/home-assistant/pull/22541 [#22578]: https://github.com/home-assistant/home-assistant/pull/22578 [#22608]: https://github.com/home-assistant/home-assistant/pull/22608 [#22689]: https://github.com/home-assistant/home-assistant/pull/22689 [#22789]: https://github.com/home-assistant/home-assistant/pull/22789 [#22799]: https://github.com/home-assistant/home-assistant/pull/22799 [#22827]: https://github.com/home-assistant/home-assistant/pull/22827 [#22844]: https://github.com/home-assistant/home-assistant/pull/22844 [#22934]: https://github.com/home-assistant/home-assistant/pull/22934 [#22946]: https://github.com/home-assistant/home-assistant/pull/22946 [#22949]: https://github.com/home-assistant/home-assistant/pull/22949 [#22968]: https://github.com/home-assistant/home-assistant/pull/22968 [#22972]: https://github.com/home-assistant/home-assistant/pull/22972 [#22976]: https://github.com/home-assistant/home-assistant/pull/22976 [#22981]: https://github.com/home-assistant/home-assistant/pull/22981 [#22986]: https://github.com/home-assistant/home-assistant/pull/22986 [#22988]: https://github.com/home-assistant/home-assistant/pull/22988 [#23049]: https://github.com/home-assistant/home-assistant/pull/23049 [#23052]: https://github.com/home-assistant/home-assistant/pull/23052 [#23061]: https://github.com/home-assistant/home-assistant/pull/23061 [#23108]: https://github.com/home-assistant/home-assistant/pull/23108 [#23124]: https://github.com/home-assistant/home-assistant/pull/23124 [#23135]: https://github.com/home-assistant/home-assistant/pull/23135 [#23139]: https://github.com/home-assistant/home-assistant/pull/23139 [#23164]: https://github.com/home-assistant/home-assistant/pull/23164 [#23171]: https://github.com/home-assistant/home-assistant/pull/23171 [#23173]: https://github.com/home-assistant/home-assistant/pull/23173 [#23179]: https://github.com/home-assistant/home-assistant/pull/23179 [#23180]: https://github.com/home-assistant/home-assistant/pull/23180 [#23187]: https://github.com/home-assistant/home-assistant/pull/23187 [#23190]: https://github.com/home-assistant/home-assistant/pull/23190 [#23191]: https://github.com/home-assistant/home-assistant/pull/23191 [#23207]: https://github.com/home-assistant/home-assistant/pull/23207 [#23221]: https://github.com/home-assistant/home-assistant/pull/23221 [#23224]: https://github.com/home-assistant/home-assistant/pull/23224 [#23230]: https://github.com/home-assistant/home-assistant/pull/23230 [#23231]: https://github.com/home-assistant/home-assistant/pull/23231 [#23232]: https://github.com/home-assistant/home-assistant/pull/23232 [#23233]: https://github.com/home-assistant/home-assistant/pull/23233 [#23235]: https://github.com/home-assistant/home-assistant/pull/23235 [#23236]: https://github.com/home-assistant/home-assistant/pull/23236 [#23237]: https://github.com/home-assistant/home-assistant/pull/23237 [#23246]: https://github.com/home-assistant/home-assistant/pull/23246 [#23247]: https://github.com/home-assistant/home-assistant/pull/23247 [#23248]: https://github.com/home-assistant/home-assistant/pull/23248 [#23249]: https://github.com/home-assistant/home-assistant/pull/23249 [#23250]: https://github.com/home-assistant/home-assistant/pull/23250 [#23251]: https://github.com/home-assistant/home-assistant/pull/23251 [#23252]: https://github.com/home-assistant/home-assistant/pull/23252 [#23253]: https://github.com/home-assistant/home-assistant/pull/23253 [#23254]: https://github.com/home-assistant/home-assistant/pull/23254 [#23255]: https://github.com/home-assistant/home-assistant/pull/23255 [#23256]: https://github.com/home-assistant/home-assistant/pull/23256 [#23258]: https://github.com/home-assistant/home-assistant/pull/23258 [#23263]: https://github.com/home-assistant/home-assistant/pull/23263 [#23273]: https://github.com/home-assistant/home-assistant/pull/23273 [#23274]: https://github.com/home-assistant/home-assistant/pull/23274 [#23277]: https://github.com/home-assistant/home-assistant/pull/23277 [#23279]: https://github.com/home-assistant/home-assistant/pull/23279 [#23283]: https://github.com/home-assistant/home-assistant/pull/23283 [#23289]: https://github.com/home-assistant/home-assistant/pull/23289 [#23296]: https://github.com/home-assistant/home-assistant/pull/23296 [#23311]: https://github.com/home-assistant/home-assistant/pull/23311 [#23314]: https://github.com/home-assistant/home-assistant/pull/23314 [#23315]: https://github.com/home-assistant/home-assistant/pull/23315 [#23320]: https://github.com/home-assistant/home-assistant/pull/23320 [#23321]: https://github.com/home-assistant/home-assistant/pull/23321 [#23323]: https://github.com/home-assistant/home-assistant/pull/23323 [#23325]: https://github.com/home-assistant/home-assistant/pull/23325 [#23327]: https://github.com/home-assistant/home-assistant/pull/23327 [#23330]: https://github.com/home-assistant/home-assistant/pull/23330 [#23336]: https://github.com/home-assistant/home-assistant/pull/23336 [#23337]: https://github.com/home-assistant/home-assistant/pull/23337 [#23339]: https://github.com/home-assistant/home-assistant/pull/23339 [#23341]: https://github.com/home-assistant/home-assistant/pull/23341 [#23342]: https://github.com/home-assistant/home-assistant/pull/23342 [#23343]: https://github.com/home-assistant/home-assistant/pull/23343 [#23344]: https://github.com/home-assistant/home-assistant/pull/23344 [#23345]: https://github.com/home-assistant/home-assistant/pull/23345 [#23352]: https://github.com/home-assistant/home-assistant/pull/23352 [#23355]: https://github.com/home-assistant/home-assistant/pull/23355 [#23359]: https://github.com/home-assistant/home-assistant/pull/23359 [#23363]: https://github.com/home-assistant/home-assistant/pull/23363 [#23373]: https://github.com/home-assistant/home-assistant/pull/23373 [#23377]: https://github.com/home-assistant/home-assistant/pull/23377 [#23381]: https://github.com/home-assistant/home-assistant/pull/23381 [#23384]: https://github.com/home-assistant/home-assistant/pull/23384 [#23385]: https://github.com/home-assistant/home-assistant/pull/23385 [#23391]: https://github.com/home-assistant/home-assistant/pull/23391 [#23397]: https://github.com/home-assistant/home-assistant/pull/23397 [#23398]: https://github.com/home-assistant/home-assistant/pull/23398 [#23401]: https://github.com/home-assistant/home-assistant/pull/23401 [#23403]: https://github.com/home-assistant/home-assistant/pull/23403 [#23409]: https://github.com/home-assistant/home-assistant/pull/23409 [#23410]: https://github.com/home-assistant/home-assistant/pull/23410 [#23420]: https://github.com/home-assistant/home-assistant/pull/23420 [#23421]: https://github.com/home-assistant/home-assistant/pull/23421 [#23433]: https://github.com/home-assistant/home-assistant/pull/23433 [#23436]: https://github.com/home-assistant/home-assistant/pull/23436 [#23446]: https://github.com/home-assistant/home-assistant/pull/23446 [#23451]: https://github.com/home-assistant/home-assistant/pull/23451 [#23454]: https://github.com/home-assistant/home-assistant/pull/23454 [#23462]: https://github.com/home-assistant/home-assistant/pull/23462 [#23464]: https://github.com/home-assistant/home-assistant/pull/23464 [#23467]: https://github.com/home-assistant/home-assistant/pull/23467 [#23468]: https://github.com/home-assistant/home-assistant/pull/23468 [#23469]: https://github.com/home-assistant/home-assistant/pull/23469 [#23471]: https://github.com/home-assistant/home-assistant/pull/23471 [#23472]: https://github.com/home-assistant/home-assistant/pull/23472 [#23473]: https://github.com/home-assistant/home-assistant/pull/23473 [#23479]: https://github.com/home-assistant/home-assistant/pull/23479 [#23481]: https://github.com/home-assistant/home-assistant/pull/23481 [#23482]: https://github.com/home-assistant/home-assistant/pull/23482 [#23484]: https://github.com/home-assistant/home-assistant/pull/23484 [#23489]: https://github.com/home-assistant/home-assistant/pull/23489 [#23491]: https://github.com/home-assistant/home-assistant/pull/23491 [#23492]: https://github.com/home-assistant/home-assistant/pull/23492 [#23493]: https://github.com/home-assistant/home-assistant/pull/23493 [#23498]: https://github.com/home-assistant/home-assistant/pull/23498 [#23500]: https://github.com/home-assistant/home-assistant/pull/23500 [#23507]: https://github.com/home-assistant/home-assistant/pull/23507 [#23508]: https://github.com/home-assistant/home-assistant/pull/23508 [#23513]: https://github.com/home-assistant/home-assistant/pull/23513 [#23520]: https://github.com/home-assistant/home-assistant/pull/23520 [#23522]: https://github.com/home-assistant/home-assistant/pull/23522 [#23523]: https://github.com/home-assistant/home-assistant/pull/23523 [#23524]: https://github.com/home-assistant/home-assistant/pull/23524 [#23531]: https://github.com/home-assistant/home-assistant/pull/23531 [#23532]: https://github.com/home-assistant/home-assistant/pull/23532 [#23534]: https://github.com/home-assistant/home-assistant/pull/23534 [#23536]: https://github.com/home-assistant/home-assistant/pull/23536 [#23544]: https://github.com/home-assistant/home-assistant/pull/23544 [#23560]: https://github.com/home-assistant/home-assistant/pull/23560 [#23562]: https://github.com/home-assistant/home-assistant/pull/23562 [#23563]: https://github.com/home-assistant/home-assistant/pull/23563 [#23565]: https://github.com/home-assistant/home-assistant/pull/23565 [#23568]: https://github.com/home-assistant/home-assistant/pull/23568 [#23572]: https://github.com/home-assistant/home-assistant/pull/23572 [#23575]: https://github.com/home-assistant/home-assistant/pull/23575 [#23578]: https://github.com/home-assistant/home-assistant/pull/23578 [#23579]: https://github.com/home-assistant/home-assistant/pull/23579 [#23580]: https://github.com/home-assistant/home-assistant/pull/23580 [#23583]: https://github.com/home-assistant/home-assistant/pull/23583 [#23584]: https://github.com/home-assistant/home-assistant/pull/23584 [#23585]: https://github.com/home-assistant/home-assistant/pull/23585 [#23586]: https://github.com/home-assistant/home-assistant/pull/23586 [#23587]: https://github.com/home-assistant/home-assistant/pull/23587 [#23588]: https://github.com/home-assistant/home-assistant/pull/23588 [#23589]: https://github.com/home-assistant/home-assistant/pull/23589 [#23592]: https://github.com/home-assistant/home-assistant/pull/23592 [#23593]: https://github.com/home-assistant/home-assistant/pull/23593 [#23596]: https://github.com/home-assistant/home-assistant/pull/23596 [#23598]: https://github.com/home-assistant/home-assistant/pull/23598 [#23599]: https://github.com/home-assistant/home-assistant/pull/23599 [#23603]: https://github.com/home-assistant/home-assistant/pull/23603 [#23608]: https://github.com/home-assistant/home-assistant/pull/23608 [#23609]: https://github.com/home-assistant/home-assistant/pull/23609 [#23611]: https://github.com/home-assistant/home-assistant/pull/23611 [#23617]: https://github.com/home-assistant/home-assistant/pull/23617 [#23618]: https://github.com/home-assistant/home-assistant/pull/23618 [#23621]: https://github.com/home-assistant/home-assistant/pull/23621 [#23622]: https://github.com/home-assistant/home-assistant/pull/23622 [#23623]: https://github.com/home-assistant/home-assistant/pull/23623 [#23624]: https://github.com/home-assistant/home-assistant/pull/23624 [#23625]: https://github.com/home-assistant/home-assistant/pull/23625 [#23635]: https://github.com/home-assistant/home-assistant/pull/23635 [#23641]: https://github.com/home-assistant/home-assistant/pull/23641 [#23643]: https://github.com/home-assistant/home-assistant/pull/23643 [#23649]: https://github.com/home-assistant/home-assistant/pull/23649 [#23651]: https://github.com/home-assistant/home-assistant/pull/23651 [#23661]: https://github.com/home-assistant/home-assistant/pull/23661 [#23663]: https://github.com/home-assistant/home-assistant/pull/23663 [#23666]: https://github.com/home-assistant/home-assistant/pull/23666 [#23667]: https://github.com/home-assistant/home-assistant/pull/23667 [#23670]: https://github.com/home-assistant/home-assistant/pull/23670 [#23671]: https://github.com/home-assistant/home-assistant/pull/23671 [#23672]: https://github.com/home-assistant/home-assistant/pull/23672 [#23673]: https://github.com/home-assistant/home-assistant/pull/23673 [#23674]: https://github.com/home-assistant/home-assistant/pull/23674 [#23675]: https://github.com/home-assistant/home-assistant/pull/23675 [#23676]: https://github.com/home-assistant/home-assistant/pull/23676 [#23677]: https://github.com/home-assistant/home-assistant/pull/23677 [#23678]: https://github.com/home-assistant/home-assistant/pull/23678 [#23679]: https://github.com/home-assistant/home-assistant/pull/23679 [#23680]: https://github.com/home-assistant/home-assistant/pull/23680 [#23685]: https://github.com/home-assistant/home-assistant/pull/23685 [#23694]: https://github.com/home-assistant/home-assistant/pull/23694 [#23695]: https://github.com/home-assistant/home-assistant/pull/23695 [#23697]: https://github.com/home-assistant/home-assistant/pull/23697 [#23700]: https://github.com/home-assistant/home-assistant/pull/23700 [#23701]: https://github.com/home-assistant/home-assistant/pull/23701 [#23705]: https://github.com/home-assistant/home-assistant/pull/23705 [#23711]: https://github.com/home-assistant/home-assistant/pull/23711 [#23712]: https://github.com/home-assistant/home-assistant/pull/23712 [#23713]: https://github.com/home-assistant/home-assistant/pull/23713 [#23714]: https://github.com/home-assistant/home-assistant/pull/23714 [#23716]: https://github.com/home-assistant/home-assistant/pull/23716 [#23724]: https://github.com/home-assistant/home-assistant/pull/23724 [#23729]: https://github.com/home-assistant/home-assistant/pull/23729 [#23732]: https://github.com/home-assistant/home-assistant/pull/23732 [#23733]: https://github.com/home-assistant/home-assistant/pull/23733 [#23736]: https://github.com/home-assistant/home-assistant/pull/23736 [#23740]: https://github.com/home-assistant/home-assistant/pull/23740 [#23743]: https://github.com/home-assistant/home-assistant/pull/23743 [#23746]: https://github.com/home-assistant/home-assistant/pull/23746 [#23751]: https://github.com/home-assistant/home-assistant/pull/23751 [#23753]: https://github.com/home-assistant/home-assistant/pull/23753 [#23763]: https://github.com/home-assistant/home-assistant/pull/23763 [#23766]: https://github.com/home-assistant/home-assistant/pull/23766 [#23769]: https://github.com/home-assistant/home-assistant/pull/23769 [#23787]: https://github.com/home-assistant/home-assistant/pull/23787 [#23791]: https://github.com/home-assistant/home-assistant/pull/23791 [#23803]: https://github.com/home-assistant/home-assistant/pull/23803 [#23807]: https://github.com/home-assistant/home-assistant/pull/23807 [#23853]: https://github.com/home-assistant/home-assistant/pull/23853 [#23854]: https://github.com/home-assistant/home-assistant/pull/23854 [#23855]: https://github.com/home-assistant/home-assistant/pull/23855 [#23857]: https://github.com/home-assistant/home-assistant/pull/23857 [@4lloyd]: https://github.com/4lloyd [@Adminiuga]: https://github.com/Adminiuga [@BKPepe]: https://github.com/BKPepe [@Chris-V]: https://github.com/Chris-V [@Danielhiversen]: https://github.com/Danielhiversen [@GeertvanHorrik]: https://github.com/GeertvanHorrik [@GoNzCiD]: https://github.com/GoNzCiD [@Jc2k]: https://github.com/Jc2k [@JonasPed]: https://github.com/JonasPed [@Julius2342]: https://github.com/Julius2342 [@Kane610]: https://github.com/Kane610 [@MartinHjelmare]: https://github.com/MartinHjelmare [@SNoof85]: https://github.com/SNoof85 [@StevenLooman]: https://github.com/StevenLooman [@SukramJ]: https://github.com/SukramJ [@Swamp-Ig]: https://github.com/Swamp-Ig [@ThaStealth]: https://github.com/ThaStealth [@TheLastProject]: https://github.com/TheLastProject [@TomerFi]: https://github.com/TomerFi [@UgaitzEtxebarria]: https://github.com/UgaitzEtxebarria [@ViViDboarder]: https://github.com/ViViDboarder [@adrum]: https://github.com/adrum [@alengwenus]: https://github.com/alengwenus [@amelchio]: https://github.com/amelchio [@andrewsayre]: https://github.com/andrewsayre [@anrudolph]: https://github.com/anrudolph [@arsaboo]: https://github.com/arsaboo [@atomic7777]: https://github.com/atomic7777 [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@bdurrer]: https://github.com/bdurrer [@bieniu]: https://github.com/bieniu [@brange]: https://github.com/brange [@bwarden]: https://github.com/bwarden [@carstenschroeder]: https://github.com/carstenschroeder [@cdce8p]: https://github.com/cdce8p [@cgtobi]: https://github.com/cgtobi [@chmielowiec]: https://github.com/chmielowiec [@cyrosy]: https://github.com/cyrosy [@dmulcahey]: https://github.com/dmulcahey [@dreed47]: https://github.com/dreed47 [@droopanu]: https://github.com/droopanu [@elupus]: https://github.com/elupus [@emontnemery]: https://github.com/emontnemery [@etheralm]: https://github.com/etheralm [@evanjd]: https://github.com/evanjd [@fabaff]: https://github.com/fabaff [@flowolf]: https://github.com/flowolf [@fredrike]: https://github.com/fredrike [@hunterjm]: https://github.com/hunterjm [@itn3rd77]: https://github.com/itn3rd77 [@ktnrg45]: https://github.com/ktnrg45 [@ludeeus]: https://github.com/ludeeus [@maddenp]: https://github.com/maddenp [@max-te]: https://github.com/max-te [@mcc05]: https://github.com/mcc05 [@mikeage]: https://github.com/mikeage [@mitchellrj]: https://github.com/mitchellrj [@nielstron]: https://github.com/nielstron [@panosmz]: https://github.com/panosmz [@pascallj]: https://github.com/pascallj [@phdelodder]: https://github.com/phdelodder [@pnbruckner]: https://github.com/pnbruckner [@pszafer]: https://github.com/pszafer [@pvizeli]: https://github.com/pvizeli [@raman325]: https://github.com/raman325 [@robbiet480]: https://github.com/robbiet480 [@robmarkcole]: https://github.com/robmarkcole [@rohankapoorcom]: https://github.com/rohankapoorcom [@rolfberkenbosch]: https://github.com/rolfberkenbosch [@scop]: https://github.com/scop [@sowelie]: https://github.com/sowelie [@teliov]: https://github.com/teliov [@tsvi]: https://github.com/tsvi [@unixko]: https://github.com/unixko [@vigonotion]: https://github.com/vigonotion [@w1ll1am23]: https://github.com/w1ll1am23 [@zanglang]: https://github.com/zanglang [@zewelor]: https://github.com/zewelor [@zxdavb]: https://github.com/zxdavb [ads docs]: /integrations/ads/ [alexa docs]: /integrations/alexa/ [ambiclimate docs]: /integrations/ambiclimate/ [amcrest docs]: /integrations/amcrest/ [自动化 docs]: /integrations/自动化/ [bizkaibus docs]: /integrations/bizkaibus/ [bluesound docs]: /integrations/bluesound/ [caldav docs]: /integrations/caldav/ [cast docs]: /integrations/cast/ [counter docs]: /integrations/counter/ [daikin docs]: /integrations/daikin/ [danfoss_air docs]: /integrations/danfoss_air/ [deconz docs]: /integrations/deconz/ [discord docs]: /integrations/discord/ [discovery docs]: /integrations/discovery/ [dnsip docs]: /integrations/dnsip/ [dyson docs]: /integrations/dyson/ [econet docs]: /integrations/econet/ [enocean docs]: /integrations/enocean/ [epsonworkforce docs]: /integrations/epsonworkforce/ [essent docs]: /integrations/essent/ [evohome docs]: /integrations/evohome/ [前端 docs]: /integrations/frontend/ [geniushub docs]: /integrations/geniushub/ [geofency docs]: /integrations/geofency/ [glances docs]: /integrations/glances/ [google docs]: /integrations/google_translate [google_assistant docs]: /integrations/google_assistant/ [greeneye_monitor docs]: /integrations/greeneye_monitor/ [hangouts docs]: /integrations/hangouts/ [heos docs]: /integrations/heos/ [homekit docs]: /integrations/homekit/ [homekit_controller docs]: /integrations/homekit_controller/ [homematic docs]: /integrations/homematic/ [homematicip_cloud docs]: /integrations/homematicip_cloud/ [honeywell docs]: /integrations/honeywell/ [html5 docs]: /integrations/html5/ [huawei_lte docs]: /integrations/huawei_lte/ [hue docs]: /integrations/hue/ [ihc docs]: /integrations/ihc/ [incomfort docs]: /integrations/incomfort/ [influxdb docs]: /integrations/influxdb/ [input_datetime docs]: /integrations/input_datetime/ [iqvia docs]: /integrations/iqvia/ [lcn docs]: /integrations/lcn/ [lifx docs]: /integrations/lifx/ [local_file docs]: /integrations/local_file/ [locative docs]: /integrations/locative/ [logi_circle docs]: /integrations/logi_circle/ [mastodon docs]: /integrations/mastodon/ [media_extractor docs]: /integrations/media_extractor/ [媒体播放器 docs]: /integrations/媒体播放器/ [meteoalarm docs]: /integrations/meteoalarm/ [mobile_app docs]: /integrations/mobile_app/ [MQTT docs]: /integrations/MQTT/ [mysensors docs]: /integrations/mysensors/ [namecheapdns docs]: /integrations/namecheapdns/ [netatmo docs]: /integrations/netatmo/ [netgear_lte docs]: /integrations/netgear_lte/ [nextbus docs]: /integrations/nextbus/ [nmap_tracker docs]: /integrations/nmap_tracker/ [通知 docs]: /integrations/通知/ [oasa_telematics docs]: /integrations/oasa_telematics/ [ohmconnect docs]: /integrations/ohmconnect/ [onboarding docs]: /integrations/onboarding/ [onvif docs]: /integrations/onvif/ [opencv docs]: /integrations/opencv/ [openuv docs]: /integrations/openuv/ [opple docs]: /integrations/opple/ [orangepi_gpio docs]: /integrations/orangepi_gpio/ [otp docs]: /integrations/otp/ [panasonic_bluray docs]: /integrations/panasonic_bluray/ [philips_js docs]: /integrations/philips_js/ [plex docs]: /integrations/plex/ [pollen docs]: /integrations/iqvia [ps4 docs]: /integrations/ps4/ [rainmachine docs]: /integrations/rainmachine/ [recorder docs]: /integrations/recorder/ [rest docs]: /integrations/rest/ [sendgrid docs]: /integrations/sendgrid/ [serial_pm docs]: /integrations/serial_pm/ [sesame docs]: /integrations/sesame/ [seventeentrack docs]: /integrations/seventeentrack/ [shodan docs]: /integrations/shodan/ [simplisafe docs]: /integrations/simplisafe/ [slack docs]: /integrations/slack/ [snmp docs]: /integrations/snmp/ [sonos docs]: /integrations/sonos/ [spotcrime docs]: /integrations/spotcrime/ [sql docs]: /integrations/sql/ [startca docs]: /integrations/startca/ [stream docs]: /integrations/stream/ [sun docs]: /integrations/sun/ [switchbot docs]: /integrations/switchbot/ [switcher_kis docs]: /integrations/switcher_kis/ [syncthru docs]: /integrations/syncthru/ [systemmonitor docs]: /integrations/systemmonitor/ [tapsaff docs]: /integrations/tapsaff/ [ted5000 docs]: /integrations/ted5000/ [telegram_bot docs]: /integrations/telegram_bot/ [tellduslive docs]: /integrations/tellduslive/ [tensorflow docs]: /integrations/tensorflow/ [thethingsnetwork docs]: /integrations/thethingsnetwork/ [tplink_lte docs]: /integrations/tplink_lte/ [traccar docs]: /integrations/traccar/ [trend docs]: /integrations/trend/ [upc_connect docs]: /integrations/upc_connect/ [upnp docs]: /integrations/upnp/ [velux docs]: /integrations/velux/ [vesync docs]: /integrations/vesync/ [vizio docs]: /integrations/vizio/ [websocket_api docs]: /integrations/websocket_api/ [xiaomi_aqara docs]: /integrations/xiaomi_aqara/ [xmpp docs]: /integrations/xmpp/ [yeelight docs]: /integrations/yeelight/ [zeroconf docs]: /integrations/zeroconf/ [zestimate docs]: /integrations/zestimate/ [zha docs]: /integrations/zha/ [zwave docs]: /integrations/zwave/ --- url: /home-assistant/blog/2019-06-05-release-94.md --- # 0.94: SmartHab, Watson TTS, Azure Event Hub 又到了 0.94 发布,这次带来了不少非常棒的内容。我们正在努力打磨各个部分,为重大的 Home Assistant 1.0 发布做准备,而且已经越来越接近了。甚至接近到:这是第一个无需接触文本编辑器就能完成安装和配置的版本!从引导、配置集成,到管理自动化和脚本,都可以直接在 UI 中完成。
This milestone has been achieved thanks to the hard work by [@emontnemery] who contributed the ability to store the 核心 config in storage: name, location, unit system, time 区域. We still allow 用户 to store their 核心 配置 in `configuration.yaml`, which will take precedent when defined. This means that it is a non-breaking change. 核心 config is now set during onboarding and can be edited in the general page of the config 面板. Another cool new feature is the total revamp of how you manage which 实体 are exposed to Google Assistant via Home Assistant Cloud. From the cloud UI you can now click "Manage 实体" and you are brought to the Google Assistant 实体 manager. From here you can enable which 实体 are exposed and, if you deem appropriate, choose to disable the two factor 认证 on your garage door (the asking for a pin).

Screenshot of the new 用户 interface to manage which 实体 are exposed to Google Assistant. Screenshot of the new 用户 interface to manage which 实体 are exposed to Google Assistant.

## 发现 Discovery has been modernized thanks to [@Kane610] and with the input from [@Jc2k]. Each 集成 is now able to specify how they can be discovered in their manifest, and the new `zeroconf` and `ssdp` 集成 will do the rest. The new discovery is non-obtrusive: no 设备 are set up without approval by the 用户. Instead, you will need to approve each discovered 集成. You can find them in the discovered section of the 集成 page in the config. Only a handful of 集成 have been migrated to the new approach in this 发布: Hue, LIFX, Deconz, Trådfri, Axis, ESPHome, HomeKit Controller. The new discovery is now part of the default config. If you are not using the default config, add `ssdp:` and `zeroconf:` to your 配置.yaml. ## 弃用 Python 3.5 支持 This 发布 has deprecated support for the almost 4 year old 版本 3.5 of Python. The first Home Assistant 发布 after August 1 will drop support. This is part of our newly adopted [Python support approach](https://github.com/home-assistant/architecture/blob/master/adr/0002-minimum-supported-python-版本.md). This will only impact you if you are running a custom 安装 of Home Assistant. This will not impact anyone using Hass.io or Docker. If you are using hassbian, you can 升级 Python by following [these instructions](https://github.com/home-assistant/hassbian-脚本/blob/dev/docs/suites/python.md). ## 现代化设备追踪器 This 发布 also introduces a long overdue overhaul of how the 设备 tracker works. We are introducing this overhaul piece by piece, focusing first on 设备 tracker platforms that push their updates to Home Assistant: mobile app, OwnTracks, GeoFency, GPSLogger and Locative. These 集成 will no longer use `known_devices.yaml` but instead use 实体, like all other 集成 in Home Assistant. You can change the name and 实体 ID via the UI. It is no longer posible to merge the 设备 with other 设备 tracker 实体, this includes using the `see` 服务. This was flaky at best. You should now use the new person 集成 for this. ## 改进后的 Hass.io 构建流程 We have been working hard on improving Hass.io builds. It's our goal to make the 更新 process faster and more predictable. A build can now be online in as little as 30 minutes after a new 发布 has been tagged. This is thanks to a new wheel-based infrastructure build by [@pvizeli] with input from [@frenck]. With Python wheels, we will build all the requirements of 集成 ahead of time, and so a new 版本 of Home Assistant is now just putting pieces together. Because of this, we changed how packages are 已安装 when running Home Assistant inside a Docker 容器. It will now 安装 the packages into the Python environment inside the 容器, instead of storing them in the `config/deps` folder, which lived outside the 容器. **Note:** Because of the new way packages are 已安装, Home Assistant on Hass.io will take longer to start the first time it is launched after an 升级. Don't worry and let it finish! We are working on making this process faster in the future. **Note 2:** If you are using Hass.io or a dockerized 版本 of Home Assistant, this 发布 will one time clear the `deps` folder in your config folder. [@frenck]: https://github.com/frenck ## New 集成 * Adding Watson TTS (IBM Cloud) ([@rutkai] - [#23299]) ([watson\_tts docs][watson_tts docs]) (new-集成) * MCP23017 ([@jardiamj] - [#23127]) ([mcp23017 docs]) (new-集成) * Solax Inverter 传感器 Component ([@squishykid] - [#22579]) ([solax docs]) (new-集成) * Add 遥控器 RPi Component ([@jgriff2] - [#23518]) ([remote\_rpi\_gpio docs][remote_rpi_gpio docs]) (new-集成) * Azure Event Hub history component ([@eavanvalkenburg] - [#23878]) ([azure\_event\_hub docs][azure_event_hub docs]) (new-集成) * Add SSDP 集成 ([@balloob] - [#24090]) ([default\_config docs][default_config docs]) ([discovery docs]) ([hue docs]) ([ssdp docs]) ([zeroconf docs]) (new-集成) * Add Repetier-Server Component ([@MTrab] - [#21658]) ([repetier docs]) (new-集成) ## New Platforms * Add LCN 温控 platform ([@alengwenus] - [#22542]) ([lcn docs]) (new-platform) * Add incomfort 温控 and bump client ([@zxdavb] - [#23830]) ([incomfort docs]) (new-platform) * Add new SmartHab 灯光 and 遮盖 platform ([@outadoc] - [#21225]) ([smarthab docs]) (new-platform) * Add geniushub 传感器 and binary\_sensor ([@zxdavb] - [#23811]) ([geniushub docs]) (new-platform) * Mobile app to use 设备 tracker config entry ([@balloob] - [#24238]) ([mobile\_app docs][mobile_app docs]) (beta fix) (new-platform) ## 发布 0.94.1 - June 7 * Add a discovery config flow to Wemo ([@balloob] - [#24208]) ([discovery docs]) ([wemo docs]) * Initiate websession inside event loop ([@balloob] - [#24331]) ([tado docs]) * Bump dependency ([@Kane610] - [#24376]) ([axis docs]) * Updated pubnubsub-handler to 1.0.7 to fix crash on slow startup ([@w1ll1am23] - [#24388]) ([wink docs]) * Fix 自动化 failing to 恢复 状态 ([@balloob] - [#24390]) ([自动化 docs]) * Add more HomeKit models for discovery ([@balloob] - [#24391]) ([homekit\_controller docs][homekit_controller docs]) ([hue docs]) ([tradfri docs]) ([wemo docs]) * Check cloud trusted proxies ([@balloob] - [#24395]) ([cloud docs]) ([http docs]) * Fix for sun issues ([@Swamp-Ig] - [#24309]) ([sun docs]) * deCONZ - properly identify configured bridge ([@Kane610] - [#24378]) ([deconz docs]) [#24208]: https://github.com/home-assistant/home-assistant/pull/24208 [#24309]: https://github.com/home-assistant/home-assistant/pull/24309 [#24331]: https://github.com/home-assistant/home-assistant/pull/24331 [#24376]: https://github.com/home-assistant/home-assistant/pull/24376 [#24378]: https://github.com/home-assistant/home-assistant/pull/24378 [#24388]: https://github.com/home-assistant/home-assistant/pull/24388 [#24390]: https://github.com/home-assistant/home-assistant/pull/24390 [#24391]: https://github.com/home-assistant/home-assistant/pull/24391 [#24395]: https://github.com/home-assistant/home-assistant/pull/24395 [@Kane610]: https://github.com/Kane610 [@Swamp-Ig]: https://github.com/Swamp-Ig [@balloob]: https://github.com/balloob [@w1ll1am23]: https://github.com/w1ll1am23 [自动化 docs]: /integrations/自动化/ [axis docs]: /integrations/axis/ [cloud docs]: /integrations/cloud/ [deconz docs]: /integrations/deconz/ [discovery docs]: /integrations/discovery/ [homekit_controller docs]: /integrations/homekit_controller/ [http docs]: /integrations/http/ [hue docs]: /integrations/hue/ [sun docs]: /integrations/sun/ [tado docs]: /integrations/tado/ [tradfri docs]: /integrations/tradfri/ [wemo docs]: /integrations/wemo/ [wink docs]: /integrations/wink/ ## 发布 0.94.2 - June 11 * Load the SSDP component only when it's needed ([@aerialls] - [#24420]) ([deconz docs]) ([hue docs]) * Axis discovery MAC filter ([@Kane610] - [#24442]) ([axis docs]) * Remember gpslogger 实体 across restarts (fixes #24432) ([@andkit] - [#24444]) ([gpslogger docs]) * 更新 Hass.io when 核心 config is updated ([@balloob] - [#24461]) ([hassio docs]) * Sun listener to adapt to 核心 config updates ([@balloob] - [#24464]) * 更新 home 区域 when 核心 config updated ([@balloob] - [#24237]) ([config docs]) ([区域 docs]) [#24237]: https://github.com/home-assistant/home-assistant/pull/24237 [#24420]: https://github.com/home-assistant/home-assistant/pull/24420 [#24442]: https://github.com/home-assistant/home-assistant/pull/24442 [#24444]: https://github.com/home-assistant/home-assistant/pull/24444 [#24461]: https://github.com/home-assistant/home-assistant/pull/24461 [#24464]: https://github.com/home-assistant/home-assistant/pull/24464 [@Kane610]: https://github.com/Kane610 [@aerialls]: https://github.com/aerialls [@andkit]: https://github.com/andkit [@balloob]: https://github.com/balloob [axis docs]: /integrations/axis/ [config docs]: /integrations/config/ [deconz docs]: /integrations/deconz/ [gpslogger docs]: /integrations/gpslogger/ [hassio docs]: /integrations/hassio/ [hue docs]: /integrations/hue/ [区域 docs]: /integrations/区域/ ## 发布 0.94.3 - June 12 * Fix 错误 when renewing 遥控器 UI certs ([@balloob] - [#24481]) ([cloud docs]) * Watson TTS: Fix missing comma preventing other voices ([@aidbish] - [#24487]) ([watson\_tts docs][watson_tts docs]) * Fix owntracks source\_type for location messages with default 触发器 ([@pnbruckner] - [#24503]) ([owntracks docs]) [#24481]: https://github.com/home-assistant/home-assistant/pull/24481 [#24487]: https://github.com/home-assistant/home-assistant/pull/24487 [#24503]: https://github.com/home-assistant/home-assistant/pull/24503 [@aidbish]: https://github.com/aidbish [@balloob]: https://github.com/balloob [@pnbruckner]: https://github.com/pnbruckner [cloud docs]: /integrations/cloud/ [owntracks docs]: /integrations/owntracks/ [watson_tts docs]: /integrations/watson_tts/ ## 发布 0.94.4 - June 19 * Fixing tplink issues with offline 设备 during 设置 ([@vangorra] - [#23668]) ([tplink docs]) * Fix zeroconf migration messing up ESPHome discovery ([@OttoWinter] - [#24578]) ([esphome docs]) * Fixed issue #24335 ([@Swamp-Ig] - [#24612]) ([sun docs]) [#23668]: https://github.com/home-assistant/home-assistant/pull/23668 [#24578]: https://github.com/home-assistant/home-assistant/pull/24578 [#24612]: https://github.com/home-assistant/home-assistant/pull/24612 [@OttoWinter]: https://github.com/OttoWinter [@Swamp-Ig]: https://github.com/Swamp-Ig [@vangorra]: https://github.com/vangorra [esphome docs]: /integrations/esphome/ [sun docs]: /integrations/sun/ [tplink docs]: /integrations/tplink/ ## 如果你需要帮助…… ……欢迎随时使用我们非常活跃的[论坛](https://community.home-assistant.io/),或者加入我们的 [聊天频道](https://discord.gg/c5DvZ4e)。虽然发布说明也开放评论,但我们更希望你优先使用前面的沟通渠道。谢谢。 ## 反馈问题 如果这次发布引入了问题,请前往我们的 [issue tracker](https://github.com/home-assistant/home-assistant/issues) 提交反馈。请务必填写 issue 模板中的所有字段。 ## Backward-incompatible changes * **Sun** - Inspired by a [reddit](https://www.reddit.com/r/homeassistant/comments/bm62hl/sunsun_chatty_sensor_psa/) report, the sun.sun 传感器 has been tuned so that it doesn't 更新 nearly as frequently. Previously the sun.sun 传感器 was updating every 30 seconds, day and night. Now it updates dependent on the solar elevation. This could possibly be a breaking change for some 用户 as it updates less frequently. ([@Swamp-Ig] - [#23832]) ([sun docs]) * **Doorbird** -*Refactored*- This change cleans up the code for the component quite a bit. Schedule manipulation has been removed and HTTP views have been consolidated. The 配置 changes should result in an overall easier experience for setting up a Doorbird in HA and allow for new Doorbird events to be utilized without having to 更新 the component as often. No changes for 开关 or 摄像头 集成 of this component. ([@oblogic7] - [#23892]) ([doorbird docs]) Example 配置: ```yaml doorbird: devices: - host: 10.10.10.10 token: 12345678abcd name: Side Entry username: abcd1234 password: abcd4321 events: - button_1 - unit_1_button - movement - relay_1 - lock_relay ``` * **Plex** * 配置 option `include_non_clients` has been removed. The component was unnecessarily complicated with separate 更新 methods for Plex 设备 and Plex sessions. This change always updates all known Plex clients regardless of type. The previous design also had issues where the Plex sessions are never polled if there are no Plex clients connected at startup and only 'session' client types connect after that point. This leads to a failure to discover new 设备. This is a breaking change if the config option `include_non_clients` is being used since it has been removed. ([@jjlawren] - [#24038]) ([plex docs]) * 配置 options use\_custom\_entity\_ids and entity\_namespace have been removed. This change will prepend the display name (and therefore the default entity\_id) of each newly 创建 实体 with 'Plex' for easy identification. 用户 may customize each display name and entity\_id as desired via the 实体 Registry. 实体 创建 before this PR will not be affected as the unique\_id remains the same. ([@jjlawren] - [#24072]) ([plex docs]) * **Verisure** - Base entity\_id of alarm\_control\_panel on alias of 安装 set by giid rather than first 安装. This is a breaking change as it will change entity\_id of alarm\_control\_panel in cases where a 用户 is configuring an 安装 using giid that is not the first 安装. ([@tkjacobsen] - [#23606]) ([verisure docs]) * **Zestimate** - Changed name property to return Zestimate and the property address. This will make it easier to distinguish multiple Zestimate 传感器 实体 in the UI and is a breaking change as it will change entity\_id of Zestimate 传感器. If you have 自动化 relying on your Zestimate 传感器(s) you may need to revisit them to fix the ID's to the new ones. Also, you may need to 更新 your Zestimate 传感器(s) in your Lovelace UI. ([@dreed47] - [#23770]) ([zestimate docs]) * **Python** - *Deprecation* - Python 3.5.3 support will be removed in the first 发布 after August 1, 2019. This 发布 will print a 警告 if a soon to be unsupported Python 版本 is used. A 通知 will be present if Home Assistant is run under 3.6.0. ([@balloob] - [#24177]) * **Async** - *Developers only* - `hass.components.frontend.async_register_built_in_panel` is no longer an async function. This allows removing 面板 form the 前端 on the fly, and fires and event when 面板 are added/removed so the 前端 knows when to 重载. ([@balloob] - [#24184]) * **TP-Link** - *Distress Signal* - Add a deprecation 警告 for tplink device\_tracker ([@rytilahti] - [#24236]) ([tplink docs]) ## Beta Fixes * Dynamic 面板 ([@balloob] - [#24184]) (breaking change) (beta fix) * Fix ESPHome discovered when already exists ([@OttoWinter] - [#24187]) ([esphome docs]) (beta fix) * homekit\_controller no longer 日志 with transient network 错误 causing crypto failures as it will auto recover ([@Jc2k] - [#24193]) ([homekit\_controller docs][homekit_controller docs]) (beta fix) * 更新 hass-nabucasa ([@balloob] - [#24197]) ([cloud docs]) (beta fix) * Bump oauthlib 版本 ([@therve] - [#24111]) ([fitbit docs]) (beta fix) * Allow discovery flows to be discovered via zeroconf/ssdp ([@balloob] - [#24199]) (beta fix) * Instantiate 门锁 inside event loop ([@balloob] - [#24203]) (beta fix) * Improve 错误 handling ([@balloob] - [#24204]) ([ssdp docs]) (beta fix) * Axis - Handle Vapix 错误 messages ([@Kane610] - [#24215]) ([axis docs]) (beta fix) * Don't follow redirect on ingress itself ([@pvizeli] - [#24218]) ([hassio docs]) (beta fix) * Use resource for index routing. ([@balloob] - [#24223]) ([前端 docs]) (beta fix) * Add manifest support for homekit discovery ([@balloob] - [#24225]) ([lifx docs]) ([zeroconf docs]) (beta fix) * 日志 HomeKit model ([@balloob] - [#24229]) ([homekit\_controller docs][homekit_controller docs]) (beta fix) * Don't allow more than one config flow per discovered Axis 设备 ([@Kane610] - [#24230]) ([axis docs]) (beta fix) * Add GPSLogger device\_info and unique\_id ([@balloob] - [#24231]) ([gpslogger docs]) (beta fix) * GeoFency unique ID and 设备 info ([@balloob] - [#24232]) ([geofency docs]) (beta fix) * add a deprecation 警告 for tplink device\_tracker ([@rytilahti] - [#24236]) ([tplink docs]) (breaking change) (beta fix) * Mobile app to use 设备 tracker config entry ([@balloob] - [#24238]) ([mobile\_app docs][mobile_app docs]) (beta fix) (new-platform) * Do not use the cache dir for PIP installs ([@balloob] - [#24233]) (beta fix) * Add 恢复 状态 to OwnTracks 设备 tracker ([@balloob] - [#24256]) ([owntracks docs]) (beta fix) * Mobile app 设备 tracker to 恢复 状态 ([@balloob] - [#24266]) ([mobile\_app docs][mobile_app docs]) (beta fix) * Add 恢复 状态 to Geofency ([@balloob] - [#24268]) ([geofency docs]) (beta fix) * deCONZ migrate to SSDP discovery ([@Kane610] - [#24252]) ([deconz docs]) ([hue docs]) ([ssdp docs]) (beta fix) * Add temperature 传感器 support to google smarthome thermostat 设备 ([@piitaya] - [#24264]) ([google\_assistant docs][google_assistant docs]) (beta fix) * Bump aioesphomeapi to 2.1.0 ([@OttoWinter] - [#24278]) ([esphome docs]) (beta fix) * Fix cors on the index view ([@balloob] - [#24283]) ([http docs]) (beta fix) * Remove deps folder in config when on Docker ([@balloob] - [#24284]) (beta fix) * Guard against bad 状态 in Mobile App/OwnTracks ([@balloob] - [#24292]) ([mobile\_app docs][mobile_app docs]) ([owntracks docs]) (beta fix) * Create progress file for pip installs ([@pvizeli] - [#24297]) (beta fix) * Run SSDP discovery in parallel ([@balloob] - [#24299]) ([ssdp docs]) (beta fix) * 升级 Zeroconf to 0.23 ([@balloob] - [#24300]) ([zeroconf docs]) (beta fix) * address is deprecated in favor of addresses ([@Kane610] - [#24302]) ([zeroconf docs]) (beta fix) * Fix OwnTracks race 条件 ([@balloob] - [#24303]) ([owntracks docs]) (beta fix) ## All changes * Add 在场 Detector Indoor to Homematic IP ([@SukramJ] - [#23755]) ([homematicip\_cloud docs][homematicip_cloud docs]) * Split up yaml loaders into multiple files ([@ties] - [#23774]) * Add config entry for IQVIA ([@bachya] - [#23765]) ([iqvia docs]) * Add stepped volume to demo ([@elupus] - [#23759]) ([demo docs]) * Add battery 二元sensor to homematic ([@sander76] - [#23067]) ([homematic docs]) * fix two times creating JWT headers. ([@pszafer] - [#23777]) ([html5 docs]) * Bumped keenetic NDMS2 client 版本 ([@foxel] - [#23786]) ([keenetic\_ndms2 docs][keenetic_ndms2 docs]) * Add support for an external step in config flow ([@balloob] - [#23782]) * Centralize geniushub updates ([@zxdavb] - [#23764]) ([geniushub docs]) * Move tests to right folder ([@balloob] - [#23790]) * Add LCN 温控 platform ([@alengwenus] - [#22542]) ([lcn docs]) (new-platform) * Bump venstarcolortouch to v0.7 ([@stbenjam] - [#23806]) ([venstar docs]) * 升级 youtube\_dl to 2019.05.11 ([@fabaff] - [#23808]) ([media\_extractor docs][media_extractor docs]) * Bump pyotgw to 0.4b4, fix Opentherm Gateway name in manifest.json ([@mvn23] - [#23810]) ([opentherm\_gw docs][opentherm_gw docs]) * Fix patching right import ([@balloob] - [#23816]) * Add incomfort 温控 and bump client ([@zxdavb] - [#23830]) ([incomfort docs]) (new-platform) * Make broadlink 开关 恢复 its 状态 ([@akloeckner] - [#23829]) ([broadlink docs]) * Catch import 错误 when processing config ([@balloob] - [#23833]) * Remove badges from README \[skipci] ([@balloob] - [#23815]) * HomeKit Controller: Adopt config entries for pairing with homekit accessories ([@Jc2k] - [#23825]) ([discovery docs]) ([homekit\_controller docs][homekit_controller docs]) * Automatically generate config flow list ([@balloob] - [#23802]) * Add new SmartHab 灯光 and 遮盖 platform ([@outadoc] - [#21225]) ([smarthab docs]) (new-platform) * Daikin adaptions for AirBase units ([@fredrike] - [#23734]) ([daikin docs]) * Fix for battery 设备: new\_device referenced before assignment. ([@sander76] - [#23793]) ([homematic docs]) * Better handle large amounts of data being sent over WS ([@balloob] - [#23842]) ([摄像头 docs]) ([Lovelace docs]) ([媒体播放器 docs]) ([websocket\_api docs][websocket_api docs]) * Zeroconf - replace library ([@Kane610] - [#23835]) ([zeroconf docs]) * WS: Improve 服务 calling 错误 ([@balloob] - [#23840]) ([脚本 docs]) ([websocket\_api docs][websocket_api docs]) * Allow deletion of 自动化 and 脚本 ([@balloob] - [#23845]) ([config docs]) * Use Cloudhooks for OwnTracks ([@balloob] - [#23847]) ([owntracks docs]) * Fix aiohttp response serialize ([@balloob] - [#23858]) ([cloud docs]) * Add geniushub 传感器 and binary\_sensor ([@zxdavb] - [#23811]) ([geniushub docs]) (new-platform) * Quiet the chatty sun.sun ([@Swamp-Ig] - [#23832]) ([sun docs]) (breaking change) * Take code owner for sun.sun ([@Swamp-Ig] - [#23877]) ([sun docs]) * Fix homekit test assert no messages ([@scop] - [#23856]) * Restructure 设备 tracker ([@balloob] - [#23862]) ([device\_tracker docs][device_tracker docs]) * 更新 Pynetgear to v0.6.1 ([@starkillerOG] - [#23886]) ([netgear docs]) * Fix ecobee 3 homekit pairing ([@Jc2k] - [#23882]) ([homekit\_controller docs][homekit_controller docs]) * Enable Homematic IP cloud 温控 设备 with HeatingThermostat only ([@SukramJ] - [#23776]) ([homematicip\_cloud docs][homematicip_cloud docs]) * Load HA 核心 config from storage ([@emontnemery] - [#23872]) * Netatmo, handle offline 设备 ([@Danielhiversen] - [#23907]) ([netatmo docs]) * \[WIP] Simplify zeroconf ([@robbiet480] - [#23890]) ([zeroconf docs]) * 版本 bump insteonplm to 0.15.4 ([@nugget] - [#23918]) * Fix bug when IQVIA API fails to return data ([@bachya] - [#23916]) ([iqvia docs]) * Fix icons for homekit\_controller 传感器 ([@Jc2k] - [#23921]) ([homekit\_controller docs][homekit_controller docs]) * Fix additional IQVIA data bug ([@bachya] - [#23931]) ([iqvia docs]) * Have homekit\_controller use 设备 registry ([@Jc2k] - [#23874]) ([homekit\_controller docs][homekit_controller docs]) * Fix for non existing Daikin 区域 ([@fredrike] - [#23792]) ([daikin docs]) * Fix 风扇 rates for Daikin ([@fredrike] - [#23860]) ([daikin docs]) * Added support for 传感器 other than temperature and humidity ([@Bouni] - [#23863]) ([spaceapi docs]) * Add unit of measurement to Tautulli 传感器 ([@SiliconAvatar] - [#23873]) ([tautulli docs]) * 更新 requests to 2.22.0 ([@BKPepe] - [#23958]) * show battery level also when 吸尘器 has no map support ([@adrianschroeter] - [#23947]) ([neato docs]) * Upate xiaomi voltage parser, fix #23898 ([@Danielhiversen] - [#23962]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * Doorbird Refactor ([@oblogic7] - [#23892]) ([doorbird docs]) (breaking change) * 更新 russound\_rio dependency to 版本 0.1.7 ([@wickerwaka] - [#23973]) ([russound\_rio docs][russound_rio docs]) * Adding Watson TTS (IBM Cloud) ([@rutkai] - [#23299]) ([watson\_tts docs][watson_tts docs]) (new-集成) * 实体 Cleanup on Z-Wave node removal ([@cgarwood] - [#23633]) ([zwave docs]) * Use the timezone defined in Home Assistant when making the API call ([@ludeeus] - [#23284]) ([vasttrafik docs]) * Updated non-blocking timout to 10 seconds for fixing timeout issues. ([@TomerFi] - [#23930]) ([switcher\_kis docs][switcher_kis docs]) * Delete 设备 / 实体 when we remove a config entry. ([@Swamp-Ig] - [#23983]) * Better handle file not found when loading YAML ([@balloob] - [#23908]) ([apns docs]) ([http docs]) * daikin 版本 bump ([@fredrike] - [#23991]) ([daikin docs]) * Bump loopenergy library 版本 - catches runtime exception. ([@pavoni] - [#23989]) ([loopenergy docs]) * 更新 owner 前端 集成 \[skip ci] ([@balloob] - [#24001]) ([前端 docs]) ([Lovelace docs]) ([panel\_custom docs][panel_custom docs]) ([panel\_iframe docs][panel_iframe docs]) * Axis IO-port support ([@Kane610] - [#23312]) ([axis docs]) * Fire event when 核心 config is updated ([@emontnemery] - [#23922]) * 更新 CODEOWNERS ([@emontnemery] - [#24015]) * Add websocket API for updating 核心 config ([@emontnemery] - [#24009]) ([config docs]) * Add geniushub 传感器 for issues ([@zxdavb] - [#23976]) ([geniushub docs]) * Fix iterating over NoneType exception ([@iamtpage] - [#23648]) ([darksky docs]) * bump geniushub-client to 0.4.9 ([@zxdavb] - [#24022]) ([geniushub docs]) * Zeroconf discovery for config entries ([@Kane610] - [#23919]) ([axis docs]) ([zeroconf docs]) * Improve yeelight imports ([@zewelor] - [#24020]) ([yeelight docs]) * Downgrade Hue 警告 ([@balloob] - [#24033]) ([hue docs]) * Ambiclimate test, mock ([@Danielhiversen] - [#24034]) * 升级 Mastodon.py to 1.4.2 ([@fabaff] - [#24004]) ([mastodon docs]) * Require 核心 config detection to be triggerd manually ([@balloob] - [#24019]) ([config docs]) ([onboarding docs]) * Don't pass in loop ([@balloob] - [#23984]) * 更新 ambiclimate library ([@Danielhiversen] - [#24049]) ([ambiclimate docs]) * ESPHome component to use zeroconf discovery ([@Kane610] - [#24043]) ([esphome docs]) * Add support for available property for broadlink ([@Danielhiversen] - [#23981]) ([broadlink docs]) * Always 更新 all Plex client types ([@jjlawren] - [#24038]) ([plex docs]) (breaking change) * Convert stream source to method ([@balloob] - [#23905]) * Fix 实体 id naming when not using first 安装 ([@tkjacobsen] - [#23606]) ([verisure docs]) (breaking change) * Daikin airbase beta fixes ([@fredrike] - [#24050]) ([daikin docs]) * Better logging of method used for ADB connection ([@JeffLIrion] - [#24037]) ([androidtv docs]) * Fix zeroconf sorting ([@balloob] - [#24068]) * Rfxtrx, add data types ([@Danielhiversen] - [#24066]) ([rfxtrx docs]) * 更新 the name of Zestimate 传感器 ([@dreed47] - [#23770]) ([zestimate docs]) (breaking change) * Added possibility to define the data type of Homematic ([@p0l0] - [#24078]) ([homematic docs]) * Add 'adb\_response' 属性 to Android TV / Fire TV ([@JeffLIrion] - [#23960]) ([androidtv docs]) * Adjust logging ([@elupus] - [#24082]) * Fix Hue bridge timeout ([@terual] - [#24084]) ([hue docs]) * MCP23017 ([@jardiamj] - [#23127]) ([mcp23017 docs]) (new-集成) * Remove 设备 tracker unnecessary separate except clause ([@elupus] - [#24081]) ([device\_tracker docs][device_tracker docs]) * Refactoring of LCN component ([@alengwenus] - [#23824]) ([lcn docs]) * 更新 code owner for Xiaomi TV ([@simse] - [#24102]) ([xiaomi\_tv docs][xiaomi_tv docs]) * Issue #23514 - fix invalid hue response ([@techfreek] - [#23909]) ([emulated\_hue docs][emulated_hue docs]) * Config entry 设备 tracker ([@balloob] - [#24040]) ([device\_tracker docs][device_tracker docs]) ([geofency docs]) ([gpslogger docs]) ([icloud docs]) ([locative docs]) ([owntracks docs]) ([区域 docs]) * Solax Inverter 传感器 Component ([@squishykid] - [#22579]) ([solax docs]) (new-集成) * Set assumed\_state property to True. ([@jardiamj] - [#24118]) ([mcp23017 docs]) * Remove custom entity\_id naming ([@jjlawren] - [#24072]) ([plex docs]) (breaking change) * Move imports to top ([@andrewsayre] - [#24108]) ([heos docs]) * Use name in ESPHome discovery title ([@OttoWinter] - [#24100]) * Add 遥控器 RPi Component ([@jgriff2] - [#23518]) ([remote\_rpi\_gpio docs][remote_rpi_gpio docs]) (new-集成) * Azure Event Hub history component ([@eavanvalkenburg] - [#23878]) ([azure\_event\_hub docs][azure_event_hub docs]) (new-集成) * geniushub: fix 传感器 battery level, and bump client ([@zxdavb] - [#24123]) ([geniushub docs]) * Use importlib metadata to check 已安装 packages ([@balloob] - [#24114]) * Avoid useless Sonos 状态 updates ([@amelchio] - [#24135]) ([sonos docs]) * Add SSDP 集成 ([@balloob] - [#24090]) ([default\_config docs][default_config docs]) ([discovery docs]) ([hue docs]) ([ssdp docs]) ([zeroconf docs]) (new-集成) * Lovelace: Fire event on save ([@bramkragten] - [#24104]) ([Lovelace docs]) * Use central polling to 更新 实体 ([@jjlawren] - [#24059]) ([plex docs]) * Library refactorization of deCONZ ([@Kane610] - [#23725]) ([deconz docs]) * Retrieve wire and wireless 设备 with the SRM 设备 tracker ([@aerialls] - [#24117]) ([synology\_srm docs][synology_srm docs]) * bump dependency envoy\_reader to 0.4 ([@jesserizzo] - [#24145]) ([enphase\_envoy docs][enphase_envoy docs]) * 调试 日志 when polling ZHA 灯光. ([@Adminiuga] - [#24167]) ([zha docs]) * 升级 huawei-lte-api to 1.2.0 ([@chmielowiec] - [#24165]) ([huawei\_lte docs][huawei_lte docs]) * Use 设备 name for device\_tracker entry ([@robbiet480] - [#24155]) ([mobile\_app docs][mobile_app docs]) * Use global imports for ESPHome ([@OttoWinter] - [#24158]) ([esphome docs]) * Add Repetier-Server Component ([@MTrab] - [#21658]) ([repetier docs]) (new-集成) * Cloud: Websocket API to manage Google assistant 实体 config ([@balloob] - [#24153]) ([cloud docs]) ([google\_assistant docs][google_assistant docs]) * Fix calling 通知.通知 with mobile\_app targets in play. Fixes #24064 ([@robbiet480] - [#24156]) ([mobile\_app docs][mobile_app docs]) * Remove unused Sonos 打开/off methods ([@amelchio] - [#24174]) ([sonos docs]) * Reinstate passing loop to DSMR ([@balloob] - [#24127]) ([dsmr docs]) * Trådfri component to use new zeroconf discovery ([@Kane610] - [#24041]) ([discovery docs]) ([tradfri docs]) * Move Homekit controller component to 用户 zeroconf discovery ([@Kane610] - [#24042]) ([discovery docs]) ([homekit\_controller docs][homekit_controller docs]) * Revert Zeroconf back to previously used library ([@Kane610] - [#24139]) ([zeroconf docs]) * Deprecate Python 3.5.3 ([@balloob] - [#24177]) (breaking change) * Keep 集成 in discovery ([@Kane610] - [#24179]) ([discovery docs]) * Avoid slow updates with unavailable Sonos 设备 ([@amelchio] - [#24180]) ([sonos docs]) * Support Hass.io wheels / Docker env ([@pvizeli] - [#24175]) * Remove discovery from initial config ([@balloob] - [#24183]) * Fix duplicated discovered homekit 设备 ([@Jc2k] - [#24178]) ([homekit\_controller docs][homekit_controller docs]) * Add 服务 calls for LCN component ([@alengwenus] - [#24105]) ([lcn docs]) * 更新 azure-pipelines.yml for check 版本 ([@pvizeli] - [#24194]) * Dynamic 面板 ([@balloob] - [#24184]) (breaking change) (beta fix) * Fix ESPHome discovered when already exists ([@OttoWinter] - [#24187]) ([esphome docs]) (beta fix) * homekit\_controller no longer 日志 with transient network 错误 causing crypto failures as it will auto recover ([@Jc2k] - [#24193]) ([homekit\_controller docs][homekit_controller docs]) (beta fix) * 更新 hass-nabucasa ([@balloob] - [#24197]) ([cloud docs]) (beta fix) * Fix ESPHome config flow with invalid config entry ([@OttoWinter] - [#24213]) ([esphome docs]) * Bump oauthlib 版本 ([@therve] - [#24111]) ([fitbit docs]) (beta fix) * Allow discovery flows to be discovered via zeroconf/ssdp ([@balloob] - [#24199]) (beta fix) * Instantiate 门锁 inside event loop ([@balloob] - [#24203]) (beta fix) * Improve 错误 handling ([@balloob] - [#24204]) ([ssdp docs]) (beta fix) * Axis - Handle Vapix 错误 messages ([@Kane610] - [#24215]) ([axis docs]) (beta fix) * Don't follow redirect on ingress itself ([@pvizeli] - [#24218]) ([hassio docs]) (beta fix) * Use resource for index routing. ([@balloob] - [#24223]) ([前端 docs]) (beta fix) * Add manifest support for homekit discovery ([@balloob] - [#24225]) ([lifx docs]) ([zeroconf docs]) (beta fix) * 日志 HomeKit model ([@balloob] - [#24229]) ([homekit\_controller docs][homekit_controller docs]) (beta fix) * Don't allow more than one config flow per discovered Axis 设备 ([@Kane610] - [#24230]) ([axis docs]) (beta fix) * Add GPSLogger device\_info and unique\_id ([@balloob] - [#24231]) ([gpslogger docs]) (beta fix) * GeoFency unique ID and 设备 info ([@balloob] - [#24232]) ([geofency docs]) (beta fix) * add a deprecation 警告 for tplink device\_tracker ([@rytilahti] - [#24236]) ([tplink docs]) (breaking change) (beta fix) * Mobile app to use 设备 tracker config entry ([@balloob] - [#24238]) ([mobile\_app docs][mobile_app docs]) (beta fix) (new-platform) * Do not use the cache dir for PIP installs ([@balloob] - [#24233]) (beta fix) * Add 恢复 状态 to OwnTracks 设备 tracker ([@balloob] - [#24256]) ([owntracks docs]) (beta fix) * Mobile app 设备 tracker to 恢复 状态 ([@balloob] - [#24266]) ([mobile\_app docs][mobile_app docs]) (beta fix) * Add 恢复 状态 to Geofency ([@balloob] - [#24268]) ([geofency docs]) (beta fix) * deCONZ migrate to SSDP discovery ([@Kane610] - [#24252]) ([deconz docs]) ([hue docs]) ([ssdp docs]) (beta fix) * Add temperature 传感器 support to google smarthome thermostat 设备 ([@piitaya] - [#24264]) ([google\_assistant docs][google_assistant docs]) (beta fix) * Bump aioesphomeapi to 2.1.0 ([@OttoWinter] - [#24278]) ([esphome docs]) (beta fix) * Fix cors on the index view ([@balloob] - [#24283]) ([http docs]) (beta fix) * Remove deps folder in config when on Docker ([@balloob] - [#24284]) (beta fix) * Guard against bad 状态 in Mobile App/OwnTracks ([@balloob] - [#24292]) ([mobile\_app docs][mobile_app docs]) ([owntracks docs]) (beta fix) * Create progress file for pip installs ([@pvizeli] - [#24297]) (beta fix) * Run SSDP discovery in parallel ([@balloob] - [#24299]) ([ssdp docs]) (beta fix) * 升级 Zeroconf to 0.23 ([@balloob] - [#24300]) ([zeroconf docs]) (beta fix) * address is deprecated in favor of addresses ([@Kane610] - [#24302]) ([zeroconf docs]) (beta fix) * Fix OwnTracks race 条件 ([@balloob] - [#24303]) ([owntracks docs]) (beta fix) [#21225]: https://github.com/home-assistant/home-assistant/pull/21225 [#21658]: https://github.com/home-assistant/home-assistant/pull/21658 [#22542]: https://github.com/home-assistant/home-assistant/pull/22542 [#22579]: https://github.com/home-assistant/home-assistant/pull/22579 [#23067]: https://github.com/home-assistant/home-assistant/pull/23067 [#23127]: https://github.com/home-assistant/home-assistant/pull/23127 [#23284]: https://github.com/home-assistant/home-assistant/pull/23284 [#23299]: https://github.com/home-assistant/home-assistant/pull/23299 [#23312]: https://github.com/home-assistant/home-assistant/pull/23312 [#23518]: https://github.com/home-assistant/home-assistant/pull/23518 [#23606]: https://github.com/home-assistant/home-assistant/pull/23606 [#23633]: https://github.com/home-assistant/home-assistant/pull/23633 [#23648]: https://github.com/home-assistant/home-assistant/pull/23648 [#23725]: https://github.com/home-assistant/home-assistant/pull/23725 [#23734]: https://github.com/home-assistant/home-assistant/pull/23734 [#23755]: https://github.com/home-assistant/home-assistant/pull/23755 [#23759]: https://github.com/home-assistant/home-assistant/pull/23759 [#23764]: https://github.com/home-assistant/home-assistant/pull/23764 [#23765]: https://github.com/home-assistant/home-assistant/pull/23765 [#23770]: https://github.com/home-assistant/home-assistant/pull/23770 [#23774]: https://github.com/home-assistant/home-assistant/pull/23774 [#23776]: https://github.com/home-assistant/home-assistant/pull/23776 [#23777]: https://github.com/home-assistant/home-assistant/pull/23777 [#23782]: https://github.com/home-assistant/home-assistant/pull/23782 [#23786]: https://github.com/home-assistant/home-assistant/pull/23786 [#23790]: https://github.com/home-assistant/home-assistant/pull/23790 [#23792]: https://github.com/home-assistant/home-assistant/pull/23792 [#23793]: https://github.com/home-assistant/home-assistant/pull/23793 [#23802]: https://github.com/home-assistant/home-assistant/pull/23802 [#23806]: https://github.com/home-assistant/home-assistant/pull/23806 [#23808]: https://github.com/home-assistant/home-assistant/pull/23808 [#23810]: https://github.com/home-assistant/home-assistant/pull/23810 [#23811]: https://github.com/home-assistant/home-assistant/pull/23811 [#23815]: https://github.com/home-assistant/home-assistant/pull/23815 [#23816]: https://github.com/home-assistant/home-assistant/pull/23816 [#23824]: https://github.com/home-assistant/home-assistant/pull/23824 [#23825]: https://github.com/home-assistant/home-assistant/pull/23825 [#23829]: https://github.com/home-assistant/home-assistant/pull/23829 [#23830]: https://github.com/home-assistant/home-assistant/pull/23830 [#23832]: https://github.com/home-assistant/home-assistant/pull/23832 [#23833]: https://github.com/home-assistant/home-assistant/pull/23833 [#23835]: https://github.com/home-assistant/home-assistant/pull/23835 [#23840]: https://github.com/home-assistant/home-assistant/pull/23840 [#23842]: https://github.com/home-assistant/home-assistant/pull/23842 [#23845]: https://github.com/home-assistant/home-assistant/pull/23845 [#23847]: https://github.com/home-assistant/home-assistant/pull/23847 [#23856]: https://github.com/home-assistant/home-assistant/pull/23856 [#23858]: https://github.com/home-assistant/home-assistant/pull/23858 [#23860]: https://github.com/home-assistant/home-assistant/pull/23860 [#23862]: https://github.com/home-assistant/home-assistant/pull/23862 [#23863]: https://github.com/home-assistant/home-assistant/pull/23863 [#23872]: https://github.com/home-assistant/home-assistant/pull/23872 [#23873]: https://github.com/home-assistant/home-assistant/pull/23873 [#23874]: https://github.com/home-assistant/home-assistant/pull/23874 [#23877]: https://github.com/home-assistant/home-assistant/pull/23877 [#23878]: https://github.com/home-assistant/home-assistant/pull/23878 [#23882]: https://github.com/home-assistant/home-assistant/pull/23882 [#23886]: https://github.com/home-assistant/home-assistant/pull/23886 [#23890]: https://github.com/home-assistant/home-assistant/pull/23890 [#23892]: https://github.com/home-assistant/home-assistant/pull/23892 [#23905]: https://github.com/home-assistant/home-assistant/pull/23905 [#23907]: https://github.com/home-assistant/home-assistant/pull/23907 [#23908]: https://github.com/home-assistant/home-assistant/pull/23908 [#23909]: https://github.com/home-assistant/home-assistant/pull/23909 [#23916]: https://github.com/home-assistant/home-assistant/pull/23916 [#23918]: https://github.com/home-assistant/home-assistant/pull/23918 [#23919]: https://github.com/home-assistant/home-assistant/pull/23919 [#23921]: https://github.com/home-assistant/home-assistant/pull/23921 [#23922]: https://github.com/home-assistant/home-assistant/pull/23922 [#23930]: https://github.com/home-assistant/home-assistant/pull/23930 [#23931]: https://github.com/home-assistant/home-assistant/pull/23931 [#23947]: https://github.com/home-assistant/home-assistant/pull/23947 [#23958]: https://github.com/home-assistant/home-assistant/pull/23958 [#23960]: https://github.com/home-assistant/home-assistant/pull/23960 [#23962]: https://github.com/home-assistant/home-assistant/pull/23962 [#23973]: https://github.com/home-assistant/home-assistant/pull/23973 [#23976]: https://github.com/home-assistant/home-assistant/pull/23976 [#23981]: https://github.com/home-assistant/home-assistant/pull/23981 [#23983]: https://github.com/home-assistant/home-assistant/pull/23983 [#23984]: https://github.com/home-assistant/home-assistant/pull/23984 [#23989]: https://github.com/home-assistant/home-assistant/pull/23989 [#23991]: https://github.com/home-assistant/home-assistant/pull/23991 [#24001]: https://github.com/home-assistant/home-assistant/pull/24001 [#24004]: https://github.com/home-assistant/home-assistant/pull/24004 [#24009]: https://github.com/home-assistant/home-assistant/pull/24009 [#24015]: https://github.com/home-assistant/home-assistant/pull/24015 [#24019]: https://github.com/home-assistant/home-assistant/pull/24019 [#24020]: https://github.com/home-assistant/home-assistant/pull/24020 [#24022]: https://github.com/home-assistant/home-assistant/pull/24022 [#24033]: https://github.com/home-assistant/home-assistant/pull/24033 [#24034]: https://github.com/home-assistant/home-assistant/pull/24034 [#24037]: https://github.com/home-assistant/home-assistant/pull/24037 [#24038]: https://github.com/home-assistant/home-assistant/pull/24038 [#24040]: https://github.com/home-assistant/home-assistant/pull/24040 [#24041]: https://github.com/home-assistant/home-assistant/pull/24041 [#24042]: https://github.com/home-assistant/home-assistant/pull/24042 [#24043]: https://github.com/home-assistant/home-assistant/pull/24043 [#24049]: https://github.com/home-assistant/home-assistant/pull/24049 [#24050]: https://github.com/home-assistant/home-assistant/pull/24050 [#24059]: https://github.com/home-assistant/home-assistant/pull/24059 [#24066]: https://github.com/home-assistant/home-assistant/pull/24066 [#24068]: https://github.com/home-assistant/home-assistant/pull/24068 [#24072]: https://github.com/home-assistant/home-assistant/pull/24072 [#24078]: https://github.com/home-assistant/home-assistant/pull/24078 [#24081]: https://github.com/home-assistant/home-assistant/pull/24081 [#24082]: https://github.com/home-assistant/home-assistant/pull/24082 [#24084]: https://github.com/home-assistant/home-assistant/pull/24084 [#24090]: https://github.com/home-assistant/home-assistant/pull/24090 [#24100]: https://github.com/home-assistant/home-assistant/pull/24100 [#24102]: https://github.com/home-assistant/home-assistant/pull/24102 [#24104]: https://github.com/home-assistant/home-assistant/pull/24104 [#24105]: https://github.com/home-assistant/home-assistant/pull/24105 [#24108]: https://github.com/home-assistant/home-assistant/pull/24108 [#24111]: https://github.com/home-assistant/home-assistant/pull/24111 [#24114]: https://github.com/home-assistant/home-assistant/pull/24114 [#24117]: https://github.com/home-assistant/home-assistant/pull/24117 [#24118]: https://github.com/home-assistant/home-assistant/pull/24118 [#24123]: https://github.com/home-assistant/home-assistant/pull/24123 [#24127]: https://github.com/home-assistant/home-assistant/pull/24127 [#24135]: https://github.com/home-assistant/home-assistant/pull/24135 [#24139]: https://github.com/home-assistant/home-assistant/pull/24139 [#24145]: https://github.com/home-assistant/home-assistant/pull/24145 [#24153]: https://github.com/home-assistant/home-assistant/pull/24153 [#24155]: https://github.com/home-assistant/home-assistant/pull/24155 [#24156]: https://github.com/home-assistant/home-assistant/pull/24156 [#24158]: https://github.com/home-assistant/home-assistant/pull/24158 [#24165]: https://github.com/home-assistant/home-assistant/pull/24165 [#24167]: https://github.com/home-assistant/home-assistant/pull/24167 [#24174]: https://github.com/home-assistant/home-assistant/pull/24174 [#24175]: https://github.com/home-assistant/home-assistant/pull/24175 [#24177]: https://github.com/home-assistant/home-assistant/pull/24177 [#24178]: https://github.com/home-assistant/home-assistant/pull/24178 [#24179]: https://github.com/home-assistant/home-assistant/pull/24179 [#24180]: https://github.com/home-assistant/home-assistant/pull/24180 [#24183]: https://github.com/home-assistant/home-assistant/pull/24183 [#24184]: https://github.com/home-assistant/home-assistant/pull/24184 [#24187]: https://github.com/home-assistant/home-assistant/pull/24187 [#24193]: https://github.com/home-assistant/home-assistant/pull/24193 [#24194]: https://github.com/home-assistant/home-assistant/pull/24194 [#24197]: https://github.com/home-assistant/home-assistant/pull/24197 [#24199]: https://github.com/home-assistant/home-assistant/pull/24199 [#24203]: https://github.com/home-assistant/home-assistant/pull/24203 [#24204]: https://github.com/home-assistant/home-assistant/pull/24204 [#24213]: https://github.com/home-assistant/home-assistant/pull/24213 [#24215]: https://github.com/home-assistant/home-assistant/pull/24215 [#24218]: https://github.com/home-assistant/home-assistant/pull/24218 [#24223]: https://github.com/home-assistant/home-assistant/pull/24223 [#24225]: https://github.com/home-assistant/home-assistant/pull/24225 [#24229]: https://github.com/home-assistant/home-assistant/pull/24229 [#24230]: https://github.com/home-assistant/home-assistant/pull/24230 [#24231]: https://github.com/home-assistant/home-assistant/pull/24231 [#24232]: https://github.com/home-assistant/home-assistant/pull/24232 [#24233]: https://github.com/home-assistant/home-assistant/pull/24233 [#24236]: https://github.com/home-assistant/home-assistant/pull/24236 [#24238]: https://github.com/home-assistant/home-assistant/pull/24238 [#24252]: https://github.com/home-assistant/home-assistant/pull/24252 [#24256]: https://github.com/home-assistant/home-assistant/pull/24256 [#24264]: https://github.com/home-assistant/home-assistant/pull/24264 [#24266]: https://github.com/home-assistant/home-assistant/pull/24266 [#24268]: https://github.com/home-assistant/home-assistant/pull/24268 [#24278]: https://github.com/home-assistant/home-assistant/pull/24278 [#24283]: https://github.com/home-assistant/home-assistant/pull/24283 [#24284]: https://github.com/home-assistant/home-assistant/pull/24284 [#24292]: https://github.com/home-assistant/home-assistant/pull/24292 [#24297]: https://github.com/home-assistant/home-assistant/pull/24297 [#24299]: https://github.com/home-assistant/home-assistant/pull/24299 [#24300]: https://github.com/home-assistant/home-assistant/pull/24300 [#24302]: https://github.com/home-assistant/home-assistant/pull/24302 [#24303]: https://github.com/home-assistant/home-assistant/pull/24303 [@Adminiuga]: https://github.com/Adminiuga [@BKPepe]: https://github.com/BKPepe [@Bouni]: https://github.com/Bouni [@Danielhiversen]: https://github.com/Danielhiversen [@Jc2k]: https://github.com/Jc2k [@JeffLIrion]: https://github.com/JeffLIrion [@Kane610]: https://github.com/Kane610 [@MTrab]: https://github.com/MTrab [@OttoWinter]: https://github.com/OttoWinter [@SiliconAvatar]: https://github.com/SiliconAvatar [@SukramJ]: https://github.com/SukramJ [@Swamp-Ig]: https://github.com/Swamp-Ig [@TomerFi]: https://github.com/TomerFi [@adrianschroeter]: https://github.com/adrianschroeter [@aerialls]: https://github.com/aerialls [@akloeckner]: https://github.com/akloeckner [@alengwenus]: https://github.com/alengwenus [@amelchio]: https://github.com/amelchio [@andrewsayre]: https://github.com/andrewsayre [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@bramkragten]: https://github.com/bramkragten [@cgarwood]: https://github.com/cgarwood [@chmielowiec]: https://github.com/chmielowiec [@dreed47]: https://github.com/dreed47 [@eavanvalkenburg]: https://github.com/eavanvalkenburg [@elupus]: https://github.com/elupus [@emontnemery]: https://github.com/emontnemery [@fabaff]: https://github.com/fabaff [@foxel]: https://github.com/foxel [@fredrike]: https://github.com/fredrike [@iamtpage]: https://github.com/iamtpage [@jardiamj]: https://github.com/jardiamj [@jesserizzo]: https://github.com/jesserizzo [@jgriff2]: https://github.com/jgriff2 [@jjlawren]: https://github.com/jjlawren [@ludeeus]: https://github.com/ludeeus [@mvn23]: https://github.com/mvn23 [@nugget]: https://github.com/nugget [@oblogic7]: https://github.com/oblogic7 [@outadoc]: https://github.com/outadoc [@p0l0]: https://github.com/p0l0 [@pavoni]: https://github.com/pavoni [@piitaya]: https://github.com/piitaya [@pszafer]: https://github.com/pszafer [@pvizeli]: https://github.com/pvizeli [@robbiet480]: https://github.com/robbiet480 [@rutkai]: https://github.com/rutkai [@rytilahti]: https://github.com/rytilahti [@sander76]: https://github.com/sander76 [@scop]: https://github.com/scop [@simse]: https://github.com/simse [@squishykid]: https://github.com/squishykid [@starkillerOG]: https://github.com/starkillerOG [@stbenjam]: https://github.com/stbenjam [@techfreek]: https://github.com/techfreek [@terual]: https://github.com/terual [@therve]: https://github.com/therve [@ties]: https://github.com/ties [@tkjacobsen]: https://github.com/tkjacobsen [@wickerwaka]: https://github.com/wickerwaka [@zewelor]: https://github.com/zewelor [@zxdavb]: https://github.com/zxdavb [ambiclimate docs]: /integrations/ambiclimate/ [androidtv docs]: /integrations/androidtv/ [apns docs]: /integrations/apns/ [axis docs]: /integrations/axis/ [azure_event_hub docs]: /integrations/azure_event_hub/ [broadlink docs]: /integrations/broadlink/ [摄像头 docs]: /integrations/摄像头/ [cloud docs]: /integrations/cloud/ [config docs]: /integrations/config/ [daikin docs]: /integrations/daikin/ [darksky docs]: /integrations/darksky/ [deconz docs]: /integrations/deconz/ [default_config docs]: /integrations/default_config/ [demo docs]: /integrations/demo/ [device_tracker docs]: /integrations/device_tracker/ [discovery docs]: /integrations/discovery/ [doorbird docs]: /integrations/doorbird/ [dsmr docs]: /integrations/dsmr/ [emulated_hue docs]: /integrations/emulated_hue/ [enphase_envoy docs]: /integrations/enphase_envoy/ [esphome docs]: /integrations/esphome/ [fitbit docs]: /integrations/fitbit/ [前端 docs]: /integrations/frontend/ [geniushub docs]: /integrations/geniushub/ [geofency docs]: /integrations/geofency/ [google_assistant docs]: /integrations/google_assistant/ [gpslogger docs]: /integrations/gpslogger/ [hassio docs]: /integrations/hassio/ [heos docs]: /integrations/heos/ [homekit_controller docs]: /integrations/homekit_controller/ [homematic docs]: /integrations/homematic/ [homematicip_cloud docs]: /integrations/homematicip_cloud/ [html5 docs]: /integrations/html5/ [http docs]: /integrations/http/ [huawei_lte docs]: /integrations/huawei_lte/ [hue docs]: /integrations/hue/ [icloud docs]: /integrations/icloud/ [incomfort docs]: /integrations/incomfort/ [iqvia docs]: /integrations/iqvia/ [keenetic_ndms2 docs]: /integrations/keenetic_ndms2/ [lcn docs]: /integrations/lcn/ [lifx docs]: /integrations/lifx/ [locative docs]: /integrations/locative/ [loopenergy docs]: /integrations/loopenergy/ [Lovelace docs]: /integrations/Lovelace/ [mastodon docs]: /integrations/mastodon/ [mcp23017 docs]: /integrations/mcp23017/ [media_extractor docs]: /integrations/media_extractor/ [媒体播放器 docs]: /integrations/媒体播放器/ [mobile_app docs]: /integrations/mobile_app/ [neato docs]: /integrations/neato/ [netatmo docs]: /integrations/netatmo/ [netgear docs]: /integrations/netgear/ [onboarding docs]: /integrations/onboarding/ [opentherm_gw docs]: /integrations/opentherm_gw/ [owntracks docs]: /integrations/owntracks/ [panel_custom docs]: /integrations/panel_custom/ [panel_iframe docs]: /integrations/panel_iframe/ [plex docs]: /integrations/plex/ [remote_rpi_gpio docs]: /integrations/remote_rpi_gpio/ [repetier docs]: /integrations/repetier/ [rfxtrx docs]: /integrations/rfxtrx/ [russound_rio docs]: /integrations/russound_rio/ [脚本 docs]: /integrations/脚本/ [smarthab docs]: /integrations/smarthab/ [solax docs]: /integrations/solax/ [sonos docs]: /integrations/sonos/ [spaceapi docs]: /integrations/spaceapi/ [ssdp docs]: /integrations/ssdp/ [sun docs]: /integrations/sun/ [switcher_kis docs]: /integrations/switcher_kis/ [synology_srm docs]: /integrations/synology_srm/ [tautulli docs]: /integrations/tautulli/ [tplink docs]: /integrations/tplink/ [tradfri docs]: /integrations/tradfri/ [vasttrafik docs]: /integrations/vasttrafik/ [venstar docs]: /integrations/venstar/ [verisure docs]: /integrations/verisure/ [watson_tts docs]: /integrations/watson_tts/ [websocket_api docs]: /integrations/websocket_api/ [xiaomi_aqara docs]: /integrations/xiaomi_aqara/ [xiaomi_tv docs]: /integrations/xiaomi_tv/ [yeelight docs]: /integrations/yeelight/ [zeroconf docs]: /integrations/zeroconf/ [zestimate docs]: /integrations/zestimate/ [zha docs]: /integrations/zha/ [区域 docs]: /integrations/区域/ [zwave docs]: /integrations/zwave/ --- url: /home-assistant/blog/2019-06-26-release-95.md --- # 0.95: AdGuard, Life360, Plaato Airlock 又到了 0.95 发布,猜猜怎样?它很棒!先说重点,你看到[全新的树莓派 4](https://www.raspberrypi.org/博客/raspberry-pi-4-on-sale-now-from-35/) 了吗?速度是 3 代的 3 倍、千兆网口现在真的能跑满千兆、内存读写更快,总之几乎所有方面都更快![跑分表现相当亮眼。](https://www.raspberrypi.org/magpi/raspberry-pi-4-specs-benchmarks/) 最棒的是?基础售价保持不变。当然,你现在也可以花更多钱买到更大内存的升级款,如果你喜欢安装各种 hass.io 插件,这会非常合适。 说到 Hass.io 支持,我们已经收到了设备,适配工作很快就会开始 🚀。既然聊到树莓派,顺便快速说一句 SD 卡吧?质量真的很重要。买 SD 卡时尽量选择专业版,最好是 [A1 级](https://www.amazon.com/dp/B073JYVKNX),更好的是 [A2 级](https://www.amazon.com/dp/B07G3GMRYF)。A 代表 application,这类卡是为运行应用而优化的,比如 Home Assistant。 ## 房车助手 Home Assistant is not just limited to homes. Recently we had a boat owner on [Home Assistant podcast episode 48](https://hasspodcast.io/ha048/), and Home Assistant also powers recreational vehicles (RV) ([like this schoolbus](https://thisisthebus.com/our-tech-stack.html)). With this 发布, we're making integrating Home Assistant into moving vehicles so much easier. In the last 发布, we introduced support for the 核心 config to be updated without restarting Home Assistant. This 发布 brings it a step further and introduces a new 服务 `homeassistant.set_location`. With this 服务, you can automatically change the location that Home Assistant is located. Once updated, it automatically updates all the things that rely on the location, like your sunset 触发器 and your current 天气 (only [Met][met docs] supported now). ## AdGuard Home - 本地广告与追踪器拦截 Here at Home Assistant, we're big 风扇 of privacy and we're always working on improving it. So this brings us to [AdGuard](https://adguard.com/). AdGuard Home is a local DNS server that automatically blocks any 设备 looking up a domain that is used to serve ads, spreads malware, or isn't appropriate for your kids. Thanks to [@frenck], starting 发布 0.95, it has a top-notch 集成 with Home Assistant: * One-click 安装 the AdGuard 插件 from the [Community Hass.io Add-ons](https://github.com/hassio-addons/repository/blob/master/README.md). * Home Assistant automatically detects the Hass.io 插件 and offers to set it up. (It works with standalone installs too, see the [AdGuard 集成 文档][adguard docs] on how to 配置 it.) * DONE! One cool new feature: because parental control is now available as a 开关, you can control AdGuard via Alexa and Google: "Hey Google, 打开 parental control" 😲.

Screenshot of Frenck during his stream demoing AdGuard. Frenck shows a demo of the AdGuard 集成 during his stream. See the demo.

## Life360 More goodies. Keep paying attention as we're not done yet. Also new in 0.95 is the [Life360 集成][life360 docs] thanks to the hard work by [@pnbruckner]. 此integrations started its life a little over 360 days ago [on the forums as a custom 集成](https://community.home-assistant.io/t/life360-devices-tracker-platform/52406) and has now become part of Home Assistant. Life360 is an app to allow friends or family members to share location with each other. If you are migrating from the custom 集成, [please read the instructions](https://community.home-assistant.io/t/life360-devices-tracker-platform/52406/1077). ## 改进后的 Alexa 集成 One more thing… This 发布 improves the Home Assistant Cloud Alexa 集成. Just like Google Assistant, it is now possible to manage which 实体 are exposed to Amazon via the 用户 interface. Alexa actually offers some cool features around this. Any change you make is instantly reflected inside Alexa. Add an 实体? Control it instantly via Alexa. However, we didn't stop there. The [manual installations of Alexa](/home-assistant/integrations/alexa.smart_home/index.md#alexa-component-configuration) has had optional proactive 状态 reporting since earlier this year, and this is now available for Home Assistant Cloud 用户 too. If you choose to opt-in to this, every 状态 change of your exposed 实体 is sent to Amazon as soon as they happen. It allows Amazon Echos with displays, to instantly reflect the 状态 and allows you to create routines inside Amazon powered by your Home Assistant 实体.
## 更多可用图标 [Austin Andrews](https://twitter.com/templarian), the lead designer of Material Design Icons, informed us that Material Design Icons 3.7.95 has been released. It includes a handful of the top requested Home Assistant icons (and a total of 100 new icons!). ## 值得注意的不兼容变更 For the last couple of releases, we've been printing 警告 if your 配置 contained invalid slugs or extra keys. Starting with this 发布, these 警告 are now 错误. No procrastination anymore, you'll need to fix it now. We have also realized that the default database clean up task never automatically ran as intended. Instead of running every night, cleaning up your history so that it only contains the last 10 days, it never ran. Oopsie. We've fixed it in this 发布, so now the defaults kick in. Want to adjust how much history you want to retain? Check [the docs][recorder docs]. ## New 集成 * Adds AdGuard Home 集成 ([@frenck] - [#24219]) ([adguard docs]) (new-集成) * SolarEdge Local Component ([@drobtravels] - [#23996]) ([solaredge\_local docs][solaredge_local docs]) (new-集成) * Google Cloud Platform component (TTS) ([@lufton] - [#23629]) ([google\_cloud docs][google_cloud docs]) (new-集成) * Life360 集成 ([@pnbruckner] - [#24227]) ([life360 docs]) (new-集成) * Adds 集成 for Plaato Airlock ([@JohNan] - [#23727]) ([plaato docs]) (new-集成) * Queensland bushfire alert feed platform ([@exxamalte] - [#24473]) ([qld\_bushfire docs][qld_bushfire docs]) (new-集成) * Vlc telnet ([@rodripf] - [#24290]) ([vlc\_telnet docs][vlc_telnet docs]) (beta fix) (new-集成) ## New Platforms * Add LCN 场景 platform ([@alengwenus] - [#24242]) ([lcn docs]) (new-platform) * Add Environment Canada 天气, 传感器, and 摄像头 platforms ([@michaeldavie] - [#21110]) ([environment\_canada docs][environment_canada docs]) (new-platform) * Support for Salda Smarty XV/XP Ventilation Unit ([@z0mbieprocess] - [#21491]) ([smarty docs]) (new-platform) * Add support for ZHA door 门锁 #2 ([@presslab-us] - [#24344]) ([zha docs]) (new-platform) * Somfy open api ([@tetienne] - [#19548]) ([somfy docs]) (new-platform) * Add APRS 设备 tracker component ([@PhilRW] - [#22469]) ([aprs docs]) (new-platform) * 摄像头 platform for buienradar imagery ([@ties] - [#23358]) ([buienradar docs]) (new-platform) * Add incomfort 传感器 and binary\_sensor ([@zxdavb] - [#23812]) ([incomfort docs]) (new-platform) * Added ELV PCA 301 smart emeter 开关 ([@majuss] - [#23300]) ([elv docs]) (new-platform) ## 发布 0.95.1 - June 26 * Fix life360 exception when no location provided ([@pnbruckner] - [#24777]) ([life360 docs]) * Pubnub to 1.0.8 ([@w1ll1am23] - [#24781]) ([wink docs]) * Catch uncaught Alexa 错误 ([@balloob] - [#24785]) ([cloud docs]) [#24777]: https://github.com/home-assistant/home-assistant/pull/24777 [#24781]: https://github.com/home-assistant/home-assistant/pull/24781 [#24785]: https://github.com/home-assistant/home-assistant/pull/24785 [@balloob]: https://github.com/balloob [@pnbruckner]: https://github.com/pnbruckner [@w1ll1am23]: https://github.com/w1ll1am23 [cloud docs]: /integrations/cloud/ [life360 docs]: /integrations/life360/ [wink docs]: /integrations/wink/ ## 发布 0.95.2 - June 28 * Fix netatmo weatherstation 设置 错误 ([@cgtobi] - [#24788]) ([netatmo docs]) * 更新 azure-pipelines-发布.yml for Azure Pipelines ([@pvizeli] - [#24800]) * Make sure 实体 config is never none ([@balloob] - [#24801]) ([google\_assistant docs][google_assistant docs]) * Bump ZHA quirks module ([@dmulcahey] - [#24802]) ([zha docs]) * Fix another Life360 bug ([@pnbruckner] - [#24805]) ([life360 docs]) * Fix calling empty 脚本 关闭 ([@balloob] - [#24827]) ([脚本 docs]) [#24788]: https://github.com/home-assistant/home-assistant/pull/24788 [#24800]: https://github.com/home-assistant/home-assistant/pull/24800 [#24801]: https://github.com/home-assistant/home-assistant/pull/24801 [#24802]: https://github.com/home-assistant/home-assistant/pull/24802 [#24805]: https://github.com/home-assistant/home-assistant/pull/24805 [#24827]: https://github.com/home-assistant/home-assistant/pull/24827 [@balloob]: https://github.com/balloob [@cgtobi]: https://github.com/cgtobi [@dmulcahey]: https://github.com/dmulcahey [@pnbruckner]: https://github.com/pnbruckner [@pvizeli]: https://github.com/pvizeli [google_assistant docs]: /integrations/google_assistant/ [life360 docs]: /integrations/life360/ [netatmo docs]: /integrations/netatmo/ [脚本 docs]: /integrations/脚本/ [zha docs]: /integrations/zha/ ## 发布 0.95.3 - June 28 * Alexa sync 状态 report ([@balloob] - [#24835]) ([cloud docs]) [#24835]: https://github.com/home-assistant/home-assistant/pull/24835 [@balloob]: https://github.com/balloob [cloud docs]: /integrations/cloud/ ## 发布 0.95.4 - June 28 * Improve autodiscovered yeelights model detection ([@zewelor] - [#24671]) ([yeelight docs]) * Guard for None 实体 config ([@balloob] - [#24838]) ([alexa docs]) ([cloud docs]) [#24671]: https://github.com/home-assistant/home-assistant/pull/24671 [#24838]: https://github.com/home-assistant/home-assistant/pull/24838 [@balloob]: https://github.com/balloob [@zewelor]: https://github.com/zewelor [alexa docs]: /integrations/alexa/ [cloud docs]: /integrations/cloud/ [yeelight docs]: /integrations/yeelight/ ## 如果你需要帮助…… ……欢迎随时使用我们非常活跃的[论坛](https://community.home-assistant.io/),或者加入我们的 [聊天频道](https://discord.gg/c5DvZ4e)。 ## 反馈问题 如果这次发布引入了问题,请前往我们的 [issue tracker](https://github.com/home-assistant/home-assistant/issues) 提交反馈。请务必填写 issue 模板中的所有字段。 ## Backward-incompatible changes * No longer allow invalid slugs or extra keys ([@balloob] - [#24176]) (breaking change) * Add 服务 for adding event to google component ([@isabellaalstrom] - [#22473]) ([google docs]) (breaking change) * Remove deprecated AlarmControlPanel ([@SukramJ] - [#24322]) ([homematicip\_cloud docs][homematicip_cloud docs]) (breaking change) * Remove 属性 lowBat ([@SukramJ] - [#24323]) ([homematicip\_cloud docs][homematicip_cloud docs]) (breaking change) * Remove 二元sensor for ZHA 遥控器 and controllers ([@dmulcahey] - [#24370]) ([zha docs]) (breaking change) * 恢复 自动化 last\_triggered with initial\_state override ([@frenck] - [#24400]) ([自动化 docs]) (breaking change) * Fix recorder defaults ([@balloob] - [#24399]) ([recorder docs]) (breaking change) * Uber API is going away on June 13, 2019, remove component ([@robbiet480] - [#24468]) (breaking change) * Add Linky 传感器 : yesterday + months + years ([@Quentame] - [#23726]) (breaking change) * Position is reversed for horizontal awnings ([@kbickar] - [#23257]) ([tahoma docs]) (breaking change) * Remove conversation from default config ([@balloob] - [#24515]) ([default\_config docs][default_config docs]) (breaking change) * Added name to 传感器 ([@cliffordwhansen] - [#24525]) ([synologydsm docs]) (breaking change) * Battery 属性 & accuracy filter ([@GoNzCiD] - [#24277]) ([traccar docs]) (breaking change) * Added percent to the disk,memory and swap percent labels ([@cliffordwhansen] - [#24575]) ([glances docs]) (breaking change) * Save cached logi\_circle tokens in config folder ([@evanjd] - [#24726]) ([logi\_circle docs][logi_circle docs]) (breaking change) (beta fix) ## Beta Fixes * Vlc telnet ([@rodripf] - [#24290]) ([vlc\_telnet docs][vlc_telnet docs]) (beta fix) (new-集成) * Fix 设备 tracker see for 实体 registry 实体 ([@MartinHjelmare] - [#24633]) ([device\_tracker docs][device_tracker docs]) (beta fix) * Bump ZHA dependencies. ([@Adminiuga] - [#24637]) ([zha docs]) (beta fix) * 更新 LIFX brightness during long transitions ([@amelchio] - [#24653]) ([lifx docs]) (beta fix) * 升级 blinkpy==0.14.1 for startup bugfix ([@fronzbot] - [#24656]) ([blink docs]) (beta fix) * Warn when 用户 tries run custom config flow ([@balloob] - [#24657]) (beta fix) * Bump pysmartthings ([@andrewsayre] - [#24659]) ([smartthings docs]) (beta fix) * Prefere binary with wheels ([@pvizeli] - [#24669]) (beta fix) * Allow extra js modules to be included in 前端 ([@thomasloven] - [#24675]) ([前端 docs]) (beta fix) * Fix time expression parsing ([@amelchio] - [#24696]) (beta fix) * ZHA fix 设备 type mappings ([@dmulcahey] - [#24699]) ([zha docs]) (beta fix) * Bump 版本 pyatmo to 2.0.1 ([@cgtobi] - [#24703]) ([netatmo docs]) (beta fix) * Extend websocket method usage to port 8002 in Samsung TV media player ([@2sheds] - [#24716]) ([samsungtv docs]) (beta fix) * 更新 ZHA dependencies ([@dmulcahey] - [#24718]) ([zha docs]) (beta fix) * Add show\_as\_state options to Life360 ([@pnbruckner] - [#24725]) ([life360 docs]) (beta fix) * Save cached logi\_circle tokens in config folder ([@evanjd] - [#24726]) ([logi\_circle docs][logi_circle docs]) (breaking change) (beta fix) * 更新 ZHA dependencies. ([@Adminiuga] - [#24736]) ([zha docs]) (beta fix) * AdGuard to 更新 entry ([@balloob] - [#24737]) ([adguard docs]) (beta fix) * 更新 pysonos to 0.0.17 ([@amelchio] - [#24740]) ([sonos docs]) (beta fix) * Clean up Google Config ([@balloob] - [#24663]) ([cloud docs]) ([google\_assistant docs][google_assistant docs]) (beta fix) * Fix locative 设备 更新 ([@MartinHjelmare] - [#24744]) ([locative docs]) (beta fix) * Improve Alexa 错误 handling ([@balloob] - [#24745]) ([alexa docs]) ([cloud docs]) ([websocket\_api docs][websocket_api docs]) (beta fix) * Bump pyatmo to v2.1.0 ([@cgtobi] - [#24724]) ([netatmo docs]) (beta fix) * Handle timeouts gracefully ([@cgtobi] - [#24752]) ([netatmo docs]) (beta fix) * 更新 Waze route dependency to 0.10 ([@johntdyer] - [#24754]) ([waze\_travel\_time docs][waze_travel_time docs]) (beta fix) * Ignore duplicate tradfri discovery ([@balloob] - [#24759]) ([tradfri docs]) (beta fix) * Return correct name for met.no ([@Danielhiversen] - [#24763]) ([met docs]) (beta fix) ## All changes * 更新 pysonos to 0.0.14 ([@amelchio] - [#24185]) ([sonos docs]) * 升级 broadlink library, Use cryptography instead of pycryptodome ([@Danielhiversen] - [#24186]) ([broadlink docs]) * danielhiversen as codeowner for yr ([@Danielhiversen] - [#24189]) * No longer allow invalid slugs or extra keys ([@balloob] - [#24176]) (breaking change) * 更新 azure-pipelines.yml for check 版本 ([@pvizeli] - [#24194]) * 更新 Tibber library ([@Danielhiversen] - [#24192]) ([tibber docs]) * :pencil2: Corrects incorrect command in hassfest ([@frenck] - [#24188]) * Fix ESPHome config flow with invalid config entry ([@OttoWinter] - [#24213]) ([esphome docs]) * Add control of Amcrest indicator 灯光 ([@pnbruckner] - [#23986]) ([amcrest docs]) * ZHA requirements 版本 bump. ([@Adminiuga] - [#24228]) ([zha docs]) * Bump pychromecast ([@soldag] - [#24234]) ([cast docs]) * Round Awair 传感器 values ([@danielsjf] - [#24093]) ([awair docs]) * Sense 更新 ([@kbickar] - [#24220]) ([sense docs]) * fix gitlab\_ci sad icon ([@Emilv2] - [#24241]) ([gitlab\_ci docs][gitlab_ci docs]) * Add details to triggered 状态 for total connect 报警 ([@austinmroczek] - [#24106]) ([totalconnect docs]) * Bump python-velbus 版本 for velbus component ([@Cereal2nd] - [#24226]) ([velbus docs]) * Adds AdGuard Home 集成 ([@frenck] - [#24219]) ([adguard docs]) (new-集成) * Fix typo in 集成 component ([@Emilv2] - [#24250]) ([集成 docs]) * Replace pyunifi with aiounifi in UniFi 设备 tracker ([@Kane610] - [#24149]) ([unifi docs]) * Add 服务 for adding event to google component ([@isabellaalstrom] - [#22473]) ([google docs]) (breaking change) * Remove icon() ([@fabaff] - [#24280]) ([meteoalarm docs]) * Split 设备 of nodes with multiple instances ([@Swamp-Ig] - [#24032]) ([zwave docs]) * 更新 pyvera to 0.3.1 for alert support ([@brandond] - [#24289]) ([vera docs]) * Expose specific device\_class for Velux 遮盖 ([@gibman] - [#24279]) ([velux docs]) * Change meteoalertapi to 版本 0.1.3 ([@rolfberkenbosch] - [#24307]) ([meteoalarm docs]) * 升级 pytest and -cov ([@scop] - [#24258]) * Add LCN 场景 platform ([@alengwenus] - [#24242]) ([lcn docs]) (new-platform) * Add support for learning new commands ([@felipediel] - [#23888]) ([遥控器 docs]) * 升级 to newer 版本 of rflink with improve 错误 handling on incoming data. ([@aequitas] - [#24263]) ([rflink docs]) * SolarEdge Local Component ([@drobtravels] - [#23996]) ([solaredge\_local docs][solaredge_local docs]) (new-集成) * Push to 版本 0.7.9 of denonavr ([@scarface-4711] - [#24260]) ([denonavr docs]) * Bump simplipy to 3.4.2 ([@bachya] - [#24326]) ([simplisafe docs]) * Meteofrance fix 24244 ([@victorcerutti] - [#24315]) ([meteo\_france docs][meteo_france docs]) * Only 更新 media icon when necessary ([@jjlawren] - [#24324]) ([webostv docs]) * components/遮盖: Typo in docstring. ([@andre-richter] - [#24329]) ([遮盖 docs]) * Add exception handling for Netatmo 温控 ([@cgtobi] - [#24311]) ([netatmo docs]) * Remove deprecated AlarmControlPanel ([@SukramJ] - [#24322]) ([homematicip\_cloud docs][homematicip_cloud docs]) (breaking change) * Use node descriptor from Zigpy for ZHA ([@dmulcahey] - [#24316]) ([zha docs]) * Add abbreviation for 灯光 模板 variable names ([@bieniu] - [#24336]) ([MQTT docs]) * Remove 属性 lowBat ([@SukramJ] - [#24323]) ([homematicip\_cloud docs][homematicip_cloud docs]) (breaking change) * Don't load last\_checkpoint if shipment is pending ([@davidbb] - [#24301]) ([aftership docs]) * 升级 youtube\_dl to 2019.05.20 ([@fabaff] - [#24347]) ([media\_extractor docs][media_extractor docs]) * Add new movement type "actively" of the Xiaomi Vibration 传感器 ([@syssi] - [#24334]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * Fix set\_cover\_position of the xiaomi\_aqara 遮盖 for LAN protocol v2 ([@syssi] - [#24333]) ([xiaomi\_aqara docs][xiaomi_aqara docs]) * Add Environment Canada 天气, 传感器, and 摄像头 platforms ([@michaeldavie] - [#21110]) ([environment\_canada docs][environment_canada docs]) (new-platform) * Google Cloud Platform component (TTS) ([@lufton] - [#23629]) ([google\_cloud docs][google_cloud docs]) (new-集成) * Add Streamlabs Water Monitor ([@cpopp] - [#21205]) ([streamlabswater docs]) * ebusd: added check for monitored 条件 validity within correct circuit ([@danielkucera] - [#22461]) ([ebusd docs]) * Bring the Sisyphus 集成 to silver quality ([@jkeljo] - [#22457]) ([sisyphus docs]) * Support for Salda Smarty XV/XP Ventilation Unit ([@z0mbieprocess] - [#21491]) ([smarty docs]) (new-platform) * Bump to pypck==0.6.1 ([@alengwenus] - [#24356]) ([lcn docs]) * Add templating to MQTT 遮盖 tilt\_status ([@tommyjlong] - [#24355]) ([MQTT docs]) * 升级 ruamel.yaml to 0.15.97 ([@fabaff] - [#24350]) * Bump regenmaschine to 1.5.1 ([@bachya] - [#24358]) ([rainmachine docs]) * Life360 集成 ([@pnbruckner] - [#24227]) ([life360 docs]) (new-集成) * Refactor Waze Travel Time & 更新 Requirements ([@Petro31] - [#22428]) ([waze\_travel\_time docs][waze_travel_time docs]) * 更新 pyhomematic ([@danielperna84] - [#24368]) ([homematic docs]) * Add 服务 to 更新 核心 location ([@balloob] - [#24328]) ([homeassistant docs]) * Fix ZHA battery level when value is reported via signal ([@dmulcahey] - [#24371]) ([zha docs]) * Remove 二元sensor for ZHA 遥控器 and controllers ([@dmulcahey] - [#24370]) ([zha docs]) (breaking change) * Add support for ZHA door 门锁 #2 ([@presslab-us] - [#24344]) ([zha docs]) (new-platform) * 升级 discord.py to 1.1.1 ([@fabaff] - [#24375]) ([discord docs]) * 升级 Mastodon.py to 1.4.3 ([@fabaff] - [#24374]) ([mastodon docs]) * Add shuffle support for itunes component ([@kvanhoorn] - [#24319]) ([itunes docs]) * Fixed wrong setpoint value on startup when 温控 was previously turned off ([@alengwenus] - [#24377]) ([lcn docs]) * Add ATTR\_FORECAST\_PRECIPITATION option ([@rolfberkenbosch] - [#24308]) ([buienradar docs]) * Provide an option for the DD-WRT 设备 tracker to include non-wireless 设备 ([@Klikini] - [#24259]) ([ddwrt docs]) * Add for option for 模板 触发器 ([@pnbruckner] - [#24330]) ([自动化 docs]) * Improve amcrest 错误 handling and bump amcrest package to 1.5.3 ([@pnbruckner] - [#24262]) ([amcrest docs]) * Improve boolean validator ([@Swamp-Ig] - [#24294]) * add 设备 class to 传感器 ([@dmulcahey] - [#24373]) ([zha docs]) * Fixes linter 警告 in ZHA 传感器 ([@frenck] - [#24406]) ([zha docs]) * Use loose 版本 ([@balloob] - [#24394]) * 恢复 自动化 last\_triggered with initial\_state override ([@frenck] - [#24400]) ([自动化 docs]) (breaking change) * Fix recorder defaults ([@balloob] - [#24399]) ([recorder docs]) (breaking change) * Minor improvements to 自动化 test suite ([@frenck] - [#24424]) * 升级 broadlink library ([@Danielhiversen] - [#24450]) ([broadlink docs]) * 升级 ambiclimate library ([@Danielhiversen] - [#24449]) ([ambiclimate docs]) * Rename via\_hub to via\_device ([@Swamp-Ig] - [#24360]) * Remove frequest asuswrt 日志 spam ([@jwater7] - [#24448]) ([asuswrt docs]) * Publish test results ([@pvizeli] - [#24460]) * Life360: Fix config entry handling for accounts imported from 配置 ([@pnbruckner] - [#24455]) ([life360 docs]) * Add default config to constaint file ([@balloob] - [#24423]) * Add websock command to query 设备 for 触发器 ([@emontnemery] - [#24044]) ([自动化 docs]) ([灯光 docs]) * Uber API is going away on June 13, 2019, remove component ([@robbiet480] - [#24468]) (breaking change) * Use met.no instead of yr.no in default config ([@thomasloven] - [#24470]) * Bump pyubee to 0.7 to support more models ([@mzdrale] - [#24477]) * Somfy open api ([@tetienne] - [#19548]) ([somfy docs]) (new-platform) * Add APRS 设备 tracker component ([@PhilRW] - [#22469]) ([aprs docs]) (new-platform) * Add Linky 传感器 : yesterday + months + years ([@Quentame] - [#23726]) (breaking change) * Add attributs and fix lightlevel inconsistency for LightLevel 传感器 ([@Cyr-ius] - [#24439]) ([hue docs]) * Support ZLO 设备 types to support newer Zigbee 设备 in ZHA ([@jurriaan] - [#24429]) ([zha docs]) * 摄像头 platform for buienradar imagery ([@ties] - [#23358]) ([buienradar docs]) (new-platform) * Position is reversed for horizontal awnings ([@kbickar] - [#23257]) ([tahoma docs]) (breaking change) * Fix aprs imports ([@amelchio] - [#24485]) ([aprs docs]) * 版本 bump for toonapilib to include new API call for fetching thermostat 状态, which was sometimes missing causing 错误 in the library ([@reinder83] - [#24459]) ([toon docs]) * remove docs from config entries file \[skip ci] ([@balloob] - [#24488]) * Bump adguardhome to 0.2.1 ([@frenck] - [#24486]) ([adguard docs]) * Add Cast discovery to manifest ([@balloob] - [#24504]) ([cast docs]) ([discovery docs]) * Bump pyatmo to 2.00 ([@cgtobi] - [#24505]) ([netatmo docs]) * Migrate HEOS discovery to manifest ([@balloob] - [#24508]) ([discovery docs]) ([heos docs]) * Bumping Keenetic NDMS2 client to 0.0.8 ([@foxel] - [#24469]) ([keenetic\_ndms2 docs][keenetic_ndms2 docs]) * 更新 DelugeClient to 1.7.1 ([@GuyKh] - [#24518]) ([deluge docs]) * Clean up Alexa smart home code ([@balloob] - [#24514]) ([alexa docs]) ([cloud docs]) * Remove conversation from default config ([@balloob] - [#24515]) ([default\_config docs][default_config docs]) (breaking change) * Refactor yeelight code ([@zewelor] - [#22547]) ([yeelight docs]) * Migrate Sonos discovery to manifest ([@balloob] - [#24507]) ([discovery docs]) ([sonos docs]) * Cloud: allow managing Alexa 实体 via UI ([@balloob] - [#24522]) ([alexa docs]) ([cloud docs]) * WIP Ps4 Convert 实体 to Async / Fix 实体 name changing ([@ktnrg45] - [#24101]) ([ps4 docs]) * deCONZ - Change 属性 Watts to W ([@Kane610] - [#24535]) ([deconz docs]) * Improve stability of netatmo 传感器 ([@Danielhiversen] - [#24190]) ([netatmo docs]) * 更新 meteoalertapi to 0.1.5 ([@rolfberkenbosch] - [#24528]) ([meteoalarm docs]) * PS4 bump to 0.8.3 ([@ktnrg45] - [#24527]) ([ps4 docs]) * Pyyaml5.1 ([@BackSlasher] - [#24529]) * Added name to 传感器 ([@cliffordwhansen] - [#24525]) ([synologydsm docs]) (breaking change) * 更新 requirement 版本 and add switcher\_kis 服务 ([@TomerFi] - [#23477]) ([switcher\_kis docs][switcher_kis docs]) * Flux 开关 ([@Swamp-Ig] - [#24542]) * UniFi simplify 更新 ([@Kane610] - [#24304]) ([unifi docs]) * Fix incomfort issue #24478 & bump client ([@zxdavb] - [#24548]) ([incomfort docs]) * Handle stacktrace when rtorrent host is unreachable ([@mafrosis] - [#24541]) ([rtorrent docs]) * Fix a bug with Ambient PWS reconnection ([@bachya] - [#24540]) ([ambient\_station docs][ambient_station docs]) * 更新 **init**.py ([@lundan] - [#24553]) ([nissan\_leaf docs][nissan_leaf docs]) * 更新 ambiclimate library ([@Danielhiversen] - [#24562]) ([ambiclimate docs]) * Misc. ZHA enhancements ([@dmulcahey] - [#24559]) ([zha docs]) * 更新 pysonos to 0.0.15 ([@amelchio] - [#24565]) ([sonos docs]) * Whitelist yeelight predefined effects per 设备 type ([@zewelor] - [#24544]) ([yeelight docs]) * Battery 属性 & accuracy filter ([@GoNzCiD] - [#24277]) ([traccar docs]) (breaking change) * Bump androidtv to 0.0.16 ([@JeffLIrion] - [#24576]) ([androidtv docs]) * Added percent to the disk,memory and swap percent labels ([@cliffordwhansen] - [#24575]) ([glances docs]) (breaking change) * SMA 传感器: Add optional path ([@kellerza] - [#24558]) ([sma docs]) * Fix geniushub issue #24530 (via a client bump) & handle edge cases ([@zxdavb] - [#24546]) ([geniushub docs]) * Add sensitivity and sensitvity\_max attributs for 二元sensor ([@Cyr-ius] - [#24438]) ([hue docs]) * Cloud: Add Alexa report 状态 ([@balloob] - [#24536]) ([alexa docs]) ([cloud docs]) * Added 切换 服务 to 遮盖 ([@kbickar] - [#23198]) ([遮盖 docs]) * Added invert\_percent 配置 for zwave rollershutter ([@tommasomarchionni] - [#23101]) ([zwave docs]) * Add code\_arm\_required to manual 报警 with MQTT ([@JumpMaster] - [#22641]) ([manual\_mqtt docs][manual_mqtt docs]) * Add code\_arm\_required to manual 报警 ([@JumpMaster] - [#22618]) ([demo docs]) ([manual docs]) * Add source selection to Samsung TV media player ([@escoand] - [#22612]) ([samsungtv docs]) * Fix 报警 control 面板 tests ([@balloob] - [#24586]) * Adds 集成 for Plaato Airlock ([@JohNan] - [#23727]) ([plaato docs]) (new-集成) * Fix honeywell issue #18932 ([@zxdavb] - [#24402]) ([honeywell docs]) * Bump base Somfy MyLink library 版本 ([@bendews] - [#24587]) ([somfy\_mylink docs][somfy_mylink docs]) * Better pairing for Xiaomi 设备 in ZHA ([@dmulcahey] - [#24564]) ([zha docs]) * ESPHome config flow only connect when needed ([@OttoWinter] - [#24593]) ([esphome docs]) * ESPHome load platforms lazily ([@OttoWinter] - [#24594]) ([esphome docs]) * Add ESPHome event generation and 用户-defined 服务 array support ([@OttoWinter] - [#24595]) ([esphome docs]) * Fix validator for lcn.send\_keys 服务 ([@alengwenus] - [#24580]) ([lcn docs]) * Cloud: Make sure on\_connect forwards platform only once ([@balloob] - [#24582]) ([cloud docs]) * Add config entry for Met.no ([@bachya] - [#24608]) ([met docs]) * 通知 Alexa when exposed 实体 change ([@balloob] - [#24609]) ([alexa docs]) ([cloud docs]) * 更新 pysonos to 0.0.16 ([@amelchio] - [#24607]) ([sonos docs]) * check for None 状态 in broadlink ([@Danielhiversen] - [#24589]) ([broadlink docs]) * Queensland bushfire alert feed platform ([@exxamalte] - [#24473]) ([qld\_bushfire docs][qld_bushfire docs]) (new-集成) * Add incomfort 传感器 and binary\_sensor ([@zxdavb] - [#23812]) ([incomfort docs]) (new-platform) * Add support for opencv wheels ([@pvizeli] - [#24620]) ([opencv docs]) * tellstick: Add socat to package dependencies ([@torarnv] - [#24531]) * Tolerance 配置 for dlib\_face\_identify ([@gonzalezcalleja] - [#24497]) ([dlib\_face\_identify docs][dlib_face_identify docs]) * Fix sending 更新 when not logged in ([@balloob] - [#24624]) ([cloud docs]) * Uses signal dispatcher to invoke 状态 更新 ([@JohNan] - [#24627]) ([plaato docs]) * Add 天气 alert 传感器 to meteo france component ([@oncleben31] - [#23128]) ([meteo\_france docs][meteo_france docs]) * Set up Met during onboarding ([@balloob] - [#24622]) ([met docs]) ([onboarding docs]) * Added ELV PCA 301 smart emeter 开关 ([@majuss] - [#23300]) ([elv docs]) (new-platform) * Vlc telnet ([@rodripf] - [#24290]) ([vlc\_telnet docs][vlc_telnet docs]) (beta fix) (new-集成) * Fix 设备 tracker see for 实体 registry 实体 ([@MartinHjelmare] - [#24633]) ([device\_tracker docs][device_tracker docs]) (beta fix) * Bump ZHA dependencies. ([@Adminiuga] - [#24637]) ([zha docs]) (beta fix) * 更新 LIFX brightness during long transitions ([@amelchio] - [#24653]) ([lifx docs]) (beta fix) * 升级 blinkpy==0.14.1 for startup bugfix ([@fronzbot] - [#24656]) ([blink docs]) (beta fix) * Warn when 用户 tries run custom config flow ([@balloob] - [#24657]) (beta fix) * Bump pysmartthings ([@andrewsayre] - [#24659]) ([smartthings docs]) (beta fix) * Prefere binary with wheels ([@pvizeli] - [#24669]) (beta fix) * Allow extra js modules to be included in 前端 ([@thomasloven] - [#24675]) ([前端 docs]) (beta fix) * Fix time expression parsing ([@amelchio] - [#24696]) (beta fix) * ZHA fix 设备 type mappings ([@dmulcahey] - [#24699]) ([zha docs]) (beta fix) * Bump 版本 pyatmo to 2.0.1 ([@cgtobi] - [#24703]) ([netatmo docs]) (beta fix) * Extend websocket method usage to port 8002 in Samsung TV media player ([@2sheds] - [#24716]) ([samsungtv docs]) (beta fix) * 更新 ZHA dependencies ([@dmulcahey] - [#24718]) ([zha docs]) (beta fix) * Add show\_as\_state options to Life360 ([@pnbruckner] - [#24725]) ([life360 docs]) (beta fix) * Save cached logi\_circle tokens in config folder ([@evanjd] - [#24726]) ([logi\_circle docs][logi_circle docs]) (breaking change) (beta fix) * 更新 ZHA dependencies. ([@Adminiuga] - [#24736]) ([zha docs]) (beta fix) * AdGuard to 更新 entry ([@balloob] - [#24737]) ([adguard docs]) (beta fix) * 更新 pysonos to 0.0.17 ([@amelchio] - [#24740]) ([sonos docs]) (beta fix) * Clean up Google Config ([@balloob] - [#24663]) ([cloud docs]) ([google\_assistant docs][google_assistant docs]) (beta fix) * Fix locative 设备 更新 ([@MartinHjelmare] - [#24744]) ([locative docs]) (beta fix) * Improve Alexa 错误 handling ([@balloob] - [#24745]) ([alexa docs]) ([cloud docs]) ([websocket\_api docs][websocket_api docs]) (beta fix) * Bump pyatmo to v2.1.0 ([@cgtobi] - [#24724]) ([netatmo docs]) (beta fix) * Handle timeouts gracefully ([@cgtobi] - [#24752]) ([netatmo docs]) (beta fix) * 更新 Waze route dependency to 0.10 ([@johntdyer] - [#24754]) ([waze\_travel\_time docs][waze_travel_time docs]) (beta fix) * Ignore duplicate tradfri discovery ([@balloob] - [#24759]) ([tradfri docs]) (beta fix) * Return correct name for met.no ([@Danielhiversen] - [#24763]) ([met docs]) (beta fix) [#19548]: https://github.com/home-assistant/home-assistant/pull/19548 [#21110]: https://github.com/home-assistant/home-assistant/pull/21110 [#21205]: https://github.com/home-assistant/home-assistant/pull/21205 [#21491]: https://github.com/home-assistant/home-assistant/pull/21491 [#22428]: https://github.com/home-assistant/home-assistant/pull/22428 [#22457]: https://github.com/home-assistant/home-assistant/pull/22457 [#22461]: https://github.com/home-assistant/home-assistant/pull/22461 [#22469]: https://github.com/home-assistant/home-assistant/pull/22469 [#22473]: https://github.com/home-assistant/home-assistant/pull/22473 [#22547]: https://github.com/home-assistant/home-assistant/pull/22547 [#22612]: https://github.com/home-assistant/home-assistant/pull/22612 [#22618]: https://github.com/home-assistant/home-assistant/pull/22618 [#22641]: https://github.com/home-assistant/home-assistant/pull/22641 [#23101]: https://github.com/home-assistant/home-assistant/pull/23101 [#23128]: https://github.com/home-assistant/home-assistant/pull/23128 [#23198]: https://github.com/home-assistant/home-assistant/pull/23198 [#23257]: https://github.com/home-assistant/home-assistant/pull/23257 [#23300]: https://github.com/home-assistant/home-assistant/pull/23300 [#23358]: https://github.com/home-assistant/home-assistant/pull/23358 [#23477]: https://github.com/home-assistant/home-assistant/pull/23477 [#23629]: https://github.com/home-assistant/home-assistant/pull/23629 [#23726]: https://github.com/home-assistant/home-assistant/pull/23726 [#23727]: https://github.com/home-assistant/home-assistant/pull/23727 [#23812]: https://github.com/home-assistant/home-assistant/pull/23812 [#23888]: https://github.com/home-assistant/home-assistant/pull/23888 [#23986]: https://github.com/home-assistant/home-assistant/pull/23986 [#23996]: https://github.com/home-assistant/home-assistant/pull/23996 [#24032]: https://github.com/home-assistant/home-assistant/pull/24032 [#24044]: https://github.com/home-assistant/home-assistant/pull/24044 [#24093]: https://github.com/home-assistant/home-assistant/pull/24093 [#24101]: https://github.com/home-assistant/home-assistant/pull/24101 [#24106]: https://github.com/home-assistant/home-assistant/pull/24106 [#24149]: https://github.com/home-assistant/home-assistant/pull/24149 [#24176]: https://github.com/home-assistant/home-assistant/pull/24176 [#24185]: https://github.com/home-assistant/home-assistant/pull/24185 [#24186]: https://github.com/home-assistant/home-assistant/pull/24186 [#24188]: https://github.com/home-assistant/home-assistant/pull/24188 [#24189]: https://github.com/home-assistant/home-assistant/pull/24189 [#24190]: https://github.com/home-assistant/home-assistant/pull/24190 [#24192]: https://github.com/home-assistant/home-assistant/pull/24192 [#24194]: https://github.com/home-assistant/home-assistant/pull/24194 [#24213]: https://github.com/home-assistant/home-assistant/pull/24213 [#24219]: https://github.com/home-assistant/home-assistant/pull/24219 [#24220]: https://github.com/home-assistant/home-assistant/pull/24220 [#24226]: https://github.com/home-assistant/home-assistant/pull/24226 [#24227]: https://github.com/home-assistant/home-assistant/pull/24227 [#24228]: https://github.com/home-assistant/home-assistant/pull/24228 [#24234]: https://github.com/home-assistant/home-assistant/pull/24234 [#24241]: https://github.com/home-assistant/home-assistant/pull/24241 [#24242]: https://github.com/home-assistant/home-assistant/pull/24242 [#24250]: https://github.com/home-assistant/home-assistant/pull/24250 [#24258]: https://github.com/home-assistant/home-assistant/pull/24258 [#24259]: https://github.com/home-assistant/home-assistant/pull/24259 [#24260]: https://github.com/home-assistant/home-assistant/pull/24260 [#24262]: https://github.com/home-assistant/home-assistant/pull/24262 [#24263]: https://github.com/home-assistant/home-assistant/pull/24263 [#24277]: https://github.com/home-assistant/home-assistant/pull/24277 [#24279]: https://github.com/home-assistant/home-assistant/pull/24279 [#24280]: https://github.com/home-assistant/home-assistant/pull/24280 [#24289]: https://github.com/home-assistant/home-assistant/pull/24289 [#24290]: https://github.com/home-assistant/home-assistant/pull/24290 [#24294]: https://github.com/home-assistant/home-assistant/pull/24294 [#24301]: https://github.com/home-assistant/home-assistant/pull/24301 [#24304]: https://github.com/home-assistant/home-assistant/pull/24304 [#24307]: https://github.com/home-assistant/home-assistant/pull/24307 [#24308]: https://github.com/home-assistant/home-assistant/pull/24308 [#24311]: https://github.com/home-assistant/home-assistant/pull/24311 [#24315]: https://github.com/home-assistant/home-assistant/pull/24315 [#24316]: https://github.com/home-assistant/home-assistant/pull/24316 [#24319]: https://github.com/home-assistant/home-assistant/pull/24319 [#24322]: https://github.com/home-assistant/home-assistant/pull/24322 [#24323]: https://github.com/home-assistant/home-assistant/pull/24323 [#24324]: https://github.com/home-assistant/home-assistant/pull/24324 [#24326]: https://github.com/home-assistant/home-assistant/pull/24326 [#24328]: https://github.com/home-assistant/home-assistant/pull/24328 [#24329]: https://github.com/home-assistant/home-assistant/pull/24329 [#24330]: https://github.com/home-assistant/home-assistant/pull/24330 [#24333]: https://github.com/home-assistant/home-assistant/pull/24333 [#24334]: https://github.com/home-assistant/home-assistant/pull/24334 [#24336]: https://github.com/home-assistant/home-assistant/pull/24336 [#24344]: https://github.com/home-assistant/home-assistant/pull/24344 [#24347]: https://github.com/home-assistant/home-assistant/pull/24347 [#24350]: https://github.com/home-assistant/home-assistant/pull/24350 [#24355]: https://github.com/home-assistant/home-assistant/pull/24355 [#24356]: https://github.com/home-assistant/home-assistant/pull/24356 [#24358]: https://github.com/home-assistant/home-assistant/pull/24358 [#24360]: https://github.com/home-assistant/home-assistant/pull/24360 [#24368]: https://github.com/home-assistant/home-assistant/pull/24368 [#24370]: https://github.com/home-assistant/home-assistant/pull/24370 [#24371]: https://github.com/home-assistant/home-assistant/pull/24371 [#24373]: https://github.com/home-assistant/home-assistant/pull/24373 [#24374]: https://github.com/home-assistant/home-assistant/pull/24374 [#24375]: https://github.com/home-assistant/home-assistant/pull/24375 [#24377]: https://github.com/home-assistant/home-assistant/pull/24377 [#24394]: https://github.com/home-assistant/home-assistant/pull/24394 [#24399]: https://github.com/home-assistant/home-assistant/pull/24399 [#24400]: https://github.com/home-assistant/home-assistant/pull/24400 [#24402]: https://github.com/home-assistant/home-assistant/pull/24402 [#24406]: https://github.com/home-assistant/home-assistant/pull/24406 [#24423]: https://github.com/home-assistant/home-assistant/pull/24423 [#24424]: https://github.com/home-assistant/home-assistant/pull/24424 [#24429]: https://github.com/home-assistant/home-assistant/pull/24429 [#24438]: https://github.com/home-assistant/home-assistant/pull/24438 [#24439]: https://github.com/home-assistant/home-assistant/pull/24439 [#24448]: https://github.com/home-assistant/home-assistant/pull/24448 [#24449]: https://github.com/home-assistant/home-assistant/pull/24449 [#24450]: https://github.com/home-assistant/home-assistant/pull/24450 [#24455]: https://github.com/home-assistant/home-assistant/pull/24455 [#24459]: https://github.com/home-assistant/home-assistant/pull/24459 [#24460]: https://github.com/home-assistant/home-assistant/pull/24460 [#24468]: https://github.com/home-assistant/home-assistant/pull/24468 [#24469]: https://github.com/home-assistant/home-assistant/pull/24469 [#24470]: https://github.com/home-assistant/home-assistant/pull/24470 [#24473]: https://github.com/home-assistant/home-assistant/pull/24473 [#24477]: https://github.com/home-assistant/home-assistant/pull/24477 [#24485]: https://github.com/home-assistant/home-assistant/pull/24485 [#24486]: https://github.com/home-assistant/home-assistant/pull/24486 [#24488]: https://github.com/home-assistant/home-assistant/pull/24488 [#24497]: https://github.com/home-assistant/home-assistant/pull/24497 [#24504]: https://github.com/home-assistant/home-assistant/pull/24504 [#24505]: https://github.com/home-assistant/home-assistant/pull/24505 [#24507]: https://github.com/home-assistant/home-assistant/pull/24507 [#24508]: https://github.com/home-assistant/home-assistant/pull/24508 [#24514]: https://github.com/home-assistant/home-assistant/pull/24514 [#24515]: https://github.com/home-assistant/home-assistant/pull/24515 [#24518]: https://github.com/home-assistant/home-assistant/pull/24518 [#24522]: https://github.com/home-assistant/home-assistant/pull/24522 [#24525]: https://github.com/home-assistant/home-assistant/pull/24525 [#24527]: https://github.com/home-assistant/home-assistant/pull/24527 [#24528]: https://github.com/home-assistant/home-assistant/pull/24528 [#24529]: https://github.com/home-assistant/home-assistant/pull/24529 [#24531]: https://github.com/home-assistant/home-assistant/pull/24531 [#24535]: https://github.com/home-assistant/home-assistant/pull/24535 [#24536]: https://github.com/home-assistant/home-assistant/pull/24536 [#24540]: https://github.com/home-assistant/home-assistant/pull/24540 [#24541]: https://github.com/home-assistant/home-assistant/pull/24541 [#24542]: https://github.com/home-assistant/home-assistant/pull/24542 [#24544]: https://github.com/home-assistant/home-assistant/pull/24544 [#24546]: https://github.com/home-assistant/home-assistant/pull/24546 [#24548]: https://github.com/home-assistant/home-assistant/pull/24548 [#24553]: https://github.com/home-assistant/home-assistant/pull/24553 [#24558]: https://github.com/home-assistant/home-assistant/pull/24558 [#24559]: https://github.com/home-assistant/home-assistant/pull/24559 [#24562]: https://github.com/home-assistant/home-assistant/pull/24562 [#24564]: https://github.com/home-assistant/home-assistant/pull/24564 [#24565]: https://github.com/home-assistant/home-assistant/pull/24565 [#24575]: https://github.com/home-assistant/home-assistant/pull/24575 [#24576]: https://github.com/home-assistant/home-assistant/pull/24576 [#24580]: https://github.com/home-assistant/home-assistant/pull/24580 [#24582]: https://github.com/home-assistant/home-assistant/pull/24582 [#24586]: https://github.com/home-assistant/home-assistant/pull/24586 [#24587]: https://github.com/home-assistant/home-assistant/pull/24587 [#24589]: https://github.com/home-assistant/home-assistant/pull/24589 [#24593]: https://github.com/home-assistant/home-assistant/pull/24593 [#24594]: https://github.com/home-assistant/home-assistant/pull/24594 [#24595]: https://github.com/home-assistant/home-assistant/pull/24595 [#24607]: https://github.com/home-assistant/home-assistant/pull/24607 [#24608]: https://github.com/home-assistant/home-assistant/pull/24608 [#24609]: https://github.com/home-assistant/home-assistant/pull/24609 [#24620]: https://github.com/home-assistant/home-assistant/pull/24620 [#24622]: https://github.com/home-assistant/home-assistant/pull/24622 [#24624]: https://github.com/home-assistant/home-assistant/pull/24624 [#24627]: https://github.com/home-assistant/home-assistant/pull/24627 [#24633]: https://github.com/home-assistant/home-assistant/pull/24633 [#24637]: https://github.com/home-assistant/home-assistant/pull/24637 [#24653]: https://github.com/home-assistant/home-assistant/pull/24653 [#24656]: https://github.com/home-assistant/home-assistant/pull/24656 [#24657]: https://github.com/home-assistant/home-assistant/pull/24657 [#24659]: https://github.com/home-assistant/home-assistant/pull/24659 [#24663]: https://github.com/home-assistant/home-assistant/pull/24663 [#24669]: https://github.com/home-assistant/home-assistant/pull/24669 [#24675]: https://github.com/home-assistant/home-assistant/pull/24675 [#24696]: https://github.com/home-assistant/home-assistant/pull/24696 [#24699]: https://github.com/home-assistant/home-assistant/pull/24699 [#24703]: https://github.com/home-assistant/home-assistant/pull/24703 [#24716]: https://github.com/home-assistant/home-assistant/pull/24716 [#24718]: https://github.com/home-assistant/home-assistant/pull/24718 [#24724]: https://github.com/home-assistant/home-assistant/pull/24724 [#24725]: https://github.com/home-assistant/home-assistant/pull/24725 [#24726]: https://github.com/home-assistant/home-assistant/pull/24726 [#24736]: https://github.com/home-assistant/home-assistant/pull/24736 [#24737]: https://github.com/home-assistant/home-assistant/pull/24737 [#24740]: https://github.com/home-assistant/home-assistant/pull/24740 [#24744]: https://github.com/home-assistant/home-assistant/pull/24744 [#24745]: https://github.com/home-assistant/home-assistant/pull/24745 [#24752]: https://github.com/home-assistant/home-assistant/pull/24752 [#24754]: https://github.com/home-assistant/home-assistant/pull/24754 [#24759]: https://github.com/home-assistant/home-assistant/pull/24759 [#24763]: https://github.com/home-assistant/home-assistant/pull/24763 [@2sheds]: https://github.com/2sheds [@Adminiuga]: https://github.com/Adminiuga [@BackSlasher]: https://github.com/BackSlasher [@Cereal2nd]: https://github.com/Cereal2nd [@Cyr-ius]: https://github.com/Cyr-ius [@Danielhiversen]: https://github.com/Danielhiversen [@Emilv2]: https://github.com/Emilv2 [@GoNzCiD]: https://github.com/GoNzCiD [@GuyKh]: https://github.com/GuyKh [@JeffLIrion]: https://github.com/JeffLIrion [@JohNan]: https://github.com/JohNan [@JumpMaster]: https://github.com/JumpMaster [@Kane610]: https://github.com/Kane610 [@Klikini]: https://github.com/Klikini [@MartinHjelmare]: https://github.com/MartinHjelmare [@OttoWinter]: https://github.com/OttoWinter [@Petro31]: https://github.com/Petro31 [@PhilRW]: https://github.com/PhilRW [@Quentame]: https://github.com/Quentame [@SukramJ]: https://github.com/SukramJ [@Swamp-Ig]: https://github.com/Swamp-Ig [@TomerFi]: https://github.com/TomerFi [@aequitas]: https://github.com/aequitas [@alengwenus]: https://github.com/alengwenus [@amelchio]: https://github.com/amelchio [@andre-richter]: https://github.com/andre-richter [@andrewsayre]: https://github.com/andrewsayre [@austinmroczek]: https://github.com/austinmroczek [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@bendews]: https://github.com/bendews [@bieniu]: https://github.com/bieniu [@brandond]: https://github.com/brandond [@cgtobi]: https://github.com/cgtobi [@cliffordwhansen]: https://github.com/cliffordwhansen [@cpopp]: https://github.com/cpopp [@danielkucera]: https://github.com/danielkucera [@danielperna84]: https://github.com/danielperna84 [@danielsjf]: https://github.com/danielsjf [@davidbb]: https://github.com/davidbb [@dmulcahey]: https://github.com/dmulcahey [@drobtravels]: https://github.com/drobtravels [@emontnemery]: https://github.com/emontnemery [@escoand]: https://github.com/escoand [@evanjd]: https://github.com/evanjd [@exxamalte]: https://github.com/exxamalte [@fabaff]: https://github.com/fabaff [@felipediel]: https://github.com/felipediel [@foxel]: https://github.com/foxel [@frenck]: https://github.com/frenck [@fronzbot]: https://github.com/fronzbot [@gibman]: https://github.com/gibman [@gonzalezcalleja]: https://github.com/gonzalezcalleja [@isabellaalstrom]: https://github.com/isabellaalstrom [@jjlawren]: https://github.com/jjlawren [@jkeljo]: https://github.com/jkeljo [@johntdyer]: https://github.com/johntdyer [@jurriaan]: https://github.com/jurriaan [@jwater7]: https://github.com/jwater7 [@kbickar]: https://github.com/kbickar [@kellerza]: https://github.com/kellerza [@ktnrg45]: https://github.com/ktnrg45 [@kvanhoorn]: https://github.com/kvanhoorn [@lufton]: https://github.com/lufton [@lundan]: https://github.com/lundan [@mafrosis]: https://github.com/mafrosis [@majuss]: https://github.com/majuss [@michaeldavie]: https://github.com/michaeldavie [@mzdrale]: https://github.com/mzdrale [@oncleben31]: https://github.com/oncleben31 [@pnbruckner]: https://github.com/pnbruckner [@presslab-us]: https://github.com/presslab-us [@pvizeli]: https://github.com/pvizeli [@reinder83]: https://github.com/reinder83 [@robbiet480]: https://github.com/robbiet480 [@rodripf]: https://github.com/rodripf [@rolfberkenbosch]: https://github.com/rolfberkenbosch [@scarface-4711]: https://github.com/scarface-4711 [@scop]: https://github.com/scop [@soldag]: https://github.com/soldag [@syssi]: https://github.com/syssi [@tetienne]: https://github.com/tetienne [@thomasloven]: https://github.com/thomasloven [@ties]: https://github.com/ties [@tommasomarchionni]: https://github.com/tommasomarchionni [@tommyjlong]: https://github.com/tommyjlong [@torarnv]: https://github.com/torarnv [@victorcerutti]: https://github.com/victorcerutti [@z0mbieprocess]: https://github.com/z0mbieprocess [@zewelor]: https://github.com/zewelor [@zxdavb]: https://github.com/zxdavb [adguard docs]: /integrations/adguard/ [aftership docs]: /integrations/aftership/ [alexa docs]: /integrations/alexa/ [ambiclimate docs]: /integrations/ambiclimate/ [ambient_station docs]: /integrations/ambient_station/ [amcrest docs]: /integrations/amcrest/ [androidtv docs]: /integrations/androidtv/ [aprs docs]: /integrations/aprs/ [asuswrt docs]: /integrations/asuswrt/ [自动化 docs]: /integrations/自动化/ [awair docs]: /integrations/awair/ [blink docs]: /integrations/blink/ [broadlink docs]: /integrations/broadlink/ [buienradar docs]: /integrations/buienradar/ [cast docs]: /integrations/cast/ [cloud docs]: /integrations/cloud/ [遮盖 docs]: /integrations/遮盖/ [ddwrt docs]: /integrations/ddwrt/ [deconz docs]: /integrations/deconz/ [default_config docs]: /integrations/default_config/ [deluge docs]: /integrations/deluge/ [demo docs]: /integrations/demo/ [denonavr docs]: /integrations/denonavr/ [device_tracker docs]: /integrations/device_tracker/ [discord docs]: /integrations/discord/ [discovery docs]: /integrations/discovery/ [dlib_face_identify docs]: /integrations/dlib_face_identify/ [ebusd docs]: /integrations/ebusd/ [elv docs]: /integrations/开关.pca/ [environment_canada docs]: /integrations/environment_canada/ [esphome docs]: /integrations/esphome/ [前端 docs]: /integrations/frontend/ [geniushub docs]: /integrations/geniushub/ [gitlab_ci docs]: /integrations/gitlab_ci/ [glances docs]: /integrations/glances/ [google docs]: /integrations/google_translate [google_assistant docs]: /integrations/google_assistant/ [google_cloud docs]: /integrations/google_cloud/ [heos docs]: /integrations/heos/ [homeassistant docs]: /integrations/homeassistant/ [homematic docs]: /integrations/homematic/ [homematicip_cloud docs]: /integrations/homematicip_cloud/ [honeywell docs]: /integrations/honeywell/ [hue docs]: /integrations/hue/ [incomfort docs]: /integrations/incomfort/ [集成 docs]: /integrations/集成/ [itunes docs]: /integrations/itunes/ [keenetic_ndms2 docs]: /integrations/keenetic_ndms2/ [lcn docs]: /integrations/lcn/ [life360 docs]: /integrations/life360/ [lifx docs]: /integrations/lifx/ [灯光 docs]: /integrations/灯光/ [linky docs]: /integrations/linky/ [locative docs]: /integrations/locative/ [logi_circle docs]: /integrations/logi_circle/ [manual docs]: /integrations/manual/ [manual_mqtt docs]: /integrations/manual_mqtt/ [mastodon docs]: /integrations/mastodon/ [media_extractor docs]: /integrations/media_extractor/ [met docs]: /integrations/met/ [meteo_france docs]: /integrations/meteo_france/ [meteoalarm docs]: /integrations/meteoalarm/ [MQTT docs]: /integrations/MQTT/ [netatmo docs]: /integrations/netatmo/ [nissan_leaf docs]: /integrations/nissan_leaf/ [onboarding docs]: /integrations/onboarding/ [opencv docs]: /integrations/opencv/ [plaato docs]: /integrations/plaato/ [ps4 docs]: /integrations/ps4/ [qld_bushfire docs]: /integrations/qld_bushfire/ [rainmachine docs]: /integrations/rainmachine/ [recorder docs]: /integrations/recorder/ [遥控器 docs]: /integrations/遥控器/ [rflink docs]: /integrations/rflink/ [rtorrent docs]: /integrations/rtorrent/ [samsungtv docs]: /integrations/samsungtv/ [sense docs]: /integrations/sense/ [simplisafe docs]: /integrations/simplisafe/ [sisyphus docs]: /integrations/sisyphus/ [sma docs]: /integrations/sma/ [smartthings docs]: /integrations/smartthings/ [smarty docs]: /integrations/smarty/ [solaredge_local docs]: /integrations/solaredge_local/ [somfy docs]: /integrations/somfy/ [somfy_mylink docs]: /integrations/somfy_mylink/ [sonos docs]: /integrations/sonos/ [streamlabswater docs]: /integrations/streamlabswater/ [switcher_kis docs]: /integrations/switcher_kis/ [synologydsm docs]: /integrations/synologydsm/ [tahoma docs]: /integrations/tahoma/ [tibber docs]: /integrations/tibber/ [toon docs]: /integrations/toon/ [totalconnect docs]: /integrations/totalconnect/ [traccar docs]: /integrations/traccar/ [tradfri docs]: /integrations/tradfri/ [unifi docs]: /integrations/unifi/ [velbus docs]: /integrations/velbus/ [velux docs]: /integrations/velux/ [vera docs]: /integrations/vera/ [vlc_telnet docs]: /integrations/vlc_telnet [waze_travel_time docs]: /integrations/waze_travel_time/ [webostv docs]: /integrations/webostv/ [websocket_api docs]: /integrations/websocket_api/ [xiaomi_aqara docs]: /integrations/xiaomi_aqara/ [yeelight docs]: /integrations/yeelight/ [zha docs]: /integrations/zha/ [zwave docs]: /integrations/zwave/ --- url: /home-assistant/blog/2019-07-09-home-assistant-cast-preview.md --- # Home Assistant Cast(预览版) 今天是我的生日。我33岁了。为了庆祝,我想分享一个我一直在开发的项目预览:Home Assistant Cast。这是 Home Assistant Lovelace 界面,但是专为支持 Cast 的设备设计的,比如 Chromecast 或带有屏幕的 Google Assistant 设备。

Photo of a Google Nest Hub running the Home Assistant Cast interface. 运行 Home Assistant Cast 界面的 Google Nest Hub 照片。

它可以在任何支持 Cast 的设备上运行,如果可用,还允许用户使用触摸屏与界面进行交互。该界面基于 Lovelace 构建,因此它具有您现在所习惯的同样强大的功能和实时交互体验。 Chromecast 应用通常从浏览器或 Android/iOS 移动应用启动。但如果只有一种解决方案,那就不是 Home Assistant 了。Home Assistant 与 Chromecast 的集成已有5年多的历史。这意味着您将能够作为自动化的一部分启动 Home Assistant Cast。例如,当检测到前门有访客时,您可以在电视上显示信息。太棒了! 有关其工作原理的完整演示,请观看以下视频:
--- url: /home-assistant/blog/2019-07-17-release-96.md --- # 0.96: Notion, updated sidebar, advanced mode It's time for Home Assistant 0.96. It's a great 发布, but we also made some changes, so please pay attention. ## 最后一个支持 Python 3.5 的版本 This will be the last 发布 that supports Python 3.5. Home Assistant 0.97 will require at least Python 3.6. If you are using Hass.io or Docker, you will not have to do anything. If you are running Hassbian, [升级 instructions are here](https://github.com/home-assistant/hassbian-脚本/blob/dev/docs/suites/python.md). If you run Home Assistant inside a virtual environment, please follow the instructions for your OS to 更新. Home Assistant has adopted a new [Python support strategy](https://github.com/home-assistant/architecture/blob/master/adr/0002-minimum-supported-python-版本.md). Starting August 1, we will now support the last two minor stable releases of Python. This is currently Python 3.6 and Python 3.7. Python 3.8 is expected to be released near the end of the year. Once that is released, Python 3.6 support is deprecated and removed 2 months later. ## Pimp my 侧边栏 The 侧边栏 has gotten an improved look! Idea started with [a mockup by @JuanMTech on Twitter](https://twitter.com/JuanMTech/status/1143757213971943424) and grew into a full blown implementation. When visiting Home Assistant on 设备 with big screens (tablets, laptops, desktops), the 侧边栏 will now always be visible in a minimized mode with the ability to fully hide it via the profile page. The developer tool 按钮 have been collapsed into a single menu item. The dev tools will now store its exact 状态 when you navigate away, included the dev tool that is open. We've also taken the opportunity to make 通知 accessible from the 侧边栏, instead of only via the Lovelace UI. On mobile 设备 the 侧边栏 will behave like it previously did. Check [the demo](https://demo.home-assistant.io) for a preview.

Screenshot of the demo with the new 侧边栏. Screenshot of the demo with the new 侧边栏. Click to open.

## 温控 This 发布 includes a major clean up of our 温控 集成, correcting some architectural flaws from the past. The goal of this clean up was to a better job at providing an abstraction layer that fits many 设备. This will improve compatibility with 服务 that interact with Home Assistant (like Alexa/Google) and will allow us to make sure the UI works for everyone. We've done a lot of testing during the beta, but there might still be things that don't work as expected. If you notice anything, please report by [**opening a bug report**](https://github.com/home-assistant/home-assistant/issues). For a breakdown of what was driving the change, [check our 博客 post on the dev 博客](https://开发者.home-assistant.io/博客/2019/07/03/温控-cleanup.html). The following things have been changed: * `operation_mode` has been renamed to `hvac_mode` to emphasize what the mode is for. * We split HVAC mode `auto` into `auto` and `heat_cool`. If it's `heat_cool`, the 用户 has set a temperature range the 设备 has to use heating and cooling to stay within. Auto mode is now limited to 设备 that are running on a schedule or AI. * The 状态 of a 温控 实体 is now always equal to the HVAC mode. * `hvac_action` is introduced for 集成 that know the current 动作: heating, cooling, idle. * `set_away_mode` and `set_hold_mode` have been merged into `set_preset_mode`. So instead of `turn_away_mode_on()`, we will now call `set_preset_mode("away")`. * The `is_on` property has been removed. If a 设备 is able to 关闭, it should include the HVAC mode `HVAC_MODE_OFF`. * Property names have been aligned, anything ending with "\_list" is now named "\_modes". * 集成 are only allowed to represent functionality that is present in the API. It is not allowed to add your own fake away mode. Huge thanks to [@pvizeli] who drove the 核心 implementation and to the following people for helping getting it past the finish line: * [@andrewsayre] * [@balloob] * [@cgtobi] * [@Danielhiversen] * [@frenck] * [@Jc2k] * [@marvin-w] * [@OnFreund] * [@SukramJ] * [@zxdavb] [@JuanMTech]: https://github.com/JuanMTech [@Jc2k]: https://github.com/Jc2k [@marvin-w]: https://github.com/marvin-w [@OnFreund]: https://github.com/OnFreund [@SukramJ]: https://github.com/SukramJ [@isabellaalstrom]: https://github.com/isabellaalstrom ## 高级模式 As part of Home Assistant 1.0 effort, we're simplifying the default 用户 interface. We're doing this by hiding certain 配置 options like the customize 面板 behind a new "advanced mode" 切换. You can find this 切换 on your profile page. Advanced mode is only available to admin 用户 and is a per-用户 setting. Enabling it for yourself won't enable it for other admins. ## In other news… 树莓派 4 support has arrived in beta. [@pvizeli] has been hard at work and the first beta 发布 [is available](https://github.com/home-assistant/hassos/releases/tag/3.3). If you flash this 图像, you will be able to 更新 to a stable 发布 later from within the UI. Big shout out to [@frenck] who has been doing a lot of clean up on the website. Like, a lot lot. He has removed over 20.000 unused lines of code, and has simplified how we render code blocks, pages and headers. It takes Jekyll now a mere 14 seconds to generate the whole website! It used to be 6 minutes! 😲 Last week [@balloob] showed a preview of the upcoming [Home Assistant Cast](/home-assistant/blog/2019/07/09/home-assistant-cast-preview/), a new interface for Home Assistant that runs on Chromecasts and Google Assistant 设备 with screens. The [Home Assistant code repository on GitHub](https://github.com/home-assistant/home-assistant) has hit 25.000 stars! 🤩 The Home Assistant Podcast has published [episode 53](https://hasspodcast.io/ha053/) to discuss all the ins and outs of this new 发布. [@isabellaalstrom] has redone her Lovelace UI and it is looking fabulous! ## New 集成 * Add Trafikverket train component ([@endor-force] - [#23470]) ([trafikverket\_train docs][trafikverket_train docs]) (new-集成) * Add 集成 for Vallox Ventilation Units ([@andre-richter] - [#24660]) ([vallox docs]) (new-集成) * Add support for aurora ABB Powerone solar photovoltaic inverter ([@davet2001] - [#24809]) ([aurora\_abb\_powerone docs][aurora_abb_powerone docs]) (new-集成) * Add support for arcam fmj receivers ([@elupus] - [#24621]) ([arcam\_fmj docs][arcam_fmj docs]) (new-集成) * Add support for Notion Home Monitoring ([@bachya] - [#24634]) ([notion docs]) (new-集成) * Add support for World Wide Lightning Location Network ([@bachya] - [#25001]) (new-集成) ## New Platforms * Add 模板 吸尘器 support ([@luukd] - [#22904]) ([模板 docs]) (new-platform) * Fronius (solar energy and inverter) component ([@nielstron] - [#22316]) ([传感器 docs]) (new-platform) * New scanner 设备 tracker and ZHA 设备 tracker support ([@dmulcahey] - [#24584]) ([device\_tracker docs][device_tracker docs]) ([zha docs]) (new-platform) * \[温控] Bugfix honeywell misleading 错误 message ([@zxdavb] - [#25048]) ([evohome docs]) ([honeywell docs]) (new-platform) * \[温控] Add water\_heater to evohome ([@zxdavb] - [#25035]) ([evohome docs]) (beta fix) (new-platform) * \[温控] Hive Add 热水器 Component post the refresh of the 温控 component. ([@KJonline] - [#25148]) ([hive docs]) (beta fix) (new-platform) ## 发布 0.96.1 - July 18 * Show off value ([@pvizeli] - [#25236]) * Fix eq3btsmart ([@pvizeli] - [#25238]) ([eq3btsmart docs]) * Make presets prettier ([@cgtobi] - [#25245]) ([netatmo docs]) * Fix the unit of measurement for ecobee 温控 ([@cgtobi] - [#25246]) ([ecobee docs]) * ecobee Preset Fix ([@geekofweek] - [#25256]) ([ecobee docs]) * 更新 CT80 Humidity call ([@zombielinux] - [#25258]) ([radiotherm docs]) * 恢复 SmartThings A/C on/off 服务 ([@andrewsayre] - [#25259]) ([smartthings docs]) * Add hvac modes back to opentherm ([@balloob] - [#25268]) ([opentherm\_gw docs][opentherm_gw docs]) * Added 状态 and modes for zwave 温控 ([@stboch] - [#25274]) ([zwave docs]) [#25236]: https://github.com/home-assistant/home-assistant/pull/25236 [#25238]: https://github.com/home-assistant/home-assistant/pull/25238 [#25245]: https://github.com/home-assistant/home-assistant/pull/25245 [#25246]: https://github.com/home-assistant/home-assistant/pull/25246 [#25256]: https://github.com/home-assistant/home-assistant/pull/25256 [#25258]: https://github.com/home-assistant/home-assistant/pull/25258 [#25259]: https://github.com/home-assistant/home-assistant/pull/25259 [#25268]: https://github.com/home-assistant/home-assistant/pull/25268 [#25274]: https://github.com/home-assistant/home-assistant/pull/25274 [@andrewsayre]: https://github.com/andrewsayre [@balloob]: https://github.com/balloob [@cgtobi]: https://github.com/cgtobi [@geekofweek]: https://github.com/geekofweek [@pvizeli]: https://github.com/pvizeli [@stboch]: https://github.com/stboch [@zombielinux]: https://github.com/zombielinux [ecobee docs]: /integrations/ecobee/ [eq3btsmart docs]: /integrations/eq3btsmart/ [netatmo docs]: /integrations/netatmo/ [opentherm_gw docs]: /integrations/opentherm_gw/ [radiotherm docs]: /integrations/radiotherm/ [smartthings docs]: /integrations/smartthings/ [zwave docs]: /integrations/zwave/ ## 发布 0.96.2 - July 19 * Fix fritzbox 温控 HVAC mode / temperature ([@cgtobi] - [#25275]) ([fritzbox docs]) * Fixed python-wink method names ([@w1ll1am23] - [#25285]) ([wink docs]) * \[温控] Correct honeywell supported\_features ([@zxdavb] - [#25292]) ([honeywell docs]) * Fix HM with use wrong datapoint for off ([@pvizeli] - [#25298]) ([homematic docs]) * Fix plant 错误 when adding new value ([@cgtobi] - [#25302]) ([plant docs]) [#25275]: https://github.com/home-assistant/home-assistant/pull/25275 [#25285]: https://github.com/home-assistant/home-assistant/pull/25285 [#25292]: https://github.com/home-assistant/home-assistant/pull/25292 [#25298]: https://github.com/home-assistant/home-assistant/pull/25298 [#25302]: https://github.com/home-assistant/home-assistant/pull/25302 [@cgtobi]: https://github.com/cgtobi [@pvizeli]: https://github.com/pvizeli [@w1ll1am23]: https://github.com/w1ll1am23 [@zxdavb]: https://github.com/zxdavb [fritzbox docs]: /integrations/fritzbox/ [homematic docs]: /integrations/homematic/ [honeywell docs]: /integrations/honeywell/ [plant docs]: /integrations/plant/ [wink docs]: /integrations/wink/ ## 发布 0.96.3 - July 21 * temporary patch to fix KNX 温控 设备 ([@farmio] - [#25356]) ([knx docs]) * 恢复 sensiobo 打开/off methods ([@balloob] - [#25321]) ([sensibo docs]) * 更新 zwave 温控 mappings ([@eyager1] - [#25327]) ([zwave docs]) * 恢复 Daikin A/C on/off 服务 ([@fredrike] - [#25332]) ([daikin docs]) * Fix for hvac\_modes list being null ([@schmic] - [#25347]) ([zwave docs]) * add available to 设备 info ([@dmulcahey] - [#25349]) ([zha docs]) * Fix preset 服务 call ([@cgtobi] - [#25358]) ([netatmo docs]) * Improve geniushub logging and bump client ([@zxdavb] - [#25359]) ([geniushub docs]) * Introduce PRESET\_NONE for 温控 ([@balloob] - [#25360]) * bump quirks 版本 ([@dmulcahey] - [#25362]) ([zha docs]) * Fix ESPHome 温控 migration ([@OttoWinter] - [#25366]) ([esphome docs]) * fix remove and re-add scenario ([@dmulcahey] - [#25370]) ([zha docs]) * change and 条件 to or 条件 ([@dmulcahey] - [#25374]) * Add Netatmo 温控 battery level ([@cgtobi] - [#25143]) ([netatmo docs]) [#25321]: https://github.com/home-assistant/home-assistant/pull/25321 [#25143]: https://github.com/home-assistant/home-assistant/pull/25143 [#25327]: https://github.com/home-assistant/home-assistant/pull/25327 [#25332]: https://github.com/home-assistant/home-assistant/pull/25332 [#25347]: https://github.com/home-assistant/home-assistant/pull/25347 [#25349]: https://github.com/home-assistant/home-assistant/pull/25349 [#25356]: https://github.com/home-assistant/home-assistant/pull/25356 [#25358]: https://github.com/home-assistant/home-assistant/pull/25358 [#25359]: https://github.com/home-assistant/home-assistant/pull/25359 [#25360]: https://github.com/home-assistant/home-assistant/pull/25360 [#25362]: https://github.com/home-assistant/home-assistant/pull/25362 [#25366]: https://github.com/home-assistant/home-assistant/pull/25366 [#25370]: https://github.com/home-assistant/home-assistant/pull/25370 [#25374]: https://github.com/home-assistant/home-assistant/pull/25374 [@OttoWinter]: https://github.com/OttoWinter [@balloob]: https://github.com/balloob [@cgtobi]: https://github.com/cgtobi [@dmulcahey]: https://github.com/dmulcahey [@eyager1]: https://github.com/eyager1 [@farmio]: https://github.com/farmio [@fredrike]: https://github.com/fredrike [@schmic]: https://github.com/schmic [@zxdavb]: https://github.com/zxdavb [daikin docs]: /integrations/daikin/ [esphome docs]: /integrations/esphome/ [geniushub docs]: /integrations/geniushub/ [knx docs]: /integrations/knx/ [netatmo docs]: /integrations/netatmo/ [sensibo docs]: /integrations/sensibo/ [zha docs]: /integrations/zha/ [zwave docs]: /integrations/zwave/ ## 发布 0.96.4 - July 23 * Fix Netatmo 温控 battery level ([@cgtobi] - [#25165]) ([netatmo docs]) * Tweak evohome migration ([@zxdavb] - [#25281]) ([evohome docs]) * Bump pyatmo 版本 to 2.1.2 ([@cgtobi] - [#25296]) ([netatmo docs]) * \[温控] Bugfix/Tweak honeywell migration ([@zxdavb] - [#25369]) ([honeywell docs]) * 更新 Daikin preset modes ([@fredrike] - [#25395]) ([daikin docs]) * 更新 pysonos to 0.0.22 ([@amelchio] - [#25399]) ([sonos docs]) * \[温控] Correct evohome hvac\_action ([@zxdavb] - [#25407]) ([evohome docs]) [#25165]: https://github.com/home-assistant/home-assistant/pull/25165 [#25281]: https://github.com/home-assistant/home-assistant/pull/25281 [#25296]: https://github.com/home-assistant/home-assistant/pull/25296 [#25369]: https://github.com/home-assistant/home-assistant/pull/25369 [#25395]: https://github.com/home-assistant/home-assistant/pull/25395 [#25399]: https://github.com/home-assistant/home-assistant/pull/25399 [#25407]: https://github.com/home-assistant/home-assistant/pull/25407 [@amelchio]: https://github.com/amelchio [@cgtobi]: https://github.com/cgtobi [@fredrike]: https://github.com/fredrike [@zxdavb]: https://github.com/zxdavb [daikin docs]: /integrations/daikin/ [evohome docs]: /integrations/evohome/ [honeywell docs]: /integrations/honeywell/ [netatmo docs]: /integrations/netatmo/ [sonos docs]: /integrations/sonos/ ## 发布 0.96.5 - July 25 * Bump geniushub client ([@zxdavb] - [#25458]) ([geniushub docs]) * Allow cors for static files ([@balloob] - [#25468]) ([http docs]) * Fix Nest turning off eco ([@balloob] - [#25472]) ([nest docs]) [#25458]: https://github.com/home-assistant/home-assistant/pull/25458 [#25468]: https://github.com/home-assistant/home-assistant/pull/25468 [#25472]: https://github.com/home-assistant/home-assistant/pull/25472 [@balloob]: https://github.com/balloob [@zxdavb]: https://github.com/zxdavb [geniushub docs]: /integrations/geniushub/ [http docs]: /integrations/http/ [nest docs]: /integrations/nest/ ## 如果你需要帮助…… ……欢迎随时使用我们非常活跃的[论坛](https://community.home-assistant.io/),或者加入我们的 [聊天频道](https://discord.gg/c5DvZ4e)。 ## 反馈问题 如果这次发布引入了问题,请前往我们的 [issue tracker](https://github.com/home-assistant/home-assistant/issues) 提交反馈。请务必填写 issue 模板中的所有字段。 ## Backward-incompatible changes * **OpenTherm** - Adds support for more than one OpenTherm Gateway 设备 which changes the 配置 structure. ([@mvn23] - [#22932]) ([opentherm\_gw docs][opentherm_gw docs]) Example 配置: ```yaml opentherm_gw: living_room: device: /dev/ttyUSB0 ``` * **Ambient 天气 Station** - By default, the Ambient solar radiation (i.e., brightness) 传感器 is measured in W/m². Since this unit of measurement is not used anywhere else, this change updates the 传感器 to use the more prevalent lx unit. Any 自动化 that use this 传感器 should be updated accordingly. ([@bachya] - [#24690]) ([ambient\_station docs][ambient_station docs]) * **Google Cloud** - Changed the default encoding to mp3 from opus ogg, allowing it to support many more media players. ([@GrandNewbien] - [#24808]) ([google\_cloud docs][google_cloud docs]) Example 配置: ```yaml tts: - platform: google_cloud key_file: googlecloud.json encoding: mp3 # The new default, which can still be changed to opus ogg or linear16 ``` * **SimpliSafe** - The SimpliSafe 报警 control 面板 no longer shows a temperature 属性. ([@bachya] - [#24833]) ([simplisafe docs]) * **Luftdaten** - The under-laying Python module is now limited to the P1 (particles 10 microns and below) and P2 (particles 2.5 microns and below), which means you have to recreate your 传感器. ([@fabaff] - [#24842]) ([luftdaten docs]) * **Velbus** - Added autodicovery for 遮盖 in velbus and bumped the python velbus 版本 ([@Cereal2nd] - [#24877]) ([velbus docs]) * **ZHA** - ZHA 实体 are being removed and battery 传感器 are being added. We have been asked several times to remove the ZHA domain 实体 because they do not follow the HA standards. They were originally used to show 设备 online / offline status, rssi, lqi and last seen. They were eventually expanded to hold battery information as well because many Zigbee 设备 have several power 配置 clusters. Online and offline handling, rssi, lqi last seen and the handling of 设备 availability have all been moved to the 设备 object and battery information has been split back out into its own 传感器. Any 用户 that 创建 模板 传感器 that leveraged the data in the ZHA 实体 will be affected by this change. ([@dmulcahey] - [#24909]) ([zha docs]) * **Netatmo** - If the module type can not be determined the 温控 设备 will default to the type "valve" as it implements a subset of "thermostat". Consequently those 设备 wont be able to be turned off. This should not be a major issue and should only happen when there are issues with the data retrieved form the Netatmo API. ([@cgtobi] - [#25029]) ([netatmo docs]) * **Netatmo** - The 配置 of individual monitored 条件 has been removed so that now all 条件 are available per module by default. ([@cgtobi] - [#24944]) (netatmo docs) * **GeoJSON Events** - 更新 geojson\_client library to 版本 0.4.This changes the access to the external feed from HTTP to HTTPS for the nsw\_rural\_fire\_service\_feed platform. This should normally not make any difference to anyone consuming this feed. Only if for example you have set up a 模板 传感器 or 自动化 that reads the external\_id 属性 of a geo\_location 实体 and compare it against a pattern, would you need to change this. ([@exxamalte] - [#25039]) ([geo\_json\_events docs][geo_json_events docs]) ([nsw\_rural\_fire\_service\_feed docs][nsw_rural_fire_service_feed docs]) ([usgs\_earthquakes\_feed docs][usgs_earthquakes_feed docs]) ## Beta Fixes * Add websocket API command for Z-Wave network status ([@cgarwood] - [#25066]) ([zwave docs]) (beta fix) * Do not reverse open/close calls ([@balloob] - [#24879]) ([tahoma docs]) (breaking change) (beta fix) * Add support for on/off 温控 ([@pvizeli] - [#25026]) ([温控 docs]) (beta fix) * Change unique\_id formula for Notion 实体 ([@bachya] - [#25076]) ([notion docs]) (beta fix) * Fix powercontrol media player alexa ([@pvizeli] - [#25080]) ([alexa docs]) (beta fix) * Support podcast episodes as Sonos favorites ([@amelchio] - [#25087]) ([sonos docs]) (beta fix) * Guard module being None ([@balloob] - [#25077]) (beta fix) * \[温控] Add water\_heater to evohome ([@zxdavb] - [#25035]) ([evohome docs]) (beta fix) (new-platform) * Fix Netatmo 温控 issue when 设备 out of reach ([@cgtobi] - [#25096]) ([netatmo docs]) (beta fix) * Add 打开/off to coolmaster ([@OnFreund] - [#25097]) ([coolmaster docs]) (beta fix) * Fix window exception in WWLLN ([@bachya] - [#25100]) (beta fix) * Fix missing 传感器 unit in RainMachine ([@bachya] - [#25101]) ([rainmachine docs]) (beta fix) * Add 温控 related 服务 to Homematic IP Cloud ([@SukramJ] - [#25079]) ([homematicip\_cloud docs][homematicip_cloud docs]) (beta fix) * Simplify Alexa/Google for new 温控 turn\_on/off ([@balloob] - [#25115]) ([alexa docs]) ([google\_assistant docs][google_assistant docs]) (beta fix) * Verify cloud 用户 exists during boot ([@balloob] - [#25119]) ([cloud docs]) (beta fix) * Allow 区域 ID in 服务 call schemas ([@balloob] - [#25121]) ([灯光 docs]) ([开关 docs]) (beta fix) * Load requirements for platforms ([@elupus] - [#25133]) (beta fix) * Handle Sonos connection 错误 during 设置 ([@amelchio] - [#25135]) ([sonos docs]) (beta fix) * \[温控-1.0] Bugfix evohome showstopper ([@zxdavb] - [#25139]) ([evohome docs]) (beta fix) * remove comfort mode ([@SukramJ] - [#25140]) ([homematicip\_cloud docs][homematicip_cloud docs]) (beta fix) * \[温控-1.0] Add RoundThermostat to evohome ([@zxdavb] - [#25141]) ([evohome docs]) (beta fix) * \[温控] Hive Add 热水器 Component post the refresh of the 温控 component. ([@KJonline] - [#25148]) ([hive docs]) (beta fix) (new-platform) * Remove check and 恢复 temp/mode changes ([@andersonshatch] - [#25149]) ([tado docs]) (beta fix) * 更新 pyhomematic to 0.1.60 ([@danielperna84] - [#25152]) ([homematic docs]) (beta fix) * 版本 传感器 更新 ([@ludeeus] - [#25162]) ([版本 docs]) (beta fix) * Make dev tools titlte translatable ([@balloob] - [#25166]) ([前端 docs]) (beta fix) * Fix 设备 types for some HomeMatic IP 传感器 ([@danielperna84] - [#25167]) ([homematic docs]) (beta fix) * 更新 pysonos to 0.0.21 ([@amelchio] - [#25168]) (beta fix) * Fix 温控 is\_aux\_heat type hint. ([@Adminiuga] - [#25170]) ([温控 docs]) (beta fix) * 升级 luftdaten to 0.6.2 ([@fabaff] - [#25177]) ([luftdaten docs]) (beta fix) * Correctly set property decorator on preset modes ([@balloob] - [#25151]) ([fritzbox docs]) (beta fix) * Fix 设备 name customization on ZHA add 设备 page ([@dmulcahey] - [#25180]) ([zha docs]) (beta fix) * \[温控] Tweak evohome migration ([@zxdavb] - [#25187]) ([evohome docs]) (beta fix) * Only include target temp if has right support flag ([@balloob] - [#25193]) ([温控 docs]) (beta fix) ## All changes * Fix AttributeError: 'NoneType' object has no 属性 'group' with sytadin component ([@foreign-sub] - [#24652]) * braviatv, nmap\_tracker: use getmac for getting MAC addresses ([@scop] - [#24628]) ([braviatv docs]) ([braviatv docs]) ([braviatv docs]) ([nmap\_tracker docs][nmap_tracker docs]) * Fix downloader\_download\_failed event not firing for HTTP response 错误 ([@sfjes] - [#24640]) ([downloader docs]) * Multiple 设备 support for opentherm\_gw ([@mvn23] - [#22932]) ([opentherm\_gw docs][opentherm_gw docs]) (breaking change) * Add 设备 class support for Ambient PWS 传感器 ([@bachya] - [#24677]) ([ambient\_station docs][ambient_station docs]) * Add RainMachine 设备 classes where appropriate ([@bachya] - [#24682]) ([rainmachine docs]) * Change Ambient solar radiation units to lx ([@bachya] - [#24690]) ([ambient\_station docs][ambient_station docs]) (breaking change) * 升级 to async\_upnp\_client==0.14.10 and increase search timeout ([@StevenLooman] - [#24685]) ([dlna\_dmr docs][dlna_dmr docs]) ([upnp docs]) * 升级 mypy to 0.710 ([@scop] - [#24666]) * 模板: Expand method to expand groups, and closest as filter ([@Swamp-Ig] - [#23691]) * Add aml\_thermal label ([@jmw6773] - [#24665]) ([glances docs]) * Corrected number of default LCN segment coupler scan tryouts ([@alengwenus] - [#24678]) ([lcn docs]) * 升级 discord.py to 1.2.2 ([@fabaff] - [#24695]) ([discord docs]) * 升级 youtube\_dl to 2019.06.08 ([@fabaff] - [#24692]) ([media\_extractor docs][media_extractor docs]) * 升级 Sphinx to 2.1.2 ([@fabaff] - [#24693]) * Solax 更新 0.1.0 ([@squishykid] - [#24708]) ([solax docs]) * Fix PS4 实体 with shared host not updating and latency with multiple connections ([@ktnrg45] - [#24642]) ([ps4 docs]) * Add initial support for 遥控器 dev 容器 ([@pvizeli] - [#24681]) * Expose ports 8123, 8300 and 51827 in Dockerfile ([@johnluetke] - [#24389]) * Add Trafikverket train component ([@endor-force] - [#23470]) ([trafikverket\_train docs][trafikverket_train docs]) (new-集成) * Add 'unique\_id' Property to Inverter 传感器 ([@squishykid] - [#24707]) ([solax docs]) * Remove 设备 and 实体 registry entries when removing a ZHA 设备 ([@dmulcahey] - [#24369]) ([zha docs]) * Add support for 传感器 状态 STATE\_UNAVAILABLE ([@cnrd] - [#24641]) ([plant docs]) * Add 集成 for Vallox Ventilation Units ([@andre-richter] - [#24660]) ([vallox docs]) (new-集成) * Vallox: Fix missing hass member ([@andre-richter] - [#24753]) ([vallox docs]) * Remove obsolete comments in Dockerfile ([@Emilv2] - [#24748]) * fix an 错误 in the description ([@alain57] - [#24735]) * Add support for IPP Printers to the CUPS 集成 ([@Matte23] - [#24756]) ([cups docs]) * Enhancement/zha model manuf ([@Adminiuga] - [#24771]) ([zha docs]) * 实体 to handle updates via events ([@balloob] - [#24733]) * 升级 vallox to async client API ([@andre-richter] - [#24774]) ([vallox docs]) * 升级 pytest to 4.6.3 ([@scop] - [#24782]) * Add time delta option when searching for deutsche\_bahn connections ([@h3ndrik] - [#24600]) ([deutsche\_bahn docs][deutsche_bahn docs]) * Zestimate fix for issue #23837 ([@dreed47] - [#23838]) ([zestimate docs]) * Use 温控 设备's target temp step value ([@andersonshatch] - [#24804]) ([homekit docs]) * Use step from tado rather than assuming 0.1 ([@andersonshatch] - [#24807]) ([tado docs]) * Changed default encoding to mp3 ([@GrandNewbien] - [#24808]) ([google\_cloud docs][google_cloud docs]) (breaking change) * Add 开发者工具 面板 ([@balloob] - [#24812]) ([前端 docs]) * Add 模板 吸尘器 support ([@luukd] - [#22904]) ([模板 docs]) (new-platform) * Make sure alert is set up after 通知 ([@balloob] - [#24829]) ([alert docs]) * Remove temperature 属性 from SimpliSafe 报警 control 面板 ([@bachya] - [#24833]) ([simplisafe docs]) (breaking change) * Fronius (solar energy and inverter) component ([@nielstron] - [#22316]) ([传感器 docs]) (new-platform) * Add 模板 support to 模板 触发器's for option ([@pnbruckner] - [#24810]) ([自动化 docs]) * 升级 sisyphus-control to 2.2 ([@jkeljo] - [#24837]) ([sisyphus docs]) * Fix yeelight color temp getter ([@zewelor] - [#24830]) ([yeelight docs]) * 升级 luftdaten to 0.6.1 ([@fabaff] - [#24842]) ([luftdaten docs]) (breaking change) * 升级 sqlalchemy to 1.3.5 ([@fabaff] - [#24844]) ([recorder docs]) ([sql docs]) * 升级 numpy to 1.16.4 ([@fabaff] - [#24845]) ([iqvia docs]) ([opencv docs]) ([tensorflow docs]) ([trend docs]) * 升级 certifi to >= 2019.6.16 ([@fabaff] - [#24846]) * 升级 pyyaml to 5.1.1 ([@fabaff] - [#24847]) * 升级 jinja2 to >=2.10.1 ([@fabaff] - [#24851]) * 升级 psutil to 5.6.3 ([@fabaff] - [#24854]) ([systemmonitor docs]) * 升级 cryptography to 2.7 ([@fabaff] - [#24852]) * Fix mysensors icon name ([@zewelor] - [#24871]) ([mysensors docs]) * 更新 praw to 6.3.1 ([@fabaff] - [#23737]) ([reddit docs]) * Hungarian is also supported in Google Cloud TTS ([@realthk] - [#24861]) ([google\_cloud docs][google_cloud docs]) * 升级 youtube\_dl to 2019.06.27 ([@fabaff] - [#24875]) ([media\_extractor docs][media_extractor docs]) * Velbus: autodiscover 遮盖 ([@Cereal2nd] - [#24877]) ([velbus docs]) (breaking change) * 升级 importlib-metadata to 0.18 ([@fabaff] - [#24848]) * 升级 bcrypt to 3.1.7 ([@fabaff] - [#24850]) * Fix traceback during ZHA 设备 removal ([@dmulcahey] - [#24882]) ([zha docs]) * Move SmartThings imports to top ([@andrewsayre] - [#24878]) ([smartthings docs]) * Bump androidtv to 0.0.17 ([@JeffLIrion] - [#24886]) * 升级 pytest to 5.0.0 ([@Danielhiversen] - [#24885]) * Tweak geniushub battery icons according to 设备 状态 ([@zxdavb] - [#24798]) ([geniushub docs]) * Support MQTT discovery topic prefix with slashes ([@cybe] - [#24840]) ([MQTT docs]) * 更新 tts.py ([@kevank] - [#24892]) ([watson\_tts docs][watson_tts docs]) * go back to signals and no hard 实体 references ([@dmulcahey] - [#24894]) ([zha docs]) * 更新 IDs for rename node/value ([@Swamp-Ig] - [#24646]) ([zwave docs]) * Bump life360 package to 4.0.1 ([@pnbruckner] - [#24905]) ([life360 docs]) * Stability improvements for Sonos availability ([@amelchio] - [#24880]) ([sonos docs]) * Fix 'same 状态' monitoring in numeric\_state 触发器 ([@pnbruckner] - [#24910]) ([自动化 docs]) * Fix 'same 状态' monitoring in 状态 触发器 ([@pnbruckner] - [#24904]) ([自动化 docs]) * Add missing 触发器.for variable to 模板 触发器 ([@pnbruckner] - [#24893]) ([自动化 docs]) * Add ability to send attachments in pushover 通知 ([@kreegahbundolo] - [#24806]) ([pushover docs]) * Fix home coach discovery ([@cgtobi] - [#24902]) ([netatmo docs]) * New languages that looks like supported by Google but not documented: ([@lufton] - [#24881]) ([google\_cloud docs][google_cloud docs]) * Remove ZHA 设备 实体 ([@dmulcahey] - [#24909]) ([zha docs]) (breaking change) * Bump androidtv to 0.0.18 ([@JeffLIrion] - [#24927]) ([androidtv docs]) * 更新 pysonos to 0.0.19 ([@amelchio] - [#24930]) ([sonos docs]) * Add support for Yale YRL256 门锁 ([@ctso] - [#24932]) ([zwave docs]) * Fix exclusion of routes with excl\_filter ([@gadgetchnnel] - [#24928]) ([waze\_travel\_time docs][waze_travel_time docs]) * New scanner 设备 tracker and ZHA 设备 tracker support ([@dmulcahey] - [#24584]) ([device\_tracker docs][device_tracker docs]) ([zha docs]) (new-platform) * Allow updating of via\_device in 设备 registry ([@bachya] - [#24921]) * 更新 pyHik library to 0.2.3 ([@mezz64] - [#24957]) ([hikvision docs]) * Implement ADR0003 for Netatmo 传感器 ([@cgtobi] - [#24944]) ([netatmo docs]) (breaking change) * Fix monitoring of trays in syncthru component ([@nielstron] - [#24961]) ([syncthru docs]) * Batch of Component(s) -> 集成(s) ([@frenck] - [#24972]) * Add sonos.play\_queue 服务 ([@apeeters] - [#24974]) ([sonos docs]) * Fix 错误 if rest source becomes unavailable ([@slackr31337] - [#24986]) ([scrape docs]) * Switched from tuyapy to tuyaha as 1st one is not maintained ([@PaulAnnekov] - [#24821]) ([tuya docs]) * Adds 门锁 Threads Probot ([@frenck] - [#24984]) * Adds Stale Probot for issues ([@frenck] - [#24985]) * 升级 mypy to 0.711, drop no longer needed workarounds ([@scop] - [#24998]) * Changes as per code review of #24646 ([@Swamp-Ig] - [#24917]) ([zwave docs]) * Sleepiq single sleeper crash ([@qypea] - [#24941]) ([sleepiq docs]) * Add support for aurora ABB Powerone solar photovoltaic inverter ([@davet2001] - [#24809]) ([aurora\_abb\_powerone docs][aurora_abb_powerone docs]) (new-集成) * Test dependency updates ([@scop] - [#25004]) * 升级 switchmate to latest lib ([@Danielhiversen] - [#25006]) ([switchmate docs]) * 升级 hdate==0.8.8 ([@tsvi] - [#25008]) ([jewish\_calendar docs][jewish_calendar docs]) * 升级 insteonplm to 0.16.0 and add INSTEON 场景 triggering ([@teharris1] - [#24765]) ([insteon docs]) * 安装 requirements for 集成 in packages before importing them. ([@ludeeus] - [#25005]) * Added missing yeelight models mapping ([@cadavre] - [#24963]) ([yeelight docs]) * Correct socket use in cert\_expiry platform ([@elupus] - [#25011]) ([cert\_expiry docs][cert_expiry docs]) * 温控 1.0 ([@pvizeli] - [#23899]) ([温控 docs]) * Implement Twilio SMS 通知 MediaUrl support ([@Chris-Johnston] - [#24971]) ([twilio\_sms docs][twilio_sms docs]) * Enphase envoy individual inverter production ([@jesserizzo] - [#24445]) ([enphase\_envoy docs][enphase_envoy docs]) * Add support for arcam fmj receivers ([@elupus] - [#24621]) ([arcam\_fmj docs][arcam_fmj docs]) (new-集成) * Sensibo, add HVAC\_MODE\_OFF ([@Danielhiversen] - [#25016]) ([sensibo docs]) * Fix ecobee flaky test ([@balloob] - [#25019]) ([ecobee docs]) * Fix mimetypes on borked Windows machines ([@balloob] - [#25018]) ([前端 docs]) * Add datetime option to input\_datetime.set\_datetime 服务 ([@pnbruckner] - [#24975]) ([input\_datetime docs][input_datetime docs]) * Add 模板 support to numeric\_state 触发器's for option ([@pnbruckner] - [#24955]) ([自动化 docs]) * Add 模板 support to 状态 触发器's for option ([@pnbruckner] - [#24912]) ([自动化 docs]) * Fix Nest 传感器 ([@balloob] - [#25023]) ([温控 docs]) ([nest docs]) * ambiclimate hvac\_modes ([@Danielhiversen] - [#25015]) ([ambiclimate docs]) * homematic add off support for 温控 ([@pvizeli] - [#25017]) ([homematic docs]) * Support config flow on custom components ([@elupus] - [#24946]) ([config docs]) * Improve SmartThings test mocking ([@andrewsayre] - [#25028]) * Toon fixes for 温控 1.0 ([@frenck] - [#25027]) ([toon docs]) * Add hvac 风扇 状态 ([@andrewsayre] - [#25030]) ([温控 docs]) ([smartthings docs]) * Add support for Notion Home Monitoring ([@bachya] - [#24634]) ([notion docs]) (new-集成) * Fix Netatmo 温控 presets ([@cgtobi] - [#25029]) ([netatmo docs]) (breaking change) * Add missing support for jewish\_calendar.omer\_count 传感器 ([@arigilder] - [#24958]) ([jewish\_calendar docs][jewish_calendar docs]) * Centralizes Toon data, reducing API calls ([@frenck] - [#23988]) ([toon docs]) * 升级 youtube\_dl to 2019.07.02 ([@fabaff] - [#24990]) ([media\_extractor docs][media_extractor docs]) * updated geojson\_client library to 版本 0.4 ([@exxamalte] - [#25039]) ([geo\_json\_events docs][geo_json_events docs]) ([nsw\_rural\_fire\_service\_feed docs][nsw_rural_fire_service_feed docs]) ([usgs\_earthquakes\_feed docs][usgs_earthquakes_feed docs]) (breaking change) * Improve toon 温控 ([@frenck] - [#25040]) ([toon docs]) * Fix Netatmo rain gauge precision ([@cgtobi] - [#25036]) ([netatmo docs]) * Bump pyvera to 0.3.2, null/missing value protection ([@jlrgraham] - [#25041]) ([vera docs]) * Add radiotherm CT80 current humidity support ([@zombielinux] - [#25024]) ([radiotherm docs]) * Add config flow support to Geolocation ([@bachya] - [#25046]) ([geo\_location docs][geo_location docs]) * 更新 tuyaha to 0.0.2 to catch API exceptions ([@PaulAnnekov] - [#25050]) ([tuya docs]) * Added marker 传感器 to CUPS 集成 ([@Matte23] - [#25037]) ([cups docs]) * Remove myself as codeowner ([@cdce8p] - [#25043]) ([homekit docs]) * \[温控] Bugfix honeywell misleading 错误 message ([@zxdavb] - [#25048]) ([evohome docs]) ([honeywell docs]) (new-platform) * Add Sonos 调试 logging ([@amelchio] - [#25063]) ([sonos docs]) * Avoid flooding steam API ([@Swamp-Ig] - [#23941]) ([steam\_online docs][steam_online docs]) * Add check\_config 助手 ([@kellerza] - [#24557]) * bump zha-quirks 版本 ([@dmulcahey] - [#25059]) ([zha docs]) * Fix broken test in Python 3.7 ([@balloob] - [#25067]) * Fix for Sonos 调试 logging ([@amelchio] - [#25064]) ([sonos docs]) * Bump up ZHA dependencies. ([@Adminiuga] - [#25062]) ([zha docs]) * Add support for World Wide Lightning Location Network ([@bachya] - [#25001]) (new-集成) * SMA catch 错误 ([@kellerza] - [#25045]) ([sma docs]) * Change phrases in the logbook component for persons and binary\_sensors ([@Martijn02] - [#25053]) ([logbook docs]) * Make sure volume level is valid when incrementing/decrementing ([@JeffLIrion] - [#25061]) ([vizio docs]) * Complete OPERATION\_MODES ([@monte-monte] - [#25069]) ([knx docs]) * Add websocket API command for Z-Wave network status ([@cgarwood] - [#25066]) ([zwave docs]) (beta fix) * Correctly store removed 实体 for 恢复 状态 ([@balloob] - [#25073]) * 恢复 自动化 last\_triggered as datetime & fix test ([@pnbruckner] - [#24951]) ([自动化 docs]) * Support hass-发布 inside devcontainer ([@pvizeli] - [#25090]) * Do not reverse open/close calls ([@balloob] - [#24879]) ([tahoma docs]) (breaking change) (beta fix) * Add support for on/off 温控 ([@pvizeli] - [#25026]) ([温控 docs]) (beta fix) * Change unique\_id formula for Notion 实体 ([@bachya] - [#25076]) ([notion docs]) (beta fix) * Fix powercontrol media player alexa ([@pvizeli] - [#25080]) ([alexa docs]) (beta fix) * Support podcast episodes as Sonos favorites ([@amelchio] - [#25087]) ([sonos docs]) (beta fix) * Guard module being None ([@balloob] - [#25077]) (beta fix) * \[温控] Add water\_heater to evohome ([@zxdavb] - [#25035]) ([evohome docs]) (beta fix) (new-platform) * Fix Netatmo 温控 issue when 设备 out of reach ([@cgtobi] - [#25096]) ([netatmo docs]) (beta fix) * Add 打开/off to coolmaster ([@OnFreund] - [#25097]) ([coolmaster docs]) (beta fix) * Fix window exception in WWLLN ([@bachya] - [#25100]) (beta fix) * Fix missing 传感器 unit in RainMachine ([@bachya] - [#25101]) ([rainmachine docs]) (beta fix) * Add 温控 related 服务 to Homematic IP Cloud ([@SukramJ] - [#25079]) ([homematicip\_cloud docs][homematicip_cloud docs]) (beta fix) * Simplify Alexa/Google for new 温控 turn\_on/off ([@balloob] - [#25115]) ([alexa docs]) ([google\_assistant docs][google_assistant docs]) (beta fix) * Verify cloud 用户 exists during boot ([@balloob] - [#25119]) ([cloud docs]) (beta fix) * Allow 区域 ID in 服务 call schemas ([@balloob] - [#25121]) ([灯光 docs]) ([开关 docs]) (beta fix) * Load requirements for platforms ([@elupus] - [#25133]) (beta fix) * Handle Sonos connection 错误 during 设置 ([@amelchio] - [#25135]) ([sonos docs]) (beta fix) * \[温控-1.0] Bugfix evohome showstopper ([@zxdavb] - [#25139]) ([evohome docs]) (beta fix) * remove comfort mode ([@SukramJ] - [#25140]) ([homematicip\_cloud docs][homematicip_cloud docs]) (beta fix) * \[温控-1.0] Add RoundThermostat to evohome ([@zxdavb] - [#25141]) ([evohome docs]) (beta fix) * \[温控] Hive Add 热水器 Component post the refresh of the 温控 component. ([@KJonline] - [#25148]) ([hive docs]) (beta fix) (new-platform) * Remove check and 恢复 temp/mode changes ([@andersonshatch] - [#25149]) ([tado docs]) (beta fix) * 更新 pyhomematic to 0.1.60 ([@danielperna84] - [#25152]) ([homematic docs]) (beta fix) * 版本 传感器 更新 ([@ludeeus] - [#25162]) ([版本 docs]) (beta fix) * Make dev tools titlte translatable ([@balloob] - [#25166]) ([前端 docs]) (beta fix) * Fix 设备 types for some HomeMatic IP 传感器 ([@danielperna84] - [#25167]) ([homematic docs]) (beta fix) * 更新 pysonos to 0.0.21 ([@amelchio] - [#25168]) (beta fix) * Fix 温控 is\_aux\_heat type hint. ([@Adminiuga] - [#25170]) ([温控 docs]) (beta fix) * 升级 luftdaten to 0.6.2 ([@fabaff] - [#25177]) ([luftdaten docs]) (beta fix) * Correctly set property decorator on preset modes ([@balloob] - [#25151]) ([fritzbox docs]) (beta fix) * Fix 设备 name customization on ZHA add 设备 page ([@dmulcahey] - [#25180]) ([zha docs]) (beta fix) * \[温控] Tweak evohome migration ([@zxdavb] - [#25187]) ([evohome docs]) (beta fix) * Only include target temp if has right support flag ([@balloob] - [#25193]) ([温控 docs]) (beta fix) [#22316]: https://github.com/home-assistant/home-assistant/pull/22316 [#22904]: https://github.com/home-assistant/home-assistant/pull/22904 [#22932]: https://github.com/home-assistant/home-assistant/pull/22932 [#23470]: https://github.com/home-assistant/home-assistant/pull/23470 [#23691]: https://github.com/home-assistant/home-assistant/pull/23691 [#23737]: https://github.com/home-assistant/home-assistant/pull/23737 [#23838]: https://github.com/home-assistant/home-assistant/pull/23838 [#23899]: https://github.com/home-assistant/home-assistant/pull/23899 [#23941]: https://github.com/home-assistant/home-assistant/pull/23941 [#23988]: https://github.com/home-assistant/home-assistant/pull/23988 [#24369]: https://github.com/home-assistant/home-assistant/pull/24369 [#24389]: https://github.com/home-assistant/home-assistant/pull/24389 [#24445]: https://github.com/home-assistant/home-assistant/pull/24445 [#24557]: https://github.com/home-assistant/home-assistant/pull/24557 [#24584]: https://github.com/home-assistant/home-assistant/pull/24584 [#24600]: https://github.com/home-assistant/home-assistant/pull/24600 [#24621]: https://github.com/home-assistant/home-assistant/pull/24621 [#24628]: https://github.com/home-assistant/home-assistant/pull/24628 [#24634]: https://github.com/home-assistant/home-assistant/pull/24634 [#24640]: https://github.com/home-assistant/home-assistant/pull/24640 [#24641]: https://github.com/home-assistant/home-assistant/pull/24641 [#24642]: https://github.com/home-assistant/home-assistant/pull/24642 [#24646]: https://github.com/home-assistant/home-assistant/pull/24646 [#24652]: https://github.com/home-assistant/home-assistant/pull/24652 [#24660]: https://github.com/home-assistant/home-assistant/pull/24660 [#24665]: https://github.com/home-assistant/home-assistant/pull/24665 [#24666]: https://github.com/home-assistant/home-assistant/pull/24666 [#24677]: https://github.com/home-assistant/home-assistant/pull/24677 [#24678]: https://github.com/home-assistant/home-assistant/pull/24678 [#24681]: https://github.com/home-assistant/home-assistant/pull/24681 [#24682]: https://github.com/home-assistant/home-assistant/pull/24682 [#24685]: https://github.com/home-assistant/home-assistant/pull/24685 [#24690]: https://github.com/home-assistant/home-assistant/pull/24690 [#24692]: https://github.com/home-assistant/home-assistant/pull/24692 [#24693]: https://github.com/home-assistant/home-assistant/pull/24693 [#24695]: https://github.com/home-assistant/home-assistant/pull/24695 [#24707]: https://github.com/home-assistant/home-assistant/pull/24707 [#24708]: https://github.com/home-assistant/home-assistant/pull/24708 [#24733]: https://github.com/home-assistant/home-assistant/pull/24733 [#24735]: https://github.com/home-assistant/home-assistant/pull/24735 [#24748]: https://github.com/home-assistant/home-assistant/pull/24748 [#24753]: https://github.com/home-assistant/home-assistant/pull/24753 [#24756]: https://github.com/home-assistant/home-assistant/pull/24756 [#24765]: https://github.com/home-assistant/home-assistant/pull/24765 [#24771]: https://github.com/home-assistant/home-assistant/pull/24771 [#24774]: https://github.com/home-assistant/home-assistant/pull/24774 [#24782]: https://github.com/home-assistant/home-assistant/pull/24782 [#24798]: https://github.com/home-assistant/home-assistant/pull/24798 [#24804]: https://github.com/home-assistant/home-assistant/pull/24804 [#24806]: https://github.com/home-assistant/home-assistant/pull/24806 [#24807]: https://github.com/home-assistant/home-assistant/pull/24807 [#24808]: https://github.com/home-assistant/home-assistant/pull/24808 [#24809]: https://github.com/home-assistant/home-assistant/pull/24809 [#24810]: https://github.com/home-assistant/home-assistant/pull/24810 [#24812]: https://github.com/home-assistant/home-assistant/pull/24812 [#24821]: https://github.com/home-assistant/home-assistant/pull/24821 [#24829]: https://github.com/home-assistant/home-assistant/pull/24829 [#24830]: https://github.com/home-assistant/home-assistant/pull/24830 [#24833]: https://github.com/home-assistant/home-assistant/pull/24833 [#24837]: https://github.com/home-assistant/home-assistant/pull/24837 [#24840]: https://github.com/home-assistant/home-assistant/pull/24840 [#24842]: https://github.com/home-assistant/home-assistant/pull/24842 [#24844]: https://github.com/home-assistant/home-assistant/pull/24844 [#24845]: https://github.com/home-assistant/home-assistant/pull/24845 [#24846]: https://github.com/home-assistant/home-assistant/pull/24846 [#24847]: https://github.com/home-assistant/home-assistant/pull/24847 [#24848]: https://github.com/home-assistant/home-assistant/pull/24848 [#24850]: https://github.com/home-assistant/home-assistant/pull/24850 [#24851]: https://github.com/home-assistant/home-assistant/pull/24851 [#24852]: https://github.com/home-assistant/home-assistant/pull/24852 [#24854]: https://github.com/home-assistant/home-assistant/pull/24854 [#24861]: https://github.com/home-assistant/home-assistant/pull/24861 [#24871]: https://github.com/home-assistant/home-assistant/pull/24871 [#24875]: https://github.com/home-assistant/home-assistant/pull/24875 [#24877]: https://github.com/home-assistant/home-assistant/pull/24877 [#24878]: https://github.com/home-assistant/home-assistant/pull/24878 [#24879]: https://github.com/home-assistant/home-assistant/pull/24879 [#24880]: https://github.com/home-assistant/home-assistant/pull/24880 [#24881]: https://github.com/home-assistant/home-assistant/pull/24881 [#24882]: https://github.com/home-assistant/home-assistant/pull/24882 [#24885]: https://github.com/home-assistant/home-assistant/pull/24885 [#24886]: https://github.com/home-assistant/home-assistant/pull/24886 [#24892]: https://github.com/home-assistant/home-assistant/pull/24892 [#24893]: https://github.com/home-assistant/home-assistant/pull/24893 [#24894]: https://github.com/home-assistant/home-assistant/pull/24894 [#24902]: https://github.com/home-assistant/home-assistant/pull/24902 [#24904]: https://github.com/home-assistant/home-assistant/pull/24904 [#24905]: https://github.com/home-assistant/home-assistant/pull/24905 [#24909]: https://github.com/home-assistant/home-assistant/pull/24909 [#24910]: https://github.com/home-assistant/home-assistant/pull/24910 [#24912]: https://github.com/home-assistant/home-assistant/pull/24912 [#24917]: https://github.com/home-assistant/home-assistant/pull/24917 [#24921]: https://github.com/home-assistant/home-assistant/pull/24921 [#24927]: https://github.com/home-assistant/home-assistant/pull/24927 [#24928]: https://github.com/home-assistant/home-assistant/pull/24928 [#24930]: https://github.com/home-assistant/home-assistant/pull/24930 [#24932]: https://github.com/home-assistant/home-assistant/pull/24932 [#24941]: https://github.com/home-assistant/home-assistant/pull/24941 [#24944]: https://github.com/home-assistant/home-assistant/pull/24944 [#24946]: https://github.com/home-assistant/home-assistant/pull/24946 [#24951]: https://github.com/home-assistant/home-assistant/pull/24951 [#24955]: https://github.com/home-assistant/home-assistant/pull/24955 [#24957]: https://github.com/home-assistant/home-assistant/pull/24957 [#24958]: https://github.com/home-assistant/home-assistant/pull/24958 [#24961]: https://github.com/home-assistant/home-assistant/pull/24961 [#24963]: https://github.com/home-assistant/home-assistant/pull/24963 [#24971]: https://github.com/home-assistant/home-assistant/pull/24971 [#24972]: https://github.com/home-assistant/home-assistant/pull/24972 [#24974]: https://github.com/home-assistant/home-assistant/pull/24974 [#24975]: https://github.com/home-assistant/home-assistant/pull/24975 [#24984]: https://github.com/home-assistant/home-assistant/pull/24984 [#24985]: https://github.com/home-assistant/home-assistant/pull/24985 [#24986]: https://github.com/home-assistant/home-assistant/pull/24986 [#24990]: https://github.com/home-assistant/home-assistant/pull/24990 [#24998]: https://github.com/home-assistant/home-assistant/pull/24998 [#25001]: https://github.com/home-assistant/home-assistant/pull/25001 [#25004]: https://github.com/home-assistant/home-assistant/pull/25004 [#25005]: https://github.com/home-assistant/home-assistant/pull/25005 [#25006]: https://github.com/home-assistant/home-assistant/pull/25006 [#25008]: https://github.com/home-assistant/home-assistant/pull/25008 [#25011]: https://github.com/home-assistant/home-assistant/pull/25011 [#25015]: https://github.com/home-assistant/home-assistant/pull/25015 [#25016]: https://github.com/home-assistant/home-assistant/pull/25016 [#25017]: https://github.com/home-assistant/home-assistant/pull/25017 [#25018]: https://github.com/home-assistant/home-assistant/pull/25018 [#25019]: https://github.com/home-assistant/home-assistant/pull/25019 [#25023]: https://github.com/home-assistant/home-assistant/pull/25023 [#25024]: https://github.com/home-assistant/home-assistant/pull/25024 [#25026]: https://github.com/home-assistant/home-assistant/pull/25026 [#25027]: https://github.com/home-assistant/home-assistant/pull/25027 [#25028]: https://github.com/home-assistant/home-assistant/pull/25028 [#25029]: https://github.com/home-assistant/home-assistant/pull/25029 [#25030]: https://github.com/home-assistant/home-assistant/pull/25030 [#25035]: https://github.com/home-assistant/home-assistant/pull/25035 [#25036]: https://github.com/home-assistant/home-assistant/pull/25036 [#25037]: https://github.com/home-assistant/home-assistant/pull/25037 [#25039]: https://github.com/home-assistant/home-assistant/pull/25039 [#25040]: https://github.com/home-assistant/home-assistant/pull/25040 [#25041]: https://github.com/home-assistant/home-assistant/pull/25041 [#25043]: https://github.com/home-assistant/home-assistant/pull/25043 [#25045]: https://github.com/home-assistant/home-assistant/pull/25045 [#25046]: https://github.com/home-assistant/home-assistant/pull/25046 [#25048]: https://github.com/home-assistant/home-assistant/pull/25048 [#25050]: https://github.com/home-assistant/home-assistant/pull/25050 [#25053]: https://github.com/home-assistant/home-assistant/pull/25053 [#25059]: https://github.com/home-assistant/home-assistant/pull/25059 [#25061]: https://github.com/home-assistant/home-assistant/pull/25061 [#25062]: https://github.com/home-assistant/home-assistant/pull/25062 [#25063]: https://github.com/home-assistant/home-assistant/pull/25063 [#25064]: https://github.com/home-assistant/home-assistant/pull/25064 [#25066]: https://github.com/home-assistant/home-assistant/pull/25066 [#25067]: https://github.com/home-assistant/home-assistant/pull/25067 [#25069]: https://github.com/home-assistant/home-assistant/pull/25069 [#25073]: https://github.com/home-assistant/home-assistant/pull/25073 [#25076]: https://github.com/home-assistant/home-assistant/pull/25076 [#25077]: https://github.com/home-assistant/home-assistant/pull/25077 [#25079]: https://github.com/home-assistant/home-assistant/pull/25079 [#25080]: https://github.com/home-assistant/home-assistant/pull/25080 [#25087]: https://github.com/home-assistant/home-assistant/pull/25087 [#25090]: https://github.com/home-assistant/home-assistant/pull/25090 [#25096]: https://github.com/home-assistant/home-assistant/pull/25096 [#25097]: https://github.com/home-assistant/home-assistant/pull/25097 [#25100]: https://github.com/home-assistant/home-assistant/pull/25100 [#25101]: https://github.com/home-assistant/home-assistant/pull/25101 [#25115]: https://github.com/home-assistant/home-assistant/pull/25115 [#25119]: https://github.com/home-assistant/home-assistant/pull/25119 [#25121]: https://github.com/home-assistant/home-assistant/pull/25121 [#25133]: https://github.com/home-assistant/home-assistant/pull/25133 [#25135]: https://github.com/home-assistant/home-assistant/pull/25135 [#25139]: https://github.com/home-assistant/home-assistant/pull/25139 [#25140]: https://github.com/home-assistant/home-assistant/pull/25140 [#25141]: https://github.com/home-assistant/home-assistant/pull/25141 [#25148]: https://github.com/home-assistant/home-assistant/pull/25148 [#25149]: https://github.com/home-assistant/home-assistant/pull/25149 [#25151]: https://github.com/home-assistant/home-assistant/pull/25151 [#25152]: https://github.com/home-assistant/home-assistant/pull/25152 [#25162]: https://github.com/home-assistant/home-assistant/pull/25162 [#25166]: https://github.com/home-assistant/home-assistant/pull/25166 [#25167]: https://github.com/home-assistant/home-assistant/pull/25167 [#25168]: https://github.com/home-assistant/home-assistant/pull/25168 [#25170]: https://github.com/home-assistant/home-assistant/pull/25170 [#25177]: https://github.com/home-assistant/home-assistant/pull/25177 [#25180]: https://github.com/home-assistant/home-assistant/pull/25180 [#25187]: https://github.com/home-assistant/home-assistant/pull/25187 [#25193]: https://github.com/home-assistant/home-assistant/pull/25193 [@Adminiuga]: https://github.com/Adminiuga [@Cereal2nd]: https://github.com/Cereal2nd [@Chris-Johnston]: https://github.com/Chris-Johnston [@Danielhiversen]: https://github.com/Danielhiversen [@Emilv2]: https://github.com/Emilv2 [@GrandNewbien]: https://github.com/GrandNewbien [@JeffLIrion]: https://github.com/JeffLIrion [@KJonline]: https://github.com/KJonline [@Martijn02]: https://github.com/Martijn02 [@Matte23]: https://github.com/Matte23 [@OnFreund]: https://github.com/OnFreund [@PaulAnnekov]: https://github.com/PaulAnnekov [@StevenLooman]: https://github.com/StevenLooman [@SukramJ]: https://github.com/SukramJ [@Swamp-Ig]: https://github.com/Swamp-Ig [@alain57]: https://github.com/alain57 [@alengwenus]: https://github.com/alengwenus [@amelchio]: https://github.com/amelchio [@andersonshatch]: https://github.com/andersonshatch [@andre-richter]: https://github.com/andre-richter [@andrewsayre]: https://github.com/andrewsayre [@apeeters]: https://github.com/apeeters [@arigilder]: https://github.com/arigilder [@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@cadavre]: https://github.com/cadavre [@cdce8p]: https://github.com/cdce8p [@cgarwood]: https://github.com/cgarwood [@cgtobi]: https://github.com/cgtobi [@cnrd]: https://github.com/cnrd [@ctso]: https://github.com/ctso [@cybe]: https://github.com/cybe [@danielperna84]: https://github.com/danielperna84 [@davet2001]: https://github.com/davet2001 [@dmulcahey]: https://github.com/dmulcahey [@dreed47]: https://github.com/dreed47 [@elupus]: https://github.com/elupus [@endor-force]: https://github.com/endor-force [@exxamalte]: https://github.com/exxamalte [@fabaff]: https://github.com/fabaff [@foreign-sub]: https://github.com/foreign-sub [@frenck]: https://github.com/frenck [@gadgetchnnel]: https://github.com/gadgetchnnel [@h3ndrik]: https://github.com/h3ndrik [@jesserizzo]: https://github.com/jesserizzo [@jkeljo]: https://github.com/jkeljo [@jlrgraham]: https://github.com/jlrgraham [@jmw6773]: https://github.com/jmw6773 [@johnluetke]: https://github.com/johnluetke [@kellerza]: https://github.com/kellerza [@kevank]: https://github.com/kevank [@kreegahbundolo]: https://github.com/kreegahbundolo [@ktnrg45]: https://github.com/ktnrg45 [@ludeeus]: https://github.com/ludeeus [@lufton]: https://github.com/lufton [@luukd]: https://github.com/luukd [@mezz64]: https://github.com/mezz64 [@monte-monte]: https://github.com/monte-monte [@mvn23]: https://github.com/mvn23 [@nielstron]: https://github.com/nielstron [@pnbruckner]: https://github.com/pnbruckner [@pvizeli]: https://github.com/pvizeli [@qypea]: https://github.com/qypea [@realthk]: https://github.com/realthk [@scop]: https://github.com/scop [@sfjes]: https://github.com/sfjes [@slackr31337]: https://github.com/slackr31337 [@squishykid]: https://github.com/squishykid [@teharris1]: https://github.com/teharris1 [@tsvi]: https://github.com/tsvi [@zewelor]: https://github.com/zewelor [@zombielinux]: https://github.com/zombielinux [@zxdavb]: https://github.com/zxdavb [alert docs]: /integrations/alert/ [alexa docs]: /integrations/alexa/ [ambiclimate docs]: /integrations/ambiclimate/ [ambient_station docs]: /integrations/ambient_station/ [androidtv docs]: /integrations/androidtv/ [arcam_fmj docs]: /integrations/arcam_fmj/ [aurora_abb_powerone docs]: /integrations/aurora_abb_powerone/ [自动化 docs]: /integrations/自动化/ [braviatv docs]: /integrations/braviatv/ [cert_expiry docs]: /integrations/cert_expiry/ [温控 docs]: /integrations/温控/ [cloud docs]: /integrations/cloud/ [config docs]: /integrations/config/ [coolmaster docs]: /integrations/coolmaster/ [cups docs]: /integrations/cups/ [deutsche_bahn docs]: /integrations/deutsche_bahn/ [device_tracker docs]: /integrations/device_tracker/ [discord docs]: /integrations/discord/ [dlna_dmr docs]: /integrations/dlna_dmr/ [downloader docs]: /integrations/downloader/ [ecobee docs]: /integrations/ecobee/ [enphase_envoy docs]: /integrations/enphase_envoy/ [evohome docs]: /integrations/evohome/ [fritzbox docs]: /integrations/fritzbox/ [前端 docs]: /integrations/frontend/ [geniushub docs]: /integrations/geniushub/ [geo_json_events docs]: /integrations/geo_json_events/ [geo_location docs]: /integrations/geo_location/ [glances docs]: /integrations/glances/ [google_assistant docs]: /integrations/google_assistant/ [google_cloud docs]: /integrations/google_cloud/ [hikvision docs]: /integrations/hikvision/ [hive docs]: /integrations/hive/ [homekit docs]: /integrations/homekit/ [homematic docs]: /integrations/homematic/ [homematicip_cloud docs]: /integrations/homematicip_cloud/ [honeywell docs]: /integrations/honeywell/ [input_datetime docs]: /integrations/input_datetime/ [insteon docs]: /integrations/insteon/ [iqvia docs]: /integrations/iqvia/ [jewish_calendar docs]: /integrations/jewish_calendar/ [knx docs]: /integrations/knx/ [lcn docs]: /integrations/lcn/ [life360 docs]: /integrations/life360/ [灯光 docs]: /integrations/灯光/ [logbook docs]: /integrations/logbook/ [luftdaten docs]: /integrations/luftdaten/ [media_extractor docs]: /integrations/media_extractor/ [MQTT docs]: /integra