本帖最后由 chiunownow 于 2019-9-7 07:19 编辑
Tasker - 米家智能门锁(伪)接入 Hass
成果图:
需求与思路
- 米家 APP 中创建智能通知,为各类开关门操作推送通知。(似乎需要小米蓝牙网关)
- 用 Tasker 捕获米家 APP 通知,判断通知内容,向 Hass 上报操作和文本。
- 需要一台 Android 手机,闲置最佳。建议 Tasker 与 米家 APP 均不优化电池,保证操作及时上报与通知捕获顺利运行。
碎碎念
米家门锁真是要多傻有多傻。
- 大概是为了省电,使用的是 BLE 接入,联网需要蓝牙网关(我买的是小米闹钟)。但是他的 APP 获取门锁状态的逻辑十分弱智,先蓝牙寻找设备,找半天找不到再联网通过网关获取设备状态和日志。不在家要看门锁状态,最好是先手动关闭手机蓝牙。
- 米家 APP 里绝大多数设备都可以分享给其他用户,目前只碰到这个门锁是不能共享的。比如我的家人出门了想看看门有没有忘记上锁,用自己的小米账号登录是无法查看的,只能用我的账号
- 小米的其他 BLE 设备似乎都已经可以蓝牙直接接入 Hass(花花草草,温湿度计之类的),但门锁目前还没有正常的接入方法
- 这种伪接入方法相当不靠谱。如果 Tasker 被杀进程了,米家 APP 突然收不到推送了,或者装 Tasker 的手机碰上没电没网死机之类的偶发状况,都会导致接入失效。但目前似乎也只能这样了。
- 下面会提到的 Tasker
%evtprm 数组真是个好东西,我顺便用了这个方法,把短信验证码上报到 Hass 方便电脑复制粘贴使用。
步骤
1. Tasker 接入 Hass API(长效令牌方法)
方法来自 Hass 官方论坛的bokub,原帖内容(英文)见此处。下面简要介绍一下接入方法。请参考原帖食用
-
在 Hass 中创建长效令牌
-
在 Tasker 中定义变量
%HA_ADDR 即 Hass URL。(建议用闲置 Android 手机,使用非 SSL 的方法接入。Tasker 要求 SSL 的两个证书文件均正确配置,不是 Chrome 访问时显示小绿锁就足够,我以前在这里栽过坑,所以多说两句)
%HA_AUTH 即 Hass 长效令牌
-
在 Tasker 中新建一个任务,名称 Call Hass。
-
在任务 Call Hass 中新建一个 JavaScriptlet 动作,在 Code 中填入以下脚本
const url = global('%HA_ADDR') + local('par1');
const token= 'Bearer ' + global('%HA_AUTH');
const xhttp = new XMLHttpRequest();
xhttp.open('POST', url, false);
xhttp.setRequestHeader('Authorization', token);
xhttp.send(local('par2'));
if( xhttp.status != 200 ) {
console.error(xhttp.status + ' - ' + xhttp.responseText);
}
-
保存此任务。之后需要调用 Hass API 的任务,只需要在任务中,增加 执行任务 这个动作,在 参数1 中填写需要调用的 API URL,在 参数2 中填写执行内容的 JSON 代码(不是 YAML,而且需去掉换行符)。例如
# 参数1(%par1)
/api/services/light/turn_on
# 参数2(%par2)
{"entity_id":"light.taideng"}
备注:此处仅实现 HTTP POST 方式的接入。HTTP GET 请参考原帖另行配置。此案例不需要故不赘述。
2. Hass 组件准备
# /config/packages/xiaomi_lock.yaml
input_text:
mijia_notify: #(非必要)文本输入组件,用于接收 Tasker 上报的所有米家 APP 推送文本。
name: 米家通知
input_boolean:
door_lock: #布尔值输入组件,Tasker 通过判断米家 APP 推送的文本内容,判断开锁或关锁操作,上报至此。
#不建议将此组件放在前端,避免人为误操作,导致状态显示错误。
sensor:
- platform: template #两个自定义模板传感器,用于显示门锁状态和米家 APP 推送文本
sensors:
door_lock: #显示门锁状态,也可做为自动化的 Trigger。
friendly_name: "门锁"
value_template: >- #判断布尔值输入组件的开关状态,显示上锁或未锁
{% if is_state('input_boolean.door_lock', 'off') %}
上锁
{% else %}
未锁
{% endif %}
icon_template: >- #判断布尔值输入组件的开关状态,显示不同的图标
{% if is_state('input_boolean.door_lock', 'off') %}
mdi:door-closed-lock
{% else %}
mdi:door-open
{% endif %}
mijia_notify: #同步文本输入组件内容。文本输入组件无历史记录,通过此方法得以保存历史记录
friendly_name: "米家通知"
value_template: "{{states('input_text.mijia_notify')}}"
icon_template: mdi:message-text-outline
3. 门锁(伪)接入
实现方式参考自 Tasker免插件提取Android通知正文 。感谢作者 Mike Yin。
简单说一下关键的隐藏招式,数组 %evtprm ,当任务是由 通知 这一事件触发时,通知的参数会被传递到这一数组,%evtprm1 是推送通知的应用标题,%evtprm2 是通知标题,%evtprm3 是通知内容。
由于米家 APP 的智能通知,有效信息都在通知标题中,所以以下均只使用 %evtprm2 这一变量
-
在米家 APP 中创建智能通知
-
创建 配置文件(我简单地理解为类似 Hass 里 automation 的 trigger),名称自定,点 √ 确认名称后,依次点选 事件 - 界面 - 通知
-
在配置文件的编辑界面,点击 所有者程序 右侧的四个小方块,选择米家 APP,然后点击两次左上角 ← 箭头返回首页。
-
为此配置文件创建新任务,名称自定。
图片说明:当米家 APP 收到推送时,执行对应任务
-
编辑任务,添加上报开关门锁对应的上报动作,与文本上报对应动作
以上动作 1~6 是判断通知内容上报门锁开关操作;7是上报完整通知文本
-
开关门锁
-
例子
-
逻辑
如果通知的标题(即 %evtprm2 )包含“任意指纹开门”,则执行 打开开关 的动作
其他几项同理。建议调整判断的正则表达式,免得像我一样,增加一堆动作。
-
上报文本
-
例子
-
逻辑
没啥逻辑可言,将 %evtprm2 的内容上报到文本输入框中。
其他
- 建议加上特殊情况上报(如破坏门锁,撬锁,电池电量低等)
- 现在可以用门锁作为自动化的 trigger 了,比如有人开门时,将大方摄像头朝向门口并拍摄视频
|