零、前言
安卓端的 Home Assistant 官方 APP 定位成功率低,实时性几乎没有,耗电量还奇高,因此开发了这个工具。
经过近一年的迭代和测试,在配置合理的情况下:
- 从不误触“离开”事件
- 90% 的情况下能及时上报“进入”事件(然后就能在我开门后欢迎我捏🥰)
- 每天仅消耗 20-70mAh 的电量
这是我第一次开发安卓原生应用,也是第一次学习和使用 Kotlin,写的不好敬请谅解。
为了尽可能少地处理兼容性问题,本应用需要安卓 13 及以上的系统才能安装和运行。
如果遇到了问题请提交 Issue,我会尽可能地解决。
不同品牌的手机坑应该挺多的,但是我没有那么多手机。
一、下载
等级不够喵,附件限制 3 MB 以内,本应用有 5 MB。
Github 进不去的话——换个网络环境试试。
GitHub Release
二、保活
手机最难办的地方是保活和自启,你也可以在评论中分享你手机的设置方法。
我只有荣耀手机,不知道其它厂商的后台管理策略,如果你遇到了麻烦,可以上 B 站找找教程或者问问手机厂商的客服。
你可能需要进行的操作:
- 荣耀:耗电详情 -> 启动管理 -> 关闭自动管理 -> 允许自启动 -> 允许后台活动 -> 允许关联启动
此外,我发现授予通知管理权限对应用保活有奇效,你可以尝试在“设置”页中启用“移除高耗电通知”。
三、操作方法
添加用户
- 转到“用户”页,点击右下角“+”。
- 根据“创建用户向导”指示添加用户。
提示:
- 支持同时向多台 Home Assistant 服务器上报位置。
基础定位
必须启用基础定位,辅助功能才会生效。
- 转到“首页”,点击圆形按钮启用基础定位。
- 首次启用时,需要授予所需的所有基本权限。
任何情况下,本应用均遵守最小权限申请的原则。
网络状态触发器
本功能利用手机自动连接/断开 WiFi 的特性,在手机明显移动时触发定位。
如果你经常切换网络环境,这个功能可能会增加功耗(因为每切换一次都会触发定位)。
- 转到“设置”页,启用“网络状态触发器”。
- 首次启用时,需要授予所需的所有基本权限。
Wi-Fi 地理围栏
可有效降低意外的“离开”事件,并提升“进入”事件的触发速度(甚至快于你进门)。
本功能利用手机 WiFi 被动扫描结果,无额外电量消耗。
-
转到“设置”页,选择“地理围栏”。
-
在“地理围栏”页面中,点击“启用地理围栏”。
-
首次启用时,需要授予所需的所有基本权限。
-
点击右下角“+”,开始创建地理围栏。
提示:
网络偏好设置
你可以指定上报数据时使用的网络。
Home Assistant 默认使用 HTTP 协议。在连接公共 Wi-Fi 或代理等不可信网络时,通信内容可能被截获。
通过自定义网络偏好(如首选移动数据)来保护与 Home Assistant 的连接。
-
转到“设置”页,选择“网络偏好”。
-
在“网络偏好”页面中,点击“启用网络偏好设置”。
-
点击右下角“+”,开始创建网络偏好。
提示:
步数推送
国内厂商通常不会把当日步数同步到 Health Connect,导致 Home Assistant 无法获取当日步数。
我知道,这与位置上报无关——
但是本应用确实可以把手机步数传感器的数据推送到 Health Connect。
-
转到“设置”页,启用“步数推送”。
-
首次启用时,需要授予所需的所有基本权限。
提示:
- 如果开关为禁用状态,则说明你设备的 Health Connect 组件被厂商阉割,不支持推送数据。
四、实现逻辑
基础定位
本应用会按 1–15 分钟的动态间隔主动上报位置,间隔时间按以下逻辑计算:
-
信息不全(没有上次或当前位置信息):2 分钟
-
位置未变化
- 连续 1-5 次:10 分钟
- 连续超过 5 次:15 分钟
-
位置有变化(根据速度判断)
- 速度 < 0.5 m/s(静止或很慢):5 分钟
- 速度 0.5-8.33 m/s(步行/慢速,约 1.8-30 km/h):3 分钟
- 速度 8.33-13.89 m/s(中速,约 30-50 km/h):2 分钟
- 速度 >= 13.89 m/s(高速,约 50+ km/h):1 分钟
定位提供链路按“融合 → 网络 → GPS → 被动”依次回退:
- 单次请求 10 秒无结果即切换下一种定位方式,兼顾时效与能耗。
- 基础定位旨在提供实时定位兜底机制,适用于对实时性不高的场景。如需增强实时性,请按需启用下文所述的各项辅助功能。
- 手机定位并非 100% 准确,当出现定位偏移时,极有可能误触自动化。建议合理配置“地理围栏”,以减少自动化误触。
获取定位坐标后,根据以下逻辑判定所在区域:
方法一:计算每个区域的匹配分数
-
对于每个区域,分别计算两种比率,得出最终分数。
- 高斯比率(Gaussian Ratio):表示定位点的概率分布有多少落在该区域内
- 均匀比率(Uniform Ratio):表示区域有多少面积与定位点重叠
- 最终分数:取两个比率的最大值,限制在 0.0-1.0 之间
-
优先选择分数最高的区域。
-
如果分数相同,执行方法二。
方法二:选择更深入内部的区域
例外情况:
- 当定位精度 > 200 米,且试图进入某区域时,阻止区域变更。
- 当前处于“地理围栏”的“离开保护”范围内,可能阻止区域变更。
网络状态触发器
当网络从固定 Wi-Fi(非按流量计费)切到其它网络,或从其它网络切回固定 Wi-Fi 时,会额外触发一次定位:
- 切入固定 Wi-Fi:延迟 1 秒触发;
- 切出固定 Wi-Fi:延迟 1 分钟触发(避免“刚出门”定位仍贴近接入点导致无效触发)。
提示:
- 切换网络状态时触发上报可能出现网络错误,配置首选“网络偏好”为“移动数据”或许会有所改善。
Wi-Fi 地理围栏
以 Wi-Fi 设备作为围栏参照,提供两项功能:
- 离开保护
若定位坐标判定“离开”了区域,但手机仍能扫描到围栏内指定的 Wi-Fi,则判定为定位漂移,不改变 device_tracker 的区域状态(仍会上报坐标)。
- 快速进入
手机扫描到附近 Wi-Fi 的时间往往早于定位。当扫描到围栏内 Wi-Fi 时,直接用区域中心坐标作为设备坐标上报。
五、许可协议
以 AGPL-3.0 开源发布。