修改日志
2019-06-04 初稿。
2019-08-23 增加1种更方便的方法来解决客户端ID不能填写https://的问题。PS:感谢19楼fengit大佬分享的方法。
前言
前面折腾好了天猫精灵和小度后,继续折腾叮咚mini2音箱。
前置条件
1.要有公网IP和域名。
2.小京鱼·Skill开放平台的开发者账号(自己去申请)。
申请完开发者账号后,还需要写邮件给官方人员来开启真机调试。
需要2样东西:1.你的叮咚mini2音箱产品序列号SN,app里可以查看到的。2.你的京东用户名。
把音箱序列号SN和京东用户名,发到 mailto:[email protected] 官方客服邮箱。
我是等了大概7天才回复通过,然后客服人员会让你加QQ,给你发1个沙箱版的叮咚音箱APP(里面可以添加查看测试技能),其实没什么用,不用APP也可以,直接在平台的测试技能网页上可以输入命令来操作。
叮咚音箱:aihome作者说由于小京鱼平台在配置服务端点的客户端ID不能填写https://这几个字符,需要修改HA的核心组件 所以就我放弃了。
经尝试,可以修改HA的auth组件,让HA不验证oauth格式,从而让客户端ID保存,具体怎么修改后面会说明。
19楼fengit大佬分享了更加方便的方法,具体方法请往下看。
接入流程
- 1.HA平台配置
- 2.修改HA的auth组件
- 3.音箱平台配置
- 4.HA - customize配置
- 5.音箱测试
HA平台配置
音箱平台配置
下面是我的小京鱼·Skill开放平台,服务端点-配置,参考下:
*Https端点:https://你的域名:你的端口/aihome_service
*SSL证书:服务端点有受信任证书颁发机构的证书
*授权网址:https://你的域名:你的端口/auth/authorize
*客户端ID:https://alphadev.jd.com
*客户端密码:随便填
*访问令牌URL:https://你的域名:你的端口/aihome_auth
解决客户端ID不能填写https://的问题
使用Chrome浏览器打开小京鱼·Skill开放平台服务配置页面,
在 保存 按钮的旁边按鼠标右键,选择 审查元素 ,找到下面这段代码
<button type="button" class="ant-btn ant-btn-primary" disabled="">
删除掉disabled字段,保存按钮变亮就可以保存了。
HA - customize配置
-
- packages/master_bedroom_lihgt.yaml下主卧灯的配置,可以参考下:
homeassistant:
customize:
light.master_bedroom_pendant_light:
friendly_name: "主卧吊灯"
aihome_device: True
aligenie_deviceName: 吊灯
aligenie_zone: 主卧
aligenie_deviceType: light
aligenie_actions: ["TurnOn", "TurnOff"]
dueros_deviceType: 'LIGHT'
dueros_actions: ['turnOn', 'turnOff']
jdwhale_deviceType: 'LIGHT'
jdwhale_actions: ['TurnOn', 'TurnOff', 'Query', 'QueryPowerState']
light.master_bedroom_down_light:
friendly_name: "主卧筒灯"
aihome_device: True
aligenie_deviceName: 筒灯
aligenie_zone: 主卧
aligenie_deviceType: light
aligenie_actions: ["TurnOn", "TurnOff"]
dueros_deviceType: 'LIGHT'
dueros_actions: ['turnOn', 'turnOff']
jdwhale_deviceType: 'LIGHT'
jdwhale_actions: ['TurnOn', 'TurnOff', 'Query', 'QueryPowerState']
-
- packages/living_room_cover.yaml下客厅窗帘的配置,可以参考下:
homeassistant:
customize:
cover.living_room_cover:
friendly_name: "客厅窗帘"
aihome_device: True
aligenie_deviceName: 窗帘
aligenie_zone: 客厅
aligenie_deviceType: curtain
aligenie_actions: ["TurnOn", "TurnOff"]
dueros_deviceType: 'CURTAIN'
dueros_actions: ["turnOn", "timingTurnOn", "turnOff", "timingTurnOff", "pause"]
jdwhale_deviceType: 'CURTAIN'
jdwhale_actions: ['TurnOn', 'TurnOff', 'Query', 'QueryPowerState']
音箱测试
以上配置好后,一定要重启下HA。
打开小京鱼·Skill开放平台测试技能选项,
点击启用按钮后,会弹出HA平台账号授权关联页面,填入你的HA账号和密码,完成验证。(我测试过,手机沙箱app不用绑定自己的技能名。)
完成后在下面的输入框里输入“发现设备”。
然后点击发送请求,左侧的设备列表会列出HA平台中customize自定义配置过的设备。(发送1次请求不成功的话,多尝试几次)
到此,可以测试一下是否成功。
对着叮咚mini2音箱说:叮咚叮咚,打开主卧筒灯。
PS:修改HA的auth组件
下面我们来讲下如何修改HA的auth组件。
需要修改2个文件,login_flow.py和indieauth.py
我这边安装的是hassio
# 进入homeassistant 容器
docker exec -it homeassistant /bin/bash
#cd到auth目录
cd /usr/local/lib/python3.7/site-packages/homeassistant/components/auth/
#备份login_flow.py文件,以防误修改
cp login_flow.py login_flow.py.bak
#修改login_flow.py
vi login_flow.py
#跳转到163行
:163 回车
把
@log_invalid_auth
async def post(self, request, data):
"""Create a new login flow."""
if not await indieauth.verify_redirect_uri(
request.app['hass'], data['client_id'], data['redirect_uri']):
return self.json_message('invalid client id or redirect uri', 400)
if isinstance(data['handler'], list):
handler = tuple(data['handler'])
改为:
@log_invalid_auth
async def post(self, request, data):
"""Create a new login flow."""
# if not await indieauth.verify_redirect_uri(
# request.app['hass'], data['client_id'], data['redirect_uri']):
# return self.json_message('invalid client id or redirect uri', 400)
if isinstance(data['handler'], list):
handler = tuple(data['handler'])
# 进入homeassistant 容器
docker exec -it homeassistant /bin/bash
#cd到auth目录
cd /usr/local/lib/python3.7/site-packages/homeassistant/components/auth/
#备份indieauth.py文件,以防误修改
cp indieauth.py indieauth.py.bak
#修改indieauth.py
vi indieauth.py
#跳转到111行
:111 回车
把
def verify_client_id(client_id):
"""Verify that the client id is valid."""
try:
_parse_client_id(client_id)
return True
except ValueError:
return False
改为:
def verify_client_id(client_id):
"""Verify that the client id is valid."""
try:
# _parse_client_id(client_id)
return True
except ValueError:
return False