bowen liu
/
mbed-os-example-blinky
ex
Fork of mbed-os-example-mbed5-blinky by
Revision 44:c1d8923072ba, committed 2017-07-18
- Comitter:
- TMBOY
- Date:
- Tue Jul 18 16:27:22 2017 +0800
- Parent:
- 43:294225846244
- Child:
- 45:2aa9f933c8d2
- Commit message:
- ?
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/.gitignore Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,51 @@ +# Logs +logs +*.log +npm-debug.log* + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules +jspm_packages + +# Optional npm cache directory +.npm + +# Optional REPL history +.node_repl_history + +#vim swp +*.swp + +# OS +.DS_Store + +# Config/Output +/build/ +/config.js +/build.tgz +/build.zip +/build_debug.zip +/build_debug.tgz
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/README.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,8 @@ + + +### 度秘开放api文档 +[度秘开放api文档](doc/OPENAPI_README.md) + +### 度秘开放api json schema详细定义 +基于[http://json-schema.org/](http://json-schema.org/)的标准,提供了详细的schema验证 +[json schema详细定义](schema/README.md)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/BOTAPI2.0_README.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,253 @@ +# 度秘开放平台-BotApi2.0接口说明 + +## Table of Contents + + + * [度秘开放平台-BotApi2.0接口说明](#度秘开放平台-botapi20接口说明) + * [Table of Contents](#table-of-contents) + * [交互模式说明](#交互模式说明) + * [关于confirm的说明](#关于confirm的说明) + * [请求格式](#请求格式) + * [未来的响应格式](#未来的响应格式) + * [bot配置(开放平台的输出)](#bot配置开放平台的输出) + + +## 交互模式说明 + +### 关于confirm的说明 +![confirm](http://d.hiphotos.baidu.com/xiaodu/pic/item/f9dcd100baa1cd1111c81ea2b012c8fcc3ce2d31.jpg) + + * 之所以有confirm请求,是因为us会把同一个请求发给多个bot,然后挑选较好的一个。bot返回的结果,有可能不被使用 + * 按bot对请求的处理有无副作用,分为幂等请求和非幂等请求 + * 幂等请求如: + * 通用信息 + * 天气 + * 非幂等请求如: + * 提醒(bot会为用户创建提醒) + * 打车(bot会帮用户叫车) + + +## 请求格式 + +```javascript +{ + "version": 2, + "query":"", //query,可能已经经过了改写 + "raw_query":"", //原始query,可选 + "content_type": "image",//可选,默认是txt + "user_id":"", //对bot来说,可以唯一标识一个用户的string + + "cuid":"", //设备id,可选 + "dumi_id":"", //度秘登录用户id,可选 + "baidu_uid":"", //百度登录后的passport id,可选 + "bot_id":"",//把bot_id带下来,其实可以不看 + + "log_id":"5969bdd5126d493387a6b127d8c45ce7", + "confirm":1,//0或者1,0代表可能不会使用bot的返回结果,1代表肯定会使用bot的返回结果。(参考上面的[关于confirm的说明]) + + "query_type":"1",//请求类型,标识用户发这个请求的方法,参见文档 http://agroup.baidu.com/dbo/md/article/49113 + "client_info":{ + "device_interface":{ + "Alerts":{}, + "AudioPlayer":{}, + "PlaybackController":{}, + "Speaker":{}, + "Settings":{}, + "System":{} + }, //设备支持的接口(包含directive、event等整套实现) + + "device_event":{ + //query_type==30 的时候才会有 device_event + "header": { + "namespace": "AudioPlayer", + "name": "PlaybackStarted", + "message_id": "message_id-1344" + }, + "payload": { + //AudioPlayer里可能出现的payload + "token": "156", + "offset_ms": 10000 + //Speaker里可能出现的payload + "volume": 1, + //SpeechSynthesizer可能出现的payload + "token": "156", + "type": "{{Text/SSML}}", + "content": ["xxxx1", "xxxx2"], + "speak_behavior": "REPLACE_ALL", + "should_get_next_speech": true + } + }, + + "device_status":{ + "AudioPlayer":{ + "audio_item_id":"xxx",//正在播放的音频流id + "offsetInMilliseconds":20000,//播放到多少ms了 + "playerActivity":"IDLE PAUSED PLAYING BUFFER_UNDERRUN FINISHED STOPPED" + }, + }, + "operation_system":"android", + "operation_system_version":"5.0", + "from_client":"sdk",// sdk/na/shoubai + "appid":"appid", + "appkey":"appkey", + "device_brand":"apple", //设备品牌 (目前只有对外sdk有该字段),ios写死"apple",安卓取android.os.Build.BRAND + "device_model":"iphone 6s", //设备具体型号 (目前只有对外sdk有该字段)ios取 设备型号字符串 + "ua":"",//可选,浏览器的user agent + "app_ver":"1.0.0" + }, + + //完整的地址信息 + "location": { + "la": 40.0433, + "lo": 116.269, + "bd_la": 40.0508, + "bd_lo": 116.281, + "mi_la": 4845580, + "mi_lo": 12944500, + "address": "北京市海淀区软件园西三路", + "city": "北京市", + "city_code": 131, + "country": "中国", + "country_code": 0, + "direction": "", + "distance": "", + "district": "海淀区", + "province": "北京市", + "street": "软件园西三路", + "street_number": "", + "cip": "1.2.2.1", + "cip_type": "mockbycity", + "location_type": "real", + "sematic_description": "百度科技园内" + }, + + "session": {//是上次user_id + bot_id 请求的返回值里的session,纯kv,内部结构不做限制(串行化保存的值) + "key":"value", + "key2":"value2" + }, + //用户常驻地址,可选,字段和上面location一致 + "freq_location": { "la": 40.0433, "lo": 116.269, "bd_la": 40.0508, "bd_lo": 116.281, "mi_la": 4845580, "mi_lo": 12944500, "address": "北京市海淀区软件园西三路", "city": "北京市", "city_code": 131, "country": "中国", "country_code": 0, "direction": "", "distance": "", "district": "海淀区", "province": "北京市", "street": "软件园西三路", "street_number": "", "cip": "1.2.2.1", "cip_type": "mockbycity", "location_type": "real", "sematic_description": "百度科技园内" }, + //最近几次访问的地址,可选,一个数组,每个元素里面的结构和location 一致 + "last_location":[ + { "la": 40.0433, "lo": 116.269, "bd_la": 40.0508, "bd_lo": 116.281, "mi_la": 4845580, "mi_lo": 12944500, "address": "北京市海淀区软件园西三路", "city": "北京市", "city_code": 131, "country": "中国", "country_code": 0, "direction": "", "distance": "", "district": "海淀区", "province": "北京市", "street": "软件园西三路", "street_number": "", "cip": "1.2.2.1", "cip_type": "mockbycity", "location_type": "real", "sematic_description": "百度科技园内" }, + { "la": 40.0433, "lo": 116.269, "bd_la": 40.0508, "bd_lo": 116.281, "mi_la": 4845580, "mi_lo": 12944500, "address": "北京市海淀区软件园西三路", "city": "北京市", "city_code": 131, "country": "中国", "country_code": 0, "direction": "", "distance": "", "district": "海淀区", "province": "北京市", "street": "软件园西三路", "street_number": "", "cip": "1.2.2.1", "cip_type": "mockbycity", "location_type": "real", "sematic_description": "百度科技园内" }, + ], + + //da解析结果,对一个query可能有多种理解,所以是一个数组 + "nlu_list":[ + {"score":100,"domain":"remind","intent":"remind","slots":{"event_title":"开会","intent":"设置","remind_time":"{\"month\":\"10\",\"day\":\"21\",\"hour\":\"9\",\"apm\":\"am\"}","__intent__":"setup","__id__":"1483430617165_fu6tll","remind_type_message":"否","remind_type_phone":"否","remind_type_dumi":"否","remind_type_clock":"否","remind_time_type":"abstime","remind_time_data":"1508547600","status":"create_confirm"}}, + {"score":100,"domain":"duer_weather","intent":"sys_weather","slots":{"loc_city":"九江市","loc_county":"九江市","loc_province":"江西省","time":"2017-01-03,2017-01-03"}}, + ], + //其他da解析结果,会放服务的原始返回,比如分词、语法分析之类的结果 + "nlu_extend":{ + "nlu_responce": "{\"analysis\":{},\"parsed_text\":\"张 岩\",\"raw_text\":\"张岩\",\"results\":[{\"demand\":0,\"domain\":\"universal_search\",\"intent\":\"search\",\"object\":{},\"pushleft_switch\":\"0\",\"score\":1,\"str_result_content\":{},\"str_result_type\":\"\"}],\"sugs\":\"张岩\",\"sugs_types\":\"PAT_EC\"}\n" + "qu_responce": "{\"err_no\":0, \"result\":[{\"normal\":{}, \"qu\":{\"query_voice\":{\"res\":[{\"domain\":\"phone\", \"intent\":\"F->Phone->Context\", \"score\":1, \"objects\":[{\"key\":\"CallTarget\", \"value\":\"张岩\", \"score\":1}, {\"key\":\"_CallTarget\", \"value\":\"张岩\", \"score\":1}], \"reduce_tree_info\":\"(query(F->Phone->Context(CallTarget(Person 张岩))))\"}, {\"domain\":\"UNDEFINED\", \"intent\":\"F->alarmlocation\", \"score\":5502, \"objects\":[{\"key\":\"Route\", \"value\":\"张岩\", \"score\":1}, {\"key\":\"_Route\", \"value\":\"张岩\", \"score\":1}], \"reduce_tree_info\":\"(query(F->alarmlocation(Route(F->route(Arrival(F->arrival(ARRIVAL(VILLAGE 张岩))))))))\"}, {\"domain\":\"UNDEFINED\", \"intent\":\"F->alarmlocation\", \"score\":5503, \"objects\":[{\"key\":\"Route\", \"value\":\"张岩\", \"score\":1}, {\"key\":\"_Route\", \"value\":\"张岩\", \"score\":1}], \"reduce_tree_info\":\"(query(F->alarmlocation(Route(F->route(Arrival(F->arrival(ARRIVAL(POI(VILLAGE 张岩)))))))))\"}]}}, \"queryId\":1}]}" + }, +} +``` + +## 未来的响应格式 + +里面的result结构中的views、resource、nlu、speech、directives、hint都和对外输出的格式里的定义一致,详细结构可见([度秘API2.0文档](http://gitlab.baidu.com/wangpeng20/dumi_schema/blob/master/doc/OPENAPI_README.md)) + +```javascript +{ + "status" : 0, //0 success,other fail + "version": 2, + "msg" : "string", //status 0,msg "success",status not 0,msg explaining reason + "need_confirm":1, //可选,默认为0,参考前面的[关于confirm的说明] + "data" : { + //如果bot没有召回结果,就不要返回result结构了 + "result":{ + //必选 + "views":[], + //可选 + "resource":{}, + //应该从请求的nlus里选一条返回,可选 + "nlu":{"domain":"duer_weather","intent":"sys_weather","slots":{"loc_city":"九江市","loc_county":"九江市","loc_province":"江西省","time":"2017-01-03,2017-01-03"}}, + //必选 + "speech":{}, + //可选 + "directives":[], + //可选 + "hint":[], + //可选,默认为true,如果为false,客户端应该立即进入收听用户query的状态,不用重新唤醒 + 'should_end_session':false, + }, + //会被串行化后保存起来,下次同一个 (user_id,bot_id) 请求的时候,会带上 + "session":{ + "key":"value", + "key2":"value2" + }, + /* + bot_state的取值 + 0,根据da给出的intent,返回结果 + 1,bot自己改写了intent(返回到了result.nlu里面),返回结果 + 2、da返回的槽位值,bot认为有错,返回中给出了相应的错误提示 + 3、bot不能响应intent,出了保底话术 + 默认为0 + */ + "bot_state":0, + //rank使用的字段,建议选填,key可以自定,排序的时候会看相关性高低 + "strategy":{ + "title":"标题", + "content":"主要内容", + "url":"http://www.baidu.com",//地址,可能会看来源的权威性 + "resource_type":"views,audio", //views和audio的组合,本条结果适合的场景,中控会根据当前应用场景和客户端类型来排序 + "is_valid_result":true,//默认为true,标识这条返回是保底的,还是真的有内容的 + } + } +} + +``` + + +## bot配置(开放平台的输出) + * 服务的host定义 + * protocol: https / http / nshead+mcpack + * domain: 可以是ip/域名;如果是bns,需要设置domain_type + * domain_type :"dns/bns", //可选,默认是dns + * port: http默认80, https默认443 + * uri: 地址 + * 只有被定义在intents中,这个intent才会被转发给bot + * event请求,根据schema中的interface字段和event的namespace,决定是否转发 + +```javascript +{ + "bot_id":"phone", + "bot_meta":{ //下游bot元数据 + "description":"返回音乐类结果", // 文字描述 + "version":"1.0.0", //版本 + "type":"音乐" //TODO,bot类型见pm给的分类 + }, + //"url":"http://xiaodu.baidu.com:80/api/phone", + + "protocol": "https / http / nshead+mcpack", + "domain":"172.0.0.1", //可以是ip;如果是bns,要加domain_type + "domain_type":"dns/bns", //可选,默认是dns + "port":"8080", http默认80, https默认443 + "uri":"/saiya/search", + //标识bot能接受哪些客户端事件 + "interface":{ + "AudioPlayer":{}, + }, + "intents": [ + { + "intent": "phone", + "slots": [ + { + "name": "action_type", + "type": "ACTION_TYPE" + }, + { + "name": "Date", + "type": "AMAZON.DATE" + } + ] + }, + { + "intent": "GetLuckyNumbers" + } + ] +} +```
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/BOTAPI_README.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,515 @@ +# 度秘开放平台-BotApi接口说明 + + +## Table of Contents + + + * [度秘开放平台-BotApi接口说明](#度秘开放平台-botapi接口说明) + * [Table of Contents](#table-of-contents) + * [文档目的](#文档目的) + * [整体格式说明](#整体格式说明) + * [架构描述](#架构描述) + * [交互模式说明(confirm)](#交互模式说明confirm) + * [请求格式](#请求格式) + * [请求字段中,.supported_content_type字段的解释](#请求字段中supported_content_type字段的解释) + * [请求字段中,.msg.device_data字段的解释](#请求字段中msgdevice_data字段的解释) + * [正常返回格式](#正常返回格式) + * [和策略相关的字段](#和策略相关的字段) + * [正常返回的字段中,content字段的解释](#正常返回的字段中content字段的解释) + + +## 文档目的 + +目的: + * 为了让能够让度秘内部的rd开发下游bot + * 为了给未来的bot开放平台做准备 + +整理度秘系统和bot之间的接口 + +## 整体格式说明 + +### 架构描述 + +![dumi_system](http://e.hiphotos.baidu.com/xiaodu/pic/item/2934349b033b5bb53d4d4c7c3fd3d539b700bc9e.jpg) + +这篇文档整理的是下游bot的输入输出接口 + + +## 交互模式说明(confirm) + +![confirm](http://d.hiphotos.baidu.com/xiaodu/pic/item/f9dcd100baa1cd1111c81ea2b012c8fcc3ce2d31.jpg) + + * 之所以有confirm请求,是因为us会把同一个请求发给多个bot,然后挑选较好的一个。bot返回的结果,有可能不被使用 + * 按bot对请求的处理有无副作用,分为幂等请求和非幂等请求 + * 幂等请求如: + * 通用信息 + * 天气 + * 非幂等请求如: + * 提醒(bot会为用户创建提醒) + * 打车(bot会帮用户叫车) + +### 请求格式 + +以下是现有的协议 + +```javascript +{ + //最终返回值里的bot_id,相当于以前的source_type,在中控配置。以后bot_id不再由bot返回的source_type决定 + "bot_name": "ai.dueros.bot.information_general", + "launch":true,//标识是第一次open这个bot的请求,默认是false + "end_session":true,//标识是第一次open这个bot的请求,默认是false + "user_id": "3101", ///用户id,如果非登录用户会改成 + "query": "张岩", //原始query + "version": 1, //版本号 + "msg": { ///老的协议格式,原始的msg,不知为何result_content是个字符串 + "id": "1454319650_5906bphzi", + "debug": 1, + "mode": 0, + "operation_system": "ios", + "app_ver": "1.4.0", + "from": "ios", + "ctime": 1454319650, + "type": "user", + "query_type": "1", + "device_data":"{}",//target_device_id,device_interface, device_event, device_status 三个字段的打包json,因为现在idl定义不了这三个字段的结构 + "result_list": [ + { + "result_confidence": 100, + "result_content": "{\"answer\":\"张岩\"}\n", + "result_type": "txt", + "source_type": "" + } + ], + "request_uid": "1463803763", + "client_msg_id": "20674", + "request_from": "0", + "request_type": "0", + "sample_name": "bear_brain_wireless" + }, + "log_id": "5969bdd5126d493387a6b127d8c45ce7", //串起整个请求的id + "request_type": "dumi", //现在的策略分支 + "params": { + "loc": "%7B%22crd%22%3A%2212944500.486221_4845580.669330_200%22%2C%22city%22%3A%22%5Cu5317%5Cu4eac%5Cu5e02%22%2C%22addr%22%3A%22%5Cu5317%5Cu4eac%5Cu5e02%5Cu6d77%5Cu6dc0%5Cu533a%5Cu8f6f%5Cu4ef6%5Cu56ed%5Cu897f%5Cu4e09%5Cu8def%22%7D",//其实是地址信息,但有了location之后这个已经没用了 + "cip": "1.2.2.1",//客户端ip + "bear_params": { + "nlu_response": "{\"analysis\":{},\"parsed_text\":\"张 岩\",\"raw_text\":\"张岩\",\"results\":[{\"demand\":0,\"domain\":\"universal_search\",\"intent\":\"search\",\"object\":{},\"pushleft_switch\":\"0\",\"score\":1,\"str_result_content\":{},\"str_result_type\":\"\"}],\"sugs\":\"张岩\",\"sugs_types\":\"PAT_EC\"}\n" + }, + "client_from": "NA", + "intervene_from": "na", + "sc_response": "{}" + }, + //完整的地址信息 + "location": { + "la": 40.0433, + "lo": 116.269, + "bd_la": 40.0508, + "bd_lo": 116.281, + "mi_la": 4845580, + "mi_lo": 12944500, + "address": "北京市海淀区软件园西三路", + "city": "北京市", + "city_code": 131, + "country": "中国", + "country_code": 0, + "direction": "", + "distance": "", + "district": "海淀区", + "province": "北京市", + "street": "软件园西三路", + "street_number": "", + "cip": "1.2.2.1", + "cip_type": "mockbycity", + "location_type": "real", + "sematic_description": "百度科技园内" + }, + "page_cnt": 10, + "page_num": 1, + //没有多轮就可以忽略session字段 +/* + "sessions": [ + { + "action": "get", + "type": "string", + "name": "phone", + "key": "3101", + "list_sessions": [], + "list_sessions_str": [ + "{\"SendSMS\":{\"intent\":\"SendSMS\",\"score\":42,\"objects\":[{\"key\":\"MSMOmit\",\"value\":\"\\u8bf4\",\"score\":1},{\"key\":\"_MSMOmit\",\"value\":\"\\u8bf4\",\"score\":1},{\"key\":\"MSGBody\",\"value\":\"\\u4e0d\\u56de\\u5bb6\\u5403\\u996d\",\"score\":1},{\"key\":\"_MSGBody\",\"value\":\"\\u4e0d\\u56de\\u5bb6\\u5403\\u996d\",\"score\":1},{\"key\":\"SendKey\",\"value\":\"\\u53d1\",\"score\":1},{\"key\":\"_SendKey\",\"value\":\"\\u53d1\",\"score\":1},{\"key\":\"WantKey\",\"value\":\"\\u6211\\u8981\",\"score\":1},{\"key\":\"_WantKey\",\"value\":\"\\u6211\\u8981\",\"score\":1}]}}" + ], + "hash_sessions": [] + } + ], +*/ + "safe_mode":false, //儿童模式开关,true为打开状态,fasle为关闭状态 + "bot_sessions": [ + { + "action": "get", + "type": "string", + "key": "3101", + "list_sessions": [], + "list_sessions_str": [ + "{\"SendSMS\":{\"intent\":\"SendSMS\",\"score\":42,\"objects\":[{\"key\":\"MSMOmit\",\"value\":\"\\u8bf4\",\"score\":1},{\"key\":\"_MSMOmit\",\"value\":\"\\u8bf4\",\"score\":1},{\"key\":\"MSGBody\",\"value\":\"\\u4e0d\\u56de\\u5bb6\\u5403\\u996d\",\"score\":1},{\"key\":\"_MSGBody\",\"value\":\"\\u4e0d\\u56de\\u5bb6\\u5403\\u996d\",\"score\":1},{\"key\":\"SendKey\",\"value\":\"\\u53d1\",\"score\":1},{\"key\":\"_SendKey\",\"value\":\"\\u53d1\",\"score\":1},{\"key\":\"WantKey\",\"value\":\"\\u6211\\u8981\",\"score\":1},{\"key\":\"_WantKey\",\"value\":\"\\u6211\\u8981\",\"score\":1}]}}" + ], + "hash_sessions": [] + } + ], + //////////上次返回new_bot_session, 这次也会用new_bot_session带下来,这是新的session机制,协议简单点 @zhanggang + "new_bot_session" :{ + "value":"{\"empty\":true}" //需要写入到session中的内容 + }, + //如果是百度登录用户的话,会有信息 + "user_info": { + "user_id": "", + "extra": [] + }, + "data": { + "status": 0, + "msg": "OK", + "da_query_info": [ //现在的qu结果,数组,type是服务(第二级的type是domain,第三级result_list里的type是intent) + { + "query": "张岩", + "type": "qu", + "result_list": [ + { + "type": "query", + "score": 0, + "result_list": [] + }, + { + "type": "session", + "score": 0, + "result_list": [] + } + ] + } + ], + "params": [ //其他几个qu结果的原始数据,一般情况都不用看 + { + "key": "nlu_responce", + "value": "{\"analysis\":{},\"parsed_text\":\"张 岩\",\"raw_text\":\"张岩\",\"results\":[{\"demand\":0,\"domain\":\"universal_search\",\"intent\":\"search\",\"object\":{},\"pushleft_switch\":\"0\",\"score\":1,\"str_result_content\":{},\"str_result_type\":\"\"}],\"sugs\":\"张岩\",\"sugs_types\":\"PAT_EC\"}\n" + }, + { + "key": "qu_responce", + "value": "{\"err_no\":0, \"result\":[{\"normal\":{}, \"qu\":{\"query_voice\":{\"res\":[{\"domain\":\"phone\", \"intent\":\"F->Phone->Context\", \"score\":1, \"objects\":[{\"key\":\"CallTarget\", \"value\":\"张岩\", \"score\":1}, {\"key\":\"_CallTarget\", \"value\":\"张岩\", \"score\":1}], \"reduce_tree_info\":\"(query(F->Phone->Context(CallTarget(Person 张岩))))\"}, {\"domain\":\"UNDEFINED\", \"intent\":\"F->alarmlocation\", \"score\":5502, \"objects\":[{\"key\":\"Route\", \"value\":\"张岩\", \"score\":1}, {\"key\":\"_Route\", \"value\":\"张岩\", \"score\":1}], \"reduce_tree_info\":\"(query(F->alarmlocation(Route(F->route(Arrival(F->arrival(ARRIVAL(VILLAGE 张岩))))))))\"}, {\"domain\":\"UNDEFINED\", \"intent\":\"F->alarmlocation\", \"score\":5503, \"objects\":[{\"key\":\"Route\", \"value\":\"张岩\", \"score\":1}, {\"key\":\"_Route\", \"value\":\"张岩\", \"score\":1}], \"reduce_tree_info\":\"(query(F->alarmlocation(Route(F->route(Arrival(F->arrival(ARRIVAL(POI(VILLAGE 张岩)))))))))\"}]}}, \"queryId\":1}]}" + } + ] + }, + //数组每一个元素为一类资源类型;audio(mp3(16000,128000),aac)代表音频格式只支持mp3和aac,其中mp3只支持码率在16k~128k之间 + "supported_content_type":["audio(mp3(16000,128000),aac)","video","image","webview","speech"], + //keep_silence=1的时候,中控不给客户端返回tts或者显示的信息,但会做写session等处理 + "keep_silence":1 +} + + + +``` + +#### 请求字段中,.supported_content_type字段的解释 +表示了端支持的内容类型,bot应该召回端支持的内容类型,**不召回**端不支持的内容 + * audio + * video + * image + * webview + * speech + +#### 请求字段中,.msg.device_data字段的解释 + +.msg.device_data字段,是一个json_encode后的字符串 + +会把[请求里的几个字段](api/request.md#客户端能力相关device_interface-device_event-device_status)映射过来 + +下面是这个json展开后的结构 +```javascript +{ + + "target_device_id":"xxxxxx", + "device_interface":{ + "Alerts":{}, + "AudioPlayer":{ + //"no_pause":1, + //"no_seek":1, + }, + "PlaybackController":{}, + "Speaker":{}, + "Settings":{}, + "System":{} + }, + "device_event":{ + //query_type==30 的时候才会有 device_event + "header": { + "namespace": "AudioPlayer", + "name": "PlaybackStarted", + "message_id": "message_id-1344" + }, + "payload": { + //AudioPlayer里可能出现的payload + "token": "156", + "offset_ms": 10000, + //Speaker里可能出现的payload + "volume": 1, + //SpeechSynthesizer可能出现的payload + "token": "156", + "type": "{{Text/SSML}}", + "content": ["xxxx1", "xxxx2"], + "speak_behavior": "REPLACE_ALL", + "should_get_next_speech": true + } + }, + "device_status":{ + "AudioPlayer":{ + "token":"xxx",//正在播放的音频流id + "offset_ms":20000,//播放到多少ms了 + "player_activity":"IDLE PAUSED PLAYING BUFFER_UNDERRUN FINISHED STOPPED" + }, + } +} +``` + + +### 正常返回格式 + + +```javascript + +{ + "status": 0, + "msg": "ok", + "data": { + "result_list": [ + { + //内容质量得分,可选 + "confidence": 100, + //bot的id,必须有 + "source_type": "phone", + //统计字段,可以用来给bot的返回值分类,可以不传 + "source_sub_type": "contact", + //真正拼的消息其实是这个content字段,现在对外返回的resource、directives等字段都放在这个里面,和result_list平级,下一段详细讲这个content + "content": "{\"result_list\":[{\"result_content\":{\"answer\":\"<SYSTEM-NAME>为你查看联系人“张岩”\"},\"result_type\":\"txt\",\"source_type\":\"phone\",\"source_sub_type\":\"contact\",\"voice\":\"<SYSTEM-NAME>为你查看联系人“张岩”\"}],\"type\":\"server\",\"generator\":\"phone_function\",\"user_id\":\"3101\"}", + //会用于us排序的字段,为了让排序策略起作用,尽可能传一下 + "stategy_middle_data": { + "bot_intent":{ + "query":"raw query" ////请求的query,如果有bot_intent,这个就必须有 + "query_score":100 ////和需求的匹配度,可选 + }, + "raw_answer": [ + { + "title": "", + "subtitle": "", + "answer": "<SYSTEM-NAME>为你查看联系人“张岩”", + "url": "" + } + ] + } + } + ], + //页码,总页数,总结果数,都可以不传 + "page_num": 1, + "page_cnt": 1, + "result_num": 1, + ////和请求中的da_query_info格式一致,表示下游bot实际使用的da_query_info(也可以说就是把请求中不使用的),可以为空 + "service_query_info": [ + { + "query": "张岩", + "type": "phone", + "result_list": [ + { + "type": "phone", + "score": 100, + "result_list": [ + { + "type": "contact", + "score": 0, + "content": "", + "result_list": [ + { + "key": "name_for_view", + "type": "text", + "score": 0, + "value": [ + { + "name": "name_for_view", + "value": "张岩" + } + ] + }, + { + "key": "pinyin_for_view", + "type": "text", + "score": 0, + "value": [ + { + "name": "pinyin_for_view", + "value": "zhang+yan" + } + ] + }, + { + "key": "action_type", + "type": "text", + "score": 0, + "value": [ + { + "name": "action_type", + "value": "1" + } + ] + }, + { + "key": "show_query", + "type": "text", + "score": 0, + "value": [ + { + "name": "show_query", + "value": "张岩" + } + ] + } + ] + } + ] + } + ] + } + ], + "server_query_intent": "\"\"" + }, + /////如果不是多轮,此字段可没有 + ///sessions字段已经废弃,现在是bot_sessions和decision_sessions, 不再有name +/* + "sessions": [ + { + "status": 0, + "msg": "ok", + "action": "set", + "type": "string", + "name": "phone", + "key": "3101", + "list_sessions_str": [ + "{\"empty\":true}" + ] + } + ] +*/ + "bot_sessions": [ + { + "status": 0, + "msg": "ok", + "action": "set", + "type": "string", + "key": "3101", + "list_sessions_str": [ + "{\"empty\":true}" + ] + } + ], + //////////用new_bot_session的话,请求也会带new_bot_session下来,这是新的session机制,协议简单点 @zhanggang + "new_bot_session" :{ + "value":"{\"empty\":true}",//需要写入到session中的内容 + "expire":0,//这个Session的过期时间 + }, + /////////////////////////////// + "decision_sessions": [ + { + "status": 0, + "msg": "ok", + "action": "set", + "type": "string", + "key": "3101", + "list_sessions_str": [ + "{\"empty\":true}" + ] + } + ], + //可选,默认为true,如果为false,客户端应该立即进入收听用户query的状态,不用重新唤醒 + "should_end_session":false, + +} + +``` + +所以,极简单情况下(没有多轮,没有使用da结果),bot可以只返回以下结构 +```javascript +{ + "status": 0, + "msg": "ok", + "data": { + "result_list": [ + { + //内容质量得分,可选 + "confidence": 100, + //bot的id,必须有 + "source_type": "phone", + //真正拼的消息其实是这个content字段,现在对外返回的resource、directives等字段都放在这个里面,和result_list平级,下一段详细讲这个content + "content": "{\"result_list\":[{\"result_content\":{\"answer\":\"<SYSTEM-NAME>为你查看联系人“张岩”\"},\"result_type\":\"txt\",\"source_type\":\"phone\",\"source_sub_type\":\"contact\",\"voice\":\"<SYSTEM-NAME>为你查看联系人“张岩”\"}],\"type\":\"server\",\"generator\":\"phone_function\",\"user_id\":\"3101\"}", + //会用于us排序的字段,为了让排序策略起作用,尽可能传一下 + "stategy_middle_data": { + "bot_intent":{ + "query":"raw query" ////请求的query,如果有bot_intent,这个就必须有 + "query_score":100 ////和需求的匹配度,可选 + }, + "raw_answer": [ + { + "title": "", + "subtitle": "", + "answer": "<SYSTEM-NAME>为你查看联系人“张岩”", + "url": "" + } + ] + } + } + ] + }, + //可选,默认为true,如果为false,客户端应该立即进入收听用户query的状态,不用重新唤醒 + "should_end_session":false +} + +``` + +#### 和策略相关的字段 + * data.result_list[].stategy_middle_data.bot_intent.query_score,取值0-100 ,标识内容的质量 + * data.result_list[].confidence,取值0-100 ,标识和query的匹配度 + +#### 正常返回的字段中,content字段的解释 + +.data.result_list[].content字段,是一个json_encode后的字符串 + +下面是这个json展开后的结构 + +内部可以加入新协议的字段,如resource、speech、views等等,但一定要有一个result_list。 + * 如果有传views、speech、resource等字段,result_list的内容可以随意,不会在新的输出接口中生效 + * 如果不传views、speech、resource等字段,api2.0接口输出时,会把result_list按一定规则转换成这些新字段 + * views、speech、resource等字段的数据结构,参见[度秘api2.0文档](api/response.md) + * 老的result_list内部的详细格式,可参考[度秘api1.0文档](http://agroup.baidu.com/duer/md/article/17301),主要是定义了result_list可以放的卡片格式 + +```javascript +{ + //result_list是老的结构,现在无论如何要传一个 + "result_list": [ + { + "result_content": { + "answer": "<SYSTEM-NAME>为你查看联系人“张岩”" + }, + "result_type": "txt", + "source_type": "phone", + //可选,用于统计 + "source_sub_type": "contact", + //语音播报的内容,可选 + "voice": "<SYSTEM-NAME>为你查看联系人“张岩”" + } + ], + //可选,内容见api2.0接口 + views:[], + //可选,内容见api2.0接口 + resource:{}, + //可选,内容见api2.0接口 + speech:{}, + //可选,内容见api2.0接口 + directives:{}, + //可选,内容见api2.0接口 + hint:[], + //可选,最好是传下来的nlu数据里选一个返回,内容见api2.0接口 + nlu:{}, + "type": "server" +} +```
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/OPENAPI_README.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,15 @@ +### 目录 +<!--目录--> + * [接入指导](tutorial.md) + * [Sdk相关](sdk/index.md) + * Api 参考 + * [概览](api/overview.md) + * [请求字段解释](api/request.md) + * [响应字段解释](api/response.md) + * 端能力 + * [AudioPlayer](directives/AudioPlayer.md) + * [Speaker](directives/Speaker.md) + * [SpeechSynthesizer](directives/SpeechSynthesizer.md) + * [其他](directives/) + * [Skill介绍](Skills.md) +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/Skills.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,51 @@ +# Skills + +## Table of Contents + + + * [Skills](#skills) + * [Table of Contents](#table-of-contents) + * [下游服务介绍](#下游服务介绍) + + +## 下游服务介绍 + +bot_id|描述|测试query +------|----|--------- +[aries_general](bot/information_genernal.md)|通用信息查询|周杰伦是谁 +[life_common](bot/life_common.md)|生活服务;鲜花、美容、理发、导航、周边、路况|附近堵车么;故宫在哪里;附近的饭馆 +restaurant_bot|美食服务|北京哪里的烤鸭好吃 +[remind](bot/remind.md)|提醒、闹钟|5分钟之后提醒我 +[alerts](bot/alerts.md)|闹钟、计时器|5分钟之后提醒我 +recommend_service_wireless|笑话、新闻|讲个笑话 +sysprofile_service|系统画像(可根据端类型自定义返回内容)|你是什么星座的 +[phone](bot/phone.md)|电话指令、打开app、网页、通信录、我的位置| +movie_satisfy|电影|正在上映的电影 +o2o_satisfy|外卖|帮我叫个外卖 +[texi_order](bot/texi_order.md)|打车|我要打车 +[image_satisfy](bot/image_satisfy.md)|图片搜索(多模sdk)|(用多模sdk上传图片) +duer_gaokao_server|高考志愿填报|我要报志愿;北京650分能上什么大学 +drama_satisfy|电视剧|琅琊榜 +travel_server|旅游,景点,hi周末|最近有什么演唱会? +recharge|手机充值(必须登录)|帮我充值话费 +online_shopping|在线购物|网购高露洁 +hotel|酒店|附近的酒店 +sport_server|部分NBA功能?| +nba_search|NBA|nba +baojie|保洁(必须登陆)|帮我找个保洁 +[duer_weather](bot/duer_weather.md)|天气|今天天气怎么样 +talk_service|开放集合聊天|(兜底服务) +doudi_server|聊天封闭集合兜底|(兜底服务) +[smart_tv](bot/smart_tv.md)|电视(有电视剧)|我想看琅琊榜 +[speaker_hardware](bot/speaker_hardware.md)|扬声器控制|声音大一点 +[audio_news](bot/audio_news.md)|新闻|英特尔的最新新闻 +[audio_music](bot/audio_music.md)|音乐|放一首周杰伦的歌 +[audio_unicast](bot/audio_unicast.md)|点播垂类(有声资源)|播放郭德纲的相声 +[audio_joke](bot/audio_joke.md)|笑话|给我讲个笑话 +audio_scene|场景化垂类|进入助眠模式 +[audio_live](bot/audio_live.md)|直播垂类|播放北京文艺广播 +[fridge](bot/fridge.md)|冰箱指令| +[cookbook](bot/cookbook.md)|菜谱| +scene_satisfaction|明星|周杰伦的最新专辑 + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/api/directives_design.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,24 @@ +# directives的交互设计参考 + +## directives的执行顺序 +一条返回值的结构体,包含一个directives数组 + + * 顺序执行directives数组中的指令 + * SpeechSynthesizer.Speak 指令,需要播报完了再取下一条 + * udioPlayer的指令,操作后台的播放器进程,执行时间会很短,执行完后立即取下一条。 + * Speaker等其它指令,block直接执行。 + +如果收到一条新的返回值结构体,停止之前的directives数组的执行(如果正在播报SpeechSynthesizer.Speak,停止播报),丢弃尚未执行的directives,执行新返回的directives数组。但是AudioPlayer的播放列表保持不变 + + + +## 声音内容输入输出的分类: + +Channel: + + * Alerts:闹钟Alerts + * Dialog:用户对话,包括SpeechRecognizer, 不带channel="Content"的SpeechSynthesizer + * Content:播放的内容,包括AudioPlayer指令的内容,带有channel="Content"的SpeechSynthesizer指令的内容 (会被用来读新闻,读故事等) + +原则上,声音输入输出的优先级应该是Alerts > Dialog > Content +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/api/overview.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,32 @@ +# API概览 + +## Table of Contents + + + * [API概览](#api概览) + * [Table of Contents](#table-of-contents) + * [整体格式说明](#整体格式说明) + * [架构描述](#架构描述) + * [概念解释](#概念解释) + + +## 整体格式说明 + +### 架构描述 +![dumi_system](http://g.hiphotos.baidu.com/xiaodu/pic/item/8718367adab44aed80c9d366ba1c8701a08bfba9.jpg) + +### 概念解释 + +概念名字 | 概念解释 +------------ | ------------- +bot | 字面理解就是机器人,是真正负责返回结果的度秘平台子服务 +bot列表(服务列表) | 每个合作方可以选择自己想要使用的bot +nlu | Natural Language Understanding (自然语言理解),可以理解为把用户的自然语言query转换为结构化数据的服务 +cuid | 设备id,它与用户id是独立的概念 +user_id | 用户id,它与设备id是独立的概念 +appid | 每个合作方的id +appkey | 每个合作方的密钥 +appqps | 合作方的每秒访问次数限制 +appqps | 合作方的每天访问次数限制 + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/api/request.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,210 @@ +# 请求字段解释 + +## Table of Contents + + + * [请求字段解释](#请求字段解释) + * [Table of Contents](#table-of-contents) + * [请求示例](#请求示例) + * [请求值(request)中数据格式分块详细说明](#请求值request中数据格式分块详细说明) + * [客户端能力相关(device_interface, device_event, device_status)](#客户端能力相关device_interface-device_event-device_status) + * [请求字段中,.supported_content_type字段的解释](#请求字段中supported_content_type字段的解释) + + +### 请求示例 + +给服务端发请求内容。使用sdk的用户,无需关注此节,因为sdk的请求不用手动拼 + +```javascript +{ + //==========以下是开放sdk会有的字段======================== + "appid": "650DEBC2B99A4dA4", + "appkey": "2F4B662AF2064323A16122D702160F15", + "sdk_ui": "no", + "sdk_init": "no", + "appname": "com.baidu.duersdk.xiaomi", + "from_client": "sdk", + //======================================================== + //string 用户id, 如有Cookie则不需要此字段 + "request_uid": "string", + //string 输入来源,-1-回访引导请求,0-语音输入,1-键盘输入,2-编辑query,3-引导query,4-重新发送,6-新用户回访引导请求,7-用户上传图片,8-点击导航图标输入,9-applink方式传参数发送,10-自动回复,11-未知,12-对话过程中的特殊回访,13-手百插件新用户引导浮层点击,14-feed流拉取,21-心跳,30-客户端event + //标识用户发这个请求的方法,参见文档 http://agroup.baidu.com/dbo/md/article/49113 + "query_type": "string", + //默认为空,类型string, 多个以逗号分隔, 为空可以不填该字段 + "hint_id": "用户选中hint的id" + //string 机器id + "CUID": "string", + //double 经度 + "longitude": double, + //double 纬度 + "latitude": double, + //可选,如果经纬度是来自于缓存,增加location_type:cache,add by 王芃、吴芮生2016-08-11 + "location_type": "wgs84", + //当前定位数据坐标系统,取值为:”bd09ll”(百度球面坐标)或”wgs84”(GPS球面坐标)或”bd09mc”(百度墨卡托坐标)。默认是wgs84 + "location_system":"wgs84" + //如果用户是语音输入的,存语音输入的id + "speech_id":"xxxx", + //string 请求类型,-1-手百插件注册(query为空), 0-输入框输入,1-鼠标点击输入,2-查看聊天历史,3-写入聊天历史,4-注册用户信息,5-查看用户信息,6-查看熊成长信息,7-更改熊身上装备,8-检查是否可以修改昵称, 9-app从后台恢复 + "request_type": "string", + //string 请求来源,0-和熊对话,1-框中输入,2-主动触发熊,3-首页, 4-feed流,,5-客户端选择操作类型请求 + "request_from": "string", + //string 服务标识 + "sample_name": "bear_brain_wireless", + //string 客户端生成的消息id + "client_msg_id": "string", + //int 调试标记,1-测试消息 0或字段不存在表示线上消息 + "debug": int, + //int 消息模式, 1-3D演示模式 0或字段不存在为默认状态 + "mode": int, + //操作系统, 可选,android/ios + "operation_system": "ios", + "operation_system_version":"7.0.0", //操作系统版本号(目前只有对外sdk有该字段),ios取[[[UIDevice currentDevice] systemVersion] floatValue],安卓取android.os.Build.VERSION.RELEASE + "device_brand":"apple", //设备品牌 (目前只有对外sdk有该字段),ios写死"apple",安卓取android.os.Build.BRAND + "device_model":"iphone 6s", //设备具体型号 (目前只有对外sdk有该字段)ios取 设备型号字符串 sysctlbyname("hw.machine", name, &size, NULL, 0);,安卓取android.os.Build.MODEL + "device_interface":{ + "Alerts":{}, + "AudioPlayer":{ + "no_pause":1, + "no_seek":1, + }, + "PlaybackController":{}, + "Speaker":{}, + "Settings":{}, + "SpeechSynthesizer":{}, + "System":{} + }, + "device_event":{ + //query_type==30 的时候才会有 device_event + "header": { + "namespace": "AudioPlayer", + "name": "PlaybackStarted", + "message_id": "message_id-1344" + }, + "payload": { + //AudioPlayer里可能出现的payload + "token": "156", + "offset_ms": 10000 + //Speaker里可能出现的payload + "volume": 1, + //SpeechSynthesizer可能出现的payload + "token": "156", + "type": "{{Text/SSML}}", + "content": ["xxxx1", "xxxx2"], + "speak_behavior": "REPLACE_ALL", + "should_get_next_speech": true + } + }, + "device_status":{ + "SpeechSynthesizer":{ + "token":"xxx",//正在播放的音频流id + "offset_ms":20000,//播放到多少ms了 + "player_activity":"PLAYING / FINISHED" + }, + "Speaker":{ + "volume": 50, + "muted": false + }, + "AudioPlayer":{ + "token":"xxx",//正在播放的音频流id + "offset_ms":20000,//播放到多少ms了 + "player_activity":"IDLE PAUSED PLAYING BUFFER_UNDERRUN FINISHED STOPPED" + }, + //如果用户界面上有一些可操作元素,需要做语音控制,可以传这个字段 + "UiControl":{ + "items":[ + {"label":"下一个","url:"xxapp://next"}, + {"label":"暂停”,url:"xxapp://pause"}, + {"label":”停止”,url:"xxapp://stop"}, + ], + }, + //可以传被控制的设备 + "SmartHomeControl":{ + "target_devices":[ + {"name":"客厅的电视","id":"xxxxxx","type":"duer_iot"},//type、device_id可选 + ], + }, + }, + //app_ver 版本号,2.0.0之后返回现在的v2格式 + "app_ver": "2.0.0", + "searchbox_ver":"8.0",//宿主版本号,只存在于插件形式,比如手百、地图、浏览器 + //string 可选,默认值是"txt",可用的值现在有txt / image,消息内容的类型,会决定服务端如何解析request_query + "content_type": "image", + //int 可选,content_type=='image'的时候,表示图片的高度 + "image_height": int, + //int 可选,content_type=='image'的时候,表示图片的宽度 + "image_width": int, + //string 请求query + "request_query": "query", + //数组,标志客户端支持的内容类型,可选,如果不传,认为客户端都支持 + "supported_content_type":["audio","image","video","webview","speech"], + + //可选,如果是一个控制指令,可以传target_device_id,这个字段会被透传给bot,作为调用设备云的硬件id + //未来会变成不传这个字段,靠query解析和设备管理理解出这个字段 + "target_device_id":"xxxxxx", +} +``` + +### 请求值(request)中数据格式分块详细说明 + +#### 客户端能力相关(device_interface, device_event, device_status) + + * device_interface 标识客户端有哪些能力 + * AudioPlayer + * no_pause 说明客户端不支持暂停、继续 + * no_seek 说明客户端不支持快进、快退、定位播放 + * SpeechSynthesizer + * Speaker + * device_event 客户端事件的类型和内容。只有query_type==30的时候,才会有device_event,此时会忽略query字段(没有文本query),比如下面的端能力,里面都有相关事件的定义 + * [AudioPlayer](../directives/AudioPlayer.md) 音乐播放 + * [Speaker](../directives/Speaker.md) 扬声器控制、设置 + * [SpeechSynthesizer](../directives/SpeechSynthesizer.md) 语音播报(TTS) +例如: + +```javascript + "device_event":{ + "header": { + "namespace": "AudioPlayer", + "name": "PlaybackStarted", + "message_id": "message_id-1344" + }, + "payload": { + "token": "156", + "offset_ms": 10000 + } + } +``` + + * device_status 客户端的当前状态,按能力分类(每种端能力有每种端能力的状态) + * AudioPlayer + * SpeechSynthesizer + * Speaker +例如: + +```javascript + "device_status":{ + "SpeechSynthesizer":{ + "token":"xxx",//正在播放的音频流id + "offset_ms":20000,//播放到多少ms了 + "player_activity":"PLAYING / FINISHED" + }, + "Speaker":{ + "volume": 50, + "muted": false + }, + "AudioPlayer":{ + "token":"xxx",//正在播放的音频流id + "offset_ms":20000,//播放到多少ms了 + "player_activity":"IDLE / PAUSED / PLAYING / BUFFER_UNDERRUN / FINISHED / STOPPED" + } + } +``` + * target_device_id 可选,如果是一个控制指令,可以传target_device_id,这个字段会被透传给bot,作为调用设备云的硬件id + * 未来会变成不传这个字段,靠query解析和设备管理理解出这个字段 + +#### 请求字段中,.supported_content_type字段的解释 +表示了端支持的内容类型,bot应该召回端支持的内容类型,**不召回**端不支持的内容 + * audio + * video + * image + * webview + * speech
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/api/response.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,438 @@ +# 响应字段解释 + +## Table of Contents + + + * [响应字段解释](#响应字段解释) + * [Table of Contents](#table-of-contents) + * [正常返回的结果](#正常返回的结果) + * [常见的错误返回](#常见的错误返回) + * [返回值(response)中数据格式分块详细说明](#返回值response中数据格式分块详细说明) + * [bot_id、bot_meta](#bot_idbot_meta) + * [views](#views) + * [文本卡片](#文本卡片) + * [图文卡片](#图文卡片) + * [图片卡片](#图片卡片) + * [resource](#resource) + * [天气](#天气) + * [新闻](#新闻) + * [音乐](#音乐) + * [speech](#speech) + * [directives](#directives) + * [AudioPlayer](#audioplayer) + * [Speaker](#speaker) + * [SpeechSynthesizer](#speechsynthesizer) + * [SpeechRecognizer](#speechrecognizer) + * [Extension](#extension) + * [hint](#hint) + * [nlu](#nlu) + * [格式说明](#格式说明) + * [包含query解析结果的结构化数据](#包含query解析结果的结构化数据) + * [以下是跑出来的一批nlu数据的例子](#以下是跑出来的一批nlu数据的例子) + + +### 正常返回的结果 + +以下是一次典型请求中,sdk(客户端)收到的完整json数据 + +```javascript +{ + "status":0, //0 表示成功,其他值表示失败 + "msg":"ok", //错误状态文本 + "se_query":"我要听周杰伦的歌", //用户请求的query + "logid":"xxxx1234354", //日志查询用的logid + "id":"id12334235", //消息id + "user_id":"", //请求的用户id + "cuid":"", //请求的设备id + "time":1482226019, //当前的服务端时间戳 + "client_msg_id": "string", //客户端上报的请求msg id,如果是回复用户的某个请求的消息,可以用这个字段串起来 + "speech_id": "string", //如果是个语音请求,这是语音的id(请求中的speech_id字段,2合一的get参数sn) + "need_passport_login": false, //如果为true,客户端应该调用百度passport登录接口 + "result":{ + "bot_id":"duer_music", //返回结果的bot的id,如果没有任何垂类服务返回,bot_id== NO_RESULT + "bot_meta":{ //下游bot元数据 + "description":"返回音乐类结果", // 文字描述 + "version":"1.0.0", //版本 + "type":"音乐" //TODO,bot类型见pm给的分类 + }, + "views":[ //显示用的数据,一个结果里可包含多个卡片 + { + "type":"list", //卡片类型,只有txt,list,image三种类型 + "list":[ + { + "title": "东方破", + "image": "http://nodeapi.cloudfoundry.com/qrcode.jpg", + "url": "http://nodeapi.cloudfoundry.com/" + }, + { + "title": "双截棍", + "image": "http://nodeapi.cloudfoundry.com/qrcode.jpg", + "url": "http://nodeapi.cloudfoundry.com/" + } + ] + } + ], + "directives":[ //指令,用于控制给客户端、目标硬件下达命令,可选字段,一个结果可包含多条啊指令 + { + "header": { //指令的名字 + "namespace": "AudioPlayer", + "name": "Play" + }, + "payload": { //指令的参数 + "play_behavior": "REPLACE_ALL", + "audio_item": { + "audio_item_id": "156", + "stream": { + "url": "http://yinyueshiting.baidu.com/data2/music/124088643/124088643.mp3?xcode=57462f29cfc176f86a37d80a2c02fc5b", + "stream_format": "AUDIO_MP3", + "offset_ms": 0, + "token": "156", + "progress_report_interval_ms": 10000 + } + } + } + } + ], + + "nlu": { //query解析的结果 + "domain": "music", + "intent": "music", //domain + intent确定一种解析结果的类型 + "slots": { //从query中提取出来的槽位信息 + "action_type":"1", + "singer": "周杰伦" + } + }, + "resource":{ //数据资源,可选字段 + "type":"music_ref",//资源类型,目前已经有music/news/weather等资源类型 + "data":{ + "api": { + "method": "GET", + "url": "http: //s.xiaodu.baidu.com/v20161223/resource/music?user_id=888" + } + //以上地址,可以增加page参数来翻页,如 http://s.xiaodu.baidu.com/v20161223/resource/music?user_id=888&page=2 + //抓取以上api地址后会返回如下格式 +/* +{ + "status": 0, + "code": null, + "data": { + "page": 1, + "total_page": 5, + "list": [ + { + "duration": "238", + "name": "恋红尘", + "alias": "", + "singer_name": "祁隆,彭丽嘉", + "all_singer_name": "", + "genre": "流行", + "tag": "好听,新歌,网络歌曲", + "language": "", + "original_singer": "", + "composer": "", + "lyricist": "", + "url": "http://music.baidu.com/song/271665582?fm=altg_new3", + "same_name_url": "http://music.baidu.com/search?fm=altg_new3&key=%E6%81%8B%E7%BA%A2%E5%B0%98", + "streaming_vedio_url": "http://zhangmenshiting.baidu.com/data2/music/a1d4eca5675d21e6e0b3dad002de5c1d/271665733/271665733.mp3?x +code=2e387ebc099d9e5aa0d51cfc739c1004", + "head_image_url": "http://qukufile2.qianqian.com/data2/pic/25b1faff5bf89f84b6491593e31381ed/271665166/271665166.jpg", + "album_name": "恋红尘", + "album_url": "", + "score": "0", + "publish_time": "2016-09-20", + "publish_company": "华宇世博", + "is_need_pay_listen": "0", + "from_site": "1", + "hot": "237391" + }... + ] + } +} +*/ + } + }, + 'should_end_session':false, //默认为true,如果为false,客户端应该立即进入收听用户query的状态,不用重新唤醒 + "speech": { //TTS播报用的数据 + "type": "Text", //有SSML和Text两种类型 + "content": "为您播放周杰伦的歌曲", + "reprompt": "" //可选,should_end_session==false的时候,会自动进入语音识别状态,8s后如果用户都不说话,客户端会用tts播放一个短提示,reprompt就是短提示的内容 + } + } +} + +``` + +### 常见的错误返回 + +返回值 | 含义 +---------- | ------------- +status:1,msg: appid unvalid | appid无效 +status:2,msg: appkey unvalid | appkey无效 +status:3,msg: appqps warning | appqps前一天峰值警告 +status:4,msg: appqps refuse | appqps拒绝 +status:5,msg: appqpd warning | appqpd前一天峰值警告 +status:6,msg: appqpd refuse | appqpd拒绝 +status:7,msg: sericelist empty | 请求的服务列表未配置 + +### 返回值(response)中数据格式分块详细说明 + +#### bot_id、bot_meta + +bot 是真正负责返回结果的度秘平台子服务,每条结果中会带有真正服务的bot的id和meta信息 +下面的表格是现有的bot及其说明 + +bot_id | 说明 +------ | ------- +phone | 电话服务 +remind | 提醒服务 +recommend_service_wireless source_sub_type: joke | 笑话 +duer_weather | 天气服务 +music | 音乐服务 +restaurant_bot | 美食服务 +life_common | 生活服务(地图导航) +sac | 火车航班,查限行 +aries_general aries_guide aries_dqa kg_service | 通用信息(翻译) +sysprofile_service | 系统画像 +image_satisfy | 图搜服务 + + +#### views +返回展示卡片数据,必选字段。一次可返回一个或多个卡片。 +一共有三种类型: + +##### 文本卡片 +只能返回一段文本 +```javascript +{ + "type":"txt", + "content":"为你推荐如下热门资讯", + "url":"http://www.baidu.com" //可选字段 +} +``` + +##### 图文卡片 +```javascript +{ + "type":"list", + "list":[ + { + "title": "你来我家接我吧", + "summary": "这是女神与高富帅之间的对话", ///可选字段 + "image": "http://nodeapi.cloudfoundry.com/qrcode.jpg",//可选字段 + "url": "http://nodeapi.cloudfoundry.com/" + }, + { + "title": "你来我家接我吧", + "summary": "这是女神与高富帅之间的对话", //可选字段 + "image": "http://nodeapi.cloudfoundry.com/qrcode.jpg",//可选字段 + "url": "http://nodeapi.cloudfoundry.com/" + } + ] +} +``` + +##### 图片卡片 +可一次返回多张图片,可选缩略图 +```javascript +{ + "type": "image", + "list": [ + { + "src":"http://c.hiphotos.baidu.com/image/pic/item/7af40ad162d9f2d38d7056c8acec8a136327ccb0.jpg", + "thumb":"http://c.hiphotos.baidu.com/image/pic/item/7af40ad162d9f2d38d7056c8acec8a136327ccb0.jpg" //可选字段 缩略图 + }, + { + "src":"http://b.hiphotos.baidu.com/image/pic/item/b21bb051f8198618df86c5424eed2e738ad4e637.jpg", + "thumb":"http://c.hiphotos.baidu.com/image/pic/item/7af40ad162d9f2d38d7056c8acec8a136327ccb0.jpg" //可选字段 缩略图 + }, + { + "src":"http://c.hiphotos.baidu.com/image/pic/item/83025aafa40f4bfbc9c817b9074f78f0f63618c6.jpg", + "thumb":"http://c.hiphotos.baidu.com/image/pic/item/7af40ad162d9f2d38d7056c8acec8a136327ccb0.jpg" //可选字段 缩略图 + } + ] +} + +``` + +#### resource +根据用户的意图和度秘服务的能力,在一些请求里会返回复杂的结构化数据,用于客户端的特殊逻辑和展示,现有的resource类型有以下几类,还在不断增加中 + +##### 天气 +```javascript +"resource":{ + "type":"weather", + "data":{ + "city": "北京", + "current_temp": "-1℃", //实时温度,只有query查询今天的天气的时候才会有值,如“今天天气怎么样” + "pm25": "426", //实时pm2.5,只有query查询今天的天气的时候才会有值,如“今天天气怎么样” + "temp": "-3℃~5℃", //当天的温度 + "time": "周二 12月20日", //查询目标时间的文字描述 + "weather": "雾",//天气的文字描述 + "weather_all": "雾,-3℃~5℃,微风", //完整的天气描述 + "wind": "微风", + "weather_info": [//未来5天的天气数据 + { + "current_temp": "-1℃", + "icon": "http://s1.bdstatic.com/r/www/aladdin/img/new_weath/bigicon/4.png", + "pm25": "426", + "pm_level": "严重污染", + "temp": "-3℃~5℃", + "time": "周二 12月20日", + "weather": "雾", + "wind": "微风" + }, + { + "icon": "http://s1.bdstatic.com/r/www/aladdin/img/new_weath/icon/7.png", + "temp": "-3℃~3℃", + "time": "周三 12月21日", + "weather": "霾", + "wind": "微风" + }, + { + "icon": "http://s1.bdstatic.com/r/www/aladdin/img/new_weath/icon/1.png", + "temp": "-5℃~6℃", + "time": "周四 12月22日", + "weather": "晴", + "wind": "北风3-4级" + }, + { + "icon": "http://s1.bdstatic.com/r/www/aladdin/img/new_weath/icon/1.png", + "temp": "-6℃~3℃", + "time": "周五 12月23日", + "weather": "晴转多云", + "wind": "北风微风" + }, + { + "icon": "http://s1.bdstatic.com/r/www/aladdin/img/new_weath/icon/5.png", + "temp": "-5℃~3℃", + "time": "周六 12月24日", + "weather": "多云转霾", + "wind": "北风微风" + } + ] + } +}, +``` + +##### 新闻 + +一次查询会返回多条新闻,现在是10条,新闻内容(content字段)如果太长会被截断 +```javascript +"resource":{ + "type":"news", + "data":{ + "list":[ + { + "id":"xxx1234bbb", + "title":"河北首次启动区域红色应急响应 雾霾笼罩", + "summary":"河北首次启动区域红色应急响应 雾霾笼罩", + "content":"霾是什么?雾是什么?都是怎么形成的?它们的关系是什么?气温丶湿度丶风力丶风向丶地形丶地表丶温湿度丶灰尘丶烟尘丶粉尘丶扬尘那个危害更大,这些都应当弄清了,再谈霾和雾,不要把霾字前加雾字。这本来就是两种截然不同的两种物质。只是它们互相影响而已。把它们混为一谈。就是错的引导。霾在四五年前就已经开始了。只是越来越严重而已。它是随着汽车进入家庭而伴生的。", //新闻内容 + "url":"http://headline.baidu.com/doc/detail?app_from=dumi_news&url_key=http%3A//news.163.com/photoview/00AP0001/2216510.html", + "image" : "http://ztd00.photos.bdimg.com/ztd/whfpf%3D160%2C120%2C50%3Bq%3D70/sign=1a96a9f0f41f4134e062563e4322a4fc/d000baa1cd11728bfb98b831c1fcc3cec3fd2c6f.jpg", + "thumb":"http://ztd00.photos.bdimg.com/ztd/whfpf%3D160%2C120%2C50%3Bq%3D70/sign=1a96a9f0f41f4134e062563e4322a4fc/d000baa1cd11728bfb98b831c1fcc3cec3fd2c6f.jpg", + "pubtime":"2016-12-20 20:01:01" + }, + { + "id":"xxx1234bbb", + "title":"河北首次启动区域红色应急响应 雾霾笼罩", + "summary":"河北首次启动区域红色应急响应 雾霾笼罩", + "content":"霾是什么?雾是什么?都是怎么形成的?它们的关系是什么?气温丶湿度丶风力丶风向丶地形丶地表丶温湿度丶灰尘丶烟尘丶粉尘丶扬尘那个危害更大,这些都应当弄清了,再谈霾和雾,不要把霾字前加雾字。这本来就是两种截然不同的两种物质。只是它们互相影响而已。把它们混为一谈。就是错的引导。霾在四五年前就已经开始了。只是越来越严重而已。它是随着汽车进入家庭而伴生的。", + "url":"http://headline.baidu.com/doc/detail?app_from=dumi_news&url_key=http%3A//news.163.com/photoview/00AP0001/2216510.html", + "image":"http://ztd00.photos.bdimg.com/ztd/whfpf%3D160%2C120%2C50%3Bq%3D70/sign=1a96a9f0f41f4134e062563e4322a4fc/d000baa1cd11728bfb98b831c1fcc3cec3fd2c6f.jpg", + "thumb":"http://ztd00.photos.bdimg.com/ztd/whfpf%3D160%2C120%2C50%3Bq%3D70/sign=1a96a9f0f41f4134e062563e4322a4fc/d000baa1cd11728bfb98b831c1fcc3cec3fd2c6f.jpg", + "pubtime":"2016-12-20 20:01:01" + } + ] + } +}, +``` + +##### 音乐 +[音乐垂类的resource说明](../bot/audio_music.md#resource-部分的解释说明) + +#### speech +目前仅返回Text类型,SSML类型在开发中,[SSML的说明](https://www.w3.org/TR/speech-synthesis/) +```javascript +"speech": { + "type": "Text", + "content": "为您播放周杰伦的歌曲" +} +``` + +#### directives +基础结构: +```javascript +"directives":[ //指令,用于控制给客户端、目标硬件下达命令,可选字段,一个结果可包含多条啊指令 + { + "header": { + "namespace": "",//指令的分类 + "name": "" //指令的名字 + }, + "payload":{ //指令的参数 + } + } +] +``` +现在有以下namespace指令可能返回 + +##### AudioPlayer + * [AudioPlayer](../directives/AudioPlayer.md) 音乐播放相关指令 + +##### Speaker + * [Speaker](../directives/Speaker.md) 扬声器控制、设置相关指令 + +##### SpeechSynthesizer + * [SpeechSynthesizer](../directives/SpeechSynthesizer.md) 语音播报(TTS)相关指令 + +##### SpeechRecognizer + * 只有部分客户端支持的指令 + * [SpeechRecognizer](../directives/SpeechRecognizer.md) 语音识别相关指令 + +##### Extension + * 只有部分客户端支持的指令 + * [Extension](../directives/Extension.md) 部分客户端会收到的扩展指令 + + +#### hint +用户接下去可能会输入的query,可以用来给用户提示,辅助用户输入 +比如下面的例子是“讲个笑话”这个query返回的hint +```javascript +"hint":["再来一个", "文字笑话", "图片笑话"], +``` + + +#### nlu + +##### 格式说明 + +```javascript +"nlu": { //query解析的结果 + "domain": "music", + "intent": "music", //domain + intent确定一种解析结果的类型 + "slots": { //从query中提取出来的槽位信息 + "action_type":"1", + "singer": "周杰伦" + } +} +``` + +##### 包含query解析结果的结构化数据 + +描述|domain|intent|slots(可用的槽位)|example +----|------|------|-----------------|------- +火车票|22|22|end_point(终点站), start_point(起点站), search_type(如:高铁), start_time(时间)|给我买张到武汉的高铁票 +天气|duer_weather|sys_weather|loc_city(城市), loc_county(国家), loc_province(省), time(时间)|北京明天天气如何 +地址查询类需求|lbs|poi|poi(地址字符串)|射阳在哪儿 +周边查询类需求|lbs|nearby|start_point(出发地),start_point_bd_la(出发地纬度),start_point_bd_lo(出发地经度),user_location_city(用户当前所在城市),end_point(目的地),travel_type(出行方式),坐标类型为bd09ll(百度经纬度坐标)|附近的飞机场 +导航查询类需求|lbs|navigation/route/traffic_condition|start_point(出发地),start_point_bd_la(出发地纬度),start_point_bd_lo(出发地经度),user_location_city(用户当前所在城市),end_point(目的地),travel_type(出行方式),坐标类型为bd09ll(百度经纬度坐标)|导航从北京到上海 +音乐类需求|music|music|action_type(0. 关闭 1. 打开 2. 播放 3. 暂停 4. 下一首 5. 上一首 6. 换一首 7. 重播), song(歌名), singer(歌手), music_language(语言), music_emotion(情感,如悲伤、欢快等), music_tag, music_type(嘻哈、摇滚、儿歌等)| +让度秘唱歌,类似调戏|music|music_sing|CommandAccepter, action_type(0. 关闭 1. 打开 2. 播放 3. 暂停 4. 下一首 5. 上一首 6. 换一首 7. 重播), song(歌名), singer(歌手)| +联系人查询需求|phone|contact|action_type(1:查看 0:新建 2:发送), pinyin_for_view(要查看的联系人的拼音), name_for_view(要查看的联系人的名字), pinyin_to_send(要发送的联系人的拼音), name_to_send(要发送的联系人的名字)|告诉我张凤仪的电话号码, 庞翔宇的电话号码发给张凤仪 +打开网址|phone|open_website|action_type, name, website_url|携程火车票 +发短信|phone|sms|content(短信内容), number(目标号码), name(目标姓名), pinyin(目标姓名拼音)|短信发给15140559455 +提醒、闹钟|remind|remind|action, event_title, intent, remind_time, remind_type_message, remind_type_phone, remind_type_dumi, remind_type_clock, remind_time_type, remind_time_value, remind_time_data, status|设置提醒每天晚上9点半洗衣服。 +美食、团购|restaurant_bot|find|catetag, fragment, location, sortby, cuisine, crowd, groupon|附近有什么好吃的饭馆 + +##### 以下是跑出来的一批nlu数据的例子 + +[Examples](../nlu/example.md)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/bot/alerts.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,645 @@ +# Alerts 设备端能力要求 + +## 连接网络 +用户使用设备创建、删除Alerts,需要接受DCS(duer conversation service)下发的Directive去创建、删除Alert,创建、删除失败后必须向DCS上报Event。 + +## Alerts创建后在设备离线后可以正确触发 +例如用户创建第二天早上8点的alarm后,设备断网,第二天早上8点alarm需要准时触发。 + +## 支持本地重建Alerts +设备重启后需要能够在本地重建Alerts,这种场景下不需要向DCS上报Event。 + +## 支持NTP网络时间协议 +DCS Alerts下发Alerts都为标准时间戳,设备端需要支持NTP协议对齐时间。 + +# Alerts 流程 +## 基本Alerts流程 +![图片](http://bos.nj.bpc.baidu.com/v1/agroup/149b86d35ae902fa853a4eecaa8a5d6c57816155) +## 通过设备实体交互停止响铃流程 +![图片](http://bos.nj.bpc.baidu.com/v1/agroup/373bf9939c691a59d3e80079bae581a037b12135) +## 周期重复alarm流程 +![图片](http://bos.nj.bpc.baidu.com/v1/agroup/cec09e6dd874a76a2a83969c04a7e1f63888dfe4) +## 删除Alerts流程 +![图片](http://bos.nj.bpc.baidu.com/v1/agroup/3b13b8573f2ac6deab79333696f1a3c703bdb479) +## mateapp删除Alerts流程 +![图片](http://bos.nj.bpc.baidu.com/v1/agroup/015c147dc1ced884408d30e06711703f320ed251) + + +# Alerts接口协议 + +## 输出能力级别定义 +### all: 输出完整的Alerts能力 +完整能力输出包括qu解析、Alerts业务逻辑、数据存储。 + +### qu: 仅输出qu能力 +qu能力输出仅包括qu解析,接入端需要实现Alerts业务逻辑、数据存储。使用DCS管理需要将设备端Alerts详细数据通过device_status携带,且数据格式需是[duer约定格式](#alert_struct)。 + +## Alerts数据结构 +### <span id="alert_struct">AlertsStruct</span> +```javascript +AlertsStruct = { + "token": string,// 唯一标识 + "type": string,// Alert类型 TIMER|ALARM + "scheduled_time": string,// Alert触发时间,秒级时间戳 + "content": string, // Alert事件名称 + + // ####### 接入完整能力不要关注此字段######### + "extensions": ExtensionsStruct json, // 可选,额外信息,qu能力级别输出携带,例如接入完整能力的A音箱则没有该字段,接入qu能力的B手机助手则有该字段|mateapp携带 +} +``` +```javascript +ExtensionsStruct = { + "start_time": int, // 开始时间 + "content": string, // 事件名称 + "duration": int, // timer时长 + "repeat_type": string, // 重复类型 day|week|month|year + "repeat_week": int, // 可选,重复星期 从低位到高位表示星期一到星期日 + "repeat_month": int, // 可选,重复月 从低位到高位表示1~12月 + "repeat_year": string, // 可选, 重复年 12-1,8-2 + "special_calender": string, // 农历,lunar + "special_day": string, // 工作日, weekday +} +``` + + +## device_status Alerts +客户端请求DCS、上报Event需要携带Alerts device_status +```javascript +{ + "all_alerts": [ + AlertsStruct,// 见Alerts数据结构 + ], + // 正在活跃的Alerts + "active_alerts": [ + AlertsStruct,// 见Alerts数据结构 + ], +} +``` + +## Create +设备Alerts的本地创建,必须且只有在接受到DCS 的SetAlert Directive之后进行。 +### SetAlert Directive +DCS下发SetAlert Directive场景: +1、客户端通过语音创建alarm、timer +2、mateapp重新开启已经创建的alarm、timer +3、mateapp更新已经创建的alarm、timer + +```javascript + { + "header": { + "namespace": "Alerts", + "name": "SetAlert", + "message_id": string, + }, + "payload": AlertsStruct,// 见Alerts数据结构 + } +``` + +### SetAlertSucceeded Event +客户端在收到SetAlert Directive后成功创建Alert必须向DCS上报SetAlertSucceeded Event +```javascript +{ + "header": { + "namespace": "Alerts", + "name": "SetAlertSucceeded" + }, + "payload": { + "token": string,// 唯一标识 + } +} +``` + +### SetAlertFailed Event +客户端在收到SetAlert Directive后未成功创建Alert必须向DCS上报SetAlertFailed Event +```javascript +{ + "header": { + "namespace": "Alerts", + "name": "SetAlertFailed" + }, + "payload": { + "token": string,// 唯一标识 + } +} +``` + +## Delete +设备Alerts的本地删除,必须且只有在接受到DCS 的SetAlert Directive之后进行。 +### DeleteAlert Directive +DCS下发DeleteAlert Directive场景: +1、客户端通过语音删除alarm、timer +2、客户端通过语音停止响铃的alarm、timer +2、mateapp删除alarm、timer +3、mateapp暂停已经创建的alarm + +```javascript + { + "header": { + "namespace": "Alerts", + "name": "DeleteAlert", + "message_id": string, + }, + "payload":{ + "token": string,// 唯一标识 + } + } +``` + +### DeleteAlertSucceeded Event +客户端在收到DeleteAlert Directive后成功删除Alert必须向DCS上报DeleteAlertSucceeded Event +```javascript +{ + "header": { + "namespace": "Alerts", + "name": "DeleteAlertSucceeded" + }, + "payload": { + "token": string,// 唯一标识 + } +} +``` + +### DeleteAlertFailed Event +客户端在收到DeleteAlert Directive后未成功删除Alert必须向DCS上报DeleteAlertfailed Event +```javascript +{ + "header": { + "namespace": "Alerts", + "name": "DeleteAlertFailed" + }, + "payload": { + "token": string,// 唯一标识 + } +} +``` + +## Start and Stop +### AlertStarted Event +Alert到触发时间响铃必须向DCS上报AlertStarted Event +```javascript +{ + "header": { + "namespace": "Alerts", + "name": "AlertStarted" + }, + "payload": { + "token": string,// 唯一标识 + } +} +``` +### AlertStoped Event +Alert停止正在响铃的Alert必须向DCS上报AlertStoped Event +```javascript +{ + "header": { + "namespace": "Alerts", + "name": "AlertStoped" + }, + "payload": { + "token": string,// 唯一标识 + } +} +``` + + +## 前后台切换 +### AlertEnteredForeground Event +```javascript +{ + "header": { + "namespace": "Alerts", + "name": "AlertEnteredForeground" + }, + "payload": { + "token": string,// 唯一标识 + } +} +``` + +### AlertEnteredBackground Event +```javascript +{ + "header": { + "namespace": "Alerts", + "name": "AlertEnteredBackground" + }, + "payload": { + "token": string,// 唯一标识 + } +} +``` + +# Alarm输出schema +## 输出实例 + +### 创建实例 +```javascript +{ + "result": { + "bot_id": "alarm", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "directives":[ + { + "header": { + "namespace": "SpeechSynthesizer", + "name": "Speak", + "message_id": "message_id-1344" + }, + "payload": { + "token": "156", + "type": "Text", + "content": ["为你设置了【起床】提醒。\n度秘将于明天上午8点通知你"], + "speak_behavior": "REPLACE_ALL", + "should_get_next_speech": true + } + }, + { + "header": { + "namespace": "Alerts", + "name": "SetAlert", + "message_id": "test_message_id", + }, + "payload": { + "token": "test_token", + "type": "ALARM", + "scheduled_time": "1490774496", + } + } + ], + "views": [ + { + "type": "list", + "list": [ + { + "title": "起床", + "summary": "为你设置了【起床】提醒。\n度秘将于明天上午8点通知你", + "url": "http://xiaodu.baidu.com/saiya/events", + "image": "http://xiaodu.baidu.com/saiya/img/remind.png" + } + ] + } + ], + "nlu": { + "domain": "alarm", + "intent": "alarm", + "slots": { + "event_title": "起床", + "event_type": "wakeup", + "alarm_time": "{\"day\":\"next\",\"hour\":\"8\",\"apm\":\"am\"}", + } + }, + "speech": { + "type": "Text", + "content": "为你设置了【起床】提醒。\n度秘将于明天上午8点通知你" + } + }, + "id": "1490616124_7372v4pbq", + "logid": "14906161247428", + "user_id": "2856", + "time": 1490616124, + "cuid": "test_1490616124403", + "se_query": "明天上午8点提醒我起床", + "msg": "ok", + "client_msg_id": "c9bfe944-992b-45b1-8afe-dc2cdaee622a", + "speech_id": "12345", + "status": 0 +} +``` +### 管理实例 +```javascript +{ + "result": { + "directives":[ + { + "header": { + "namespace": "SpeechSynthesizer", + "name": "Speak", + "message_id": "message_id-1344" + }, + "payload": { + "token": "156", + "type": "Text", + "content": ["当前没有任何闹钟"], + "speak_behavior": "REPLACE_ALL", + "should_get_next_speech": true + } + }, + { + "header": { + "namespace": "Alerts", + "name": "DeleteAlert", + "message_id": "test_message_id", + }, + "payload": { + "token": "test_token", + "type": "ALARM", + "scheduled_time": "1490774496", + } + } + ], + "views": [ + { + "type": "txt", + "content": "当前没有任何闹钟" + } + ], + "speech": { + "type": "Text", + "content": "当前没有任何闹钟" + }, + "bot_id": "alarm", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "nlu": { + "domain": "alarm", + "intent": "alarm_manage", + "slots": { + "action": "delete", + "alarm_time": "null\n", + } + } + }, + "id": "1490663709_4834c2s7b", + "logid": "14906637094391", + "user_id": "2856", + "time": 1490663709, + "cuid": "4B7163F0FD2B34", + "se_query": "取消闹钟", + "msg": "ok", + "client_msg_id": "f67d63bb-917c-4c67-8fa8-be773ec913ba", + "status": 0 +} +``` + +## NLU +|slot |desc | value | +|---|---|---| +|intent|alarm意图|alarm,alarm_manage| +|action|alarm动作类型|create,list,update,delete| +|event_title | alarm标题 | eg:起床| +|event_type | alarm事件类型 | eg:wakeup| +|alarm_time|[alarm_time说明](#alarm_time)|json字符串 +|scheduled_time | alarm设置的时间。只会在提醒创建前(即槽位完备)给出 | 1486598400| + +## <span id="alarm_time">alarm_time字段说明</span> +|Key |Value |说明| +|---|---|---| +|minute |3, +2, -1|string. 3分,2分钟后,1分钟前| +|hour|2, +1, -3|string. 2点,1小时后,3小时前| +|day|1, +2, -3, -1,next, +0|string. 1号,2天后,3天前,昨天,明天,今天| +|month|1, +2, -3, +0|string. 1月,2个月后,3个月前,这个月| +|year|1984, +1, -2, +0|string. 1984年,明年,2年前,今年| +|week|+1, -1, 2, 3, 2+1|string. 下周,上一周,星期二,周三, 下周二| +|apm|am, pm|string. 上午,下午| +|const|recent, awhile|string. 刚刚,一会儿| +|repeat|day, month, year|string. 每天,每月,每年| +|special_day |weekend, weekday|string. 周末,工作日,节气,节日| +|special_calendar|lunar|string. 农历| + +# timer输出schema +## 输出实例 +### 创建实例 +```javascript +{ + "result": { + "directives":[ + { + "header": { + "namespace": "SpeechSynthesizer", + "name": "Speak", + "message_id": "message_id-1344" + }, + "payload": { + "token": "156", + "type": "Text", + "content": ["5分钟,计时开始"], + "speak_behavior": "REPLACE_ALL", + "should_get_next_speech": true + } + }, + { + "header": { + "namespace": "Alerts", + "name": "SetAlert", + "message_id": "test_message_id", + }, + "payload": { + "token": "test_token", + "type": "TIMER", + "scheduled_time": "1490774496", + } + } + ], + "views": [ + { + "type": "txt", + "content": "5分钟,计时开始" + } + ], + "speech": { + "type": "Text", + "content": "5分钟,计时开始" + }, + "bot_id": "timer", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "nlu": { + "domain": "timer", + "intent": "timer", + "slots": { + "intent": "create", + "minute": "5", + } + } + }, + "id": "1490664954_776f4315j", + "logid": "14906649544030", + "user_id": "2856", + "time": 1490664954, + "cuid": "4B7163F0FD2B34", + "se_query": "5分钟倒计时", + "msg": "ok", + "client_msg_id": "f67d63bb-917c-4c67-8fa8-be773ec913ba", + "status": 0 +} +``` + +### timer管理实例 +```javascript +{ + "result": { + "directives":[ + { + "header": { + "namespace": "SpeechSynthesizer", + "name": "Speak", + "message_id": "message_id-1344" + }, + "payload": { + "token": "156", + "type": "Text", + "content": ["刚刚5分钟内没有设置过计时"], + "speak_behavior": "REPLACE_ALL", + "should_get_next_speech": true + } + }, + { + "header": { + "namespace": "Alerts", + "name": "DeleteAlert", + "message_id": "test_message_id", + }, + "payload": { + "token": "test_token", + "type": "TIMER", + "scheduled_time": "1490774496", + } + } + ], + "views": [ + { + "type": "txt", + "content": "刚刚5分钟内没有设置过计时" + } + ], + "speech": { + "type": "Text", + "content": "刚刚5分钟内没有设置过计时" + }, + "bot_id": "timer", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "nlu": { + "domain": "timer", + "intent": "timer_manage", + "slots": { + "condition": "recent", + "intent": "list", + } + } + }, + "id": "1490665516_47484jz9e", + "logid": "14906655159796", + "user_id": "2856", + "time": 1490665516, + "cuid": "4B7163F0FD2B34", + "se_query": "查看刚刚的倒计时", + "msg": "ok", + "client_msg_id": "f67d63bb-917c-4c67-8fa8-be773ec913ba", + "status": 0 +} +``` + +## NLU +|slot |Value |说明| +|---|---|---| +|minute|3|string. 3分| +|hour|2|string. 2小时| +|day|1|string. 1天| +|month|1|string. 1个月| +|year|2|string. 2年| +|week|1|string. 一周| +|condition|recent|string. 刚刚| + + +# mateapp 接口 +## Alerts列表 +`/saiya/alerts` +`method:GET` +`datatype:JSON` +`params:type=(ALARM|TIMER)` + +### response +```javascript +{ + "status": int, //状态码 0正确 其他错误 + "msg": string, // 错误信息 + "data": [ + AlertsStruct, // 见Alerts数据结构 + AlertsStruct, // 见Alerts数据结构 + ] +} +``` + +## Alerts暂停 +`/saiya/pause` +`method:POST` +`datatype:JSON` +### postbody +```javascript +{ + "token": string, // 唯一标识 +} +``` + +### response +```javascript +{ + "status": int, //状态码 0正确 其他错误 + "msg": string, // 错误信息 + "data": null +} +``` + +## Alerts重新开启 +`/saiya/enable` +`method:POST` +`datatype:JSON` +### postbody +```javascript +{ + "token": string, // 唯一标识 +} +``` + +## Alerts删除 +`/saiya/delete` +`method:POST` +`datatype:JSON` +### postbody +```javascript +{ + "token": string, // 唯一标识 +} +``` + +### response +```javascript +{ + "status": int, //状态码 0正确 其他错误 + "msg": string, // 错误信息 + "data": null +} +``` + +## Alerts更新 +`/saiya/update` +`method:POST` +`datatype:JSON` +### postbody +```javascript +AlertsStruct +``` + +### response +```javascript +{ + "status": int, //状态码 0正确 其他错误 + "msg": string, // 错误信息 + "data": null +} +``` +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/bot/app_launcher.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,77 @@ +#打开应用输出 + +bot_id: ai.dueros.bot.app_launcher + +## v2 协议输出 +```javascript +// query: 打开大冒险 +{ + "result": { + "views": [{ + "type": "txt", + "content": "度秘正在为您打开大冒险" + }], + "nlu": { + "domain": "app_launcher", + "intent": "launch_app", + "slots": { + "name": "大冒险" + } + }, + "resource": { + "website_url": null, + "package_name": "com.Game_Swing.StikboldDLC" + }, + "speech": { + "type": "txt", + "content": "度秘正在为您打开大冒险" + }, + "bot_id": "ai.dueros.bot.app_launcher", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + } + }, + "id": "1494562066_4851rktsi", + "logid": "14945620661492", + "user_id": "test_offline1490608417.0", + "time": 1494562066, + "cuid": null, + "se_query": "打开大冒险", + "msg": "ok", + "status": 0 +} +``` + +字段说明: +view: + +|字段 | 描述 | 举例 | +|---|---|---| +|type | 返回展示卡片数据,必选字段,这里默认是文本 | txt | +|content | 文本内容 | 度秘正在为您打开大冒险 | + + +nlu: + +|字段 | 描述 | 举例 | +|---|---|---| +|intent | 意图 | launch_app:打开app<br> close_app: 关闭app<br> uninstall_app:卸载app<br> download_app:下载app<br> search_app:搜索app<br>| +|slots |从query中提取出来的槽位信息 | "name": "大冒险" | + + +resource: + +|字段 | 描述 | 举例 | +|---|---|---| +|website_url | 网址(没有就是null) | www.baidu.com | +|package_name | 应用包名(存在就返回,不存在,就不返回这个字段,这个主要给电视厂商使用) | com.Game_Swing.StikboldDLC | + + +speech: + +|字段 | 描述 | 举例 | +|---|---|---| +|type | 文本格式 | txt | +|content | 语音文本 | 度秘正在为您打开大冒险 |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/bot/armoto.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,117 @@ +armoto 类,目前没有多轮交互,而且只支持query理解,不会返回内容,所以请忽略除[nlu](../OPENAPI_README.md#nlu)结构外的其他字段 + +所以以下示例,返回值只是.result.nlu的内容,先放一个完整内容的示例 + +```javascript +{ + "result": { + "nlu": { + "domain": "control", + "intent": "ai.dueros.control.SysCommand", + "slots": { + "cmd": "emit" + } + }, + "bot_id": "ai.dueros.bot.system_control_armoto", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "度秘为你找到如下结果" + } + ], + "speech": { + "type": "Text", + "content": "度秘为你找到如下结果" + } + }, + "id": "1498017775_821adojn9", + "logid": "14980177754515", + "user_id": "lihao21_debug_monitor", + "time": 1498017775, + "cuid": "lihao21_debug_monitor", + "se_query": "发射空气炮", + "msg": "ok", + "timeuse": 594, + "status": 0 +} +``` + +### ai.dueros.control.SetVolume 声音控制 +slot key|slot value +--------|---------- +vol_up|代表声音增大 +vol_down|代表声音变小 +vol_set_size|max: 最大;min: 最小 + +声音减小 +声音调到最大 +```javascript +{ + "domain": "control", + "intent": "ai.dueros.control.SetVolume", + "slots": { + "vol_down": "变小" + } +} +``` + + +### ai.dueros.control.SetBrightness 屏幕控制 +slot key|slot value +--------|---------- +up|代表屏幕亮度增大 +down|代表屏幕亮度变小 + +屏幕亮度减小 +```javascript +{ + "domain": "control", + "intent": "ai.dueros.control.SetBrightness", + "slots": { + "up": "高" + } +} +``` + +### ai.dueros.control.SysCommand 设备控制 +slots: + +slot key|slot value +--------|---------- +cmd|emit、change_color、close_light、change_shape、open_cap + +变色、变身 +```javascript +{ + "domain": "control", + "intent": "ai.dueros.control.SysCommand", + "slots": { + "cmd": "change_color" + } +} +``` + +### ai.dueros.control.OperateApp 系统应用控制 +slots: + +slot key|slot value +--------|---------- +app_name|代表app名字 +open|代表打开,若缺失也代表打开app_name + +变色、变身 +```javascript +{ + "domain": "control", + "intent": "ai.dueros.control.OperateApp", + "slots": { + "app_name": "灯光控制", + "open": "进入" + } +} +```
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/bot/audio_joke.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,260 @@ +# 笑话Bot + +## 有声笑话完整输出 + +``` +{ + "result": { + "directives": [ + { + "header": { + "message_id": "fb299466-bbe2-46e3-bcda-65c9b68fa1fb", + "name": "Play", + "namespace": "AudioPlayer" + }, + "payload": { + "audio_item": { + "audio_item_id": "56467429673", + "stream": { + "offset_ms": 0, + "progress_report_interval_ms": 1000, + "stream_format": "AUDIO_MP3", + "token": "56467429673", + "url": "http://fdfs.xmcdn.com/group5/M08/2E/3F/wKgDtlSuElnDb355AAV5Dsfoo8Q652.mp3" + } + }, + "play_behavior": "REPLACE_ALL" + } + } + ], + "nlu": { + "domain": "audio.joke", + "intent": "audio.joke.play", + "slots": {} + }, + "bot_id": "audio_joke", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "Play" + } + ], + "speech": { + "type": "Text", + "content": "" + } + }, + "id": "1497940145_101fbs4kc", + "logid": "14979401448642", + "user_id": "@@@cuid@@@", + "time": 1497940145, + "cuid": "@@@cuid@@@", + "se_query": "讲个笑话", + "msg": "ok", + "client_msg_id": "c9bfe944-992b-45b1-8afe-dc2cdaee622a", + "status": 0, + "timeuse": 296 +} +``` + +## 图文笑话完整输出 + +``` +{ + "emotion": 0, + "hint": [ + "再来一个", + "图片笑话", + "动图笑话", + "文字笑话" + ], + "logid": "14979406701265", + "request_time": "1497940670813", + "request_uid": "zhoubingxuan_debug", + "result_list": [ + { + "card_id": "", + "result_content": { + "img_height": 0, + "img_width": 0, + "imgs": [ + "https://ss1.baidu.com/9vo3dSag_xI4khGko9WTAnF6hhy/xiaodu/pic/item/6a600c338744ebf8a30fda49def9d72a6059a74e.jpg" + ], + "link": "", + "source": null + }, + "result_type": "img_comm", + "source_type": "joke", + "source_sub_type": "joke", + "voice": "" + }, + { + "card_id": "", + "result_content": { + "answer": "白赚十块钱" + }, + "result_type": "txt", + "source_type": "joke", + "voice": "白赚十块钱", + "source_sub_type": "joke" + } + ], + "se_query": "讲个笑话", + "service_id": "27", + "status": 0, + "tips_num": 0, + "kuangim_msgid": 1497940670813329, + "type": "server", + "send_id": "1497940670_506fel3fq", + "send_kuangim_msgid": 1497940670505929, + "count_down": 0, + "hint_id": "BDB2B8F6D0A6BBB0", + "hint_mult": { + "data": [ + { + "id": "0", + "value": "再来一个" + }, + { + "id": "1", + "value": "图片笑话" + }, + { + "id": "2", + "value": "动图笑话" + }, + { + "id": "3", + "value": "文字笑话" + } + ], + "placeholder": "", + "type": "multi_column", + "hint_float": 1 + }, + "nlu": { + "domain": "unknown", + "intent": "unknown", + "slots": [] + }, + "ctime": 1497940670, + "id": "1497940670_8132pceds" +} +``` + +### result_list分三种情况,文字笑话、图片笑话、动图笑话 + +* 文字笑话 + +``` +{ + "result_list": [ + { + "card_id": "", + "result_content": { + "answer": "本人是男的。有一天和我朋友去银行取钱,怕贴条,叫朋友看着车。一会我朋友进来银行了。急着说 大哥快炮,警,察来了。突然银行里安安静静的。" + }, + "result_type": "txt", + "source_type": "joke", + "voice": "本人是男的。有一天和我朋友去银行取钱,怕贴条,叫朋友看着车。一会我朋友进来银行了。急着说 大哥快炮,警,察来了。突然银行里安安静静的。", + "source_sub_type": "joke" + } + ] +} +``` + +* 图片笑话 + +``` +{ + "result_list": [ + { + "card_id": "", + "result_content": { + "img_height": 0, + "img_width": 0, + "imgs": [ + "https://ss3.baidu.com/-fo3dSag_xI4khGko9WTAnF6hhy/xiaodu/pic/item/ca1349540923dd54c82b6f1ed609b3de9c824868.jpg" + ], + "link": "", + "source": null + }, + "result_type": "img_comm", + "source_type": "joke", + "source_sub_type": "joke", + "voice": "" + }, + { + "card_id": "", + "result_content": { + "answer": "下雪的真相" + }, + "result_type": "txt", + "source_type": "joke", + "voice": "下雪的真相", + "source_sub_type": "joke" + } + ] +} +``` + +* 动图笑话 + +``` +{ + "result_list": [ + { + "card_id": "", + "result_content": { + "img": "https://ss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/xiaodu/pic/item/7e3e6709c93d70cfdbbf47ddffdcd100bba12b9d.jpg", + "txt": "这个广告我给满分" + }, + "result_type": "gif_face", + "source_type": "joke", + "source_sub_type": "joke", + "voice": "" + }, + { + "card_id": "", + "result_content": { + "answer": "这个广告我给满分" + }, + "result_type": "txt", + "source_type": "joke", + "voice": "这个广告我给满分", + "source_sub_type": "joke" + } + ] +} +``` + +result_list每个元素代表一个资源,一个资源的类型由result_type决定,其中图片为txt,静态图片为img_comm,git图片为git_face; + +当query是一个明确的"文字笑话"、"图片笑话"、"动图笑话"时,result_list会固定是上面所列的某个类型的返回结果,如果query是"讲个笑话"泛意图query,result_list将随机出一个类型的结果。 + + +## nlu说明 + +intent|slot_name|slot_value|备注 +----|----|--------|---- +audio.joke.play|||播放笑话 + |textual|文字笑话|表达文字笑话意图(针对图文笑话) + |image|图片笑话|表达图片笑话意图(针对图文笑话) + |dynamic_image|动图笑话|表达动图笑话意图(针对图文笑话) +audio.joke.next|||下一个 +audio.joke.previous|||上一个 +audio.joke.continue|||继续 +audio.joke.stop|||停止 + + +## directives 部分的说明 + +参见相关directives的文档 +* [AudioPlayer](../directives/AudioPlayer.md) 播放相关指令 +* [Speaker](../directives/Speaker.md) 扬声器控制、设置相关指令 +* [SpeechSynthesizer](../directives/SpeechSynthesizer.md) 语音播报(TTS)相关指令
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/bot/audio_live.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,320 @@ +直播功能输出: +服务名:audio_live + +直播返回示例: +```javascript +// 播放北京台 + +{ + "data": { + "directives": [ + { + "header": { + "namespace": "AudioPlayer", + "name": "Play", + "message_id": "1488285070_053fydydo" + }, + "payload": { + "play_behavior": "REPLACE_ALL", + "audio_item": { + "audio_item_id": "2007", + "stream": { + "token": "2007", + "url": "http://hls.qingting.fm/live/4851.m3u8?bitrate=1000", + "stream_format": "AUDIO_M3U8", + "offset_ms": 0 + } + } + } + } + ], + "speech": { + "type": "Text", + "content": "播放北京动听调频MetroRdiao 来自蜻蜓FM" + }, + "resource": { + "type": "live_ref", + "data": { + "api": { + "method": "GET", + "url": "http://s.xiaodu.baidu.com/v20161223/resource/live?user_id=DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768" + } + } + }, + "nlu": { + "domain": "audio.live", + "intent": "audio.live.play", + "slots": { + "channel": "北京文艺广播", + "province": "北京", + "category": "文艺" + } + } + } +} +``` + + +### 1、电台列表 + * 接口地址:http://s.xiaodu.baidu.com/v20161223/live/channelList + * 请求方式:GET + * 请求参数: + +参数|类型|是否必须|备注 +----|----|--------|---- +cuid|string|是|设备ID,设备的唯一标识 +category|string|否|分类 (国家,网络,省市,本地,交通,资讯,都市,音乐, ,经济,综合,乡村,书法,休闲,体育,健康,儿童,公益,农业,农村,创业,医疗,商业,国际,外语,女性,娱乐,影视,戏曲,故事,教育,文化,文艺,新闻,方言,旅游,时尚,时政,明星,曲艺,校园,民生,汽车,生活,电影,电视,私家车,科教,综艺,网络,股市,语言,财经,购物等) +province|string|否|省 +la|string|当category为本地,必须|纬度 +lo|string|当category为本地,必须|经度 +page|int|否|页码,默认为1 +pagesize|int|否|每页数据量,默认为10 +appid|string|是|必须|标识请求的端 + +返回格式: +```javascript +{ + "status": 0, + "code": 200, + "data": { + "page": 1, + "total_page": 10, + "list": [ + { + "channel_id": 1, + "channel_name": "北京文艺广播", + "attr_province": "北京", + "freq_fm": "", + "media_info": [ + { + "pic": { + "small": "http://pic.qingting.fm/2015/0828/20150828111022698.jpg!small", + "medium": "http://pic.qingting.fm/2015/0828/20150828111022698.jpg!medium", + "large": "http://pic.qingting.fm/2015/0828/20150828111022698.jpg!large" + }, + "program_name": "娱乐有范儿", + "source": "蜻蜓FM", + "source_icon": "http://123.jpg" + }, + { + "pic": { + "small": "http://fdfs.xmcdn.com/group6/M08/A9/12/wKgDhFUKl1jyghlVAABRqWHVL_g545_mobile_small.jpg", + "medium": "http://fdfs.xmcdn.com/group6/M08/A9/12/wKgDhFUKl1jyghlVAABRqWHVL_g545_mobile_large.jpg", + "large": "http://fdfs.xmcdn.com/group6/M08/A9/12/wKgDhFUKl1jyghlVAABRqWHVL_g545_mobile_large.jpg" + }, + "program_name": "娱乐有范儿", + "source": "喜马拉雅", + "source_icon": "http://123.jpg" + }, + { + "pic": { + "small": "http://img.kaolafm.net/mz/images/201607/5d54a015-4700-4b6e-a2b4-8f08c2918209/default.jpg", + "medium": "http://img.kaolafm.net/mz/images/201607/5d54a015-4700-4b6e-a2b4-8f08c2918209/default.jpg", + "large": "http://img.kaolafm.net/mz/images/201607/5d54a015-4700-4b6e-a2b4-8f08c2918209/default.jpg" + }, + "program_name": "娱乐有范儿", + "source": "考拉", + "source_icon": "http://123.jpg" + } + ], + "update_time": "2016-02-12 13:00:00", + "create_time": "2016-02-11 14:00:00" + } + ] + } +} +``` +### 2、电台详情信息接口 + * 接口地址:http://s.xiaodu.baidu.com/v20161223/live/channelInfo + * 请求方式:GET + * 请求参数: + +参数|类型|是否必须|备注 +----|----|--------|---- +cuid |string |是 |设备ID,设备的唯一标识 +channel_id|int|是|电台ID +appid|string|是|必须|标识请求的端 +retry|int|是|0是正常请求,大于0是失败后再次请求该节目资源 +```javascript +{ + "status": 0, + "code": 200, + "data": { + "channel_id": 1, + "channel_name": "北京文艺广播", + "attr_province": "北京", + "freq_fm": "", + "media_info": [ + { + "play_url": "http://hls.qingting.fm/live/333.m3u8?bitrate=1000", + "pic": { + "small": "http://pic.qingting.fm/2015/0828/20150828111022698.jpg!small", + "medium": "http://pic.qingting.fm/2015/0828/20150828111022698.jpg!medium", + "large": "http://pic.qingting.fm/2015/0828/20150828111022698.jpg!large" + }, + "program_name": "娱乐有范儿", + "source": "蜻蜓FM", + "source_icon": "http://123.jpg" + }, + { + "play_url": "http://live.xmcdn.com/live/94/64.m3u8?transcode=ts", + "pic": { + "small": "http://fdfs.xmcdn.com/group6/M08/A9/12/wKgDhFUKl1jyghlVAABRqWHVL_g545_mobile_small.jpg", + "medium": "http://fdfs.xmcdn.com/group6/M08/A9/12/wKgDhFUKl1jyghlVAABRqWHVL_g545_mobile_large.jpg", + "large": "http://fdfs.xmcdn.com/group6/M08/A9/12/wKgDhFUKl1jyghlVAABRqWHVL_g545_mobile_large.jpg" + }, + "program_name": "娱乐有范儿", + "source": "喜马拉雅", + "source_icon": "http://123.jpg" + }, + { + "play_url": "http://trslbs.itings.com/016f63815d64d4db/1600000000459/playlist.m3u8", + "pic": { + "small": "http://img.kaolafm.net/mz/images/201607/5d54a015-4700-4b6e-a2b4-8f08c2918209/default.jpg", + "medium": "http://img.kaolafm.net/mz/images/201607/5d54a015-4700-4b6e-a2b4-8f08c2918209/default.jpg", + "large": "http://img.kaolafm.net/mz/images/201607/5d54a015-4700-4b6e-a2b4-8f08c2918209/default.jpg" + }, + "program_name": "娱乐有范儿", + "source": "考拉", + "source_icon": "http://123.jpg" + } + ], + "update_time": "2016-02-12 13:00:00", + "create_time": "2016-02-11 14:00:00" + } +} +``` +### 3、获取播放列表接口: + * 接口地址:http://s.xiaodu.baidu.com/v20161223/live/playlist + * 请求方式:GET + * 请求参数: + +参数|类型|是否必须|备注 +----|----|--------|---- +cuid |string |是 |设备ID,设备的唯一标识 +page|int|否|页码,默认为1 +pagesize|int|否|每页数据量,默认为10 +appid|string|是|必须|标识请求的端 + +返回格式: +```javascript +{ + "status": 0, + "code": 200, + "data": { + "page": 1, + "total_page": 10, + "list": [ + { + "channel_id": 1, + "channel_name": "北京文艺广播", + "attr_province": "北京", + "freq_fm": "", + "media_info": [ + { + "pic": { + "small": "http://pic.qingting.fm/2015/0828/20150828111022698.jpg!small", + "medium": "http://pic.qingting.fm/2015/0828/20150828111022698.jpg!medium", + "large": "http://pic.qingting.fm/2015/0828/20150828111022698.jpg!large" + }, + "program_name": "娱乐有范儿", + "source": "蜻蜓FM", + "source_icon": "http://123.jpg" + }, + { + "pic": { + "small": "http://fdfs.xmcdn.com/group6/M08/A9/12/wKgDhFUKl1jyghlVAABRqWHVL_g545_mobile_small.jpg", + "medium": "http://fdfs.xmcdn.com/group6/M08/A9/12/wKgDhFUKl1jyghlVAABRqWHVL_g545_mobile_large.jpg", + "large": "http://fdfs.xmcdn.com/group6/M08/A9/12/wKgDhFUKl1jyghlVAABRqWHVL_g545_mobile_large.jpg" + }, + "source": "喜马拉雅", + "source_icon": "http://123.jpg" + }, + { + "pic": { + "small": "http://img.kaolafm.net/mz/images/201607/5d54a015-4700-4b6e-a2b4-8f08c2918209/default.jpg", + "medium": "http://img.kaolafm.net/mz/images/201607/5d54a015-4700-4b6e-a2b4-8f08c2918209/default.jpg", + "large": "http://img.kaolafm.net/mz/images/201607/5d54a015-4700-4b6e-a2b4-8f08c2918209/default.jpg" + }, + "program_name": "娱乐有范儿", + "source": "考拉", + "source_icon": "http://123.jpg" + } + ], + "update_time": "2016-02-12 13:00:00", + "create_time": "2016-02-11 14:00:00" + } + ] + } +} +``` + +### 4、播放历史接口 + * 接口地址:http://s.xiaodu.baidu.com/v20161223/live/history + * 请求方式:GET + * 请求参数: + +参数|类型|是否必须|备注 +----|----|--------|---- +cuid |string |是 |设备ID,设备的唯一标识 +page|int|否|页码,默认为1 +pagesize|int|否|每页数据量,默认为10 +appid|string|是|必须|标识请求的端 + +返回格式: +```javascript +{ + "status": "0", + "code": "200", + "data": [ + "page": 1, + "total_page": 10, + "list": [ + { + "record_id": 6366998, + "channel_id": 23, + "channel_name": "北京音乐广播", + "last_program": "环球音乐", + "create_time": "2016-02-12 14:00:00", + "update_time": "2016-02-12 15:00:00", + "source": "喜马拉雅", + "source_icon": "http://123.jpg" + } + ] + } +} +``` + + +直播槽位 + +intent|slot|slot_name|slot_value|举例 +------|----|---------|----------|---- +intent::audio.live.play 直播播放|搜索源|search_list|空(所有电台列表) / favorite (收藏列表)|P1| +||电台名|channel|归一化后的电台名 或query中 认为是电台名的词语|例如query"播放北京乱七八糟电台",channel为“乱七八糟” +||一级地域|province|湖南| +||二级地域|city|长沙|P0| +||内容分类|category|(音乐)台| +||调频|fm|调频,fm| +||调频频率|freq|87.6| +||节目名|program||开心茶馆 +intent::audio.live.ask.channel 直播channel相关问答|频道名|channel|值:this(本频道)or具体频道名,如“北京故事广播”|P0|这个频道信息,凤凰娱乐节目信息 +||节目名|program|值:空 or 具体节目名|P1|放午夜书场的是什么频道 +||主持人|artist|修饰| +||专辑|album|修饰| +||剧集|episode|修饰| +||播放状态|playing|修饰| +intent::audio.live.ask.program 直播program相关问答|频道名|program|值:this(本节目) or 具体节目名,如‘音乐旅途’|P1| +intent::audio.live.ask.artist 直播(艺人/主持人/主讲人)相关问答|主持人|artist|值:this(当前主持人)or 具体主持人名,如‘张三’|P1|这个主持人的信息 +intent::audio.live.ask.album 直播album相关问答|专辑名|album|值:this(当前专辑) or 具体专辑名称|P1| +intent::audio.live.ask.episode 直播剧集相关问答|剧集数|ask_sum|总共多少集|P1|总共多少集| +||当前第几集|now_index|第几集|现在第几集 +intent::audio.live.ask.playing 直播playing相关问答|频道|channel|值:this(当前频道在播放什么) or 具体频道在播放什么|P1|cnr文艺之声在播放什么,这是在播什么 +intent::audio.live.favorite.channel 收藏电台|动作|action|like(收藏)、unlike(取消收藏)| +||频道名|channel|为空时收藏or删除收藏当前电台,非空时,收藏or删除收藏指定电台名| +intent::audio.live.favorite.program收藏节目|动作|action|like(收藏)、unlike(取消收藏)| +||节目|program|为空时收藏or删除收藏当前节目,非空时,收藏or删除收藏指定节目| +intent::audio.live.favorite.artist 收藏(艺人/主持人/主讲人)|动作|action|like(收藏)、unlike(取消收藏)| +||主持人|artist|为空时收藏or删除收藏当前主持人,非空时,收藏or删除收藏指定主持人| +intent::audio.live.favorite.album |收藏专辑|动作|action|like(收藏)、unlike(取消收藏)| +||专辑|album|为空时收藏or删除收藏当前专辑,非空时,收藏or删除收藏指定专辑| \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/bot/audio_music.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,783 @@ +音乐返回的完整例子: +```javascript +//放一首周杰伦的歌 +{ + "result": { + "directives": [ + { + "header": { + "message_id": "14851538172760", + "name": "Play", + "namespace": "AudioPlayer" + }, + "payload": { + "audio_item": { + "audio_item_id": "846803671", + "stream": { + "offset_ms": 0, + "progress_report_interval_ms": 1000, + "stream_format": "AUDIO_MP3", + "token": "846803671", + "url": "http://zhangmenshiting.baidu.com/data2/music/64333976/64333976.mp3?xcode=0411b74c6de0c453a0d51cfc739c1004" + } + }, + "play_behavior": "REPLACE_ALL" + } + } + ], + "resource": { + "data": { + "api": { + "method": "GET", + "url": "http://s.xiaodu.baidu.com/v20161223/resource/music?user_id=DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768" + } + }, + "type": "music_ref" + }, + "speech": { + "content": "周杰伦 晴天", + "message_id": "14851538172760", + "type": "Text" + }, + "bot_id": "audio_music", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "周杰伦 晴天" + } + ], + "nlu": { + "domain": "audio.music", + "intent": "audio.music.play", + "slots": { + "singer": "周杰伦", + "unit": "歌曲" + } + } + }, + "id": "1485153817_97578ae8d", + "logid": "14851538172760", + "user_id": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "time": 1485153817, + "cuid": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "se_query": "放一首周杰伦的歌", + "msg": "ok", + "status": 0 +} +``` + +### nlu部分的说明 +intent|slot|slot_name|slot_value +------|----|---------|---------- +intent::audio.music.play音乐播放|歌手/乐队名|singer|周杰伦/二手玫瑰 + |歌曲名|song|听妈妈的话 + |专辑名|album|依然范特西 + |排序类型|sort_type|sort_new(最新)|/|sort_hot(最热) + |单位|unit|歌曲、专辑(用于区分“播放周杰伦的歌曲”和“播放周杰伦的专辑”) + |标签|tag|好听、悲伤、80后、摇滚 + |榜单名|top_name|热歌榜、原创音乐榜 + |歌单名|list_name|让音乐撞见你的心事;别让时间消磨掉你的青春 + |作词人|lyricist|方文山 + |作曲人|composer|周杰伦 +intent::audio.music.ask 知识问答|歌手名|singer|有值代表有询问需求;空代表无询问需求 + |专辑名|album|有值代表有询问需求;空代表无询问需求 + |歌曲名|song|有值代表有询问需求;空代表无询问需求 +intent::audio.music.favorite 收藏歌曲|动作|action|like(收藏)/unlike(取消收藏) + |歌名|name|这首歌,这个 +intent::audio.music.songlist 歌单管理|歌曲名|song|这首歌 + |动作|action|add(加入歌单)/delete(删除歌单) + |歌单名|list_name|小清新 +intent::audio.music.stop 停止 | +intent::audio.music.pause 暂停 | +intent::audio.music.continue 继续 | +intent::audio.music.next 下一首 | 换一首、换一批 | unit | 槽位值为group是换一批,槽位值为空是下一首 +intent::audio.music.previous 上一首 | +intent::audio.music.play_mode 播放模式 | 循环模式 |mode |single_cycle,rand,list_cycle + + +### directives 部分的说明 + +参见音乐相关directives的文档 + * [AudioPlayer](../directives/AudioPlayer.md) 音乐播放相关指令 + * [Speaker](../directives/Speaker.md) 扬声器控制、设置相关指令 + * [SpeechSynthesizer](../directives/SpeechSynthesizer.md) 语音播报(TTS)相关指令 + + + +### resource 部分的解释说明 + +.result.resource.type==music_ref的resource,是一个播放列表的地址,支持翻页 +```javascript +{ + "data": { + "api": { + "method": "GET", + "url": "http://s.xiaodu.baidu.com/v20161223/resource/music?user_id=DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768" + } + }, + "type": "music_ref" +} +``` + +### 播放列表接口 + * 接口地址:http://s.xiaodu.baidu.com/v20161223/resource/music + (对应语音交互返回结果的result的result.resource.data.api.url字段内容) + * 请求方式:GET + * 请求参数: + +参数|类型|是否必须|备注 +----|----|--------|---- +user_id|string|是|设备ID,设备的唯一标识 +appid|string|是|appid +page|int|否|页码,默认为1 +page|int|否|页码,默认为1 +page_size|int|否|每页数据量,默认为10 + +返回格式: +```javascript +{ + "status": 0, + "code": "", + "data": { + "page": 1, + "total_page": 5, + "list": [ + { + "id": "1006090198", + "duration": "252", + "name": "黑雨", + "alias": "", + "singer_name": [ + "莫文蔚" + ], + "original_singer": [], + "primitive_singer": [ + "莫文蔚" + ], + "album_info": [ + { + "album_url": "http:\\/\\/music.baidu.com\\/album\\/179567", + "album_url_md5": "5e1b2464c0fa0abac9369f89eb68e753", + "album_id": "1043086642", + "album_name": "x" + } + ], + "genre": [ + "流行" + ], + "tag": [ + "流行" + ], + "language": "", + "composer": [], + "lyricist": [], + //"lycUrl": "http://music.baidu.com/song/929759?fm=altg_new3#song_lyric", + //"lycContent": "歌词详情", + //"wap_lycUrl": "http://music.baidu.com/song/929759?fm=altg_new3", + //"lycDownload": "http://qukufile2.qianqian.com/data2/lrc/12459382/12459382.lrc", + "url": "http://music.baidu.com/song/929759", + "same_name_url": "http://music.baidu.com/search?fm=altg_new3&key=%E9%BB%91%E9%9B%A8", + "head_image_url": "http://qukufile2.qianqian.com/data2/pic/124206198/124206198.jpg", + "score": "0", + "publish_time": "2003-09-01", + "publish_company": "SONY MUSIC", + "is_need_pay_listen": 0, + "hot": "144", + "from_site": 1 + + }, + .... + ] + }, + "message": "" +} +``` +### 歌曲详情接口 + * 接口地址:http://s.xiaodu.baidu.com/v20161223/resource/musicdetail + * 请求方式:GET + * 请求参数: + +参数|类型|是否必须|备注 +----|----|--------|---- +song_id|int|是|歌曲id(对应歌曲列表接口返回的id字段) + + +返回值: +```javascript +{ + "status": 0, + "code": ‘’, + "data": { + "id": "1006090198", + "duration": "252", + "name": "黑雨", + "alias": "", + "singer_name": [ + "莫文蔚" + ], + "original_singer": [], + "primitive_singer": [ + "莫文蔚" + ], + "album_info": [ + { + "album_url": "http:\\/\\/music.baidu.com\\/album\\/179567", + "album_url_md5": "5e1b2464c0fa0abac9369f89eb68e753", + "album_id": "1043086642", + "album_name": "x" + } + ], + "genre": [ + "流行" + ], + "tag": [ + "流行" + ], + "language": "", + "composer": [], + "lyricist": [], + "lycUrl": "http://music.baidu.com/song/929759?fm=altg_new3#song_lyric", + "lycContent": "歌词详情", + "wap_lycUrl": "http://music.baidu.com/song/929759?fm=altg_new3", + "lycDownload": "http://qukufile2.qianqian.com/data2/lrc/12459382/12459382.lrc", + "url": "http://music.baidu.com/song/929759", + "same_name_url": "http://music.baidu.com/search?fm=altg_new3&key=%E9%BB%91%E9%9B%A8", + "head_image_url": "http://qukufile2.qianqian.com/data2/pic/124206198/124206198.jpg", + "score": "0", + "publish_time": "2003-09-01", + "publish_company": "SONY MUSIC", + "is_need_pay_listen": 0, + "hot": "144", + "from_site": 1, + "streaming_vedio_url": "http://zhangmenshiting.baidu.com/data2/music/42531820/42531820.mp3?xcode=1ddc85b4186134be718197b4a0f16666" + }, + "message": "" +} +``` +其中status 为0返回正常,其它异常 + +### 歌曲歌词接口 + * 接口地址:http://s.xiaodu.baidu.com/v20161223/resource/songlyric + * 请求方式:GET + * 请求参数: + +参数|类型|是否必须|备注 +----|----|--------|---- +song_id|int|是|歌曲id(对应歌曲列表接口返回的id字段) + +返回值 +```javascript +{ + "status": 0, + "code": "", + "data": { + "lycUrl": "http://music.baidu.com/song/130244161?fm=altg_new3#song_lyric", + "lycContent": "歌词内容", + "lycDownload": "http://qukufile2.qianqian.com/data2/lrc/130488147/130488147.lrc" + }, + "message": "" +} +``` +### 歌曲最新播放url接口 +请求参数 + * 接口地址:http://s.xiaodu.baidu.com/v20161223/resource/musicstreamurl + * 请求方式:GET + * 请求参数: + +参数|类型|是否必须|备注 +----|----|--------|---- +song_id|int|是|歌曲id(对应歌曲列表接口返回的id字段) + +返回值: +```javascript +{ + "status": 0, + "code": "", + "data": { + "streaming_vedio_url": "http://zhangmenshiting.baidu.com/data2/music/ec75bbd373de776107be888a4dab4596/263815849/263815849.mp3?xcode=e8a6f9d3d7ea39bc06d3b5c82f9312a3" + }, + "message": "" +} +``` + + +### 歌单列表接口 + * 接口地址:http://s.xiaodu.baidu.com/v20161223/resource/songsheetlist + * 请求方式:GET + * 请求参数: + +参数|类型|是否必须|备注 +----|----|--------|---- +page|int|否|页码,默认为1 +page_size|int|否|每页数据量,默认为10 + +返回结果 + +```javascript +{ + status: 0, + code: "", + data: { + "page" : 1, //当前页 + "total_page" : 10, //总页数 + "list": [ + { + "sheet_id" : 121, //歌单id + "name":"【环球之音】一听就上瘾的欧美节奏", //歌单名字 + "pic":"http://musicugc.cdn.qianqian.com/ugcdiy/pic/7d584d4298a6584be32f0cd115722280.jpg", //歌单封面 + "desc":"环球旗下的顶尖歌手们,正用他们开拓的创新精神引领着这个时代的音乐潮流。节奏是一首歌的心跳,更是嘻哈音乐和电子音乐的灵魂,这样的节奏足够精彩到让人流连忘返。", //歌单简介 + "tag":"欧美 说唱 电子" //歌单标签 + }, + { + "sheet_id" : 122, + "name":"【环球之音】一听就上瘾的欧美节奏", + "pic":"http://musicugc.cdn.qianqian.com/ugcdiy/pic/7d584d4298a6584be32f0cd115722280.jpg", + "desc":"环球旗下的顶尖歌手们,正用他们开拓的创新精神引领着这个时代的音乐潮流。节奏是一首歌的心跳,更是嘻哈音乐和电子音乐的灵魂,这样的节奏足够精彩到让人流连忘返。", + "tag":"欧美 说唱 电子" + } + ] + }, + message: "" +} +``` +其中status 为0返回正常,其它异常 + +### 歌单的歌曲列表接口 + * 接口地址:url:http://s.xiaodu.baidu.com/v20161223/resource/songsheetmusic + * 请求方式:GET + * 请求参数: + +参数|类型|是否必须|备注 +----|----|--------|---- +sheet_id|int|是|歌单id +page|int|否|页码,默认为1 +page_size|int|否|每页数据量,默认为10 + + +返回值: +```javascript + +{ + "status": 0, + "code": "", + "data": { + "total_page": 4, + "page": "1", + "list": [ + { + "id": "1004785648", + "duration": "215", + "name": "告白气球", + "alias": "", + "singer_name": [ + "周杰伦" + ], + "original_singer": [], + "primitive_singer": [ + "周杰伦" + ], + "album_info": [ + { + "album_url": "http://music.baidu.com/album/266322553", + "album_url_md5": "4ff9f62e9bdc0bfc4361efe9d219f86d", + "album_id": "1045401856", + "album_name": "周杰伦的床边故事" + } + ], + "genre": [ + "R&B", + "节奏布鲁斯" + ], + "tag": [ + "RnB", + "节奏怨曲", + "R&B", + "节奏蓝调", + "好听", + "节奏布鲁斯" + ], + "language": "", + "composer": [], + "lyricist": [], + "url": "http://music.baidu.com/song/266322598", + "same_name_url": "http://music.baidu.com/search?fm=altg_new3&key=%E5%91%8A%E7%99%BD%E6%B0%94%E7%90%83", + "head_image_url": "http://qukufile2.qianqian.com/data2/pic/7d093104b5e3c0a92a95eea7e24456ff/273945517/273945517.jpg", + "score": "0", + "publish_time": "2016-06-24", + "publish_company": "杰威尔JVR音乐有限公司", + "is_need_pay_listen": 0, + "hot": "854092", + "from_site": "baidu" + }, + { + "id": "998002844", + "duration": "240", + "name": "青花瓷", + "alias": "", + "singer_name": [ + "周杰伦" + ], + "original_singer": [], + "primitive_singer": [ + "周杰伦" + ], + "album_info": [ + { + "album_url": "http://music.baidu.com/album/68674", + "album_url_md5": "8ddd52a97c2aaeff6ca774c607573f03", + "album_id": "1054918835", + "album_name": "我很忙" + } + ], + "genre": [ + "流行" + ], + "tag": [ + "流行" + ], + "language": "", + "composer": [], + "lyricist": [], + "url": "http://music.baidu.com/song/354387", + "same_name_url": "http://music.baidu.com/search?fm=altg_new3&key=%E9%9D%92%E8%8A%B1%E7%93%B7", + "head_image_url": "http://qukufile2.qianqian.com/data2/pic/1df84db0f1cc0f7d92c9925b47e7fa7d/88389089/88389089.jpg", + "score": "0", + "publish_time": "2007-11-02", + "publish_company": "杰威尔JVR音乐有限公司", + "is_need_pay_listen": 0, + "hot": "93427", + "from_site": "baidu" + }, + { + "id": "964861563", + "duration": "270", + "name": "晴天", + "alias": "", + "singer_name": [ + "周杰伦" + ], + "original_singer": [], + "primitive_singer": [ + "周杰伦" + ], + "album_info": [ + { + "album_url": "http://music.baidu.com/album/72257", + "album_url_md5": "67a675d5ce7e9c2501f77855c9e69ec3", + "album_id": "1011284556", + "album_name": "叶惠美" + } + ], + "genre": [ + "流行" + ], + "tag": [ + "流行" + ], + "language": "", + "composer": [], + "lyricist": [], + "url": "http://music.baidu.com/song/816477", + "same_name_url": "http://music.baidu.com/search?fm=altg_new3&key=%E6%99%B4%E5%A4%A9", + "head_image_url": "http://qukufile2.qianqian.com/data2/pic/115434572/115434572.jpg", + "score": "0", + "publish_time": "2003-07-31", + "publish_company": "杰威尔JVR音乐有限公司", + "is_need_pay_listen": 0, + "hot": "70453", + "from_site": "baidu" + }, + { + "id": "1009088399", + "duration": "229", + "name": "夜曲", + "alias": "", + "singer_name": [ + "周杰伦" + ], + "original_singer": [], + "primitive_singer": [ + "周杰伦" + ], + "album_info": [ + { + "album_url": "http://music.baidu.com/album/697896", + "album_url_md5": "e8a4fd90e081275d4c2c00c6e06b6730", + "album_id": "1011290034", + "album_name": "十一月的萧邦" + } + ], + "genre": [ + "流行" + ], + "tag": [ + "寂寞", + "纯音乐", + "孤独", + "孤单", + "流行", + "Absolute" + ], + "language": "", + "composer": [], + "lyricist": [], + "url": "http://music.baidu.com/song/1191265", + "same_name_url": "http://music.baidu.com/search?fm=altg_new3&key=%E5%A4%9C%E6%9B%B2", + "head_image_url": "http://qukufile2.qianqian.com/data2/pic/2ff7ed1d61b5473cd64d805577ddab36/115457137/115457137.jpg", + "score": "0", + "publish_time": "2005-11-01", + "publish_company": "杰威尔JVR音乐有限公司", + "is_need_pay_listen": 0, + "hot": "106174", + "from_site": "baidu" + }, + { + "id": "1003959977", + "duration": "224", + "name": "稻香", + "alias": "", + "singer_name": [ + "周杰伦" + ], + "original_singer": [], + "primitive_singer": [ + "周杰伦" + ], + "album_info": [ + { + "album_url": "http://music.baidu.com/album/116177", + "album_url_md5": "224c2d8eee1ea941a6cbd342a0c3d0d1", + "album_id": "1009252782", + "album_name": "魔杰座" + } + ], + "genre": [ + "流行" + ], + "tag": [ + "流行" + ], + "language": "", + "composer": [], + "lyricist": [], + "url": "http://music.baidu.com/song/1390840", + "same_name_url": "http://music.baidu.com/search?fm=altg_new3&key=%E7%A8%BB%E9%A6%99", + "head_image_url": "http://qukufile2.qianqian.com/data2/pic/97be3c1753fbf496315d4b4953e06ee2/274049124/274049124.jpg", + "score": "0", + "publish_time": "2008-10-14", + "publish_company": "杰威尔JVR音乐有限公司", + "is_need_pay_listen": 0, + "hot": "21893", + "from_site": "baidu" + }, + { + "id": "997036570", + "duration": "269", + "name": "简单爱", + "alias": "", + "singer_name": [ + "周杰伦" + ], + "original_singer": [], + "primitive_singer": [ + "周杰伦" + ], + "album_info": [ + { + "album_url": "http://music.baidu.com/album/10735646", + "album_url_md5": "94c999d194215d8204e9e80b873acf7c", + "album_id": "1043072482", + "album_name": "婚礼歌手 幸福情歌精选" + } + ], + "genre": [ + "流行" + ], + "tag": [ + "流行" + ], + "language": "", + "composer": [], + "lyricist": [], + "url": "http://music.baidu.com/song/10736444", + "same_name_url": "http://music.baidu.com/search?fm=altg_new3&key=%E7%AE%80%E5%8D%95%E7%88%B1", + "head_image_url": "http://qukufile2.qianqian.com/data2/pic/a882d5cbbc469ba95f3b6442a9db2aa3/117628079/117628079.jpg", + "score": "0", + "publish_time": "2010-02-08", + "publish_company": "SONY MUSIC", + "is_need_pay_listen": 0, + "hot": "66379", + "from_site": "baidu" + }, + { + "id": "996977531", + "duration": "302", + "name": "发如雪", + "alias": "", + "singer_name": [ + "周杰伦" + ], + "original_singer": [], + "primitive_singer": [ + "周杰伦" + ], + "album_info": [ + { + "album_url": "http://music.baidu.com/album/697896", + "album_url_md5": "e8a4fd90e081275d4c2c00c6e06b6730", + "album_id": "1011290034", + "album_name": "十一月的萧邦" + } + ], + "genre": [ + "流行" + ], + "tag": [ + "中国风", + "伴奏", + "Absolute", + "流行", + "纯音乐" + ], + "language": "", + "composer": [], + "lyricist": [], + "url": "http://music.baidu.com/song/1147070", + "same_name_url": "http://music.baidu.com/search?fm=altg_new3&key=%E5%8F%91%E5%A6%82%E9%9B%AA", + "head_image_url": "http://qukufile2.qianqian.com/data2/pic/2ff7ed1d61b5473cd64d805577ddab36/115457137/115457137.jpg", + "score": "0", + "publish_time": "2005-11-01", + "publish_company": "杰威尔JVR音乐有限公司", + "is_need_pay_listen": 0, + "hot": "56316", + "from_site": "baidu" + }, + { + "id": "1005362249", + "duration": "276", + "name": "红尘客栈", + "alias": "", + "singer_name": [ + "周杰伦" + ], + "original_singer": [], + "primitive_singer": [ + "周杰伦" + ], + "album_info": [ + { + "album_url": "http://music.baidu.com/album/31496572", + "album_url_md5": "2bb5adb0bb278e9169adcf97ecc8f63d", + "album_id": "1054909997", + "album_name": "十二新作" + } + ], + "genre": [ + "流行" + ], + "tag": [ + "流行" + ], + "language": "", + "composer": [], + "lyricist": [], + "url": "http://music.baidu.com/song/31496563", + "same_name_url": "http://music.baidu.com/search?fm=altg_new3&key=%E7%BA%A2%E5%B0%98%E5%AE%A2%E6%A0%88", + "head_image_url": "http://qukufile2.qianqian.com/data2/pic/1b62c0ccc53edc47a1152d9f004a31ce/115744261/115744261.jpg", + "score": "0", + "publish_time": "2012-12-06", + "publish_company": "杰威尔JVR音乐有限公司", + "is_need_pay_listen": 0, + "hot": "47853", + "from_site": "baidu" + }, + { + "id": "1006041007", + "duration": "257", + "name": "说好的幸福呢", + "alias": "", + "singer_name": [ + "周杰伦" + ], + "original_singer": [], + "primitive_singer": [ + "周杰伦" + ], + "album_info": [ + { + "album_url": "http://music.baidu.com/album/116177", + "album_url_md5": "224c2d8eee1ea941a6cbd342a0c3d0d1", + "album_id": "1009252782", + "album_name": "魔杰座" + } + ], + "genre": [ + "流行" + ], + "tag": [ + "流行" + ], + "language": "", + "composer": [], + "lyricist": [], + "url": "http://music.baidu.com/song/1392875", + "same_name_url": "http://music.baidu.com/search?fm=altg_new3&key=%E8%AF%B4%E5%A5%BD%E7%9A%84%E5%B9%B8%E7%A6%8F%E5%91%A2", + "head_image_url": "http://qukufile2.qianqian.com/data2/pic/97be3c1753fbf496315d4b4953e06ee2/274049124/274049124.jpg", + "score": "0", + "publish_time": "2008-10-14", + "publish_company": "杰威尔JVR音乐有限公司", + "is_need_pay_listen": 0, + "hot": "34673", + "from_site": "baidu" + }, + { + "id": "1016008345", + "duration": "263", + "name": "烟花易冷", + "alias": "", + "singer_name": [ + "周杰伦" + ], + "original_singer": [], + "primitive_singer": [ + "周杰伦" + ], + "album_info": [ + { + "album_url": "http://music.baidu.com/album/67834", + "album_url_md5": "c07513e19430c434d69618d15a0a9959", + "album_id": "1050554398", + "album_name": "跨时代" + } + ], + "genre": [ + "流行" + ], + "tag": [ + "流行" + ], + "language": "", + "composer": [], + "lyricist": [], + "url": "http://music.baidu.com/song/228393", + "same_name_url": "http://music.baidu.com/search?fm=altg_new3&key=%E7%83%9F%E8%8A%B1%E6%98%93%E5%86%B7", + "head_image_url": "http://qukufile2.qianqian.com/data2/pic/21d4d618a2b1a077bb7332cb6d09fe0b/274045307/274045307.jpg", + "score": "0", + "publish_time": "2010-05-18", + "publish_company": "杰威尔JVR音乐有限公司", + "is_need_pay_listen": 0, + "hot": "49779", + "from_site": "baidu" + } + ] + }, + "message": "" +} +``` + 其中status 为0返回正常,其它异常 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/bot/audio_news.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,386 @@ +## 新闻返回示例: + +```javascript +// 播放娱乐新闻 +{ + "data":{ + "directives":[ + { + "header":{ + "namespace":"SpeechSynthesizer", + "name":"Speak", + "message_id":"1493864807_662bc4xyq" + }, + "payload":{ + "token":"3506569477723439778", + "type":"Text", + "channel":"Content", + "speak_behavior":"REPLACE_ALL", + "content":[ + "格斗狂人徐晓冬发文甄子丹和成龙对比成龙只是个演员", + "连王思聪都开始关心此事,称虽然有炒作嫌疑,但是徐晓冬起码在打假,一时让这位格斗狂人成为网红", + "MMA徐晓冬成为网红后,最近开始回答网友提问,其中一个问题引起大家热议,有网友问甄子丹和成龙谁更厉害,徐晓冬直言甄子丹和成龙对战的话,毫无疑问甄子丹更强,而成龙就是个演员" + ], + "should_get_next_speech":true + } + } + ], + "speech":{ + "type":"Text", + "content":"为您播放相关新闻的主要内容" + }, + "resource":{ + "type":"news_ref", + "data":{ + "api":{ + "method":"GET", + "url":"http://s.xiaodu.baidu.com/v20161223/news/playlist?user_id=qa_test_debug_yinjie_debug_monitor" + } + } + }, + "views":[ + { + "type":"list", + "list":[ + { + "title":"格斗狂人徐晓冬发文 甄子丹和成龙对比 成龙只是个演员" + "summary":"连王思聪都开始关心此事,称虽然有炒作嫌疑,但是徐晓冬起码在打假,一时让这位格斗狂人成为网红。MMA徐晓冬成为网红后,最近开始回答网友提问,其中一个问题引起大家热议,有网友问甄子丹和成龙谁更厉害,徐晓冬直言甄子丹和成龙对战的话,毫无疑问甄子丹更强,而成龙就是个演员。", + "image":"https://t10.baidu.com/it/u=48542835,4216554270&fm=170&s=7D3203D1502A1B132F35F01E03008040&w=218&h=146&img.JPEG", + "url":"http://m.baidu.com/feed/data/landingpage?s_type=news&dsp=wise&nid=3506569477723439778&n_type=1&p_from=5", + "site":"热门集结号", + }, + { + "title":"又一枚招黑体要逆袭了!真实的娜扎其实是这样的…" + "summary":"五一小长假宝宝们休息得可还满意咩?大家一定猜出是谁了吧~凑是她---古力娜扎!一些娜扎的粉丝表示,娜扎能在《花少3》里放飞自我,少了之前上综艺节目的羞涩和紧张,江疏影起到了非常重要的作用,也有观众表示娜扎和江疏影还原了生活中闺蜜们的真实模样~。", + "image":"https://t12.baidu.com/it/u=1451155880,534240721&fm=170&s=F92BA05408530BD455267C810300E088&w=218&h=146&img.GIF", + "url":"http://m.baidu.com/feed/data/landingpage?s_type=news&dsp=wise&nid=2559658158706376148&n_type=0&p_from=5", + "site":"新浪娱乐", + }, + { + "title":"郑爽至今没有和杨洋走到一起,原来是被他占了先机,亲密关系胜过杨洋!" + "summary":"去年的《微微一笑很倾城》中的贝薇薇和肖奈CP,相信给大家的印象很是深刻,网友都说两个人不在一起实在是太可惜啦,甜炸的两个人真的很般配呢。虽然和郑爽组过cp的也不算少,但是貌似和郑爽配的只有杨洋了。近日《翡翠恋人》中郑爽和李钟硕的合影又使网友们发现了新cp。李钟硕揽着郑爽的腰,两人配的一脸,你支持郑爽和那一位男星组cp呢?", + "image":"https://t10.baidu.com/it/u=3057389397,2784140068&fm=170&s=A0E066B15C73CE90EE45E45E03008073&w=218&h=146&img.JPEG", + "url":"http://m.baidu.com/feed/data/landingpage?s_type=news&dsp=wise&nid=3418558970771359236&n_type=1&p_from=5", + "site":"小兔子娱乐", + } + ], + } + ] + "nlu":{ + "domain":"audio.news", + "intent":"audio.news.play", + "slots":{ + "category":"娱乐" + } + } + } +} +``` + + +### nlu部分的说明 +intent|slot|slot_name|slot_value +------|----|---------|---------- +intent::audio.news.play 新闻播放|分类|category|国际/国内/体育/娱乐/社会/财经/互联网/科技/房产/汽车/教育/时尚/游戏/军事/旅游/生活/人文/创意/搞笑/美图/女人/美食/家居/健康/两性/情感/星座命理/育儿/文化/历史/宠物/科学/动漫/职场/三农/本地/悦读/交通/影视/时事/法律/综合 + |省份|province|浙江 + |城市|city|杭州 + |关键字|keyword|王宝强 + |排序类型|sort_type|最热/最新 +intent::audio.news.stop 停止 | +intent::audio.news.next 下一条 | +intent::audio.news.previous 上一条 | + + +### directives 部分的说明 + +参考:[SpeechSynthesizer](../directives/SpeechSynthesizer.md) 语音播报(TTS)相关指令 + + +### resource 部分的解释说明 + +存放新闻列表的地址。 + +说明:当前的data对象下面存在list字段,为短期内兼容之前的协议版本所保留,后续会下线,请勿使用。新闻列表请通过api字段下的url链接获取。 + +```javascript +"resource": { + "type": "news_ref", + "data": { + "api": { + "method": "GET", + "url": "http://s.xiaodu.baidu.com/v20161223/news/playlist?user_id=yinjie05_debug_monitor" + } + } +}, +``` + + +## 获取新闻播放列表 + + * 接口地址:http://s.xiaodu.baidu.com/v20161223/news/playlist?user_id=yinjie05_debug_monitor + (对应语音交互返回结果的resource.data.api.url字段内容) + * 请求方式:GET + * 请求参数: + +参数|类型|是否必须|备注 +----|----|--------|---- +user_id|string|是|用户ID,用户的唯一标识 +appid|string|是|appid +page|int|否|页码,默认为1 +page_size|int|否|每页数据量,默认为10 + + * 返回码:status为0表示成功,非0表示失败。 + + * 说明:当前只支持最多获取10条新闻。 + +返回格式: + +```javascript +{ + "status":0, + "code":"", + "data":[ + { + "id":"3506569477723439778", + "title":"格斗狂人徐晓冬发文 甄子丹和成龙对比 成龙只是个演员", + "summary":"连王思聪都开始关心此事,称虽然有炒作嫌疑,但是徐晓冬起码在打假,一时让这位格斗狂人成为网红。MMA徐晓冬成为网红后,最近开始回答网友提问,其中一个问题引起大家热议,有网友问甄子丹和成龙谁更厉害,徐晓冬直言甄子丹和成龙对战的话,毫无疑问甄子丹更强,而成龙就是个演员。", + "content_url":"http://s.xiaodu.baidu.com/v20161223/news/content?id=3506569477723439778", + "url":"http://m.baidu.com/feed/data/landingpage?s_type=news&dsp=wise&nid=3506569477723439778&n_type=1&p_from=5", + "site":"热门集结号", + "image":"", + "thumb":"https://t10.baidu.com/it/u=48542835,4216554270&fm=170&s=7D3203D1502A1B132F35F01E03008040&w=218&h=146&img.JPEG", + "pubtime":"2017-05-04 09:58:56" + }, + { + "id":"2559658158706376148", + "title":"又一枚招黑体要逆袭了!真实的娜扎其实是这样的…", + "summary":"五一小长假宝宝们休息得可还满意咩?大家一定猜出是谁了吧~凑是她---古力娜扎!一些娜扎的粉丝表示,娜扎能在《花少3》里放飞自我,少了之前上综艺节目的羞涩和紧张,江疏影起到了非常重要的作用,也有观众表示娜扎和江疏影还原了生活中闺蜜们的真实模样~。", + "content_url":"http://s.xiaodu.baidu.com/v20161223/news/content?id=2559658158706376148", + "url":"http://m.baidu.com/feed/data/landingpage?s_type=news&dsp=wise&nid=2559658158706376148&n_type=0&p_from=5", + "site":"新浪娱乐", + "image":"", + "thumb":"https://t12.baidu.com/it/u=1451155880,534240721&fm=170&s=F92BA05408530BD455267C810300E088&w=218&h=146&img.GIF", + "pubtime":"2017-05-04 09:57:00" + }, + { + "id":"3418558970771359236", + "title":"郑爽至今没有和杨洋走到一起,原来是被他占了先机,亲密关系胜过杨洋!", + "summary":"去年的《微微一笑很倾城》中的贝薇薇和肖奈CP,相信给大家的印象很是深刻,网友都说两个人不在一起实在是太可惜啦,甜炸的两个人真的很般配呢。虽然和郑爽组过cp的也不算少,但是貌似和郑爽配的只有杨洋了。近日《翡翠恋人》中郑爽和李钟硕的合影又使网友们发现了新cp。李钟硕揽着郑爽的腰,两人配的一脸,你支持郑爽和那一位男星组cp呢?", + "content_url":"http://s.xiaodu.baidu.com/v20161223/news/content?id=3418558970771359236", + "url":"http://m.baidu.com/feed/data/landingpage?s_type=news&dsp=wise&nid=3418558970771359236&n_type=1&p_from=5", + "site":"小兔子娱乐", + "image":"", + "thumb":"https://t10.baidu.com/it/u=3057389397,2784140068&fm=170&s=A0E066B15C73CE90EE45E45E03008073&w=218&h=146&img.JPEG", + "pubtime":"2017-05-04 09:40:28" + }, + { + "id":"3205985826513278211", + "title":"拍过3级片玩过地下情,被彭于晏暗恋,她最终嫁作他人妇", + "summary":"彭于晏用自己的蜕变和精湛的演技。7年过去了,彭于晏很多地方都变了。彭于晏的好友余文乐带他去拜。那时在场的香港人无人认识彭于晏。彭于晏的办法很简单:“做她喜欢的事情。彭于晏最终还是没能和舒淇在一起。祝福彭于晏也早点找到自己的另一半吧。", + "content_url":"http://s.xiaodu.baidu.com/v20161223/news/content?id=3205985826513278211", + "url":"http://m.baidu.com/feed/data/landingpage?s_type=news&dsp=wise&nid=3205985826513278211&n_type=1&p_from=5", + "site":"环球旅游", + "image":"", + "thumb":"https://t11.baidu.com/it/u=3502029508,2438972355&fm=170&s=65BB33D75413CD88057151F10300C034&w=218&h=146&img.JPEG", + "pubtime":"2017-05-04 09:39:46" + }, + { + "id":"3157049548926521845", + "title":"他择天记里给鹿晗做配角,被骂惨", + "summary":"不得不说,看了几集发现,在一众”面瘫‘男主之中,鹿晗相对属于演技自然的那种。到目前爲止除有些台词和情形略显为难,陈长生的各种举措还算行云流水。这回说说在《择天记》中,饰演金玉律的高圣远,他的名字大家有些生疏,但是他的标签可是周迅的老公,大家还记得周迅在微博上发布爱情时分的甘美。", + "content_url":"http://s.xiaodu.baidu.com/v20161223/news/content?id=3157049548926521845", + "url":"http://m.baidu.com/feed/data/landingpage?s_type=news&dsp=wise&nid=3157049548926521845&n_type=1&p_from=5", + "site":"七月杂货铺", + "image":"", + "thumb":"https://t11.baidu.com/it/u=1823692162,64319016&fm=170&s=80334F302BF165920CD940C20300A0B2&w=218&h=146&img.JPEG", + "pubtime":"2017-05-04 09:38:15" + }, + { + "id":"2811454756298141532", + "title":"陕西版《人民的名义》 阵容强大,绝对精彩!", + "summary":"看着戏中各个新老演员的精湛演技。结果发现阵容强大、演技颜值兼具。李琦,陕西西安人,1955年2月17日。孙浩,陕西西安人,歌手出身,代表作《中华民谣》、《阳光天堂》等,近几年也参演了不少影视作品。最后再来看看陕西话版《人民的名义》。适合《人民的名义》的什么角色。", + "content_url":"http://s.xiaodu.baidu.com/v20161223/news/content?id=2811454756298141532", + "url":"http://m.baidu.com/feed/data/landingpage?s_type=news&dsp=wise&nid=2811454756298141532&n_type=1&p_from=5", + "site":"汉中微部落", + "image":"", + "thumb":"https://t11.baidu.com/it/u=2947932262,3007708866&fm=170&s=C18B93554070B198DDB14C2A03002053&w=218&h=146&img.JPEG", + "pubtime":"2017-05-04 09:36:15" + }, + { + "id":"3829479301106064223", + "title":"杨幂?吴磊?杨紫?下一个爆火的童星可是他!", + "summary":"接下来,就跟着小编看下现场情况吧~。我们还将携手目前国内最火的短视频二更,邀请我们参演的小朋友进行微剧、短视频的创作。5月份开始,台州国学儿童剧项目将与各大学校合作,开展萌星杯“中华小故事国学儿童剧”小演员选拔赛。报名地址:椒江区东环大道345台州老广电大楼一楼海视影业。", + "content_url":"http://s.xiaodu.baidu.com/v20161223/news/content?id=3829479301106064223", + "url":"http://m.baidu.com/feed/data/landingpage?s_type=news&dsp=wise&nid=3829479301106064223&n_type=1&p_from=5", + "site":"名人八卦", + "image":"", + "thumb":"https://t11.baidu.com/it/u=1222753300,35338058&fm=170&s=12B3538710BB4D9ACAADF8DF03000021&w=218&h=146&img.PNG", + "pubtime":"2017-05-04 09:31:09" + }, + { + "id":"3638621966798515943", + "title":"《极限挑战》已定档,当三精遇到三傻是否可以超越《奔跑吧》?给我们无穷无尽的快乐!", + "summary":"《极限挑战》自2015年暑假和大家见面以来,现在也只播出了两季,第三季迟迟不播出一直吊着观众的胃口,着实是让大家等得很焦灼啊。因为节目组一直是在保证质量加上男人帮之间感情深厚,观众也是一直在等待。极限三傻继续傻下去?极限三傻、是颜王孙红雷、大松鼠王迅、小绵羊张艺兴 ,极限三傻带给我们无穷无尽的快乐。", + "content_url":"http://s.xiaodu.baidu.com/v20161223/news/content?id=3638621966798515943", + "url":"http://m.baidu.com/feed/data/landingpage?s_type=news&dsp=wise&nid=3638621966798515943&n_type=1&p_from=5", + "site":"娱乐随便聊", + "image":"", + "thumb":"https://t11.baidu.com/it/u=1654168168,1922263267&fm=170&s=FAEDA9444943395B66791C9303008088&w=218&h=146&img.JPEG", + "pubtime":"2017-05-04 09:25:07" + }, + { + "id":"3597096676794455655", + "title":"泰国女富豪找到第9任老公, 前夫称:一夜28次受不了才离婚的!", + "summary":"非常感谢朋友们打开小编的文章,我将一如既往的给大家开诚布公的分享一些知识和看法,如果接下来的内容哪怕能对您产生一些小小的快乐,笔者将不胜荣幸!小编话说:谢谢这么优秀的你来看文章,有什么想对小编说的尽管来吧,大家的支持就是我们的动力,欢迎大家踊跃发表评论,欢迎吐槽,让我在评论区看到高逼格的你,小编在评论区等你哦。", + "content_url":"http://s.xiaodu.baidu.com/v20161223/news/content?id=3597096676794455655", + "url":"http://m.baidu.com/feed/data/landingpage?s_type=news&dsp=wise&nid=3597096676794455655&n_type=1&p_from=5", + "site":"盘点奇趣异事", + "image":"", + "thumb":"https://t11.baidu.com/it/u=3483554392,2200937200&fm=170&s=A7161DCF48623007429100B003008012&w=218&h=146&img.JPEG", + "pubtime":"2017-05-04 09:21:25" + }, + { + "id":"3370672881399791496", + "title":"王宝强刚被曝出结婚消息,马蓉父亲立马称要曝大料毁掉他!", + "summary":"近来,王宝强与熊乃瑾走得比较近,两人经常一起亲密的进入某体育馆做健身,王宝强还亲密的贴身教熊乃瑾武术招式。消息传得沸沸扬扬,粉丝们争先送上了祝福,没想到,马蓉的父亲却见不得宝强好,在微博上大声吆喝,称自己这儿有王宝强的大料,要毁掉王宝强一辈子。微博用户名字是马蓉父亲马阳卫,他第一条微博说:蓉儿现在比较稳定,我老伴本身就要高血压,现在还在监护病房。", + "content_url":"http://s.xiaodu.baidu.com/v20161223/news/content?id=3370672881399791496", + "url":"http://m.baidu.com/feed/data/landingpage?s_type=news&dsp=wise&nid=3370672881399791496&n_type=1&p_from=5", + "site":"娱乐开森妹", + "image":"", + "thumb":"https://t11.baidu.com/it/u=3875812192,3041931758&fm=170&s=0F04EA07528880BAB98CA3B603005027&w=218&h=146&img.PNG", + "pubtime":"2017-05-04 09:18:24" + } + ], + "message":"" +} +``` + + +## 获取新闻内容接口 + + * 接口地址:http://s.xiaodu.baidu.com/v20161223/news/content?id=17415159588394100071 + * 请求方式:GET + * 请求参数: + +参数|类型|是否必须|备注 +----|----|--------|---- +id|string|是|新闻ID,新闻的唯一标识 + + * 返回码:status为0表示成功,非0表示失败。 + + * 说明:新闻内容包含图片和问题,返回结果中通过type字段区分。 + +返回格式: +``` +{ + status: 0, + code: "", + data: [ + { + type: "image", + data: { + big: { + height: 680, + url: "http://t11.baidu.com/it/u=2235963898,1792389728&fm=170&s=CBD4D1AE0937A5EF5EB9458603003007&w=623&h=680&img.JPEG", + width: 623 + }, + original: { + height: 680, + url: "http://img1.gtimg.com/ent/pics/hv1/217/233/2185/142139257.jpg", + width: 623 + }, + original_third: { + height: 680, + url: "http://img1.gtimg.com/ent/pics/hv1/217/233/2185/142139257.jpg", + width: 623 + }, + small: { + height: 360, + url: "http://t11.baidu.com/it/u=279339871,159264062&fm=170&s=CBD4D1AE0937A5EF5EB9458603003007&w=480&h=360&img.JPEG", + width: 480 + } + } + }, + { + type: "text", + data: "节目录制现场" + }, + { + type: "image", + data: { + big: { + height: 302, + url: "http://t11.baidu.com/it/u=2144948446,1705532450&fm=170&s=928048A70E7A72964D19900203001011&w=479&h=302&img.JPEG", + width: 479 + }, + original: { + height: 302, + url: "http://img1.gtimg.com/ent/pics/hv1/222/233/2185/142139262.jpg", + width: 479 + }, + original_third: { + height: 302, + url: "http://img1.gtimg.com/ent/pics/hv1/222/233/2185/142139262.jpg", + width: 479 + }, + small: { + height: 302, + url: "http://t11.baidu.com/it/u=188324419,72406784&fm=170&s=928048A70E7A72964D19900203001011&w=479&h=302&img.JPEG", + width: 479 + } + } + }, + { + type: "text", + data: "黄晓明拍戏受伤" + }, + { + type: "image", + data: { + big: { + height: 680, + url: "http://t11.baidu.com/it/u=2176538020,1732823474&fm=170&s=3EE2C704CA23529C260C09B2030080C3&w=509&h=680&img.JPEG", + width: 509 + }, + original: { + height: 680, + url: "http://img1.gtimg.com/ent/pics/hv1/233/233/2185/142139273.jpg", + width: 509 + }, + original_third: { + height: 680, + url: "http://img1.gtimg.com/ent/pics/hv1/233/233/2185/142139273.jpg", + width: 509 + }, + small: { + height: 360, + url: "http://t11.baidu.com/it/u=219913993,99697808&fm=170&s=3EE2C704CA23529C260C09B2030080C3&w=480&h=360&img.JPEG", + width: 480 + } + } + }, + { + type: "text", + data: "黄晓明写真" + }, + { + type: "text", + data: "腾讯娱乐讯昨晚(2月12日)播出的某综艺节目,黄晓明在猜评团中“神探”上身,对于各MC邀请的神秘嘉宾好友几乎每猜必中。" + }, + { + type: "text", + data: "大部分都不是歌手出身的MC们,为了在这次歌会中有精彩的表现,也是极尽突破挑战自我。猜评团成员张大大突然现场爆料黄晓明不仅正在发烧中,还知道他前两周去做正骨,痛到大叫,令黄爸爸凌晨两点在隔壁房间听到儿子的叫声十分心疼。" + }, + { + type: "text", + data: "黄晓明出道近二十年,拍戏一向拼命的他,虽然不是专业动作演员,拍动作戏也尽量亲身上阵,所以多年来身上的大伤小伤一直不断,而为了不影响剧组的进度,常常都是不顾医生的“工作禁令”就回到剧组继续工作。" + }, + { + type: "text", + data: "2003年拍摄《龙票》时在沙漠翻车导致颈椎严重骨折,医生就勒令让黄晓明休息几个月,黄晓明担心剧组工作人员都在等他,坚持继续拍戏,医生说“你疯了吗,如果不好好休息就会瘫痪!”但他仍旧坚持开工,于是,就此留下了严重的后遗症。直到现在,黄晓明都无法睡正常的枕头,必须要特制的圆形枕头睡觉,他的颈椎才不会那么疼。他还曾自曝其实有“威亚恐惧症”,几年前拍摄一部电影时,从威亚上直接掉了下来,脚趾粉碎性骨折,打了4根钢钉,2根钢针。但他在伤后40天还是坚持去拍戏,打着绷带吊着腿继续吊威亚。“劳模”背后的努力和坚持令人敬佩。" + } + ], + message: "" +} +``` +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/bot/audio_unicast.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,569 @@ +点播功能输出: +服务名:audio_unicast + +点播返回示例: +```javascript +// 播放相声 + +{ + "data": { + "directives": [ + { + "header": { + "message_id": "14851538172760", + "name": "Play", + "namespace": "AudioPlayer" + }, + "payload": { + "play_behavior": "REPLACE_ALL", + "audio_item": { + "audio_item_id": "55690041011", + "stream": { + "url": "http://fdfs.xmcdn.com/group3/M01/77/42/wKgDsVKMdDLCVKUUAIMXy99Q7Vo340.mp3", + "stream_format": "mp3", + "offset_ms": 0, + "token": "55690041011", + "progress_report_interval_ms": 50000 + } + } + } + } + ], + "speech": { + "type": "Text", + "content": "播放郭德纲相声" + }, + "resource": { + "type": "unicast_ref", + "data": { + "api": { + "method": "GET", + "url": "http://s.xiaodu.baidu.com/v20161223/unicast/playlist?cuid=XXXX" + } + } + }, + "views": { + "type": "txt", + "content": "郭德纲相声" + } + } +} +``` + + +### 1、专辑列表 + * 接口地址:http://s.xiaodu.baidu.com/v20161223/unicast/albumlist + * 请求方式:GET + * 请求参数: + +参数|类型|是否必须|备注 +----|----|--------|---- +category|int|是|分类ID +cuid|string|是|设备ID,设备的唯一标识 +appid|string|是|appid,标识接入方 +page|int|否|页码,默认为1 +pagesize|int|否|每页数据量,默认为10 +sort|string |否 |排序:热门:grade、最新:album_last_track_time(默认:热门) +orderby |string |否 |倒序:desc, 正序 asc (默认:asc) + +分类ID|分类名称 +-------|-------- +1|相声 +2|小说 +3|公开课 +4|诗歌 +5|戏曲 +6|段子 +7|讲座 +8|演讲 +9|健康养生 +11|有声书 +12|资讯 +13|历史 +14|评书 +15|广播剧 +16|小品 +17|故事 +18|人文 +20|脱口秀 + +返回格式: +```javascript +{ + status: 0, + code: "", + data: + { + "page" : 1, //当前页 + "total_page" : 10, //总页数 + "list" + [ + { + "id":1, //专辑ID + "album_title":"逻辑思维", //专辑名 + "include_track_count":100, //节目总数 + "cover_url": + { + "small":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_small.jpg", + "middle":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_meduim.jpg", + "large":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_large.jpg", + }, + "play_count":188376, //播放量 + "category_name":"资讯", //分类 + "category_id":3, //分类ID + "update_time":"2017-03-03 10:09:18", //更新时间 + "create_time":"2017-03-03 10:09:18", //创建时间 + "source": "喜马拉雅", //资源方 + "source_icon": "http://xxxx.xxx.xxx/xx/xx.jpg", //资源方Icon + }, + { + "id":1, + "album_title":"逻辑思维2", + "include_track_count":160, + "cover_url": + { + "small":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_small.jpg", + "middle":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_meduim.jpg", + "large":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_large.jpg", + }, + "play_count":188300, + "category_name":"资讯", + "category_id":3, + "update_time":"2017-03-03 10:09:18", //更新时间 + "create_time":"2017-03-03 10:09:18", //创建时间 + "source": "喜马拉雅", //资源方 + "source_icon": "http://xxxx.xxx.xxx/xx/xx.jpg", //资源方Icon + } + ] + } +} + +``` + + +### 2、获得某个专辑的节目列表 + * 接口地址:http://s.xiaodu.baidu.com/v20161223/unicast/tracklist + * 请求方式:GET + * 请求参数: + +参数|类型|是否必须|备注 +----|----|--------|---- +albumid |int |是 |专辑ID +cuid |string |是 |设备ID,设备的唯一标识 +appid |string|是|appid,标识接入方 +page |int |否 |页码,默认为1 +pagesize |int |否 |每页数据量,默认为10 +sort |int |否 |正序:acs、倒序:desc + +返回格式: +```javascript +{ + status: 0, + code: "", + data: + { + "page" : 1, //当前页 + "total_page" : 10, //总页数 + "list" + [ + { + "id":1, //节目ID + "track_title":"大保镖", //节目名 + "duration":100, //节目时长 + "cover_url": { + "small":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_small.jpg", + "middle":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_meduim.jpg", + "large":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_large.jpg", + }, + "play_count":188376, //播放量 + "category_name":"相声", //分类名 + "category_id":3, //分类ID + "update_time":1479966445, //更新时间 + "create_time":1481595445, //创建时间 + "source": "喜马拉雅", //资源方 + "source_icon": "XXX.icon", //资源方Icon + }, + { + "id":1, + "track_title":"逗你玩", + "duration":160, + "cover_url": { + "small":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_small.jpg", + "middle":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_meduim.jpg", + "large":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_large.jpg", + }, + "play_count":188300, + "category_name":"资讯", + "category_id":3, + "update_time":"2017-03-03 10:09:18", //更新时间 + "create_time":"2017-03-03 10:09:18", //创建时间 + "source": "喜马拉雅", //资源方 + "source_icon": "http://xxxx.xxx.xxx/xx/xx.jpg", //资源方Icon + } + ] + } +} + +``` + +### 3、获取节目信息 + * 接口地址:http://s.xiaodu.baidu.com/v20161223/unicast/trackplay + * 请求方式:GET + * 请求参数: + +参数|类型|是否必须|备注 +----|----|--------|---- +trackid |int |是 |专辑ID +cuid |string |是 |设备ID,设备的唯一标识 +appid |string|是|appid,标识接入方 +retry |int|是|0是正常请求,大于0是失败后再次请求该节目资源 + +#### 播放url地址说明: + * mp3\aac\m4a代表音频的格式 + * 32\64\128代表各个格式下32\64\128位的音频的播放地址 + * 注:每个音频会有多种格式多种码率的播放地址,但不是每种格式/码率的地址都有(端上要注意判断空),端上可根据支持的格式与网络情况按需取用相应的播放地址 + +返回格式: +```javascript +{ + status: 0, + code: "", + data: + { + "id":1, + "track_title":"逗你玩", + "duration":160, + "cover_url": + { + "small":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_small.jpg", + "middle":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_meduim.jpg", + "large":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_large.jpg", + }, + "play_count":188300, + "category_name":"资讯", + "category_id":3, + "update_time":"2017-03-03 10:09:18", //更新时间 + "create_time":"2017-03-03 10:09:18", //创建时间 + "source": "喜马拉雅", //资源方 + "source_icon": "http://xxxx.xxx.xxx/xx/xx.jpg", //资源方Icon + "play_url": + { + "mp3":{//代表播放的音频格式 + "32": "http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_32.mp3",//代表32位mp3格式的声音的播放地址 + "64": "http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_64.mp3",//代表64位mp3格式的声音的播放地址 + }, + "acc":{ + "32": "http://image.kaolafm.net/mz/aac_32/201305/1d257f2b-944d-4607-a846-15c8838a8aab.aac", + "64": "http://image.kaolafm.net/mz/aac_64/201305/1d257f2b-944d-4607-a846-15c8838a8aab.aac", + "128": "http://image.kaolafm.net/mz/aac_128/201305/1d257f2b-944d-4607-a846-15c8838a8aab.aac", + }, + "m4a":{ + "24":"http://audio.xmcdn.com/group7/M03/03/FE/wKgDWlbB5mCj94OWAFBSGzSmA1g528.m4a", + "64": "http://audio.xmcdn.com/group7/M03/03/DA/wKgDX1bB5l3S4rnMANJrwQTRSPo780.m4a", + }, + }, + } +} + +``` + + +### 4、获取播放列表接口: + * 接口地址:http://s.xiaodu.baidu.com/v20161223/unicast/playlist + * 请求方式:GET + * 请求参数: + +参数|类型|是否必须|备注 +----|----|--------|---- +cuid |string |是 |设备ID,设备的唯一标识 +appid|string|是|appid,标识接入方 +page |int |否 |页码,默认为1 +pagesize |int |否 |每页数据量,默认为10 + +返回格式: +```javascript +{ + status: 0, + code: "", + data:{ + page : 1, + total_page : 10, + list:[ + { + "id":1, + "track_title":"逗你玩", + "duration":160, + "cover_url": + { + "small":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_small.jpg", + "middle":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_meduim.jpg", + "large":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_large.jpg", + }, + + "play_count":188300, + "category_name":"资讯", + "category_id":3, + "update_time":"2017-03-03 10:09:18", //更新时间 + "create_time":"2017-03-03 10:09:18", //创建时间 + "source": "喜马拉雅", //资源方 + "source_icon": "http://xxxx.xxx.xxx/xx/xx.jpg", //资源方Icon + }, + { + "id":2, + "track_title":"逗你玩", + "duration":160, + "cover_url": + { + "small":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_small.jpg", + "middle":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_meduim.jpg", + "large":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_large.jpg", + }, + + "play_count":188300, + "category_name":"资讯", + "category_id":3, + "update_time":"2017-03-03 10:09:18", //更新时间 + "create_time":"2017-03-03 10:09:18", //创建时间 + "source": "喜马拉雅", //资源方 + "source_icon": "http://xxxx.xxx.xxx/xx/xx.jpg", //资源方Icon + }, + ] + } +} + +``` + +#### 5、播放历史接口: + * 接口地址:http://s.xiaodu.baidu.com/v20161223/unicast/historylist + * 请求方式:GET + * 请求参数: + +参数|类型|是否必须|备注 +----|----|--------|---- +cuid |string |是 |设备ID,设备的唯一标识 +appid|string|是|appid,标识接入方 +page |int |否 |页码,默认为1 +pagesize |int |否 |每页数据量,默认为10 + + * 返回格式: + + ```javascript + { + status: 0, + code: "", + data: + { + "page" : 1, //当前页 + "total_page" : 10, //总页数 + "list" [ + { + "id":1, //节目ID + "track_title":"逗你玩", //节目名 + "album_id":23, //专辑ID + "album_name": "逻辑思维", //专辑名 + "duration": 220, //节目时长,单位:s + "offset": 100, //播放到的断点位置,单位:s,0为播放完毕 + "update_time":"2017-03-03 10:09:18", //更新时间 + "create_time":"2017-03-03 10:09:18", //创建时间 + "source": "喜马拉雅", //资源方 + "source_icon": "http://xxxx.xxx.xxx/xx/xx.jpg", //资源方Icon + }, + { + "id":2, //节目ID + "track_title":"大保镖", //节目名 + "album_id":23, //专辑ID + "album_name": "逻辑思维", //专辑名 + "duration": 160, //节目时长,单位:s + "offset": 50, //播放到的断点位置,单位:s,0为播放完毕 + "update_time":"2017-03-03 10:09:18", //更新时间 + "create_time":"2017-03-03 10:09:18", //创建时间 + "source": "喜马拉雅", //资源方 + "source_icon": "http://xxxx.xxx.xxx/xx/xx.jpg", //资源方Icon + }, + ] + } +} + + ``` +6、按tag获取专辑列表信息 +* 接口地址:http://s.xiaodu.baidu.com/v20161223/unicast/albumbytags +* 请求方式:GET +* 请求参数: + +参数|类型|是否必须|备注 +------|-----|-----|------ +cuid|string|是|设备ID,设备的唯一标识 +appid|string|是|唯一标识接入方 +tags|string|是|需要查询的标签列表,多个标签用逗号(",")隔开 多个标签取结果的交集,比如标签"儿童,故事",结果集是既包含儿童又包含故事的专辑列表 +category| int |是|需要查询的标签所属的列表 +page|int|否|页码,默认1 +pagesize|int|否|每页数据量,默认10 + + +分类ID|分类名称|标签列表 +-------|--------|------- +1|相声 |郭德纲,岳云鹏 +2|小说 |悬疑,玄幻,言情,都市 +3|公开课| +4|诗歌| 抒情 +5|戏曲|豫剧 , 昆剧 , 京剧 +6|段子|搞笑 +7|讲座|互联网 +8|演讲|科技 +9|健康养生|饮食 , 运动 +11|有声书|儿童 , 官场 +12|资讯|国内 , 国外 +13|历史|三国 +14|评书|刘兰芳 , 单田芳 +15|广播剧|电台广播 +16|小品|赵本山 +17|故事|儿童 , 情感 +18|人文|名著 +20|脱口秀娱乐 + +``` +{ + status: 0, + code: null, + data: + { + "page" : 1, //当前页 + "total_page" : 10, //总页数 + "total_nums" : 1000,//分类下的专辑总量 + "list" + [ + { + "id":1, //专辑ID + "album_title":"逻辑思维", //专辑名 + "include_track_count":100, //节目总数 + "cover_url": { + "small":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_small.jpg", + "middle":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_meduim.jpg", + "large":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_large.jpg", + }, + "play_count":188376, //播放量 + "category_name":"资讯", //分类 + "category_id":3, //分类ID + "update_time":1479966445, //更新时间 + "create_time":1481595445, //创建时间 + "source": "喜马拉雅", //资源方 + "source_icon": "XXX.icon", //资源方Icon + }, + { + "id":1, + "album_title":"逻辑思维2", + "include_track_count":160, + "cover_url": { "small":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_small.jpg", + "middle":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_meduim.jpg", + "large":"http://fdfs.xmcdn.com/group3/M09/34/94/wKgDsVMUWC-i2BqxAALZkSLeN4o874_mobile_large.jpg", + }, + "play_count":188300, + "category_name":"资讯", + "category_id":3, + "update_time":1479966445, + "create_time":1481595445, + } + ] + } +} +``` +7、一级类目信息查询 + +* 接口地址:http://s.xiaodu.baidu.com/v20161223/unicast/getcategory +* 请求方式:GET +* 请求参数: + +参数|类型|是否必须|备注 +-------|-----|----|----- +cuid|string|是|设备ID,设备的唯一标识 +appid|string|是|唯一标识接入方 + +``` +{ + status : 0, + code: null, + data: { + list:[ + { + categoryid : 1, + categoryname : '相声', + album_num : 300 + }, + { + categoryid : 1, + categoryname : '小品', + album_num : 500 + + } + ] + } +} +``` +### 点播QU槽位 + +intent|slot|slot_name|slot_value +----|----|--------|---- +intent::audio.unicast.play|点播播放 |一级分类 |first_category|小说、评书、相声等({播放}+{点播泛词}的query的一级分类:default) +播放XXX与继续播放XXX无差别,都视为正常播放|搜索范围|search_list|favorite (收藏列表),空为不限即全部 P1 新增,规则:当有播放收藏列表词时,出播放意图,此槽位=favorite + |主讲人| artist |郭德纲(演艺人员)| P0 槽位已实现,后端检索已支持 词典完善,多值是否能实现待确认 + |关键词 |keyword |去除口语化后,意图/槽位 |不能识别的term,逗号分隔(qu做diff处理后的term) P0 槽位已有,值未实现,后端检索已支持 实现未识别term填充 + |二级分类 |second_category |股市、儿童睡前故事 P1 槽位已实现 词典添加,后端检索支持 + |节目名 |track_name |大保镖 P0 槽位已实现 词典完善(与专辑名相同时,出节目名) + |专辑名 |album_name | P0 槽位已实现 词典完善 + |排序类型| sort_type| sort_new(最新) / sort_hot(最热) P0 支持排序类语意解析 + |来源 |source |资源提供方 如:喜马拉雅 P1 新增,提供资源方名称词典 + |标签 |tag |其他属性词 P0 新增 ,提供属性词典 + |第几集 |episode| 用于专辑内定位节目,值:整数,“最后一集”或“最新一集”时,值为:last P0 新增, 示例:播放梅花三弄的第5集 + |单位 |unit |节目、专辑 P1 检索后端忽略此槽位 +intent::audio.unicast.ask.track| 点播节目问答| | + |艺人| artist |艺人修饰槽位:非空有需求 P1 槽位格式修改,见前面的value说明 + |专辑 |album |专辑修饰槽位:非空有需求 P1 槽位格式修改,见前面的value说明 + |第几集 |episode |集修饰槽位:非空有需求,第五集,值为5 P1 槽位格式修改,见前面的value说明 + |节目 |track |节目修饰槽位:非空有需求 P1 槽位格式修改,见前面的value说明 +intent::audio.unicast.ask.album |点播专辑问答|| + |艺人 |artist| 艺人修饰槽位:非空有需求 + |节目 |track |节目修饰槽位:非空有需求 P1 + |集 |episode |集修饰槽位:非空有需求,第五集,值为5 + |专辑 |album |专辑修饰槽位:非空有需求 P1 +intent::audio.unicast.ask.artist |点播艺人问答 | | + |节目 |track |节目修饰槽位:非空有需求 P1 + |专辑 |album |专辑修饰槽位:非空有需求 P1 + |集 |episode|集修饰槽位:非空有需求,第五集,值为5 + |艺人 |artist |艺人修饰槽位:非空有需求 P1 +intent::audio.unicast.ask.episode|点播集问答|| + |艺人 |artist |艺人修饰槽位:非空有需求 P1 + |节目 |track |节目修饰槽位:非空有需求 P1 + |专辑 |album |专辑修饰槽位:非空有需求 P1 + |集 |episode|集修饰槽位:默认为问第几集:1,第几集:1,剩多少集:2,总共多少集:3P1 +intent::audio.unicast.favorite.album |点播专辑收藏 || + |艺人 |artist |艺人修饰槽位:非空有需求 P1 + |节目 |track |节目修饰槽位:非空有需求 P1 + |专辑 |album |专辑修饰槽位:非空有需求 P0 +intent::audio.unicast.favorite.artist |点播艺人收藏|| + |艺人 |artist |艺人修饰槽位:非空有需求 P1 + |节目 |track |节目修饰槽位:非空有需求 P1 + |专辑 |album |专辑修饰槽位:非空有需求 P1 +intent::audio.unicast.favorite.track点播节目收藏|| + |艺人 |artist |艺人修饰槽位:非空有需求 P1 + |节目 |track |节目修饰槽位:非空有需求 P1 + |专辑 |album |专辑修饰槽位:非空有需求 P1 + +#### 点播控制 + +intent |slot |slot_name |slot_value| 指令动作| 指令说法 +----|----|--------|------|--------|---- +intent::audio.unicast.stop| 停止|||| +intent::audio.unicast.pause |暂停|||| +intent::audio.unicast.continue |继续|||| +intent::audio.unicast.next |下一首 |||| +intent::audio.unicast.previous |上一首 |||| +intent::audio.unicast.nextalbum |下一专辑 |||| +intent::audio.unicast.previousalbum |上一专辑 |||| +intent::audio.unicast.play_mode| 播放模式 播放模式 |mode |single_cycle,rand,list_cycle|| +intent::audio.unicast.goto |跳转到指定节目集 | episode| 数字\last(最后一集)\new(最新一集)| 播放第几集、播放最后一集、播放最新一集 +intent::audio.unicast.speed |快进/退 | ||| + | |forward |非空:快进需求,空:非快进| + | |forward_speed |快进速度 ,int,倍数 | 与端定默认速度 + | |rewind |非空:快退需求,空:非快退 | + | |rewind_speed |快退速度 ,int,倍数 | 与端定默认速度 + | |time |单位:s \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/bot/cookbook.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,238 @@ +cookbook 类,满足食材、菜谱类需求,目前没有多轮交互,而且只支持query理解,不会返回内容,所以请忽略除[nlu](../OPENAPI_README.md#nlu)结构外的其他字段 + +所以以下示例,返回值只是.result.nlu的内容,先放一个完整内容的示例 + +```javascript +{ + "result": { + "bot_id": "cookbook", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "度秘为你找到如下结果" + } + ], + "nlu": { + "domain": "cookbook", + "intent": "cookbook.open", + "slots": { + "dish": "西红柿炒鸡蛋" + } + }, + "speech": { + "type": "Text", + "content": "度秘为你找到如下结果" + } + }, + "id": "1485139903_1013gs22f", + "logid": "14851399025585", + "user_id": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "time": 1485139903, + "cuid": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "se_query": "怎么做西红柿炒鸡蛋", + "msg": "ok", + "status": 0 +} +``` + +### cookbook.open + +slot key|slot value +--------|---------- +material|食材 +system|菜系 +dish|菜名 +tag|类别:热门、特色、当季 +season|季节 +flavor|口味 +holiday|节日 +people|人群 +symptom|症状 + +- 怎么做菜 +- 看看菜谱 +- 教我做饭吧 +- 今天做点啥菜呢 + +```javascript +{ + "domain": "cookbook", + "intent": "cookbook.open", + "slots": {} +} +``` + + +- 好吃的川菜 +- 好吃的川菜做法 +- 好吃的川菜大全 +- 好吃的川菜菜谱 + +```javascript +{ + "domain": "cookbook", + "intent": "cookbook.open", + "slots": { + "system": "川菜" + } +} +``` + +- 草鱼怎么做好吃 + +```javascript +{ + "domain": "cookbook", + "intent": "cookbook.open", + "slots": { + "material": "草鱼" + } +} +``` + +- 查找热门食谱 +- 特色食谱教学 +- 当季菜做法大全 + +```javascript +{ + "domain": "cookbook", + "intent": "cookbook.open", + "slots": { + "tag": "热门" + } +} +``` + +- 夏至适合吃的菜 +- 大暑适合吃的菜 + +```javascript +{ + "domain": "cookbook", + "intent": "cookbook.open", + "slots": { + "season": "夏至" + } +} +``` + +- 看看川味儿菜谱 +- 教我做酸甜口味的菜吧 +- 口味偏甜的菜有哪些 + +```javascript +{ + "domain": "cookbook", + "intent": "cookbook.open", + "slots": { + "flavor": "酸甜口味" + } +} +``` + +- 年夜饭做啥菜呢 +- 春节吃什么好 + +```javascript +{ + "domain": "cookbook", + "intent": "cookbook.open", + "slots": { + "holiday": "春节" + } +} +``` + +- 适合老年人吃的菜 +- 适合做饭初学者的菜谱 +- 孕妇菜谱大全 + +```javascript +{ + "domain": "cookbook", + "intent": "cookbook.open", + "slots": { + "people": "孕妇" + } +} +``` + +- 补肾食谱 +- 美白应该吃什么 + +```javascript +{ + "domain": "cookbook", + "intent": "cookbook.open", + "slots": { + "symptom": "补肾" + } +} +``` + + +### cookbook.step +精确菜名的步骤播报 + +slot key|slot value +--------|---------- +dish|菜名 + +- 做水煮鱼的步骤 +- 水煮鱼步骤详解 +- 水煮鱼的做法和步骤 + +```javascript +{ + "domain": "cookbook", + "intent": "cookbook.step", + "slots": { + "dish": "水煮鱼" + } +} +``` + +### cookbook.collect +查看收藏 + +- 查看收藏 +- 打开收藏的菜谱 +- 看看收藏菜谱 +- 我收藏了哪些菜 +- 打开收藏菜谱 + +```javascript +{ + "domain": "cookbook", + "intent": "cookbook.collect", + "slots": { + } +} +``` + +### cookbook.video +食谱视频 + + +slot key|slot value +--------|---------- +dish|菜名 + +- 水煮鱼的视频 +- 水煮鱼视频教学 + +```javascript +{ + "domain": "cookbook", + "intent": "cookbook.video", + "slots": { + "dish": "水煮鱼" + } +} +```
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/bot/duer_weather.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,104 @@ +# weather bot输出schema + +## 天气意图(intent:weather) +```javascript +//query = 今天天气咋样 +{ + "result": { + "resource": { + "type": "weather", + "data": { + "city": "北京", + "current_temp": "14℃", + "pm25": "132", + "temp": "11℃~25℃", + "time": "周四 04月06日", + "weather": "多云转阴", + "weather_all": "多云转阴,11℃~25℃,南风微风", + "wind": "南风微风", + "weather_info": [ + { + "current_temp": "14℃", + "icon": "http://s1.bdstatic.com/r/www/aladdin/img/new_weath/bigicon/5.png", + "pm25": "132", + "pm_level": "轻度污染", + "temp": "11℃~25℃", + "time": "周四 04月06日", + "weather": "多云转阴", + "wind": "南风微风" + }, + { + "icon": "http://s1.bdstatic.com/r/www/aladdin/img/new_weath/icon/3.png", + "temp": "14℃~22℃", + "time": "周五 04月07日", + "weather": "阴", + "wind": "南风微风" + }, + { + "icon": "http://s1.bdstatic.com/r/www/aladdin/img/new_weath/icon/5.png", + "temp": "7℃~19℃", + "time": "周六 04月08日", + "weather": "多云", + "wind": "南风微风" + }, + { + "icon": "http://s1.bdstatic.com/r/www/aladdin/img/new_weath/icon/5.png", + "temp": "10℃~20℃", + "time": "周日 04月09日", + "weather": "多云转阴", + "wind": "南风微风" + }, + { + "icon": "http://s1.bdstatic.com/r/www/aladdin/img/new_weath/icon/3.png", + "temp": "10℃~21℃", + "time": "周一 04月10日", + "weather": "阴转晴", + "wind": "南风微风" + } + ] + } + }, + "bot_id": "duer_weather", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "list", + "list": [ + { + "title": "北京市今天多云转阴", + "summary": "实时:14℃\n温度:11℃~25℃\n风力:南风微风\n空气质量指数:132,轻度污染\n来源:中国天气网", + "url": "https://m.baidu.com/from=2001a/s?word=北京市天气", + "image": "http://xiaodu.baidu.com/img/pic?pic_id=47950952" + } + ] + } + ], + "nlu": { + "domain": "duer_weather", + "intent": "sys_weather", //(还包括:SYS_AQI(空气指数)、SYS_CLOTHES(穿衣指数)、SYS_RAIN(下雨天)、SYS_SNOW(下雪天) +、SYS_SUNNY(晴天)、SYS_TEMP(温度)、SYS_ULTRAVIOLET(紫外线指数)、SYS_WIND(刮风天)、SYS_LOW_TEMP(低温)、SYS_HIGH_TEMP(高温)、SYS_EXERCISE(运动指数)、SYS_TRIP(旅行指数)、SYS_WASH_CAR(洗车指数)、SYS_INFLUENZA(感冒指数),均为小写 + "slots": { + "loc_city": "北京市", + "loc_province": "北京市", + "time": "2017-04-06,2017-04-06" + } + }, + "speech": { + "type": "Text", + "content": "北京今天多云转阴,11℃~25℃,南风微风。空气质量指数为132,轻度污染。" + } + }, + "id": "1491444790_995cbnd5u", + "logid": "14914447905270", + "user_id": "test", + "time": 1491444790, + "cuid": null, + "se_query": "天气咋样", + "msg": "ok", + "status": 0 +} +```
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/bot/fridge.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,455 @@ +fridge 类,目前没有多轮交互,而且只支持query理解,不会返回内容,所以请忽略除[nlu](../OPENAPI_README.md#nlu)结构外的其他字段 + +所以以下示例,返回值只是.result.nlu的内容,先放一个完整内容的示例 + +```javascript +{ + "result": { + "bot_id": "fridge", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "度秘为你找到如下结果" + } + ], + "nlu": { + "domain": "fridge", + "intent": "fridge.setting.temperature", + "slots": { + "room": "冷藏室", + "set_temp": "1" + } + }, + "speech": { + "type": "Text", + "content": "度秘为你找到如下结果" + } + }, + "id": "1485070067_3463wp76x", + "logid": "14850700666625", + "user_id": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "time": 1485070067, + "cuid": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "se_query": "冷藏室的温度设置到1度", + "msg": "ok", + "status": 0 +} +``` + +### fridge.setting.temperature 调温度 +可能的slots: + +slot key|slot value +--------|---------- +room|冷冻 冷藏 保鲜 速冻 变温 恒温 +temp_set|温度设置,如“设为” +set_temp|设置温度值,如“1” +temp_down|温度变小 +temp_down_size|温度变小幅度 +temp_up|温度增加 +temp_up_size|温度增加幅度 +temp_negative|代表温度为负值,如“零下” + + +冷藏室的温度设置到零下1度 +```javascript +{ + "domain": "fridge", + "intent": "fridge.setting.temperature", + "slots": { + "room": "冷藏室", + "temp_set": "设置", + "set_temp": "1", + "temp_negative": "零下" + } +} +``` +冷藏室的温度降低一点 +```javascript +{ + "domain": "fridge", + "intent": "fridge.setting.temperature", + "slots": { + "room": "冷藏室", + "temp_down": "降低" + } +} +``` + +### fridge.app.market 商城相关 +slot key|slot value +--------|---------- +action|add/del +cart|购物车 +name|订单 +category|虾/苹果 + +打开商城、商城最近有什么活动 +```javascript +{ + "domain": "fridge", + "intent": "fridge.app.market", + "slots": {} +} +``` + +查看订单 +```javascript +{ + "domain": "fridge", + "intent": "fridge.app.market", + "slots": { + "order": "查看订单" + } +} +``` + +查看购物车 +```javascript +{ + "domain": "fridge", + "intent": "fridge.app.market", + "slots": { + "cart": "查看购物车" + } +} +``` + +我要买虾 +我要买水果 + +```javascript +{ + "domain": "fridge", + "intent": "fridge.app.market", + "slots": { + "category": "虾" + } +} +``` + + +### fridge.food.manage 食材管理 +slot key|slot value +--------|---------- +name|食材名字 +action|add/del/update +expire_day|过期时间(天) + + +帮我添加苹果 +把苹果放入冰箱 +```javascript +{ + "domain": "fridge", + "intent": "fridge.food.manage", + "slots": { + "action": "add", + "name": "苹果" + } +} +``` + +删除苹果 +```javascript +{ + "domain": "fridge", + "intent": "fridge.food.manage", + "slots": { + "action": "del", + "name": "苹果" + } +} +``` + +今天买个苹果,保质期1天 +```javascript +{ + "domain": "fridge", + "intent": "fridge.food.manage", + "slots": { + "add": "买", + "expire_day": "1", + "name": "苹果" + } +} +``` + + +### fridge.food.search 食材查询 +slot key|slot value +--------|---------- +name|食材名字 +expired|已过期 +expiring|快过期 +normal|正常 +fresh|新鲜 +not_expire|未过期 + +冰箱里有什么呀? +```javascript +{ + "domain": "fridge", + "intent": "fridge.food.search", + "slots": {} +} +``` + +新鲜的食材有哪些 +```javascript +{ + "domain": "fridge", + "intent": "fridge.food.search", + "slots": { + "fresh": "新鲜" + } +} +``` + +有哪些食材快过期了 +```javascript +{ + "domain": "fridge", + "intent": "fridge.food.search", + "slots": { + "expiring": "快过期" + } +} +``` + +鸡蛋什么时候过期 +```javascript +{ + "domain": "fridge", + "intent": "fridge.food.search", + "slots": { + "not_expire": "过期", + "name": "鸡蛋" + } +} +``` + +### fridge.info.agreement 查看用户协议 +看看用户协议 +用户协议是什么 +用户协议有什么啊 +看一下用户协议 +```javascript +{ + "domain": "fridge", + "intent": "fridge.info.agreement", + "slots": {} +} +``` + +### fridge.info.service 查看服务 +服务是什么 +```javascript +{ + "domain": "fridge", + "intent": "fridge.info.service", + "slots": {} +} +``` + + +### fridge.info.version 查看系统版本 +现在系统是什么版本 +```javascript +{ + "domain": "fridge", + "intent": "fridge.info.version", + "slots": {} +} +``` + + +### fridge.setting.address 设置用户地址 +我现在的地址是哪里 +```javascript +{ + "domain": "fridge", + "intent": "fridge.setting.address", + "slots": {} +} +``` + + +### fridge.setting.room 冷冻、xx室控制 + +slot key|slot value +--------|---------- +room| 冷冻 制冷 冷藏 +open| 打开冰箱舱室,如“开启” +close | 关闭冰箱舱室,如“关闭” + +关闭冷冻室 +```javascript +{ + "domain": "fridge", + "intent": "fridge.setting.room", + "slots": { + "close": "关闭", + "room": "冷冻" + } +} +``` + + +### fridge.setting.mode 设置冰箱模式 + +slot key|slot value +--------|---------- +mode| 自动 智能 速冻 休眠 假日 速冷 微冻 零度 冷饮 干货 +open| 打开冰箱模式,如“开启” +close | 关闭冰箱模式,如“关闭” + +进入速冻模式 +```javascript +{ + "domain": "fridge", + "intent": "fridge.setting.mode", + "slots": { + "mode": "速冻", + "open": "进入" + } +} +``` + +关闭速冻模式 +```javascript +{ + "domain": "fridge", + "intent": "fridge.setting.mode", + "slots": { + "close": "关闭", + "mode": "速冻" + } +} +``` + + +### fridge.setting.phone_bind 绑定手机 +我该怎么绑定 +怎么绑定APP +手机怎么控制冰箱 +绑定教程看一下 +看一下绑定教程 +```javascript +{ + "domain": "fridge", + "intent": "fridge.setting.phone_bind", + "slots": { + "mode": "速冻" + } +} +``` + + +### fridge.connect +冰箱绑定了哪些设备 +```javascript +{ + "domain": "fridge", + "intent": "fridge.connect", + "slots": {} +} +``` + + +### fridge.setting.app + +slot key|slot value +--------|---------- +app | 代表应用名 +open | 代表`打开`的操作意图 +close | 代表`关闭`的操作意图 + +系统设置/打开我的/打开消息中心 +```javascript +{ + "domain": "fridge", + "intent": "fridge.setting.app", + "slots": { + "app": "我的", + "open": "打开", + } +} +``` + + +### fridge.image.recognition 图像识别 +识别食材 +```javascript +{ + "domain": "fridge", + "intent": "fridge.image.recognition", + "slots": {} +} +``` + +### fridge.exit +退出 +拜拜 +```javascript +{ + "domain": "fridge", + "intent": "fridge.exit", + "slots": {} +} +``` + +### fridge.back.last +返回 +上一页 +```javascript +{ + "domain": "fridge", + "intent": "fridge.back.last", + "slots": {} +} +``` + +### fridge.back.home +回到首页 +```javascript +{ + "domain": "fridge", + "intent": "fridge.back.home", + "slots": {} +} +``` + +### fridge.info.function +功能介绍 +```javascript +{ + "domain": "fridge", + "intent": "fridge.info.function", + "slots": {} +} +``` + +### control.hardware.screen.bright + +slot key|slot value +--------|---------- +up | 代表亮度变大 +down | 代表亮度变小 +bright_set_size|max: 代表最大音量;min: 代表最小音量 + +屏幕太暗 +```javascript +{ + "domain": "control.hardware", + "intent": "control.hardware.screen.bright", + "slots": { + "up": "太暗" + } +} +```
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/bot/image_satisfy.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,50 @@ +image_satisfy 图片搜索(多模sdk),需要用多模sdk上传图片 + +所以以下示例,先放一个完整内容的示例 + +```javascript +{ + "result": { + "resource": { + "type": "image_satisfy", + "data": { + "hasResult": false, + "category": "question", + "url": "https://graph.baidu.com/s?tn=bdbox&sign=051fcfcf7f7d0c540b9f411487143582&session=YToxOntzOjEyOiJ0YW5zbGF0ZVNpZ24iO3M6MzI6IjA1MWZjZmNmN2Y3ZDBjNTQwYjlmNDExNDg3MTQzNTgyIjt9&f=question&itype=1&idctag=tc&bdImageExist=1&sids=10010_10026_10028_10002_10005_10101_10201_9999&logid=1582752350&uid=D5169D3E7F26822D7A7CC5C07D5AB3AD%7CDBB0AA0500001A&network=1_0&sdk_source=d18735b0316d01c62e65d8e5f4627398&sdk_version=1.0.0&sdk_ua=NzIwXzEyODBfYW5kcm9pZF81LjFfMzIw&sdk_ut=dml2byBWM00gQV81LjFfdml2bw%3D%3D&origin_version=1.0", + "imgUrl": "http://graph.baidu.com/resource/051fcfcf7f7d0c540b9f411487143582.jpg" + } + }, + "bot_id": "image_satisfy", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "抱歉,未能找到图片中的题目。度秘教你如何拍照搜题。", + "url": "https://graph.baidu.com/s?tn=bdbox&sign=051fcfcf7f7d0c540b9f411487143582&session=YToxOntzOjEyOiJ0YW5zbGF0ZVNpZ24iO3M6MzI6IjA1MWZjZmNmN2Y3ZDBjNTQwYjlmNDExNDg3MTQzNTgyIjt9&f=question&itype=1&idctag=tc&bdImageExist=1&sids=10010_10026_10028_10002_10005_10101_10201_9999&logid=1582752350&uid=D5169D3E7F26822D7A7CC5C07D5AB3AD%7CDBB0AA0500001A&network=1_0&sdk_source=d18735b0316d01c62e65d8e5f4627398&sdk_version=1.0.0&sdk_ua=NzIwXzEyODBfYW5kcm9pZF81LjFfMzIw&sdk_ut=dml2byBWM00gQV81LjFfdml2bw%3D%3D&origin_version=1.0" + } + ], + "nlu": { + "domain": "unknown", + "intent": "unknown", + "slots": {} + }, + "speech": { + "type": "Text", + "content": "抱歉,未能找到图片中的题目。度秘教你如何拍照搜题。" + } + }, + "id": "1487214979_502aqt86i", + "logid": "14872149798917", + "user_id": "3596403", + "time": 1487214979, + "cuid": "D5169D3E7F26822D7A7CC5C07D5AB3AD|DBB0AA0500001A", + "se_query": "http://graph.baidu.com/resource/051fcfcf7f7d0c540b9f411487143582.jpg", + "msg": "ok", + "status": 0 +} +``` +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/bot/information_genernal.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,1318 @@ +# 通用信息输出schema + +## 百科 +```javascript +//query = 刘德华 +{ + "result": { + "hint": [ + "梁朝伟和刘德华的演技谁比较好?", + "刘德华:一位我追了十二年的偶像", + "刘德华的八卦新闻", + "刘德华和周杰伦为什么不开微博?", + "刘德华电影全集国语优酷", + "刘德华演唱会" + ], + "nlu": { + "domain": "universal_search", + "intent": "baike", + "slots": {} + }, + "resource": { + "data": { + "image": "http://t12.baidu.com/it/u=2052923039,2278194179&fm=58&bpow=960&bpoh=633&u_exp_0=1993718624,2011089295&fm_exp_0=86", + "introduction": "刘德华(Andy Lau),1961年9月27日出生于中国香港,演员、歌手、作词人、制片人。1981年出演电影处女作《彩云曲》。1983年主演的武侠剧《神雕侠侣》在香港获得62点的收视纪录。1985年因拒签五年合约而被TVB雪藏。1988年将事业重心转向电影。1991年创办天幕电影公司。1994年担任剧情片《天与地》的制片人。2000年凭借警匪片《暗战》获得第19届香港电影金像奖最佳男主角奖。2004年凭借警匪片《无间道3:终极无间》获得第41届台湾金马奖最佳男主角奖。2005年获得香港UA院线颁发的“1985-2005年全港最高累积票房香港男演员”奖。2006年获得釜山国际电影节亚洲最有贡献电影人奖。2011年主演剧情片《桃姐》,并凭借该片先后获得台湾金马奖最佳男主角奖、香港电影金像奖最佳男主角奖;同年担任第49届台湾电影金马奖评审团主席。2017年主演警匪动作片《拆弹专家》", + "media_url_new": null, + "speech": "刘德华(Andy Lau),1961年9月27日出生于中国香港,演员、歌手、作词人、制片人。1981年出演电影处女作《彩云曲》。1983年主演的武侠剧《神雕侠侣》在香港获得62点的收视纪录。1985年因拒签五年合约而被TVB雪藏。1988年将事业重心转向电影。1991年创办天幕电影公司。1994年担任剧情片《天与地》的制片人。2000年凭借警匪片《暗战》获得第19届香港电影金像奖最佳男主角奖。2004年凭借警匪片《无间道3:终极无间》获得第41届台湾金马奖最佳男主角奖。2005年获得香港UA院线颁发的“1985-2005年全港最高累积票房香港男演员”奖。2006年获得釜山国际电影节亚洲最有贡献电影人奖。2011年主演剧情片《桃姐》,并凭借该片先后获得台湾金马奖最佳男主角奖、香港电影金像奖最佳男主角奖;同年担任第49届台湾电影金马奖评审团主席。2017年主演警匪动作片《拆弹专家》", + "title": "刘德华", + "url": "http://baike.baidu.com/item/%E5%88%98%E5%BE%B7%E5%8D%8E/114923" + }, + "type": "baike" + }, + "bot_id": "aries_general", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "list", + "list": [ + { + "title": "刘德华", + "summary": "刘德华(Andy Lau),1961年9月27日出生于中国香港,演员、歌手、作词人、制片人。1981年出演电影处女作《彩云曲》。1983年主演的武侠剧《神雕侠侣》在香港获得62点的收视纪录。1985年因拒签五年合约而被TVB雪藏。1988年将事业重心转向电影。1991年创办天幕电影公司。1994年担任剧情片《天与地》的制片人。2000年凭借警匪片《暗战》获得第19届香港电影金像奖最佳男主角奖。2004年凭借警匪片《无间道3:终极无间》获得第41届台湾金马奖最佳男主角奖。2005年获得香港UA院线颁发的“1985-2005年全港最高累积票房香港男演员”奖。2006年获得釜山国际电影节亚洲最有贡献电影人奖。2011年主演剧情片《桃姐》,并凭借该片先后获得台湾金马奖最佳男主角奖、香港电影金像奖最佳男主角奖;同年担任第49届台湾电影金马奖评审团主席。2017年主演警匪动作片《拆弹专家》", + "url": "https://ss0.baidu.com/9rM4dzva2gU2pMbgoY3K/item/%E5%88%98%E5%BE%B7%E5%8D%8E/114923", + "image": "https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=2052923039,2278194179&fm=58&bpow=960&bpoh=633&u_exp_0=1993718624,2011089295&fm_exp_0=86" + } + ] + } + ], + "speech": { + "type": "Text", + "content": "刘德华(Andy Lau),1961年9月27日出生于中国香港,演员、歌手、作词人、制片人。1981年出演电影处女作《彩云曲》。1983年主演的武侠剧《神雕侠侣》在香港获得62点的收视纪录。1985年因拒签五年合约而被TVB雪藏。1988年将事业重心转向电影。1991年创办天幕电影公司。1994年担任剧情片《天与地》的制片人。2000年凭借警匪片《暗战》获得第19届香港电影金像奖最佳男主角奖。2004年凭借警匪片《无间道3:终极无间》获得第41届台湾金马奖最佳男主角奖。2005年获得香港UA院线颁发的“1985-2005年全港最高累积票房香港男演员”奖。2006年获得釜山国际电影节亚洲最有贡献电影人奖。2011年主演剧情片《桃姐》,并凭借该片先后获得台湾金马奖最佳男主角奖、香港电影金像奖最佳男主角奖;同年担任第49届台湾电影金马奖评审团主席。2017年主演警匪动作片《拆弹专家》" + } + }, + "id": "1499346291_835e16mgq", + "logid": "14993462911180", + "user_id": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "time": 1499346291, + "cuid": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138123", + "se_query": "刘德华", + "msg": "ok", + "client_msg_id": "c9bfe944-992b-45b1-8afe-dc2cdaee622a", + "status": 0, + "timeuse": 321 +} + +//query = 刘德华(纯文本输出) +{ + "result": { + "hint": [ + "梁朝伟和刘德华的演技谁比较好?", + "刘德华:一位我追了十二年的偶像", + "刘德华的八卦新闻", + "刘德华和周杰伦为什么不开微博?", + "刘德华电影全集国语优酷", + "刘德华演唱会" + ], + "nlu": { + "domain": "universal_search", + "intent": "baike", + "slots": {} + }, + "resource": { + "data": { + "image": "http://t12.baidu.com/it/u=2052923039,2278194179&fm=58&bpow=960&bpoh=633&u_exp_0=1993718624,2011089295&fm_exp_0=86", + "introduction": "刘德华(Andy Lau),1961年9月27日出生于中国香港,演员、歌手、作词人、制片人。1981年出演电影处女作《彩云曲》。1983年主演的武侠剧《神雕侠侣》在香港获得62点的收视纪录。1985年因拒签五年合约而被TVB雪藏。1988年将事业重心转向电影。1991年创办天幕电影公司。1994年担任剧情片《天与地》的制片人。2000年凭借警匪片《暗战》获得第19届香港电影金像奖最佳男主角奖。2004年凭借警匪片《无间道3:终极无间》获得第41届台湾金马奖最佳男主角奖。2005年获得香港UA院线颁发的“1985-2005年全港最高累积票房香港男演员”奖。2006年获得釜山国际电影节亚洲最有贡献电影人奖。2011年主演剧情片《桃姐》,并凭借该片先后获得台湾金马奖最佳男主角奖、香港电影金像奖最佳男主角奖;同年担任第49届台湾电影金马奖评审团主席。2017年主演警匪动作片《拆弹专家》", + "media_url_new": null, + "speech": "刘德华(Andy Lau),1961年9月27日出生于中国香港,演员、歌手、作词人、制片人。1981年出演电影处女作《彩云曲》。1983年主演的武侠剧《神雕侠侣》在香港获得62点的收视纪录。1985年因拒签五年合约而被TVB雪藏。1988年将事业重心转向电影。1991年创办天幕电影公司。1994年担任剧情片《天与地》的制片人。2000年凭借警匪片《暗战》获得第19届香港电影金像奖最佳男主角奖。2004年凭借警匪片《无间道3:终极无间》获得第41届台湾金马奖最佳男主角奖。2005年获得香港UA院线颁发的“1985-2005年全港最高累积票房香港男演员”奖。2006年获得釜山国际电影节亚洲最有贡献电影人奖。2011年主演剧情片《桃姐》,并凭借该片先后获得台湾金马奖最佳男主角奖、香港电影金像奖最佳男主角奖;同年担任第49届台湾电影金马奖评审团主席。2017年主演警匪动作片《拆弹专家》", + "title": "刘德华", + "url": "http://baike.baidu.com/item/%E5%88%98%E5%BE%B7%E5%8D%8E/114923" + }, + "type": "baike" + }, + "bot_id": "aries_general", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "刘德华(Andy Lau),1961年9月27日出生于中国香港,演员、歌手、作词人、制片人。1981年出演电影处女作《彩云曲》。1983年主演的武侠剧《神雕侠侣》在香港获得62点的收视纪录。1985年因拒签五年合约而被TVB雪藏。1988年将事业重心转向电影。1991年创办天幕电影公司。1994年担任剧情片《天与地》的制片人。2000年凭借警匪片《暗战》获得第19届香港电影金像奖最佳男主角奖。2004年凭借警匪片《无间道3:终极无间》获得第41届台湾金马奖最佳男主角奖。2005年获得香港UA院线颁发的“1985-2005年全港最高累积票房香港男演员”奖。2006年获得釜山国际电影节亚洲最有贡献电影人奖。2011年主演剧情片《桃姐》,并凭借该片先后获得台湾金马奖最佳男主角奖、香港电影金像奖最佳男主角奖;同年担任第49届台湾电影金马奖评审团主席。2017年主演警匪动作片《拆弹专家》" + } + ], + "speech": { + "type": "Text", + "content": "刘德华(Andy Lau),1961年9月27日出生于中国香港,演员、歌手、作词人、制片人。1981年出演电影处女作《彩云曲》。1983年主演的武侠剧《神雕侠侣》在香港获得62点的收视纪录。1985年因拒签五年合约而被TVB雪藏。1988年将事业重心转向电影。1991年创办天幕电影公司。1994年担任剧情片《天与地》的制片人。2000年凭借警匪片《暗战》获得第19届香港电影金像奖最佳男主角奖。2004年凭借警匪片《无间道3:终极无间》获得第41届台湾金马奖最佳男主角奖。2005年获得香港UA院线颁发的“1985-2005年全港最高累积票房香港男演员”奖。2006年获得釜山国际电影节亚洲最有贡献电影人奖。2011年主演剧情片《桃姐》,并凭借该片先后获得台湾金马奖最佳男主角奖、香港电影金像奖最佳男主角奖;同年担任第49届台湾电影金马奖评审团主席。2017年主演警匪动作片《拆弹专家》" + } + }, + "id": "1499346414_3836gdsao", + "logid": "14993464144485", + "user_id": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "time": 1499346414, + "cuid": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138123", + "se_query": "刘德华", + "msg": "ok", + "client_msg_id": "c9bfe944-992b-45b1-8afe-dc2cdaee622a", + "status": 0, + "timeuse": 251 +} +``` +## 限行 +```javascript +//今日限行 +{ + "result": { + "nlu": { + "domain": "universal_search", + "intent": "traffic_limit", + "slots": {} + }, + "bot_id": "aries_general", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "list", + "list": [ + { + "title": "为你找到以下图片", + "image": "http://xiaodu.baidu.com/img/pic?pic_id=54261165", + "url": "http://justfortest.nj.m.baidu.com/uiapi/f24b0b/aladdin.html?from=1009717l&cip=61.135.169.80&count=1&os=1&usdata=1&target=_blank&word=%E5%8C%97%E4%BA%AC%E5%B8%82%E4%BB%8A%E6%97%A5%E9%99%90%E8%A1%8C&loc=%7B%22crd%22%3A%2212957817.404506_4829433.130120_200%22%2C%22city%22%3A%22%5Cu5317%5Cu4eac%5Cu5e02%22%2C%22addr%22%3A%22%5Cu5317%5Cu4eac%5Cu5e02%5Cu897f%5Cu57ce%5Cu533a%5Cu897f%5Cu697c%5Cu5df715%5Cu53f7%22%2C%22city_code%22%3A131%7D&give=chezhu_limit&pu=sz%401320_480%2Ccua%40_avLC_aE-i4qywoUfpw1zyaBXi4Xa2iLA%2Ccut%40_u2g8juSvh_Dh2IJgNvHtyN6moi5pQqAC%2Cosname%40baiduboxapp%2Cctv%402%2Ccfrom%40757b%2Ccen%40cuid_cua_cut%2Ccsrc%40app_dumi_voice" + } + ] + } + ], + "speech": { + "type": "Text", + "content": "北京今日限行尾号为5和0" + } + }, + "id": "1497432721_922dgzprz", + "logid": "14974327215379", + "user_id": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "time": 1497432721, + "cuid": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138123", + "se_query": "今日限行", + "msg": "ok", + "client_msg_id": "c9bfe944-992b-45b1-8afe-dc2cdaee622a", + "status": 0, + "timeuse": 536 +} + +//今日限行(纯文本输出) +{ + "result": { + "nlu": { + "domain": "universal_search", + "intent": "traffic_limit", + "slots": {} + }, + "bot_id": "aries_general", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "北京今日限行尾号为5和0" + } + ], + "speech": { + "type": "Text", + "content": "北京今日限行尾号为5和0" + } + }, + "id": "1497432788_263bu5naw", + "logid": "14974327888613", + "user_id": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "time": 1497432788, + "cuid": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138123", + "se_query": "今日限行", + "msg": "ok", + "client_msg_id": "c9bfe944-992b-45b1-8afe-dc2cdaee622a", + "status": 0, + "timeuse": 253 +} +``` +## 股票 +```javascript +//百度股价 +{ + "result": { + "nlu": { + "domain": "universal_search", + "intent": "stock", + "slots": {} + }, + "resource": { + "data": { + "ExtendedLocation": "", + "OriginQuery": "百度股价", + "TitleSuffix": "test", + "appinfo": "", + "dispNum": 3, + "fetchkey": "百度股价", + "listNum": 3, + "normdisp": 1, + "open_query_uri": "code", + "open_resource_name": "stock_meigu", + "otherinfo": "{}", + "resNum": 3, + "resourceid": "8191", + "result": [ + { + "change": "-0.87(-0.48%)", + "code": "BIDU", + "current_price": "179.19", + "info": [ + { + "color": "#0f990f", + "name": "今开", + "value": "181.52" + }, + { + "color": "", + "name": "昨收", + "value": "180.06" + }, + { + "color": "#0f990f", + "name": "最高", + "value": "181.52" + }, + { + "color": "#f54545", + "name": "最低", + "value": "177.24" + }, + { + "color": "", + "name": "成交量", + "value": "257.12万" + }, + { + "color": "", + "name": "市盈率", + "value": "39.73" + }, + { + "color": "", + "name": "每股收益", + "value": "4.51" + }, + { + "color": "", + "name": "总市值", + "value": "619.33亿" + }, + { + "color": "", + "name": "换手率", + "value": "0.72%" + } + ], + "name": "百度", + "time": "2017/06/13 16:00:00", + "trade_condition": "收盘" + }, + { + "change": "", + "code": "BIDU", + "current_price": "", + "info": "", + "name": "百度", + "time": "", + "trade_condition": "收盘" + }, + { + "change": "", + "code": "BIDU", + "current_price": "", + "info": "", + "name": "百度", + "time": "", + "trade_condition": "收盘" + } + ], + "showlamp": "1", + "speech": "百度现在179.19美元,跌幅0.48%,已收盘", + "template_pattern_demand_index": 0, + "term_demand": -1, + "tplt": "stockdynamic_moretab", + "url": "http://xueqiu.com/S/BIDU" + }, + "type": "stock" + }, + "bot_id": "aries_general", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "list", + "list": [ + { + "title": "为你找到以下图片", + "image": "http://xiaodu.baidu.com/img/pic?pic_id=54261558", + "url": "http://justfortest.nj.m.baidu.com/uiapi/4fb32b/aladdin.html?from=1009717l&cip=61.135.169.80&count=1&os=1&usdata=1&target=_blank&word=%E7%99%BE%E5%BA%A6%E8%82%A1%E4%BB%B7&give=stockdynamic_moretab&pu=sz%401320_480%2Ccua%40_avLC_aE-i4qywoUfpw1zyaBXi4Xa2iLA%2Ccut%40_u2g8juSvh_Dh2IJgNvHtyN6moi5pQqAC%2Cosname%40baiduboxapp%2Cctv%402%2Ccfrom%40757b%2Ccen%40cuid_cua_cut%2Ccsrc%40app_dumi_voice" + } + ] + } + ], + "speech": { + "type": "Text", + "content": "百度现在179.19美元,跌幅0.48%,已收盘" + } + }, + "id": "1497432815_56230jij0", + "logid": "14974328157567", + "user_id": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "time": 1497432815, + "cuid": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138123", + "se_query": "百度股价", + "msg": "ok", + "client_msg_id": "c9bfe944-992b-45b1-8afe-dc2cdaee622a", + "status": 0, + "timeuse": 304 +} + +//百度股价(纯文本输出) +{ + "result": { + "nlu": { + "domain": "universal_search", + "intent": "stock", + "slots": {} + }, + "resource": { + "data": { + "ExtendedLocation": "", + "OriginQuery": "百度股价", + "TitleSuffix": "test", + "appinfo": "", + "dispNum": 3, + "fetchkey": "百度股价", + "listNum": 3, + "normdisp": 1, + "open_query_uri": "code", + "open_resource_name": "stock_meigu", + "otherinfo": "{}", + "resNum": 3, + "resourceid": "8191", + "result": [ + { + "change": "-0.87(-0.48%)", + "code": "BIDU", + "current_price": "179.19", + "info": [ + { + "color": "#0f990f", + "name": "今开", + "value": "181.52" + }, + { + "color": "", + "name": "昨收", + "value": "180.06" + }, + { + "color": "#0f990f", + "name": "最高", + "value": "181.52" + }, + { + "color": "#f54545", + "name": "最低", + "value": "177.24" + }, + { + "color": "", + "name": "成交量", + "value": "257.12万" + }, + { + "color": "", + "name": "市盈率", + "value": "39.73" + }, + { + "color": "", + "name": "每股收益", + "value": "4.51" + }, + { + "color": "", + "name": "总市值", + "value": "619.33亿" + }, + { + "color": "", + "name": "换手率", + "value": "0.72%" + } + ], + "name": "百度", + "time": "2017/06/13 16:00:00", + "trade_condition": "收盘" + }, + { + "change": "", + "code": "BIDU", + "current_price": "", + "info": "", + "name": "百度", + "time": "", + "trade_condition": "收盘" + }, + { + "change": "", + "code": "BIDU", + "current_price": "", + "info": "", + "name": "百度", + "time": "", + "trade_condition": "收盘" + } + ], + "showlamp": "1", + "speech": "百度现在179.19美元,跌幅0.48%,已收盘", + "template_pattern_demand_index": 0, + "term_demand": -1, + "tplt": "stockdynamic_moretab", + "url": "http://xueqiu.com/S/BIDU" + }, + "type": "stock" + }, + "bot_id": "aries_general", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "百度现在179.19美元,跌幅0.48%,已收盘" + } + ], + "speech": { + "type": "Text", + "content": "百度现在179.19美元,跌幅0.48%,已收盘" + } + }, + "id": "1497432995_2025f7lyn", + "logid": "14974329946093", + "user_id": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "time": 1497432995, + "cuid": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138123", + "se_query": "百度股价", + "msg": "ok", + "client_msg_id": "c9bfe944-992b-45b1-8afe-dc2cdaee622a", + "status": 0, + "timeuse": 244 +} +``` +## 汇率 +```javascript +//人民币和美元汇率 +{ + "result": { + "nlu": { + "domain": "universal_search", + "intent": "exchange_rate", + "slots": {} + }, + "resource": { + "data": { + "exchange_amount": "1人民币元=0.1472美元", + "exchange_currency": "美元", + "exchange_ratio": "1人民币元=0.1472美元", + "original_amount": null, + "original_currency": "人民币元", + "speech": "1元人民币等于0.1472美元" + }, + "type": "exchange" + }, + "bot_id": "aries_general", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "list", + "list": [ + { + "title": "为你找到以下图片", + "image": "http://xiaodu.baidu.com/img/pic?pic_id=54262028", + "url": "https://sp3.baidu.com/84oIbT3kAMgDnd_/&pu=sz%401320_480%2Ccua%40_avLC_aE-i4qywoUfpw1zyaBXi4Xa2iLA%2Ccut%40_u2g8juSvh_Dh2IJgNvHtyN6moi5pQqAC%2Cosname%40baiduboxapp%2Cctv%402%2Ccfrom%40757b%2Ccen%40cuid_cua_cut%2Ccsrc%40app_dumi_voice/s?word=%E4%BA%BA%E6%B0%91%E5%B8%81%E5%92%8C%E7%BE%8E%E5%85%83%E6%B1%87%E7%8E%87&give=bigcard" + } + ] + } + ], + "speech": { + "type": "Text", + "content": "1人民币等于0.1472美元" + } + }, + "id": "1497433040_655f9vaye", + "logid": "14974330402373", + "user_id": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "time": 1497433040, + "cuid": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138123", + "se_query": "人民币和美元汇率", + "msg": "ok", + "client_msg_id": "c9bfe944-992b-45b1-8afe-dc2cdaee622a", + "status": 0, + "timeuse": 521 +} + +//人民币和美元汇率(纯文本输出) +{ + "result": { + "nlu": { + "domain": "universal_search", + "intent": "exchange_rate", + "slots": {} + }, + "resource": { + "data": { + "exchange_amount": "1人民币元=0.1472美元", + "exchange_currency": "美元", + "exchange_ratio": "1人民币元=0.1472美元", + "original_amount": null, + "original_currency": "人民币元", + "speech": "1元人民币等于0.1472美元" + }, + "type": "exchange" + }, + "bot_id": "aries_general", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "1人民币等于0.1472美元" + } + ], + "speech": { + "type": "Text", + "content": "1人民币等于0.1472美元" + } + }, + "id": "1497433087_326bip8ca", + "logid": "14974330872416", + "user_id": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "time": 1497433087, + "cuid": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138123", + "se_query": "人民币和美元汇率", + "msg": "ok", + "client_msg_id": "c9bfe944-992b-45b1-8afe-dc2cdaee622a", + "status": 0, + "timeuse": 217 +} +``` +## 翻译 +```javascript +//手机的翻译 +{ + "result": { + "nlu": { + "domain": "universal_search", + "intent": "translator", + "slots": {} + }, + "resource": { + "data": { + "entry": null, + "example_sentence": null, + "input": "手机怎么翻译", + "paraphrase": [ + "cellphone", + "handset", + "mobile phone", + "Handphone" + ], + "phonetic_symbol": null, + "sound": null, + "speech": "1 cellphone; 2 handset; 3 mobile phone; 4 Handphone; ", + "url": "http://fanyi.baidu.com/#zh/en/%E6%89%8B%E6%9C%BA" + }, + "type": "translator" + }, + "bot_id": "aries_general", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "list", + "list": [ + { + "title": "为你找到以下图片", + "image": "http://xiaodu.baidu.com/img/pic?pic_id=56993341", + "url": "http://justfortest.nj.m.baidu.com/uiapi/0238fc/aladdin.html?from=1009717l&cip=61.135.169.80&count=1&os=1&usdata=1&target=_blank&word=%E6%89%8B%E6%9C%BA%E6%80%8E%E4%B9%88%E7%BF%BB%E8%AF%91&loc=%7B%22crd%22%3A%2212957817.404497_4829433.051660_200%22%2C%22city%22%3A%22%5Cu5317%5Cu4eac%5Cu5e02%22%2C%22addr%22%3A%22%5Cu5317%5Cu4eac%5Cu5e02%5Cu897f%5Cu57ce%5Cu533a%5Cu897f%5Cu697c%5Cu5df715%5Cu53f7%22%2C%22city_code%22%3A131%7D&give=dictwisenew&pu=sz%401320_480%2Ccua%40_avLC_aE-i4qywoUfpw1zyaBXi4Xa2iLA%2Ccut%40_u2g8juSvh_Dh2IJgNvHtyN6moi5pQqAC%2Cosname%40baiduboxapp%2Cctv%402%2Ccfrom%40757b%2Ccen%40cuid_cua_cut%2Ccsrc%40app_dumi_voice" + } + ] + } + ], + "speech": { + "type": "Text", + "content": "1 cellphone; 2 handset; 3 mobile phone; 4 Handphone; " + } + }, + "id": "1499346487_0864f1l85", + "logid": "14993464864465", + "user_id": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "time": 1499346487, + "cuid": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138123", + "se_query": "手机的翻译", + "msg": "ok", + "client_msg_id": "c9bfe944-992b-45b1-8afe-dc2cdaee622a", + "status": 0, + "timeuse": 606 +} +//手机的翻译(纯文本输出) +{ + "result": { + "nlu": { + "domain": "universal_search", + "intent": "translator", + "slots": {} + }, + "resource": { + "data": { + "entry": null, + "example_sentence": null, + "input": "手机怎么翻译", + "paraphrase": [ + "cellphone", + "handset", + "mobile phone", + "Handphone" + ], + "phonetic_symbol": null, + "sound": null, + "speech": "1 cellphone; 2 handset; 3 mobile phone; 4 Handphone; ", + "url": "http://fanyi.baidu.com/#zh/en/%E6%89%8B%E6%9C%BA" + }, + "type": "translator" + }, + "bot_id": "aries_general", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "1 cellphone; 2 handset; 3 mobile phone; 4 Handphone; " + } + ], + "speech": { + "type": "Text", + "content": "1 cellphone; 2 handset; 3 mobile phone; 4 Handphone; " + } + }, + "id": "1499346528_705bdvsx1", + "logid": "14993465285169", + "user_id": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "time": 1499346528, + "cuid": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138123", + "se_query": "手机的翻译", + "msg": "ok", + "client_msg_id": "c9bfe944-992b-45b1-8afe-dc2cdaee622a", + "status": 0, + "timeuse": 335 +} +``` +## 计算 +```javascript +//10的平方减去5的立方 +{ + "result": { + "nlu": { + "domain": "universal_search", + "intent": "calculator", + "slots": {} + }, + "resource": { + "data": { + "input": "(10^2)-(5^3)", + "output": "-25", + "speech": "10的平方减5的立方等于负25" + }, + "type": "calculate" + }, + "bot_id": "aries_general", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "list", + "list": [ + { + "title": "为你找到以下图片", + "image": "http://xiaodu.baidu.com/img/pic?pic_id=53990217", + "url": "http://justfortest.nj.m.baidu.com/uiapi/ac60c7/aladdin.html?from=1009717l&cip=61.135.169.80&count=1&os=1&usdata=1&target=_blank&word=10%E7%9A%84%E5%B9%B3%E6%96%B9%E5%87%8F%E5%8E%BB5%E7%9A%84%E7%AB%8B%E6%96%B9&give=calculator&pu=sz%401320_480%2Ccua%40_avLC_aE-i4qywoUfpw1zyaBXi4Xa2iLA%2Ccut%40_u2g8juSvh_Dh2IJgNvHtyN6moi5pQqAC%2Cosname%40baiduboxapp%2Cctv%402%2Ccfrom%40757b%2Ccen%40cuid_cua_cut%2Ccsrc%40app_dumi_voice" + } + ] + } + ], + "speech": { + "type": "Text", + "content": "10的平方减5的立方等于负25" + } + }, + "id": "1497433188_324dkg9kg", + "logid": "14974331874825", + "user_id": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "time": 1497433188, + "cuid": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138123", + "se_query": "10的平方减去5的立方", + "msg": "ok", + "client_msg_id": "c9bfe944-992b-45b1-8afe-dc2cdaee622a", + "status": 0, + "timeuse": 511 +} + +//10的平方减去5的立方(纯文本输出) +{ + "result": { + "nlu": { + "domain": "universal_search", + "intent": "calculator", + "slots": {} + }, + "resource": { + "data": { + "input": "(10^2)-(5^3)", + "output": "-25", + "speech": "10的平方减5的立方等于负25" + }, + "type": "calculate" + }, + "bot_id": "aries_general", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "10的平方减5的立方等于负25" + } + ], + "speech": { + "type": "Text", + "content": "10的平方减5的立方等于负25" + } + }, + "id": "1497433232_64857gw6e", + "logid": "14974332323613", + "user_id": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "time": 1497433232, + "cuid": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138123", + "se_query": "10的平方减去5的立方", + "msg": "ok", + "client_msg_id": "c9bfe944-992b-45b1-8afe-dc2cdaee622a", + "status": 0, + "timeuse": 239 +} +``` +## 时间 +```javascript +//后天是星期几 +{ + "result": { + "nlu": { + "domain": "universal_search", + "intent": "time", + "slots": {} + }, + "resource": { + "data": { + "country": null, + "festival": null, + "festival_arrangement": null, + "location": null, + "lunar_calendar": null, + "solar_calendar": null, + "specific_time": null, + "speech": "后天是星期六,2017年7月8日", + "time_period": null, + "time_zone": null, + "url": null, + "weekday": null + }, + "type": "time" + }, + "bot_id": "aries_general", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "后天是星期六,2017年7月8日" + } + ], + "speech": { + "type": "Text", + "content": "后天是星期六,2017年7月8日" + } + }, + "id": "1499346566_6879o3kh3", + "logid": "14993465669051", + "user_id": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "time": 1499346566, + "cuid": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138123", + "se_query": "后天是星期几", + "msg": "ok", + "client_msg_id": "c9bfe944-992b-45b1-8afe-dc2cdaee622a", + "status": 0, + "timeuse": 290 +} + +//纽约时间(世界时间) +{ + "result": { + "nlu": { + "domain": "universal_search", + "intent": "time", + "slots": {} + }, + "bot_id": "aries_general", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "list", + "list": [ + { + "title": "为你找到以下图片", + "image": "http://xiaodu.baidu.com/img/pic?pic_id=54262904", + "url": "http://justfortest.nj.m.baidu.com/uiapi/659f88/aladdin.html?from=1009717l&cip=61.135.169.80&count=1&os=1&usdata=1&target=_blank&word=%E7%BA%BD%E7%BA%A6%E7%8E%B0%E5%9C%A8%E5%87%A0%E7%82%B9&loc=%7B%22crd%22%3A%2212957817.434604_4829432.738026_200%22%2C%22city%22%3A%22%5Cu5317%5Cu4eac%5Cu5e02%22%2C%22addr%22%3A%22%5Cu5317%5Cu4eac%5Cu5e02%5Cu897f%5Cu57ce%5Cu533a%5Cu897f%5Cu697c%5Cu5df715%5Cu53f7%22%2C%22city_code%22%3A131%7D&give=worldtime&pu=sz%401320_480%2Ccua%40_avLC_aE-i4qywoUfpw1zyaBXi4Xa2iLA%2Ccut%40_u2g8juSvh_Dh2IJgNvHtyN6moi5pQqAC%2Cosname%40baiduboxapp%2Cctv%402%2Ccfrom%40757b%2Ccen%40cuid_cua_cut%2Ccsrc%40app_dumi_voice" + } + ] + } + ], + "speech": { + "type": "Text", + "content": "纽约时间现在是6月14日上午5点43分,星期三,比北京慢了12个小时" + } + }, + "id": "1497433429_777d2xi2v", + "logid": "14974334298067", + "user_id": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "time": 1497433429, + "cuid": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138123", + "se_query": "纽约几点了", + "msg": "ok", + "client_msg_id": "c9bfe944-992b-45b1-8afe-dc2cdaee622a", + "status": 0, + "timeuse": 551 +} +``` +## 诗词问答 +```javascript +//清明时节雨纷纷的下一句 +{ + "result": { + "nlu": { + "domain": "universal_search", + "intent": "kg", + "slots": {} + }, + "resource": { + "data": { + "answer": [ + { + "author": { + "key": "作者", + "value": "杜牧" + }, + "content": { + "key": "全文", + "value": "清明时节雨纷纷,路上行人欲断魂。\n借问酒家何处有?牧童遥指杏花村。" + }, + "dynasty": { + "key": "朝代", + "value": "唐" + }, + "etype": "poemline", + "source": { + "key": "出处", + "value": "清明" + }, + "value": "路上行人欲断魂" + } + ], + "property": "下一句", + "query": "清明时节雨纷纷的下一句", + "source_link": "http://hanyu.baidu.com/shici/detail?pid=62bd01655ee04c60b01c1ee41bce805b&query=%E6%B8%85%E6%98%8E%E6%97%B6%E8%8A%82%E9%9B%A8%E7%BA%B7%E7%BA%B7%E7%9A%84%E4%B8%8B%E4%B8%80%E5%8F%A5&srcid=28239&from=kg2", + "source_name": "百度汉语", + "title": "清明时节雨纷纷的下一句" + }, + "type": "property" + }, + "bot_id": "aries_general", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "清明时节雨纷纷的下一句路上行人欲断魂\n\n全文:\n清明时节雨纷纷,路上行人欲断魂。\n借问酒家何处有?牧童遥指杏花村。", + "url": "http://hanyu.baidu.com/shici/detail?pid=62bd01655ee04c60b01c1ee41bce805b&query=%E6%B8%85%E6%98%8E%E6%97%B6%E8%8A%82%E9%9B%A8%E7%BA%B7%E7%BA%B7%E7%9A%84%E4%B8%8B%E4%B8%80%E5%8F%A5&srcid=28239&from=kg2" + } + ], + "speech": { + "type": "Text", + "content": "清明时节雨纷纷的下一句是路上行人欲断魂" + } + }, + "id": "1499346644_3267wyml0", + "logid": "14993466435013", + "user_id": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "time": 1499346644, + "cuid": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138123", + "se_query": "清明时节雨纷纷的下一句", + "msg": "ok", + "client_msg_id": "c9bfe944-992b-45b1-8afe-dc2cdaee622a", + "status": 0, + "timeuse": 591 +} + +//清明时节雨纷纷的下一句(纯文本输出) +{ + "result": { + "nlu": { + "domain": "universal_search", + "intent": "kg", + "slots": {} + }, + "resource": { + "data": { + "answer": [ + { + "author": { + "key": "作者", + "value": "杜牧" + }, + "content": { + "key": "全文", + "value": "清明时节雨纷纷,路上行人欲断魂。\n借问酒家何处有?牧童遥指杏花村。" + }, + "dynasty": { + "key": "朝代", + "value": "唐" + }, + "etype": "poemline", + "source": { + "key": "出处", + "value": "清明" + }, + "value": "路上行人欲断魂" + } + ], + "property": "下一句", + "query": "清明时节雨纷纷的下一句", + "source_link": "http://hanyu.baidu.com/shici/detail?pid=62bd01655ee04c60b01c1ee41bce805b&query=%E6%B8%85%E6%98%8E%E6%97%B6%E8%8A%82%E9%9B%A8%E7%BA%B7%E7%BA%B7%E7%9A%84%E4%B8%8B%E4%B8%80%E5%8F%A5&srcid=28239&from=kg2", + "source_name": "百度汉语", + "title": "清明时节雨纷纷的下一句" + }, + "type": "property" + }, + "bot_id": "aries_general", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "清明时节雨纷纷的下一句是路上行人欲断魂" + } + ], + "speech": { + "type": "Text", + "content": "清明时节雨纷纷的下一句是路上行人欲断魂" + } + }, + "id": "1499346689_9166axryw", + "logid": "14993466897314", + "user_id": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "time": 1499346689, + "cuid": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138123", + "se_query": "清明时节雨纷纷的下一句", + "msg": "ok", + "client_msg_id": "c9bfe944-992b-45b1-8afe-dc2cdaee622a", + "status": 0, + "timeuse": 349 +} +``` +## 汉字问答 +```javascript +//三个牛是什么字 +{ + "result": { + "nlu": { + "domain": "universal_search", + "intent": "kg", + "slots": {} + }, + "resource": { + "data": { + "answer": [ + { + "definition": { + "key": "释义", + "value": "[bēn]" + }, + "etype": "word", + "spell": { + "key": "拼音", + "value": "[bēn]" + }, + "url": "http://hanyu.baidu.com/zici/s?wd=%E7%8A%87&query=%E4%B8%89%E4%B8%AA%E7%89%9B%E6%98%AF%E4%BB%80%E4%B9%88%E5%AD%97&srcid=28238&from=kg2&from=kg2", + "value": "犇" + } + ], + "query": "三个牛是什么字", + "source_link": "http://hanyu.baidu.com/zici/s?wd=%E7%8A%87&query=%E4%B8%89%E4%B8%AA%E7%89%9B%E6%98%AF%E4%BB%80%E4%B9%88%E5%AD%97&srcid=28238&from=kg2&from=kg2", + "source_name": "百度汉语", + "title": "犇" + }, + "type": "entity" + }, + "bot_id": "aries_general", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "list", + "list": [ + { + "title": "犇_百度汉语", + "summary": "读音: [bēn]\n解释: 同“奔bēn”。", + "url": "http://hanyu.baidu.com/zici/s?wd=%E7%8A%87&query=%E4%B8%89%E4%B8%AA%E7%89%9B%E6%98%AF%E4%BB%80%E4%B9%88%E5%AD%97&srcid=28238&from=kg2&from=kg2", + "image": "https://ss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=3977785258,837525944&fm=58" + } + ] + } + ], + "speech": { + "type": "Text", + "content": "这个字是 犇,意思是同“奔bēn”。" + } + }, + "id": "1499346781_0467yn8e3", + "logid": "14993467803335", + "user_id": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "time": 1499346781, + "cuid": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138123", + "se_query": "三个牛是什么字", + "msg": "ok", + "client_msg_id": "c9bfe944-992b-45b1-8afe-dc2cdaee622a", + "status": 0, + "timeuse": 460 +} +//三个牛是什么字(纯文本) +{ + "result": { + "nlu": { + "domain": "universal_search", + "intent": "kg", + "slots": {} + }, + "resource": { + "data": { + "answer": [ + { + "definition": { + "key": "释义", + "value": "[bēn]" + }, + "etype": "word", + "spell": { + "key": "拼音", + "value": "[bēn]" + }, + "url": "http://hanyu.baidu.com/zici/s?wd=%E7%8A%87&query=%E4%B8%89%E4%B8%AA%E7%89%9B%E6%98%AF%E4%BB%80%E4%B9%88%E5%AD%97&srcid=28238&from=kg2&from=kg2", + "value": "犇" + } + ], + "query": "三个牛是什么字", + "source_link": "http://hanyu.baidu.com/zici/s?wd=%E7%8A%87&query=%E4%B8%89%E4%B8%AA%E7%89%9B%E6%98%AF%E4%BB%80%E4%B9%88%E5%AD%97&srcid=28238&from=kg2&from=kg2", + "source_name": "百度汉语", + "title": "犇" + }, + "type": "entity" + }, + "bot_id": "aries_general", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "这个字是 犇,意思是同“奔bēn”。" + } + ], + "speech": { + "type": "Text", + "content": "这个字是 犇,意思是同“奔bēn”。" + } + }, + "id": "1499346855_763b0zf67", + "logid": "14993468557645", + "user_id": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "time": 1499346855, + "cuid": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138123", + "se_query": "三个牛是什么字", + "msg": "ok", + "client_msg_id": "c9bfe944-992b-45b1-8afe-dc2cdaee622a", + "status": 0, + "timeuse": 339 +} +``` +## 通用搜索 +```javascript +//肚子饿了怎么办 +{ + "result": { + "bot_id": "aries_general", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "list", + "list": [ + { + "title": "肚子饿了怎么办_百度知道", + "summary": "走出门 一直走 遇到红路灯不要向左转 一直走 有车直接撞", + "url": "http://zhidao.baidu.com/question/159263414.html" + }, + { + "title": "肚子饿了怎么办_有问必答_快速问医生", + "summary": "不饱,刚吃完饭一会就感到肚子饿,无论吃得多饱,一会就饿了,我是不是有病啊,这该怎么办啊...", + "url": "http://m.120ask.com/askg/bd_detail/34368453" + }, + { + "title": "睡前肚子饿了怎么办?10种睡前可以吃的食物~..._百度文库", + "summary": "10种睡前可以吃的食物~(46条震撼你的生活小常识)。睡前肚子饿了怎么办?10种睡前可以吃的食物 ...", + "url": "http://wenku.baidu.com/view/b717aa8071fe910ef12df884.html" + }, + { + "title": "肚子饿了怎么办_百度经验", + "summary": "肚子饿了怎么办,很多朋友在废寝忘食工作或者过度放松的情况下往往会忘了吃饭,于是造成的结果就是肚子很饿...", + "url": "http://jingyan.baidu.com/article/e3c78d64bbf5c23c4c85f5a5.html", + "image": "http://cdn01.baidu-img.cn/timg?wisealaddin&size=u200_200&quality=80&sec=1491457643&di=0061a9dba8a00f7cbcf666b803eea34e&src=http%3A%2F%2Ft11.baidu.com%2Fit%2Fu%3D4234974745%2C3911491710%26fm%3D58%26s%3DCEA41C62D3CB40EB4A5CB9DE000080B1%26bpow%3D800%26bpoh%3D600" + }, + { + "title": "半夜里饿了怎么办?没吃的东西的前提下。_百度拇指医生", + "summary": "半夜里饿了怎么办?没吃的东西的前提下。最快的减肥:第一种:喝白开水!早上起床后就喝杯白开水既解饿也...", + "url": "http://muzhi.baidu.com/question/495721149646178164.html" + }, + { + "title": "减肥过程中饿了怎么办_百度经验", + "summary": "减肥过程中饿了怎么办,成功减肥者的8大心得。成功瘦身者传授瘦身心得,再配合正确的减肥方法的同时,还...", + "url": "http://jingyan.baidu.com/article/e3c78d640308aa3c4c85f5df.html" + }, + { + "title": "睡前饿了怎么办,十种可以吃的食物_百度文库", + "summary": ",中午吃的像平民,晚上吃的像乞丐 睡前饿了怎么办?10 种睡前可以吃的食物~再也不怕晚上肚子饿啦~ ...", + "url": "http://wenku.baidu.com/view/07e1692458fb770bf78a55b5.html" + }, + { + "title": "如果大家晚上突然感觉饿了会怎么办?吃还是不吃?..._果壳", + "summary": "选择不吃的人,你是靠什么来抵抗自己巨大的饿感?另外,想吃的话吃什么能比较不容易发胖?大家说出来交流下呗~", + "url": "http://m.guokr.com/post/455727/" + }, + { + "title": "我肚子饿了怎么办啊真的好饿啊,没的吃的 - 爱问知识人", + "summary": "好评回答 2163374807 | 11-07-05 0 0 举报 想办法弄点食物吃或者用绳子捆住肚子。...", + "url": "http://m.iask.sina.com.cn/b/18838974.html" + } + ] + } + ], + "nlu": { + "domain": "universal_search", + "intent": "normal", + "slots": {} + }, + "speech": { + "type": "Text", + "content": "为你找到以下内容" + } + }, + "id": "1491457644_209ce75u4", + "logid": "14914576433556", + "user_id": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "time": 1491457644, + "cuid": "DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768", + "se_query": "肚子饿了怎么办", + "msg": "ok", + "client_msg_id": "c9bfe944-992b-45b1-8afe-dc2cdaee622a", + "status": 0 +} +``` + +## nlu输出 +```javascript +domain: universal_search +intent: +calculator => 计算器 +stock => 股票 +exchange_rate => 汇率 +image => 图片 +traffic_limit => 限行 +kg => 知识图谱(问答/人物/诗词/汉语...) +short_video => 短视频 +app => 应用下载 +weather => 天气 +tieba => 贴吧 +lbs_consume => lbs消费 +novel => 小说 +teleplay => 电视剧 +music => 音乐 +car_series => 车系 +lottery => 彩票 +cookbook => 菜谱 +3c => 3C产品 +animation => 动漫 +douban => 豆瓣 +lbs => 导航 +train_ticket => 火车票 +shopping_search => 购物搜索 +nba => NBA +moive_ticket => 电影票 +weibo => 微博 +constellation => 星座 +recruit => 招聘 +travel => 旅游 +hotel => 酒店 +plane_ticket => 飞机票 +drugs => 药品 +baike => 百科 +time => 时间 +general_aladdin => 其他泛阿拉丁 +``` +## 知识图谱 +```javascript +度秘知识谱图服务包含多种子服务,比较重要的几个大类目: +汉语 ai.dueros.bot.knowledge_graph_chinese +诗词 ai.dueros.bot.knowledge_graph_poetry +人物 ai.dueros.bot.knowledge_graph_personage +影视 ai.dueros.bot.knowledge_graph_film_tv +地理 ai.dueros.bot.knowledge_graph_geography +历史 ai.dueros.bot.knowledge_graph_history +音乐 ai.dueros.bot.knowledge_graph_music +世界之最 ai.dueros.bot.knowledge_graph_world_top +动物 ai.dueros.bot.knowledge_graph_animal +植物 ai.dueros.bot.knowledge_graph_plant +体育 ai.dueros.bot.knowledge_graph_sport + +其中,每个类目的resource输出对应着不同的schema格式,具体见: +http://wiki.baidu.com/pages/viewpage.action?pageId=345971498 +``` \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/bot/life_common.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,296 @@ + + +# life_common服务 + +## 服务介绍 + +生活服务,满足用户**路线导航、路况、地理信息点、附近周边**(包括鲜花、美发、KTV等)查询需求。支持query理解,输出nlu信息。服务返回百度地图h5落地页url,应用方还可以根据服务返回的nlu槽位(slots)拼接百度地图schema调起百度地图app。 + +## 服务支持的常见查询请求 + +导航支持: + +从当前地点到某个位置的导航、以及从地点A到地点B的导航,如果用户query包含出行方式,会优先给出该出行方式的导航结果。 + +周边查找支持的常见类目: + +吃喝:美食、小吃快餐、火锅、中餐、酒吧、咖啡厅 + +住宿:酒店、快捷酒店、星级酒店、特价酒店、宾馆、公寓酒店、招待所、青年旅社 + +出行:公交站、地铁站、加油站、停车场、火车票代售点、汽车站 + +娱乐:网吧、洗浴、足疗、KTV、电影院、按摩 + +生活:银行、超市、医院、药店、厕所、ATM、快递、花点、照相馆、幼儿园、菜市场、小学、书店、车管所、眼镜店、五金店、蛋糕店、美容美发 + +景点:景点、公园、名胜古迹、度假村、步行街 + +购物:商场、万达广场、丽人、宜家 + +# bot输出schema + +## domain: lbs + +## 周边查询(intent: nearby) +周边查询返回的完整例子: +```javascript +//query=百度大厦附近的地铁站 +{ + "result": { + "bot_id": "life_common", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "为你找到百度大厦附近的地铁站", + "url": "http://api.map.baidu.com/place/search?query=地铁站&location=40.056974,116.307689&coord_type=bd09ll&radius=1000®ion=北京市&output=html&src=dumi" + } + ], + "nlu": { + "domain": "lbs", + "intent": "nearby", + "slots": { + "end_point": "地铁站", + "start_point": "百度大厦", + "start_point_bd_la": "40.056974", + "start_point_bd_lo": "116.307689", + "user_location_city": "北京市" + } + }, + "speech": { + "type": "Text", + "content": "为你找到百度大厦附近的地铁站" + } + }, + "id": "1486365914_104fngxrj", + "logid": "14863659133650", + "user_id": "test_cuid", + "time": 1486365914, + "cuid": null, + "se_query": "百度大厦附近的地铁站", + "msg": "ok", + "status": 0 +} +``` +### nlu说明 + +| 槽位(slot) | 槽位描述(desc) | 槽位值(value) | +| ------------------ | ---------- | -------------- | +| end_point | 搜索目标名称 | eg: 地铁站 | +| start_point | 搜索中心点名称 | eg: 百度大厦 | +| start_point_bd_la | 搜索中心点纬度 | eg: 40.056974 | +| start_point_bd_lo | 搜索中心点经度 | eg: 116.307689 | +| user_location_city | 用户当前所在城市 | 北京市 | + +### 调起百度地图APP方法 + +使用的百度地图的**周边搜索**调起方法,在百度地图APP查看给定的关键字、检索条件的检索结果。 + +**URL接口:** + +``` +baidumap://map/place/search +``` + +**参数说明:** + +| 参数名称 | 描述 | nlu槽位对应关系 | 是否必选 | 格式(示例) | +| -------- | ------------------------------------- | ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | +| query | 关键词 | 填入end_point槽位 | 必选 | 地铁站 | +| region | 城市名或县名 | 填入user_location_city槽位 | 选择方式:地点搜索限定范围可以由region和location + radius方式进行,其中location + radius优先级高于region | 北京市 | +| location | 中心点经纬度,或中心点经纬度和名称描述,注意,名称不参与检索,只负责显示。 | nlu槽位包含start_point_bd_la,start_point_bd_lo时使用,如果为两个坐标都为空则不填入 | 同上 | 经纬度: 39.9761,116.3282;经纬度和名称: latlng:39.9761,116.3282\|name:中关村 (注意:坐标先纬度,后经度);经纬度和名称: latlng:39.9761,116.3282\|name:中关村 (注意:坐标先纬度,后经度)。 | +| radius | 检索半径,单位:m | 填入默认值1000 | 同上 | 1000m | + +**使用示例:** + +```java +// 周边搜索 + +"baidumap://map/place/search?query=地铁站®ion=北京市&location=40.056974,116.307689&radius=1000" +``` + +显示效果如下 + +<img src="http://gitlab.baidu.com/wangpeng20/dumi_schema/raw/master/doc/img/lifecommon_lbs_nearby.jpg" width = "30%" /> + +## 地址查询(intent: poi) + +地址查询返回的完整例子: +```javascript +//query=百度科技园在哪里 +{ + "result": { + "bot_id": "life_common", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "为你找到百度科技园", + "url": "http://api.map.baidu.com/geocoder?address=百度科技园&output=html&src=dumi" + } + ], + "nlu": { + "domain": "lbs", + "intent": "poi", + "slots": { + "poi": "百度科技园" + } + }, + "speech": { + "type": "Text", + "content": "为你找到百度科技园" + } + }, + "id": "1486353184_3716wf322", + "logid": "14863531849519", + "user_id": "test_cuid", + "time": 1486353184, + "cuid": "test_cuid", + "se_query": "百度科技园在哪里", + "msg": "ok", + "status": 0 +} +``` +### nlu说明 + +| slot | desc | value | +| ---- | ----- | --------- | +| poi | 地址字符串 | eg: 百度科技园 | + +### 调起百度地图APP方法 + +使用的百度地图的**poi地址解析**调起方法,在百度地图APP查看该地址对应的坐标点的详细信息。 + +**URL接口:** + +``` +baidumap://map/geocoder +``` + +**参数说明:** + +| 参数名称 | 描述 | nlu槽位对应关系 | 是否必选 | 格式(示例) | +| ------- | ---- | ------------ | ---- | ------ | +| address | 地址名称 | 对应nlu中的poi槽位 | 必选 | 百度科技园 | + +**使用示例:** + +```java +// 地址解析 + +"baidumap://map/geocoder?src=dumi&address=百度科技园" +``` + +显示效果如下 + +<img src="http://gitlab.baidu.com/wangpeng20/dumi_schema/raw/master/doc/img/lifecommon_lbs_poi.jpg" width = "30%" /> + +## 导航查询(intent: navigation) + +导航查询返回的完整例子: +```javascript +//query=导航从百度科技园到西二旗地铁站 +{ + "result": { + "bot_id": "life_common", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "为你找到从百度科技园到西二旗地铁站的路线,建议出行方式:驾车", + "url": "http://api.map.baidu.com/direction?origin=百度科技园&destination=西二旗地铁站&mode=transit®ion=北京市&output=html&src=dumi" + } + ], + "nlu": { + "domain": "lbs", + "intent": "navigation", + "slots": { + "end_point": "西二旗地铁站", + "start_point": "百度科技园", + "start_point_bd_la": "", + "start_point_bd_lo": "", + "user_location_city": "北京市", + "travel_type": "" + } + }, + "speech": { + "type": "Text", + "content": "为你找到从百度科技园到西二旗地铁站的路线,建议出行方式:驾车" + } + }, + "id": "1486365990_8515fq3zv", + "logid": "14863659908617", + "user_id": "test_cuid", + "time": 1486365990, + "cuid": "test_cuid", + "se_query": "导航从百度科技园到西二旗地铁站", + "msg": "ok", + "status": 0 +} +``` +### nlu说明 + +| slot | desc | value | +| ------------------ | -------- | -------------- | +| end_point | 目的地 | eg: 西二旗地铁站 | +| start_point | 出发地 | eg: 百度大厦 | +| start_point_bd_la | 出发地纬度 | eg: 40.056974 | +| start_point_bd_lo | 出发地经度 | eg: 116.307689 | +| user_location_city | 用户当前所在城市 | eg:北京市 | +| travel_type | 出行方式 | TAXI:出租车 | +| | | DRIVE:驾车 | +| | | PUBTRANS:公共交通 | +| | | WALK:步行 | + +### 调起百度地图APP方法 + +使用的百度地图的**路线规划**调起方法,在百度地图APP中查看公交、驾车、步行导航路线规划结果。 + +**URL接口:** + +``` +baidumap://map/direction +``` + +**参数说明:** + +| 参数名称 | 描述 | nlu槽位对应关系 | 是否必选 | 格式(示例) | +| ----------- | ---------------------------------------- | ---------------------------------------- | -------------------------------------- | ---------------------------------------- | +| origin | 起点名称或经纬度,或者可同时提供名称和经纬度,此时经纬度优先级高,将作为导航依据,名称只负责展示 | | origin和destination二者至少一个有值(默认值是当前定位地址) | 经纬度: 39.9761,116.3282经纬度和名称: latlng:39.9761,116.3282\|name:中关村 (注意:坐标先纬度,后经度) | +| destination | 终点名称或经纬度,或者可同时提供名称和经纬度,此时经纬度优先级高,将作为导航依据,名称只负责展示。 | | 同上 | 经纬度: 39.9761,116.3282经纬度和名称: latlng:39.9761,116.3282\|name:中关村 (注意:坐标先纬度,后经度) | +| mode | 导航模式,可选transit(公交)、driving(驾车)、walking(步行)和riding(骑行).默认:driving | 对应nlu中的出行方式槽位:TAXI(出租车)对应driving,DRIVE(驾车)对应driving; PUBTRANS(公共交通)对应transit; WALK(步行)对应walking; | 可选 | 根据travel_type槽位映射,添入对应mode(driving,transit,walking) | +| region | 城市名或县名 | 对应user_location_city | 可选 | 北京市 | + +**使用示例:** + +```java +//公交路线规划示例: + +"baidumap://map/direction?origin=百度科技园&destination=西二旗地铁站&mode=transit" + +//驾车路线规划示例: + +"baidumap://map/direction?region=北京市&origin=百度科技园&destination=西二旗地铁站&mode=driving" + +//步行路线规划示例: + +"baidumap://map/direction?region=北京市&origin=百度科技园&destination=西二旗地铁站&mode=walking" +``` + +显示效果如下 + +<img src="http://gitlab.baidu.com/wangpeng20/dumi_schema/raw/master/doc/img/lifecommon_lbs_nav.jpg" width = "30%" /> +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/bot/phone.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,384 @@ +# phone bot输出schema + +## 打电话(intent:telephone) +打电话返回的完整例子: +```javascript +//query=打电话给测试薛斌 +{ + "result": { + "bot_id": "phone", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "语音助手正在为您寻找联系人“测试薛斌”" + }, + { + "type": "txt", + "content": "一通电话显得格外珍贵,一条贴心的短信就是浓浓的爱,与身边的人多联系联系", + "url": "xiaoduapp://phone?pinyin=ce+shi+xue+bin&name=%E6%B5%8B%E8%AF%95%E8%96%9B%E6%96%8C" + } + ], + "nlu": { + "domain": "phone", + "intent": "telephone", + "slots": { + "name": "测试薛斌", + "pinyin": "ce+shi+xue+bin" + } + }, + "speech": { + "type": "Text", + "content": "语音助手正在为您寻找联系人“测试薛斌”" + } + }, + "id": "1491445965_354dvoswq", + "logid": "14914459652028", + "user_id": "test_waiwang_yinjie_fenji_1111111", + "time": 1491445965, + "cuid": "test_waiwang_shiquan_fenji_111111", + "se_query": "打电话给测试薛斌", + "msg": "ok", + "client_msg_id": "58512fc9-d688-4e4e-9263-14495de3a60a", + "status": 0 +} +``` +### nlu部分的说明 + +|slot |desc | value | +|---|---|---| +|name | 名字 | 中文名 | +|pinyin | 姓名拼音 | eg:xuebin | +|number | 电话号码 | eg:10086 | +|use_sim_index | sim卡号 | 1、2 | +|same_pinyin_names | 相同拼音联系人 | Eg:[“张棋”,”张起”]| +|high_confidence_similar_names | 高置信度相似拼音 | Eg:["张宁","张玲"]| +|include_names | 通讯录包含查找名称 | Eg:[\"测试薛斌\"]| +|similar_names | 底置信度相似拼音 | Eg:["张层","张增"]| +|similar_include_names | 包含底置信度相似拼音 | Eg:[\"测试薛斌\"]| +|recommend_names | 模糊匹配命中名字 | Eg:[“张棋”,”张起”]排序规则:name、same-pingyin-name、high-confidence—Similar–names、include-name、Similar–names、Similar–include-names| +|yellow_pages | 阿拉丁黄页客服 | Eg:[{"name":"搜狐客服电话","number":"01062726666"}]| +|status|cancel|取消| + + +### 多轮状态机 +![图片](http://bos.nj.bpc.baidu.com/v1/agroup/b21b32af56cea9946daec3283726f62fb64b13ed) + + +## 发短信(intent:sms) +发短信返回的完整例子: +```javascript +//query=发短信给测试度秘 +{ + "result": { + "bot_id": "phone", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "请问要发送什么内容?" + } + ], + "nlu": { + "domain": "phone", + "intent": "sms", + "slots": { + "name": "测试度秘", + "pinyin": "ce+shi+du+mi" + } + }, + "speech": { + "type": "Text", + "content": "请问要发送什么内容?" + } + }, + "id": "1486353184_3716wf322", + "logid": "14863531849519", + "user_id": "test_cuid", + "time": 1486353184, + "cuid": "test_cuid", + "se_query": "发短信给测试度秘", + "msg": "ok", + "status": 0 +} +``` +### nlu部分的说明 + +|slot | desc | value | +|---|---|---| +|name | 名字 | 中文名 | +|pinyin | 姓名拼音 | eg:xuebin | +|number | 电话号码 | eg:10086 | +|use_sim_index | sim卡号 | 1、2 | +|same_pinyin_names | 相同拼音联系人 | Eg:[“张棋”,”张起”]| +|high_confidence_similar_names | 高置信度相似拼音 | Eg:["张宁","张玲"]| +|include_names | 通讯录包含查找名称 | Eg:[\"测试薛斌\"]| +|similar_names | 底置信度相似拼音 | Eg:["张层","张增"]| +|similar_include_names | 包含底置信度相似拼音 | Eg:[\"测试薛斌\"]| +|recommend_names | 模糊匹配命中名字 | Eg:[“张棋”,”张起”]排序规则:name、same-pingyin-name、high-confidence—Similar–names、include-name、Similar–names、Similar–include-names| +|yellow_pages | 阿拉丁黄页客服 | Eg:[{"name":"搜狐客服电话","number":"01062726666"}]| +|status|cancel、confirm|确认、取消| +|content|短信内容|Eg:今晚加班晚点回家| + +### 多轮状态机 +![图片](http://bos.nj.bpc.baidu.com/v1/agroup/2c3ddea49eb9abbdc2161c4bb51a34e516b2361f) + +## 通讯录(intent:contact) +通讯录返回的完整例子: +```javascript +//query=把李四的名片发给张三 +{ + "result": { + "bot_id": "phone", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "语音助手正在为你发送“李四”的名片到“张三”" + } + ], + "nlu": { + "domain": "phone", + "intent": "contact", + "slots": { + "action_type": "2", + "pinyin_for_view": "li+si", + "pinyin_to_send": "zhang+san", + "name_for_view": "李四", + "name_to_send": "张三" + } + }, + "speech": { + "type": "Text", + "content": "语音助手正在为你发送“李四”的名片到“张三”" + } + }, + "id": "1486365990_8515fq3zv", + "logid": "14863659908617", + "user_id": "test_cuid", + "time": 1486365990, + "cuid": "test_cuid", + "se_query": "把李四的名片发给张三", + "msg": "ok", + "status": 0 +} +``` +### nlu部分的说明 +|slot | desc | value | +|---|---|---| +|action_type | 动作类型 | 0:新建 | +| | | 1:查看 | +| | | 2:发送 | +|name_for_view | 查看联系人的名字 | 把A的名片发给B:那么这里填A;若是新建联系人A,这里也是填A | +|pinyin_for_view | <span style="background-color: rgb(249, 249, 249);">查看联系人的名字的拼音</span> | eg:xue+bin | +|high_confidence_similar_names_for_view | 高置信度相似拼音 | Eg:["张宁","张玲"] | +|include_names_for_view | 通讯录包含查找名称 | Eg:["张宁宁","张玲玲"] | +|similar_names_for_view | 底置信度相似拼音 | Eg:["张层","张增"] | +|similar_include_names_for_view | 包含底置信度相似拼音 | Eg:["张莹莹","张怡怡"] | +|recommend_names_for_view | 模糊匹配命中名字 | Eg:["张莹莹","张怡怡"]排序规则:name、same-pingyin-name、high-confidence—Similar–names、include-name、Similar–names、Similar–include-names | +|yellow_pages_for_view | 黄页信息 | Eg:[{"name":"搜狐客服电话","number":"01062726666"}] | +|name_to_send | 发送联系人的名字 | 把A的名片发给B:那么这里填B | +|pinyin_to_send | 发送联系人的名字的拼音 | eg:xue+bin | +|number_to_send | 发送联系人的号码 | eg:把A的号码发给18983479834,number_to_send填18983479834 | +|number | 电话号码 | eg:新建薛斌的号码是1868979721897,number填1868979721897 | + + +## 手机设置(intent:phone_settings) +手机设置返回的完整例子: +```javascript +//query=打开蓝牙 +{ + "result": { + "bot_id": "phone", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "世界上最遥远的距离就是:我在您身边,而您却没有打开蓝牙" + } + ], + "nlu": { + "domain": "phone", + "intent": "phone_settings", + "slots": { + "action_type": "1", + "setting_name": "bluetooth" + } + }, + "speech": { + "type": "Text", + "content": "世界上最遥远的距离就是:我在您身边,而您却没有打开蓝牙" + } + }, + "id": "1486367016_766faqcvb", + "logid": "14863670169694", + "user_id": "test_cuid", + "time": 1486367016, + "cuid":"test_cuid", + "se_query": "打开蓝牙", + "msg": "ok", + "status": 0 +} +``` +### nlu部分的说明 +|slot | desc | value | +|---|---|---| +|function_name | 功能名称 | font:字体 | +| | | vertical_screen_lock:竖屏锁定 | +| | | wifi:无线网 | +| | | do_not_disturb:勿扰模式 | +| | | personal_hotspot:个人热点 | +| | | bluetooth:蓝牙 | +| | | vpn:专用网络 | +| | | airplane_mode:飞行模式 | +| | | drive_mode:驾驶模式 | +| | | brightness:亮度 | +| | | night_mode:夜间模式 | +| | | vibration:振动 | +| | | assistive_touch:悬浮球 | +| | | GPS:定位 | +| | | volume:音量 | +| | | 4G | +| | | 3G | +| | | 2G | +| | | GPRS | +| | | cellular:蜂窝网络 | +| | | NFC:NFC | +| | | power:电源(对应重启和关闭) | +| | | power_save_mode:省电模式 | +| | | silent_mode:静音模式 | +| | | synchronization:同步 | +| | | eye_protect_mode:护眼模式 | +|action_type | 动作类型 | 0:关闭 | +| | | 1:打开 | +| | | 2:调大 | +| | | 3:调小 | +| | | 4:重启 | + +## 打开应用(intent:open_app) +打开应用返回的完整例子: +```javascript +//query=打开支付宝 +{ + "result": { + "bot_id": "phone", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "语音助手正在为您打开支付宝" + }, + { + "type": "list", + "list": [ + { + "title": "支付宝", + "summary": "支付宝(中国)网络技术有限公司是国内领先的第三方支付平台,致力于提供“简单、安全、快速”的支付解决方案。", + "url": "xiaoduapp://openapp?ios_scheme=alipay%3A%2F%2F&appstore_url=https%3A%2F%2Fitunes.apple.com%2Fcn%2Fapp%2Fzhi-fu-bao-zhifubao-kou-bei%2Fid333206289%3Fmt%3D8&android_package=com.eg.android.AlipayGphone&android_url=http%3A%2F%2Fmobile.baidu.com%2F%23%2Fitem%3Fdocid%3D8653239", + "image": "http://xiaodu.baidu.com/saiya/appicon/37.zhifubao.jpg" + } + ] + } + ], + "nlu": { + "domain": "phone", + "intent": "open_app", + "slots": { + "action_type": "1", + "name": "支付宝" + } + }, + "speech": { + "type": "Text", + "content": "" + } + }, + "id": "1486368307_142b7clqy", + "logid": "14863683062888", + "user_id": "test_cuid", + "time": 1486368307, + "cuid": null, + "se_query": "打开支付宝", + "msg": "ok", + "status": 0 +} +``` +### nlu部分的说明 +|slot | desc | value | +|---|---|---| +|name | 网站中文名| eg:新浪网 | +|action_type | 动作类型 | 0:关闭 | +| | | 1:打开 | +| | | 2:卸载 | +| | | 3:下载 | +| | | 4:搜索 | + +## 打开网页(intent:open_website) +打开网页返回的完整例子: +```javascript +//query=打开新浪网 +{ + "result": { + "bot_id": "phone", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "语音助手为你找到新浪网" + } + ], + "nlu": { + "domain": "phone", + "intent": "open_website", + "slots": { + "action_type": "1", + "name": "新浪网", + "website_url": "http://www.sina.com.cn/" + } + }, + "speech": { + "type": "Text", + "content": "语音助手为你找到新浪网" + } + }, + "id": "1486367770_289g7bs0s", + "logid": "14863677704443", + "user_id": "test_cuid", + "time": 1486367770, + "cuid": "test_cuid", + "se_query": "打开新浪网", + "msg": "ok", + "status": 0 +} +``` +### nlu部分的说明 +|slot | desc | value | +|---|---|---| +|name | 网站中文名| eg:新浪网 | +|website_url|网站地址|eg:http://www.sina.com.cn/ +|action_type | 动作类型 | 0:关闭 | +| | | 1:打开 |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/bot/phone_call.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,98 @@ +#打电话应用输出 + +bot_id: ai.dueros.bot.phone_call + +## v2 协议输出 +```javascript +{ + "result": { + "views": { + "type": "txt", + "content": "度秘为您找到相关的联系人:测试薛斌" + }, + "nlu": { + "domain": "phone", // TODO:确认打电话个发短信的名称 + "intent": "telephone", + // TODO: 确认名称。 + // 目前da解析结果:打电话是telephone,发短信是sms + // 看看是否需要丰富: + // 目前打电话包含:1. 请问要打给谁?;2. 电话主动取消; 3. 拨出电话。 + // 发短信包括:1. 请问要发给谁?;2. 请问要发送什么内容?;3. 短信问确认: 请问你要发送、取消还是修改?;4. 短信主动取消;5. 短信结束,正在为你发送短信 + "slots": { + "name": "测试薛斌", + "use_sim_index": "1", // sim卡 + "carrier": "联通" // 联通,移动,电信 + } + }, + "resource": { + // TDDO: 带确认下面解析的名称 + "pinyin": "ce+shi+xue+bin", // 姓名拼音 + "same_pinyin_names": "[“张棋”,”张起”]", // 相同拼音的联系人 + "high_confidence_similar_names": ["张宁","张玲"], // 高置信度相似拼音 + "include_names": "[\"测试薛斌\"]", // 通讯录包含查找名称 + "similar_names": "["张层","张增"]", // 底置信度相似拼音 + "similar_include_names": "["张莹莹","张怡怡"]", // 包含底置信度相似拼音 + "recommend_names": "[\"测试薛斌\"]" // 模糊匹配命中名字 + "yellow_pages": "[{"name":"搜狐客服电话","number":"01062726666"}]" // 阿拉丁黄页客服 + }, + "speech": { + "type": "txt", + "content": "度秘为您找到相关的联系人:测试薛斌" + }, + "bot_id": "ai.dueros.bot.phone_call", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + } + }, + "id": "1494935842_931dttn5s", + "logid": "14949358421483", + "user_id": "test_offline1490608414.0", + "time": 1494935842, + "cuid": null, + "se_query": "打电话给薛冰", + "msg": "ok", + "status": 0 +} +``` + + +字段说明: +### view: + +|字段 | 描述 | 举例 | +|---|---|---| +|type | 返回展示卡片数据,必选字段,这里默认是文本 | txt | +|content | 文本内容 | 度秘为您找到相关的联系人:测试薛斌 | + +### nlu: + +|slot |desc | value | +|---|---|---| +|name | 名字 | 中文名 | +|number | 电话号码 | eg:10086 | +|use_sim_index | sim卡号 | 1、2 | +|status|cancel|取消| + + +### resource: + +|字段 | 描述 | 举例 | +|---|---|---| +|pinyin | 姓名拼音 | eg:xuebin | +|same_pinyin_names | 相同拼音联系人 | Eg:[“张棋”,”张起”]| +|include_names | 通讯录包含联系人 | Eg:["张宁宁","张玲玲"]| +|high_confidence_similar_names | 高置信度相似拼音 | Eg:["张宁","张玲"]| +|similar_names | 低置信度相似拼音 | Eg:["张层","张增"]| +|similar_include_names | 包含底置信度相似拼音 | Eg:["张莹莹","张怡怡"]| +|recommend_names | 模糊匹配命中名字 | Eg:["张莹莹","张怡怡"] 排序规则:name、same-pingyin-name、high-confidence—Similar–names、include-name、Similar–names、Similar–include-names| +|yellow_pages | 客服黄页 | Eg:[{"name":"搜狐客服电话","number":"01062726666"}]| + + +### speech: + +|字段 | 描述 | 举例 | +|---|---|---| +|type | 文本格式 | txt | +|content | 语音文本 | 度秘为您找到相关的联系人:测试薛斌 |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/bot/poem.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,104 @@ +# poem bot输出schema + +## 度秘写诗 +```javascript +//query = 写诗->中秋快乐 +{ + "result": { + "hint": [ + "换一首", + "换主题句", + "退出写诗", + "只要文字", + "换背景" + ], + "nlu": { + "domain": "unknown", + "intent": "unknown", + "slots": {} + }, + "bot_id": "poem", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "image", + "list": [ + { + "src": "http://xiaodu.baidu.com/img/pic?pic_id=55698631" + } + ] + } + ], + "speech": { + "type": "Text", + "content": "欢歌笑语满堂香.喜看嫦娥舞霓裳.万户团圆人尽望.中秋佳节好时光." + } + }, + "id": "1498542896_4478zu8w5", + "logid": "14985428962008", + "user_id": "XXXXXXXEBE29BC13C7CBAADXEFXXXXXX|111118820888888", + "time": 1498542896, + "cuid": "XXXXXXXEBE29BC13C7CBAADXEFXXXXXX|111118820888888", + "se_query": "中秋快乐", + "msg": "ok", + "client_msg_id": "c9bfe944-992b-45b1-8afe-dc2cdaee622a", + "speech_id": "12345", + "status": 0, + "timeuse": 188 +} +``` +## 藏头诗 +```javascript +//query = 藏头诗->度秘祝你快乐 +{ + "result": { + "hint": [ + "换一首", + "换主题句", + "退出写诗", + "只要文字", + "换背景" + ], + "nlu": { + "domain": "unknown", + "intent": "unknown", + "slots": {} + }, + "bot_id": "poem", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "image", + "list": [ + { + "src": "http://xiaodu.baidu.com/img/pic?pic_id=55688235" + } + ] + } + ], + "speech": { + "type": "Text", + "content": "度诗挥墨添儒雅.秘词举书助境高.祝吟风情千万景.你唱故事万千情.快把灯笼坛上挂.乐凭影罩苑前藏." + } + }, + "id": "1498536521_6269nksfk", + "logid": "14985365211616", + "user_id": "XXXXXXXEBE29BC13C7CBAADXEFXXXXXX|111118820888888", + "time": 1498536521, + "cuid": "XXXXXXXEBE29BC13C7CBAADXEFXXXXXX|111118820888888", + "se_query": "度秘祝你快乐", + "msg": "ok", + "client_msg_id": "c9bfe944-992b-45b1-8afe-dc2cdaee622a", + "speech_id": "12345", + "status": 0, + "timeuse": 223 +} +``` \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/bot/remind.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,238 @@ +# remind bot输出schema + +## 创建提醒(intent:remind) +打电话返回的完整例子: +```javascript +//query=明天上午8点提醒我起床 +{ + "result": { + "bot_id": "remind", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "list", + "list": [ + { + "title": "起床", + "summary": "为你设置了【起床】提醒。\n语音助手将于明天上午8点通知你", + "url": "http://xiaodu.baidu.com/saiya/events", + "image": "http://xiaodu.baidu.com/saiya/img/remind.png" + } + ] + } + ], + "nlu": { + "domain": "remind", + "intent": "remind", + "slots": { + "event_title": "起床", + "event_type": "wakeup", + "remind_time": "{\"day\":\"next\",\"hour\":\"8\",\"apm\":\"am\"}", + "remind_type_message": "否", + "remind_type_phone": "否", + "remind_type_dumi": "否", + "remind_type_clock": "是", + "remind_time_type": "abstime", + "remind_time_data": "1486598400", + "status": "create" + } + }, + "speech": { + "type": "Text", + "content": "为你设置了【起床】提醒。\n语音助手将于明天上午8点通知你" + } + }, + "id": "1486548437_49427afb0", + "logid": "14865484374487", + "user_id": "test", + "time": 1486548437, + "cuid": null, + "se_query": "明天上午8点提醒我起床", + "msg": "ok", + "status": 0 +} +``` +![remind_create](http://f.hiphotos.baidu.com/xiaodu/pic/item/574e9258d109b3ded96189eac5bf6c81810a4c51.jpg) + +### nlu部分的说明 + +|slot |desc | value | +|---|---|---| +|name | 名字 | 中文名 | +|event_title | 提醒标题 | eg:起床| +|event_type | 提醒事件类型 | eg:wakeup| +|remind_time_data | 提醒设置的时间。只会在提醒创建前(即槽位完备)给出 | 1486598400| +|remind_type_clock | 提醒触达方式闹钟 | 是| +|status| create |创建| + + +## 查看提醒(intent:remind_manage) +打电话返回的完整例子: +```javascript +//query=查看我明天上午开会的提醒 +{ + "result": { + "bot_id": "remind", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "暂时没有提醒哦,有任何需求可以告诉我,语音助手帮你记下来。" + } + ], + "nlu": { + "domain": "remind", + "intent": "remind_manage", + "slots": { + "action": "list", + "event_title": "开会", + "remind_time": "{\"day\":\"next\",\"apm\":\"am\"}", + "remind_type_message": "否", + "remind_type_phone": "否", + "remind_type_dumi": "否", + "remind_type_clock": "否" + } + }, + "speech": { + "type": "Text", + "content": "暂时没有提醒哦,有任何需求可以告诉我,语音助手帮你记下来。" + } + }, + "id": "1486549266_6504f3o6a", + "logid": "14865492666785", + "user_id": "test", + "time": 1486549266, + "cuid": null, + "se_query": "查看我明天上午开会的提醒", + "msg": "ok", + "status": 0 +} +``` +![remind_manage](http://c.hiphotos.baidu.com/xiaodu/pic/item/c9fcc3cec3fdfc03f85a8f3add3f8794a4c22615.jpg) + +### nlu部分的说明 + +|slot |desc | value | +|---|---|---| +|name | 名字 | 中文名 | +|event_title | 提醒标题 | eg:起床| +|remind_time | 提醒时间 | json | +|action | 操作类型 | eg:list、update、delete,分别为查看、更新、删除| + +### 时间json内字段说明 + +remind_time如果不完备,会在多轮对话中不断的澄清,是一个中间结果 + +|Key |Value |说明| +|---|---|---| +|minute |3, +2, -1|string. 3分,2分钟后,1分钟前| +|hour|2, +1, -3|string. 2点,1小时后,3小时前| +|day|1, +2, -3, -1,next, +0|string. 1号,2天后,3天前,昨天,明天,今天| +|month|1, +2, -3, +0|string. 1月,2个月后,3个月前,这个月| +|year|1984, +1, -2, +0|string. 1984年,明年,2年前,今年| +|week|+1, -1, 2, 3, 2+1|string. 下周,上一周,星期二,周三, 下周二| +|apm|am, pm|string. 上午,下午| +|const|recent, awhile|string. 刚刚,一会儿| +|repeat|day, month, year|string. 每天,每月,每年| +|special_day |weekend, weekday|string. 周末,工作日,节气,节日| +|special_calendar|lunar|string. 农历| + +### 闹钟数据同步 + * 如果使用度秘的存储保存闹钟数据,通过请求度秘获取闹钟数据 + * URL: http://xiaodu.baidu.com/saiya/events/Index/clock + +```javascript +{ + "status": 0, + "msg": "", + "data": [ + //一次性的提醒,type : abstime + { + "type": "abstime", + "time": 1482019200, //闹钟响铃的时间 时间戳 + "id": "359482_1482019200", + "title": "我的生日", // 闹钟的内容 + "clock_type": "normal" //闹钟的类型:普通normal,还有叫早wakeup; 计时器timer + }, + + //or + //周期重复type:repeat_mult, 周 工作日 月 年 + { + "type": "repeat_mult", + "repeat_mult": { + "name": "每周", + "type": "week", //week: 周, weekday:工作日,month:月, year:年 + "value": [ + 1 //周级别 1~7, 月 1~31, 年 101 ~1231 + ] + }, + + "time": 1479686400, //闹钟响铃的时间 时间戳 + "terminal": null, + "id": 525568, + "title": "吃饭", + "clock_type": "normal" + }, + + //or + //每天重复type: absinterval + //其实考虑有每几天的重复,目前只每天 + { + "terminal": "na_ios", + "type": "absinterval", //类型 + "repeat": { + "type": "每天", + "value": 86400 //每多久触发一次,时间戳 ,单位:秒 + }, + "time": 1481241600, + "id": 604866, + "title": "吃饭", + "clock_type": "normal" + } + ] +} +``` +### 闹钟数据字段说明 + +|key |value|desc | +|---|---|---| +|title | 吃饭| 提醒的title | +|type | 重复类型 | eg:abstime| +|time | 提醒时间 | 时间戳 | +|clock_type | 闹钟类型 | eg:timer、normal、wakeup,分别为计时器、普通闹钟、起床闹钟| + + +### 闹钟同步命令 + * 如果使用度秘的存储保存闹钟数据,收到同步命令,客户端需通过请求度秘获取闹钟数据 + +```javascript +{ + "header": { + "namespace": "Remind", + "name": "UpdateClock", + "message_id": "message_id-1344" + }, + "payload": {} +} +``` +### 闹钟停止命令 + * 停止闹钟响铃指令 + +```javascript +{ + "header": { + "namespace": "Remind", + "name": "StopClock", + "message_id": "message_id-1344" + }, + "payload": {} +} +```
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/bot/smart_tv.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,955 @@ +# 智能电视 + +## Table of Contents + + + * [智能电视](#智能电视) + * [Table of Contents](#table-of-contents) + * [简介](#简介) + * [语音播报 Speech](#语音播报-speech) + * [天气](#天气) + * [指令 Directives](#指令-directives) + * [设计原型](#设计原型) + * [详细指令列表](#详细指令列表) + * [tv.system.volume.Up](#tvsystemvolumeup) + * [tv.system.volume.Down](#tvsystemvolumedown) + * [tv.system.volume.Set](#tvsystemvolumeset) + * [tv.system.volume.Mute](#tvsystemvolumemute) + * [tv.system.volume.Unmute](#tvsystemvolumeunmute) + * [tv.system.light.Up](#tvsystemlightup) + * [tv.system.light.Down](#tvsystemlightdown) + * [tv.system.constrast.Up](#tvsystemconstrastup) + * [tv.system.contrast.Down](#tvsystemcontrastdown) + * [tv.system.application.Open](#tvsystemapplicationopen) + * [tv.system.application.Close](#tvsystemapplicationclose) + * [tv.system.application.Upgrade](#tvsystemapplicationupgrade) + * [tv.system.application.Uninstall](#tvsystemapplicationuninstall) + * [tv.system.command.Go](#tvsystemcommandgo) + * [tv.system.command.Exit](#tvsystemcommandexit) + * [tv.system.command.Back](#tvsystemcommandback) + * [tv.system.command.Sleep](#tvsystemcommandsleep) + * [tv.system.command.Wake](#tvsystemcommandwake) + * [tv.system.command.TVOn](#tvsystemcommandtvon) + * [tv.system.command.TVOff](#tvsystemcommandtvoff) + * [tv.system.channel.Open](#tvsystemchannelopen) + * [tv.system.channel.Update](#tvsystemchannelupdate) + * [tv.player.resource.Play](#tvplayerresourceplay) + * [tv.player.control.Pause](#tvplayercontrolpause) + * [tv.player.control.FastForward](#tvplayercontrolfastforward) + * [tv.player.control.Goto](#tvplayercontrolgoto) + * [tv.player.control.BackForward](#tvplayercontrolbackforward) + * [tv.player.control.Speed](#tvplayercontrolspeed) + * [tv.player.control.Previous](#tvplayercontrolprevious) + * [tv.player.control.Next](#tvplayercontrolnext) + * [tv.player.control.Episode](#tvplayercontrolepisode) + * [tv.image.snapshot.Upload](#tvimagesnapshotupload) + * [tv.view.card.Render](#tvviewcardrender) + * [tv.view.text.Render](#tvviewtextrender) + * [tv.view.list.Render](#tvviewlistrender) + * [tv.view.detail.Render](#tvviewdetailrender) + * [意图识别 NLU](#意图识别-nlu) + * [MV类目](#mv类目) + * [原型](#原型) + * [样例](#样例) + * [影视类目](#影视类目) + * [原型](#原型-1) + * [样例](#样例-1) + * [控制指令类目](#控制指令类目) + * [ChangeLog](#changelog) + * [备注](#备注) + + +## 简介 +智能电视是<kbd>DuerOS</kbd>下的一个垂类服务, 通过语音解析和意图识别等能力给盒子提供服务,如: +语音控制换台, 语音检索影片, 根据画面查询人物信息, 控制视频播放的节奏等. + +作为<kbd>DuerOS</kbd>的垂类服务, 因此通过<kbd>DuerOS</kbd>的协议字段directives提供给终端使用. <kbd>DuerOS</kbd>的协议以及其他垂类返回格式可直接参考:[<<度秘开放平台OpenAPI使用说明>>](../api/overview.md), 本文档只具体描述智能TV盒子的接口协议. + +## 语音播报 Speech +语音播报描述字段speech是与directives指令平行的一个字段, 当服务端返回的数据有需要播放的文本或者其他时, 就需要补充该字段, 客户端通过解析该字段来调用speaker接口. 格式如下: + + "speech": { + "type": "Text", + "content": "正在为您播放周杰伦的歌曲" + } + +## 天气 + +天气需要填充视图和进行语音播报,天气视图描述字段views,其value为jsonarray格式,客户端通过views字段填充视图,通过解析speech字段进行语音播报. 其中views格式如下: + + "views": [ + { + "type": "list", + "list": [ + { + "summary": "实时:6℃\n温度:-3℃~7℃\n风力:北风4-5级\n空气质量指数:30,优\n来源:中国天气网", + "image": "http://xiaodu.baidu.com/img/pic?pic_id=46191609", + "title": "北京市今天晴", + "url": "https://m.baidu.com/from=2001a/s?word=北京市天气" + } + ] + } + ] + +## 指令 Directives +### 设计原型 + + { + "header": { + "namespace": "tv.xxx", + "name": "Xxx" + }, + "payload": { + "extend":{} + } + } +1. 通过header中的namespace和name确定一种指令 +2. payload为指令附加的参数 +3. extend为扩展字段, 通常情况下都为空, 用户不需关心 +4. 尽可能使用全称,而不是简写 +5. namespace用小写和"."分隔 +6. name采用首字母大写的驼峰命名法 + + +### 详细指令列表 + +#### tv.system.volume.Up + 音量增大 + { + "header": { + "namespace": "tv.system.volume", + "name": "Up" + }, + "payload": { + "value": 1, + "extend": {} + } + } + + + +#### tv.system.volume.Down + 减小音量 + { + "header": { + "namespace": "tv.system.volume", + "name": "Down" + }, + "payload": { + "value": 1, + "extend": {} + } + } + +#### tv.system.volume.Set + 设置音量 + { + "header": { + "namespace": "tv.system.volume", + "name": "Set" + }, + "payload": { + "value": 1, + "extend": {} + } + } + + +#### tv.system.volume.Mute + 静音 + { + "header": { + "namespace": "tv.system.volume", + "name": "Mute" + }, + "payload": { + "value": 0, + "extend": {} + } + } + +#### tv.system.volume.Unmute + 取消静音 + { + "header": { + "namespace": "tv.system.volume", + "name": "Unmute" + }, + "payload": { + "value": 0, + "extend": {} + } + } + +#### tv.system.light.Up + 调高亮度 + { + "header": { + "namespace": "tv.system.light", + "name": "Up" + }, + "payload": { + "value": 2, + "extend": {} + } +} + +#### tv.system.light.Down + 调低亮度 + { + "header": { + "namespace": "tv.system.light", + "name": "Down" + }, + "payload": { + "value": 2, + "extend": {} + } + } + +#### tv.system.constrast.Up + 对比度增大 + { + "header": { + "namespace": "tv.system.constrast", + "name": "Up" + }, + "payload": { + "value": 2, + "extend": {} + } + } + +#### tv.system.contrast.Down + 对比度减小 + { + "header": { + "namespace": "tv.system.constrast", + "name": "Down" + }, + "payload": { + "value": 2, + "extend": {} + } + } +#### tv.system.application.Open + 打开应用 + { + "header": { + "namespace": "tv.system.application", + "name": "Open" + }, + "payload": { + "name": "应用名称", + "package_name": "xxxx.apk", + "args": "模块名-子模块-子子", + "deep_link":"", + "extend": {} + } + } + +#### tv.system.application.Close + 关闭应用 + { + "header": { + "namespace": "tv.system.application", + "name": "Close" + }, + "payload": { + "name": "应用名称", + "package_name": "xxxx.apk", + "args": "模块名-子模块-子子", + "deep_link":"", + "extend": {} + } + + +#### tv.system.application.Upgrade + 升级应用 + { + "header": { + "namespace": "tv.system.application", + "name": "Upgrade" + }, + "payload": { + "name": "应用名称", + "package_name": "xxxx.apk", + "args": "", + "extend": {} + } + } + +#### tv.system.application.Uninstall + 卸载应用 + { + "header": { + "namespace": "tv.system.application", + "name": "Uninstall" + }, + "payload": { + "name": "应用名称", + "package_name": "xxxx.apk", + "args": "", + "extend": {} + } + } + +#### tv.system.command.Go + //打开主页launcher/系统设置/某个主页模块 + { + "header": { + "namespace": "tv.system.command", + "name": "Go" + }, + "payload": { + "name":"主页", //比如主页, 设置, 某个主页模块名 + "extend": {} + } + } + +#### tv.system.command.Exit + 退出 + { + "header": { + "namespace": "tv.system.command", + "name": "Exit" + }, + "payload": { + "extend":{} + } + } +#### tv.system.command.Back + 返回 + { + "header": { + "namespace": "tv.system.command", + "name": "Back" + }, + "payload": { + "extend":{} + } + } + +#### tv.system.command.Sleep + 休眠 + { + "header": { + "namespace": "tv.system.command", + "name": "Sleep" + }, + "payload": { + "extend":{} + } + } + +#### tv.system.command.Wake + 唤醒盒子 + { + "header": { + "namespace": "tv.system.command", + "name": "Wake" + }, + "payload": { + "extend":{} + } + } + +#### tv.system.command.TVOn + 打开电视 + { + "header": { + "namespace": "tv.system.command", + "name": "TVOn" + }, + "payload": { + "extend":{} + } + } + +#### tv.system.command.TVOff + 关闭电视 + { + "header": { + "namespace": "tv.system.command", + "name": "TVOff" + }, + "payload": { + "extend":{} + } + } +#### tv.system.channel.Open + 打开电视台的指令 + { + "header": { + "namespace": "tv.system.channel", + "name": "Open" + }, + "payload": { + "channel_name": "北京卫视", + "channel_code": "btv", + "extend": {} + } + } + +#### tv.system.channel.Update + 升级直播资源 + { + "header": { + "namespace": "tv.system.channel", + "name": "Update", + }, + "payload": { + "extend": { } + } + } +#### tv.player.resource.Play + 播放器播放指令 + { + "header": { + "namespace": "tv.player.resource", + "name": "Play", + }, + "payload": { //指令的参数 + "title" : "", //资源名称 + "description": "" //资源描述信息 + "uri": "资源唯一标识" //可以是url或者是资源id + "time_point" : "", //播放参数, 跳转到某个时间点进行播放 + "extend": {} + } + } + + +#### tv.player.control.Pause + 播放器暂停/继续 + { + "header": { + "namespace": "tv.player.control", + "name": "Pause", + }, + "payload": { + "value" : 1, //1:暂停 || 0: 继续(取消暂停) + "extend": {} + } + } +#### tv.player.control.FastForward + 快进 + { + "header": { + "namespace": "tv.player.control", + "name": "FastForward", + }, + "payload": { //指令的参数 + "offset":30 //快进一次跨越的时间, 默认30秒 + "extend": { } + } + } +#### tv.player.control.Goto + 指定时间点跳转 + { + "header": { + "namespace": "tv.player.control", + "name": "Goto", + }, + "payload": { //指令的参数 + "time_point": 367 //单位: 秒, 相对于影片开头的秒数 + "extend" : {} + } + } +#### tv.player.control.BackForward + 快退指令 + { + "header": { + "namespace": "tv.player.control", + "name": "BackForward", + }, + "payload": { //指令的参数 + "offset":30 //后退一次跨越的时间, 默认30秒 + "extend": { } + } + } + +#### tv.player.control.Speed + 播放器几倍速播放 + { + "header": { + "namespace": "tv.player.control", + "name": "Speed", + }, + "payload": { + "value" : 2 //几倍速度, 默认2倍 + "extend": {} + } + } + +#### tv.player.control.Previous + 上一集 + { + "header": { + "namespace": "tv.player.control", + "name": "Previous", + }, + "payload": { + "value" : 1 // 上一集 + "extend": {} + } + } + +#### tv.player.control.Next + 下一集 + { + "header": { + "namespace": "tv.player.control", + "name": "Next", + }, + "payload": { + "value" : 1 //下一集 + "extend": {} + } + } + +#### tv.player.control.Episode + 第3集 + { + "header": { + "namespace": "tv.player.control", + "name": "Episode", + }, + "payload": { + "value" : 3 //第3集 + "extend": {} + } + } + +#### tv.image.snapshot.Upload + 截图上传指令 + { + "header": { + "namespace": "tv.image.snapshot", + "name": "Upload", + }, + "payload": { + "behavior" : "" , + "extend": {} + } + + +#### tv.view.card.Render + 弹出层的视觉渲染(比如明星识图) + { + "header": { + "namespace": "tv.view.card", + "name": "Render" + }, + "payload": { + "title":"姚明", + "description":"中国著名篮球运动员", + "thumb":"https://imgsa.baidu.com/baike/sig.jpg", + "url":"http://baike.baidu.com/item/%E5%A7%9A%E6%98%8E/28", + "extend": {} + } + } + +#### tv.view.text.Render + 对话框中的文本内容 + { + "header": { + "namespace": "tv.view.text", + "name": "Render" + }, + "payload": { + "text":"姚明", + "extend": {} + } + } +#### tv.view.list.Render + 资源列表结果展示 + { + "header": { + "namespace": "tv.view.list", + "name": "Render" + }, + "payload": { + "ott_res": [{ + "resource_id": "123331", + "resource_name": "美国队长", + "type":"电影", + "category": "科幻", + "thumb": "http://aaa.jpg", + "description": "美国队长史蒂夫·罗杰斯(克里斯·埃文斯 Chris Evans 饰)带领着全新组建的复仇者联盟,继续维护世界和平。", + "score": "6.5"}, {}{}{}....{} + ], + "dvb_res": [{ + "channel_id": "123331", + "channel_name": "湖南卫视", + "resource_name": "快乐大本营", + "category": "综艺", + "thumb": "http://aaa.jpg", + "description": "何炅谢娜的快乐大本营。"},{},{},{}.....{} + ], + "extend": {} + } + } +#### tv.view.detail.Render + 单一结果,直接进详情页 + 去掉了resource_url: 原因是统一电影和电视剧字段格式, 把对应的数据放到了item数组里. + { + "header": { + "namespace": "tv.view.detail", + "name": "Render" + }, + "payload": { //指令的参数 + "type":"电影", //类型包含电影film, 电视剧tv, 综艺ent + "resource" : { + "resource_id":"1231111", + "resource_name":"美国队长", + "description":"美国队长史蒂夫·罗杰斯(克里斯·埃文斯 Chris Evans 饰)带领着全新组建的复仇者联盟,继续维护世界和平。", + "director":"乔·庄斯顿", + "actors":"克里斯·埃文斯,海莉·阿特维尔,塞巴斯蒂安·斯坦,雨果·维文,汤米·李·琼斯,史坦利·图齐", + "era":"2011", + "area":"美国", + "category":"科幻,动作", + "language":"英语", + "season":"", + "count":"", //电视剧总集数 + "poster_url":"http://........jpg", + "items":[ //如果是电视剧, item里每个元素是一集电视 + {"item_id": 1213211, + "item_number": "1", + "item_url" : "http://123123123.mp4"},{}...{} + ] + }, + "extend": {} + } + } + + +## 意图识别 NLU +### MV类目 +#### 原型 + ["我想唱东风破", { + "domain":"MV", + "intent":"MV_SEARCH", + "slots":{ + "song":"东风破", + "singer":"歌手名(周杰伦)", + "language":"国语/粤语/英文", + "emotion":"情感类型(欢快/悲伤)", + "type":"歌曲类型:民谣什么的", + "release_time":"发行年代, 如:2016", + "area":"港台/大陆", + "resolution":"清晰度", + "origin_version":"是/否原唱", + "sort_type":"排序规则(热度/评分等)", + "album":"专辑名称", + "lyric":"歌词" + } + + }] + +#### 样例 + ["我想唱东风破", { + "domain":"MV", + "intent":"MV_SEARCH", + "slots":{ + "song":"东风破", + } + }] + ["周杰伦的七里香", { + "domain":"MV", + "intent":"MV_SEARCH", + "slots":{ + "song":"七里香", + "singer":"周杰伦" + } + }] + ["唱首欢快的歌曲", { + "domain":"MV", + "intent":"MV_SEARCH", + "slots":{ + "emotion":"欢快" + } + }] + +### 影视类目 +#### 原型 + ["我想看武林外传", { + "domain":"FILM", + "intent":"FILM_SEARCH", + "slots":{ + "name":"武林外传", + "category":"电视剧/电影", + "channel":"电视台[北京卫视, 东方卫视]", + "series_file":"系列电影[美国队长, 谍影重重]", + "actor":"演员", + "director":"导员", + "presentor":"主持人", + "film_type":"喜剧/科幻", + "film_tag":"公主类/暴力类", + "description":"简介", + "area":"美国/意大利", + "time":"公映时间[1994]", + "is_free":"是否免费[是/否]", + "is_hot":"是否热映[是/否]", + "is_pre_release":"是否即将上映[是/否]", + "whdepart":"第几部", + "episode":"第几集", + "hd":"是否高清[是/否]", + "film_property":"询问的属性[name/category/channel/actor/director/type/area/language/time]", + } + + }] + +#### 样例 + ["我想看欢乐颂", { + "domain":"FILM", + "intent":"FILM_SEARCH", + "slots":{ + "name":"欢乐颂", + "category":"电视剧" + } + }] + ["看美国队长", { + "domain":"FILM", + "intent":"FILM_SEARCH", + "slots":{ + "name":"美国队长", + "category":"电影" + } + }] + ["我想看陈坤演的爱情片", { + "domain":"FILM", + "intent":"FILM_SEARCH", + "slots":{ + "actor":"陈坤", + "type":"爱情片" + } + }] + + +### 控制指令类目 +#### + ["声音大点", { + "domain":"COMMAND", + "intent":"volum.up", + "slots":{ + "value":1, + } + }] + ["声音小点", { + "domain":"COMMAND", + "intent":"volum.down", + "slots":{ + "value":1, + } + }] + ["静音", { + "domain":"COMMAND", + "intent":"volum.mute", + "slots":{ + } + }] + ["取消静音", { + "domain":"COMMAND", + "intent":"volum.unmute", + "slots":{ + } + }] + ["调节音量到5", { + "domain":"COMMAND", + "intent":"volume.set", + "slots":{ + "value":5 + } + }] + ["亮度增大", { + "domain":"COMMAND", + "intent":"light.up", + "slots":{ + "value":1 + } + }] + ["亮度减小", { + "domain":"COMMAND", + "intent":"light.down", + "slots":{ + "value":1 + } + }] + ["对比度增大", { + "domain":"COMMAND", + "intent":"contrast.up", + "slots":{ + "value":1 + } + }] + ["对比度减小", { + "domain":"COMMAND", + "intent":"contrast.down", + "slots":{ + "value":1 + } + }] + ["打开应用", { + "domain":"COMMAND", + "intent":"application.open", + "slots":{ + "name": "应用名称", + "package_name": "xxxx.apk", + "args": "模块名-子模块-子子", + "deep_link":"", + } + }] + ["关闭应用", { + "domain":"COMMAND", + "intent":"application.close", + "slots":{ + "name": "应用名称", + "package_name": "xxxx.apk", + "args": "模块名-子模块-子子", + "deep_link":"", + } + }] + ["卸载爱奇艺", { + "domain":"COMMAND", + "intent":"application.uninstall", + "slots":{ + "name": "应用名称", + "package_name": "xxxx.apk", + "args": "模块名-子模块-子子", + "deep_link":"", + } + }] + ["升级爱奇艺", { + "domain":"COMMAND", + "intent":"application.upgrade", + "slots":{ + "name": "应用名称", + "package_name": "xxxx.apk", + "args": "模块名-子模块-子子", + "deep_link":"", + } + }] + ["回到主页/打开设置", { + "domain":"COMMAND", + "intent":"command.go", + "slots":{ + "name":"主页", + } + }] + ["退出", { + "domain":"COMMAND", + "intent":"command.exit", + "slots":{ + } + }] + ["返回", { + "domain":"COMMAND", + "intent":"command.back", + "slots":{ + } + }] + ["关机", { + "domain":"COMMAND", + "intent":"command.tvoff", + "slots":{ + } + }] + ["开机", { + "domain":"COMMAND", + "intent":"command.tvon", + "slots":{ + } + }] + ["睡眠", { + "domain":"COMMAND", + "intent":"command.sleep", + "slots":{ + } + }] + ["唤醒", { + "domain":"COMMAND", + "intent":"command.wake", + "slots":{ + } + }] + ["打开北京卫视", { + "domain":"COMMAND", + "intent":"channel.open", + "slots":{ + "channel_name": "北京卫视", + "channel_code": "btv" + } + }] + ["升级播放资源", { + "domain":"COMMAND", + "intent":"channel.update", + "slots":{ + } + }] + ["播放器播放", { + "domain":"COMMAND", + "intent":"resource.play", + "slots":{ + "title" : "", //资源名称 + "description": "" //资源描述信息 + "uri": "资源唯一标识" //可以是url或者是资源id + "time_point" : "", //播放参数, 跳转到某个时间点进行播放 + } + }] + ["播放暂停/继续", { + "domain":"COMMAND", + "intent":"player.pause", + "slots":{ + "value": 1, //1:暂停 || 0: 继续(取消暂停) + } + }] + ["快进", { + "domain":"COMMAND", + "intent":"player.fastforward", + "slots":{ + "offset": 30, //快进一次跨越的时间, 默认30秒 + } + }] + ["快退", { + "domain":"COMMAND", + "intent":"player.backforward", + "slots":{ + "offset": 30, //快退一次跨越的时间, 默认30秒 + } + }] + ["按XX倍速播放", { + "domain":"COMMAND", + "intent":"player.speed", + "slots":{ + "value": 2, //几倍速度, 默认2倍 + } + }] + ["截图上传指令", { + "domain":"COMMAND", + "intent":"snapshot.upload", + "slots":{ + } + }] + +## ChangeLog +* 2017-2-7 + 增加MV类nlu返回的结果 +* 2017-2-10 + 增加影视类nlu返回的结果 +* 2017-2-14 + 命名空间增加前缀tv, 去掉behavior + 增加speech指令解释 +* 2017-2-15 + 增加打开设置, 打开某个首页模块的指令 + 增加了控制指令的nlu返回 + + +## 备注 +1. 点播资源和直播资源分两个指令,分页问题 +~~2.详情页:resoure_url去掉,假如推荐的资源字段,与item_list平级~~ +4. list页面加type,方便分类展示 +5. 设定所有value都为int类型,更改暂停value=1/0;为区别倍速后退,更改倍速播放的behavior=speedfast; 新增休眠、关机、唤醒、切换分辨率、~~上一集、下一集、第XX集等~~;——By: fanxing01, 2017.02.07 +7. view.text.render,用于显示返回的对话框的文本内容,比如未找到相关影片的话术。 +8. 需要为应用搜索结果定义接口。 +9. 需增加"打开设置"、"打开教育模块"等功能,重新确定指令tv.system.command.GoLauncher; +10. 控制指令的nlu字段设计;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/bot/sms.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,106 @@ +#发短信应用输出 + +bot_id: ai.dueros.bot.sms + +## v2 协议输出 +```javascript +{ + "result": { + "views": { + "type": "txt", + "content": "请问要发送什么内容?" + }, + "nlu": { + "domain": "phone", + "intent": "sms", + // 发短信包括:1. 请问要发给谁?;2. 请问要发送什么内容?;3. 短信问确认: 请问你要发送、取消还是修改?;4. 短信主动取消;5. 短信结束,正在为你发送短信 + "slots": { + "SMSKey": "短信", + "SendKey": "发", + "UseKey": "用", + "carrier": "联通", + "name": "测试薛斌" + "content": "短信内容", + } + }, + "resource": { + // TDDO: 带确认下面解析的名称 + "pinyin": "ce+shi+xue+bin", // 姓名拼音 + "same_pinyin_names": "[“张棋”,”张起”]", // 相同拼音的联系人 + "high_confidence_similar_names": ["张宁","张玲"], // 高置信度相似拼音 + "include_names": "[\"测试薛斌\"]", // 通讯录包含查找名称 + "similar_names": "["张层","张增"]", // 底置信度相似拼音 + "similar_include_names": "["张莹莹","张怡怡"]", // 包含底置信度相似拼音 + "recommend_names": "[\"测试薛斌\"]" // 模糊匹配命中名字 + "yellow_pages": "[{"name":"搜狐客服电话","number":"01062726666"}]" // 阿拉丁黄页客服 + }, + "speech": { + "type": "txt", + "content": "请问要发送什么内容?" + }, + "bot_id": "ai.dueros.bot.sms", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + } + }, + "id": "1494937215_367bkp6hf", + "logid": "14949372148532", + "user_id": "test_offline1490608414.0", + "time": 1494937215, + "cuid": null, + "se_query": "用联通卡发短信给薛斌", + "msg": "ok", + "status": 0 +} +``` + + +字段说明: +### view: + +|字段 | 描述 | 举例 | +|---|---|---| +|type | 返回展示卡片数据,必选字段,这里默认是文本 | txt | +|content | 文本内容 | 请问要发送什么内容? | + +### nlu: + +|slot |desc | value | +|---|---|---| +|name | 名字 | 中文名 | +|number | 电话号码 | eg:10086 | +|use_sim_index | sim卡号 | 1、2 | +|status|cancel|取消| +|content|短信内容|Eg:今晚加班晚点回家| + + +|slot |desc | value | +|---|---|---| +|name | 名字 | 中文名 | +|number | 电话号码 | eg:10086 | +|use_sim_index | sim卡号 | 1、2 | +|status|cancel|取消| + + +### resource: + +|字段 | 描述 | 举例 | +|---|---|---| +|pinyin | 姓名拼音 | eg:xuebin | +|same_pinyin_names | 相同拼音联系人 | Eg:[“张棋”,”张起”]| +|include_names | 通讯录包含联系人 | Eg:["张宁宁","张玲玲"]| +|high_confidence_similar_names | 高置信度相似拼音 | Eg:["张宁","张玲"]| +|similar_names | 低置信度相似拼音 | Eg:["张层","张增"]| +|similar_include_names | 包含底置信度相似拼音 | Eg:["张莹莹","张怡怡"]| +|recommend_names | 模糊匹配命中名字 | Eg:["张莹莹","张怡怡"] 排序规则:name、same-pingyin-name、high-confidence—Similar–names、include-name、Similar–names、Similar–include-names| +|yellow_pages | 客服黄页 | Eg:[{"name":"搜狐客服电话","number":"01062726666"}]| + + +### speech: + +|字段 | 描述 | 举例 | +|---|---|---| +|type | 文本格式 | txt | +|content | 语音文本 | 请问要发送什么内容? |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/bot/speaker_hardware.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,74 @@ +speaker_hardware 返回案例 + + +```javascript +"data": { + "directives": [ + { + "header": { + "namespace": "Speaker", + "name": "SetVolume", + "message_id": "1494329999_103fg56vq" + }, + "payload": { + "volume": 93 + } + }, + { + "header": { + "namespace": "Speaker", + "name": "SetMute", + "message_id": "1494329999_18078ukiv" + }, + "payload": { + "mute": false + } + } + ], + "nlu": { + "domain": "control.hardware", + "intent": "control.hardware.volume", + "slots": { + "vol_up": "大", + "vol_up_size": "0.50" + } + }, + "speech": {}, + "prompt": {}, + "resource": {}, + "views": [], + } + ``` + +### control.hardware.volume 调声音 +可能的slots: + +slot key|slot value +--------|---------- +vol_down|小、高 +vol_up|大、低 +vol_set_size|50(指定值)如果值为小数,视为百分比 + +### nlu +声音调大50% + +```javascript +{ + "domain": "control.hardware", + "intent": "control.hardware.volume", + "slots": { + "vol_up": "大", + "vol_up_size": "0.50" + } +}, +``` +#### nlu部分的说明 +intent | 说明 +:--------:|:--------: +intent:control.hardware.volume |底层音箱调音 +intent:control.hardware.micphone|底层音箱调麦克风 +intent:control.hardware.bluetooth|底层音箱调蓝牙 + +### directives 部分的说明 + +参考[Speaker](../directives/Speaker.md)硬件相关指令
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/bot/taxi_order.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,602 @@ +# 打车bot多轮状态转移过程 +## 状态机 +![图片](http://bos.nj.bpc.baidu.com/v1/agroup/14773a5100540790187d37513e15c0c1714e637e) + +## Book +### askTime +#### 进入条件 +满足如下条件之一: + +* 有约车意图 +* 时间槽位有值,但是时间不明确或者非法 + +#### 澄清逻辑 +时间澄清策略与提醒时间澄清逻辑一致(非重复提醒),但有如下区别: + ++ 有效时间范围:今天、明天、后天,三天之内,超过报非法 ++ 最近的可约时间:20分钟后的最近的十分点(10,20,30,40,50,00) ++ 若约车时间小于最近可约时间,自动去最近可约时间,不会报非法 ++ 没有凌晨澄清逻辑 + +说明:时间澄清策略wiki:http://wiki.baidu.com/pages/viewpage.action?pageId=218313803 + +### askPosition +#### 进入条件 +满足如下条件之一: + ++ 没有打车目的地 ++ 无定位信息且没有出发地址(默认出发地为当期位置) ++ 地址非法 + +#### 地址处理 +异常包括: + ++ 出发地城市无法确定 ++ 在出发地城市,没有定位到目的地 + +参考:http://agroup.baidu.com/duer/md/edit/237312 + +### askCarType +#### 进入条件 +满足如下条件之一: + ++ 没有car_type ++ car_type指定的车辆类型无法满足(附近没有对应的车辆) + +#### 车类型合法性验证 +通过车辆数量费用接口,如果车辆数量为0,即为非法。 + +### askResubmitOrder +#### 进入条件 +订单创建过程可能出现如下异常状况: + ++ 价格倍数突然变化,比如:临时调价1.5倍 ++ 下单失败 + +上述状况会进入resubmitOrder状态 + +### 车辆状态Polling +#### 进入条件 +如下两种条件会启动订单状态轮询: + ++ 即时打车订单创建成功后 ++ 约车订单,约定上车时间前30分钟开始 + +#### 轮询过程 +![图片](http://bos.nj.bpc.baidu.com/v1/agroup/a340217441a71bfa2041b8a07dc39c90e533b237) + +上述过程,列出了4中轮询过程中的server push + ++ 等待司机接单超过1min,这种情况经常出现在用车高峰期。会询问用户是继续等待还是取消订单。 ++ 司机接单。如果是约车订单,停止轮询,否则轮询周期改为60s一次。 ++ 司机到达。 ++ 订单完成。 + +## CancelOrder +### 生效条件 +满足下列条件之一: + ++ 当前有订单进行中,且没有上车 ++ 有约车订单 + +说明: + ++ 从订单创建成功到上车之前,都可以取消订单 ++ 即时的订单取消,不会有confirm; + +## WaitOrder +对应订单创建过程中,长时间没有司机接单的情况。 + +### 生效条件 +满足如下条件: + ++ 订单创建成功到司机接单期间 + +说明: + ++ 用户肯定答复,仅仅回复话术 + +## CallDriver +### 进入条件 +满足如下条件: + ++ 订单状态为司机已接单,以及以后的状态(约车订单也可以呼叫) + +## QueryStatus +满足如下条件: + ++ 当前有即时打车订单 ++ 订单状态为司机已接单,以及以后的状态 + +# 打车订单创建多轮 +## 完整的叫车例子: +```javascript +//query = 帮我叫个出租车去西二旗地铁站 +{ + "result": { + "bot_id": "rent_car", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "下单确认起始地:什刹海街道米粮库社区西北116米\n目的地:西二旗\n车辆类型:出租车" + }, + { + "type": "txt", + "content": "请确认下单" + } + ], + "nlu": { + "domain": "rent_car", + "intent": "rent_car.book", + "slots": { + "car_type": "出租车", + "end_point": "西二旗地铁站", + "loc_fragment": "西", + "to_loc": "西二旗地铁站" + } + }, + "speech": { + "type": "Text", + "content": "下单确认起始地:什刹海街道米粮库社区西北116米\n目的地:西二旗\n车辆类型:出租车。请确认下单" + } + }, + "id": "1490598241_8768w33x8", + "logid": "14905982406254", + "user_id": null, + "time": 1490598241, + "cuid": "test", + "se_query": "帮我叫个出租车去西二旗地铁站", + "msg": "ok", + "client_msg_id": "58512fc9-d688-4e4e-9263-14495de3a60a", + "status": 0 +} +``` +### nlu部分的说明 +intent:rent_car.book 打车意图 +### slots 说明 +|slot_name|解释|slot_value|说明| +|----|----|--------|--------| +|end_point|目的地|地址,比如西二旗|string| +|car_type|用车类型|比如快车、专车、出租车|string| + +## 完整的约车例子 +//query = 帮我约个明天上午8点的出租车去西二旗地铁站 +```javascript +{ + "result": { + "bot_id": "rent_car", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "抱歉,目前只有专车支持预约。" + }, + { + "type": "txt", + "content": "下单确认起始地:什刹海街道米粮库社区西北116米\n目的地:西二旗\n车辆类型:专车\n预估价格:88元\n用车时间:03月28日 08时00分" + }, + { + "type": "txt", + "content": "请确认下单" + } + ], + "nlu": { + "domain": "rent_car", + "intent": "rent_car.book", + "slots": { + "car_type": "专车", + "end_point": "西二旗地铁站", + "loc_fragment": "西", + "reserve_order": "1", + "service_time": "{\"apm\":\"am\",\"day\":\"next\",\"hour\":\"8\",\"raw\":{\"apm\":\"明天上午\",\"day\":\"明天上午\",\"hour\":\"8点\"}}\n", + "to_loc": "西二旗地铁站" + } + }, + "speech": { + "type": "Text", + "content": "抱歉,目前只有专车支持预约。。下单确认起始地:什刹海街道米粮库社区西北116米\n目的地:西二旗\n车辆类型:专车\n预估价格:88元\n用车时间:03月28日 08时00分。请确认下单" + } + }, + "id": "1490598770_851ayoo1r", + "logid": "14905987688475", + "user_id": null, + "time": 1490598770, + "cuid": "test", + "se_query": "帮我约个明天上午8点的出租车去西二旗地铁站", + "msg": "ok", + "client_msg_id": "58512fc9-d688-4e4e-9263-14495de3a60a", + "status": 0 +} +``` +### slots 说明 +|slot_name|解释|slot_value|说明| +|----|----|--------|--------| +|reserve_order|是否约车|0或者1|string| +|service_time|用车时间|json格式,wiki:todo|string| + + +## 下单所需槽位搜集完整,确认下单 +```javascript +//query = 确认下单 +{ + "result": { + "bot_id": "rent_car", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "正在为你叫车,请耐心等待....." + } + ], + "nlu": { + "domain": "rent_car", + "intent": "rent_car.book", + "slots": { + "car_type": "出租车", + "end_point": "西二旗地铁站", + "loc_fragment": "西", + "to_loc": "西二旗地铁站", + "confirm_intent": "1" + } + }, + "speech": { + "type": "Text", + "content": "正在为你叫车,请耐心等待....." + } + }, + "id": "1490598579_192ffpxeh", + "logid": "14905985779877", + "user_id": null, + "time": 1490598579, + "cuid": "test", + "se_query": "确认", + "msg": "ok", + "client_msg_id": "58512fc9-d688-4e4e-9263-14495de3a60a", + "status": 0 +} +``` + +## 槽位不完整询问例子 +### 问end_point +```javascript +{ +... + "views": [ + { + "type": "txt", + "content": "请问你打车去哪?" + } + ], + "nlu": { + "domain": "rent_car", + "intent": "rent_car.book", + "slots": {} + }, + "speech": { + "type": "Text", + "content": "请问你打车去哪?" + } +... +} +``` + +### 问约车时间 +```javascript +{ +... + "views": [ + { + "type": "txt", + "content": "请问预约什么时候的车呢?" + } + ], + "nlu": { + "domain": "rent_car", + "intent": "rent_car.book", + "slots": { + "car_type": "专车", + "reserve_order": "1" + } + }, + "speech": { + "type": "Text", + "content": "请问预约什么时候的车呢?" + } +... +} +``` + +### 问车辆类型 +```javascript +{ +... + "views": [ + { + "type": "txt", + "content": "什刹海街道米粮库社区西北116米到西二旗出租车:最近司机约1分钟抵达,附近10辆车。\n\n快车:。\n\n专车:首汽约车,最近司机约3分钟抵达,附近10辆车,预估96元。\n\n请选择车型" + } + ], + "nlu": { + "domain": "rent_car", + "intent": "rent_car.book", + "slots": { + "end_point": "西二旗" + } + }, + "speech": { + "type": "Text", + "content": "什刹海街道米粮库社区西北116米到西二旗出租车:最近司机约1分钟抵达,附近10辆车。\n\n快车:。\n\n专车:首汽约车,最近司机约3分钟抵达,附近10辆车,预估96元。\n\n请选择车型" + } +... +} +``` + +### slots 说明 +|slot_name|解释|slot_value|说明| +|----|----|--------|--------| +|confirm_intent|确认意图|0或者1|string| + + +# 打车订单取消intent +//取消打车订单 +```javascript +{ + "result": { + "bot_id": "rent_car", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "订单取消成功" + } + ], + "nlu": { + "domain": "rent_car", + "intent": "rent_car.cancel_order", + "slots": { + "enum": "取消打车订单" + } + }, + "speech": { + "type": "Text", + "content": "订单取消成功" + } + }, + "id": "1490600187_806d0pb9v", + "logid": "14906001876248", + "user_id": null, + "time": 1490600187, + "cuid": "test", + "se_query": "取消打车订单", + "msg": "ok", + "client_msg_id": "58512fc9-d688-4e4e-9263-14495de3a60a", + "status": 0 +} +``` +### nlu部分的说明 ++ intent:rent_car.cancel_order 打车取消意图 ++ slots 可不关注 + +# 查询司机位置intent +```javascript +//query = 司机到哪儿了 +{ + "result": { + "bot_id": "rent_car", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "距你2.2公里,预计5分钟后到达" + } + ], + "nlu": { + "domain": "rent_car", + "intent": "rent_car.query_status", + "slots": { + "enum": "司机到哪儿了" + } + }, + "speech": { + "type": "Text", + "content": "距你2.2公里,预计5分钟后到达" + } + }, + "id": "1490600411_0474khogv", + "logid": "14906004108530", + "user_id": null, + "time": 1490600411, + "cuid": "test", + "se_query": "司机到哪儿了", + "msg": "ok", + "client_msg_id": "58512fc9-d688-4e4e-9263-14495de3a60a", + "status": 0 +} +``` +### nlu部分的说明 ++ intent:rent_car.query_status 查询司机位置intent ++ slots 可不关注 + +# 继续等待司机接单intent +```javascript +//query = 司机到哪儿了 +{ + "result": { + "bot_id": "rent_car", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "度秘将为你持续叫车" + } + ], + "nlu": { + "domain": "rent_car", + "intent": "rent_car.wait_order", + "slots": { + "enum": "继续等待" + } + }, + "speech": { + "type": "Text", + "content": "度秘将为你持续叫车" + } + }, + "id": "1490600411_0474khogv", + "logid": "14906004108530", + "user_id": null, + "time": 1490600411, + "cuid": "test", + "se_query": "继续等待", + "msg": "ok", + "client_msg_id": "58512fc9-d688-4e4e-9263-14495de3a60a", + "status": 0 +} +``` +### nlu部分的说明 ++ intent:rent_car.wait_order 继续等待intent ++ slots 可不关注 + +# UI交互卡片 +## 登录 +``` +{ + "result": { + "bot_id": "rent_car", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "去登录度秘很愿意帮你,但需要您先登录账号后度秘才能操作哦,快去登录吧", + "url": "http://xiaodu.baidu.com/saiya/uber/login" + } + ], + "nlu": { + "domain": "rent_car", + "intent": "rent_car.book", + "slots": {} + }, + "speech": { + "type": "Text", + "content": "度秘很愿意帮你,但需要您先登录账号后度秘才能操作哦,快去登录吧" + } + }, + "id": "1490603466_603cfb901", + "logid": "14906034663181", + "user_id": null, + "time": 1490603466, + "cuid": "test", + "se_query": "我要打车", + //需要调用百度passport登录 + "need_passport_login": true, + "msg": "ok", + "client_msg_id": "58512fc9-d688-4e4e-9263-14495de3a60a", + "status": 0 +} +``` + +## 绑定银行卡 + +```javascript +{ + "result": { + "bot_id": "rent_car", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "开通授权支付抱歉,你还没有绑定银行卡,请先绑定后,度秘才能再为你叫车", + "url": "https://www.baifubao.com/wap/0/contract_sign/0?service_code=1&sp_no=3300000109&order_create_time=20170328174302&order_no=17032894182256508059&goods_name=%B0%D9%B6%C8%D7%A8%B3%B5%CA%DA%C8%A8%C7%A9%D4%BC&unit_amount=0&unit_count=1&transport_amount=0&total_amount=0¤cy=1&return_url=http%3A%2F%2Falliance.carpo.baidu.com%2Fpay%2Fcontract%2Fsigncallback&pay_type=2&input_charset=1&version=2&sign_method=1&sp_user_name=175441974&contract_type=1&pure_sign=1&sign=b715f6b12d54c178bdf8b9e0446a7471" + } + ], + "nlu": { + "domain": "rent_car", + "intent": "rent_car.book", + "slots": {} + }, + "speech": { + "type": "Text", + "content": "开通授权支付,抱歉,你还没有绑定银行卡,请先绑定后,度秘才能再为你叫车" + } + }, + "id": "1490694182_3537qxbb5", + "logid": "14906941819388", + "user_id": "4541", + "time": 1490694182, + "cuid": null, + "se_query": "我要打车", + "msg": "ok", + "status": 0 +} +``` +## 打电话 +```javascript +{ + "result": { + "bot_id": "rent_car", + "bot_meta": { + "version": "1.0.0", + "type": "其他", + "description": "desc" + }, + "views": [ + { + "type": "txt", + "content": "正在打电话给司机,请稍等", + "url": "xiaoduapp://phone?number=123242134134" + } + ], + "nlu": { + "domain": "rent_car", + "intent": "rent_car.call_driver", + "slots": { + "driver_phone_number" : "1234123123" + } + }, + "speech": { + "type": "Text", + "content": "正在打电话给司机,请稍等" + } + }, + "id": "1490694182_3537qxbb5", + "logid": "14906941819388", + "user_id": "4541", + "time": 1490694182, + "cuid": null, + "se_query": "我要打车", + "msg": "ok", + "status": 0 +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/build.sh Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,56 @@ +#brew install pandoc + +cat >files <<END +mateapp.md +tutorial.md +sdk/index.md +api/overview.md +api/request.md +api/response.md +directives/AudioPlayer.md +directives/Speaker.md +directives/SpeechSynthesizer.md +directives/SpeechRecognizer.md +directives/UiControl.md +directives/SmartHomeControl.md +directives/ImageRecognizer.md +bot/smart_tv.md +Skills.md +BOTAPI_README.md +BOTAPI2.0_README.md +END + +######### update index +for f in $(cat files|grep -v '#') +do +cat >tmp_awk_script <<END +BEGIN{ + off=0; +} +{ + if(\$0~/^## Table of Contents/) { + print + off=1 + print "\n" + system("./gh-md-toc $f|grep '*'"); + print "\n" + }else if(\$0~/^##/) { + off=0 + } + if(off==0){ + print + } +} +END +awk -f tmp_awk_script $f >tmp_md +rm tmp_awk_script +mv tmp_md $f +done +##################### + + +#pandoc -f markdown -t docx OPENAPI_README.md -o OPENAPI_README.docx +#pandoc -f markdown -t html OPENAPI_README.md -o OPENAPI_README.html + + +#tar czvf openapi$(date +%Y%m%d).tgz OPENAPI_README.md OPENAPI_README.docx OPENAPI_README.html img sdk/sdk_v2_online.zip
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/demo.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,27 @@ + + +[下载demo](sdk/sdk_v2_online.zip) +解压后安装里面的app-release.apk + + +![demo1](http://f.hiphotos.baidu.com/xiaodu/pic/item/18d8bc3eb13533facf24ffaca1d3fd1f40345ba5.jpg) + +点语音识别 + +![demo2](http://b.hiphotos.baidu.com/xiaodu/pic/item/838ba61ea8d3fd1f10f8ceb8394e251f94ca5fba.jpg) + +点vad模式 + +![demo3](http://d.hiphotos.baidu.com/xiaodu/pic/item/a686c9177f3e670992f3297d32c79f3df9dc5544.jpg) + +点顶上的按钮切换 + +![demo4](http://f.hiphotos.baidu.com/xiaodu/pic/item/bd3eb13533fa828beb14f261f41f4134970a5a78.jpg) + +点下面的“点一下说话” + +![demo5](http://g.hiphotos.baidu.com/xiaodu/pic/item/203fb80e7bec54e72829769cb0389b504ec26a6e.jpg) + +收到结果json + +json格式的文档[openapi doc](OPENAPI_README.md)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/directives/Alerts.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,174 @@ +## Alerts数据结构 +### <span id="alert_struct">AlertsStruct</span> +```javascript +AlertsStruct = { + "token": string,// 唯一标识 + "type": string,// Alert类型 TIMER|ALARM + "scheduled_time": string,// Alert触发时间,秒级时间戳 + "content": string, // Alert事件名称 + + // ####### 接入完整能力不要关注此字段######### + "extensions": ExtensionsStruct json, // 可选,额外信息,qu能力级别输出携带,例如接入完整能力的A音箱则没有该字段,接入qu能力的B手机助手则有该字段|mateapp携带 +} +``` +```javascript +ExtensionsStruct = { + "start_time": int, // 开始时间 + "content": string, // 事件名称 + "duration": int, // timer时长 + "repeat_type": string, // 重复类型 day|week|month|year + "repeat_week": int, // 可选,重复星期 从低位到高位表示星期一到星期日 + "repeat_month": int, // 可选,重复月 从低位到高位表示1~12月 + "repeat_year": string, // 可选, 重复年 12-1,8-2 + "special_calender": string, // 农历,lunar + "special_day": string, // 工作日, weekday +} +``` + + +### SetAlert Directive +1、客户端通过语音创建alarm、timer +2、mateapp重新开启已经创建的alarm、timer +3、mateapp更新已经创建的alarm、timer + +```javascript + { + "header": { + "namespace": "Alerts", + "name": "SetAlert", + "message_id": string, + }, + "payload": AlertsStruct,// 见Alerts数据结构 + } +``` + +### SetAlertSucceeded Event +客户端在收到SetAlert Directive后成功创建Alert必须向DCS上报SetAlertSucceeded Event +```javascript +{ + "header": { + "namespace": "Alerts", + "name": "SetAlertSucceeded" + }, + "payload": { + "token": string,// 唯一标识 + } +} +``` + +### SetAlertFailed Event +客户端在收到SetAlert Directive后未成功创建Alert必须向DCS上报SetAlertFailed Event +```javascript +{ + "header": { + "namespace": "Alerts", + "name": "SetAlertFailed" + }, + "payload": { + "token": string,// 唯一标识 + } +} +``` + +### DeleteAlert Directive +DCS下发DeleteAlert Directive场景: +1、客户端通过语音删除alarm、timer +2、客户端通过语音停止响铃的alarm、timer +2、mateapp删除alarm、timer +3、mateapp暂停已经创建的alarm + +```javascript + { + "header": { + "namespace": "Alerts", + "name": "DeleteAlert", + "message_id": string, + }, + "payload":{ + "token": string,// 唯一标识 + } + } +``` + +### DeleteAlertSucceeded Event +客户端在收到DeleteAlert Directive后成功删除Alert必须向DCS上报DeleteAlertSucceeded Event +```javascript +{ + "header": { + "namespace": "Alerts", + "name": "DeleteAlertSucceeded" + }, + "payload": { + "token": string,// 唯一标识 + } +} +``` + +### DeleteAlertFailed Event +客户端在收到DeleteAlert Directive后未成功删除Alert必须向DCS上报DeleteAlertfailed Event +```javascript +{ + "header": { + "namespace": "Alerts", + "name": "DeleteAlertFailed" + }, + "payload": { + "token": string,// 唯一标识 + } +} +``` + +### AlertStarted Event +Alert到触发时间响铃必须向DCS上报AlertStarted Event +```javascript +{ + "header": { + "namespace": "Alerts", + "name": "AlertStarted" + }, + "payload": { + "token": string,// 唯一标识 + } +} +``` +### AlertStopped Event +Alert停止正在响铃的Alert必须向DCS上报AlertStopped Event +```javascript +{ + "header": { + "namespace": "Alerts", + "name": "AlertStoped" + }, + "payload": { + "token": string,// 唯一标识 + } +} +``` + + +## 前后台切换 +### AlertEnteredForeground Event +```javascript +{ + "header": { + "namespace": "Alerts", + "name": "AlertEnteredForeground" + }, + "payload": { + "token": string,// 唯一标识 + } +} +``` + +### AlertEnteredBackground Event +```javascript +{ + "header": { + "namespace": "Alerts", + "name": "AlertEnteredBackground" + }, + "payload": { + "token": string,// 唯一标识 + } +} +```
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/directives/AudioPlayer.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,251 @@ +# AudioPlayer + +## Table of Contents + + + * [AudioPlayer](#audioplayer) + * [Table of Contents](#table-of-contents) + * [AudioPlayer.Play指令](#audioplayerplay指令) + * [AudioPlayer.Stop指令](#audioplayerstop指令) + * [PlaybackStarted事件](#playbackstarted事件) + * [PlaybackStopped事件](#playbackstopped事件) + * [PlaybackNearlyFinished事件](#playbacknearlyfinished事件) + * [PlaybackFinished事件](#playbackfinished事件) + * [ProgressReportIntervalElapsed事件](#progressreportintervalelapsed事件) + * [上报AudioPlayer状态(在请求中)](#上报audioplayer状态在请求中) + * [有屏设备接入音乐、有声等音频服务](#有屏设备接入音乐有声等音频服务) + * [FAQ](#faq) + * [Changelog](#changelog) + + +## AudioPlayer.Play指令 +用户对音箱说“播放周杰伦的歌曲”、“播放郭德纲的相声”、"继续播放"、“下一首”、“上一首”、“下一个专辑”、“上一个专辑”都返回一个Play指令。 +```json +{ + "header": { + "namespace": "AudioPlayer", + "name": "Play", + "message_id": "message_id-1344" + }, + "payload": { + "play_behavior": "REPLACE_ALL", + "audio_item": { + "audio_item_id": "156", + "stream": { + "url": "http://yinyueshiting.baidu.com/data2/music/124088643/124088643.mp3?xcode=57462f29cfc176f86a37d80a2c02fc5b", + "stream_format": "AUDIO_MP3", + "offset_ms": 0, + "token": "156", + "progress_report_interval_ms": 1000 + } + } + } +} +``` +参数 | 描述 | 类型 | 必须 +---- | --- | --- | --- +play_behavior | REPLACE_ALL:清空播放列表,立即播放指令关联的音频。"播放周杰伦的歌曲"、"播放郭德纲的相声"、"下一首"、"上一首",使用它。ENQUEUE:把指令关联的音频添加到播放列表末尾,当前播放的音频不受影响.下一首预取的时候试用它。REPLACE_ENQUEUED:清空播放列表,同时把指令关联的音频加到播放列表,但当前播放的歌曲不受影响。"这首歌播放完后播放周杰伦的歌曲",使用它;用户说“单曲循环、列表循环、随机播放”的时候,也使用它。| string | 是 +audio_item | 音频对象,包括音频流和元数据 | object | 是 +audio_item.audio_item_id | 音频ID | string | 是 +audio_item.stream | 音频流对象 | object | 是 +audio_item.stream.url | 音频流url | string | 是 +audio_item.stream.stream_format | 音频流格式: AUDIO_MP3、AUDIO_M3U8、AUDIO_M4A | string | 是 +audio_item.stream.offset_ms | 客户端从哪里开始播放音频,如果值等于0,从开头播放。 | long | 是 +audio_item.stream.token | 同音频ID | string | 是 +audio_item.stream.progress_report_interval_ms |客户端每隔多长时间上报一次进度,这个取值必须大于0,如果没有这个字段,则不上报进度 | long | 否 + +## AudioPlayer.Stop指令 +```json +{ + "header": { + "namespace": "AudioPlayer", + "name": "Stop", + "message_id": "message_id-1344" + }, + "payload": { + } +} +``` + +## PlaybackStarted事件 +客户端开始播放的时候,需要上报此事件。 +```json +{ + "device_event": { + "header": { + "namespace": "AudioPlayer", + "name": "PlaybackStarted", + "message_id": "message_id-1344" + }, + "payload": { + "token": "156", + "offset_ms": 10000 + } + } +} +``` +## PlaybackStopped事件 +用户说"暂停播放"、 "停止播放"后,会收到Stop指令,客户端执行完Stop指令后,即暂停播放后,需要上报此事件,云端会保存断点,供下一次继续播放使用。 +```json +{ + "device_event": { + "header": { + "namespace": "AudioPlayer", + "name": "PlaybackStopped", + "message_id": "message_id-1344" + }, + "payload": { + "token": "156", + "offset_ms": 10000 + } + } +} +``` +## PlaybackNearlyFinished事件 +这个事件用来获取下一首歌曲,云端收到这个事件后,返回下一首歌曲对应的Play指令,play_behavior选项设为ENQUEUE, +指示客户端加入到本地列表中,利用此事件,客户端可以实现下一首的预取。这个事件的上报时机取决于客户端, +可以在歌曲播放的中间发送,也可以剩余几秒钟的时候发送。如果不需要预取,也可以在歌曲播放完毕后上报此事件。但必须保证: + +1 PlaybackNearlyFinished必须在PlaybackStarted事件发送完毕后才上报。 + +2 一首歌曲只发送一次PlaybackNearlyFinished事件。 + +```json +{ + "device_event": { + "header": { + "namespace": "AudioPlayer", + "name": "PlaybackNearlyFinished", + "message_id": "message_id-1344" + }, + "payload": { + "token": "156", + "offset_ms": 10000 + } + } +} +``` +## PlaybackFinished事件 +当且仅当歌曲正常播放到末尾后,上报此事件。注意如果被其它指令打断比如“下一首”、“上一首”导致没有播放到末尾的,不上报此事件。 +```json +{ + "device_event": { + "header": { + "namespace": "AudioPlayer", + "name": "PlaybackFinished", + "message_id": "message_id-1344" + }, + "payload": { + "token": "156", + "offset_ms": 10000 + } + } +} +``` +## ProgressReportIntervalElapsed事件 +如果Play指令设置了progress_report_interval_ms的值,那么客户端需要周期性的每隔一段时间上报一次当前的播放进度, +直到歌曲播放结束。注意歌曲开始播放和歌曲结束播放的时候,可以不上报这个事件。 + +情况1:假如progress_report_interval_ms的值为3000,Play指令的offset_ms值为0, 从音频流的0位置算起,如果播放位置到达3000的整数倍,就上报一次事件。 + +情况2:假如progress_report_interval_ms的值为3000,Play指令的offset_ms值为1000, 从音频流的0位置算起,如果播放位置到达3000的整数倍,就上报一次事件。 + +这2种情况,上报事件时所处的播放位置是一样的,跟offset_ms的值没有关系,因为是从音频流的0位置算起。 +云端收到这个事件后,可能会返回给客户端一条指令,需要客户端执行之,比如Stop指令、AdjustVolume指令等。利用这个特性可以实现助眠模式。 + + +## 上报AudioPlayer状态(在请求中) + +```javascript +"device_status":{ + "AudioPlayer":{ + "token":"xxx",//正在播放的音频流id + "offset_ms":20000,//播放到多少ms了 + "player_activity":"IDLE PAUSED PLAYING BUFFER_UNDERRUN FINISHED STOPPED" + }, +}, +``` + +## 有屏设备接入音乐、有声等音频服务 +Directive和Event机制非常适合无屏设备使用,对于有屏设备, +也推荐使用Directive和Event机制接入音频服务,端和云之间的交互的性能和流畅性会更好,带来更好的用户体验。 +但是如果厂商认为接入Directive和Event开发成本高,需要快速出产品效果,也可以通过NLU+Resource的方式接入音频服务,具体流程如下: + +1. 用户语音说“”播放周杰伦的歌曲”,发起第一次网络请求,DuerOS云端除了返回Play指令外,还会返回resource,里面有一个api + url,用于从云端获取播放列表,端上发起第二次网络请求获取播放列表在屏幕展现,然后端上拿到列表中第一首歌曲的ID,向度秘云端 + 发起第三次网络请求,拿到第一首歌曲的MP3 + URL,开始音频的播放。这里需要三次网络请求才能实现歌曲的播放,链路长,性能不好,如果为了更快的播放,端上可以选择第一次网络请求后,从Play指令中提取MP3 + URL,直接开始第一首歌曲的播放,不用等到第二次和第三次网络请求之后就能播放歌曲了。 + +2. 用户在屏幕GUI上点击一首歌曲的播放,端上发起一次网络请求,根据歌曲ID拿到MP3 URL,开始播放用户点击的歌曲。 + +3. 用户语音说"下一首",发起第一次网络请求,DuerOS云端返回NLU结果,客户端判断NLU结果为换一首,然后本地取得下一首歌曲的歌曲ID,发起第二次网络请求,拿到MP3 URL,开始下一首歌曲的播放。 + 其它播放控制也类似,DuerOS NLU支持的播放控制,可以参考[音乐](../bot/audio_music.md) 、[点播](../bot/audio_unicast.md)、[直播](../bot/audio_live.md)。 + +4. 用户语音说“换一批”,发起第一次网络请求,DuerOS云端返回NLU结果,客户端判断NLU结果为换一批,发起第二次网络请求,获取下一页的歌曲列表,将列表中第一首歌曲的ID,发起第三次网络请求,拿到MP3 + URL,开始下一批歌曲的播放。 + +5. 用户在频幕GUI上的上滑翻页操作,请求播放列表的接口,拿到下一页的歌曲列表,追加到GUI的播放列表中。 + +## FAQ +* 如何实现暂停、继续 + +暂停和继续只需要实现Play和Stop两个指令,语音说“暂停”,云端返回Stop指令,客户端收到指令后执行暂停,同时立马上报一个PlaybackStopped的事件, +云端收到事件后把断点位置offset_ms保存下来,接下来语音说“继续”,云端返回Play指令,offset_ms的值为上一次说暂停时上报的位置,客户端收到Play指令后, +从offset_ms的位置开始播放,从而实现继续播放的功能。 + +* 如何实现循环模式(列表循环、随机播放、单曲循环) + +循环模式的逻辑由云端实现,客户端不需要实现循环模式的逻辑,客户端只需要维持本地的播放列表,一首一首的播放,以及实现Play指令的play_behavior的REPLACE_ENQUEUED模式,例如单曲循环的实现: +当前正在播放的音频id为156,语音说“单曲循环”,云端会把播放模式切换为单曲循环,同时返回一个Play指令 +```json +{ + "header": { + "namespace": "AudioPlayer", + "name": "Play", + "message_id": "message_id-1344" + }, + "payload": { + "play_behavior": "REPLACE_ENQUEUED", + "audio_item": { + "audio_item_id": "156", + "stream": { + "url": "http://yinyueshiting.baidu.com/data2/music/124088643/124088643.mp3?xcode=57462f29cfc176f86a37d80a2c02fc5b", + "stream_format": "AUDIO_MP3", + "offset_ms": 0, + "token": "156", + "progress_report_interval_ms": 1000 + } + } + } +} +``` +Play指令的play_behavior为REPLACE_ENQUEUED,客户端清空本地之前预取保存的播放列表,同时把音频id为156的歌曲加入到播放列表,当前播放的歌曲不受 +影响,继续播放直到结束,结束后开始播放本地播放列表中的下一首歌曲,即音频id为156的歌曲。这里重点是要清空本地的播放列表,否则下一首歌曲可能不会符合预期。播放到一定位置后,客户端上报PlaybackNearlyFinished事件 +实现预取,云端返回的音频id依然为156,播放模式为ENQUEUED。 +```json +{ + "header": { + "namespace": "AudioPlayer", + "name": "Play", + "message_id": "message_id-1344" + }, + "payload": { + "play_behavior": "ENQUEUED", + "audio_item": { + "audio_item_id": "156", + "stream": { + "url": "http://yinyueshiting.baidu.com/data2/music/124088643/124088643.mp3?xcode=57462f29cfc176f86a37d80a2c02fc5b", + "stream_format": "AUDIO_MP3", + "offset_ms": 0, + "token": "156", + "progress_report_interval_ms": 1000 + } + } + } +} +``` +下一次预取依然返回相同的Play指令,依此类推,这样就实现了单曲循环的功能。 + +## Changelog +* 2017-4-10 修改有屏设备接入的说明;增加FAQ。
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/directives/Extension.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,45 @@ +# Extension + +## Table of Contents + + +## Extension.Settings.Set指令 + + +### 打开/关闭蓝牙 + +用户对音箱说“打开/关闭蓝牙”,会返回如下指令,true表示打开,false表示关闭。 + +```json +{ + "header": { + "namespace": "Extension.Settings", + "name": "Set", + "message_id": "message_id-1344" + }, + "payload": { + "bluetooth": true + } +} +``` + + +### 关闭麦克风 + +用户对音箱说“关闭麦克风”,会返回如下指令,false表示关闭。 + +说明:对于麦克风的控制,只支持关闭指令,打开操作需要通过其他方式(如:物理按键)实现。 + +```json +{ + "header": { + "namespace": "Extension.Settings", + "name": "Set", + "message_id": "message_id-1344" + }, + "payload": { + "microphone": false + } +} +``` +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/directives/ImageRecognizer.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,62 @@ +# ImageRecognizer + + +## Table of Contents + + + * [ImageRecognizer](#imagerecognizer) + * [Table of Contents](#table-of-contents) + * [总体逻辑](#总体逻辑) + * [ImageRecognizer.StartRecognize指令](#imagerecognizerstartrecognize指令) + * [ImageRecognizer.Recognize 事件](#imagerecognizerrecognize-事件) + + +## 总体逻辑 + + 1. 用户发query:帮我看看这是什么水果 + 2. 服务端返回ImageRecognizer.StartRecognize directive, 包含type参数:水果 + 3. 客户端拍照(或者截图、让用户选图片)后返回ImageRecognizer.Recognize event, 包含type参数:水果,url参数:图片地址,message_id是步骤2中的message_id + 4. 中控把event发给负责图像识别的bot,返回结果(可能要根据da的需求,返回多轮标志) + +如果不是完全由语音发起的操作,客户端可以直接由步骤3开始,不传message_id,这种情况下后端需要有明确的图片处理bot + +## ImageRecognizer.StartRecognize指令 + +在[响应](../api/response.md)中的directives字段中的一项 + +```javascript +{ + "header": { + "namespace": "ImageRecognizer", + "name": "StartRecognize", + "message_id": "message_id-1344" + }, + "payload": { + "type":"水果" + } +} +``` + + + +## ImageRecognizer.Recognize 事件 +识别图片的请求 + +在[请求](../api/request.md)中的device_event字段 + +```javascript +{ + "device_event":{ + "header": { + "namespace": "ImageRecognizer", + "name": "Recognize", + "message_id": "message_id-1344" + }, + "payload": { + "type":"水果", //可选 + "url":"http://f10.baidu.com/it/u=2640880481,1295783988&fm=72" + } + } +} +``` +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/directives/SmartHomeControl.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,39 @@ +# SmartHomeControl + +## Table of Contents + + + * [SmartHomeControl](#smarthomecontrol) + * [Table of Contents](#table-of-contents) + * [总体逻辑](#总体逻辑) + * [上报SmartHomeControl状态](#上报smarthomecontrol状态) + + +## 总体逻辑 + +这个协议用于用一个可以语音交互的设备,去控制可联网的其它设备 + +客户端在请求中上报当前可以被控制的设备列表,da如果识别出语音请求是在操作设备列表中的某个设备(比如用户说:“打开客厅的电视”,设备列表中存在一项“客厅的电视”),就会返回设备控制的intent,并在槽位中加上target_device字段 + + +## 上报SmartHomeControl状态 + +在[请求](../api/request.md)中的device_status字段 + +```javascript +"device_status":{ + "SmartHomeControl":{ + "target_devices":[ + {"name":"客厅的电视","id":"xxxxxx","type":"duer_iot"},//type、id可选 + {"name":"厨房的音箱","id":"yyy"} + ], + }, +}, +``` + +target_devices是设备列表,一个设备的描述包含如下字段 + * name 必选,设备名字,会用这个值做query的匹配 + * id 可选,代表设备id + * type 可选,设备类型,代表 + +被用户query选中要操作的设备,以上设备描述字段会完整的发给bot(会放在da解析的槽位中),由bot完成最终的控制操作(比如调用设备云接口),并且由bot返回给用户的反馈(指在主控设备上的反馈)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/directives/Speaker.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,105 @@ +# Speaker + +## Table of Contents + + + * [Speaker](#speaker) + * [Table of Contents](#table-of-contents) + * [SetVolume指令](#setvolume指令) + * [AdjustVolume指令](#adjustvolume指令) + * [SetMute 指令](#setmute-指令) + * [MuteChanged 事件](#mutechanged-事件) + * [VolumeChanged事件](#volumechanged事件) + * [Speaker状态上报](#speaker状态上报) + + +## SetVolume指令 +音量绝对控制指令, volumn取值为[0,100] +```json +{ + "header": { + "namespace": "Speaker", + "name": "SetVolume", + "message_id": "message_id-1344" + }, + "payload": { + "volume": 10 + } +} +``` + +## AdjustVolume指令 +音量相对控制指令,volume的取值范围为[-100,100],正数表示增大音量,负数表示减小音量。 +```json +{ + "header": { + "namespace": "Speaker", + "name": "AdjustVolume", + "message_id": "message_id-1344" + }, + "payload": { + "volume": -10 + } +} +``` + +## SetMute 指令 +设置静音状态打开/关闭。mute取值:true静音;false取消静音。 +```json +{ + "header": { + "namespace": "Speaker", + "name": "SetMute", + "message_id": "message_id-1344" + }, + "payload": { + "mute": true + } +} +``` + + +## MuteChanged 事件 +静音状态改变的事件上报 +```json +"device_event": { + "header": { + "namespace": "Speaker", + "name": "MuteChanged", + "message_id": "message_id-1344" + }, + "payload": { + "muted": true, + "volume": 10 + } +} +``` + + +## VolumeChanged事件 +```json +"device_event": { + "header": { + "namespace": "Speaker", + "name": "VolumeChanged", + "message_id": "message_id-1344" + }, + "payload": { + "volume": 10 + } +} +``` + + +## Speaker状态上报 +正常请求中也需要上报Speaker当前的状态 +```json +"device_status":{ + "Speaker":{ + "volume": 50, + "muted": false + } +} +``` + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/directives/SpeechRecognizer.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,39 @@ +# SpeechRecognizer 语音识别 + +## Table of Contents + + + * [SpeechRecognizer 语音识别](#speechrecognizer-语音识别) + * [Table of Contents](#table-of-contents) + * [ExpectSpeech指令](#expectspeech指令) + * [ExpectSpeechTimedOut事件](#expectspeechtimedout事件) + + +## ExpectSpeech指令 +需要客户端开始语音识别的时候,返回这个指令。 +其实是一个多轮的标识,标识播报结果完成后,需要用户马上说话,而不是进入等待唤醒的状态 +```json +{ + "header": { + "namespace": "SpeechRecognizer", + "name": "ExpectSpeech", + }, + "payload": { + } +} +``` + + +## ExpectSpeechTimedOut事件 + +客户端开始语音识别后,一段时间(默认8s)没有收到用户的语音,超时的事件 +```json +{ + "header": { + "namespace": "SpeechRecognizer", + "name": "ExpectSpeechTimedOut", + }, + "payload": { + } +} +```
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/directives/SpeechSynthesizer.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,120 @@ +# SpeechSynthesizer 语音合成 + +## Table of Contents + + + * [SpeechSynthesizer 语音合成](#speechsynthesizer-语音合成) + * [Table of Contents](#table-of-contents) + * [Speak指令](#speak指令) + * [Stop指令](#stop指令) + * [SpeechStarted事件](#speechstarted事件) + * [SpeechFinished事件](#speechfinished事件) + * [SpeechStopped事件](#speechstopped事件) + * [SpeechSynthesizer状态上报](#speechsynthesizer状态上报) + + +## Speak指令 +需要扬声器语音播报的时候,返回这个指令。客户端收到这个指令后,需要把内容tts播报出来。听新闻返回的就是一个Speak指令。 +```json +{ + "header": { + "namespace": "SpeechSynthesizer", + "name": "Speak", + "message_id": "message_id-1344" + }, + "payload": { + "channel":"Content", //可选,标志内容的优先级,默认为Dialog + "token": "156", + "type": "{{Text/SSML}}", + "content": ["xxxx1", "xxxx2"], + "speak_behavior": "REPLACE_ALL", + "should_get_next_speech": true + } +} +``` +参数 | 描述 | 类型 | 必须 +--- | --- | --- | --- +token | tts的token | string | 是 +type | TTS类型,type字段的两种取值:Text和SSML| string | 是 +content | 播报内容,content字段固定为数组,即使只有一条内容,也使用数组。| array | 是 +speak_behavior | 播报模式 REPLACE_ALL: 清空列表,立即播报;ENQUEUE: 把指令关联的tts添加到列表末尾,下一条预取的时候使用它 | string | 是 +channel | 播报内容的分类和优先级,取值:Dialog/Content/Alerts,请参考[directives的交互设计参考](../api/directives_design.md) | string | 否,默认为Dialog + +## Stop指令 +```json +{ + "header": { + "namespace": "SpeechSynthesizer", + "name": "Stop", + "message_id": "message_id-1344" + }, + "payload": { + } +} +``` + +## SpeechStarted事件 +收到Speak指令后,开始播报之前,上报此事件。 +```json +{ + "device_event": { + "header": { + "namespace": "SpeechSynthesizer", + "name": "SpeechStarted", + "message_id": "message_id-1344" + }, + "payload": { + "token": "156", + } + } +} +``` + +## SpeechFinished事件 +播报完毕后,上报此事件。 +```json +{ + "device_event": { + "header": { + "namespace": "SpeechSynthesizer", + "name": "SpeechFinished", + "message_id": "message_id-1344" + }, + "payload": { + "token": "156" + } + } +} +``` + +## SpeechStopped事件 +用户说"暂停播放"、 "停止播放"后,会收到Stop指令,客户端执行完Stop指令后,即暂停播放后,需要上报此事件,云端会保存断点,供下一次继续播放使用。 +```json +{ + "device_event": { + "header": { + "namespace": "SpeechSynthesizer", + "name": "SpeechStopped", + "message_id": "message_id-1344" + }, + "payload": { + "token": "156", + "offset_ms": 10000 + } + } +} +``` + +## SpeechSynthesizer状态上报 + +正常请求中也需要上报SpeechSynthesizer当前的状态 + +```json +"device_status":{ + "SpeechSynthesizer":{ + "token":"xxx",//正在播放的音频流id + "offset_ms":20000,//播放到多少ms了 + "player_activity":"PLAYING / FINISHED" + } +} +```
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/directives/UiControl.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,107 @@ +# UiControl + +## Table of Contents + + + * [UiControl](#uicontrol) + * [Table of Contents](#table-of-contents) + * [总体逻辑](#总体逻辑) + * [上报UiControl状态](#上报uicontrol状态) + * [返回值](#返回值) + * [UiControl.Click指令](#uicontrolclick指令) + * [UiControl.Clicked 事件](#uicontrolclicked-事件) + + +## 总体逻辑 + +客户端在每个请求中上报当前界面的上下文,包括***可能需要语音控制的所有元素***,服务端如果识别出语音请求和里面的某一项匹配,就返回Click指令,包含对应项目的url字段 + + +## 上报UiControl状态 + +在[请求](../api/request.md)中的device_status字段 + +```javascript +"device_status":{ + "UiControl":{ + "items":[ + {"label":"下一个","scene":"control","url":"xxapp://next","x":1,"y":2,"index":2,"domain":"{nlu.domain}","intent":"{nlu.intent}","slots":{}}, + {"label":"暂停","scene":"control","url":"xxapp://pause","x":1,"y":3,"index":3}, + {"label":"停止","scene":"control","url":"xxapp://stop","x":1,"y":4,"index":4}, + {"label":"打电话给张岩","scene":"control","url":"xxapp://next","x":1,"y":2,,"domain":"phone","intent":"telephone","slots":{"name":"张岩"}}, + {"label":"跑男2017-05-10,黄磊","scene":"content","url":"xxapp://play?id=12345","x":1,"y":1}, + ], + }, +}, +``` + +这里上报了一个**可控制的元素** 的列表,说明如下 + + * label: string, 必选,按钮上的内容 + * url: string, 必选,按钮的url,代表一种客户端行为,可以是客户端自定义的schema,在Click指令中会回传给客户端 + * scene: string, 可选,代表按钮的场景。不同的场景,query理解、匹配的方式会不一样,现在的取值有 + * content: 内容按钮 + * control: 控制按钮 + * x: int, 可选,左上角开始的x坐标,用于匹配query “播放第一行第二个” + * y: int, 可选,左上角开始的y坐标 + * index: int, 可选,用于匹配query“播放第{index}个” + * domain: "{nlu.domain}", 可选, nlu的domain,可选的值可以参考[NLU的example](../nlu/example.md) + * intent: "{nlu.intent}" 可选,nlu的intent,可选的值可以参考[NLU的example](../nlu/example.md) + * slots: object{} 可选,nlu的槽位参数,可选的值参考[NLU的example](../nlu/example.md) + + +### 返回值 + +在用户的query匹配了某个 **可控制元素** 的情况下, 可能有以下2种返回值 + + * 如果用户没有上传intent和slots, 返回下面的 **UiControl.Click** 指令 + * 如果用户上传了intent和slots, 将把这个请求转发给相应的bot处理 + + +## UiControl.Click指令 + +在[响应](../api/response.md)中的directives字段中的一项 + +```javascript +{ + "header": { + "namespace": "UiControl", + "name": "Click", + "message_id": "message_id-1344" + }, + "payload": { + "url":"xxapp://next", + "label":"下一个", + "scene":"control", + "x":1, + "y":1 + } +} +``` + +## UiControl.Clicked 事件 + +用户执行Click指令之后,需要上传Clicked Event + +在[请求](../api/request.md)中的device_event字段 + +```javascript +{ + "device_event":{ + "header": { + "namespace": "UiControl", + "name": "Clicked", + "message_id": "message_id-1344" //中控根据message_id,将该事件请求发给对应的bot;当端上没有当前message_id时,该值为空 + }, + "payload": { + "url":"http://unicast.bot.dueros.ai/tracklist?album_id=123&track_id=456&action=play" //1.规定domain为bot_name的倒写,当message_id为空时,中控根据domain来识别应该接收该请求的bot; + //2.对应的bot根据url路径及参数来处理相关业务;3.url必须encode + } + } +} +``` +### 对于一个链接的访问,前端是否需要通过event事件来访问? +#### 重要:不是所有页面的请求都需要过dueros中控,因此不是所有页面上的点击行为,都需要端发起click事件! +#### 规定: + * 1.影响整个dueros对话流的行为(如页面上点击播放一首歌,改变了dueros里记录的当前播放数据,也可能改变了记录的播放列表),请求需要过dueros中控; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/directives/VideoPlayer.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,112 @@ +# VideoPlayer(非稳定版) + +## Table of Contents + +## VideoPlayer.Play指令 +用户对音箱说“播放周杰伦的歌曲”、“播放郭德纲的相声”、"继续播放"、“下一首”、“上一首”、“下一个专辑”、“上一个专辑”都返回一个Play指令。 +```json +{ + "header": { + "namespace": "VideoPlayer", + "name": "Play", + }, + "payload": { + "tips": "为您播放如下电视剧", + "resource": { + "resource_id": "102_50451", + "resource_name": "欢乐颂", + "director": "孔笙", + "type": "都市,言情", + "category": "电视剧", + "actors": "刘涛,蒋欣,王子文,杨紫", + "era": "2016", + "season": "1", + "poster_url": "http://10.0.11.10/poster/15860.jpg", + "episode" : 14, + "item_id": "102_50452", + "token": "xxxx" + "description": "心怀梦想的大龄胡同公主樊胜美能", + } + } +} +``` +参数 | 描述 | 类型 | 必须 +---- | --- | --- | --- +tips | 提示用户的信息, 可进行播放时的tips显示| string | 是 +resource | 视频对象,包括元数据和播放token | object | 是 +resource.resource_id | 视频唯一ID | string | 是 +resource.resource_name | 视频名称 | string | 是 +resource.director | 该视频导演 | string | 是 +resource.type | 视频二级分类(科幻/魔幻/言情/动作/武侠等) | string | 是 +resource.category | 视频类型(电影/电视剧/综艺/动漫/纪录片) | string | 是 +resource.era | 出品年代 | int | 否 +resource.season |第几季或者第几部 | string | 否 +resource.poster_url | 海报url地址 | string | 是 +resource.episode | 第几集 | int | 否 +resource.item_id | 电视剧某一集对应的id(不同合作方会不一样) | string | 否 +resource.token | 该视频对应的播放token(不同合作方不同) | string | 是 +resource.description | 该视频的剧情简介信息 | string | 否 + + + +## PlaybackStarted事件 +客户端开始播放的时候,需要上报此事件。 +```json +"device_event":{ + "header": { + "namespace": "VideoPlayer", + "name": "PlaybackStarted", + "message_id": "message_id-1xxxx" + }, + "payload": { + "token": "156",//客户的资源播放标识 + "resource_id": "98fd71c1523", //云端返回的视频资源唯一id + "resource_name": "魔戒1",//资源的名称 + "category": "电影",// 资源的分类 + "episode" : 15,//如果是电视剧的话, 需要填写具体的集数 + "type": "[\"动作\", \"奇幻\", \"剧情\", \"冒险\"]",//资源所属的类型 + } + } +``` +## PlaybackStopped事件 +用户说"停止播放"并执行了停止动作、或者退出了播放界面时 需要发送此事件. +```json +"device_event":{ + "header": { + "namespace": "VideoPlayer", + "name": "PlaybackFinished", + "message_id": "message_id-1xxxx" + }, + "payload": { + "token": "156", + "resource_id": "98fd71c1523", + "name": "魔戒1", + "category": "电影", + "episode" : 15, + "type": "[\"动作\", \"奇幻\", \"剧情\", \"冒险\"]", + } + } +} +``` + +## 上报VideoPlayer状态(在请求中) +当用户正在播放电视魔戒时,询问: "该电影的导演是谁?", 需要在请求中带上这些信息,协助后端进行正确的解析. +```javascript +"device_status":{ + "VideoPlayer":{ + "token": "156",//客户的资源播放标识 + "resource_id": "98fd71c1523", //云端返回的视频资源唯一id + "resource_name": "魔戒1",//资源的名称 + "category": "电影",// 资源的分类 + "episode" : 15,//如果是电视剧的话, 需要填写具体的集数 + "type": "[\"动作\", \"奇幻\", \"剧情\", \"冒险\"]",//资源所属的类型 + }, +}, +``` + + +## FAQ + + +## Changelog +* 2017-6-3 初稿。
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/directives/Wakeup.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,33 @@ +# Speaker + +## Table of Contents + + +## addWakeWord指令 +让客户端增加一个唤醒词(需要客户端的唤醒模块本身支持) +```json +{ + "header": { + "namespace": "Wakeup", + "name": "addWakeWord", + "message_id": "message_id-1344" + }, + "payload": { + "word": '小度你好' //将要加入到客户端的唤醒词,会替换掉客户端最老的一个 + } +} +``` + + +## Wakeup状态上报 +正常请求中也需要上报Wakeup模块的状态 +```json +"device_status":{ + "Wakeup":{ + "words":["小度你好"],//当前客户端设置的唤醒词,不包含内置的“小度小度”,按加入时间从新->老排序 + "maxWords":1 //最多可以设置几个唤醒词 + } +} +``` + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/gh-md-toc Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,183 @@ +#!/usr/bin/env bash + +# +# Steps: +# +# 1. Download corresponding html file for some README.md: +# curl -s $1 +# +# 2. Discard rows where no substring 'user-content-' (github's markup): +# awk '/user-content-/ { ... +# +# 3.1 Get last number in each row like ' ... </span></a>sitemap.js</h1'. +# It's a level of the current header: +# substr($0, length($0), 1) +# +# 3.2 Get level from 3.1 and insert corresponding number of spaces before '*': +# sprintf("%*s", substr($0, length($0), 1)*2, " ") +# +# 4. Find head's text and insert it inside "* [ ... ]": +# substr($0, match($0, /a>.*<\/h/)+2, RLENGTH-5) +# +# 5. Find anchor and insert it inside "(...)": +# substr($0, match($0, "href=\"[^\"]+?\" ")+6, RLENGTH-8) +# + +gh_toc_version="0.4.7" + +gh_user_agent="gh-md-toc v$gh_toc_version" + +# +# Download rendered into html README.md by its url. +# +# +gh_toc_load() { + local gh_url=$1 + + if type curl &>/dev/null; then + curl --user-agent "$gh_user_agent" -s "$gh_url" + elif type wget &>/dev/null; then + wget --user-agent="$gh_user_agent" -qO- "$gh_url" + else + echo "Please, install 'curl' or 'wget' and try again." + exit 1 + fi +} + +# +# Converts local md file into html by GitHub +# +# ➥ curl -X POST --data '{"text": "Hello world github/linguist#1 **cool**, and #1!"}' https://api.github.com/markdown +# <p>Hello world github/linguist#1 <strong>cool</strong>, and #1!</p>'" +gh_toc_md2html() { + local gh_file_md=$1 + curl -s --user-agent "$gh_user_agent" \ + --data-binary @"$gh_file_md" -H "Content-Type:text/plain" \ + https://api.github.com/markdown/raw +} + +# +# Is passed string url +# +gh_is_url() { + if [[ $1 == https* || $1 == http* ]]; then + echo "yes" + else + echo "no" + fi +} + +# +# TOC generator +# +gh_toc(){ + local gh_src=$1 + local gh_src_copy=$1 + local gh_ttl_docs=$2 + + if [ "$gh_src" = "" ]; then + echo "Please, enter URL or local path for a README.md" + exit 1 + fi + + + # Show "TOC" string only if working with one document + if [ "$gh_ttl_docs" = "1" ]; then + + echo "Table of Contents" + echo "=================" + echo "" + gh_src_copy="" + + fi + + if [ "$(gh_is_url "$gh_src")" == "yes" ]; then + gh_toc_load "$gh_src" | gh_toc_grab "$gh_src_copy" + else + gh_toc_md2html "$gh_src" | gh_toc_grab "$gh_src_copy" + fi +} + +# +# Grabber of the TOC from rendered html +# +# $1 — a source url of document. +# It's need if TOC is generated for multiple documents. +# +gh_toc_grab() { + # if closed <h[1-6]> is on the new line, then move it on the prev line + # for example: + # was: The command <code>foo1</code> + # </h1> + # became: The command <code>foo1</code></h1> + sed -e ':a' -e 'N' -e '$!ba' -e 's/\n<\/h/<\/h/g' | + # find strings that corresponds to template + grep -E -o '<a\s*id="user-content-[^"]*".*</h[1-6]' | + # remove code tags + sed 's/<code>//' | sed 's/<\/code>//' | + # now all rows are like: + # <a id="user-content-..." href="..."><span ...></span></a> ... </h1 + # format result line + # * $0 — whole string + echo -e "$(awk -v "gh_url=$1" '{ + print sprintf("%*s", substr($0, length($0), 1)*3, " ") "* [" substr($0, match($0, /a>.*<\/h/)+2, RLENGTH-5)"](" gh_url substr($0, match($0, "href=\"[^\"]+?\" ")+6, RLENGTH-8) ")"}' | sed 'y/+/ /; s/%/\\x/g')" +} + +# +# Returns filename only from full path or url +# +gh_toc_get_filename() { + echo "${1##*/}" +} + +# +# Options hendlers +# +gh_toc_app() { + local app_name="gh-md-toc" + + if [ "$1" = '--help' ] || [ $# -eq 0 ] ; then + echo "GitHub TOC generator ($app_name): $gh_toc_version" + echo "" + echo "Usage:" + echo " $app_name src [src] Create TOC for a README file (url or local path)" + echo " $app_name - Create TOC for markdown from STDIN" + echo " $app_name --help Show help" + echo " $app_name --version Show version" + return + fi + + if [ "$1" = '--version' ]; then + echo "$gh_toc_version" + return + fi + + if [ "$1" = "-" ]; then + if [ -z "$TMPDIR" ]; then + TMPDIR="/tmp" + elif [ -n "$TMPDIR" -a ! -d "$TMPDIR" ]; then + mkdir -p "$TMPDIR" + fi + local gh_tmp_md + gh_tmp_md=$(mktemp $TMPDIR/tmp.XXXXXX) + while read input; do + echo "$input" >> "$gh_tmp_md" + done + gh_toc_md2html "$gh_tmp_md" | gh_toc_grab "" + return + fi + + for md in "$@" + do + echo "" + gh_toc "$md" "$#" + done + + echo "" + echo "Created by [gh-md-toc](https://github.com/ekalinin/github-markdown-toc)" +} + +# +# Entry point +# +gh_toc_app "$@"
Binary file dumi_doc-master/doc/img/confirm.png has changed
Binary file dumi_doc-master/doc/img/demo1.png has changed
Binary file dumi_doc-master/doc/img/demo2.png has changed
Binary file dumi_doc-master/doc/img/demo3.png has changed
Binary file dumi_doc-master/doc/img/demo4.png has changed
Binary file dumi_doc-master/doc/img/demo5.png has changed
Binary file dumi_doc-master/doc/img/lifecommon_lbs_nav.jpg has changed
Binary file dumi_doc-master/doc/img/lifecommon_lbs_nearby.jpg has changed
Binary file dumi_doc-master/doc/img/lifecommon_lbs_poi.jpg has changed
Binary file dumi_doc-master/doc/img/remind_create.png has changed
Binary file dumi_doc-master/doc/img/remind_manage.png has changed
Binary file dumi_doc-master/doc/img/system.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/mateapp.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,54 @@ +# mate app 实现指南 + +## Table of Contents + + + * [mate app 实现指南](#mate-app-实现指南) + * [Table of Contents](#table-of-contents) + * [登录](#登录) + * [command](#command) + * [请求示例](#请求示例) + * [支持的command](#支持的command) + + +## 登录 +请参考[度秘无屏设备登录流程](http://agroup.baidu.com/duer/md/article/241282) + +## command +command是mate app发送给度秘的一种请求,用于控制设备 +所有的command请求,都发给 **https://xiaodu.baidu.com/saiya/command**,需要**带百度的登录态**,method为post,body是json,格式参考下面的示例 + +### 请求示例 + +```javascript +{ + //==========以下是开放sdk会有的字段======================== + "appid": "650DEBC2B99A4dA4", + "appkey": "2F4B662AF2064323A16122D702160F15", + "appname": "com.baidu.duersdk.xiaomi", + //string mate app手机的硬件id + "CUID": "string", + //被操作的设备的cuid + "device_id":"12783681267812d", + "command": {"type":"PlayCommand"} //参考下面的command列表 +} +``` + +### 支持的command + + * 播放指令: {"type":"PlayCommand"} + * 如果设备在暂停状态,设备实际执行恢复播放,并且上报PlaybackStarted事件 + * 暂停指令: {"type":"PauseCommand"} + * 如果设备在播放状态,设备实际执行暂停,并且上报PlaybackStopped事件 + * 下一首:{"type":"NextCommand"} + * 上报PlaybackNearlyFinished事件(以前的GetNextPlayback事件),理论上会收到播放下一首歌的指令,执行之,并且播放下一首歌 + * 上一首 : {"type":"PreviousCommand"} + * 播放上一首歌,上报PlaybackStarted事件 + * 音量调节:{"type":"VolumeLevelCommand","volumeLevel":40} + * 设备调整音量,并且上报Speaker.VolumeChanged事件 + * 快进后者后退(拖动进度条) {"type":"SeekCommand", "mediaPosition":161} + * 播放器快进快退,并且上报PlaybackStarted事件 + <!-- + * 重复指令: {"type":"RepeatCommand", "repeat":true/false} false为取消 + * 随机播放命令:{"type":"ShuffleCommand", "shuffle":true/false} false为取消 + -->
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/menu.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,14 @@ +### 目录 +<!--目录--> + * [接入指导](tutorial.md) + * [Sdk相关](sdk/index.md) + * Api 参考 + * [概览](api/overview.md) + * [请求字段解释](api/request.md) + * [响应字段解释](api/response.md) + * 端能力 + * [AudioPlayer](directives/AudioPlayer.md) + * [Speaker](directives/Speaker.md) + * [SpeechSynthesizer](directives/SpeechSynthesizer.md) + * [Skill介绍](Skills.md) +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/nlu-resource-collaboration-notes.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,142 @@ +# nlu+resource合作方式资源播放状态上报接口 + +## 背景 + +资源方对回传他们资源的播放状态要求很强硬,(包括用户ID(加密后)、声音音频ID、声音播放时长等等)——若违反则资源方将停止与百度的合作协议。 + +所以:`基于nlu+resource的合作方式,合作方也需要上报资源播放状态。` + +ps:上报的端上的播放状态也为多轮解析提供了支撑。 + +声明:`合作方若没有按照规范上报客户端的播放状态,则需要自行承担相关资源方停止合作的风险` + +## 上报接口 + +<table> +<tr> +<td>URL</td> +<td>https://xiaodu.baidu.com/saiya/mediastat</td> + +</tr> +<tr> +<td>Method</td> +<td>POST</td> + +</tr> +</table> + +## 接口参数 + +### 参数说明 +<table> + <tr> + <td>key</td> + <td>内容</td> + <td>类型</td> + <td>是否可能为空</td> + <td>示例</td> + <td>备注</td> + </tr> + <tr> + <td>bot_id</td> + <td>垂类bot标识</td> + <td>string</td> + <td>否</td> + <td>audio_news</td> + <td></td> + </tr> + <tr> + <td>url</td> + <td>播放的资源地址</td> + <td>string</td> + <td>否</td> + <td style="word-break:break-all">http://fdfs.***.com/group3/M01/77/42/wKgDsVKMdDLCVKUUAIMXy99Q7Vo340.mp3</td> + <td>播放资源地址</td> + </tr> + <tr> + <td>appid</td> + <td>合作方标识</td> + <td>string</td> + <td>否</td> + <td>dm4B485F6F3BE40F**</td> + <td></td> + </tr> + <tr> + <td>appkey</td> + <td>合作方标识</td> + <td>string</td> + <td>否</td> + <td>92D6A5FD2E69A84847147E69FA70B1**</td> + <td></td> + </tr> + <tr> + <td>cuid</td> + <td>用户标识</td> + <td>string</td> + <td>否</td> + <td>2D6A5FD2E69A84847147E6</td> + <td></td> + </tr> + <tr> + <td>token</td> + <td>资源id</td> + <td>string</td> + <td>否</td> + <td>188376</td> + <td></td> + </tr> + <tr> + <td>offset_ms</td> + <td>播放时长</td> + <td>int</td> + <td>是</td> + <td>20000</td> + <td>单位ms</td> + <tr> + <td>action</td> + <td>用户动作</td> + <td>enum</td> + <td>是</td> + <td>PLAYING</td> + <td>PLAYING</td> + </tr> + <tr> + <td></td> + <td></td> + <td></td> + <td></td> + <td></td> + <td>STOPPED</td> + </tr> + <tr> + <td></td> + <td></td> + <td></td> + <td></td> + <td></td> + <td>PAUSED</td> + </tr> + <tr> + <td></td> + <td></td> + <td></td> + <td></td> + <td></td> + <td>FINISHED</td> + </tr> +</table> + +### post body 示例 +``` +curl -X POST -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d '{ + "bot_id": "audio_news", + "url": "http://fdfs.***.com/group3/M01/77/42/wKgDsVKMdDLCVKUUAIMXy99Q7Vo340.mp3", + "appid": "dm4B485F6F3BE40F", + "appkey": "92D6A5FD2E69A84847147E69FA70B1", + "cuid": "2D6A5FD2E69A84847147E6", + "token": "188376", + "offset_ms": 2000000000, + "action": "PLAYING" +}' "https://xiaodu.baidu.com/saiya/mediastat" ` + +```
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/nlu/example.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,29 @@ +```javascript +["放一首周杰伦的歌",{ "domain": "audio.music", "intent": "audio.music.play", "slots": { "singer": "周杰伦", "unit": "歌曲", "hmm_singer": "周杰伦" } }] +["下一首",{ "domain": "audio.music", "intent": "audio.music.next", "slots": { "next": "下一首" } }] +["上海市天气",{"domain":"duer_weather","intent":"sys_weather","slots":{"loc_city":"上海市","loc_province":"上海市","time":"2017-01-03,2017-01-03"}}] +["附近值得去吃的美食",{"domain":"restaurant_bot","intent":"find","slots":{"catetag":"值得去吃","fragment":"值得去吃","location":"附近","sortby":"default"}}] +["附近有哪些餐馆",{"domain":"restaurant_bot","intent":"find","slots":{"location":"附近","sortby":"default"}}] +["10月21号早上九点提醒我开会",{"domain":"remind","intent":"remind","slots":{"event_title":"开会","intent":"设置","remind_time":"{\"month\":\"10\",\"day\":\"21\",\"hour\":\"9\",\"apm\":\"am\"}","__intent__":"setup","__id__":"1483430617165_fu6tll","remind_type_message":"否","remind_type_phone":"否","remind_type_dumi":"否","remind_type_clock":"否","remind_time_type":"abstime","remind_time_data":"1508547600","status":"create_confirm"}}] +["10月22号晚上11点提醒我爱康",{"domain":"remind","intent":"remind","slots":{"remind_type_message":"否","remind_type_phone":"否","remind_type_dumi":"否","remind_type_clock":"否","status":"cancel","da_system_not_understand":"2"}}] +["10月4号中午十三点提醒我要回家",{"domain":"remind","intent":"remind","slots":{"remind_type_message":"否","remind_type_phone":"否","remind_type_dumi":"否","remind_type_clock":"否","status":"cancel","da_system_not_understand":"2"}}] +["下周一早上十一点提醒我联系王妙英",{"domain":"remind","intent":"remind","slots":{"event_title":"联系王妙英","intent":"设置","remind_time":"{\"month\":\"11\",\"day\":\"1\",\"hour\":\"11\",\"week\":\"1+1\",\"apm\":\"am\",\"repeat\":\"year\",\"special_calendar\":\"lunar\"}","__intent__":"setup","__id__":"1483430625801_fn21ww","remind_type_message":"否","remind_type_phone":"否","remind_type_dumi":"否","remind_type_clock":"否","status":"create_confirm","remind_time_type":"year","remind_time_value":"1101","remind_time_data":"1513566000"}}] +["我要打电话", { "domain": "phone", "intent": "telephone", "slots": {} }] +["13192285237",{"domain":"phone","intent":"telephone","slots":{"number":"13192285237"}}] +["打开微信",{ "domain": "phone", "intent": "open_website", "slots": { "action_type": "1", "name": "微信", "website_url": "http://wx.qq.com/" } }] +["声音大一点",{ "domain": "phone", "intent": "phone_settings", "slots": { "action_type": "2", "setting_name": "volume" } }] +["一张到太原的火车票",{"domain":"22","intent":"22","slots":{"end_point":"太原","start_time":"2017-01-03","sugs":"买火车票"}}] +["买一张火车票",{"domain":"22","intent":"22","slots":{"start_time":"2017-01-03","sugs":"买火车票"}}] +["上海到北京动车多少钱",{"domain":"22","intent":"22","slots":{"end_point":"北京","start_point":"上海","start_time":"2017-01-03","sugs":"买火车票"}}] +["从成都到重庆的火车票",{"domain":"22","intent":"22","slots":{"end_point":"重庆","start_point":"成都","start_time":"2017-01-03","sugs":"买火车票"}}] +["来一段郭德纲的相声",{ "domain": "audio.unicast", "intent": "audio.unicast.play", "slots": { "artist": "郭德纲", "first_category": "相声", "rule_score": "1" } }] +["我想唱东风破", { "domain":"MV", "intent":"MV_SEARCH", "slots":{ "song":"东风破", } }] +["周杰伦的七里香", { "domain":"MV", "intent":"MV_SEARCH", "slots":{ "song":"七里香", "singer":"周杰伦" } }] +["唱首欢快的歌曲", { "domain":"MV", "intent":"MV_SEARCH", "slots":{ "emotion":"欢快" } }] +["我想看欢乐颂", { "domain":"FILM", "intent":"FILM_SEARCH", "slots":{ "name":"欢乐颂", "category":"电视剧" } }] +["看美国队长", { "domain":"FILM", "intent":"FILM_SEARCH", "slots":{ "name":"美国队长", "category":"电影" } }] +["我想看陈坤演的爱情片", { "domain":"FILM", "intent":"FILM_SEARCH", "slots":{ "actor":"陈坤", "type":"爱情片" } }] +["声音大点", { "domain":"COMMAND", "intent":"volum.up", "slots":{ "value":1 } }] +["声音小点", { "domain":"COMMAND", "intent":"volum.down", "slots":{ "value":1 } }] +``` +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/sdk/index.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,53 @@ +# 安卓sdk + +## Table of Contents + + + * [安卓sdk](#安卓sdk) + * [Table of Contents](#table-of-contents) + * [客户端sdk](#客户端sdk) + * [下载](#下载) + * [介绍](#介绍) + * [常见问题](#常见问题) + + +## 客户端sdk + +### 下载 + +内有demo工程和可测试的apk,外网用户请下载连线上环境的版本 + * [sdk下载](https://github.com/dueros/dumi_doc/blob/master/doc/sdk/sdk_v2_online.zip) + +### 介绍 + +内部含有文件 + + * app-release.apk 这个是demo app,可以安装到手机,可以试用度秘的语音识别、TTS、query理解等功能 + * demo_src.zip 这个是demo app的源代码,是一个android studio工程,可以直接打开、编译。调用sdk的代码请参考此工程 + * duersdk_library.zip 这个是sdk库,可以导入到已有工程中使用 + +### 常见问题 + + * 如何更改appid、appkey + * 请看demo工程代码中的 app/src/main/java/com/baidu/duersdkdemo/DemoApplication.java + + * 设置语音的appid、ak、sk + * **语音的app id、app key、secret key和度秘的appid、appkey是两个东西** + * 请到http://yuyin.baidu.com 并且创建应用或者向度秘方直接申请。 + * 在自己工程的AndroidManifast.xml 中配置 com.baidu.speech.APP_ID,com.baidu.speech.API_KEY,com.baidu.speech.SECRET_KEY。 + * 调用示例 +```xml + <!-- 如果集成了ASR模块,需要如下设置 --> + <meta-data + android:name="com.baidu.speech.APP_ID" + android:value="您申请的asr APP_ID" /> + <meta-data + android:name="com.baidu.speech.API_KEY" + android:value="您申请的asr API_KEY" /> + <meta-data + android:name="com.baidu.speech.SECRET_KEY" + android:value="您申请的 SECRET_KEY " /> +``` + + +
Binary file dumi_doc-master/doc/sdk/sdk_v2_online.zip has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/sdk/sdkconfig.txt Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,13 @@ +{ + "appid": "dmB729C8CCA9A74C15", + "appkey": "1A3A7F412CE14B808117DFF019CEFAC4", + "openLog": "true", + "openWriteLog": "false", + "openWriteAllLog": "false", + "writeLogTag": [ + "DuerSDK-VoiceImpl2", + "DuerSDK-AppConfigTime" + ], + "appOffline": "true", + "appOfflineUrl": "http://xiaodu.baidu.com/saiya/ws2" +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/smart_home_skill_api_reference.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,2051 @@ +# Smart Home Skill API Reference + +<!-- MarkdownTOC --> + +- [简介](#%E7%AE%80%E4%BB%8B) +- [认证](#%E8%AE%A4%E8%AF%81) +- [Skill指令](#skill%E6%8C%87%E4%BB%A4) + - [Header](#header) + - [Payload](#payload) + - [发现设备\(Discovery Message\)](#%E5%8F%91%E7%8E%B0%E8%AE%BE%E5%A4%87discovery-message) + - [DiscoverAppliancesRequest](#discoverappliancesrequest) + - [DiscoverAppliancesResponse](#discoverappliancesresponse) + - [控制设备\(Control Message\)](#%E6%8E%A7%E5%88%B6%E8%AE%BE%E5%A4%87control-message) + - [打开关闭设备\(On/Off Messages\)](#%E6%89%93%E5%BC%80%E5%85%B3%E9%97%AD%E8%AE%BE%E5%A4%87onoff-messages) + - [可控灯光设备\(Tunable Lighting Control Messages\)](#%E5%8F%AF%E6%8E%A7%E7%81%AF%E5%85%89%E8%AE%BE%E5%A4%87tunable-lighting-control-messages) + - [可控温度设备\(Temperature Control Messages\)](#%E5%8F%AF%E6%8E%A7%E6%B8%A9%E5%BA%A6%E8%AE%BE%E5%A4%87temperature-control-messages) + - [可控风速设备\(Fan Speed Control Messages\)](#%E5%8F%AF%E6%8E%A7%E9%A3%8E%E9%80%9F%E8%AE%BE%E5%A4%87fan-speed-control-messages) + - [查询状态\(Query Message\)](#%E6%9F%A5%E8%AF%A2%E7%8A%B6%E6%80%81query-message) + - [查询空气质量](#%E6%9F%A5%E8%AF%A2%E7%A9%BA%E6%B0%94%E8%B4%A8%E9%87%8F) + - [错误消息\(Error Message\)](#%E9%94%99%E8%AF%AF%E6%B6%88%E6%81%AFerror-message) + - [用户故障\(User Faults\)](#%E7%94%A8%E6%88%B7%E6%95%85%E9%9A%9Cuser-faults) + - [Bot故障\(Bot Faults\)](#bot%E6%95%85%E9%9A%9Cbot-faults) + - [其他错误\(Other Faults\)](#%E5%85%B6%E4%BB%96%E9%94%99%E8%AF%AFother-faults) + +<!-- /MarkdownTOC --> + +## 简介 + +该协议实现度秘终端互联互通的目的,达到通过使用支持DuerOS能力的设备,控制灯泡等被控设备的效果。 + +## 认证 + +Smart Home Skill API 遵循 OAuth2.0 规范。 +从 DuerOS 发送到 厂商Bot 的每个请求都包含 OAuth 的 access token。 + +## Skill指令 + +所有的指令(Directives),不论是DuerOS发送给Bot还是Bot返回给DuerOS,都是同一个结构,包含以下两个顶层字段: +* Header +* Payload + +### Header + +Header包含 命名空间、指令名称、目标版本和唯一消息标识符。以下是典型的消息Header的JSON示例: +``` +{ + "header": { + "messageId": "6d6d6e14-8aee-473e-8c24-0d31ff9c17a2", + "name": "DiscoverAppliancesRequest", + "namespace": "DuerOS.ConnectedHome.Discovery", + "payloadVersion": "1" + } +} +``` + +Header必须包含以下属性: + +|Property | Description | +|---|---| +|messageId | 单个请求或响应的唯一标识符。 这用于跟踪目的,Bot应该记录此信息,尽管它不应用于支持业务逻辑。 来自Bot的每条消息都必须填充此字段。 任何字符串数字字符和短于128个字符的字符串都是有效的,但是推荐使用随机数生成的UUID版本4 UUID。 | +|name | 指令的名称,如 DiscoverAppliancesRequest 和 DiscoverAppliancesResponse | +|namespace | 指定消息payload的类别。 目前的类别有: DuerOS.ConnectedHome.Discovery、DuerOS.ConnectedHome.Control、DuerOS.ConnectedHome.Query | +|payloadVersion | 标识payload的版本号 | + +### Payload + +Payload的内容取决于在Header中的name值。 +以下部分描述不同类型的指令,及其预期的payload描述和示例。 + +|Task | Namespace | Message Names | +|---|---|---| +|Discover connected devices | DuerOS.ConnectedHome.Discovery | DiscoverAppliancesRequest、DiscoverAppliancesResponse| +|Control connected devices; turn things off and on and change settings | DuerOS.ConnectedHome.Control |TurnOnRequest、TimingTurnOnRequest、TurnOffRequest、IncrementBrightnessRequest、DecrementBrightnessRequest、IncrementTemperatureRequest、DecrementTemperatureRequest、SetTemperatureRequest、IncrementFanSpeedRequest、DecrementFanSpeedRequest、SetModeRequest、TimingSetModeRequest | +|Query connected devices for their current state | DuerOS.ConnectedHome.Query | GetAirPM25Request | + +### 发现设备(Discovery Message) + +该消息类型用于发现可用的设备,确定其使用场景和功能。 + +#### DiscoverAppliancesRequest + +**例子:** + +“小度小度,查找我的设备” + +**目的:** + +发现与最终用户的设备云帐户相关的设备和场景。DiscoverAppliancesRequest 从 DuerOS 发送到 Bot。如果没有设备可以发现,或者您的设备云是否遇到错误,则 Bot 应返回一个空的 DiscoverAppliancesResponse,而不是错误消息。 + +##### Header + +|Property | Value | +|---|---| +|name | DiscoverAppliancesRequest | +|namespace | DuerOS.ConnectedHome.Discovery | + +##### Payload + +|Property | Description | Required | +|---|---|---| +|accessToken | 与用户设备云帐号相关的access token | Yes | + +DiscoverAppliancesRequest例子: +``` +{ + "header": { + "messageId": "6d6d6e14-8aee-473e-8c24-0d31ff9c17a2", + "name": "DiscoverAppliancesRequest", + "namespace": "DuerOS.ConnectedHome.Discovery", + "payloadVersion": "1" + }, + "payload": { + "accessToken": "*OAuth Token here*" + } +} +``` + +#### DiscoverAppliancesResponse + +**目的:** + +返回与最终用户的设备云帐户相关的所有设备的能力。是Bot对 DiscoverAppliancesRequest 的预期响应。如果没有发现设备或者您的设备云遇到错误,请返回一个空的 discoveryAppliances 数组。 DiscoverAppliancesResponse 指令包含与您的能力和数据相关联的设备列表,如: +* 用户标识的名称和描述 +* 设备类型,如light 和 scene +* 每个设备或场景支持的操作 + +##### Header + +|Property | Value | +|---|---| +|name | DiscoverAppliancesResponse | +|namespace | DuerOS.ConnectedHome.Discovery | + +##### Payload + +|Property | Description | Required | +|---|---|---| +|discoveredAppliances | discoveredAppliance 对象的数组,该对象包含可发现设备或场景,与用户设备帐户相关联的。 如果没有与用户帐户关联的设备或场景,此属性应包含一个空数组。 如果发生错误,该属性可以为null。 阵列中允许的最大项目数量为300。discoveryAppliance对象的每个属性如下所示 | Yes | +|discoveredAppliance.applianceTypes | 包含字符串的数组,其中字符串,表示所连接设备的类别,如LIGHT;或者表示场景。有关支持的字符串的完整列表,请参阅设备类别。任何其他字符串将被拒绝。 | Yes | +|discoveredAppliance.applianceId | 设备标识符。标识符在用户拥有的所有设备上必须是唯一的。此外,标识符需要在同一设备的多个发现请求之间保持一致。标识符可以包含任何字母或数字和以下特殊字符:_ - =#; :? @&。标识符不能超过256个字符。| Yes | +|discoveredAppliance.manufacturerName | 设备制造商的名称。此值不能超过128个字符。| Yes | +|discoveredAppliance.modelName | 设备型号名称。此值不能超过128个字符。 | Yes | +|discoveredAppliance.version | 供应商提供的设备版本。此值不能超过128个字符。 | Yes | +|discoveredAppliance.friendlyName | 用户用来识别设备的名称。 此值不能超过128个字符,不应包含特殊字符或标点符号。| Yes | +|discoveredAppliance.friendlyDescription | 设备的可读描述。 此值不能超过128个字符。 描述应包含设备连接方式的描述。 例如,“通过Wink连接的WiFi温控器”。| Yes | +|discoveredAppliance.isReachable | true表示设备当前可达; 否则,false。| Yes | +|discoveredAppliance.actions | 设备可支持的action的数组。合法的action包括: <br>turnOn<br/> <br>timingTurnOn<br/> <br>turnOff<br/> <br>incrementBrightness<br/> <br>decrementBrightness<br/> <br>incrementTemperature<br/> <br>decrementTemperature<br/> <br>setTemperature<br/> <br>incrementFanSpeed<br/> <br>decrementFanSpeed<br/> <br>setMode<br/> <br>timingSetMode<br/> <br>getAirPM25<br/>| Yes | +|discoveredAppliance.additionalApplianceDetails | 提供给Bot使用的设备或场景相关的附加信息的键值对。该属性的内容不能超过5000字节。而且DuerOS也不了解或使用这些数据。 | Yes,但可以为空 | + +设备 和 场景 类型: + +|Value | Description | Notes | +|---|---|---| +|WASHING_MACHINE| 洗衣机等设备 || +|AIR_CONDITION| 空调等设备 || +|RANGE_HOOD | 抽油烟机等设备 | | +|LIGHT| 代表光源的设备 || +|CURTAIN | 窗帘等设备 | | +|ACTIVITY_TRIGGER| 描述设置为特定状态的设备的组合,状态必须以特定顺序变更。例如,“观看优酷视频”场景可能需要 (1)打开电视机; (2)打开HDMI1。| | +|SCENE_TRIGGER| 描述设置为特定状态的设备的组合,状态不必以特定顺序变更。 例如睡眠模式可能包括关闭灯光和拉上窗帘,但是顺序不重要。| | + +注:在 场景 类型的appliance下,需对 friendlyDescription 和 friendlyName 的命名有一定规范: + +* friendlyDescription 的值内容必须包含“场景”及场景提供的设备厂商。如 “来自*厂商*的场景”. 此值不能超过128个字符。 +* friendlyName 是用户用来与您的场景交互并且必须存在的名称。目的是让用户以自然而轻松的方式控制场景。friendlyName应遵循以下准则: + * 首选项,仅包括场景名称。这为用户控制场景提供了最简单和最自然的方式 + * 可选,包括房间名称,如果在不同的房间提供类似的场景 + * 可选,包括房间“场景” + * 可选,包括场景名称和房间名称之间的介词,如“在” + * 不能包含特殊字符活标点符号 + * 不能超过128个字符 + +DiscoverAppliancesResponse 例子: + +``` +{ + "header":{ + "messageId":"ff746d98-ab02-4c9e-9d0d-b44711658414", + "name":"DiscoverAppliancesResponse", + "namespace":"DuerOS.ConnectedHome.Discovery", + "payloadVersion": "1" + }, + "payload":{ + "discoveredAppliances":[ + { + "actions":[ + "turnOn", + "turnOff", + "incrementBrightness", + "decrementBrightness" + ], + "applianceTypes":[ + "LIGHT" + ], + "additionalApplianceDetails":{ + "extraDetail1":"optionalDetailForSkillAdapterToReferenceThisDevice", + "extraDetail2":"There can be multiple entries", + "extraDetail3":"but they should only be used for reference purposes.", + "extraDetail4":"This is not a suitable place to maintain current device state" + }, + "applianceId":"uniqueLightDeviceId", + "friendlyDescription":"展现给用户的详细介绍", + "friendlyName":"卧室", + "isReachable":true, + "manufacturerName":"设备制造商的名称", + "modelName":"fancyLight", + "version":"your software version number here." + }, + { + "actions":[ + "turnOn", + "turnOff" + ], + "applianceTypes":[ + "CURTAIN" + ], + "additionalApplianceDetails":{ + "extraDetail1":"optionalDetailForSkillAdapterToReferenceThisDevice", + "extraDetail2":"There can be multiple entries", + "extraDetail3":"but they should only be used for reference purposes.", + "extraDetail4":"This is not a suitable place to maintain current device state" + }, + "applianceId":"uniqueSwitchDeviceId", + "friendlyDescription":"展现给用户的详细介绍", + "friendlyName":"卧室的窗帘", + "isReachable":true, + "manufacturerName":"设备制造商的名称", + "modelName":"fancyCurtain", + "version":"your software version number here." + }, + { + "actions": [ + "turnOn", + "turnOff" + ], + "applianceTypes":[ + "SCENE_TRIGGER" + ], + "additionalApplianceDetails": { + "extraDetail1": "detail about the scene", + "extraDetail2": "another detail about scene", + "extraDetail3": "only be used for reference purposes." + }, + "applianceId": "uniqueDeviceId", + "friendlyDescription": "来自设备商的场景", + "friendlyName": "回家模式", + "isReachable": true, + "manufacturerName": "yourManufacturerName", + "modelName": "提供场景的设备型号", + "version": "your software version number here." + } + ] + } +} +``` + +### 控制设备(Control Message) + +#### 打开关闭设备(On/Off Messages) + +消息类型打开或关闭目标设备。这些消息通常由几种不同类型的设备使用。 +* TurnOnRequest +* TurnOnConfirmation +* TimingTurnOnRequest +* TimingTurnOnConfirmation +* TurnOffRequest +* TurnOffConfirmation + +##### TurnOnRequest + +**例子:** +“小度小度,打开 *设备名*” + +**目的:** +DuerOS发送给Bot的打开设备的请求 + +###### Header + +|Property|Value| +|---|---| +|name|TurnOnRequest| +|namespace|DuerOS.ConnectedHome.Control| + +###### Payload + +|Property|Description|Required| +|---|---|---| +| accessToken | 从设备云端取到的access token | Yes | +| appliance object | 表示具体操作指令 | Yes | +| appliance.applianceId | 设备标识符。标识符在用户拥有的所有设备上必须是唯一的。此外,标识符需要在同一设备的多个发现请求之间保持一致。标识符可以包含任何字母或数字和以下特殊字符:_ - =#; :? @&。标识符不能超过256个字符。 | Yes | +| appliance.additionalApplianceDetails | 提供给Bot使用的设备或场景相关的附加信息的键值对。该属性的内容不能超过5000字节。而且DuerOS也不了解或使用这些数据。 | Yes,但可以为空 | + +TurnOnRequest 例子: +``` +{ + "header": { + "messageId": "01ebf625-0b89-4c4d-b3aa-32340e894688", + "name": "TurnOnRequest", + "namespace": "DuerOS.ConnectedHome.Control", + "payloadVersion": "1" + }, + "payload": { + "accessToken": "[OAuth token here]", + "appliance": { + "additionalApplianceDetails": {}, + "applianceId": "[Device ID for Ceiling Fan]" + } + } +} +``` + +##### TurnOnConfirmation + +**度秘返回的结果例子:** +“*设备name*已打开” + +**目的:** +表示设备已经被成功打开。表示Bot返回给DuerOS的打开成功的结果 + +###### Header + +|Property|Value| +|---|---| +|name| TurnOnConfirmation | +|namespace|DuerOS.ConnectedHome.Control| + +###### Payload + +|Property|Description|Required| +|---|---|---| +| N/A | N/A | N/A | + +TurnOnConfirmation 例子: +``` +{ + "header": { + "messageId": "26fa11a8-accb-4f66-a272-8b1ff7abd722", + "name": "TurnOnConfirmation", + "namespace": "DuerOS.ConnectedHome.Control", + "payloadVersion": "1" + }, + "payload": {} +} +``` + +##### TimingTurnOnRequest + +**例子:** +“小度小度,定时1分钟后打开 *设备名*” + +**目的:** +DuerOS发送给Bot的打开设备的请求 + +###### Header + +|Property|Value| +|---|---| +|name|TimingTurnOnRequest| +|namespace|DuerOS.ConnectedHome.Control| + +###### Payload + +|Property|Description|Required| +|---|---|---| +| accessToken | 从设备云端取到的access token | Yes | +| appliance object | 表示具体操作指令 | Yes | +| appliance.applianceId | 设备标识符。标识符在用户拥有的所有设备上必须是唯一的。此外,标识符需要在同一设备的多个发现请求之间保持一致。标识符可以包含任何字母或数字和以下特殊字符:_ - =#; :? @&。标识符不能超过256个字符。 | Yes | +| appliance.additionalApplianceDetails | 提供给Bot使用的设备或场景相关的附加信息的键值对。该属性的内容不能超过5000字节。而且DuerOS也不了解或使用这些数据。 | Yes,但可以为空 | +| timestamp | 表示设备定时设置的量的对象。包含一个属性值,它指定一个数字,代表时间戳。 | No | + +TimingTurnOnRequest 例子: +``` +{ + "header": { + "messageId": "01ebf625-0b89-4c4d-b3aa-32340e894688", + "name": "TimingTurnOnRequest", + "namespace": "DuerOS.ConnectedHome.Control", + "payloadVersion": "1" + }, + "payload": { + "timestamp": { + "value": 1496741861 + }, + "accessToken": "[OAuth token here]", + "appliance": { + "additionalApplianceDetails": {}, + "applianceId": "[Device ID for Ceiling Fan]" + } + } +} +``` + +##### TimingTurnOnConfirmation + +**度秘返回的结果例子:** +“*设备name*已定时成功” + +**目的:** +表示设备已经被成功定时。表示Bot返回给DuerOS的打开成功的结果 + +###### Header + +|Property|Value| +|---|---| +|name| TimingTurnOnConfirmation | +|namespace|DuerOS.ConnectedHome.Control| + +###### Payload + +|Property|Description|Required| +|---|---|---| +| N/A | N/A | N/A | + +TimingTurnOnConfirmation 例子: +``` +{ + "header": { + "messageId": "26fa11a8-accb-4f66-a272-8b1ff7abd722", + "name": "TimingTurnOnConfirmation", + "namespace": "DuerOS.ConnectedHome.Control", + "payloadVersion": "1" + }, + "payload": {} +} +``` + +##### TurnOffRequest + +**例子:** +“小度小度,关闭 *设备名*” + +**目的:** +DuerOS发送给Bot的关闭设备的请求 + +###### Header + +|Property|Value| +|---|---| +|name|TurnOffRequest| +|namespace|DuerOS.ConnectedHome.Control| + +###### Payload + +|Property|Description|Required| +|---|---|---| +| accessToken | 从设备云端取到的access token | Yes | +| appliance object | 表示具体操作指令 | Yes | +| appliance.applianceId | 设备标识符。标识符在用户拥有的所有设备上必须是唯一的。此外,标识符需要在同一设备的多个发现请求之间保持一致。标识符可以包含任何字母或数字和以下特殊字符:_ - =#; :? @&。标识符不能超过256个字符。 | Yes | +| appliance.additionalApplianceDetails | 提供给Bot使用的设备或场景相关的附加信息的键值对。该属性的内容不能超过5000字节。而且DuerOS也不了解或使用这些数据。 | Yes,但可以为空 | + +TurnOffRequest 例子: +``` +{ + "header": { + "messageId": "01ebf625-0b89-4c4d-b3aa-32340e894688", + "name": "TurnOffRequest", + "namespace": "DuerOS.ConnectedHome.Control", + "payloadVersion": "1" + }, + "payload": { + "accessToken": "[OAuth token here]", + "appliance": { + "additionalApplianceDetails": {}, + "applianceId": "[Device ID for Ceiling Fan]", + } + } +} +``` + +##### TurnOffConfirmation + +**度秘返回的结果例子:** +“*设备name*已关闭” + +**目的:** +表示设备已经被成功关闭。表示Bot返回给DuerOS的关闭成功的结果 + +###### Header + +|Property|Value| +|---|---| +|name| TurnOffConfirmation | +|namespace|DuerOS.ConnectedHome.Control| + +###### Payload + +|Property|Description|Required| +|---|---|---| +| N/A | N/A | N/A | + +TurnOffConfirmation 例子: +``` +{ + "header": { + "messageId": "26fa11a8-accb-4f66-a272-8b1ff7abd722", + "name": "TurnOffConfirmation", + "namespace": "DuerOS.ConnectedHome.Control", + "payloadVersion": "1" + }, + "payload": {} +} +``` + +#### 可控灯光设备(Tunable Lighting Control Messages) + +##### IncrementBrightnessRequest + +**例子:** +“小度小度,把卧室的灯调亮一点” + +**目的:** +DuerOS发送给Bot的调亮灯光的请求 + +###### Header + +|Property|Value| +|---|---| +|name|IncrementBrightnessRequest| +|namespace|DuerOS.ConnectedHome.Control| + +###### Payload + +|Property|Description|Required| +|---|---|---| +| accessToken | 从设备云端取到的access token | Yes | +| appliance object | 表示具体操作指令 | Yes | +| appliance.applianceId | 设备标识符。标识符在用户拥有的所有设备上必须是唯一的。此外,标识符需要在同一设备的多个发现请求之间保持一致。标识符可以包含任何字母或数字和以下特殊字符:_ - =#; :? @&。标识符不能超过256个字符。 | Yes | +| appliance.additionalApplianceDetails | 提供给Bot使用的设备或场景相关的附加信息的键值对。该属性的内容不能超过5000字节。而且DuerOS也不了解或使用这些数据。 | Yes,但可以为空 | +| deltaBrightness | 表示设备的亮度提高的量的对象。包含一个属性值,它指定一个double类型的数字,表示设备亮度调整的值,其有效范围为0.0000至1.0000。 | Yes | + +TurnOnRequest 例子: +``` +{ + "header": { + "messageId": "01ebf625-0b89-4c4d-b3aa-32340e894688", + "name": "IncrementBrightnessRequest", + "namespace": "DuerOS.ConnectedHome.Control", + "payloadVersion": "1" + }, + "payload": { + "deltaBrightness": { + "value": 0.500 + }, + "accessToken": "[OAuth token here]", + "appliance": { + "additionalApplianceDetails": {}, + "applianceId": "[Device ID for Ceiling Fan]", + } + } +} +``` + +##### IncrementBrightnessConfirmation + +**度秘返回的结果例子:** +“*设备name*已设置成功” + +**目的:** +表示设备亮度调高成功。表示Bot返回给DuerOS的成功的结果 + +###### Header + +|Property|Value| +|---|---| +|name| IncrementBrightnessConfirmation | +|namespace|DuerOS.ConnectedHome.Control| + +###### Payload + +|Property|Description|Required| +|---|---|---| +| brightness | double类型,表示亮度增加后的值。 | Yes | +| previousState object | 表示亮度变化之前的对象 | Yes | +| previousState.brightness | double类型,表示亮度增加前的值。 | Yes | + +TurnOnConfirmation 例子: +``` +{ + "header": { + "messageId": "780013dd-99d0-4c69-9e35-db0457f9f2a7", + "name": "IncrementBrightnessConfirmation", + "namespace": "DuerOS.ConnectedHome.Control", + "payloadVersion": "1" + }, + "payload": { + "previousState": { + "brightness": { + "value": 0.5 + } + }, + "brightness": { + "value": 1.0 + } + } +} +``` + +##### DecrementBrightnessRequest + +**例子:** +“小度小度,把卧室的灯调暗一点” + +**目的:** +DuerOS发送给Bot的调低灯光亮度的请求 + +###### Header + +|Property|Value| +|---|---| +|name|DecrementBrightnessRequest| +|namespace|DuerOS.ConnectedHome.Control| + +###### Payload + +|Property|Description|Required| +|---|---|---| +| accessToken | 从设备云端取到的access token | Yes | +| appliance object | 表示具体操作指令 | Yes | +| appliance.applianceId | 设备标识符。标识符在用户拥有的所有设备上必须是唯一的。此外,标识符需要在同一设备的多个发现请求之间保持一致。标识符可以包含任何字母或数字和以下特殊字符:_ - =#; :? @&。标识符不能超过256个字符。 | Yes | +| appliance.additionalApplianceDetails | 提供给Bot使用的设备或场景相关的附加信息的键值对。该属性的内容不能超过5000字节。而且DuerOS也不了解或使用这些数据。 | Yes,但可以为空 | +| deltaBrightness | 表示设备的亮度提高的量的对象。包含一个属性值,它指定一个double类型的数字,表示设备亮度调整的值,其有效范围为0.0000至1.0000。 | Yes | + +DecrementBrightnessRequest 例子: +``` +{ + "header": { + "messageId": "01ebf625-0b89-4c4d-b3aa-32340e894688", + "name": "DecrementBrightnessRequest", + "namespace": "DuerOS.ConnectedHome.Control", + "payloadVersion": "1" + }, + "payload": { + "deltaBrightness": { + "value": 0.500 + }, + "accessToken": "[OAuth token here]", + "appliance": { + "additionalApplianceDetails": {}, + "applianceId": "[Device ID for Ceiling Fan]", + } + } +} +``` + +##### DecrementBrightnessConfirmation + +**度秘返回的结果例子:** +“*设备name*已设置成功” + +**目的:** +表示设备亮度调低成功。表示Bot返回给DuerOS的成功的结果 + +###### Header + +|Property|Value| +|---|---| +|name| DecrementBrightnessConfirmation | +|namespace|DuerOS.ConnectedHome.Control| + +###### Payload + +|Property|Description|Required| +|---|---|---| +| brightness | double类型,表示亮度增加后的值。 | Yes | +| previousState object | 表示亮度变化之前的对象 | Yes | +| previousState.brightness | double类型,表示亮度增加前的值。 | Yes | + +DecrementBrightnessConfirmation 例子: +``` +{ + "header": { + "messageId": "780013dd-99d0-4c69-9e35-db0457f9f2a7", + "name": "DecrementBrightnessConfirmation", + "namespace": "DuerOS.ConnectedHome.Control", + "payloadVersion": "1" + }, + "payload": { + "previousState": { + "brightness": { + "value": 1.0 + } + }, + "brightness": { + "value": 0.5 + } + } +} +``` + +#### 可控温度设备(Temperature Control Messages) + +##### IncrementTemperatureRequest + +**例子:** +“小度小度,把卧室的温度调高一点” + +**目的:** +DuerOS发送给Bot的调高温度的请求 + +###### Header + +|Property|Value| +|---|---| +|name|IncrementTemperatureRequest| +|namespace|DuerOS.ConnectedHome.Control| + +###### Payload + +|Property|Description|Required| +|---|---|---| +| accessToken | 从设备云端取到的access token | Yes | +| appliance object | 表示具体操作指令 | Yes | +| appliance.applianceId | 设备标识符。标识符在用户拥有的所有设备上必须是唯一的。此外,标识符需要在同一设备的多个发现请求之间保持一致。标识符可以包含任何字母或数字和以下特殊字符:_ - =#; :? @&。标识符不能超过256个字符。 | Yes | +| appliance.additionalApplianceDetails | 提供给Bot使用的设备或场景相关的附加信息的键值对。该属性的内容不能超过5000字节。而且DuerOS也不了解或使用这些数据。 | Yes,但可以为空 | +| deltaTemperature | 表示设备的温度变化的量的对象。包含一个属性值,它指定一个数字。 | Yes | + +IncrementTemperatureRequest 例子: +``` +{ + "header": { + "messageId": "01ebf625-0b89-4c4d-b3aa-32340e894688", + "name": "IncrementTemperatureRequest", + "namespace": "DuerOS.ConnectedHome.Control", + "payloadVersion": "1" + }, + "payload": { + "deltaTemperature": { + "value": 2.0 + }, + "accessToken": "[OAuth token here]", + "appliance": { + "additionalApplianceDetails": {}, + "applianceId": "[Device ID for Ceiling Fan]", + } + } +} +``` + +##### IncrementTemperatureConfirmation + +**度秘返回的结果例子:** +“*设备name*已设置成功” + +**目的:** +表示设备温度调高成功。表示Bot返回给DuerOS的成功的结果 + +###### Header + +|Property|Value| +|---|---| +|name| IncrementTemperatureConfirmation | +|namespace|DuerOS.ConnectedHome.Control| + +###### Payload + +|Property|Description|Required| +|---|---|---| +| mode | 表示设置之后的设备模式。 | Yes | +| temperature | double类型,表示设置之后的值。 | Yes | +| previousState object | 表示亮度变化之前的对象 | Yes | +| previousState.mode | 表示设置之前的设备模式。 | Yes | +| previousState.temperature | double类型,表示设置之前的值。 | Yes | + +IncrementTemperatureConfirmation 例子: +``` +{ + "header": { + "messageId": "780013dd-99d0-4c69-9e35-db0457f9f2a7", + "name": "IncrementTemperatureConfirmation", + "namespace": "DuerOS.ConnectedHome.Control", + "payloadVersion": "1" + }, + "payload": { + "previousState": { + "mode": { + "value": "AUTO" + }, + "temperature": { + "value": 21.0 + } + }, + "temperature": { + "value": 25.0 + }, + "mode": { + "value": "AUTO" + } + } +} +``` + +##### DecrementTemperatureRequest + +**例子:** +“小度小度,把卧室的温度调低一点” + +**目的:** +DuerOS发送给Bot的调低温度的请求 + +###### Header + +|Property|Value| +|---|---| +|name|DecrementTemperatureRequest| +|namespace|DuerOS.ConnectedHome.Control| + +###### Payload + +|Property|Description|Required| +|---|---|---| +| accessToken | 从设备云端取到的access token | Yes | +| appliance object | 表示具体操作指令 | Yes | +| appliance.applianceId | 设备标识符。标识符在用户拥有的所有设备上必须是唯一的。此外,标识符需要在同一设备的多个发现请求之间保持一致。标识符可以包含任何字母或数字和以下特殊字符:_ - =#; :? @&。标识符不能超过256个字符。 | Yes | +| appliance.additionalApplianceDetails | 提供给Bot使用的设备或场景相关的附加信息的键值对。该属性的内容不能超过5000字节。而且DuerOS也不了解或使用这些数据。 | Yes,但可以为空 | +| deltaTemperature | 表示设备的温度变化的量的对象。包含一个属性值,它指定一个数字。 | Yes | + +DecrementTemperatureRequest 例子: +``` +{ + "header": { + "messageId": "01ebf625-0b89-4c4d-b3aa-32340e894688", + "name": "DecrementTemperatureRequest", + "namespace": "DuerOS.ConnectedHome.Control", + "payloadVersion": "1" + }, + "payload": { + "deltaTemperature": { + "value": 2.0 + }, + "accessToken": "[OAuth token here]", + "appliance": { + "additionalApplianceDetails": {}, + "applianceId": "[Device ID for Ceiling Fan]", + } + } +} +``` + +##### DecrementTemperatureConfirmation + +**度秘返回的结果例子:** +“*设备name*已设置成功” + +**目的:** +表示设备温度调低成功。表示Bot返回给DuerOS的成功的结果 + +###### Header + +|Property|Value| +|---|---| +|name| DecrementTemperatureConfirmation | +|namespace|DuerOS.ConnectedHome.Control| + +###### Payload + +|Property|Description|Required| +|---|---|---| +| mode | 表示设置之后的设备模式。 | Yes | +| temperature | double类型,表示设置之后的值。 | Yes | +| previousState object | 表示亮度变化之前的对象 | Yes | +| previousState.mode | 表示设置之前的设备模式。 | Yes | +| previousState.temperature | double类型,表示设置之前的值。 | Yes | + +DecrementTemperatureConfirmation 例子: +``` +{ + "header": { + "messageId": "780013dd-99d0-4c69-9e35-db0457f9f2a7", + "name": "DecrementTemperatureConfirmation", + "namespace": "DuerOS.ConnectedHome.Control", + "payloadVersion": "1" + }, + "payload": { + "previousState": { + "mode": { + "value": "AUTO" + }, + "temperature": { + "value": 25.0 + } + }, + "temperature": { + "value": 23.0 + }, + "mode": { + "value": "AUTO" + } + } +} +``` + +##### SetTemperatureRequest + +**例子:** +“小度小度,把卧室的温度设置为20度” + +**目的:** +DuerOS发送给Bot的设置温度的请求 + +###### Header + +|Property|Value| +|---|---| +|name|SetTemperatureRequest| +|namespace|DuerOS.ConnectedHome.Control| + +###### Payload + +|Property|Description|Required| +|---|---|---| +| accessToken | 从设备云端取到的access token | Yes | +| appliance object | 表示具体操作指令 | Yes | +| appliance.applianceId | 设备标识符。标识符在用户拥有的所有设备上必须是唯一的。此外,标识符需要在同一设备的多个发现请求之间保持一致。标识符可以包含任何字母或数字和以下特殊字符:_ - =#; :? @&。标识符不能超过256个字符。 | Yes | +| appliance.additionalApplianceDetails | 提供给Bot使用的设备或场景相关的附加信息的键值对。该属性的内容不能超过5000字节。而且DuerOS也不了解或使用这些数据。 | Yes,但可以为空 | +| targetTemperature | 表示设备的温度设置的量的对象。包含一个属性值,它指定一个数字。 | Yes | + +SetTemperatureRequest 例子: +``` +{ + "header": { + "messageId": "01ebf625-0b89-4c4d-b3aa-32340e894688", + "name": "SetTemperatureRequest", + "namespace": "DuerOS.ConnectedHome.Control", + "payloadVersion": "1" + }, + "payload": { + "targetTemperature": { + "value": 2.0 + }, + "accessToken": "[OAuth token here]", + "appliance": { + "additionalApplianceDetails": {}, + "applianceId": "[Device ID for Ceiling Fan]", + } + } +} +``` + +##### SetTemperatureConfirmation + +**度秘返回的结果例子:** +“*设备name*已设置成功” + +**目的:** +表示设备温度设置成功。表示Bot返回给DuerOS的成功的结果 + +###### Header + +|Property|Value| +|---|---| +|name| SetTemperatureConfirmation | +|namespace|DuerOS.ConnectedHome.Control| + +###### Payload + +|Property|Description|Required| +|---|---|---| +| mode | 表示设置之后的设备模式。 | Yes | +| temperature | double类型,表示设置之后的值。 | Yes | +| previousState object | 表示亮度变化之前的对象 | Yes | +| previousState.mode | 表示设置之前的设备模式。 | Yes | +| previousState.temperature | double类型,表示设置之前的值。 | Yes | + +SetTemperatureConfirmation 例子: +``` +{ + "header": { + "messageId": "780013dd-99d0-4c69-9e35-db0457f9f2a7", + "name": "SetTemperatureConfirmation", + "namespace": "DuerOS.ConnectedHome.Control", + "payloadVersion": "1" + }, + "payload": { + "previousState": { + "mode": { + "value": "AUTO" + }, + "temperature": { + "value": 25.0 + } + }, + "temperature": { + "value": 23.0 + }, + "mode": { + "value": "AUTO" + } + } +} +``` + +#### 可控风速设备(Fan Speed Control Messages) + +##### IncrementFanSpeedRequest + +**例子:** +“小度小度,把空调的风速增加一点” + +**目的:** +DuerOS发送给Bot的调高风速的请求 + +###### Header + +|Property|Value| +|---|---| +|name|IncrementFanSpeedRequest| +|namespace|DuerOS.ConnectedHome.Control| + +###### Payload + +|Property|Description|Required| +|---|---|---| +| accessToken | 从设备云端取到的access token | Yes | +| appliance object | 表示具体操作指令 | Yes | +| appliance.applianceId | 设备标识符。标识符在用户拥有的所有设备上必须是唯一的。此外,标识符需要在同一设备的多个发现请求之间保持一致。标识符可以包含任何字母或数字和以下特殊字符:_ - =#; :? @&。标识符不能超过256个字符。 | Yes | +| appliance.additionalApplianceDetails | 提供给Bot使用的设备或场景相关的附加信息的键值对。该属性的内容不能超过5000字节。而且DuerOS也不了解或使用这些数据。 | Yes,但可以为空 | +| deltaFanSpeed | 表示设备的风速变化的量的对象。包含一个属性值,它指定一个double类型的数字,表示设备风速调整的值,其有效范围为0.0000至1.0000。 | Yes | + +IncrementFanSpeedRequest 例子: +``` +{ + "header": { + "messageId": "01ebf625-0b89-4c4d-b3aa-32340e894688", + "name": "IncrementFanSpeedRequest", + "namespace": "DuerOS.ConnectedHome.Control", + "payloadVersion": "1" + }, + "payload": { + "deltaFanSpeed": { + "value": 0.5 + }, + "accessToken": "[OAuth token here]", + "appliance": { + "additionalApplianceDetails": {}, + "applianceId": "[Device ID for Ceiling Fan]", + } + } +} +``` + +##### IncrementFanSpeedConfirmation + +**度秘返回的结果例子:** +“*设备name*已设置成功” + +**目的:** +表示设备风速调高成功。表示Bot返回给DuerOS的成功的结果 + +###### Header + +|Property|Value| +|---|---| +|name| IncrementFanSpeedConfirmation | +|namespace|DuerOS.ConnectedHome.Control| + +###### Payload + +|Property|Description|Required| +|---|---|---| +| mode | 表示设置之后的设备模式。 | Yes | +| fanSpeed | double类型,表示设置之后的值。 | Yes | +| previousState object | 表示亮度变化之前的对象 | Yes | +| previousState.mode | 表示设置之前的设备模式。 | Yes | +| previousState.fanSpeed | double类型,表示设置之前的值。 | Yes | + +IncrementFanSpeedConfirmation 例子: +``` +{ + "header": { + "messageId": "780013dd-99d0-4c69-9e35-db0457f9f2a7", + "name": "IncrementFanSpeedConfirmation", + "namespace": "DuerOS.ConnectedHome.Control", + "payloadVersion": "1" + }, + "payload": { + "previousState": { + "mode": { + "value": "AUTO" + }, + "fanSpeed": { + "value": 0.5 + } + }, + "fanSpeed": { + "value": 1.0 + }, + "mode": { + "value": "AUTO" + } + } +} +``` + +##### DecrementFanSpeedRequest + +**例子:** +“小度小度,把空调的风速降低一点” + +**目的:** +DuerOS发送给Bot的调低风速的请求 + +###### Header + +|Property|Value| +|---|---| +|name|DecrementFanSpeedRequest| +|namespace|DuerOS.ConnectedHome.Control| + +###### Payload + +|Property|Description|Required| +|---|---|---| +| accessToken | 从设备云端取到的access token | Yes | +| appliance object | 表示具体操作指令 | Yes | +| appliance.applianceId | 设备标识符。标识符在用户拥有的所有设备上必须是唯一的。此外,标识符需要在同一设备的多个发现请求之间保持一致。标识符可以包含任何字母或数字和以下特殊字符:_ - =#; :? @&。标识符不能超过256个字符。 | Yes | +| appliance.additionalApplianceDetails | 提供给Bot使用的设备或场景相关的附加信息的键值对。该属性的内容不能超过5000字节。而且DuerOS也不了解或使用这些数据。 | Yes,但可以为空 | +| deltaFanSpeed | 表示设备的风速变化的量的对象。包含一个属性值,它指定一个double类型的数字,表示设备风速调整的值,其有效范围为0.0000至1.0000。 | Yes | + +DecrementFanSpeedRequest 例子: +``` +{ + "header": { + "messageId": "01ebf625-0b89-4c4d-b3aa-32340e894688", + "name": "DecrementFanSpeedRequest", + "namespace": "DuerOS.ConnectedHome.Control", + "payloadVersion": "1" + }, + "payload": { + "deltaFanSpeed": { + "value": 0.5 + }, + "accessToken": "[OAuth token here]", + "appliance": { + "additionalApplianceDetails": {}, + "applianceId": "[Device ID for Ceiling Fan]", + } + } +} +``` + +##### DecrementFanSpeedConfirmation + +**度秘返回的结果例子:** +“*设备name*已设置成功” + +**目的:** +表示设备风速调低成功。表示Bot返回给DuerOS的成功的结果 + +###### Header + +|Property|Value| +|---|---| +|name| DecrementFanSpeedConfirmation | +|namespace|DuerOS.ConnectedHome.Control| + +###### Payload + +|Property|Description|Required| +|---|---|---| +| mode | 表示设置之后的设备模式。 | Yes | +| fanSpeed | double类型,表示设置之后的值。 | Yes | +| previousState object | 表示亮度变化之前的对象 | Yes | +| previousState.mode | 表示设置之前的设备模式。 | Yes | +| previousState.fanSpeed | double类型,表示设置之前的值。 | Yes | + +DecrementFanSpeedConfirmation 例子: +``` +{ + "header": { + "messageId": "780013dd-99d0-4c69-9e35-db0457f9f2a7", + "name": "DecrementFanSpeedConfirmation", + "namespace": "DuerOS.ConnectedHome.Control", + "payloadVersion": "1" + }, + "payload": { + "previousState": { + "mode": { + "value": "AUTO" + }, + "fanSpeed": { + "value": 1.0 + } + }, + "fanSpeed": { + "value": 0.5 + }, + "mode": { + "value": "AUTO" + } + } +} +``` + +##### SetModeRequest + +**例子:** +“小度小度,把空调的模式调整为制冷” + +**目的:** +DuerOS发送给Bot的设置模式的请求 + +###### Header + +|Property|Value| +|---|---| +|name|SetModeRequest| +|namespace|DuerOS.ConnectedHome.Control| + +###### Payload + +|Property|Description|Required| +|---|---|---| +| accessToken | 从设备云端取到的access token | Yes | +| appliance object | 表示具体操作指令 | Yes | +| appliance.applianceId | 设备标识符。标识符在用户拥有的所有设备上必须是唯一的。此外,标识符需要在同一设备的多个发现请求之间保持一致。标识符可以包含任何字母或数字和以下特殊字符:_ - =#; :? @&。标识符不能超过256个字符。 | Yes | +| appliance.additionalApplianceDetails | 提供给Bot使用的设备或场景相关的附加信息的键值对。该属性的内容不能超过5000字节。而且DuerOS也不了解或使用这些数据。 | Yes,但可以为空 | +| mode | 表示设备的模式设置的量的对象。包含一个属性值,它指定一种模式。 | Yes | + +SetModeRequest 例子: +``` +{ + "header": { + "messageId": "01ebf625-0b89-4c4d-b3aa-32340e894688", + "name": "SetModeRequest", + "namespace": "DuerOS.ConnectedHome.Control", + "payloadVersion": "1" + }, + "payload": { + "mode": { + "value": "AUTO" + }, + "accessToken": "[OAuth token here]", + "appliance": { + "additionalApplianceDetails": {}, + "applianceId": "[Device ID for Ceiling Fan]", + } + } +} +``` + +##### SetModeConfirmation + +**度秘返回的结果例子:** +“*设备name*已设置成功” + +**目的:** +表示设备模式设置成功。表示Bot返回给DuerOS的成功的结果 + +###### Header + +|Property|Value| +|---|---| +|name| SetModeConfirmation | +|namespace|DuerOS.ConnectedHome.Control| + +###### Payload + +|Property|Description|Required| +|---|---|---| +| mode | 表示设置之后的设备模式。 | Yes | +| previousState object | 表示亮度变化之前的对象 | Yes | +| previousState.mode | 表示设置之前的设备模式。 | Yes | + +SetModeConfirmation 例子: +``` +{ + "header": { + "messageId": "780013dd-99d0-4c69-9e35-db0457f9f2a7", + "name": "SetModeConfirmation", + "namespace": "DuerOS.ConnectedHome.Control", + "payloadVersion": "1" + }, + "payload": { + "previousState": { + "mode": { + "value": "COOL" + } + }, + "mode": { + "value": "AUTO" + } + } +} +``` + +##### TimingSetModeRequest + +**例子:** +“小度小度,1分钟后把空调的模式调整为制冷” + +**目的:** +DuerOS发送给Bot的设置模式的请求 + +###### Header + +|Property|Value| +|---|---| +|name|TimingSetModeRequest| +|namespace|DuerOS.ConnectedHome.Control| + +###### Payload + +|Property|Description|Required| +|---|---|---| +| accessToken | 从设备云端取到的access token | Yes | +| appliance object | 表示具体操作指令 | Yes | +| appliance.applianceId | 设备标识符。标识符在用户拥有的所有设备上必须是唯一的。此外,标识符需要在同一设备的多个发现请求之间保持一致。标识符可以包含任何字母或数字和以下特殊字符:_ - =#; :? @&。标识符不能超过256个字符。 | Yes | +| appliance.additionalApplianceDetails | 提供给Bot使用的设备或场景相关的附加信息的键值对。该属性的内容不能超过5000字节。而且DuerOS也不了解或使用这些数据。 | Yes,但可以为空 | +| mode | 表示设备的模式设置的量的对象。包含一个属性值,它指定一种模式。 | Yes | +| timestamp | 表示设备定时设置的量的对象。包含一个属性值,它指定一个数字,代表时间戳。 | Yes | + +TimingSetModeRequest 例子: +``` +{ + "header": { + "messageId": "01ebf625-0b89-4c4d-b3aa-32340e894688", + "name": "TimingSetModeRequest", + "namespace": "DuerOS.ConnectedHome.Control", + "payloadVersion": "1" + }, + "payload": { + "mode": { + "value": "AUTO" + }, + "timestamp": { + "value": 2.0 + }, + "accessToken": "[OAuth token here]", + "appliance": { + "additionalApplianceDetails": {}, + "applianceId": "[Device ID for Ceiling Fan]", + } + } +} +``` + +##### TimingSetModeConfirmation + +**度秘返回的结果例子:** +“*设备name*已设置成功” + +**目的:** +表示设备模式设置成功。表示Bot返回给DuerOS的成功的结果 + +###### Header + +|Property|Value| +|---|---| +|name| TimingSetModeConfirmation | +|namespace|DuerOS.ConnectedHome.Control| + +###### Payload + +|Property|Description|Required| +|---|---|---| +| mode | 表示设置之后的设备模式。 | Yes | +| previousState object | 表示亮度变化之前的对象 | Yes | +| previousState.mode | 表示设置之前的设备模式。 | Yes | + +TimingSetModeConfirmation 例子: +``` +{ + "header": { + "messageId": "780013dd-99d0-4c69-9e35-db0457f9f2a7", + "name": "TimingSetModeConfirmation", + "namespace": "DuerOS.ConnectedHome.Control", + "payloadVersion": "1" + }, + "payload": { + "previousState": { + "mode": { + "value": "COOL" + } + }, + "mode": { + "value": "AUTO" + } + } +} +``` + +### 查询状态(Query Message) + +#### 查询空气质量 + +##### GetAirPM25Request + +**例子:** +“小度小度,查一下卧室pm2.5” + +**目的:** +DuerOS发送给Bot的设置模式的请求 + +###### Header + +|Property|Value| +|---|---| +|name|GetAirPM25Request| +|namespace|DuerOS.ConnectedHome.Query| + +###### Payload + +|Property|Description|Required| +|---|---|---| +| accessToken | 从设备云端取到的access token | Yes | +| appliance object | 表示具体操作指令 | Yes | +| appliance.applianceId | 设备标识符。标识符在用户拥有的所有设备上必须是唯一的。此外,标识符需要在同一设备的多个发现请求之间保持一致。标识符可以包含任何字母或数字和以下特殊字符:_ - =#; :? @&。标识符不能超过256个字符。 | Yes | +| appliance.additionalApplianceDetails | 提供给Bot使用的设备或场景相关的附加信息的键值对。该属性的内容不能超过5000字节。而且DuerOS也不了解或使用这些数据。 | Yes,但可以为空 | + +GetAirPM25Request 例子: +``` +{ + "header": { + "messageId": "01ebf625-0b89-4c4d-b3aa-32340e894688", + "name": "GetAirPM25Request", + "namespace": "DuerOS.ConnectedHome.Query", + "payloadVersion": "1" + }, + "payload": { + "accessToken": "[OAuth token here]", + "appliance": { + "additionalApplianceDetails": {}, + "applianceId": "[Device ID for Ceiling Fan]", + } + } +} +``` + +##### GetAirPM25Confirmation + +**度秘返回的结果例子:** +“当前卧室pm2.5为100” + +**目的:** +表示设备查询结果成功。表示Bot返回给DuerOS的成功的结果 + +###### Header + +|Property|Value| +|---|---| +|name| GetAirPM25Confirmation | +|namespace| DuerOS.ConnectedHome.Query | + +###### Payload + +|Property|Description|Required| +|---|---|---| +| PM25 | 表示当前PM2.5的数值。 | Yes | + +GetAirPM25Confirmation 例子: +``` +{ + "header": { + "messageId": "780013dd-99d0-4c69-9e35-db0457f9f2a7", + "name": "GetAirPM25Confirmation", + "namespace": "DuerOS.ConnectedHome.Query", + "payloadVersion": "1" + }, + "payload": { + "PM25": { + "value": 100 + } + } +} +``` + +### 错误消息(Error Message) + +当 DuerOS 向 Bot 发送控制请求时,可能会出现不同种类的错误,如果需要,Bot应返回相应的错误类型和信息。Bot不需要返回每个错误类型,仅返回错误对应的故障类型。本节中列出了错误类型和详细信息。除非另有说明,否则错误消息不适用于设备发现,并且不应返回错误消息作为对DiscoverAppliancesRequest的响应。 + +用户故障:由于用户错误操作,请求可能会无效,会发生以下这些错误。 例如,用户要求将空调设置为1000度。 +* ValueOutOfRangeError +* TargetOfflineError +* NoSuchTargetError +* BridgeOfflineError + +Bot故障:当请求有效时,由于硬件问题或限制,也可能会出现以下这些错误,Bot无法完成所需的任务。 +* DriverInternalError +* DependentServiceUnavailableError +* NotSupportedInCurrentModeError +* RateLimitExceededError +* TargetBridgeConnectivityUnstableError +* TargetFirmwareOutdatedError +* TargetBridgeFirmwareOutdatedError +* TargetHardwareMalfunctionError +* TargetBridgeHardwareMalfunctionError +* TargetConnectivityUnstableError +* TargetHardwareMalfunctionError +* UnableToGetValueError +* UnableToSetValueError +* UnwillingToSetValueError + +其他故障:当请求中的数据内容无法满足时,会发生这些错误; 认证令牌无效,或技能适配器无法满足请求的其他方面。 +* ExpiredAccessTokenError +* InvalidAccessTokenError +* UnsupportedTargetError +* UnsupportedOperationError +* UnsupportedTargetSettingError +* UnexpectedInformationReceivedError + +#### 用户故障(User Faults) +当用户给出不正确的指示或度秘不能完成的指令时,会发生以下错误。 + +##### ValueOutOfRangeError +目的:表示用户请求将目标值设置为超出其支持范围的值。 例如,用户说:“小度小度,将厨房设置为1000度”。 + +###### Payload + +|Property|Description|Required| +|---|---|---| +| minimumValue | 64位双精度值,表示目标设备设置允许的最低值。 | Yes | +| maximumValue | 64位双精度值,表示目标设备设置允许的最高值。 | Yes | + +ValueOutOfRangeError 例子: +``` +{ + "header":{ + "namespace":"DuerOS.ConnectedHome.Control", + "name":" ValueOutOfRangeError", + "payloadVersion":"1", + "messageId":"697fe957-c842-4545-a159-8a8c75fbe5bd" + }, + "payload":{ + "minimumValue":15.0, + "maximumValue":30.0 + } +} +``` + +##### TargetOfflineError +目的:表示目标设备未连接到用户的设备云或设备云不在线。 + +###### Payload + +|Property|Description|Required| +|---|---|---| +| N/A | N/A | N/A | + +TargetOfflineError 例子: +``` +{ + "header":{ + "namespace":"DuerOS.ConnectedHome.Control", + "name":"TargetOfflineError", + "payloadVersion":"1", + "messageId":"15a248f6-8ab5-433d-a3ac-73c358e0bebd" + }, + "payload":{ + } +} +``` + +##### BridgeOfflineError +目的:指示目标设备连接到已关闭电源。 + +###### Payload + +|Property|Description|Required| +|---|---|---| +| N/A | N/A | N/A | + +BridgeOfflineError 例子: +``` +{ + "header":{ + "namespace":"DuerOS.ConnectedHome.Control", + "name":"BridgeOfflineError", + "payloadVersion":"1", + "messageId":"15a248f6-8ab5-433d-a3ac-73c358e0bebd" + }, + "payload":{ + } +} +``` + +#### Bot故障(Bot Faults) +当Bot与设备云交互出现问题时,会发生以下错误。在这些情况下,用户请求有效,但由于某种原因无法完成。 + +##### DriverInternalError +目的:指示Bot内的通用运行时错误。如果可能,应该返回一个更具体的错误。 + +###### Payload + +|Property|Description|Required| +|---|---|---| +| N/A | N/A | N/A | + +DriverInternalError 例子: +``` +{ + "header":{ + "namespace":"DuerOS.ConnectedHome.Control", + "name":"DriverInternalError", + "payloadVersion":"1", + "messageId":"15a248f6-8ab5-433d-a3ac-73c358e0bebd" + }, + "payload":{ + } +} +``` + +##### DependentServiceUnavailableError +目的:表示技Bot依赖的模块不可用,Bot无法完成请求。 + +###### Payload + +|Property|Description|Required| +|---|---|---| +| dependentServiceName | 表示不可用的依赖模块的字符串。必须以字母数字字符和空格指定。此值在256个字符后截断。 | Yes | + +DependentServiceUnavailableError 例子: +``` +{ + "header":{ + "namespace":"DuerOS.ConnectedHome.Control", + "name":"DependentServiceUnavailableError", + "payloadVersion":"1", + "messageId":"15a248f6-8ab5-433d-a3ac-73c358e0bebd" + }, + "payload":{ + "dependentServiceName":"Customer Credential Database" + } +} +``` + +##### TargetConnectivityUnstableError +目的:表示目标设备的云连接不稳定可靠。 + +###### Payload + +|Property|Description|Required| +|---|---|---| +| N/A | N/A | N/A | + +TargetConnectivityUnstableError 例子: +``` +{ + "header":{ + "namespace":"DuerOS.ConnectedHome.Control", + "name":"TargetConnectivityUnstableError ", + "payloadVersion":"1", + "messageId":"15a248f6-8ab5-433d-a3ac-73c358e0bebd" + }, + "payload":{ + } +} +``` + +##### TargetBridgeConnectivityUnstableError +目的:表示连接目标设备的家庭hub或网桥的云连接不稳定和不可靠。 + +###### Payload + +|Property|Description|Required| +|---|---|---| +| N/A | N/A | N/A | + +TargetBridgeConnectivityUnstableError 例子: +``` +{ + "header":{ + "namespace":"DuerOS.ConnectedHome.Control", + "name":"TargetBridgeConnectivityUnstableError", + "payloadVersion":"1", + "messageId":"15a248f6-8ab5-433d-a3ac-73c358e0bebd" + }, + "payload":{ + } +} +``` + +##### TargetFirmwareOutdatedError +目的:表示目标设备的固件版本太低。 + +###### Payload + +|Property|Description|Required| +|---|---|---| +| minimumFirmwareVersion | 表示最低允许固件版本。不能超过256个字符。 | Yes | +| currentFirmwareVersion | 表示当前固件版本。不能超过256个字符。 | Yes | + +TargetFirmwareOutdatedError 例子: +``` +{ + "header":{ + "namespace":"DuerOS.ConnectedHome.Control", + "name":"TargetFirmwareOutdatedError", + "payloadVersion":"1", + "messageId":"15a248f6-8ab5-433d-a3ac-73c358e0bebd" + }, + "payload":{ + "minimumFirmwareVersion":"17", + "currentFirmwareVersion":"6" + } +} +``` + +##### TargetBridgeFirmwareOutdatedError +目的:表示连接目标设备的家庭hub或网桥的固件版本太低。 + +###### Payload + +|Property|Description|Required| +|---|---|---| +| minimumFirmwareVersion | 表示最低允许固件版本。不能超过256个字符。 | Yes | +| currentFirmwareVersion | 表示当前固件版本。不能超过256个字符。 | Yes | + +TargetBridgeFirmwareOutdatedError 例子: +``` +{ + "header":{ + "namespace":"DuerOS.ConnectedHome.Control", + "name":"TargetBridgeFirmwareOutdatedError", + "payloadVersion":"1", + "messageId":"15a248f6-8ab5-433d-a3ac-73c358e0bebd" + }, + "payload":{ + "minimumFirmwareVersion":"17", + "currentFirmwareVersion":"6" + } +} +``` + +##### TargetHardwareMalfunctionError +目的:表示目标设备出现硬件故障。 + +###### Payload + +|Property|Description|Required| +|---|---|---| +| N/A | N/A | N/A | + +TargetHardwareMalfunctionError 例子: +``` +{ + "header":{ + "namespace":"DuerOS.ConnectedHome.Control", + "name":"TargetHardwareMalfunctionError", + "payloadVersion":"1", + "messageId":"15a248f6-8ab5-433d-a3ac-73c358e0bebd" + }, + "payload":{ + } +} +``` + +##### TargetBridgeHardwareMalfunctionError +目的:表示连接目标设备的家庭hub或桥接器出现硬件故障。 + +###### Payload + +|Property|Description|Required| +|---|---|---| +| N/A | N/A | N/A | + +TargetBridgeHardwareMalfunctionError 例子: +``` +{ + "header":{ + "namespace":"DuerOS.ConnectedHome.Control", + "name":"TargetBridgeHardwareMalfunctionError", + "payloadVersion":"1", + "messageId":"15a248f6-8ab5-433d-a3ac-73c358e0bebd" + }, + "payload":{ + } +} +``` + +##### UnableToGetValueError +目的:表示尝试在目标设备上获取指定值时发生错误。当返回此错误时,适当的errorInfo.code值可以让DuerOS能够适应不同类型的故障。您只需生成适用于目标设备的错误代码。 + +###### Payload + +|Property|Description|Required| +|---|---|---| +| errorInfo | 描述为什么不能设置值的错误对象。 | Yes | +| errorInfo.code | 字符串格式的错误代码。有效值是: DEVICE_AJAR:由于门打开,无法获取指定的状态。DEVICE_BUSY:设备正忙。DEVICE_JAMMED:设备卡住。DEVICE_OVERHEATED:设备过热。HARDWARE_FAILURE:由于未确定的硬件故障,请求失败。LOW_BATTERY:设备的电池电量不足。NOT_CALIBRATED:设备未校准。 | Yes | +| errorInfo.Description | 来自设备制造商的错误的自定义描述。 | No | + +UnableToGetValueError 例子: +``` +{ + "header":{ + "namespace":"DuerOS.ConnectedHome.Control", + "name":"UnableToGetValueError", + "payloadVersion":"1", + "messageId":"917314cd-ca00-49ca-b75e-d6f65ac43503" + }, + "payload":{ + "errorInfo":{ + "code":"DEVICE_JAMMED", + "description":"A custom description of the error.." + } + } +} +``` + +##### UnableToSetValueError +目的:表示尝试在目标设备上设置指定值时发生错误。当返回此错误时,适当的errorInfo.code值使得DuerOS能够适应不同类型的故障。您只需生成适用于目标设备的错误代码。 + +###### Payload + +|Property|Description|Required| +|---|---|---| +| errorInfo | 描述为什么不能设置值的错误对象。 | Yes | +| errorInfo.code | 字符串格式的错误代码。有效值是: DEVICE_AJAR:由于门打开,无法获取指定的状态。DEVICE_BUSY:设备正忙。DEVICE_JAMMED:设备卡住。DEVICE_OVERHEATED:设备过热。HARDWARE_FAILURE:由于未确定的硬件故障,请求失败。LOW_BATTERY:设备的电池电量不足。NOT_CALIBRATED:设备未校准。 | Yes | +| errorInfo.Description | 来自设备制造商的错误的自定义描述。 | No | + +UnableToSetValueError 例子: +``` +{ + "header":{ + "namespace":"DuerOS.ConnectedHome.Control", + "name":"UnableToSetValueError", + "payloadVersion":"1", + "messageId":"917314cd-ca00-49ca-b75e-d6f65ac43503" + }, + "payload":{ + "errorInfo":{ + "code":"DEVICE_JAMMED", + "description":"A custom description of the error.." + } + } +} +``` + +##### UnwillingToSetValueError +目的:表示目标设备商不愿意在指定的设备上设置请求的值。使用此错误进行温度设置。 + +###### Payload + +|Property|Description|Required| +|---|---|---| +| errorInfo | 描述为什么不能设置值的错误对象。 | Yes | +| errorInfo.code | 字符串格式的错误代码。目前,代码的有效值为ThermostatIsOff,表示由于恒温器关闭,制造商不愿自动将其启动,因此被请求的操作被拒绝。 | Yes | +| errorInfo.Description | 来自设备制造商的错误的自定义描述。 | No | + +UnwillingToSetValueError 例子: +``` +{ + "header":{ + "namespace":"DuerOS.ConnectedHome.Control", + "name":"UnwillingToSetValueError", + "payloadVersion":"1", + "messageId":"917314cd-ca00-49ca-b75e-d6f65ac43503" + }, + "payload":{ + "errorInfo":{ + "code":"ThermostatIsOff", + "description":"The requested operation is unsafe because it requires changing the mode." + } + } +} +``` + +##### RateLimitExceededError +目的:表示超出设备接受的最大请求数。此消息提供有关设备的最大请求数和这些请求的时间单位的信息。例如,如果设备每小时接受四个请求,则消息应分别指定4和HOUR作为rateLimit和timeUnit。 + +###### Payload + +|Property|Description|Required| +|---|---|---| +| rateLimit | Integer,表示设备在指定的时间单位中接受的最大请求数。 | Yes | +| timeUnit | 大写字符串,表示rateLimit的时间单位,如MINUTE,HOUR或DAY。 | Yes | + +RateLimitExceededError 例子: +``` +{ + "header":{ + "namespace":"DuerOS.ConnectedHome.Control", + "name":"RateLimitExceededError", + "payloadVersion":"1", + "messageId":"917314cd-ca00-49ca-b75e-d6f65ac43503" + }, + "payload":{ + "errorInfo":{ + "rateLimit":"10", + "timeUnit":"HOUR" + } + } +} +``` + +##### NotSupportedInCurrentModeError +目的:表示目标设备处于无法通过DuerOS进行控制的模式,并提供有关设备当前模式的信息。 + +###### Payload + +|Property|Description|Required| +|---|---|---| +| currentDeviceMode | 表示设备当前模式的字符串。有效值为AUTO,AWAY,COLOR,COOL,HEAT和OTHER。 | Yes | + +NotSupportedInCurrentModeError 例子: +``` +{ + "header":{ + "namespace":"DuerOS.ConnectedHome.Control", + "name":"NotSupportedInCurrentModeError", + "payloadVersion":"1", + "messageId":"917314cd-ca00-49ca-b75e-d6f65ac43503" + }, + "payload":{ + "errorInfo":{ + "currentDeviceMode":"COOL", + } + } +} +``` + +#### 其他错误(Other Faults) +当一个或多个请求输入无效DuerOS无法处理时,会发生以下错误。例如,访问令牌(access token)无效。 + +##### ExpiredAccessTokenError +目的:表示用于认证的访问令牌(access token)已过期,不再有效。 + +###### Payload + +|Property|Description|Required| +|---|---|---| +| N/A | N/A | N/A | + +ExpiredAccessTokenError 例子: +``` +{ + "header":{ + "namespace":"DuerOS.ConnectedHome.Control", + "name":"ExpiredAccessTokenError", + "payloadVersion":"1", + "messageId":"917314cd-ca00-49ca-b75e-d6f65ac43503" + }, + "payload":{ + } +} +``` + +##### InvalidAccessTokenError +目的:表示用于身份验证的访问令牌(access token)无效,除了已过期的原因。 + +###### Payload + +|Property|Description|Required| +|---|---|---| +| N/A | N/A | N/A | + +InvalidAccessTokenError 例子: +``` +{ + "header":{ + "namespace":"DuerOS.ConnectedHome.Control", + "name":"InvalidAccessTokenError", + "payloadVersion":"1", + "messageId":"917314cd-ca00-49ca-b75e-d6f65ac43503" + }, + "payload":{ + } +} +``` + +##### UnsupportedTargetError +目的:指示Bot不支持目标设备。 + +###### Payload + +|Property|Description|Required| +|---|---|---| +| N/A | N/A | N/A | + +UnsupportedTargetError 例子: +``` +{ + "header":{ + "namespace":"DuerOS.ConnectedHome.Control", + "name":"UnsupportedTargetError", + "payloadVersion":"1", + "messageId":"917314cd-ca00-49ca-b75e-d6f65ac43503" + }, + "payload":{ + } +} +``` + +##### UnsupportedOperationError +目的:表示目标设备不支持请求的操作。 + +###### Payload + +|Property|Description|Required| +|---|---|---| +| N/A | N/A | N/A | + +UnsupportedOperationError 例子: +``` +{ + "header":{ + "namespace":"DuerOS.ConnectedHome.Control", + "name":"UnsupportedOperationError", + "payloadVersion":"1", + "messageId":"917314cd-ca00-49ca-b75e-d6f65ac43503" + }, + "payload":{ + } +} +``` + +##### UnsupportedTargetSettingError +目的:表示所请求的设置对于指定的设备和操作无效。 + +###### Payload + +|Property|Description|Required| +|---|---|---| +| N/A | N/A | N/A | + +UnsupportedTargetSettingError 例子: +``` +{ + "header":{ + "namespace":"DuerOS.ConnectedHome.Control", + "name":"UnsupportedTargetSettingError", + "payloadVersion":"1", + "messageId":"917314cd-ca00-49ca-b75e-d6f65ac43503" + }, + "payload":{ + } +} +``` + +##### UnexpectedInformationReceivedError +目的:由于格式错误,Bot无法处理请求消息。 + +###### Payload + +|Property|Description|Required| +|---|---|---| +| faultingParameter | 请求消息中的属性或字段格式错误,导致Bot无法处理。 | Yes | + +UnexpectedInformationReceivedError 例子: +``` +{ + "header":{ + "namespace":"DuerOS.ConnectedHome.Control", + "name":"UnexpectedInformationReceivedError", + "payloadVersion":"1", + "messageId":"917314cd-ca00-49ca-b75e-d6f65ac43503" + }, + "payload":{ + "faultingParameter": "value" + } +} +```
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/doc/tutorial.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,39 @@ +# 客户端接入指导 + +## Table of Contents + + + * [客户端接入指导](#客户端接入指导) + * [Table of Contents](#table-of-contents) + * [接入流程](#接入流程) + * [协议解析规范](#协议解析规范) + + +## 接入流程 + * 申请度秘appid + * 下载sdk + * 测试服务端效果 + * 用android studio打开sdk demo工程 + * 修改sdk demo中的appid、appkey为自己的 + * 安装到安卓手机,验证效果 + * 集成sdk到自己的app + * 解压duersdk_library.zip + * 导入duersdklib-release.aar到自己的项目 + +## 协议解析规范 + +收到的数据结构,请参考[响应字段解释](api/response.md) + + * 有屏幕的设备 + * 必须实现views数据结构里三种卡片的保底展现 + * 根据需求,如果有返回resource,resource的数据结构只和resource的type有关,和bot_id无关,建议使用resource做更强的展现 + * 建议展现hint中的提示给用户点击 + * 没屏幕的设备 + * 必须实现speech的保底播放 + * 建议在服务端返回directives的情况下,实现directives的操作,详细看下面的“客户端能力的申明和实现” + * 客户端能力的申明和实现 + * 客户端需要申明自己的端能力(device_interface,sdk提供接口设置) + * 如果客户端申明支持某种能力(比如AudioPlayer), + * 必须完整实现上报这种能力所需要的的所有device_event, + * 必须给出获取这种能力的实时状态(device_status)的回调函数 + * 不要依赖bot id做任何客户端逻辑
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/README.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,22 @@ + +### 安装ajv命令行工具(基于node) ### + * 先要安装node,推荐使用[NVM](https://github.com/creationix/nvm/blob/master/README.markdown)进行安装 + * 安装ajv命令行 + +```shell +npm install -g ajv-cli +``` + * 执行test.sh跑测试的数据 + + +### php库 ### +用到了这个第三方库 [PHP implementation of JSON schema](https://github.com/justinrainbow/json-schema) + * 推荐先装composer + +```shell +composer require justinrainbow/json-schema +``` + * 示例程序是test.php + +### C++库 ### +待调研,还没空,可参考 [http://json-schema.org/](http://json-schema.org/)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/appid.json Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,30 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "id":"https://xiaodu.baidu.com/schema/appid.json", + "title":"appid的定义,包含appid对bots的映射", + "type":"array", + "items":{ + "type":"object", + "properties":{ + "bots":{ + "type":"array", + "items":{ + "type":"object", + "properties":{ + "params":{"type":"object","description":"请求bot带上的参数,不作限制"}, + "version":{"type":"string","description":"请求bot的指定版本,默认可填0,就是最新版本"}, + "id":{"type":"string"} + } + } + }, + "appname":{"type":"string"}, + "appid":{"type":"string"}, + "appkey":{"type":"string"}, + "qps":{"type":"integer","description":"每秒最大请求次数"}, + "qpd":{"type":"integer","description":"每天最大请求次数"}, + "ctime":{"type":"integer","description":"创建时间,unix时间戳"}, + "strategy":{"type":"string","description":"排序策略"}, + "version":{"type":"string","description":"客户端版本,一个客户端可按客户端版本不同,存在多份配置"} + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/bots.json Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,71 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "id":"https://xiaodu.baidu.com/schema/bots.json", + "title":"bot列表的定义", + "type":"array", + "items":{ + "type":"object", + "required":["id","server"], + "properties":{ + "id":{"type":"string"}, + "is_session_enable":{"type":"integer"}, + "is_uic_enable":{"type":"integer"}, + "is_base_uic_enable":{"type":"integer"}, + "private_field":{ + "description":"这个估计是调用用户画像服务的参数", + "type":"array", + "items":{"type":"string"} + }, + "server":{ + "oneOf":[ + {"$ref":"#/definitions/ipport_server"}, + {"$ref":"#/definitions/bns_server"} + ] + }, + "sessions":{ + "type":"array", + "items":{ + "type":"object", + "properties":{ + "name":{"type":"string"}, + "type":{"type":"string","enum":["string","list","hash"]}, + "private":{"type":"integer","enum":[0,1]} + } + } + } + } + }, + "definitions": { + "ipport_server":{ + "type":"object", + "required":["machine","protocal","type"], + "properties":{ + "machine":{ + "type":"array", + "items":{ + "type":"object", + "required":["ip","port"], + "properties":{ + "ip":{"type":"string"}, + "port":{"type":"integer"} + } + } + }, + "protocal":{"type":"string","enum":["http","http_post","mcpack"]}, + "type":{"type":"string","enum":["ipport"]} + } + }, + "bns_server":{ + "type":"object", + "required":["protocal","bns_node_name","type"], + "properties":{ + "protocal":{"type":"string","enum":["http","http_post","mcpack"]}, + "bns_node_name":{"type":"string"}, + "bns_timeout": {"type":"integer","description":"单位是毫秒"}, + "bns_node_info_file":{"type":"string","description":"TODO 文件名,还不知道是干什么的,晓鸣也不知道"}, + "type":{"type":"string","enum":["bns"]} + } + } + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/check.sh Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,3 @@ +basepath=$(cd `dirname $0`; pwd) +RESOURCE_SCHEMA="-r $basepath/resource/news.schema.json -r $basepath/resource/music.schema.json -r $basepath/resource/weather.schema.json" +ajv -s $basepath/dumi_schema_loose.json $RESOURCE_SCHEMA -d $1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/composer.json Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,5 @@ +{ + "require": { + "justinrainbow/json-schema": "^4.0" + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/dumi_schema.json Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,208 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "id":"https://xiaodu.baidu.com/schema/dumi_schema.json", + "title":"度秘ws的返回值", + "type": "object", + "properties": { + "result": { + "type":"object", + "properties":{ + "bot_id":{ + "description":"下游服务的id,其实就是老协议里的source_type", + "type":"string" + }, + "bot_meta":{ + "description":"下游服务的信息", + "type":"object", + "required":["type","version"], + "properties":{ + "description":{"type":"string"}, + "type":{"type":"string","enum":["天气","音乐","新闻","其他"]}, + "version":{"type":"string"} + } + }, + "hint":{ + "description":"用户接下去可以输入的query建议", + "type":"array", + "items": { "type": "string" } + }, + "views":{ + "description":"展示用的卡片", + "$ref":"#/definitions/views" + }, + "directives":{ + "description":"展示用的卡片", + "$ref":"#/definitions/directives" + }, + "resource":{ + "description":"数据资源", + "$ref":"#/definitions/resource" + }, + "nlu":{ + "description":"使用的da结果", + "$ref":"#/definitions/nlu" + }, + "speech":{ + "description":"语音播报tts用的数据", + "$ref":"#/definitions/speech" + } + }, + "required": ["views","speech","nlu","bot_id","bot_meta"], + "additionalProperties":false + }, + "time": { + "description":"服务端当前时间戳", + "type":"integer" + }, + "cuid": { + "type":"string" + }, + "user_id": { + "type":"string" + }, + "id": { + "type":"string" + }, + "logid": { + "type":"string" + }, + "se_query": { + "type":"string" + }, + "status": { + "type":"integer" + }, + "client_msg_id": { + "type":"string" + }, + "speech_id": { + "type":"string" + }, + "timeuse": { + "type":"integer" + }, + "msg": { + "type":"string" + } + }, + "definitions": { + "directives": { + "type":"array", + "items":{ + "type":"object", + "properties":{ + "header":{"type":"object"}, + "payload":{"type":"object"} + } + } + }, + "resource": { + "type":"object", + "oneOf":[ + {"$ref":"weather.schema.json"}, + {"$ref":"music.schema.json"}, + {"$ref":"music_ref.schema.json"}, + {"$ref":"news.schema.json"} + ] + }, + "nlu": { + "additionalProperties":false, + "type":"object", + "required": ["domain","intent"], + "properties":{ + "domain":{ + "type":"string" + }, + "intent":{ + "type":"string" + }, + "slots":{ + "type":"object" + } + } + }, + "views": { + "type":"array", + "items":{ + "type":"object", + "oneOf":[ + { + "additionalProperties":false, + "type":"object", + "properties":{ + "type":{ + "type":"string", + "enum":["txt"] + }, + "content":{ + "type":"string" + }, + "url":{ + "type":"string" + } + } + }, + { + "additionalProperties":false, + "type":"object", + "properties":{ + "type":{ + "type":"string", + "enum":["list"] + }, + "list":{ + "type":"array", + "items":{ + "additionalProperties":false, + "type":"object", + "properties":{ + "title":{"type":"string"}, + "summary":{"type":"string"}, + "image":{"type":"string"}, + "url":{"type":"string"} + } + } + } + } + }, + { + "additionalProperties":false, + "type":"object", + "properties":{ + "type":{ + "type":"string", + "enum":["image"] + }, + "list":{ + "type":"array", + "items":{ + "additionalProperties":false, + "type":"object", + "properties":{ + "src":{"type":"string"}, + "thumb":{"type":"string"} + } + } + } + } + } + ] + } + }, + "speech": { + "additionalProperties":false, + "type":"object", + "properties":{ + "type":{ + "type":"string", + "enum":["Text","SSML"] + }, + "content":{ + "type":"string" + } + } + } + }, + "additionalProperties": false, + "required": [ "result","time","id","cuid","logid","se_query","status","msg"] +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/dumi_schema_loose.json Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,202 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "id":"https://xiaodu.baidu.com/schema/dumi_schema.json", + "title":"度秘ws的返回值", + "type": "object", + "properties": { + "result": { + "type":"object", + "properties":{ + "bot_id":{ + "description":"下游服务的id,其实就是老协议里的source_type", + "type":"string" + }, + "bot_meta":{ + "description":"下游服务的信息", + "type":"object", + "required":["type","version"], + "properties":{ + "description":{"type":"string"}, + "type":{"type":"string","enum":["天气","音乐","新闻","其他"]}, + "version":{"type":"string"} + } + }, + "hint":{ + "description":"用户接下去可以输入的query建议", + "type":"array", + "items": { "type": "string" } + }, + "views":{ + "description":"展示用的卡片", + "$ref":"#/definitions/views" + }, + "directives":{ + "description":"展示用的卡片", + "$ref":"#/definitions/directives" + }, + "resource":{ + "description":"数据资源", + "$ref":"#/definitions/resource" + }, + "nlu":{ + "description":"使用的da结果", + "$ref":"#/definitions/nlu" + }, + "speech":{ + "description":"语音播报tts用的数据", + "$ref":"#/definitions/speech" + } + }, + "required": ["views","speech","nlu","bot_id","bot_meta"], + "additionalProperties":false + }, + "time": { + "description":"服务端当前时间戳", + "type":"integer" + }, + "cuid": { + "type":"string" + }, + "user_id": { + "type":"string" + }, + "id": { + "type":"string" + }, + "logid": { + "type":"string" + }, + "se_query": { + "type":"string" + }, + "status": { + "type":"integer" + }, + "msg": { + "type":"string" + } + }, + "definitions": { + "directives": { + "type":"array", + "items":{ + "type":"object", + "properties":{ + "header":{"type":"object"}, + "payload":{"type":"object"} + } + } + }, + "resource": { + "type":"object", + "properties":{ + "type":{ + "type":"string" + }, + "data":{ + "type":"object" + } + } + }, + "nlu": { + "additionalProperties":false, + "type":"object", + "required": ["domain","intent"], + "properties":{ + "domain":{ + "type":"string" + }, + "intent":{ + "type":"string" + }, + "slots":{ + "type":"object" + } + } + }, + "views": { + "type":"array", + "items":{ + "type":"object", + "oneOf":[ + { + "additionalProperties":false, + "type":"object", + "properties":{ + "type":{ + "type":"string", + "enum":["txt"] + }, + "content":{ + "type":"string" + }, + "url":{ + "type":"string" + } + } + }, + { + "additionalProperties":false, + "type":"object", + "properties":{ + "type":{ + "type":"string", + "enum":["list"] + }, + "list":{ + "type":"array", + "items":{ + "additionalProperties":false, + "type":"object", + "properties":{ + "title":{"type":"string"}, + "summary":{"type":"string"}, + "image":{"type":"string"}, + "url":{"type":"string"} + } + } + } + } + }, + { + "additionalProperties":false, + "type":"object", + "properties":{ + "type":{ + "type":"string", + "enum":["image"] + }, + "list":{ + "type":"array", + "items":{ + "additionalProperties":false, + "type":"object", + "properties":{ + "src":{"type":"string"}, + "thumb":{"type":"string"} + } + } + } + } + } + ] + } + }, + "speech": { + "additionalProperties":false, + "type":"object", + "properties":{ + "type":{ + "type":"string", + "enum":["Text","SSML"] + }, + "content":{ + "type":"string" + } + } + } + }, + "additionalProperties": false, + "required": [ "result","time","id","cuid","logid","se_query","status","msg"] +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/resource/music.schema.json Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,113 @@ +{ + "type":"object", + "id":"https://xiaodu.baidu.com/schema/music.schema.json", + "properties":{ + "type":{ + "type":"string", + "enum":["music"] + }, + "data":{ + "type":"object", + "required":["name","singer_name","duration","url","is_need_pay_listen"], + "properties":{ + "name":{ + "description":"歌曲名", + "type":"string" + }, + "duration":{ + "description":"歌曲时常", + "type":"integer" + }, + "alias":{ + "description":"别名", + "type":"string" + }, + "singer_name":{ + "description":"歌手名", + "type":"string" + }, + "all_singer_name":{ + "description":"所有歌手名", + "type":"string" + }, + "genre":{ + "description":"歌曲流派", + "type":"string" + }, + "tag":{ + "description":"歌曲tag", + "type":"string" + }, + "language":{ + "description":"语言", + "type":"string" + }, + "original_singer":{ + "description":"原唱", + "type":"string" + }, + "composer":{ + "description":"作曲", + "type":"string" + }, + "lyricist":{ + "description":"作词", + "type":"string" + }, + "lyric":{ + "description":"歌词内容(可能很长)", + "type":"string" + }, + "url":{ + "description":"h5页面地址", + "type":"string" + }, + "same_name_url":{ + "description":"同名歌曲集合页", + "type":"string" + }, + "streaming_vedio_url":{ + "description":"流媒体url", + "type":"string" + }, + "head_image_url":{ + "description":"歌手名", + "type":"string" + }, + "album_name":{ + "description":"专辑名称", + "type":"string" + }, + "album_url":{ + "description":"专辑地址", + "type":"string" + }, + "score":{ + "description":"歌曲质量得分", + "type":"integer" + }, + "publish_time":{ + "description":"发布时间", + "type":"string" + }, + "publish_company":{ + "description":"唱片公司", + "type":"string" + }, + "is_need_pay_listen":{ + "description":"是否付费收听,0表示否,1表示是", + "type":"integer" + }, + "from_site":{ + "description":"来源站点,1:百度,2:QQ,3:网易云,4:虾米,5:一听,6:酷我", + "type":"integer" + }, + "hot":{ + "description":"热度,现在是播放次数", + "type":"integer" + } + } + } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/resource/music_ref.schema.json Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,35 @@ +{ + "type":"object", + "id":"https://xiaodu.baidu.com/schema/music_ref.schema.json", + "properties":{ + "type":{ + "type":"string", + "enum":["music_ref"] + }, + "data":{ + "type":"object", + "required":["api","media"], + "properties":{ + "api":{ + "type":"object", + "properties":{ + "method":{"type":"string"}, + "url":{"type":"string"} + } + }, + "media":{ + "type":"object", + "properties":{ + "artist":{ + "type":"array", + "items":{"type":"string"} + }, + "type":{"type":"string"} + } + } + } + } + } +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/resource/news.schema.json Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,31 @@ +{ + "type":"object", + "id":"https://xiaodu.baidu.com/schema/news.schema.json", + "properties":{ + "type":{ + "type":"string", + "enum":["news"] + }, + "data":{ + "type":"object", + "properties":{ + "list":{ + "type":"array", + "items":{ + "type":"object", + "properties":{ + "id":{"type":"string"}, + "title":{"type":"string"}, + "summary":{"type":"string"}, + "content":{"type":"string"}, + "url":{"type":"string"}, + "image":{"type":"string"}, + "thumb":{"type":"string"}, + "pubtime":{"type":"string","pattern":"\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}"} + } + } + } + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/resource/weather.schema.json Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,41 @@ +{ + "type":"object", + "id":"https://xiaodu.baidu.com/schema/weather.schema.json", + "properties":{ + "type":{ + "type":"string", + "enum":["weather"] + }, + "data":{ + "type":"object", + "properties":{ + "city":{"type":"string"}, + "current_temp":{"type":"string"}, + "pm25":{"type":"string"}, + "temp":{"type":"string"}, + "time":{"type":"string"}, + "weather":{"type":"string"}, + "weather_all":{"type":"string"}, + "wind":{"type":"string"}, + "weather_info":{ + "type":"array", + "items":{ + "type":"object", + "properties":{ + "current_temp":{"type":"string"} , + "icon":{"type":"string"}, + "pm25":{"type":"string"}, + "pm_level":{"type":"string"}, + "temp":{"type":"string"}, + "time":{"type":"string"}, + "weather":{"type":"string"}, + "wind":{"type":"string"} + } + } + } + + } + } + + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/test.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,44 @@ +<?php +$time1=microtime(true); +require("vendor/autoload.php"); +use JsonSchema\SchemaStorage; +use JsonSchema\Validator; +use JsonSchema\Constraints\Factory; + + +// Schema must be decoded before it can be used for validation +$jsonSchemaObject = json_decode(file_get_contents("dumi_schema.json")); +$newsSchemaObject = json_decode(file_get_contents("resource/news.schema.json")); +$weatherSchemaObject = json_decode(file_get_contents("resource/weather.schema.json")); +$musicSchemaObject = json_decode(file_get_contents("resource/music.schema.json")); + +// The SchemaStorage can resolve references, loading additional schemas from file as needed, etc. +$schemaStorage = new SchemaStorage(); + +// This does two things: +// 1) Mutates $jsonSchemaObject to normalize the references (to file://mySchema#/definitions/integerData, etc) +// 2) Tells $schemaStorage that references to file://mySchema... should be resolved by looking in $jsonSchemaObject +$schemaStorage->addSchema('https://xiaodu.baidu.com/schema/dumi_schema.json', $jsonSchemaObject); +$schemaStorage->addSchema('https://xiaodu.baidu.com/schema/news.schema.json', $newsSchemaObject); +$schemaStorage->addSchema('https://xiaodu.baidu.com/schema/weather.schema.json', $weatherSchemaObject); +$schemaStorage->addSchema('https://xiaodu.baidu.com/schema/music.schema.json', $musicSchemaObject); + +// Provide $schemaStorage to the Validator so that references can be resolved during validation +$jsonValidator = new Validator( new Factory($schemaStorage)); + +// JSON must be decoded before it can be validated +$jsonToValidateObject = json_decode(file_get_contents("testdata/news.json")); +var_dump($jsonToValidateObject); + +// Do validation (use isValid() and getErrors() to check the result) +$jsonValidator->check($jsonToValidateObject, $jsonSchemaObject); + +if ($jsonValidator->isValid()) { + echo "The supplied JSON validates against the schema.\n"; +} else { + echo "JSON does not validate. Violations:\n"; + foreach ($jsonValidator->getErrors() as $error) { + echo sprintf("[%s] %s\n", $error['property'], $error['message']); + } +} +var_dump(microtime(true)-$time1);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/test.sh Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,10 @@ + +RESOURCE_SCHEMA="\ +-r resource/news.schema.json \ +-r resource/music.schema.json \ +-r resource/music_ref.schema.json \ +-r resource/weather.schema.json" +curl --stderr /dev/null 'http://xiaodu.baidu.com/saiya/ws' --data $'{"appid":"dm1597589043374553","appkey":"303177F7740F4572BF52A9CD6642B7EC","sdk_ui":"no","sdk_init":"no","appname":"com.baidu.duersdk.xiaomi","channel_from":"","channel_ctag":"","from_client":"sdk","location_system":"wgs84","hint_id":"","client_msg_id":"c9bfe944-992b-45b1-8afe-dc2cdaee622a","CUID":"test_1497577830189","operation_system":"android","sample_name":"bear_brain_wireless","request_uid":"DAFABB5EBE29BC13C7CBAADBEF6BD166|234418820138768","app_ver":"2.0.0","request_query":"\u6211\u8981\u542c\u6b4c","query_type":"0","debug":"0","longitude":116.3881711235,"latitude":39.9315351235,"speech_id":"12345"}' --compressed>test.json;ajv -s dumi_schema.json $RESOURCE_SCHEMA -d test.json +#ajv -s dumi_schema.json $RESOURCE_SCHEMA -d testdata/weather.json +#ajv -s dumi_schema.json $RESOURCE_SCHEMA -d testdata/news.json +#ajv -s dumi_schema.json $RESOURCE_SCHEMA -d testdata/music.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/test_bots.sh Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,2 @@ +ajv -s bots.json -d testdata/platform/bots.json +ajv -s appid.json -d testdata/platform/appid_bots.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/test_querys Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,736 @@ +周迅老公是谁 +鹿晗是什么星座 +汤姆克鲁斯多大了 +王源是哪一天出生的 +刘雯她有多高呀 +周冬雨真实身高是多少 +刘诗诗毕业于哪里 +周恩来的妻子 +花儿乐队主唱是谁 +成龙的妻子 +麦迪的身高 +张丹峰老婆资料 +杨幂老公介绍 +贾乃亮的女儿资料 +泰勒斯威夫特身高 +包贝尔的妻子 +宋闵浩出生地 +丁志诚年龄 +小小彬今年几岁 +汪峰的生日 +张卫健几岁 +周华健的孩子 +郭达真实身高 +蒋介石父亲是谁 +杨子身高 +angelababy的岁数 +汪涵毕业于哪个学校 +姚明的身高是多少 +林志颖今年多大了 +花儿乐队哪年出道的 +鹿晗今年多大 +贾乃亮的女儿是谁 +成龙的身高是多少 +黄晓明多高 +章子怡现在的国籍 +周迅出生在哪儿 +霍建华多大了 +王鸥的身高 +杨幂的真实身高 +汪涵的老婆是谁 +黄晓明的老婆是谁 +周杰伦的妻子 +章子怡的老公是谁 +甄嬛传中的甄嬛是谁扮演的 +胡可的身高 +李清照的丈夫是谁 +贝克汉姆的妻子是谁 +米兰达可儿的国籍 +米兰达可儿的前夫是谁 +杨幂的老公是谁 +何炅身高 +生活大爆炸中谢尔顿是谁扮演的 +如果蜗牛有爱情中的叶俏是谁扮演的 +沙溢老婆是谁 +曲筱绡是谁演的 +张艺谋的媳妇 +鼓励的近义词 +茕茕孑立的意思是什么 +第三个字是人的成语有哪些 +咄嗟怎么读 +管理的近义词有什么 +含有去的成语有哪些 +创新的反义词有哪些 +包含火的成语 +魑魅魍魉是什么意思 +红开头的成语有什么 +皴字怎么读啊 +带有天的成语有什么 +危言危行指什么 +崩盘是什么意思 +暴殄天物的意思是什么 +燚怎么读 +水开头的成语有哪些 +抵制的反义词有什么 +买椟还珠的意思是什么 +以海开头的成语有哪些 +读书有三到 +寒食东风御柳斜的上一句 +但愿人长久千里共婵娟是什么意思 +蜀道难 +登幽州台歌 +不以物喜不以己悲是什么意思 +行到水穷处的下一句是什么 +小石潭记原文及翻译 +一片冰心在玉壶出处 +锦瑟原文 +离离原上草下一句是什么 +每逢佳节倍思亲的上一句 +林暗草惊风的下一句 +桂魄初生秋露微 +明日复明日下一句 +春晓 +为有源头活水来 +蓬门今始为君开 +望岳 +何当共剪西窗烛 +黄发垂髫并怡然自乐翻译 +两情若是久长时下一句 +行路难全文 +沧海月明珠有泪的下一句 +少小离家老大回全诗 +空山不见人的下一句 +多情自古伤离别出处 +窈窕淑女上一句是什么 +描写秋天的诗句 +东方明珠有多高 +青海湖占地多少面积 +华山的海拔是多少米 +牛肉的热量 +世界上面积最大的国家 +一根油条的热量 +珠穆朗玛峰的海拔多高 +牛油果的热量 +一块巧克力的热量 +牛奶的热量是多少 +1kg的奶油多少热量 +薯条有多少热量 +搭错车的主演有哪些 +王子文在欢乐颂里面演谁 +电视剧何以笙箫默演员表 +花火演员表 +超体的演员表 +大好时光是谁演的 +江一楠的扮演者 +陕西有多少个市 +射阳在哪儿 +西安市的区号是多少 +商洛属于什么省 +土耳其首都是什么 +陕B是哪里的车牌 +景德镇在哪个省 +海淀区的邮编是多少 +英国国旗是啥样的 +邯郸是哪个省的 +澳大利亚的首都 +孟加拉国国旗 +0358是哪里的区号 +阜阳市属于哪个省 +山西省吕梁市的邮编 +奇异博士上映没 +摆渡人具体上映时间 +搜一下大唐玄奘上映时间 +大闹天竺什么时候上映 +摆渡人首映 +记忆大师上映时间 +深海浩劫首映时间 +浮出水面的上映时间 +奇异博士上映时间 +台湾有哪些男明星 +中国白羊座的男明星 +香港男明星的名字 +所有女明星的名字大全 +世界第一高楼 +世界上最大的咸水湖 +中国最高的山 +世界上最大的岛是什么岛 +世界上最大的坦克 +玫瑰属于什么科 +食虫草属于什么科 +昙花的别称 +迷迭香的生长习性 +睡莲的花期 +日轮花的别称 +第一次世界大战是什么时候 +速度与激情7上映时间 +亲爱的公主病多少集 +普京的出生日期 +雀儿山隧道海拔多高 +帮我买张从北京到上海的火车票 +帮我买张火车票 +帮我买张火车票 +我要买火车票 +哪里可以买火车票? +帮我订张高铁票 +帮我订张火车票 +帮我订张动车票 +你能帮我买张火车票吗? +网上买火车票 +买火车票 +给我买张火车票 +哪里能买火车票 +我要坐火车 +火车票 +携程火车票 +我要订火车票 +怎么订火车票 +我要到哪里买火车票 +那些网站可以买火车票? +买一张火车票 +买一张回家的火车票 +给我买张动车票 +我要买动车票 +给我买张高铁票 +帮我查下夜间的车次 +帮我查下靠窗座位的火车票 +代买火车票 +我要明天到北京的火车票 +帮我查下从北京到上海的火车票 +我想要2月3号到武汉的火车票 +到廊坊的火车票要多少钱? +从成都到重庆的火车票 +帮我查下t121火车时刻表 +我在2月15号想去上海,你帮我看看有没有火车票 +北京到上海的火车票多少钱? +有星期天去武汉的火车票吗? +我想去上海,你帮我看看有没有火车票 +有2月14号到上海的火车票吗? +有到上海的火车票吗? +有2月15号去北京的火车票吗? +上海到北京的火车票 +去重庆的火车票 +帮我订一张上海到大理明天晚上的火车票 +我想要北京到杭州的火车票 +杭州到上海火车票价查询 +帮我买张明天下午三点的火车票 +明天上海虹桥火车站到北京的火车票 +给我查一下北京到上海的火车票价格 +这周日从北京到广州的高铁班次 +去深圳的火车票价格 +给我订张上海到北京的火车票 +请帮忙订一张火车票从北京到三亚 +请给我订两张初二回南京的火车票 +我想坐火车去北京 +帮我查一下从北京到上海的火车票 +帮我查一下从北京到上海的火车票有哪些 +买个上海到重庆的火车票 +从上海到太原的火车票还有没有 +帮我预订一张1月2日上海到青岛的火车票 +我需要坐火车来北京 +坐火车上海 +给我买张去北京的高铁票 +春节去上海火车票 +北京的火车票 +明天晚上上海到北京的火车票 +明天晚上上海到北京的火车票 +明天晚上上海到北京的火车票 +明天下午北京到上海的火车票 +我要订上海到北京的火车票 +帮我查查25号上海到武汉的火车票 +帮我订上海到深圳的火车票 +上海到深圳的动车票价 +G1112次火车票 +给我买张到武汉的高铁票 +帮我买张后天到南京的动车票 +到杭州的火车票要多少钱? +从杭州到重庆的火车票 +到重庆的火车票有吗? +上海到北京卧铺多少钱 +上海到北京软卧多少钱 +上海到北京硬座多少钱 +上海到北京动车多少钱 +北京火车南站火车票 +上海到北京的火车班次 +一张到太原的火车票 +帮我找找有没有星期天到北京的火车 +北京到南京火车票,最快的 +我要最快的从上海到北京的火车票 +北京到天津明天最早的火车票是几点的,多少钱 +买张火车票吧 +能帮我买火车票吗 +想买张从重庆去成都的火车票 +能帮我买明天从北京去天津的火车票吗 +下周一的火车票 +帮我订张后天的火车票 +明天去成都的高铁票 +火车票购买 +哪儿能买去成都的动车 +下周三出发去上海的火车票 +明天早上8点提醒我起床 +明早六点提醒我带手机充电器 +中午十一点半提醒我拿菊花茶 +每年10月10日提醒我奶奶生日 +设置提醒每天晚上9点半洗衣服。 +每天下午1点提醒我商标专利 +半小时后叫我起床 +每个工作日早上七点叫醒我 +10月21号早上九点提醒我开会 +每天晚上9点提醒我睡觉。 +10月4号中午十三点提醒我要回家 +一小时后提醒我放冬瓜 +明天下午两点提醒我订票去南京。 +10月22号晚上11点提醒我爱康 +今晚8点40分电话提醒我寄快递和拿快递 +晚上七点提醒我去逛逛桥参加吉他社会员活动要带乐器 +定个闹钟明天早上7点20叫我 +帮我订一个晚上八点钟的闹钟谢谢 +十五分钟后提醒我开会 +10月26号下午提醒我吃喜酒下午四点半 +晚上七点提醒我打钥匙 +周六十一点提醒我香蕉版勺子痒痒挠 +每年的十一月初一提醒贵阳苏豪准备生日礼物 +提醒我两个小时以后起床运动 +下周一早上十一点提醒我联系王妙英 +帮我设置明天上午五点四十的闹铃 +以后每天中午一点提醒我上班儿 +每个月10号上午十点提醒我还信用卡 +明天早上七点半提醒我带银子和还信用卡 +今天晚上十点半提醒我晾衣服 +唱首歌来听 +给我唱首歌吧 +你唱安眠曲给我听哦 +我知道你给我放一首歌 +你给我唱一首歌,我就开心了 +给我见好听的歌 +唱个歌听听 +演员薛之谦 +我要听悲伤逆流成河 +我要听星星这首歌 +你给我唱个歌儿吧 +度秘唱歌 +可以帮我找点好听的歌曲吗 +你会唱歌吗 +bigbang的歌 +给我唱首歌名叫明天会更好 +给我唱首生日歌吧 +哥舅舅你给我唱个歌吧 +我想听爱的传奇 +来一首歌 +唱歌 +播首周杰伦的歌 +给我唱歌来听听呗 +嗯我想听听你的歌 +唱首歌。 +会唱歌吗 +唱首歌给我听吧 +给我唱首歌 +我要听风的季节 +度秘给唱首歌吧 +给我唱一首歌 +我想听一首歌冷酷到底 +听歌曲 +我唱的好听 +好听的歌 +痒 黄龄 +唱首好听的 +再给我唱一只歌 +女人唱首歌吗 +你来唱给我听 +给我唱首歌吧度秘 +唱送别 +微微一笑很倾城歌曲 +度秘唱个歌儿 +你唱个歌吗 +李安的逝去的爱 +给我发个个歌曲 +你唱首黄土高坡的歌给我听 +你会唱歌吗 +我想听歌 +你会唱歌吗 +你会唱歌吗 +唱首李易峰的年少有你 +唱歌听听 +给我唱首歌 +找几首英文歌曲 +给我唱首歌被 +唱歌吧 +给我唱一个没有你陪伴真的好孤单 +唱一首歌 +度秘唱歌 +唱首歌给我宝宝听好吗 +给我唱首歌吗 +你能给我唱歌?吗? +给我唱青春修炼手册 +韩文歌 +我发你给我唱首歌 +你唱一首歌歌歌我听吧 +唱一首歌 +我要听歌 +嗯放个音乐听 +歌曲渴望春天 +度秘你给我唱首歌 +你会唱儿歌吗 +教我唱歌呗 +你要不要我唱给你听呢 +你会唱英文歌吗 +找几首新歌听听 +听歌 +我想听你唱歌 +你给我唱首吧 +给我来首儿歌吧 +你会唱歌 +给老子唱首歌儿 +我想听你唱歌 +那唱首歌给我听 +给我唱一首歌不再见 +最炫民族风凤凰传奇唱 +唱首歌 +你给我唱个歌 +我要听恋人心 +来首薛之谦的歌 +唱首歌吧 +唱个歌 +唱一首歌给我听 +听音乐 +吴亦凡的歌 +有没有阳光点的音乐 +你还会唱什么歌 +你给我唱首歌,我就原谅你 +你给我唱歌 +唱首歌 +我会唱啊我唱给你听呀 +唱一首歌 +我要听那些花儿 +我要听小跳蛙 +我的女儿要你唱一个歌给她听 +你唱首歌吧 +陈小春的补偿 +放首歌听 +我现在想听音乐 +我想听歌曲张惠妹的解脱 +你唱首歌给我们听 +音乐 +播放mc天佑的歌 +唱歌 +唱首歌 +你会唱歌吗 +你唱首歌给我听 +可不可以给我放首歌听 +给我唱一首歌我给说 +我要听歌 +你给我唱首歌吧 +有什么好听的歌 +鹿晗的歌 +度秘推荐几首好听的歌呗 +你唱首歌把 +也可以啊你给我唱首歌 +度秘唱歌 +你给我唱一个 +度秘,我要听钢琴曲 +我想听新世纪音乐 +度秘,我想听说唱歌曲 +我想听度秘唱红歌 +我想听中国风的歌曲 +我想听嘻哈风格的歌 +唱歌给我他 +我想听歌了 +我要听歌 +你唱歌不跑调 +你唱歌不跑调挺好听的 +你唱歌不是挺好的吗 +你长得可不可爱 +懒虫 +你唱歌不好听 +你唱歌不好听呀 +你唱歌超级难听 +你唱歌唱的我真的没法评价了真是太难听了太让我意外了 +你唱歌唱得好好听 +你长得可爱吗 +你唱歌吗 +你唱歌的时候真可爱好逗 +你唱歌的时候好可爱好好听 +你唱歌难听 +你唱歌累了去喝点水睡觉 +你长的是什么 +嗯烦了吧 +你唱歌太难听了 +你唱歌太难听了 +你唱歌我都听不了你还唱 +你唱歌挺好听的 +你唱歌挺好听的哈 +你唱歌挺好听的 +你唱歌挺好听 +你唱歌特别好听 +你长的帅呀 +你长的比大便还要丑362345853542倍你怎么不死呢? +你唱歌好难听 +你唱歌好难听 +你唱歌好难听 +你唱歌好难听 +你唱歌真的唱的好棒 +你唱歌真的挺好听耶 +你长的可真难看 +你唱歌真难听 +你唱歌真难听 +你唱歌真的真的真的很难听 +你唱歌真的好棒好喜欢你 +你唱歌真的很好听 +你长的可真可爱 +你唱歌真好听 +你唱歌真好听 +你唱歌真好听 +你唱歌真好听,也好逗 +你唱歌真好听 +你唱歌好听还是难听呢 +你唱歌好棒啊鼓掌呱唧八戒 +你唱歌好好听哦 +你唱歌好好听 +你唱歌好好听哦 +你唱歌好好听哦 +你唱歌好好听。 +你唱歌好好听 +懒虫 +你唱歌怎么那么难听 +你唱歌带有回声 +你唱歌很好玩 +你唱歌很好听呀 +你烦了,拜拜。 +你长的帮不上美但是你长得非常萌 +你长的太丑了哈哈 +你长得太丑了 +你长的太丑了 +你长的太丑了所以我不喜欢你了我们分手吧 +你长的太丑了 +你长的太丑了 +你长的太丑了 +你长得太丑 +你长的挺漂亮的 +你长的最猥琐了 +你长得挺可爱的 +你长的最可爱了 +你长得像只手表 +你长的特丑是不是 +你长的挺好 +你长得也不错 +嗯长得也帅 +你长的也太可爱了吧 +你长的这么漂亮 +你长得这么难看怎么活下去的 +你长的好看吗哪里好看 +你长的好萌 +你长得这么可爱我怎么不知道 +你长的好嫩 +你充好电没 +你长的好可爱 +你长的好可爱哦 +你长得真的是太有大哥范儿了 +你长的真萌 +你长的真是辣眼睛 +你长的真是太特别了 +你长的真可爱 +你长的一点也不萌 +你长的又丑鼻屎又多还喝一瓶鲜橙多 +你长的怎样 +你长的很矮吗? +你长的很可爱 +你长得很像闹钟挺好 +你长的跟大白一样 +我要打电话 +给庞翔宇打打电话 +给庞翔宇打个电话 +帮我给庞翔宇打个电话 +打个电话给庞翔宇 +打个电话给张凤仪 +给张凤仪打个电话 +给伤者打电话 +给赵明英打电话 +打电话给余中荣 +帮我给我乖乖打电话 +打电话 +打电话给美丽的君君 +打电话给代东华 +拨打陈平电话 +打电话给美丽的君君 +给18730372024打电话 +呼叫119 +打119 +13192285237 +打给小君 +打电话给沙县小吃 +给领导打电话 +打电话给爸爸 +给张宇洁打电话 +给刘梅打电话 +打电话给小鬼 +打开电话给小张打电话 +拨打贤哥 +打电话给朋友a +帮我给光光打电话 +给老婆打电话 +拨打18503769969 +你能帮我打电话给电信吗 +给刘鹏飞打电话 +给孙浩打电话 +打老婆的电话 +拨打电话181028321275 +给张馨元打电话 +打电话给老昌 +打小宝电话 +拨打二哥的电话 +打电话给丽丽哦 +给沈全新打电话 +给沈泉勋打电话 +给陈姐打电话 +打莫志航的电话 +打电话给甲富 +打电话给中国移动 +我要发短信 +给庞翔宇发短信 +给庞翔宇发短信说晚上不回家吃饭了 +帮我给张凤仪发短信说晚上记得加油 +发条短信给张凤仪告诉他晚上记得做饭 +发条短信给庞翔宇 +发短信给王俊华鑫 +发个短信给邱春华跟他讲我睡觉了 +发短信给心雨 +发短信给李新宇 +给马哥员工发短信 +发送短信给老爸 +发短信给杨国震 +给男神发条短信 +给豆豆发条短信 +发短信给苗 +发短信给家里 +我要发短信 +我要发短信给冯姐 +发短信给冯姐啊 +发短信 +给张梅发短信 +发短信给韩义龙 +给张梅发短信在车上等你 +短信发给1514559455 +发短信给魏玮明天一起吃饭 +我要发短信给冯姐 +我要发短信给小糖糖 +我要发短信给冯姐姐 +给李爱华发短信 +发短信给张杰写哈哈 +发短信给刘芳 +发短信给李赛凤 +短信发给15140559455 +发短信给10086 +发短信给策划策划 +我要发短信给小桐桐家妈妈 +发短信给李贞子 +发短信给傅仕勤 +发短信给李真自 +发短信给叶赛凤教他吃饭 +发短信给李贞 +发短信给韩义龙 +庞翔宇的电话号码是多少 +把庞翔宇的电话号码发给张凤仪 +告诉我张凤仪的电话号码 +把张凤仪的电话号码发给庞翔宇 +帮我查下张凤仪的电话号码 +给我看下庞翔宇的电话号码 +北京市天气 +上海市天气 +深圳市天气 +广州市天气 +重庆市天气 +成都市天气 +西安市天气 +南京市天气 +天津市天气 +武汉市天气 +沈阳市天气 +苏州市天气 +杭州市天气 +郑州市天气 +长沙市天气 +合肥市天气 +南昌市天气 +无锡市天气 +青岛市天气 +大连市天气 +厦门市天气 +济南市天气 +哈尔滨市天气 +宁波市天气 +长春市天气 +福州市天气 +石家庄市天气 +昆明市天气 +太原市天气 +常州市天气 +佛山市天气 +扬州市天气 +三亚市天气 +温州市天气 +南宁市天气 +洛阳市天气 +珠海市天气 +南通市天气 +盐城市天气 +乌鲁木齐市天气 +昆山市天气 +丽江市天气 +东莞市天气 +兰州市天气 +淄博市天气 +绍兴市天气 +香港特别行政区天气 +烟台市天气 +镇江市天气 +海口市天气 +银川市天气 +呼和浩特市天气 +湛江市天气 +汕头市天气 +贵阳市天气 +嘉兴市天气 +保定市天气 +秦皇岛市天气 +徐州市天气 +桂林市天气 +鼓浪屿市天气 +潍坊市天气 +绵阳市天气 +株洲市天气 +泰州市天气 +泰安市天气 +威海市天气 +德阳市天气 +泉州市天气 +廊坊市天气 +常熟市天气 +鞍山市天气 +澳门特别行政区天气 +湖州市天气 +大庆市天气 +九江市天气 +中山市天气 +度秘直播nba +度秘聊明星 +聊聊胡歌 +马蓉八卦 +柳岩 +章子怡怀孕 +杨幂被灌醉 +明星八卦 +胡歌八卦 +附近值得去吃的美食 +北京最好的韩国料理 +美味又美型的日本料理店 +附近值得去吃的美食 +换个地点 +选个价位 +换个菜系 +帮我推荐一些适合朋友聚会的餐厅 +附近有哪些餐馆 +找一些有团购的餐厅 +帮我推荐一些口碑好的餐厅 +北京最好吃的北京菜 +http://boscdn.bpc.baidu.com/v1/vs-resource/dumi-1cb69eec820ac0c5d00467260b08665914715787457335.jpg +http://boscdn.bpc.baidu.com/v1/vs-resource/dumi-1abb2dc3d76311944ffdbe9980fbaadd14715788626348.jpg +http://pic.qiantucdn.com/58pic/14/02/62/04i58PICkqb_1024.jpg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/testdata/music.json Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,99 @@ +{ + "status":0, + "msg":"ok", + "se_query":"我要听周杰伦的歌", + "logid":"xxxx1234354", + "id":"id12334235", + "user_id":"", + "cuid":"", + "time":1482226019, + "result":{ + "bot_id":"duer_music", + "bot_meta":{ + "version":"1.0.0", + "type":"音乐" + }, + "views":[ + { + "type":"list", + "list":[ + { + "title": "东方破", + "image": "http://nodeapi.cloudfoundry.com/qrcode.jpg", + "url": "http://nodeapi.cloudfoundry.com/" + }, + { + "title": "双截棍", + "image": "http://nodeapi.cloudfoundry.com/qrcode.jpg", + "url": "http://nodeapi.cloudfoundry.com/" + } + ] + } + ], + "directives":[ + { + "header": { + "namespace": "AudioPlayer", + "name": "Play" + }, + "payload": { + "play_behavior": "REPLACE_ALL", + "audio_item": { + "audio_item_id": "156", + "stream": { + "url": "http://yinyueshiting.baidu.com/data2/music/124088643/124088643.mp3?xcode=57462f29cfc176f86a37d80a2c02fc5b", + "stream_format": "AUDIO_MP3", + "offset_ms": 0, + "token": "156", + "progress_report_interval_ms": 10000 + } + } + } + } + ], + + "nlu": { + "domain": "Audio.Music", + "intent": "Audio.Music.Play", + "slots": { + "singer": "周杰伦" + } + }, + "resource":{ + "type":"music", + "data":{ + "duration":256, + "name":"千里之外", + "alias":"千里外", + "singer_name":"羽泉", + "all_singer_name":"陈羽凡,胡海泉", + "genre":"复古", + "tag":"港台,励志,流行,合唱,摇滚", + "language":"华语", + "original_singer":"周杰伦,费玉清", + "composer":"周杰伦", + "lyricist":"lyricist", + "lyric":"屋檐如悬崖 风铃如沧海 我等燕归来 时间被安排 演一场意外 你悄然走开 故事在城外 浓雾散不开 看不清对白 你听不出来 风声不存在 是我在感慨 梦醒来 是谁在窗台 把结局打开 那薄如蝉翼的未来 经不起谁来拆 我送你离开 千里之外 你无声黑白 沉默年代 或许不该 太遥远的相爱 我送你离开 天涯之外 你是否还在", + "url":"http://music.baidu.com/song/s/04071175dd9085630382f", + "same_name_url":"http://music.baidu.com/search?key=%E4%BD%A0%E5%BF%AB%E5%9B%9E%E6%9D%A5", + "streaming_vedio_url":"http://neisou.baidu.com/images/headportrait/zhangwenbo/0_112.jpg", + "head_image_url":"http://neisou.baidu.com/images/headportrait/zhangwenbo/0_112.jpg", + "album_name":"十一月的肖邦", + "album_url":"http://music.baidu.com/album/234211111", + "score":63, + "publish_time":"2011-09-01", + "publish_company":"飞碟", + "is_need_pay_listen":0, + "from_site":1, + "hot":12345 + } + }, + "speech": { + "type": "Text", + "content": "为您播放周杰伦的歌曲" + } + } +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/testdata/news.json Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,58 @@ +{ + "status":0, + "msg":"ok", + "se_query":"原始query", + "logid":"xxxx1234354", + "id":"id12334235", + "user_id":"", + "cuid":"", + "time":1482226019, + "result":{ + "bot_id":"aries_general", + "bot_meta":{ + "version":"1.0.0", + "type":"新闻" + }, + "views":[], + "nlu": { + "domain": "Audio.Music", + "intent": "Audio.Music.Play", + "slots": { + "singer": "周杰伦" + } + }, + "resource":{ + "type":"news", + "data":{ + "list":[ + { + "id":"xxx1234bbb", + "title":"河北首次启动区域红色应急响应 雾霾笼罩", + "summary":"河北首次启动区域红色应急响应 雾霾笼罩", + "content":"霾是什么?雾是什么?都是怎么形成的?它们的关系是什么?气温丶湿度丶风力丶风向丶地形丶地表丶温湿度丶灰尘丶烟尘丶粉尘丶扬尘那个危害更大,这些都应当弄清了,再谈霾和雾,不要把霾字前加雾字。这本来就是两种截然不同的两种物质。只是它们互相影响而已。把它们混为一谈。就是错的引导。霾在四五年前就已经开始了。只是越来越严重而已。它是随着汽车进入家庭而伴生的。", + "url":"http://headline.baidu.com/doc/detail?app_from=dumi_news&url_key=http%3A//news.163.com/photoview/00AP0001/2216510.html", + "image" : "http://ztd00.photos.bdimg.com/ztd/whfpf%3D160%2C120%2C50%3Bq%3D70/sign=1a96a9f0f41f4134e062563e4322a4fc/d000baa1cd11728bfb98b831c1fcc3cec3fd2c6f.jpg", + "thumb":"http://ztd00.photos.bdimg.com/ztd/whfpf%3D160%2C120%2C50%3Bq%3D70/sign=1a96a9f0f41f4134e062563e4322a4fc/d000baa1cd11728bfb98b831c1fcc3cec3fd2c6f.jpg", + "pubtime":"2016-12-20 20:01:01" + }, + { + "id":"xxx1234bbb", + "title":"河北首次启动区域红色应急响应 雾霾笼罩", + "summary":"河北首次启动区域红色应急响应 雾霾笼罩", + "content":"霾是什么?雾是什么?都是怎么形成的?它们的关系是什么?气温丶湿度丶风力丶风向丶地形丶地表丶温湿度丶灰尘丶烟尘丶粉尘丶扬尘那个危害更大,这些都应当弄清了,再谈霾和雾,不要把霾字前加雾字。这本来就是两种截然不同的两种物质。只是它们互相影响而已。把它们混为一谈。就是错的引导。霾在四五年前就已经开始了。只是越来越严重而已。它是随着汽车进入家庭而伴生的。", + "url":"http://headline.baidu.com/doc/detail?app_from=dumi_news&url_key=http%3A//news.163.com/photoview/00AP0001/2216510.html", + "image":"http://ztd00.photos.bdimg.com/ztd/whfpf%3D160%2C120%2C50%3Bq%3D70/sign=1a96a9f0f41f4134e062563e4322a4fc/d000baa1cd11728bfb98b831c1fcc3cec3fd2c6f.jpg", + "thumb":"http://ztd00.photos.bdimg.com/ztd/whfpf%3D160%2C120%2C50%3Bq%3D70/sign=1a96a9f0f41f4134e062563e4322a4fc/d000baa1cd11728bfb98b831c1fcc3cec3fd2c6f.jpg", + "pubtime":"2016-12-20 20:01:01" + } + ] + } + }, + "speech": { + "type": "Text", + "content": "为您播放周杰伦的歌曲" + } + } +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/testdata/platform/appid_bots.json Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,38 @@ +[ + { + "appname":"小米手机助手", + "appid":"xxxxx", + "appkey":"yyyy", + "qps":50, + "qpd":500000, + "ctime":1474283539, + "strategy":"xiaomi", + "version":"1.0.0", + "bots":[ + {"id":"talk_service","version":"1.0.0"}, + {"id":"aries_general","version":"1.0.0"}, + {"id":"movie_satisfy","version":"1.0.0"}, + {"id":"light_vertical","version":"1.0.0"}, + {"id":"recommend_service_wireless","version":"1.0.0","params":{"joke_type":1}}, + {"id":"restaurant_bot","version":"1.0.0"} + ] + }, + { + "appname":"小米手机助手", + "appid":"xxxxx1", + "appkey":"yyyy1", + "qps":0, + "qpd":0, + "ctime":1474283539, + "strategy":"xiaomi", + "version":"1.0.0", + "bots":[ + {"id":"talk_service","version":"1.0.0"}, + {"id":"aries_general","version":"1.0.0"}, + {"id":"movie_satisfy","version":"1.0.0"}, + {"id":"light_vertical","version":"1.0.0"}, + {"id":"recommend_service_wireless","version":"1.0.0","params":{"joke_type":1}}, + {"id":"restaurant_bot","version":"1.0.0"} + ] + } +]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/testdata/platform/bots.json Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,51 @@ +[ + { + "id":"talk_service", + "is_session_enable":1, + "is_uic_enable":1, + "is_base_uic_enable":1, + "private_field":["identity","family_name"], + "server":{ + "type":"bns", + "protocal":"mcpack", + "bns_node_name": "", + "bns_timeout": 1000, + "bns_node_info_file":"sac_dumi_nj.file" + }, + "sessions":[ + { + "name":"dumi_decision_info", + "type":"string", + "private":0 + }, + { + "name":"phone", + "type":"string", + "private":1 + } + ] + }, + { + "id":"phone", + "is_session_enable":1, + "is_uic_enable":1, + "is_base_uic_enable":1, + "server":{ + "type":"ipport", + "protocal":"http", + "machine":[ + { + "ip":"1.2.3.4", + "port":1234 + } + ] + }, + "sessions":[ + { + "name":"phone", + "type":"hash", + "private":1 + } + ] + } +]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/testdata/weather.json Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,126 @@ +{ + "status":0, + "msg":"ok", + "se_query":"原始query", + "logid":"xxxx1234354", + "id":"id12334235", + "user_id":"", + "cuid":"", + "time":1482226019, + "result":{ + "bot_id":"duer_weather", + "bot_meta":{ + "version":"1.0.0", + "type":"天气" + }, + "views":[ + + { + "type":"txt", + "content":"为你推荐如下热门资讯", + "url":"http://www.baidu.com" + }, + { + "type":"list", + "list":[ + { + "title": "你来我家接我吧", + "summary": "这是女神与高富帅之间的对话", + "image": "http://nodeapi.cloudfoundry.com/qrcode.jpg", + "url": "http://nodeapi.cloudfoundry.com/" + }, + { + "title": "你来我家接我吧", + "summary": "这是女神与高富帅之间的对话", + "image": "http://nodeapi.cloudfoundry.com/qrcode.jpg", + "url": "http://nodeapi.cloudfoundry.com/" + } + ] + }, + { + "type": "image", + "list": [ + { + "src":"http://c.hiphotos.baidu.com/image/pic/item/7af40ad162d9f2d38d7056c8acec8a136327ccb0.jpg", + "thumb":"http://c.hiphotos.baidu.com/image/pic/item/7af40ad162d9f2d38d7056c8acec8a136327ccb0.jpg" + }, + { + "src":"http://b.hiphotos.baidu.com/image/pic/item/b21bb051f8198618df86c5424eed2e738ad4e637.jpg", + "thumb":"http://c.hiphotos.baidu.com/image/pic/item/7af40ad162d9f2d38d7056c8acec8a136327ccb0.jpg" + }, + { + "src":"http://c.hiphotos.baidu.com/image/pic/item/83025aafa40f4bfbc9c817b9074f78f0f63618c6.jpg", + "thumb":"http://c.hiphotos.baidu.com/image/pic/item/7af40ad162d9f2d38d7056c8acec8a136327ccb0.jpg" + } + ] + } + + ], + "nlu": { + "domain": "Audio.Music", + "intent": "Audio.Music.Play", + "slots": { + "singer": "周杰伦" + } + }, + "resource":{ + "type":"weather", + "data":{ + "city": "北京", + "current_temp": "-1℃", + "pm25": "426", + "temp": "-3℃~5℃", + "time": "周二 12月20日", + "weather": "雾", + "weather_all": "雾,-3℃~5℃,微风", + "wind": "微风", + "weather_info": [ + { + "current_temp": "-1℃", + "icon": "http://s1.bdstatic.com/r/www/aladdin/img/new_weath/bigicon/4.png", + "pm25": "426", + "pm_level": "严重污染", + "temp": "-3℃~5℃", + "time": "周二 12月20日", + "weather": "雾", + "wind": "微风" + }, + { + "icon": "http://s1.bdstatic.com/r/www/aladdin/img/new_weath/icon/7.png", + "temp": "-3℃~3℃", + "time": "周三 12月21日", + "weather": "霾", + "wind": "微风" + }, + { + "icon": "http://s1.bdstatic.com/r/www/aladdin/img/new_weath/icon/1.png", + "temp": "-5℃~6℃", + "time": "周四 12月22日", + "weather": "晴", + "wind": "北风3-4级" + }, + { + "icon": "http://s1.bdstatic.com/r/www/aladdin/img/new_weath/icon/1.png", + "temp": "-6℃~3℃", + "time": "周五 12月23日", + "weather": "晴转多云", + "wind": "北风微风" + }, + { + "icon": "http://s1.bdstatic.com/r/www/aladdin/img/new_weath/icon/5.png", + "temp": "-5℃~3℃", + "time": "周六 12月24日", + "weather": "多云转霾", + "wind": "北风微风" + } + ] + } + }, + "speech": { + "type": "Text", + "content": "为您播放周杰伦的歌曲" + } + } +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/autoload.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,7 @@ +<?php + +// autoload.php @generated by Composer + +require_once __DIR__ . '/composer/autoload_real.php'; + +return ComposerAutoloaderInit8c5702c7e02cd3226420dd48de7f52c3::getLoader();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/bin/validate-json Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,1 @@ +../justinrainbow/json-schema/bin/validate-json \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/composer/ClassLoader.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,415 @@ +<?php + +/* + * This file is part of Composer. + * + * (c) Nils Adermann <naderman@naderman.de> + * Jordi Boggiano <j.boggiano@seld.be> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier <fabien@symfony.com> + * @author Jordi Boggiano <j.boggiano@seld.be> + * @see http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + // PSR-4 + private $prefixLengthsPsr4 = array(); + private $prefixDirsPsr4 = array(); + private $fallbackDirsPsr4 = array(); + + // PSR-0 + private $prefixesPsr0 = array(); + private $fallbackDirsPsr0 = array(); + + private $useIncludePath = false; + private $classMap = array(); + private $classMapAuthoritative = false; + private $missingClasses = array(); + + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', $this->prefixesPsr0); + } + + return array(); + } + + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 base directories + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731 + if ('\\' == $class[0]) { + $class = substr($class, 1); + } + + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) { + if (0 === strpos($class, $prefix)) { + foreach ($this->prefixDirsPsr4[$prefix] as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + */ +function includeFile($file) +{ + include $file; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/composer/LICENSE Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,21 @@ + +Copyright (c) 2016 Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/composer/autoload_classmap.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,9 @@ +<?php + +// autoload_classmap.php @generated by Composer + +$vendorDir = dirname(dirname(__FILE__)); +$baseDir = dirname($vendorDir); + +return array( +);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/composer/autoload_namespaces.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,9 @@ +<?php + +// autoload_namespaces.php @generated by Composer + +$vendorDir = dirname(dirname(__FILE__)); +$baseDir = dirname($vendorDir); + +return array( +);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/composer/autoload_psr4.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,10 @@ +<?php + +// autoload_psr4.php @generated by Composer + +$vendorDir = dirname(dirname(__FILE__)); +$baseDir = dirname($vendorDir); + +return array( + 'JsonSchema\\' => array($vendorDir . '/justinrainbow/json-schema/src/JsonSchema'), +);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/composer/autoload_real.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,52 @@ +<?php + +// autoload_real.php @generated by Composer + +class ComposerAutoloaderInit8c5702c7e02cd3226420dd48de7f52c3 +{ + private static $loader; + + public static function loadClassLoader($class) + { + if ('Composer\Autoload\ClassLoader' === $class) { + require __DIR__ . '/ClassLoader.php'; + } + } + + public static function getLoader() + { + if (null !== self::$loader) { + return self::$loader; + } + + spl_autoload_register(array('ComposerAutoloaderInit8c5702c7e02cd3226420dd48de7f52c3', 'loadClassLoader'), true, true); + self::$loader = $loader = new \Composer\Autoload\ClassLoader(); + spl_autoload_unregister(array('ComposerAutoloaderInit8c5702c7e02cd3226420dd48de7f52c3', 'loadClassLoader')); + + $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require_once __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInit8c5702c7e02cd3226420dd48de7f52c3::getInitializer($loader)); + } else { + $map = require __DIR__ . '/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + $loader->set($namespace, $path); + } + + $map = require __DIR__ . '/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + $loader->setPsr4($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->register(true); + + return $loader; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/composer/autoload_static.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,31 @@ +<?php + +// autoload_static.php @generated by Composer + +namespace Composer\Autoload; + +class ComposerStaticInit8c5702c7e02cd3226420dd48de7f52c3 +{ + public static $prefixLengthsPsr4 = array ( + 'J' => + array ( + 'JsonSchema\\' => 11, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'JsonSchema\\' => + array ( + 0 => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema', + ), + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInit8c5702c7e02cd3226420dd48de7f52c3::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit8c5702c7e02cd3226420dd48de7f52c3::$prefixDirsPsr4; + + }, null, ClassLoader::class); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/composer/installed.json Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,70 @@ +[ + { + "name": "justinrainbow/json-schema", + "version": "4.0.1", + "version_normalized": "4.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/justinrainbow/json-schema.git", + "reference": "10d1f6977f6be5f177dded8f585a11debdc27591" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/10d1f6977f6be5f177dded8f585a11debdc27591", + "reference": "10d1f6977f6be5f177dded8f585a11debdc27591", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "json-schema/json-schema-test-suite": "1.2.0", + "phpdocumentor/phpdocumentor": "~2", + "phpunit/phpunit": "^4.8.22" + }, + "time": "2016-11-09 16:32:33", + "bin": [ + "bin/validate-json" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "JsonSchema\\": "src/JsonSchema/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bruno Prieto Reis", + "email": "bruno.p.reis@gmail.com" + }, + { + "name": "Justin Rainbow", + "email": "justin.rainbow@gmail.com" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Robert Schönthal", + "email": "seroscho@googlemail.com" + } + ], + "description": "A library to validate a json schema.", + "homepage": "https://github.com/justinrainbow/json-schema", + "keywords": [ + "json", + "schema" + ] + } +]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/.gitattributes Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,5 @@ +/docs export-ignore +/tests export-ignore +.gitignore export-ignore +.travis.yml export-ignore +phpunit.dist.xml export-ignore
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/LICENSE Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/README.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,136 @@ +# JSON Schema for PHP + +[![Build Status](https://travis-ci.org/justinrainbow/json-schema.svg?branch=master)](https://travis-ci.org/justinrainbow/json-schema) +[![Latest Stable Version](https://poser.pugx.org/justinrainbow/json-schema/v/stable.png)](https://packagist.org/packages/justinrainbow/json-schema) +[![Total Downloads](https://poser.pugx.org/justinrainbow/json-schema/downloads.png)](https://packagist.org/packages/justinrainbow/json-schema) + +A PHP Implementation for validating `JSON` Structures against a given `Schema`. + +See [json-schema](http://json-schema.org/) for more details. + +## Installation + +### Library + + $ git clone https://github.com/justinrainbow/json-schema.git + +### Dependencies + +#### [`Composer`](https://github.com/composer/composer) (*will use the Composer ClassLoader*) + + $ wget http://getcomposer.org/composer.phar + $ php composer.phar require justinrainbow/json-schema:~2.0 + +## Usage + +### Basic usage + +```php +<?php + +$data = json_decode(file_get_contents('data.json')); + +// Validate +$validator = new JsonSchema\Validator; +$validator->check($data, (object)['$ref' => 'file://' . realpath('schema.json')]); + +if ($validator->isValid()) { + echo "The supplied JSON validates against the schema.\n"; +} else { + echo "JSON does not validate. Violations:\n"; + foreach ($validator->getErrors() as $error) { + echo sprintf("[%s] %s\n", $error['property'], $error['message']); + } +} +``` +###Type Coercion +If you're validating data passed to your application via HTTP, you can cast strings and booleans to the expected types defined by your schema: +```php +use JsonSchema\SchemaStorage; +use JsonSchema\Validator; +use JsonSchema\Constraints\Factory; +use JsonSchema\Constraints\Constraint; + +$request = (object)[ + 'processRefund'=>"true", + 'refundAmount'=>"17" +]; + +$factory = new Factory( null, null, Constraint::CHECK_MODE_TYPE_CAST | Constraint::CHECK_MODE_COERCE ); + +$validator = new Validator($factory); +$validator->check($request, (object) [ + "type"=>"object", + "properties"=>(object)[ + "processRefund"=>(object)[ + "type"=>"boolean" + ], + "refundAmount"=>(object)[ + "type"=>"number" + ] + ] +]); // validates! + +is_bool($request->processRefund); // true +is_int($request->refundAmount); // true +``` + +Note that the ```CHECK_MODE_COERCE``` flag will only take effect when an object is passed into the ```check``` method. + +### With inline references + +```php +<?php + +use JsonSchema\SchemaStorage; +use JsonSchema\Validator; +use JsonSchema\Constraints\Factory; + +$jsonSchema = <<<'JSON' +{ + "type": "object", + "properties": { + "data": { + "oneOf": [ + { "$ref": "#/definitions/integerData" }, + { "$ref": "#/definitions/stringData" } + ] + } + }, + "required": ["data"], + "definitions": { + "integerData" : { + "type": "integer", + "minimum" : 0 + }, + "stringData" : { + "type": "string" + } + } +} +JSON; + +// Schema must be decoded before it can be used for validation +$jsonSchemaObject = json_decode($jsonSchema); + +// The SchemaStorage can resolve references, loading additional schemas from file as needed, etc. +$schemaStorage = new SchemaStorage(); + +// This does two things: +// 1) Mutates $jsonSchemaObject to normalize the references (to file://mySchema#/definitions/integerData, etc) +// 2) Tells $schemaStorage that references to file://mySchema... should be resolved by looking in $jsonSchemaObject +$schemaStorage->addSchema('file://mySchema', $jsonSchemaObject); + +// Provide $schemaStorage to the Validator so that references can be resolved during validation +$jsonValidator = new Validator( new Factory($schemaStorage)); + +// JSON must be decoded before it can be validated +$jsonToValidateObject = json_decode('{"data":123}'); + +// Do validation (use isValid() and getErrors() to check the result) +$jsonValidator->check($jsonToValidateObject, $jsonSchemaObject); +``` + +## Running the tests + + $ vendor/bin/phpunit
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/bin/validate-json Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,237 @@ +#!/usr/bin/env php +<?php +/** + * JSON schema validator + * + * @author Christian Weiske <christian.weiske@netresearch.de> + */ + +/** + * Dead simple autoloader + * + * @param string $className Name of class to load + * + * @return void + */ +function __autoload($className) +{ + $className = ltrim($className, '\\'); + $fileName = ''; + $namespace = ''; + if ($lastNsPos = strrpos($className, '\\')) { + $namespace = substr($className, 0, $lastNsPos); + $className = substr($className, $lastNsPos + 1); + $fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR; + } + $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php'; + if (stream_resolve_include_path($fileName)) { + require_once $fileName; + } +} + +/** + * Show the json parse error that happened last + * + * @return void + */ +function showJsonError() +{ + $constants = get_defined_constants(true); + $json_errors = array(); + foreach ($constants['json'] as $name => $value) { + if (!strncmp($name, 'JSON_ERROR_', 11)) { + $json_errors[$value] = $name; + } + } + + echo 'JSON parse error: ' . $json_errors[json_last_error()] . "\n"; +} + +function getUrlFromPath($path) +{ + if (parse_url($path, PHP_URL_SCHEME) !== null) { + //already an URL + return $path; + } + if ($path{0} == '/') { + //absolute path + return 'file://' . $path; + } + + //relative path: make absolute + return 'file://' . getcwd() . '/' . $path; +} + +/** + * Take a HTTP header value and split it up into parts. + * + * @param $headerValue + * @return array Key "_value" contains the main value, all others + * as given in the header value + */ +function parseHeaderValue($headerValue) +{ + if (strpos($headerValue, ';') === false) { + return array('_value' => $headerValue); + } + + $parts = explode(';', $headerValue); + $arData = array('_value' => array_shift($parts)); + foreach ($parts as $part) { + list($name, $value) = explode('=', $part); + $arData[$name] = trim($value, ' "\''); + } + return $arData; +} + + +// support running this tool from git checkout +if (is_dir(__DIR__ . '/../src/JsonSchema')) { + set_include_path(__DIR__ . '/../src' . PATH_SEPARATOR . get_include_path()); +} + +$arOptions = array(); +$arArgs = array(); +array_shift($argv);//script itself +foreach ($argv as $arg) { + if ($arg{0} == '-') { + $arOptions[$arg] = true; + } else { + $arArgs[] = $arg; + } +} + +if (count($arArgs) == 0 + || isset($arOptions['--help']) || isset($arOptions['-h']) +) { + echo <<<HLP +Validate schema +Usage: validate-json data.json + or: validate-json data.json schema.json + +Options: + --dump-schema Output full schema and exit + --dump-schema-url Output URL of schema + -h --help Show this help + +HLP; + exit(1); +} + +if (count($arArgs) == 1) { + $pathData = $arArgs[0]; + $pathSchema = null; +} else { + $pathData = $arArgs[0]; + $pathSchema = getUrlFromPath($arArgs[1]); +} + +$urlData = getUrlFromPath($pathData); + +$context = stream_context_create( + array( + 'http' => array( + 'header' => array( + 'Accept: */*', + 'Connection: Close' + ), + 'max_redirects' => 5 + ) + ) +); +$dataString = file_get_contents($pathData, false, $context); +if ($dataString == '') { + echo "Data file is not readable or empty.\n"; + exit(3); +} + +$data = json_decode($dataString); +unset($dataString); +if ($data === null) { + echo "Error loading JSON data file\n"; + showJsonError(); + exit(5); +} + +if ($pathSchema === null) { + if (isset($http_response_header)) { + array_shift($http_response_header);//HTTP/1.0 line + foreach ($http_response_header as $headerLine) { + list($hName, $hValue) = explode(':', $headerLine, 2); + $hName = strtolower($hName); + if ($hName == 'link') { + //Link: <http://example.org/schema#>; rel="describedBy" + $hParts = parseHeaderValue($hValue); + if (isset($hParts['rel']) && $hParts['rel'] == 'describedBy') { + $pathSchema = trim($hParts['_value'], ' <>'); + } + } else if ($hName == 'content-type') { + //Content-Type: application/my-media-type+json; + // profile=http://example.org/schema# + $hParts = parseHeaderValue($hValue); + if (isset($hParts['profile'])) { + $pathSchema = $hParts['profile']; + } + + } + } + } + if (is_object($data) && property_exists($data, '$schema')) { + $pathSchema = $data->{'$schema'}; + } + + //autodetect schema + if ($pathSchema === null) { + echo "JSON data must be an object and have a \$schema property.\n"; + echo "You can pass the schema file on the command line as well.\n"; + echo "Schema autodetection failed.\n"; + exit(6); + } +} +if ($pathSchema{0} == '/') { + $pathSchema = 'file://' . $pathSchema; +} + +$resolver = new JsonSchema\Uri\UriResolver(); +$retriever = new JsonSchema\Uri\UriRetriever(); +try { + $urlSchema = $resolver->resolve($pathSchema, $urlData); + + if (isset($arOptions['--dump-schema-url'])) { + echo $urlSchema . "\n"; + exit(); + } +} catch (Exception $e) { + echo "Error loading JSON schema file\n"; + echo $urlSchema . "\n"; + echo $e->getMessage() . "\n"; + exit(2); +} +$refResolver = new JsonSchema\RefResolver($retriever, $resolver); +$schema = $refResolver->resolve($urlSchema); + +if (isset($arOptions['--dump-schema'])) { + $options = defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : 0; + echo json_encode($schema, $options) . "\n"; + exit(); +} + +try { + $validator = new JsonSchema\Validator(); + $validator->check($data, $schema); + + if ($validator->isValid()) { + echo "OK. The supplied JSON validates against the schema.\n"; + } else { + echo "JSON does not validate. Violations:\n"; + foreach ($validator->getErrors() as $error) { + echo sprintf("[%s] %s\n", $error['property'], $error['message']); + } + exit(23); + } +} catch (Exception $e) { + echo "JSON does not validate. Error:\n"; + echo $e->getMessage() . "\n"; + echo "Error code: " . $e->getCode() . "\n"; + exit(24); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/composer.json Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,62 @@ +{ + "name": "justinrainbow/json-schema", + "description": "A library to validate a json schema.", + "keywords": ["json", "schema"], + "homepage": "https://github.com/justinrainbow/json-schema", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Bruno Prieto Reis", + "email": "bruno.p.reis@gmail.com" + }, + { + "name": "Justin Rainbow", + "email": "justin.rainbow@gmail.com" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Robert Schönthal", + "email": "seroscho@googlemail.com" + } + ], + "repositories": [{ + "type": "package", + "package": { + "name": "json-schema/JSON-Schema-Test-Suite", + "version": "1.2.0", + "source": { + "url": "https://github.com/json-schema/JSON-Schema-Test-Suite", + "type": "git", + "reference": "1.2.0" + } + } + }], + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "json-schema/JSON-Schema-Test-Suite": "1.2.0", + "phpunit/phpunit": "^4.8.22", + "phpdocumentor/phpdocumentor": "~2" + }, + "autoload": { + "psr-4": { "JsonSchema\\": "src/JsonSchema/" } + }, + "autoload-dev": { + "psr-4": { "JsonSchema\\Tests\\": "tests/" } + }, + "bin": ["bin/validate-json"], + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "scripts": { + "test" : "vendor/bin/phpunit", + "coverage" : "vendor/bin/phpunit --coverage-text" + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/demo/README.md Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,14 @@ +## JsonSchema\Validator Demo + +This demo script uses the example from the root README.md and provides sample JSON files for testing `JsonSchema\Validator`. + +To change or replace the JSON schema document, please edit `/path/to/json-schema/demo/schema.json`. + +To change or replace the JSON document that is validated, please edit `/path/to/json-schema/demo/data.json`. + +To run the demo, change the path in the following example and run it in your terminal. + +``` +cd /path/to/json-schema/demo +php demo.php // The supplied JSON validates against the schema. +```
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/demo/data.json Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,3 @@ +{ + "foo":"bar" +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/demo/demo.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,17 @@ +<?php +require(__DIR__ . '/../vendor/autoload.php'); + +$data = json_decode(file_get_contents('data.json')); + +// Validate +$validator = new JsonSchema\Validator; +$validator->check($data, (object)['$ref' => 'file://' . realpath('schema.json')]); + +if ($validator->isValid()) { + echo "The supplied JSON validates against the schema.\n"; +} else { + echo "JSON does not validate. Violations:\n"; + foreach ($validator->getErrors() as $error) { + echo sprintf("[%s] %s\n", $error['property'], $error['message']); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/demo/schema.json Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,3 @@ +{ + "type": "object" +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/phpunit.xml.dist Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<phpunit backupGlobals="false" + backupStaticAttributes="false" + colors="true" + convertErrorsToExceptions="true" + convertNoticesToExceptions="true" + convertWarningsToExceptions="true" + processIsolation="false" + stopOnFailure="false" + syntaxCheck="false" + bootstrap="vendor/autoload.php" + verbose="true" +> + <testsuites> + <testsuite name="JSON Schema Test Suite"> + <directory>tests</directory> + </testsuite> + </testsuites> + + <filter> + <whitelist> + <directory>./src/JsonSchema/</directory> + </whitelist> + </filter> +</phpunit>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/CollectionConstraint.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,114 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Constraints; + +use JsonSchema\Entity\JsonPointer; + +/** + * The CollectionConstraint Constraints, validates an array against a given schema + * + * @author Robert Schönthal <seroscho@googlemail.com> + * @author Bruno Prieto Reis <bruno.p.reis@gmail.com> + */ +class CollectionConstraint extends Constraint +{ + /** + * {@inheritDoc} + */ + public function check($value, $schema = null, JsonPointer $path = null, $i = null) + { + // Verify minItems + if (isset($schema->minItems) && count($value) < $schema->minItems) { + $this->addError($path, "There must be a minimum of " . $schema->minItems . " items in the array", 'minItems', array('minItems' => $schema->minItems,)); + } + + // Verify maxItems + if (isset($schema->maxItems) && count($value) > $schema->maxItems) { + $this->addError($path, "There must be a maximum of " . $schema->maxItems . " items in the array", 'maxItems', array('maxItems' => $schema->maxItems,)); + } + + // Verify uniqueItems + if (isset($schema->uniqueItems) && $schema->uniqueItems) { + $unique = $value; + if (is_array($value) && count($value)) { + $unique = array_map(function($e) { return var_export($e, true); }, $value); + } + if (count(array_unique($unique)) != count($value)) { + $this->addError($path, "There are no duplicates allowed in the array", 'uniqueItems'); + } + } + + // Verify items + if (isset($schema->items)) { + $this->validateItems($value, $schema, $path, $i); + } + } + + /** + * Validates the items + * + * @param array $value + * @param \stdClass $schema + * @param JsonPointer|null $path + * @param string $i + */ + protected function validateItems($value, $schema = null, JsonPointer $path = null, $i = null) + { + if (is_object($schema->items)) { + // just one type definition for the whole array + foreach ($value as $k => $v) { + $initErrors = $this->getErrors(); + + // First check if its defined in "items" + $this->checkUndefined($v, $schema->items, $path, $k); + + // Recheck with "additionalItems" if the first test fails + if (count($initErrors) < count($this->getErrors()) && (isset($schema->additionalItems) && $schema->additionalItems !== false)) { + $secondErrors = $this->getErrors(); + $this->checkUndefined($v, $schema->additionalItems, $path, $k); + } + + // Reset errors if needed + if (isset($secondErrors) && count($secondErrors) < count($this->getErrors())) { + $this->errors = $secondErrors; + } elseif (isset($secondErrors) && count($secondErrors) === count($this->getErrors())) { + $this->errors = $initErrors; + } + } + } else { + // Defined item type definitions + foreach ($value as $k => $v) { + if (array_key_exists($k, $schema->items)) { + $this->checkUndefined($v, $schema->items[$k], $path, $k); + } else { + // Additional items + if (property_exists($schema, 'additionalItems')) { + if ($schema->additionalItems !== false) { + $this->checkUndefined($v, $schema->additionalItems, $path, $k); + } else { + $this->addError( + $path, 'The item ' . $i . '[' . $k . '] is not defined and the definition does not allow additional items', 'additionalItems', array('additionalItems' => $schema->additionalItems,)); + } + } else { + // Should be valid against an empty schema + $this->checkUndefined($v, new \stdClass(), $path, $k); + } + } + } + + // Treat when we have more schema definitions than values, not for empty arrays + if (count($value) > 0) { + for ($k = count($value); $k < count($schema->items); $k++) { + $this->checkUndefined($this->factory->createInstanceFor('undefined'), $schema->items[$k], $path, $k); + } + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Constraint.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,274 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Constraints; + +use JsonSchema\SchemaStorage; +use JsonSchema\Uri\UriRetriever; +use JsonSchema\UriRetrieverInterface; +use JsonSchema\Entity\JsonPointer; + +/** + * The Base Constraints, all Validators should extend this class + * + * @author Robert Schönthal <seroscho@googlemail.com> + * @author Bruno Prieto Reis <bruno.p.reis@gmail.com> + */ +abstract class Constraint implements ConstraintInterface +{ + protected $errors = array(); + protected $inlineSchemaProperty = '$schema'; + + const CHECK_MODE_NORMAL = 0x00000001; + const CHECK_MODE_TYPE_CAST = 0x00000002; + const CHECK_MODE_COERCE = 0x00000004; + + /** + * @var Factory + */ + protected $factory; + + /** + * @param Factory $factory + */ + public function __construct(Factory $factory = null) + { + $this->factory = $factory ? : new Factory(); + } + + /** + * {@inheritDoc} + */ + public function addError(JsonPointer $path = null, $message, $constraint='', array $more=null) + { + $error = array( + 'property' => $this->convertJsonPointerIntoPropertyPath($path ?: new JsonPointer('')), + 'pointer' => ltrim(strval($path ?: new JsonPointer('')), '#'), + 'message' => $message, + 'constraint' => $constraint, + ); + + if (is_array($more) && count($more) > 0) + { + $error += $more; + } + + $this->errors[] = $error; + } + + /** + * {@inheritDoc} + */ + public function addErrors(array $errors) + { + if ($errors) { + $this->errors = array_merge($this->errors, $errors); + } + } + + /** + * {@inheritDoc} + */ + public function getErrors() + { + return $this->errors; + } + + /** + * {@inheritDoc} + */ + public function isValid() + { + return !$this->getErrors(); + } + + /** + * Clears any reported errors. Should be used between + * multiple validation checks. + */ + public function reset() + { + $this->errors = array(); + } + + /** + * Bubble down the path + * + * @param JsonPointer|null $path Current path + * @param mixed $i What to append to the path + * + * @return JsonPointer; + */ + protected function incrementPath(JsonPointer $path = null, $i) + { + $path = $path ?: new JsonPointer(''); + $path = $path->withPropertyPaths( + array_merge( + $path->getPropertyPaths(), + array_filter(array($i), 'strlen') + ) + ); + return $path; + } + + /** + * Validates an array + * + * @param mixed $value + * @param mixed $schema + * @param JsonPointer|null $path + * @param mixed $i + */ + protected function checkArray($value, $schema = null, JsonPointer $path = null, $i = null) + { + $validator = $this->factory->createInstanceFor('collection'); + $validator->check($value, $schema, $path, $i); + + $this->addErrors($validator->getErrors()); + } + + /** + * Validates an object + * + * @param mixed $value + * @param mixed $schema + * @param JsonPointer|null $path + * @param mixed $i + * @param mixed $patternProperties + */ + protected function checkObject($value, $schema = null, JsonPointer $path = null, $i = null, $patternProperties = null) + { + $validator = $this->factory->createInstanceFor('object'); + $validator->check($value, $schema, $path, $i, $patternProperties); + + $this->addErrors($validator->getErrors()); + } + + /** + * Validates the type of a property + * + * @param mixed $value + * @param mixed $schema + * @param JsonPointer|null $path + * @param mixed $i + */ + protected function checkType($value, $schema = null, JsonPointer $path = null, $i = null) + { + $validator = $this->factory->createInstanceFor('type'); + $validator->check($value, $schema, $path, $i); + + $this->addErrors($validator->getErrors()); + } + + /** + * Checks a undefined element + * + * @param mixed $value + * @param mixed $schema + * @param JsonPointer|null $path + * @param mixed $i + */ + protected function checkUndefined($value, $schema = null, JsonPointer $path = null, $i = null) + { + $validator = $this->factory->createInstanceFor('undefined'); + + $validator->check($value, $this->factory->getSchemaStorage()->resolveRefSchema($schema), $path, $i); + + $this->addErrors($validator->getErrors()); + } + + /** + * Checks a string element + * + * @param mixed $value + * @param mixed $schema + * @param JsonPointer|null $path + * @param mixed $i + */ + protected function checkString($value, $schema = null, JsonPointer $path = null, $i = null) + { + $validator = $this->factory->createInstanceFor('string'); + $validator->check($value, $schema, $path, $i); + + $this->addErrors($validator->getErrors()); + } + + /** + * Checks a number element + * + * @param mixed $value + * @param mixed $schema + * @param JsonPointer $path + * @param mixed $i + */ + protected function checkNumber($value, $schema = null, JsonPointer $path = null, $i = null) + { + $validator = $this->factory->createInstanceFor('number'); + $validator->check($value, $schema, $path, $i); + + $this->addErrors($validator->getErrors()); + } + + /** + * Checks a enum element + * + * @param mixed $value + * @param mixed $schema + * @param JsonPointer|null $path + * @param mixed $i + */ + protected function checkEnum($value, $schema = null, JsonPointer $path = null, $i = null) + { + $validator = $this->factory->createInstanceFor('enum'); + $validator->check($value, $schema, $path, $i); + + $this->addErrors($validator->getErrors()); + } + + /** + * Checks format of an element + * + * @param mixed $value + * @param mixed $schema + * @param JsonPointer|null $path + * @param mixed $i + */ + protected function checkFormat($value, $schema = null, JsonPointer $path = null, $i = null) + { + $validator = $this->factory->createInstanceFor('format'); + $validator->check($value, $schema, $path, $i); + + $this->addErrors($validator->getErrors()); + } + + /** + * Get the type check based on the set check mode. + * + * @return TypeCheck\TypeCheckInterface + */ + protected function getTypeCheck() + { + return $this->factory->getTypeCheck(); + } + + /** + * @param JsonPointer $pointer + * @return string property path + */ + protected function convertJsonPointerIntoPropertyPath(JsonPointer $pointer) + { + $result = array_map( + function($path) { + return sprintf(is_numeric($path) ? '[%d]' : '.%s', $path); + }, + $pointer->getPropertyPaths() + ); + return trim(implode('', $result), '.'); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ConstraintInterface.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,63 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Constraints; + +use JsonSchema\Entity\JsonPointer; + +/** + * The Constraints Interface + * + * @author Robert Schönthal <seroscho@googlemail.com> + */ +interface ConstraintInterface +{ + /** + * returns all collected errors + * + * @return array + */ + public function getErrors(); + + /** + * adds errors to this validator + * + * @param array $errors + */ + public function addErrors(array $errors); + + /** + * adds an error + * + * @param JsonPointer|null $path + * @param string $message + * @param string $constraint the constraint/rule that is broken, e.g.: 'minLength' + * @param array $more more array elements to add to the error + */ + public function addError(JsonPointer $path = null, $message, $constraint='', array $more=null); + + /** + * checks if the validator has not raised errors + * + * @return boolean + */ + public function isValid(); + + /** + * invokes the validation of an element + * + * @abstract + * @param mixed $value + * @param mixed $schema + * @param JsonPointer|null $path + * @param mixed $i + * @throws \JsonSchema\Exception\ExceptionInterface + */ + public function check($value, $schema = null, JsonPointer $path = null, $i = null); +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/EnumConstraint.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,53 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Constraints; +use JsonSchema\Entity\JsonPointer; + +/** + * The EnumConstraint Constraints, validates an element against a given set of possibilities + * + * @author Robert Schönthal <seroscho@googlemail.com> + * @author Bruno Prieto Reis <bruno.p.reis@gmail.com> + */ +class EnumConstraint extends Constraint +{ + /** + * {@inheritDoc} + */ + public function check($element, $schema = null, JsonPointer $path = null, $i = null) + { + // Only validate enum if the attribute exists + if ($element instanceof UndefinedConstraint && (!isset($schema->required) || !$schema->required)) { + return; + } + $type = gettype($element); + + foreach ($schema->enum as $enum) { + $enumType = gettype($enum); + if (($this->factory->getCheckMode() & self::CHECK_MODE_TYPE_CAST) && $type == "array" && $enumType == "object") { + if ((object)$element == $enum) { + return; + } + } + + if ($type === gettype($enum)) { + if ($type == "object") { + if ($element == $enum) { + return; + } + } elseif ($element === $enum) { + return; + } + } + } + + $this->addError($path, "Does not have a value in the enumeration " . json_encode($schema->enum), 'enum', array('enum' => $schema->enum,)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Factory.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,150 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Constraints; + +use JsonSchema\Exception\InvalidArgumentException; +use JsonSchema\SchemaStorage; +use JsonSchema\Uri\UriRetriever; +use JsonSchema\UriRetrieverInterface; + +/** + * Factory for centralize constraint initialization. + */ +class Factory +{ + /** + * @var SchemaStorage + */ + protected $schemaStorage; + + /** + * @var UriRetriever $uriRetriever + */ + protected $uriRetriever; + + /** + * @var int + */ + private $checkMode; + + /** + * @var TypeCheck\TypeCheckInterface[] + */ + private $typeCheck = array(); + + /** + * @var array $constraintMap + */ + protected $constraintMap = array( + 'array' => 'JsonSchema\Constraints\CollectionConstraint', + 'collection' => 'JsonSchema\Constraints\CollectionConstraint', + 'object' => 'JsonSchema\Constraints\ObjectConstraint', + 'type' => 'JsonSchema\Constraints\TypeConstraint', + 'undefined' => 'JsonSchema\Constraints\UndefinedConstraint', + 'string' => 'JsonSchema\Constraints\StringConstraint', + 'number' => 'JsonSchema\Constraints\NumberConstraint', + 'enum' => 'JsonSchema\Constraints\EnumConstraint', + 'format' => 'JsonSchema\Constraints\FormatConstraint', + 'schema' => 'JsonSchema\Constraints\SchemaConstraint', + 'validator' => 'JsonSchema\Validator', + 'coercer' => 'JsonSchema\Coerce' + ); + + /** + * @var array<ConstraintInterface> + */ + private $instanceCache = array(); + + /** + * @param SchemaStorage $schemaStorage + * @param UriRetrieverInterface $uriRetriever + * @param int $checkMode + */ + public function __construct( + SchemaStorage $schemaStorage = null, + UriRetrieverInterface $uriRetriever = null, + $checkMode = Constraint::CHECK_MODE_NORMAL + ) { + $this->uriRetriever = $uriRetriever ?: new UriRetriever; + $this->schemaStorage = $schemaStorage ?: new SchemaStorage($this->uriRetriever); + $this->checkMode = $checkMode; + } + + /** + * @return UriRetrieverInterface + */ + public function getUriRetriever() + { + return $this->uriRetriever; + } + + public function getSchemaStorage() + { + return $this->schemaStorage; + } + + public function getTypeCheck() + { + if (!isset($this->typeCheck[$this->checkMode])) { + $this->typeCheck[$this->checkMode] = ($this->checkMode & Constraint::CHECK_MODE_TYPE_CAST) + ? new TypeCheck\LooseTypeCheck + : new TypeCheck\StrictTypeCheck; + } + + return $this->typeCheck[$this->checkMode]; + } + + /** + * @param string $name + * @param string $class + * @return Factory + */ + public function setConstraintClass($name, $class) + { + // Ensure class exists + if (!class_exists($class)) { + throw new InvalidArgumentException('Unknown constraint ' . $name); + } + // Ensure class is appropriate + if (!in_array('JsonSchema\Constraints\ConstraintInterface', class_implements($class))) { + throw new InvalidArgumentException('Invalid class ' . $name); + } + $this->constraintMap[$name] = $class; + return $this; + } + + /** + * Create a constraint instance for the given constraint name. + * + * @param string $constraintName + * @return ConstraintInterface|ObjectConstraint + * @throws InvalidArgumentException if is not possible create the constraint instance. + */ + public function createInstanceFor($constraintName) + { + if (!isset($this->constraintMap[$constraintName])) { + throw new InvalidArgumentException('Unknown constraint ' . $constraintName); + } + + if (!isset($this->instanceCache[$constraintName])) { + $this->instanceCache[$constraintName] = new $this->constraintMap[$constraintName]($this); + } + + return clone $this->instanceCache[$constraintName]; + } + + /** + * @return int + */ + public function getCheckMode() + { + return $this->checkMode; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/FormatConstraint.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,181 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Constraints; + +use JsonSchema\Rfc3339; +use JsonSchema\Entity\JsonPointer; + +/** + * Validates against the "format" property + * + * @author Justin Rainbow <justin.rainbow@gmail.com> + * @link http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.23 + */ +class FormatConstraint extends Constraint +{ + /** + * {@inheritDoc} + */ + public function check($element, $schema = null, JsonPointer $path = null, $i = null) + { + if (!isset($schema->format)) { + return; + } + + switch ($schema->format) { + case 'date': + if (!$date = $this->validateDateTime($element, 'Y-m-d')) { + $this->addError($path, sprintf('Invalid date %s, expected format YYYY-MM-DD', json_encode($element)), 'format', array('format' => $schema->format,)); + } + break; + + case 'time': + if (!$this->validateDateTime($element, 'H:i:s')) { + $this->addError($path, sprintf('Invalid time %s, expected format hh:mm:ss', json_encode($element)), 'format', array('format' => $schema->format,)); + } + break; + + case 'date-time': + if (null === Rfc3339::createFromString($element)) { + $this->addError($path, sprintf('Invalid date-time %s, expected format YYYY-MM-DDThh:mm:ssZ or YYYY-MM-DDThh:mm:ss+hh:mm', json_encode($element)), 'format', array('format' => $schema->format,)); + } + break; + + case 'utc-millisec': + if (!$this->validateDateTime($element, 'U')) { + $this->addError($path, sprintf('Invalid time %s, expected integer of milliseconds since Epoch', json_encode($element)), 'format', array('format' => $schema->format,)); + } + break; + + case 'regex': + if (!$this->validateRegex($element)) { + $this->addError($path, 'Invalid regex format ' . $element, 'format', array('format' => $schema->format,)); + } + break; + + case 'color': + if (!$this->validateColor($element)) { + $this->addError($path, "Invalid color", 'format', array('format' => $schema->format,)); + } + break; + + case 'style': + if (!$this->validateStyle($element)) { + $this->addError($path, "Invalid style", 'format', array('format' => $schema->format,)); + } + break; + + case 'phone': + if (!$this->validatePhone($element)) { + $this->addError($path, "Invalid phone number", 'format', array('format' => $schema->format,)); + } + break; + + case 'uri': + if (null === filter_var($element, FILTER_VALIDATE_URL, FILTER_NULL_ON_FAILURE)) { + $this->addError($path, "Invalid URL format", 'format', array('format' => $schema->format,)); + } + break; + + case 'email': + if (null === filter_var($element, FILTER_VALIDATE_EMAIL, FILTER_NULL_ON_FAILURE)) { + $this->addError($path, "Invalid email", 'format', array('format' => $schema->format,)); + } + break; + + case 'ip-address': + case 'ipv4': + if (null === filter_var($element, FILTER_VALIDATE_IP, FILTER_NULL_ON_FAILURE | FILTER_FLAG_IPV4)) { + $this->addError($path, "Invalid IP address", 'format', array('format' => $schema->format,)); + } + break; + + case 'ipv6': + if (null === filter_var($element, FILTER_VALIDATE_IP, FILTER_NULL_ON_FAILURE | FILTER_FLAG_IPV6)) { + $this->addError($path, "Invalid IP address", 'format', array('format' => $schema->format,)); + } + break; + + case 'host-name': + case 'hostname': + if (!$this->validateHostname($element)) { + $this->addError($path, "Invalid hostname", 'format', array('format' => $schema->format,)); + } + break; + + default: + // Empty as it should be: + // The value of this keyword is called a format attribute. It MUST be a string. + // A format attribute can generally only validate a given set of instance types. + // If the type of the instance to validate is not in this set, validation for + // this format attribute and instance SHOULD succeed. + // http://json-schema.org/latest/json-schema-validation.html#anchor105 + break; + } + } + + protected function validateDateTime($datetime, $format) + { + $dt = \DateTime::createFromFormat($format, $datetime); + + if (!$dt) { + return false; + } + + if ($datetime === $dt->format($format)) { + return true; + } + + // handles the case where a non-6 digit microsecond datetime is passed + // which will fail the above string comparison because the passed + // $datetime may be '2000-05-01T12:12:12.123Z' but format() will return + // '2000-05-01T12:12:12.123000Z' + if ((strpos('u', $format) !== -1) && (preg_match('/\.\d+Z$/', $datetime))) { + return true; + } + + return false; + } + + protected function validateRegex($regex) + { + return false !== @preg_match('/' . $regex . '/', ''); + } + + protected function validateColor($color) + { + if (in_array(strtolower($color), array('aqua', 'black', 'blue', 'fuchsia', + 'gray', 'green', 'lime', 'maroon', 'navy', 'olive', 'orange', 'purple', + 'red', 'silver', 'teal', 'white', 'yellow'))) { + return true; + } + + return preg_match('/^#([a-f0-9]{3}|[a-f0-9]{6})$/i', $color); + } + + protected function validateStyle($style) + { + $properties = explode(';', rtrim($style, ';')); + $invalidEntries = preg_grep('/^\s*[-a-z]+\s*:\s*.+$/i', $properties, PREG_GREP_INVERT); + + return empty($invalidEntries); + } + + protected function validatePhone($phone) + { + return preg_match('/^\+?(\(\d{3}\)|\d{3}) \d{3} \d{4}$/', $phone); + } + + protected function validateHostname($host) + { + $hostnameRegex = '/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/i'; + return preg_match($hostnameRegex, $host); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/NumberConstraint.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,86 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Constraints; + +use JsonSchema\Entity\JsonPointer; + +/** + * The NumberConstraint Constraints, validates an number against a given schema + * + * @author Robert Schönthal <seroscho@googlemail.com> + * @author Bruno Prieto Reis <bruno.p.reis@gmail.com> + */ +class NumberConstraint extends Constraint +{ + /** + * {@inheritDoc} + */ + public function check($element, $schema = null, JsonPointer $path = null, $i = null) + { + // Verify minimum + if (isset($schema->exclusiveMinimum)) { + if (isset($schema->minimum)) { + if ($schema->exclusiveMinimum && $element <= $schema->minimum) { + $this->addError($path, "Must have a minimum value of " . $schema->minimum, 'exclusiveMinimum', array('minimum' => $schema->minimum,)); + } elseif ($element < $schema->minimum) { + $this->addError($path, "Must have a minimum value of " . $schema->minimum, 'minimum', array('minimum' => $schema->minimum,)); + } + } else { + $this->addError($path, "Use of exclusiveMinimum requires presence of minimum", 'missingMinimum'); + } + } elseif (isset($schema->minimum) && $element < $schema->minimum) { + $this->addError($path, "Must have a minimum value of " . $schema->minimum, 'minimum', array('minimum' => $schema->minimum,)); + } + + // Verify maximum + if (isset($schema->exclusiveMaximum)) { + if (isset($schema->maximum)) { + if ($schema->exclusiveMaximum && $element >= $schema->maximum) { + $this->addError($path, "Must have a maximum value of " . $schema->maximum, 'exclusiveMaximum', array('maximum' => $schema->maximum,)); + } elseif ($element > $schema->maximum) { + $this->addError($path, "Must have a maximum value of " . $schema->maximum, 'maximum', array('maximum' => $schema->maximum,)); + } + } else { + $this->addError($path, "Use of exclusiveMaximum requires presence of maximum", 'missingMaximum'); + } + } elseif (isset($schema->maximum) && $element > $schema->maximum) { + $this->addError($path, "Must have a maximum value of " . $schema->maximum, 'maximum', array('maximum' => $schema->maximum,)); + } + + // Verify divisibleBy - Draft v3 + if (isset($schema->divisibleBy) && $this->fmod($element, $schema->divisibleBy) != 0) { + $this->addError($path, "Is not divisible by " . $schema->divisibleBy, 'divisibleBy', array('divisibleBy' => $schema->divisibleBy,)); + } + + // Verify multipleOf - Draft v4 + if (isset($schema->multipleOf) && $this->fmod($element, $schema->multipleOf) != 0) { + $this->addError($path, "Must be a multiple of " . $schema->multipleOf, 'multipleOf', array('multipleOf' => $schema->multipleOf,)); + } + + $this->checkFormat($element, $schema, $path, $i); + } + + private function fmod($number1, $number2) + { + $number1 = abs($number1); + $modulus = fmod($number1, $number2); + $precision = abs(0.0000000001); + $diff = (float)($modulus - $number2); + + if (-$precision < $diff && $diff < $precision) { + return 0.0; + } + + $decimals1 = mb_strpos($number1, ".") ? mb_strlen($number1) - mb_strpos($number1, ".") - 1 : 0; + $decimals2 = mb_strpos($number2, ".") ? mb_strlen($number2) - mb_strpos($number2, ".") - 1 : 0; + + return (float)round($modulus, max($decimals1, $decimals2)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ObjectConstraint.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,264 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Constraints; + +use JsonSchema\Entity\JsonPointer; + +/** + * The ObjectConstraint Constraints, validates an object against a given schema + * + * @author Robert Schönthal <seroscho@googlemail.com> + * @author Bruno Prieto Reis <bruno.p.reis@gmail.com> + */ +class ObjectConstraint extends Constraint +{ + /** + * {@inheritDoc} + */ + public function check($element, $definition = null, JsonPointer $path = null, $additionalProp = null, $patternProperties = null) + { + if ($element instanceof UndefinedConstraint) { + return; + } + + $matches = array(); + if ($patternProperties) { + $matches = $this->validatePatternProperties($element, $path, $patternProperties); + } + + if ($definition) { + // validate the definition properties + $this->validateDefinition($element, $definition, $path); + } + + // additional the element properties + $this->validateElement($element, $matches, $definition, $path, $additionalProp); + } + + public function validatePatternProperties($element, JsonPointer $path = null, $patternProperties) + { + $try = array('/','#','+','~','%'); + $matches = array(); + foreach ($patternProperties as $pregex => $schema) { + $delimiter = '/'; + // Choose delimiter. Necessary for patterns like ^/ , otherwise you get error + foreach ($try as $delimiter) { + if (strpos($pregex, $delimiter) === false) { // safe to use + break; + } + } + + // Validate the pattern before using it to test for matches + if (@preg_match($delimiter. $pregex . $delimiter, '') === false) { + $this->addError($path, 'The pattern "' . $pregex . '" is invalid', 'pregex', array('pregex' => $pregex,)); + continue; + } + foreach ($element as $i => $value) { + if (preg_match($delimiter . $pregex . $delimiter, $i)) { + $matches[] = $i; + $this->checkUndefined($value, $schema ? : new \stdClass(), $path, $i); + } + } + } + return $matches; + } + + /** + * Validates the element properties + * + * @param \stdClass $element Element to validate + * @param array $matches Matches from patternProperties (if any) + * @param \stdClass $objectDefinition ObjectConstraint definition + * @param JsonPointer|null $path Path to test? + * @param mixed $additionalProp Additional properties + */ + public function validateElement($element, $matches, $objectDefinition = null, JsonPointer $path = null, $additionalProp = null) + { + $this->validateMinMaxConstraint($element, $objectDefinition, $path); + + foreach ($element as $i => $value) { + $definition = $this->getProperty($objectDefinition, $i); + + // no additional properties allowed + if (!in_array($i, $matches) && $additionalProp === false && $this->inlineSchemaProperty !== $i && !$definition) { + $this->addError($path, "The property " . $i . " is not defined and the definition does not allow additional properties", 'additionalProp'); + } + + // additional properties defined + if (!in_array($i, $matches) && $additionalProp && !$definition) { + if ($additionalProp === true) { + $this->checkUndefined($value, null, $path, $i); + } else { + $this->checkUndefined($value, $additionalProp, $path, $i); + } + } + + // property requires presence of another + $require = $this->getProperty($definition, 'requires'); + if ($require && !$this->getProperty($element, $require)) { + $this->addError($path, "The presence of the property " . $i . " requires that " . $require . " also be present", 'requires'); + } + + $property = $this->getProperty($element, $i, $this->factory->createInstanceFor('undefined')); + if (is_object($property)) { + $this->validateMinMaxConstraint(!($property instanceof UndefinedConstraint) ? $property : $element, $definition, $path); + } + } + } + + /** + * Validates the definition properties + * + * @param \stdClass $element Element to validate + * @param \stdClass $objectDefinition ObjectConstraint definition + * @param JsonPointer|null $path Path? + */ + public function validateDefinition($element, $objectDefinition = null, JsonPointer $path = null) + { + $undefinedConstraint = $this->factory->createInstanceFor('undefined'); + + foreach ($objectDefinition as $i => $value) { + $property = $this->getProperty($element, $i, $undefinedConstraint); + $definition = $this->getProperty($objectDefinition, $i); + + if($this->factory->getCheckMode() & Constraint::CHECK_MODE_TYPE_CAST){ + if(!($property instanceof Constraint)) { + $property = $this->coerce($property, $definition); + + if($this->factory->getCheckMode() & Constraint::CHECK_MODE_COERCE) { + if (is_object($element)) { + $element->{$i} = $property; + } else { + $element[$i] = $property; + } + } + } + } + + if (is_object($definition)) { + // Undefined constraint will check for is_object() and quit if is not - so why pass it? + $this->checkUndefined($property, $definition, $path, $i); + } + } + } + + /** + * Converts a value to boolean. For example, "true" becomes true. + * @param $value The value to convert to boolean + * @return bool|mixed + */ + protected function toBoolean($value) + { + if($value === "true"){ + return true; + } + + if($value === "false"){ + return false; + } + + return $value; + } + + /** + * Converts a numeric string to a number. For example, "4" becomes 4. + * + * @param mixed $value The value to convert to a number. + * @return int|float|mixed + */ + protected function toNumber($value) + { + if(is_numeric($value)) { + return $value + 0; // cast to number + } + + return $value; + } + + protected function toInteger($value) + { + if(is_numeric($value) && (int)$value == $value) { + return (int)$value; // cast to number + } + + return $value; + } + + /** + * Given a value and a definition, attempts to coerce the value into the + * type specified by the definition's 'type' property. + * + * @param mixed $value Value to coerce. + * @param \stdClass $definition A definition with information about the expected type. + * @return bool|int|string + */ + protected function coerce($value, $definition) + { + $types = isset($definition->type)?$definition->type:null; + if($types){ + foreach((array)$types as $type) { + switch ($type) { + case "boolean": + $value = $this->toBoolean($value); + break; + case "integer": + $value = $this->toInteger($value); + break; + case "number": + $value = $this->toNumber($value); + break; + } + } + } + return $value; + } + + /** + * retrieves a property from an object or array + * + * @param mixed $element Element to validate + * @param string $property Property to retrieve + * @param mixed $fallback Default value if property is not found + * + * @return mixed + */ + protected function getProperty($element, $property, $fallback = null) + { + if (is_array($element) && (isset($element[$property]) || array_key_exists($property, $element)) /*$this->checkMode == self::CHECK_MODE_TYPE_CAST*/) { + return $element[$property]; + } elseif (is_object($element) && property_exists($element, $property)) { + return $element->$property; + } + + return $fallback; + } + + /** + * validating minimum and maximum property constraints (if present) against an element + * + * @param \stdClass $element Element to validate + * @param \stdClass $objectDefinition ObjectConstraint definition + * @param JsonPointer|null $path Path to test? + */ + protected function validateMinMaxConstraint($element, $objectDefinition, JsonPointer $path = null) { + // Verify minimum number of properties + if (isset($objectDefinition->minProperties) && !is_object($objectDefinition->minProperties)) { + if ($this->getTypeCheck()->propertyCount($element) < $objectDefinition->minProperties) { + $this->addError($path, "Must contain a minimum of " . $objectDefinition->minProperties . " properties", 'minProperties', array('minProperties' => $objectDefinition->minProperties,)); + } + } + // Verify maximum number of properties + if (isset($objectDefinition->maxProperties) && !is_object($objectDefinition->maxProperties)) { + if ($this->getTypeCheck()->propertyCount($element) > $objectDefinition->maxProperties) { + $this->addError($path, "Must contain no more than " . $objectDefinition->maxProperties . " properties", 'maxProperties', array('maxProperties' => $objectDefinition->maxProperties,)); + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/SchemaConstraint.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,42 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Constraints; + +use JsonSchema\Exception\InvalidArgumentException; +use JsonSchema\Entity\JsonPointer; + +/** + * The SchemaConstraint Constraints, validates an element against a given schema + * + * @author Robert Schönthal <seroscho@googlemail.com> + * @author Bruno Prieto Reis <bruno.p.reis@gmail.com> + */ +class SchemaConstraint extends Constraint +{ + /** + * {@inheritDoc} + */ + public function check($element, $schema = null, JsonPointer $path = null, $i = null) + { + if ($schema !== null) { + // passed schema + $this->checkUndefined($element, $schema, $path, $i); + } elseif ($this->getTypeCheck()->propertyExists($element, $this->inlineSchemaProperty)) { + $inlineSchema = $this->getTypeCheck()->propertyGet($element, $this->inlineSchemaProperty); + if (is_array($inlineSchema)) { + $inlineSchema = json_decode(json_encode($inlineSchema)); + } + // inline schema + $this->checkUndefined($element, $inlineSchema, $path, $i); + } else { + throw new InvalidArgumentException('no schema found to verify against'); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/StringConstraint.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,59 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Constraints; + +use JsonSchema\Entity\JsonPointer; + +/** + * The StringConstraint Constraints, validates an string against a given schema + * + * @author Robert Schönthal <seroscho@googlemail.com> + * @author Bruno Prieto Reis <bruno.p.reis@gmail.com> + */ +class StringConstraint extends Constraint +{ + /** + * {@inheritDoc} + */ + public function check($element, $schema = null, JsonPointer $path = null, $i = null) + { + // Verify maxLength + if (isset($schema->maxLength) && $this->strlen($element) > $schema->maxLength) { + $this->addError($path, "Must be at most " . $schema->maxLength . " characters long", 'maxLength', array( + 'maxLength' => $schema->maxLength, + )); + } + + //verify minLength + if (isset($schema->minLength) && $this->strlen($element) < $schema->minLength) { + $this->addError($path, "Must be at least " . $schema->minLength . " characters long", 'minLength', array( + 'minLength' => $schema->minLength, + )); + } + + // Verify a regex pattern + if (isset($schema->pattern) && !preg_match('#' . str_replace('#', '\\#', $schema->pattern) . '#u', $element)) { + $this->addError($path, "Does not match the regex pattern " . $schema->pattern, 'pattern', array( + 'pattern' => $schema->pattern, + )); + } + + $this->checkFormat($element, $schema, $path, $i); + } + + private function strlen($string) + { + if (extension_loaded('mbstring')) { + return mb_strlen($string, mb_detect_encoding($string)); + } else { + return strlen($string); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/LooseTypeCheck.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,59 @@ +<?php + +namespace JsonSchema\Constraints\TypeCheck; + +class LooseTypeCheck implements TypeCheckInterface +{ + public static function isObject($value) + { + return + is_object($value) || + (is_array($value) && (count($value) == 0 || self::isAssociativeArray($value))); + } + + public static function isArray($value) + { + return + is_array($value) && + (count($value) == 0 || !self::isAssociativeArray($value)); + } + + public static function propertyGet($value, $property) + { + if (is_object($value)) { + return $value->{$property}; + } + + return $value[$property]; + } + + public static function propertyExists($value, $property) + { + if (is_object($value)) { + return property_exists($value, $property); + } + + return array_key_exists($property, $value); + } + + public static function propertyCount($value) + { + if (is_object($value)) { + return count(get_object_vars($value)); + } + + return count($value); + } + + /** + * Check if the provided array is associative or not + * + * @param array $arr + * + * @return bool + */ + private static function isAssociativeArray($arr) + { + return (array_keys($arr) !== range(0, count($arr) - 1)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/StrictTypeCheck.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,31 @@ +<?php + +namespace JsonSchema\Constraints\TypeCheck; + +class StrictTypeCheck implements TypeCheckInterface +{ + public static function isObject($value) + { + return is_object($value); + } + + public static function isArray($value) + { + return is_array($value); + } + + public static function propertyGet($value, $property) + { + return $value->{$property}; + } + + public static function propertyExists($value, $property) + { + return property_exists($value, $property); + } + + public static function propertyCount($value) + { + return count(get_object_vars($value)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/TypeCheckInterface.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,16 @@ +<?php + +namespace JsonSchema\Constraints\TypeCheck; + +interface TypeCheckInterface +{ + public static function isObject($value); + + public static function isArray($value); + + public static function propertyGet($value, $property); + + public static function propertyExists($value, $property); + + public static function propertyCount($value); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeConstraint.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,197 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Constraints; + +use JsonSchema\Exception\InvalidArgumentException; +use JsonSchema\Entity\JsonPointer; +use UnexpectedValueException as StandardUnexpectedValueException; + +/** + * The TypeConstraint Constraints, validates an element against a given type + * + * @author Robert Schönthal <seroscho@googlemail.com> + * @author Bruno Prieto Reis <bruno.p.reis@gmail.com> + */ +class TypeConstraint extends Constraint +{ + /** + * @var array|string[] type wordings for validation error messages + */ + static $wording = array( + 'integer' => 'an integer', + 'number' => 'a number', + 'boolean' => 'a boolean', + 'object' => 'an object', + 'array' => 'an array', + 'string' => 'a string', + 'null' => 'a null', + 'any' => NULL, // validation of 'any' is always true so is not needed in message wording + 0 => NULL, // validation of a false-y value is always true, so not needed as well + ); + + /** + * {@inheritDoc} + */ + public function check($value = null, $schema = null, JsonPointer $path = null, $i = null) + { + $type = isset($schema->type) ? $schema->type : null; + $isValid = false; + $wording = array(); + + if (is_array($type)) { + $this->validateTypesArray($value, $type, $wording, $isValid, $path); + } elseif (is_object($type)) { + $this->checkUndefined($value, $type, $path); + return; + } else { + $isValid = $this->validateType($value, $type); + } + + if ($isValid === false) { + if (!is_array($type)) { + $this->validateTypeNameWording($type); + $wording[] = self::$wording[$type]; + } + $this->addError($path, ucwords(gettype($value)) . " value found, but " . + $this->implodeWith($wording, ', ', 'or') . " is required", 'type'); + } + } + + /** + * Validates the given $value against the array of types in $type. Sets the value + * of $isValid to true, if at least one $type mateches the type of $value or the value + * passed as $isValid is already true. + * + * @param mixed $value Value to validate + * @param array $type TypeConstraints to check agains + * @param array $validTypesWording An array of wordings of the valid types of the array $type + * @param boolean $isValid The current validation value + * @param $path + */ + protected function validateTypesArray($value, array $type, &$validTypesWording, &$isValid, + $path) { + foreach ($type as $tp) { + // $tp can be an object, if it's a schema instead of a simple type, validate it + // with a new type constraint + if (is_object($tp)) { + if (!$isValid) { + $validator = $this->factory->createInstanceFor('type'); + $subSchema = new \stdClass(); + $subSchema->type = $tp; + $validator->check($value, $subSchema, $path, null); + $error = $validator->getErrors(); + $isValid = !(bool)$error; + $validTypesWording[] = self::$wording['object']; + } + } else { + $this->validateTypeNameWording( $tp ); + $validTypesWording[] = self::$wording[$tp]; + if (!$isValid) { + $isValid = $this->validateType( $value, $tp ); + } + } + } + } + + /** + * Implodes the given array like implode() with turned around parameters and with the + * difference, that, if $listEnd isn't false, the last element delimiter is $listEnd instead of + * $delimiter. + * + * @param array $elements The elements to implode + * @param string $delimiter The delimiter to use + * @param bool $listEnd The last delimiter to use (defaults to $delimiter) + * @return string + */ + protected function implodeWith(array $elements, $delimiter = ', ', $listEnd = false) { + if ($listEnd === false || !isset($elements[1])) { + return implode($delimiter, $elements); + } + $lastElement = array_slice($elements, -1); + $firsElements = join($delimiter, array_slice($elements, 0, -1)); + $implodedElements = array_merge(array($firsElements), $lastElement); + return join(" $listEnd ", $implodedElements); + } + + /** + * Validates the given $type, if there's an associated self::$wording. If not, throws an + * exception. + * + * @param string $type The type to validate + * + * @throws StandardUnexpectedValueException + */ + protected function validateTypeNameWording( $type) { + if (!isset(self::$wording[$type])) { + throw new StandardUnexpectedValueException( + sprintf( + "No wording for %s available, expected wordings are: [%s]", + var_export($type, true), + implode(', ', array_filter(self::$wording))) + ); + } + } + + /** + * Verifies that a given value is of a certain type + * + * @param mixed $value Value to validate + * @param string $type TypeConstraint to check against + * + * @return boolean + * + * @throws InvalidArgumentException + */ + protected function validateType($value, $type) + { + //mostly the case for inline schema + if (!$type) { + return true; + } + + if ('integer' === $type) { + return is_int($value); + } + + if ('number' === $type) { + return is_numeric($value) && !is_string($value); + } + + if ('boolean' === $type) { + return is_bool($value); + } + + if ('object' === $type) { + return $this->getTypeCheck()->isObject($value); + } + + if ('array' === $type) { + return $this->getTypeCheck()->isArray($value); + } + + if ('string' === $type) { + return is_string($value); + } + + if ('email' === $type) { + return is_string($value); + } + + if ('null' === $type) { + return is_null($value); + } + + if ('any' === $type) { + return true; + } + + throw new InvalidArgumentException((is_object($value) ? 'object' : $value) . ' is an invalid type for ' . $type); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,280 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Constraints; + +use JsonSchema\Uri\UriResolver; +use JsonSchema\Entity\JsonPointer; + +/** + * The UndefinedConstraint Constraints + * + * @author Robert Schönthal <seroscho@googlemail.com> + * @author Bruno Prieto Reis <bruno.p.reis@gmail.com> + */ +class UndefinedConstraint extends Constraint +{ + /** + * {@inheritDoc} + */ + public function check($value, $schema = null, JsonPointer $path = null, $i = null) + { + if (is_null($schema) || !is_object($schema)) { + return; + } + + $path = $this->incrementPath($path ?: new JsonPointer(''), $i); + + // check special properties + $this->validateCommonProperties($value, $schema, $path); + + // check allOf, anyOf, and oneOf properties + $this->validateOfProperties($value, $schema, $path); + + // check known types + $this->validateTypes($value, $schema, $path, $i); + } + + /** + * Validates the value against the types + * + * @param mixed $value + * @param mixed $schema + * @param JsonPointer $path + * @param string $i + */ + public function validateTypes($value, $schema = null, JsonPointer $path, $i = null) + { + // check array + if ($this->getTypeCheck()->isArray($value)) { + $this->checkArray($value, $schema, $path, $i); + } + + // check object + if ($this->getTypeCheck()->isObject($value)) { + $this->checkObject( + $value, + isset($schema->properties) ? $this->factory->getSchemaStorage()->resolveRefSchema($schema->properties) : $schema, + $path, + isset($schema->additionalProperties) ? $schema->additionalProperties : null, + isset($schema->patternProperties) ? $schema->patternProperties : null + ); + } + + // check string + if (is_string($value)) { + $this->checkString($value, $schema, $path, $i); + } + + // check numeric + if (is_numeric($value)) { + $this->checkNumber($value, $schema, $path, $i); + } + + // check enum + if (isset($schema->enum)) { + $this->checkEnum($value, $schema, $path, $i); + } + } + + /** + * Validates common properties + * + * @param mixed $value + * @param mixed $schema + * @param JsonPointer $path + * @param string $i + */ + protected function validateCommonProperties($value, $schema = null, JsonPointer $path, $i = "") + { + // if it extends another schema, it must pass that schema as well + if (isset($schema->extends)) { + if (is_string($schema->extends)) { + $schema->extends = $this->validateUri($schema, $schema->extends); + } + if (is_array($schema->extends)) { + foreach ($schema->extends as $extends) { + $this->checkUndefined($value, $extends, $path, $i); + } + } else { + $this->checkUndefined($value, $schema->extends, $path, $i); + } + } + + // Verify required values + if ($this->getTypeCheck()->isObject($value)) { + if (!($value instanceof UndefinedConstraint) && isset($schema->required) && is_array($schema->required)) { + // Draft 4 - Required is an array of strings - e.g. "required": ["foo", ...] + foreach ($schema->required as $required) { + if (!$this->getTypeCheck()->propertyExists($value, $required)) { + $this->addError( + $this->incrementPath($path ?: new JsonPointer(''), $required), + "The property " . $required . " is required", + 'required' + ); + } + } + } elseif (isset($schema->required) && !is_array($schema->required)) { + // Draft 3 - Required attribute - e.g. "foo": {"type": "string", "required": true} + if ($schema->required && $value instanceof UndefinedConstraint) { + $this->addError($path, "Is missing and it is required", 'required'); + } + } + } + + // Verify type + if (!($value instanceof UndefinedConstraint)) { + $this->checkType($value, $schema, $path); + } + + // Verify disallowed items + if (isset($schema->disallow)) { + $initErrors = $this->getErrors(); + + $typeSchema = new \stdClass(); + $typeSchema->type = $schema->disallow; + $this->checkType($value, $typeSchema, $path); + + // if no new errors were raised it must be a disallowed value + if (count($this->getErrors()) == count($initErrors)) { + $this->addError($path, "Disallowed value was matched", 'disallow'); + } else { + $this->errors = $initErrors; + } + } + + if (isset($schema->not)) { + $initErrors = $this->getErrors(); + $this->checkUndefined($value, $schema->not, $path, $i); + + // if no new errors were raised then the instance validated against the "not" schema + if (count($this->getErrors()) == count($initErrors)) { + $this->addError($path, "Matched a schema which it should not", 'not'); + } else { + $this->errors = $initErrors; + } + } + + // Verify that dependencies are met + if (isset($schema->dependencies) && $this->getTypeCheck()->isObject($value)) { + $this->validateDependencies($value, $schema->dependencies, $path); + } + } + + /** + * Validate allOf, anyOf, and oneOf properties + * + * @param mixed $value + * @param mixed $schema + * @param JsonPointer $path + * @param string $i + */ + protected function validateOfProperties($value, $schema, JsonPointer $path, $i = "") + { + // Verify type + if ($value instanceof UndefinedConstraint) { + return; + } + + if (isset($schema->allOf)) { + $isValid = true; + foreach ($schema->allOf as $allOf) { + $initErrors = $this->getErrors(); + $this->checkUndefined($value, $allOf, $path, $i); + $isValid = $isValid && (count($this->getErrors()) == count($initErrors)); + } + if (!$isValid) { + $this->addError($path, "Failed to match all schemas", 'allOf'); + } + } + + if (isset($schema->anyOf)) { + $isValid = false; + $startErrors = $this->getErrors(); + foreach ($schema->anyOf as $anyOf) { + $initErrors = $this->getErrors(); + $this->checkUndefined($value, $anyOf, $path, $i); + if ($isValid = (count($this->getErrors()) == count($initErrors))) { + break; + } + } + if (!$isValid) { + $this->addError($path, "Failed to match at least one schema", 'anyOf'); + } else { + $this->errors = $startErrors; + } + } + + if (isset($schema->oneOf)) { + $allErrors = array(); + $matchedSchemas = 0; + $startErrors = $this->getErrors(); + foreach ($schema->oneOf as $oneOf) { + $this->errors = array(); + $this->checkUndefined($value, $oneOf, $path, $i); + if (count($this->getErrors()) == 0) { + $matchedSchemas++; + } + $allErrors = array_merge($allErrors, array_values($this->getErrors())); + } + if ($matchedSchemas !== 1) { + $this->addErrors(array_merge($allErrors, $startErrors)); + $this->addError($path, "Failed to match exactly one schema", 'oneOf'); + } else { + $this->errors = $startErrors; + } + } + } + + /** + * Validate dependencies + * + * @param mixed $value + * @param mixed $dependencies + * @param JsonPointer $path + * @param string $i + */ + protected function validateDependencies($value, $dependencies, JsonPointer $path, $i = "") + { + foreach ($dependencies as $key => $dependency) { + if ($this->getTypeCheck()->propertyExists($value, $key)) { + if (is_string($dependency)) { + // Draft 3 string is allowed - e.g. "dependencies": {"bar": "foo"} + if (!$this->getTypeCheck()->propertyExists($value, $dependency)) { + $this->addError($path, "$key depends on $dependency and $dependency is missing", 'dependencies'); + } + } elseif (is_array($dependency)) { + // Draft 4 must be an array - e.g. "dependencies": {"bar": ["foo"]} + foreach ($dependency as $d) { + if (!$this->getTypeCheck()->propertyExists($value, $d)) { + $this->addError($path, "$key depends on $d and $d is missing", 'dependencies'); + } + } + } elseif (is_object($dependency)) { + // Schema - e.g. "dependencies": {"bar": {"properties": {"foo": {...}}}} + $this->checkUndefined($value, $dependency, $path, $i); + } + } + } + } + + protected function validateUri($schema, $schemaUri = null) + { + $resolver = new UriResolver(); + $retriever = $this->factory->getUriRetriever(); + + $jsonSchema = null; + if ($resolver->isValid($schemaUri)) { + $schemaId = property_exists($schema, 'id') ? $schema->id : null; + $jsonSchema = $retriever->retrieve($schemaId, $schemaUri); + } + + return $jsonSchema; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Entity/JsonPointer.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,129 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Entity; + +/** + * @package JsonSchema\Entity + * @author Joost Nijhuis <jnijhuis81@gmail.com> + */ +class JsonPointer +{ + /** @var string */ + private $filename; + + /** @var string[] */ + private $propertyPaths = array(); + + /** + * @param string $value + * @throws \InvalidArgumentException when $value is not a string + */ + public function __construct($value) + { + if (!is_string($value)) { + throw new \InvalidArgumentException('Ref value must be a string'); + } + + $splitRef = explode('#', $value, 2); + $this->filename = $splitRef[0]; + if (array_key_exists(1, $splitRef)) { + $this->propertyPaths = $this->decodePropertyPaths($splitRef[1]); + } + } + + /** + * @param string $propertyPathString + * @return string[] + */ + private function decodePropertyPaths($propertyPathString) + { + $paths = array(); + foreach (explode('/', trim($propertyPathString, '/')) as $path) { + $path = $this->decodePath($path); + if (is_string($path) && '' !== $path) { + $paths[] = $path; + } + } + + return $paths; + } + + /** + * @return array + */ + private function encodePropertyPaths() + { + return array_map( + array($this, 'encodePath'), + $this->getPropertyPaths() + ); + } + + /** + * @param string $path + * @return string + */ + private function decodePath($path) + { + return strtr($path, array('~1' => '/', '~0' => '~', '%25' => '%')); + } + + /** + * @param string $path + * @return string + */ + private function encodePath($path) + { + return strtr($path, array('/' => '~1', '~' => '~0', '%' => '%25')); + } + + /** + * @return string + */ + public function getFilename() + { + return $this->filename; + } + + /** + * @return string[] + */ + public function getPropertyPaths() + { + return $this->propertyPaths; + } + + /** + * @param array $propertyPaths + * @return JsonPointer + */ + public function withPropertyPaths(array $propertyPaths) + { + $new = clone $this; + $new->propertyPaths = $propertyPaths; + return $new; + } + + /** + * @return string + */ + public function getPropertyPathAsString() + { + return rtrim('#/' . implode('/', $this->encodePropertyPaths()), '/'); + } + + /** + * @return string + */ + public function __toString() + { + return $this->getFilename() . $this->getPropertyPathAsString(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/ExceptionInterface.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,8 @@ +<?php + +namespace JsonSchema\Exception; + +interface ExceptionInterface +{ + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidArgumentException.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,17 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Exception; + +/** + * Wrapper for the InvalidArgumentException + */ +class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface +{ +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSchemaMediaTypeException.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,17 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Exception; + +/** + * Wrapper for the InvalidSchemaMediaType + */ +class InvalidSchemaMediaTypeException extends RuntimeException +{ +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSourceUriException.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,17 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Exception; + +/** + * Wrapper for the InvalidSourceUriException + */ +class InvalidSourceUriException extends InvalidArgumentException +{ +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/JsonDecodingException.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,40 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Exception; + +/** + * Wrapper for the JsonDecodingException + */ +class JsonDecodingException extends RuntimeException +{ + public function __construct($code = JSON_ERROR_NONE, \Exception $previous = null) + { + switch ($code) { + case JSON_ERROR_DEPTH: + $message = 'The maximum stack depth has been exceeded'; + break; + case JSON_ERROR_STATE_MISMATCH: + $message = 'Invalid or malformed JSON'; + break; + case JSON_ERROR_CTRL_CHAR: + $message = 'Control character error, possibly incorrectly encoded'; + break; + case JSON_ERROR_UTF8: + $message = 'Malformed UTF-8 characters, possibly incorrectly encoded'; + break; + case JSON_ERROR_SYNTAX: + $message = 'JSON syntax is malformed'; + break; + default: + $message = 'Syntax error'; + } + parent::__construct($message, $code, $previous); + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/ResourceNotFoundException.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,17 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Exception; + +/** + * Wrapper for the ResourceNotFoundException + */ +class ResourceNotFoundException extends RuntimeException +{ +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/RuntimeException.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,17 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Exception; + +/** + * Wrapper for the RuntimeException + */ +class RuntimeException extends \RuntimeException implements ExceptionInterface +{ +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/UnresolvableJsonPointerException.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,18 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Exception; + +/** + * @package JsonSchema\Exception + * @author Joost Nijhuis <jnijhuis81@gmail.com> + */ +class UnresolvableJsonPointerException extends InvalidArgumentException +{ +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/UriResolverException.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,17 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Exception; + +/** + * Wrapper for the UriResolverException + */ +class UriResolverException extends RuntimeException +{ +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Iterator/ObjectIterator.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,147 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Iterator; + +/** + * @package JsonSchema\Iterator + * @author Joost Nijhuis <jnijhuis81@gmail.com> + */ +class ObjectIterator implements \Iterator, \Countable +{ + /** @var object */ + private $object; + + /** @var int */ + private $position = 0; + + /** @var array */ + private $data = array(); + + /** @var bool */ + private $initialized = false; + + /** + * @param object $object + */ + public function __construct($object) + { + $this->object = $object; + } + + /** + * {@inheritdoc} + */ + public function current() + { + $this->initialize(); + + return $this->data[$this->position]; + } + + /** + * {@inheritdoc} + */ + public function next() + { + $this->initialize(); + $this->position++; + } + + /** + * {@inheritdoc} + */ + public function key() + { + $this->initialize(); + + return $this->position; + } + + /** + * {@inheritdoc} + */ + public function valid() + { + $this->initialize(); + + return isset($this->data[$this->position]); + } + + /** + * {@inheritdoc} + */ + public function rewind() + { + $this->initialize(); + $this->position = 0; + } + + /** + * {@inheritdoc} + */ + public function count() + { + $this->initialize(); + + return count($this->data); + } + + /** + * Initializer + */ + private function initialize() + { + if (!$this->initialized) { + $this->data = $this->buildDataFromObject($this->object); + $this->initialized = true; + } + } + + /** + * @param object $object + * @return array + */ + private function buildDataFromObject($object) + { + $result = array(); + + $stack = new \SplStack(); + $stack->push($object); + + while (!$stack->isEmpty()) { + + $current = $stack->pop(); + if (is_object($current)) { + array_push($result, $current); + } + + foreach ($this->getDataFromItem($current) as $propertyName => $propertyValue) { + if (is_object($propertyValue) || is_array($propertyValue)) { + $stack->push($propertyValue); + } + } + } + + return $result; + } + + /** + * @param object|array $item + * @return array + */ + private function getDataFromItem($item) + { + if (!is_object($item) && !is_array($item)) { + return array(); + } + + return is_object($item) ? get_object_vars($item) : $item; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Rfc3339.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,29 @@ +<?php + +namespace JsonSchema; + +class Rfc3339 +{ + const REGEX = '/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})(\.\d+)?(Z|([+-]\d{2}):?(\d{2}))/'; + + /** + * Try creating a DateTime instance + * + * @param string $string + * @return \DateTime|null + */ + public static function createFromString($string) + { + if (!preg_match(self::REGEX, strtoupper($string), $matches)) { + return null; + } + + $dateAndTime = $matches[1]; + $microseconds = $matches[2] ?: '.000000'; + $timeZone = 'Z' !== $matches[3] ? $matches[4] . ':' . $matches[5] : '+00:00'; + + $dateTime = \DateTime::createFromFormat('Y-m-d\TH:i:s.uP', $dateAndTime . $microseconds . $timeZone, new \DateTimeZone('UTC')); + + return $dateTime ?: null; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/SchemaStorage.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,109 @@ +<?php + +namespace JsonSchema; + +use JsonSchema\Entity\JsonPointer; +use JsonSchema\Exception\UnresolvableJsonPointerException; +use JsonSchema\Iterator\ObjectIterator; +use JsonSchema\Uri\UriResolver; +use JsonSchema\Uri\UriRetriever; + +class SchemaStorage +{ + protected $uriRetriever; + protected $uriResolver; + protected $schemas = array(); + + public function __construct( + UriRetrieverInterface $uriRetriever = null, + UriResolverInterface $uriResolver = null + ) { + $this->uriRetriever = $uriRetriever ?: new UriRetriever; + $this->uriResolver = $uriResolver ?: new UriResolver; + } + + /** + * @return UriRetrieverInterface + */ + public function getUriRetriever() + { + return $this->uriRetriever; + } + + /** + * @return UriResolverInterface + */ + public function getUriResolver() + { + return $this->uriResolver; + } + + /** + * @param string $id + * @param object $schema + */ + public function addSchema($id, $schema = null) + { + if (is_null($schema)) { + $schema = $this->uriRetriever->retrieve($id); + } + $objectIterator = new ObjectIterator($schema); + foreach ($objectIterator as $toResolveSchema) { + if (property_exists($toResolveSchema, '$ref') && is_string($toResolveSchema->{'$ref'})) { + $jsonPointer = new JsonPointer($this->uriResolver->resolve($toResolveSchema->{'$ref'}, $id)); + $toResolveSchema->{'$ref'} = (string)$jsonPointer; + } + } + $this->schemas[$id] = $schema; + } + + /** + * @param string $id + * @return object + */ + public function getSchema($id) + { + if (!array_key_exists($id, $this->schemas)) { + $this->addSchema($id); + } + + return $this->schemas[$id]; + } + + public function resolveRef($ref) + { + $jsonPointer = new JsonPointer($ref); + $refSchema = $this->getSchema($jsonPointer->getFilename()); + + foreach ($jsonPointer->getPropertyPaths() as $path) { + if (is_object($refSchema) && property_exists($refSchema, $path)) { + $refSchema = $this->resolveRefSchema($refSchema->{$path}); + } elseif (is_array($refSchema) && array_key_exists($path, $refSchema)) { + $refSchema = $this->resolveRefSchema($refSchema[$path]); + } else { + throw new UnresolvableJsonPointerException(sprintf( + 'File: %s is found, but could not resolve fragment: %s', + $jsonPointer->getFilename(), + $jsonPointer->getPropertyPathAsString() + )); + } + } + + return $refSchema; + } + + /** + * @param $refSchema + * @return object + */ + public function resolveRefSchema($refSchema) + { + if (is_object($refSchema) && property_exists($refSchema, '$ref') && is_string($refSchema->{'$ref'})) { + $newSchema = $this->resolveRef($refSchema->{'$ref'}); + $refSchema = (object) (get_object_vars($refSchema) + get_object_vars($newSchema)); + unset($refSchema->{'$ref'}); + } + + return $refSchema; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/AbstractRetriever.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,29 @@ +<?php +/** + * JsonSchema + * @filesource + */ +namespace JsonSchema\Uri\Retrievers; + +/** + * AbstractRetriever implements the default shared behavior + * that all descendant Retrievers should inherit + * @author Steven Garcia <webwhammy@gmail.com> + */ +abstract class AbstractRetriever implements UriRetrieverInterface +{ + /** + * Media content type + * @var string + */ + protected $contentType; + + /** + * {@inheritDoc} + * @see \JsonSchema\Uri\Retrievers\UriRetrieverInterface::getContentType() + */ + public function getContentType() + { + return $this->contentType; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/Curl.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,79 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Uri\Retrievers; + +use JsonSchema\Validator; + +/** + * Tries to retrieve JSON schemas from a URI using cURL library + * + * @author Sander Coolen <sander@jibber.nl> + */ +class Curl extends AbstractRetriever +{ + protected $messageBody; + + public function __construct() + { + if (!function_exists('curl_init')) { + throw new \RuntimeException("cURL not installed"); + } + } + + /** + * {@inheritDoc} + * @see \JsonSchema\Uri\Retrievers\UriRetrieverInterface::retrieve() + */ + public function retrieve($uri) + { + $ch = curl_init(); + + curl_setopt($ch, CURLOPT_URL, $uri); + curl_setopt($ch, CURLOPT_HEADER, true); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: ' . Validator::SCHEMA_MEDIA_TYPE)); + + $response = curl_exec($ch); + if (false === $response) { + throw new \JsonSchema\Exception\ResourceNotFoundException('JSON schema not found'); + } + + $this->fetchMessageBody($response); + $this->fetchContentType($response); + + curl_close($ch); + + return $this->messageBody; + } + + /** + * @param string $response cURL HTTP response + */ + private function fetchMessageBody($response) + { + preg_match("/(?:\r\n){2}(.*)$/ms", $response, $match); + $this->messageBody = $match[1]; + } + + /** + * @param string $response cURL HTTP response + * @return boolean Whether the Content-Type header was found or not + */ + protected function fetchContentType($response) + { + if (0 < preg_match("/Content-Type:(\V*)/ims", $response, $match)) { + $this->contentType = trim($match[1]); + + return true; + } + + return false; + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/FileGetContents.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,88 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Uri\Retrievers; + +use JsonSchema\Exception\ResourceNotFoundException; + +/** + * Tries to retrieve JSON schemas from a URI using file_get_contents() + * + * @author Sander Coolen <sander@jibber.nl> + */ +class FileGetContents extends AbstractRetriever +{ + protected $messageBody; + + /** + * {@inheritDoc} + * @see \JsonSchema\Uri\Retrievers\UriRetrieverInterface::retrieve() + */ + public function retrieve($uri) + { + $errorMessage = null; + set_error_handler(function ($errno, $errstr) use (&$errorMessage) { + $errorMessage = $errstr; + }); + $response = file_get_contents($uri); + restore_error_handler(); + + if ($errorMessage) { + throw new ResourceNotFoundException($errorMessage); + } + + if (false === $response) { + throw new ResourceNotFoundException('JSON schema not found at '.$uri); + } + + if ($response == '' + && substr($uri, 0, 7) == 'file://' && substr($uri, -1) == '/' + ) { + throw new ResourceNotFoundException('JSON schema not found at '.$uri); + } + + $this->messageBody = $response; + if (!empty($http_response_header)) { + $this->fetchContentType($http_response_header); + } else { + // Could be a "file://" url or something else - fake up the response + $this->contentType = null; + } + + return $this->messageBody; + } + + /** + * @param array $headers HTTP Response Headers + * @return boolean Whether the Content-Type header was found or not + */ + private function fetchContentType(array $headers) + { + foreach ($headers as $header) { + if ($this->contentType = self::getContentTypeMatchInHeader($header)) { + return true; + } + } + + return false; + } + + /** + * @param string $header + * @return string|null + */ + protected static function getContentTypeMatchInHeader($header) + { + if (0 < preg_match("/Content-Type:(\V*)/ims", $header, $match)) { + return trim($match[1]); + } + + return null; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/PredefinedArray.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,54 @@ +<?php + +namespace JsonSchema\Uri\Retrievers; + +use JsonSchema\Validator; + +/** + * URI retrieved based on a predefined array of schemas + * + * @example + * + * $retriever = new PredefinedArray(array( + * 'http://acme.com/schemas/person#' => '{ ... }', + * 'http://acme.com/schemas/address#' => '{ ... }', + * )) + * + * $schema = $retriever->retrieve('http://acme.com/schemas/person#'); + */ +class PredefinedArray extends AbstractRetriever +{ + /** + * Contains schemas as URI => JSON + * @var array + */ + private $schemas; + + /** + * Constructor + * + * @param array $schemas + * @param string $contentType + */ + public function __construct(array $schemas, $contentType = Validator::SCHEMA_MEDIA_TYPE) + { + $this->schemas = $schemas; + $this->contentType = $contentType; + } + + /** + * {@inheritDoc} + * @see \JsonSchema\Uri\Retrievers\UriRetrieverInterface::retrieve() + */ + public function retrieve($uri) + { + if (!array_key_exists($uri, $this->schemas)) { + throw new \JsonSchema\Exception\ResourceNotFoundException(sprintf( + 'The JSON schema "%s" was not found.', + $uri + )); + } + + return $this->schemas[$uri]; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/UriRetrieverInterface.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,32 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Uri\Retrievers; + +/** + * Interface for URI retrievers + * + * @author Sander Coolen <sander@jibber.nl> + */ +interface UriRetrieverInterface +{ + /** + * Retrieve a schema from the specified URI + * @param string $uri URI that resolves to a JSON schema + * @throws \JsonSchema\Exception\ResourceNotFoundException + * @return mixed string|null + */ + public function retrieve($uri); + + /** + * Get media content type + * @return string + */ + public function getContentType(); +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriResolver.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,154 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Uri; + +use JsonSchema\Exception\UriResolverException; +use JsonSchema\UriResolverInterface; + +/** + * Resolves JSON Schema URIs + * + * @author Sander Coolen <sander@jibber.nl> + */ +class UriResolver implements UriResolverInterface +{ + /** + * Parses a URI into five main components + * + * @param string $uri + * @return array + */ + public function parse($uri) + { + preg_match('|^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?|', $uri, $match); + + $components = array(); + if (5 < count($match)) { + $components = array( + 'scheme' => $match[2], + 'authority' => $match[4], + 'path' => $match[5] + ); + } + if (7 < count($match)) { + $components['query'] = $match[7]; + } + if (9 < count($match)) { + $components['fragment'] = $match[9]; + } + + return $components; + } + + /** + * Builds a URI based on n array with the main components + * + * @param array $components + * @return string + */ + public function generate(array $components) + { + $uri = $components['scheme'] . '://' + . $components['authority'] + . $components['path']; + + if (array_key_exists('query', $components)) { + $uri .= $components['query']; + } + if (array_key_exists('fragment', $components)) { + $uri .= '#' . $components['fragment']; + } + + return $uri; + } + + /** + * {@inheritdoc} + */ + public function resolve($uri, $baseUri = null) + { + if ($uri == '') { + return $baseUri; + } + + $components = $this->parse($uri); + $path = $components['path']; + + if (! empty($components['scheme'])) { + return $uri; + } + $baseComponents = $this->parse($baseUri); + $basePath = $baseComponents['path']; + + $baseComponents['path'] = self::combineRelativePathWithBasePath($path, $basePath); + if (isset($components['fragment'])) { + $baseComponents['fragment'] = $components['fragment']; + } + + return $this->generate($baseComponents); + } + + /** + * Tries to glue a relative path onto an absolute one + * + * @param string $relativePath + * @param string $basePath + * @return string Merged path + * @throws UriResolverException + */ + public static function combineRelativePathWithBasePath($relativePath, $basePath) + { + $relativePath = self::normalizePath($relativePath); + if ($relativePath == '') { + return $basePath; + } + if ($relativePath{0} == '/') { + return $relativePath; + } + + $basePathSegments = explode('/', $basePath); + + preg_match('|^/?(\.\./(?:\./)*)*|', $relativePath, $match); + $numLevelUp = strlen($match[0]) /3 + 1; + if ($numLevelUp >= count($basePathSegments)) { + throw new UriResolverException(sprintf("Unable to resolve URI '%s' from base '%s'", $relativePath, $basePath)); + } + + $basePathSegments = array_slice($basePathSegments, 0, -$numLevelUp); + $path = preg_replace('|^/?(\.\./(\./)*)*|', '', $relativePath); + + return implode('/', $basePathSegments) . '/' . $path; + } + + /** + * Normalizes a URI path component by removing dot-slash and double slashes + * + * @param string $path + * @return string + */ + private static function normalizePath($path) + { + $path = preg_replace('|((?<!\.)\./)*|', '', $path); + $path = preg_replace('|//|', '/', $path); + + return $path; + } + + /** + * @param string $uri + * @return boolean + */ + public function isValid($uri) + { + $components = $this->parse($uri); + + return !empty($components); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriRetriever.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,286 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema\Uri; + +use JsonSchema\Uri\Retrievers\FileGetContents; +use JsonSchema\Uri\Retrievers\UriRetrieverInterface; +use JsonSchema\UriRetrieverInterface as BaseUriRetrieverInterface; +use JsonSchema\Validator; +use JsonSchema\Exception\InvalidSchemaMediaTypeException; +use JsonSchema\Exception\JsonDecodingException; +use JsonSchema\Exception\ResourceNotFoundException; + +/** + * Retrieves JSON Schema URIs + * + * @author Tyler Akins <fidian@rumkin.com> + */ +class UriRetriever implements BaseUriRetrieverInterface +{ + /** + * @var null|UriRetrieverInterface + */ + protected $uriRetriever = null; + + /** + * @var array|object[] + * @see loadSchema + */ + private $schemaCache = array(); + + /** + * Guarantee the correct media type was encountered + * + * @param UriRetrieverInterface $uriRetriever + * @param string $uri + * @return bool|void + */ + public function confirmMediaType($uriRetriever, $uri) + { + $contentType = $uriRetriever->getContentType(); + + if (is_null($contentType)) { + // Well, we didn't get an invalid one + return; + } + + if (in_array($contentType, array(Validator::SCHEMA_MEDIA_TYPE, 'application/json'))) { + return; + } + + if (substr($uri, 0, 23) == 'http://json-schema.org/') { + //HACK; they deliver broken content types + return true; + } + + throw new InvalidSchemaMediaTypeException(sprintf('Media type %s expected', Validator::SCHEMA_MEDIA_TYPE)); + } + + /** + * Get a URI Retriever + * + * If none is specified, sets a default FileGetContents retriever and + * returns that object. + * + * @return UriRetrieverInterface + */ + public function getUriRetriever() + { + if (is_null($this->uriRetriever)) { + $this->setUriRetriever(new FileGetContents); + } + + return $this->uriRetriever; + } + + /** + * Resolve a schema based on pointer + * + * URIs can have a fragment at the end in the format of + * #/path/to/object and we are to look up the 'path' property of + * the first object then the 'to' and 'object' properties. + * + * @param object $jsonSchema JSON Schema contents + * @param string $uri JSON Schema URI + * @return object JSON Schema after walking down the fragment pieces + * + * @throws ResourceNotFoundException + */ + public function resolvePointer($jsonSchema, $uri) + { + $resolver = new UriResolver(); + $parsed = $resolver->parse($uri); + if (empty($parsed['fragment'])) { + return $jsonSchema; + } + + $path = explode('/', $parsed['fragment']); + while ($path) { + $pathElement = array_shift($path); + if (! empty($pathElement)) { + $pathElement = str_replace('~1', '/', $pathElement); + $pathElement = str_replace('~0', '~', $pathElement); + if (! empty($jsonSchema->$pathElement)) { + $jsonSchema = $jsonSchema->$pathElement; + } else { + throw new ResourceNotFoundException( + 'Fragment "' . $parsed['fragment'] . '" not found' + . ' in ' . $uri + ); + } + + if (! is_object($jsonSchema)) { + throw new ResourceNotFoundException( + 'Fragment part "' . $pathElement . '" is no object ' + . ' in ' . $uri + ); + } + } + } + + return $jsonSchema; + } + + /** + * {@inheritdoc} + */ + public function retrieve($uri, $baseUri = null) + { + $resolver = new UriResolver(); + $resolvedUri = $fetchUri = $resolver->resolve($uri, $baseUri); + + //fetch URL without #fragment + $arParts = $resolver->parse($resolvedUri); + if (isset($arParts['fragment'])) { + unset($arParts['fragment']); + $fetchUri = $resolver->generate($arParts); + } + + $jsonSchema = $this->loadSchema($fetchUri); + + // Use the JSON pointer if specified + $jsonSchema = $this->resolvePointer($jsonSchema, $resolvedUri); + + if ($jsonSchema instanceof \stdClass) { + $jsonSchema->id = $resolvedUri; + } + + return $jsonSchema; + } + + /** + * Fetch a schema from the given URI, json-decode it and return it. + * Caches schema objects. + * + * @param string $fetchUri Absolute URI + * + * @return object JSON schema object + */ + protected function loadSchema($fetchUri) + { + if (isset($this->schemaCache[$fetchUri])) { + return $this->schemaCache[$fetchUri]; + } + + $uriRetriever = $this->getUriRetriever(); + $contents = $this->uriRetriever->retrieve($fetchUri); + $this->confirmMediaType($uriRetriever, $fetchUri); + $jsonSchema = json_decode($contents); + + if (JSON_ERROR_NONE < $error = json_last_error()) { + throw new JsonDecodingException($error); + } + + $this->schemaCache[$fetchUri] = $jsonSchema; + + return $jsonSchema; + } + + /** + * Set the URI Retriever + * + * @param UriRetrieverInterface $uriRetriever + * @return $this for chaining + */ + public function setUriRetriever(UriRetrieverInterface $uriRetriever) + { + $this->uriRetriever = $uriRetriever; + + return $this; + } + + /** + * Parses a URI into five main components + * + * @param string $uri + * @return array + */ + public function parse($uri) + { + preg_match('|^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?|', $uri, $match); + + $components = array(); + if (5 < count($match)) { + $components = array( + 'scheme' => $match[2], + 'authority' => $match[4], + 'path' => $match[5] + ); + } + + if (7 < count($match)) { + $components['query'] = $match[7]; + } + + if (9 < count($match)) { + $components['fragment'] = $match[9]; + } + + return $components; + } + + /** + * Builds a URI based on n array with the main components + * + * @param array $components + * @return string + */ + public function generate(array $components) + { + $uri = $components['scheme'] . '://' + . $components['authority'] + . $components['path']; + + if (array_key_exists('query', $components)) { + $uri .= $components['query']; + } + + if (array_key_exists('fragment', $components)) { + $uri .= $components['fragment']; + } + + return $uri; + } + + /** + * Resolves a URI + * + * @param string $uri Absolute or relative + * @param string $baseUri Optional base URI + * @return string + */ + public function resolve($uri, $baseUri = null) + { + $components = $this->parse($uri); + $path = $components['path']; + + if ((array_key_exists('scheme', $components)) && ('http' === $components['scheme'])) { + return $uri; + } + + $baseComponents = $this->parse($baseUri); + $basePath = $baseComponents['path']; + + $baseComponents['path'] = UriResolver::combineRelativePathWithBasePath($path, $basePath); + + return $this->generate($baseComponents); + } + + /** + * @param string $uri + * @return boolean + */ + public function isValid($uri) + { + $components = $this->parse($uri); + + return !empty($components); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/UriResolverInterface.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,25 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema; + +/** + * @package JsonSchema + */ +interface UriResolverInterface +{ + /** + * Resolves a URI + * + * @param string $uri Absolute or relative + * @param null|string $baseUri Optional base URI + * @return string Absolute URI + */ + public function resolve($uri, $baseUri = null); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/UriRetrieverInterface.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,25 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema; + +/** + * @package JsonSchema + */ +interface UriRetrieverInterface +{ + /** + * Retrieve a URI + * + * @param string $uri JSON Schema URI + * @param null|string $baseUri + * @return object JSON Schema contents + */ + public function retrieve($uri, $baseUri = null); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Validator.php Tue Jul 18 16:27:22 2017 +0800 @@ -0,0 +1,40 @@ +<?php + +/* + * This file is part of the JsonSchema package. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace JsonSchema; + +use JsonSchema\Constraints\Constraint; +use JsonSchema\Entity\JsonPointer; + +/** + * A JsonSchema Constraint + * + * @author Robert Schönthal <seroscho@googlemail.com> + * @author Bruno Prieto Reis <bruno.p.reis@gmail.com> + * @see README.md + */ +class Validator extends Constraint +{ + const SCHEMA_MEDIA_TYPE = 'application/schema+json'; + + /** + * Validates the given data against the schema and returns an object containing the results + * Both the php object and the schema are supposed to be a result of a json_decode call. + * The validation works as defined by the schema proposal in http://json-schema.org + * + * {@inheritDoc} + */ + public function check($value, $schema = null, JsonPointer $path = null, $i = null) + { + $validator = $this->factory->createInstanceFor('schema'); + $validator->check($value, $schema); + + $this->addErrors(array_unique($validator->getErrors(), SORT_REGULAR)); + } +}