remotechannel是设备和手机APP之间通信的协议,但是目前也有一些消息是服务端直接发送到设备端。
目前remotechannel消息通过IOT团队提供的MQTT通道发送,MQTT连接在applications/mqtt应用中实现,其他应用通过dbus发送和订阅remotechannel消息,详见applications.mqtt文档。
remotechannel消息包含几个字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| reviceDevice | object | 是 | 接收端 |
| sourceDevice | object | 是 | 发送端 |
| topic | string | 是 | 消息主题 |
| txt | string | 是 | 消息体 |
| reqId | string | 否 | 请求类消息的id,需要回复的消息,回复的时候reqId要原值返回 |
| messageId | string | 是 | 单个消息的唯一标识,方便服务端追踪一个消息的来龙去脉 |
| expireTime | string | 否 | 整型数值类型字符串,表示消息存储在数据库的过期时间,为空时表示永久存储 |
reviceDevice和sourceDevice的定义
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| accountId | string | 是 | user id |
| deviceId | string | 是 | 设备id |
| deviceTypeId | string | 是 | 设备类型id |
手机APP端只需要填accountId,值为用户的user id;设备端三个都需要填,accountId表示master id,deviceId为SN号,deviceTypeId为设备类型id。
发送接口见comp.remotechannel.send。
remotechannel消息大概可以分为两种
- 功能型消息:这些消息有具体的功能,格式比较具体
- 通用型消息:消息有大致的功能分类,每个具体的功能格式可能不同
功能型消息
version
和手机APP的握手消息。手机APP发送version消息,收到回复后手机APP可以确认设备在线。
| 端 | txt值 |
|---|---|
| 手机APP | APP推荐的remotechannel协议版本 |
| 设备端 | 如果支持手机APP的推荐版本返回"ok",否则返回自身支持的协议版本 |
目前协议版本都为"1"。
get_volume
获取设备当前音量。txt值忽略,返回volume event消息,见下文。
set_volume
设置音量。txt为json格式字符串,key和value分别是要设置的音量通道和要设置的值,值范围是0 ~ 100,目前只支持设置music通道,比如
{ "music": 66 }
设置音量后会发送volume event消息。
asr
手机APP发送的文字指令(首页让若琪说,让若琪做功能)。txt为语音指令文本,收到后会通过speech解析出NLP,然后交由applications.activation.scene.executor执行。
目前设备支持最多5个asr 消息同时解析,收到第6个消息时会取消最前的解析。
reset_settings
恢复出厂设置。txt值忽略,收到消息后设备
- 关闭所有app
- 调用
resetRoki接口解绑和清除服务端数据 - 清除/data目录数据
- 重启设备
sys_upgrade_available
检查系统更新。txt值忽略,返回当前系统更新信息。如果comp.upgrade.readInfo返回有效值,会返回info中的信息,否则调用检查更新接口并返回对应信息。
返回消息topic相同,依然为sys_upgrade_available,txt为json格式字符串
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| checkCode | number | 是 | 0表示已是最新版本,1表示有更新 |
| currentVersion | string | 是 | 当前系统版本,从core.prop.version函数获取 |
| version | string | 否 | 要更新到的版本 |
| downloadProgress | number | 是 | 0 ~ 100,下载进度,没有更新或没有下载时为0 |
| updateAvailable | boolean | 是 | 是否可以马上更新,APP根据该值判断是否显示开始更新按钮,目前镜像下载完成后就会返回true |
| changelog | string | 否 | 更新说明,目前会返回新OTA网站发布备注输入框的内容 |
目前除了changelog在有值时才有,其他字段都会返回,比如有更新时返回
{
"checkCode": 1,
"currentVersion": "3.0.0-20180602-120000",
“version": "3.0.1-20180603-120000",
"downloadProgress": 66,
"updateAvailable": false,
"changelog": "是发布备注内容"
}
已经是最新版本时返回
{
"checkCode": 0,
"currentVersion": "3.0.1-20180603-120000",
"downloadProgress": 0,
"updateAvailable": false,
}
手机APP上的开始更新按钮发送的是upgrade forward消息,见下文。
UNIVERSAL_UNBIND
解绑消息。txt值忽略。手机APP中点击解绑按钮后收到,该消息是手机APP调用解绑接口后服务端发送。收到该消息后设备
- 清除配网历史记录
- 进入蓝牙配网模式
设备不需要调用解绑接口。
通用型消息
custom_config
custom_config同时也是network.gwrest.getDeviceInfo接口的一个namespace,用来存放一些自定义配置;手机APP修改这些选项时会发送该消息,txt为json格式字符串,key和value与服务端存放的一致,目前支持的key
1. vt_words
value为字符串格式,内容为json编码的自定义激活词结构数组,自定义激活词结构定义
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| py | string | 是 | 拼音,包含声调,比如"ruo4qi2" |
| txt | string | 是 | 激活词,比如"若琪" |
TODO 待补充
2. nightMode
TODO 待补充
event
event消息包含4个字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| event | string | 是 | 事件名称 |
| appid | string | 是 | 接收端的app id |
| type | string | 是 | 模板类型 |
| template | string | 是 | 模板值,是事件的主体 |
1. volume event
template为json格式字符串,json结构定义如下
| 字段 | 类型 | 说明 |
|---|---|---|
| mediaTotal | number | 多媒体音量最大值 |
| mediaCurrent | number | 多媒体音量当前值 |
| alarmTotal | number | 铃声音量最大值 |
| alarmCurrent | number | 铃声音量当前值 |
event为"ON_VOLUME_CHANGE",type为"Volume",appid为"com.rokid.system.volume"。
card
设备发送给手机APP的card 消息会被显示在若琪模块的消息列表,设备不处理card 消息,txt为json格式字符串,json结构定义如下
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| appid | string | 是 | app id |
| type | string | 是 | 模板类型 |
| template | string | 是 | 模板值,card主体,json格式字符串 |
| feedback | string | 否 | 触发card的ASR |
发送时不填expireTime字段,表示card 消息永久存储在云端。
TODO 补充card 消息详细定义链接
forward
应用之间自定义的消息。txt为json格式字符串,json结构定义如下
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| domain | string | 是 | 应用domain,见下文说明 |
| content | string/object | 是 | forward消息主体,必填但是可能是空字符串 |
应用domain是app id之前的概念,使用反xx格式,唯一标识一个应用,比如"com.rokid.alarm1"。
一般content结构与NLP类似,包含domain,intent和slots。
目前设备支持一下几个domain的消息
1. com.rokid.system.upgrade
系统更新。content值忽略,收到消息后马上准备更新(comp.upgrade.prepare),成功之后重启系统。
2. com.rokid.alarm1
闹钟提醒的增删改。content全部是json字符串,slots中的DateTime是字符串类型,这与NLP中的slots.DateTime不太相同,NLP中slots.DateTime是object类型,value值才是真正的时间参数
{
"type": "DateTime",
"value": "{\"AbsMonth\":6,\"RepeatType\":\"\",\"DayZone\":\"MORNING\",\"AbsYear\":2018,\"AbsDay\":3,\"AbsHour\":10,\"AbsMinute\":0}"
}
而且forward消息中的RepeatType定义与NLP也不同
| NLP | forward消息 | 说明 | |
|---|---|---|---|
| -1 | 空的(什么都不填) | 仅此一次 | |
| 0 | D1 | 每周一 | |
| 1 | D2 | 每周二 | |
| 2 | D3 | 每周三 | |
| 3 | D4 | 每周四 | |
| 4 | D5 | 每周五 | |
| 5 | D6 | 每周六 | |
| 6 | D7 | 每周日 | |
| 7 | WEEKEND | 工作日 | |
| 8 | DAY | 每天 | |
| 9 | WEEKDAY | 每周末 |
设备收到forward消息时会转换RepeatType为NLP定义,发送闹钟提醒列表时会再转换回forward消息定义的RepeatType。
修改闹钟主题content
{
"version":"1.0",
"slots":{
"Topic":"5"
},
"domain":"com.rokid.alarm1",
"intent":"_select_theme"
}
Topic为主题index。
添加闹钟content
{
"version":"1.0",
"slots":{
"isPhone":true, // 会被忽略
"DateTime":"{\"AbsMonth\":6,\"RepeatType\":\"\",\"DayZone\":\"MORNING\",\"AbsYear\":2018,\"AbsDay\":3,\"AbsHour\":10,\"AbsMinute\":0}"
},
"domain":"com.rokid.alarm1",
"intent":"_setup_alarm"
}
DateTime结构和语音指令
删除闹钟content
{
"version":"1.0",
"slots":{
"DateTime":"{\"AbsMonth\":6,\"RepeatType\":\"\",\"DayZone\":\"MORNING\",\"AbsYear\":2018,\"AbsDay\":3,\"ext\":{},\"AbsHour\":10,\"AbsMinute\":0}"
},
"domain":"com.rokid.alarm1",
"intent":"_cancel_alarm"
}
修改闹钟content
{
"version":"1.0",
"slots":{
"DateTime":"{\"AbsMonth\":0,\"RepeatType\":\"WEEKEND\",\"AbsYear\":0,\"AbsDay\":0,\"ext\":{},\"AbsHour\":12,\"AbsMinute\":0}",
"SpecificTime":"{\"AbsHour\":12,\"RepeatType\":\"WEEKDAY\",\"DayZone\":\"AFTERNOON\",\"AbsMinute\":0}"
},
"domain":"com.rokid.alarm1",
"intent":"_update_alarm"
}
SpecificTime是目标值。
闹钟列表content
设备端闹钟变化时都会发送闹钟列表到手机APP,content如下
{
"domain":"com.rokid.alarm1.service",
"title":"[{\"day\":0,\"month\":0,\"sec\":0,\"hour\":11,\"year\":0,\"minute\":0,\"id\":0,\"date\":\"每周二\",\"repeat\":\"1\"},{\"day\":3,\"month\":6,\"sec\":0,\"repeat\":\"-1\",\"date\":\"今天\",\"hour\":10,\"year\":2018,\"minute\":0,\"wday\":1,\"id\":0,\"yday\":154,\"isdst\":false}]",
"topicName":"传统保守的人",
"topic":"0"
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| domain | string | 是 | "com.rokid.alarm1.service" |
| topic | string | 是 | 整型数值字符串,表示当前的铃声主题index |
| topicName | string | 是 | 铃声主题名字 |
| title | string | 是 | json数组格式字符串,表示当前的闹钟列表,没有闹钟时为"[]" |
返回的闹钟对象不再使用DateTime结构,repeat值类型为forward消息定义的RepeatType ,设备直接使用了lua的os.date结构,所以其中有一些多余的字段,yday表示一年中的第几天,wday表示一周中的第几天。
删除提醒content
{
"version":"1.0",
"slots":{
"id":"0", // 值被忽略
"DateTime":"{\"AbsHour\":9,\"AbsMonth\":6,\"RepeatType\":\"\",\"AbsYear\":2018,\"AbsDay\":3,\"AbsMinute\":49}"
},
"domain":"com.rokid.alarm1",
"intent":"_cancel_remind"
}
id值被忽略。删除提醒时会对DateTime做完全匹配,而且不可以创建相同时间的提醒,所以DateTime可以唯一标识一个提醒。
提醒列表content
设备端提醒变化时都会发送提醒列表到手机APP,content如下
{
"title":"[{\"day\":3,\"month\":6,\"content\":\"睡回笼觉\",\"sec\":39,\"repeat\":\"-1\",\"date\":\"今天\",\"hour\":9,\"year\":2018,\"yday\":154,\"wday\":1,\"id\":0,\"minute\":34,\"isdst\":false}]",
"domain":"com.rokid.alarm1.remind.service"
}
这时forward消息的domain依然是"com.rokid.alarm1",因为闹钟提醒本身的domain/appId是相同的,但是content中的domain与闹钟列表不同。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| domain | string | 是 | "com.rokid.alarm1.remind.service" |
| title | string | 是 | json数组格式字符串,表示当前的提醒列表,没有提醒时为"[]" |
3. com.rokid.alarm1.service
闹钟查询服务。content为object类型,值被忽略,使用forward消息返回闹钟列表,txt中domain为"com.rokid.alarm1",content见上文闹钟列表content。
查询闹钟txt
{
"content": {
"descriptor": "com.rokid.alarm1.service.IGetAlarmsService",
"transaction": "1"
},
"getInfos":"com.rokid.alarm1.service","
"domain": "com.rokid.alarm1.service"
}
4. com.rokid.alarm1.remind.service
提醒查询服务。content为object类型,值被忽略,使用forward消息返回提醒列表,txt中domain为"com.rokid.alarm1",content见上文提醒列表content
查询提醒txt
{
"content": {
"transaction":"1",
"version":"1.0",
"descriptor":"com.rokid.alarm1.service.IGetRemindsService",
"domain":"com.rokid.alarm1.remind.service"
},
"getInfos":"com.rokid.alarm1.remind.service", // 也会忽略
"domain":"com.rokid.alarm1.remind.service"
}
5. RBA66C902A6347DD86CA8D419B0BB974
QQ音乐。TODO 待补充
6. com.rokid.qqmusic.service
TODO 待补充
cloud_forward
cloud发送的forward 消息,手机APP上点播音乐时调用skill提供的HTTP接口,skill会向设备发送cloud_forward 消息。txt为json格式字符串,收到后解析出NLP和action,交由applications.activation.scene.executor执行。解析方式
json.decode(json.decode(txt).content.params)
例如手机播放喜马拉雅 -> 郭德纲相声十年经典 -> 卖布头
{
"content":{
"params":"{\"action\":{\"appId\":\"RC528E2DD8E745E195173D9F8BE48436\",\"response\":{\"action\":{\"version\":\"2.0.0\",\"type\":\"NORMAL\",\"form\":\"scene\",\"shouldEndSession\":false,\"directives\":[{\"type\":\"voice\",\"disableEvent\":false,\"action\":\"STOP\"},{\"type\":\"media\",\"disableEvent\":false,\"action\":\"PLAY\",\"item\":{\"itemId\":\"2667276$$19662249$$36\",\"type\":\"AUDIO\",\"url\":\"http://fdfs.xmcdn.com/group19/M0A/6F/93/wKgJK1ei0IfSlVY1AhhaTAQ-Too260.mp3\",\"offsetInMilliseconds\":0}}]},\"resType\":\"INTENT\"},\"version\":\"2.0.0\"},\"nlp\":{\"appId\":\"RC528E2DD8E745E195173D9F8BE48436\",\"cloud\":true}}"
},
"appId":"RC528E2DD8E745E195173D9F8BE48436",
"domain":"com.rokid.cas.ximalaya"
}
params中action和NLP必须有。