前情回顾:年前折腾的通用智能音箱接入平台因音箱技能类型限制不过审翻车了,然后将项目成果整理做了个智能音箱mqtt代理转发插件。考虑到易用性,趁着过年闲着,于是折腾了下各个平台的智能家居类型技能对接,最终成果就是这么一个整合版插件了。
0.更新
新版本插件已发布并更名为havcs(传送门),主要变更了设备配置方式,其它部分内容基本仍适用,建议先粗略观看完此版本内容再移步观看新版本。
1.插件说明
本插件实际上由两大功能模块组成:
MQTT对接服务
配合本人搭建的mqtt中转服务,可以将音箱云平台的音箱命令消息、oauth消息转发到无公网环境下家中的Home Assistant。
音箱组件
即智能音箱本地网关插件,对音箱云平台的音箱命令消息进行解析、处理,可以初始化为HTTP网关服务与音箱云平台直接对接。
有三种使用模式,适合不同场景的接入:
模式一 http模式
- 生成音箱http网关,通过
自建测试技能
接入 - 适合
家庭宽带有公网ip或已实现内网穿透
场景下使用 - 建议有条件都用这个,留服务资源给有需要的人
- 生成音箱http网关,通过
模式二 http proxy模式
- 生成音箱http网关,同时使用mqtt代理穿透内网访问,通过
自建测试技能
接入 - 适合
家庭宽带无公网ip
场景下使用 - 临时提供,视服务资源情况会停止
- 生成音箱http网关,同时使用mqtt代理穿透内网访问,通过
模式三 skill模式
- 通过
官方音箱APP技能
接入,目前技能已暂未上线(也许没法上线) - 适合
无公网
、省事
场景使用 - 服务资源有限不能保证稳定
- 通过
各模式难度指数
模式一:★★★★☆
模式二:★★☆☆☆
模式三:★☆☆☆☆
配置方法
不同模式的配置方法见3.3HA插件配置章节。
智能音箱组件说明
aihomeHAVCS线上服务劝退警告
aihomeHAVCS线上服务(指模式二、三的mqtt中转服务及APP技能)可以实现叮咚音箱、天猫精灵、小度音箱接入Home Assistant(免公网IP),语音控制家中设备。线上服务主要目的在于测试、学习、交流,受限于个人能力,无法保证提供完善服务,并且使用线上服务有一定的风险,介意者建议另行部署自用的环境对接智能音箱平台。- 隐私安全
- 为解决无公网IP的家庭宽带环境下使用的痛点,线上服务采用mqtt中转的技术方案,该方案下控制消息需经个人服务器转发,存在被本人监控、冒充控制消息的风险。
- mqtt中转模式下已采用了消息隔离、消息加密、设备entity_id加密等方式对用户的控制消息进行安全保障,但仍可能存在本人没考虑全面的安全风险。
- 服务质量
- 只能尽个人最大能力保证,毕竟存在不可抗力自然因素、断电、断网、服务器宕机、本人偷懒等诸多不可控风险。
- 如果不幸本人跑路,因为相关设备信息(设备个性化配置)只保留在本地,你仍可以自行部署自用环境对接智能音箱平台继续使用。
- 服务支持
- 本服务实质上只提供便捷接入途径,后续仍要对设备信息进行个性化配置,需要对各家音箱平台的控制指令有一定了解。
- 使用本服务上手有一定难度,建议心平气和慢慢熟悉,遇到问题可加QQ群寻求帮助。
- 因个人时间有限,只侧重支撑解决使用mqtt中转服务和使用插件遇到的问题;部署自用环境对接方面问题请自行查阅厂家技能开放平台文档。
2.完成度
控制指令
- 灯、开关类型设备的开/关(小度音箱可延时)
- 电源状态、温度、湿度等状态查询
支持指令
能用的控制指令实际上与各智能音箱组件对音箱平台预设功能指令的支持度有关,因各个音箱平台有差异,无法一一描述,只能先列举叮咚音箱组件下目前个人已测试的功能。
平台适配进展
- 天猫精灵:支持,音箱APP已上线技能(“
aihome智能HAVCS”) - 小度:支持,音箱APP已上线技能(“
aihomeHAVCS”) - 叮咚:支持,音箱APP已上线技能(“
aihomeHAVCS”) - echo:看情况(等支持中文。。。)
- 小爱:计划外(手持身份证验证+商用要求劝退)
- 有其它音箱接入需求可以反馈我研究下
高能提醒
- 设备配置各个音箱平台会有一些出入,需要一定耐心熟悉上手
- 多用户使用场景没有条件测试,估计有不少bug
- 多用户并发下服务器处理性能及带宽可能有瓶颈问题
3.使用说明
3.0.准备
- 下载插件:aihome(新版本插件名称已更名为havcs,旧版本在github项目release页面下载)
- 确认采取哪种模式接入
3.1.获取账号
注:模式一跳过此步骤
打开账号获取页面,获取AppKey和AppSecret
注册
模式三需要注册用户登陆;模式二可以不登陆(暂时)。
3.2.音箱技能平台配置
注:模式三跳过此步骤
启用模式一或模式二,会生成服务网关(不分音箱平台),访问uri为/aihome_service
。
- 模式一
1
2
3
4
5
6
7
8
9
10
11#前往厂家的音箱技能平台进行设置
#授权地址
https://{你的域名}/auth/authorize
#Client_Id,回调地址域名那一串即可
小度:https://xiaodu.baidu.com
天猫:https://open.bot.tmall.com
#Token地址
https://{你的域名}/aihome_auth
#WebService(服务网关)地址
https://{你的域名}/aihome_service注意
需要自己解决域名访问问题,建议观看天猫精灵、小度音箱原版插件的教程。
- 模式二
1
2
3
4
5
6
7
8
9
10
11#前往厂家的音箱技能平台进行设置
#授权地址(授权操作只能使用本地电脑)
https://{本地HA访问地址}/auth/authorize
#Client_Id,回调地址域名那一串即可
小度:https://xiaodu.baidu.com
天猫:https://open.bot.tmall.com
#Token地址(代理地址)
https://ai-home.ljr.im/h2m2h/{app_key}/aihome_auth
#WebService(服务网关)地址(代理地址)
https://ai-home.ljr.im/h2m2h/{app_key}/aihome_service注意
{本地HA访问地址}、{app_key}替换成相应的字符串。
目前叮咚技能需要联系工作人员审核后才能绑定到指定音箱,另外client_id格式不能填写"https://"(HA的oauth格式要求),需要自行修改HA对应组件代码解决。
3.3.HA插件配置
1 | #{HA配置目录}/configuration.yaml |
3.4.HA设备个性化配置(绑定设备)
音箱云平台的设备与HA的设备属性字段有出入,HA中需要使用个性化配置文件(customize.yaml)补充额外的属性,使得音箱云平台可以识别、绑定设备。虽然音箱插件会尝试根据设备类型、设备名称进行自动补充,但目前准确率仍不高,建议还是尽量手动指定。
3.4.1.整体配置框架
以接入一个灯类设备、传感器类设备为例,会涉及几个大块配置。
方法1 分散文件配置方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#{HA配置目录}/customize.yaml,>设备个性化配置<
light.demo: # 接入音箱平台的灯(一般设备配置属性即可)
属性1:
属性2:
sensor.livingroom: # 接入音箱平台的传感器(虚拟创建的)
属性1:
属性2:
sensor.temperature: # 虚拟传感器关联的真实传感器设备(作为一种参数查询,如温度)
属性1:
sensor.humidity: # 虚拟传感器关联的真实传感器设备(作为一种参数查询,如湿度)
属性1:
#{HA配置目录}/configuration.yaml,虚拟传感器
sensor:
- platform: template
sensors:
livingroom: # 新增虚拟传感器设备,该设备在音箱云平台展示
value_template: "客厅环境"
#{HA配置目录}/group.yaml,虚拟传感器关联的传感器类分组
livingroom_sensors:
view: no
name: '客厅传感器列表'
control: hidden
entities: # 真实传感器列表,真实传感器配置过程省略
- sensor.temperature
- sensor.humidity方法2 统一文件配置方式(建议)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30#编辑{HA配置目录}/configuration.yaml,引入packages目录
homeassistant:
packages: !include_dir_named packages
#编辑{HA配置目录}/packages/自定义名称.yaml, 增加设备个性化配置、新增虚拟传感器、传感器分组等信息
homeassistant:
customize: # >设备个性化配置<
light.demo: # 接入音箱平台的灯(一般设备配置属性即可)
属性1:
属性2:
sensor.livingroom: # 接入音箱平台的传感器(虚拟创建的)
属性1:
属性2:
sensor.temperature: # 虚拟传感器关联的真实传感器设备(作为一种参数查询,如温度)
属性1:
sensor.humidity: # 虚拟传感器关联的真实传感器设备(作为一种参数查询,如湿度)
属性1:
group: # 虚拟传感器关联的传感器类分组
livingroom_sensors:
view: no
name: '客厅传感器列表'
control: hidden
entities: # 真实传感器列表,真实传感器配置过程省略
- sensor.temperature
- sensor.humidity
sensor: # 虚拟传感器
- platform: template
sensors:
livingroom: # 新增虚拟传感器设备,该设备在音箱云平台展示
value_template: "客厅环境"3.4.2.设备个性化配置属性
使用官方自带的customize组件({HA配置目录}/customize.yaml中配置)为HA的设备增加相关属性,音箱插件根据属性信息生成音箱平台可识别的设备。在3.4.1章节
>设备个性化配置<
部分,可以为指定的HA设备(entity_id)增加相关的属性。通用
1
2# 指定的设备可被发现,上报设备数据
aihome_device: True传感器专用
1
2
3
4# 虚拟传感器,关联真实传感器分组,详细用法见传感器类设备配置说明
aihome_sensor_group: group.livingroom_sensors
# 真实传感器标识,对传感器分组特定的传感器进行上报,详细用法见传感器类设备配置说明
aihome_sensor: True # 不需要再设置aihome_device叮咚音箱
1
2
3
4# 设备类型,不设置则尝试自动生成
jdwhale_deviceType: 'LIGHT'
# 设备支持操作,不设置则尝试自动生成
jdwhale_actions: ['TurnOn', 'TurnOff', 'Query']天猫精灵
1
2
3
4
5
6
7
8# 设备别名(设备类型限定设备别名可取值)
aligenie_deviceName: 灯
# 设备位置,不设置则尝试自动生成
aligenie_zone: 主卧
# 设备类型,不设置则尝试自动生成
aligenie_deviceType: 'light'
# 设备支持操作,不设置则尝试自动生成
aligenie_actions: ["TurnOn", "TurnOff"]小度音箱
1
2
3
4# 设备类型,不设置则尝试自动生成
dueros_deviceType: 'LIGHT'
# 设备支持操作,不设置则尝试自动生成
dueros_actions: ['turnOn', 'turnOff']
补充
音箱的设备类型、支持的操作建议去官网看相应智能家居技能文档,无法一一详述。
3.4.3.特殊设备配置说明
传感器类设备配置
HA中,一个传感器设备只有一种数据,而音箱云平台可以对设备查询多种属性,因此需要虚拟一个新的传感器设备整合多个真实传感器数据。
- 环境类传感器先集中到一个分组
1
2
3
4
5
6
7
8#{HA配置目录}/group.yaml,虚拟传感器关联的传感器类分组
livingroom_sensors:
view: no
name: '客厅传感器列表'
control: hidden
entities: # 真实传感器列表
- sensor.temperature
- sensor.humidity - 新增一个虚拟的sensor(使用官方sensor组件template生成即可)
1
2
3
4
5
6#{HA配置目录}/configuration.yaml,虚拟传感器
sensor:
- platform: template
sensors:
livingroom: # 新增虚拟传感器设备,该设备在音箱云平台展示
value_template: "客厅环境" - 自定义虚拟sensor的属性,关联传感器分组
1
2
3
4
5
6
7
8
9
10
11
12
13#{HA配置目录}/customize.yaml,设备个性化配置
sensor.livingroom:
aihome_device: True # 上报设备
friendly_name: 客厅传感器
aihome_sensor_group: group.livingroom_sensors # 关联真实传感器分组
jdwhale_actions: ['Query', 'QueryTemperature', 'QueryHumidity'] # 叮咚平台设置,需根据真实传感器及音箱平台支持的类型设置
# 真实传感器设置aihome_sensor属性
sensor.temperature:
aihome_sensor: True # 上报传感器数据,注意不参与直接上报,不需要再设置aihome_device
sensor.humidity:
aihome_sensor: True # 上报传感器数据,注意不参与直接上报,不需要再设置aihome_device使用建议
虚拟sensor的名称命名为“{房间名}传感器”,各个平台的识别执行成功率比较高。
- 环境类传感器先集中到一个分组
传感器功能
原天猫精灵插件根据zone组合传感器,原小度插件没有实现相应查询功能,于是对查询方法进行了统一。
直接调service类设备配置说明
可以手动指定调用服务命令,效果和新建简单脚本再调用类似。
- 新增一个input_boolean
1
2
3#{HA配置目录}/configuration.yaml
input_boolean:
call_service: - 自定义虚拟input_boolean的属性,在aihome_actions属性中设置对应的service指令(只能设置turn_on/turn_off/increase_brightness/decrease_brightness,对应打开/关闭/调高亮度/调低亮度指令)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36#{HA配置目录}/customize.yaml
input_boolean.call_service:
friendly_name: 定时充电
#↓↓↓该部分根据使用的音箱精简↓↓↓
aihome_device: True
aligenie_deviceName: 开关
aligenie_zone: 主卧
aligenie_deviceType: switch
# aligenie_actions: ["TurnOn", "TurnOff"] # 新版本已可根据aihome_actions自动识别
dueros_deviceType: 'SWITCH'
# dueros_actions: ['turnOn', 'turnOff'] # 新版本已可根据aihome_actions自动识别
jdwhale_deviceType: 'SWITCH'
# jdwhale_actions: ['TurnOn', 'TurnOff'] # 新版本已可根据aihome_actions自动识别
#↑↑↑该部分根据使用的音箱精简↑↑↑
#↓↓↓指令根据实际需要配置↓↓↓
aihome_actions:
# service指令格式:[domain, service_name, service_data(json字符串)],具体内容需参见相应组件的服务定义。
# 注意,参数变更为数组以支持多条指令,单条指令也别忘了加-
turn_on:
- ['common_timer', 'set', '{"entity_id":"switch.demo","duration":"01:00:00","operation":"off"}'] # 打开命令
- ['input_boolean', 'turn_on', '{}'] # 同步打开状态
turn_off:
- ['common_timer', 'cancel', '{"entity_id":"switch.demo"}'] # 关闭命令
- ['input_boolean', 'turn_off', '{}'] # 同步关闭状态
increase_brightness:
- ['指令1']
- ['指令2']
decrease_brightness:
- ['指令1']
- ['指令2']
timing_turn_on: # 延时打开指令(小度音箱)
- ['指令1']
- ['指令2']
timing_turn_off: # 延时关闭指令(小度音箱)
- ['指令1']
- ['指令2']使用建议
调自动化(automation.turn_on)、调脚本(scrpit.turn_on)、调红外指令(climate.xiaomi_miio_send_command)等会比较适合。
天猫精灵无法自定义名称,不太适合使用。
- 新增一个input_boolean
3.4.4.配置样例
采用统一文件配置方式,引入packages目录及即可测试,引入方法见3.4.1。
1 | #{HA配置目录}/packages/aihome_template.yaml |
3.5.上报设备
当HA中设备信息配置完毕后,需要上报信息给音箱平台。
- 叮咚
重启HA触发上报。 - 天猫精灵
在APP中重新绑定触发上报。 - 小度
执行“发现设备”指令触发上报。
3.6.控制指令说明
- 叮咚
- 打开/关闭
1
2
3
4#打开/关闭
#用途:一般为电源控制
#语义:打开/关闭{设备名称}
#例子:打开主卧灯 - 查询状态
1
2
3
4#打开/关闭
#用途:查询设备状态
#语义:查询{设备名称}的{状态/xx状态}
#例子:查询主卧传感器的状态;查询主卧传感器的温度;查询主卧灯的电源状态使用建议
传感器信息需要挂靠到具体设备上进行查询。一般来说温度、湿度需要挂靠到空气净化器类型上。
- 打开/关闭
- 天猫精灵
- 打开/关闭
1
2
3
4
5#打开/关闭
#用途:一般为电源控制
#语义:打开/关闭{房间名}的{设备类型/别名}
#例子:打开主卧的灯。
#备注:{房间名}、{设备类型/别名}需要指定,均为枚举值使用建议
优先匹配“位置(可为空)+别名”:例如有台灯、灯两个设备,“打开台灯”则精确匹配台灯;然后匹配“位置(可为空)+设备类型”,例如有一个台灯设备,“打开吸顶灯”、“打开床头灯”等都可控制。指令不带位置,如设备别名多个匹配,询问设备位置;当有相同匹配,一起执行。
- 查询状态
1
2
3
4#打开/关闭
#用途:查询设备状态
#语义:查询{房间名}{设备类型/别名}的{状态/xx状态}
#例子:查询主卧传感器的状态;查询主卧传感器的温度使用建议
查询传感器好像有个bug:查询所有状态不能正常播报;查询单个状态,发送的指令是查询所有状态的指令。
- 打开/关闭
- 小度
- 打开/关闭
1
2
3
4
5
6
7
8
9
10
11#打开/关闭
#用途:一般为电源控制
#语义:打开/关闭{设备名称}
#例子:打开主卧灯
```
- 查询状态
```yaml
#打开/关闭
#用途:查询设备状态
#语义:查询{设备名称}的{xx状态}
#例子:查询主卧传感器的温度补充
只能查询单一状态。
- 打开/关闭
4.小结
- 重新对各音箱平台智能家居指令进行分析,目前智能音箱插件功能实现度还有比较大的改进空间,但不同音箱如何统一整合还要好好考虑。
- 对原有多用户场景下mqtt消息发送、处理方式进行了重构。