之前把Home Assistant调试环境给弄好了,有点膨胀就把先前aihome插件的智能音箱网关代码进行全部重构2次。好吧,其实只是想实现不用重启可以更新设备信息就行了,中途又有点想法就就停不下来了,真的是费脑费力。不过成果还是满意的,引入一个设备信息管理层以实现配置信息的标准化,同时将基础的业务流程代码独立出来,初步实现可以通过配置的方式来扩展对音箱指令的解析支持,也算是搭建了一个粗略的框架整合接入了三个音箱平台。
0.插件说明
新插件更名为HAVSC(Home Assistant Voice Control Skill),同步更改音箱平台技能名称(不影响旧版aihome插件使用),启用新版本需要重新配置设备信息,新版本特点如下:
- 独立配置文件,支持重载文件而无需重启HA
- 大幅度简化配置
- 增加指令扩展性
1.使用说明
1.1.APP的技能方式接入
使用官方APP技能,配合havcs服务可实现免公网IP接入。
- 下载havcs插件,放置到HA自定义插件目录,最终路径结构为
{HA配置目录}/custom_components/havcs/__init__.py
。 - 前往页面注册账号,获取AppKey和AppSecret(先登录再生成,生成后记得保存)。
- 音箱APP->搜索’havcs’技能->关联账号->输入注册的账号信息登录。
- 配置Home Assistant
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# {HA配置目录}/configuration.yaml
havcs:
platform: # 音箱平台服务网关,至少启用一个
- aligenie # 天猫精灵
- dueros # 小度
- jdwhale # 叮咚
skill:
bind_device: True # 是否启动时更新设备绑定信息。不设置默认True(叮咚音箱才有效)>>*新版本加入<<
sync_device: False # 是否主动上报设备状态。不设置默认False(小度音箱才有效)
# mqtt相关设置,启用http代理服务及APP技能服务才生效
setting:
app_key: your_app_key # 注册账号获取的AppKey
app_secret: your_app_secret # 注册账号获取的AppSecret
entity_key: your_entity_key # 加密entity_id的key,自定义16个字符
device_config: device_yaml_full_path # 设备配置文件路径(完整路径)。不设置默认{HA配置目录}/havcs.yaml >>*新版本加入<< - 配置设备信息(详见第2章节)
1
2
3
4
5
6
7# 配置文件整体结构(默认文件路径:{HA配置目录}/havcs.yaml)
设备1的entity_id:
属性1:
属性2:
设备2的entity_id:
属性1:
属性2:1
2
3
4# 单设备样例
light.demo:
havcs_device_name: 主卧灯
havcs_zone: 主卧 - 更新音箱平台设备信息
- 先重载本地信息:调用服务(HA web->开发者工具->服务->调用havcs.reload)或者重启HA
- 叮咚:重载本地信息会触发上报(bind_device配置为True)。
- 天猫精灵:在APP中重新绑定触发更新。
- 小度:执行“发现设备”指令触发更新。
1.2.自建技能方式接入
- 音箱技能配置略
- 配置Home Assistant
1
2
3
4
5
6
7
8
9
10# {HA配置目录}/configuration.yaml
havcs:
platform: # 音箱平台服务网关,至少启用一个
- aligenie # 天猫精灵
- dueros # 小度
- jdwhale # 叮咚
http:
ha_url: https://localhost:8123 # HA所在主机/容器IP地址,不设置则默认识别
expire_in_hours: 24 # token超时时间,单位小时,不设置则默认24h
device_config: device_yaml_full_path # 指定设备配置文件位置(填完整路径),不设置默认位于{HA配置目录}/havcs.yaml >>*新版本加入属性<< - 配置设备信息及更新音箱平台设备信息同上章节
- 新版注意事项及实践建议
- uri调整:
/aihome_auth
->/havcs_auth
;/aihome_service
->/havcs_service
。 - 相关服务地址使用https及443端口(建议使用nginx或apache反向代理,本地可以保留http访问),https证书使用腾讯云、阿里云或者Let’s Encrypt等兼容性好的,并注意有效期。
- 先确认本地uri可访问(插件正常启动),再测试确认服务地址的可访问(手机直接访问网址,405代表网络通)。
- uri调整:
2.设备信息属性说明
在{HA配置目录}/havcs.yaml(或自定义文件)配置设备信息,用于生成音箱平台的设备(绑定设备)。
- 设备统一使用属性进行配置,属性列表如下:
属性名 | 描述 | 取值 | 样例 | 备注 |
---|---|---|---|---|
havcs_visable | 设备可见性 | [‘aligenie’, ‘dueros’, ‘jdwhale’] | [‘aligenie’, ‘dueros’] | 设置该属性则设备只对指定平台可见;如不设置,对所有平台可见 |
havcs_device_name | 设备名称 | *天猫精灵限制 | 客厅灯 | 必填,建议“房间”+“设备类型”可以兼容三个平台使用 |
havcs_zone | 设备位置 | *天猫精灵限制 | 客厅 | 天猫精灵必填,其它可不用指定 |
havcs_device_type | 设备类型 | light /switch /sensor /input_boolean | light | 一般不用指定 |
havcs_attributes | 属性 | [‘temperature’, ‘brightness’, ‘humidity’, ‘pm25’, ‘co2’, ‘power_state’] | [‘power_state’] | 一般不用指定 |
havcs_actions | 支持操作 | [‘turn_on’, ‘turn_off’, ‘timing_turn_on’, ‘timing_turn_off’, ‘query_temperature’, ‘query_humidity’, ‘increase_brightness’, ‘decrease_brightness’] | [‘turn_on’, ‘turn_off’] | 一般不用指定 |
havcs_related_sensors | 传感器设备专用,关联真实传感器 | sensor/group列表 | [‘sensor.demo’, ‘group.demo’] | 支持设置group,会搜索加入该分组下的sensor |
格式
属性字典的格式为"属性名: 取值",需要有1个空格间隔。
2.1 特殊设备配置说明
对input_boolean类型的配置方式进行了扩展,实现指定指令调用自定义的service。
- 新增一个input_boolean实体
1
2
3#{HA配置目录}/configuration.yaml
input_boolean:
call_service: - 自定义虚拟input_boolean的属性,在havcs_actions属性中设置对应的service指令(只能设置turn_on/turn_off/timing_turn_on/timing_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#{HA配置目录}/havcs.yaml
input_boolean.call_service:
havcs_device_name: 客厅灯
havcs_zone: 客厅
havcs_device_type: light # 模拟灯设备
havcs_attributes: ['power_state']
#↓↓↓指令根据实际需要配置↓↓↓
havcs_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', '{}'] # 同步关闭状态
timing_turn_on: # 延时打开指令(小度音箱)
- ['指令1']
- ['指令2']
timing_turn_off: # 延时关闭指令(小度音箱)
- ['指令1']
- ['指令2']
increase_brightness:
- ['指令1']
- ['指令2']
decrease_brightness:
- ['指令1']
- ['指令2']
使用建议
调自动化(automation.turn_on)、调脚本(scrpit.turn_on)、调红外指令(climate.xiaomi_miio_send_command)等会比较适合。
天猫精灵无法自定义名称,不太适合使用。
3.完成度
目前完成度有些低,后续再继续测试完善吧。
- 图例:✓ 支持,- 不支持,* 待测试
- switch/cover
操作 | 描述 | aligenie | dueros | jdwhale |
---|---|---|---|---|
turn_on | 打开 | ✓ | ✓ | ✓ |
turn_off | 关闭 | ✓ | ✓ | ✓ |
timing_turn_on | 延时打开 | - | ✓ | - |
timing_turn_off | 延时关闭 | - | ✓ | - |
- light
操作 | 描述 | aligenie | dueros | jdwhale |
---|---|---|---|---|
turn_on | 打开 | ✓ | ✓ | ✓ |
turn_off | 关闭 | ✓ | ✓ | ✓ |
timing_turn_on | 延时打开 | - | ✓ | - |
timing_turn_off | 延时关闭 | - | ✓ | - |
set_brightness | 设置亮度 | * | * | * |
increase_brightness | 调高亮度 | ✓ | ✓ | ✓ |
decrease_brightness | 调低亮度 | ✓ | ✓ | ✓ |
set_color | 设置颜色 | * | ✓ | * |
- sensor
操作 | 描述 | aligenie | dueros | jdwhale |
---|---|---|---|---|
query_temperature | 查询温度 | ✓ | ✓ | ✓ |
query_humidity | 查询湿度 | ✓ | ✓ | ✓ |
- inpu_boolean
操作 | 描述 | aligenie | dueros | jdwhale |
---|---|---|---|---|
turn_on | 打开 | ✓ | ✓ | ✓ |
turn_off | 关闭 | ✓ | ✓ | ✓ |
timing_turn_on | 延时打开 | - | ✓ | - |
timing_turn_off | 延时关闭 | - | ✓ | - |
increase_brightness | 调高亮度 | ✓ | ✓ | ✓ |
decrease_brightness | 调低亮度 | ✓ | ✓ | ✓ |
4.控制指令说明
- 叮咚
- 打开/关闭
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状态}/{设备名称}查询{xx状态}
#例子:查询主卧传感器的温度/主卧传感器查询温度补充
只能查询单一状态。
- 打开/关闭
4.停用插件
插件初始化代码是抄官方组件的,启用后会默认继续加载,删除core.config_entries文件相关的内容即可。新版已解决。
1 | #{HA配置目录}/.storage/core.config_entries |
5.调试说明
- 把havcs插件日志级别提高,过滤其它插件输出日志,方便观察日志输出,调试后注意恢复
1
2
3
4
5# [HA配置目录]/configuration.yaml
logger:
default: error # 提高所有组件的默认级别,调试完后改回info(预设)
logs: # 设定指定组件的级别,debug有更详细的输出
custom_components.havcs: debug
- 根据教程调整插件的调试级别查看详细的运行日志
- 配置好插件,启动HA,观看是否有mqtt连接成功信息(app技能接入方式)
- 授权过程,观看是否有相关的处理日志
- 说音响指令后,观看是否有相关的处理日志
- web页面->开发者工具->服务->havcs.reload,观看是否生成设备信息
调试建议
如需要帮助,请提供以上步骤相对应的日志信息方便定位原因。
6.小结
- 有了统一的设备信息定义,后续可以考虑做设备管理页面。