天猫精灵开放平台实验—基于模板创建开发屏显页面技能
一、前提准备
使用本地 VSCode 快速开发一个技能屏显界面,并通过控制台的操作连接猫精设备进行真机测试。
- 1、本实验目前支持CentOS、Ubuntu、MacOS上支持。本实验采用Ubuntu 20.4系统。
- 2、在Ubuntu系统上安装VSCode开发软件。# 系列文章目录
二、登录天猫精灵开放平台
1、登录天猫精灵开放平台 ,登陆后点击控制台,选择技能应用平台并点击进入。
(一)创建新技能
1、创建语音技能
2、填写基本信息
(二)创建后端服务
1、创建后端服务
2、关联阿里云账号
登录阿里云账号
完成授权,点击下一步。
开通相关服务。
3、创建技能应用
创建应用
保存创建的服务
点击“前往开发”。
查看语音交互模型已经自动完成创建
4、调试代码
示例代码如下
package com.alibaba.ailabs; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import com.alibaba.ailabs.common.AbstractEntry; import com.alibaba.da.coin.ide.spi.meta.AskedInfoMsg; import com.alibaba.da.coin.ide.spi.meta.ExecuteCode; import com.alibaba.da.coin.ide.spi.meta.GwCommand; import com.alibaba.da.coin.ide.spi.meta.ResultType; import com.alibaba.da.coin.ide.spi.standard.ResultModel; import com.alibaba.da.coin.ide.spi.standard.TaskQuery; import com.alibaba.da.coin.ide.spi.standard.TaskResult; import com.alibaba.fastjson.JSON; import com.aliyun.fc.runtime.Context; import com.google.common.collect.Lists; /** * @Description 天猫精灵技能函数入口,FC handler:com.alibaba.ailabs.GenieEntry::handleRequest * @Version 1.0 **/ public class GenieEntry extends AbstractEntry { @Override public ResultModel<TaskResult> execute(TaskQuery taskQuery, Context context) { context.getLogger().info("taskQuery: " + JSON.toJSONString(taskQuery)); //String screenStatus = taskQuery.getRequestData().get("screenStatus"); String screenStatus = "online"; // 从请求中获取意图参数以及参数值 Map<String, String> paramMap = taskQuery.getSlotEntities().stream().collect( Collectors.toMap(slotItem -> slotItem.getIntentParameterName(), slotItem -> slotItem.getOriginalValue())); String reply; String city = paramMap.get("city"); String date = paramMap.get("date"); //处理名称为 weather 的意图 if ("weather".equals(taskQuery.getIntentName())) { //weather 意图中 date 参数勾选了必选,请求数据中一定会携带 date 参数,只需要判断 city 参数有没有。 if (city == null) { reply = "您要查询哪个城市的天气?"; return askReply(reply, "city", taskQuery.getIntentId()); } //TODO 根据参数获取天气信息,这里使用假数据替代 reply = city + date + "天气 晴。"; if ("online".equals(screenStatus)) { return weatherTplReply(reply, city); } else { return reply(reply); } //处理名称为 air_quality 的意图 } else if ("air_quality".equals(taskQuery.getIntentName())) { //air_quality 意图中 date 参数勾选了必选,请求数据中一定会携带 date 参数,只需要判断 city 参数有没有。 if (city == null) { reply = "您要查询哪个城市的空气质量?"; return askReply(reply, "city", taskQuery.getIntentId()); } //TODO 根据参数获取空气质量信息,这里使用假数据替代 reply = city + date + "空气质量46 优。"; if ("online".equals(screenStatus)) { return airTplReply(reply, city); } else { return reply(reply); } } reply = "请检查意图名称是否正确,或者新增的意图没有在代码里添加对应的处理分支。"; return reply(reply); } /** * 结束对话的回复,回复后音箱闭麦 */ private ResultModel<TaskResult> reply(String reply) { ResultModel<TaskResult> res = new ResultModel<>(); TaskResult taskResult = new TaskResult(); taskResult.setReply(reply); taskResult.setExecuteCode(ExecuteCode.SUCCESS); taskResult.setResultType(ResultType.RESULT); res.setReturnCode("0"); res.setReturnValue(taskResult); return res; } /** * 指定追问参数,音箱自动开麦,用户的回答优先匹配追问的参数 */ private ResultModel<TaskResult> askReply(String reply, String parameterName, Long intentId) { ResultModel<TaskResult> res = new ResultModel<>(); TaskResult taskResult = new TaskResult(); taskResult.setReply(reply); taskResult.setExecuteCode(ExecuteCode.SUCCESS); taskResult.setResultType(ResultType.ASK_INF); AskedInfoMsg askedInfoMsg = new AskedInfoMsg(parameterName, intentId); taskResult.setAskedInfos(Lists.newArrayList(askedInfoMsg)); res.setReturnCode("0"); res.setReturnValue(taskResult); return res; } /** * 天气查询意图的TPL回复 */ private ResultModel<TaskResult> weatherTplReply(String reply, String city) { return commonReply(reply, city, reply); } /** * 空气质量查询意图的TPL回复 */ private ResultModel<TaskResult> airTplReply(String reply, String city) { return commonReply(reply, city, reply); } private ResultModel<TaskResult> commonReply(String reply, String city, String detail) { //屏显模板数据需要使用gwCommands字段携带,会导致reply失效。回复内容通过speak指令返回 GwCommand speakGwCommand = new GwCommand("AliGenie.Speaker", "Speak"); HashMap<String, Object> payload = new HashMap<>(); payload.put("type", "text"); payload.put("text", reply); speakGwCommand.setPayload(payload); //携带屏显模板数据的指令 GwCommand tplGwCommand = new GwCommand("AliGenie.Screen", "Render"); HashMap<String, Object> payload1 = new HashMap<>(); payload1.put("pageType", "TPL.RenderTemplate"); payload1.put("pageTitle", "天气小助手"); //模板标识数据 HashMap<String, Object> data = new HashMap<>(); data.put("template", "aligenie_weather_tpl"); //模板中展示内容的字段 dataSource HashMap<String, String> dataSource = new HashMap<>(); dataSource.put("imageUrl", "https://ailabs-iot.aligenie.com/iap/platform3.0/weather-banner.png"); dataSource.put("city", city); dataSource.put("minTemperature", "36°"); dataSource.put("maxTemperature", "38°"); dataSource.put("detail", detail); data.put("dataSource", dataSource); payload1.put("data", data); tplGwCommand.setPayload(payload1); return tplReply(Lists.newArrayList(speakGwCommand, tplGwCommand)); } /** * 携带TPL数据的结束对话回复,回复后音箱闭麦 */ private ResultModel<TaskResult> tplReply(List<GwCommand> gwCommands) { ResultModel<TaskResult> res = new ResultModel<>(); TaskResult taskResult = new TaskResult(); taskResult.setExecuteCode(ExecuteCode.SUCCESS); taskResult.setResultType(ResultType.RESULT); taskResult.setGwCommands(gwCommands); res.setReturnCode("0"); res.setReturnValue(taskResult); return res; } }
5、推送代码至远程分支
为防止您的代码丢失,请务必提交并推送代码到远程分支
[admin@f99f9e13-a8b9-4189-bada-d24034966e0e-77d8d5765d-h8vtm /home/admin/workspace/codeup.aliyun.com/618249ae404574409feabd87/workbench/repo_2021-11-10_2021111001491236] $git status On branch master Your branch is up to date with 'origin/master'. Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: src/main/java/com/alibaba/ailabs/GenieEntry.java no changes added to commit (use "git add" and/or "git commit -a") [admin@f99f9e13-a8b9-4189-bada-d24034966e0e-77d8d5765d-h8vtm /home/admin/workspace/codeup.aliyun.com/618249ae404574409feabd87/workbench/repo_2021-11-10_2021111001491236] $git add src [admin@f99f9e13-a8b9-4189-bada-d24034966e0e-77d8d5765d-h8vtm /home/admin/workspace/codeup.aliyun.com/618249ae404574409feabd87/workbench/repo_2021-11-10_2021111001491236] $git commit -m "weather_tpl" [master 4bf99d6] weather_tpl 1 file changed, 1 insertion(+), 1 deletion(-) [admin@f99f9e13-a8b9-4189-bada-d24034966e0e-77d8d5765d-h8vtm /home/admin/workspace/codeup.aliyun.com/618249ae404574409feabd87/workbench/repo_2021-11-10_2021111001491236] $git push Counting objects: 9, done. Delta compression using up to 5 threads. Compressing objects: 100% (5/5), done. Writing objects: 100% (9/9), 632 bytes | 42.00 KiB/s, done. Total 9 (delta 2), reused 0 (delta 0) To https://codeup.aliyun.com/618249ae404574409feabd87/workbench/repo_2021-11-10_2021111001491236.git 4235ca4..4bf99d6 master -> master [admin@f99f9e13-a8b9-4189-bada-d24034966e0e-77d8d5765d-h8vtm /home/admin/workspace/codeup.aliyun.com/618249ae404574409feabd87/workbench/repo_2021-11-10_2021111001491236] $
6、部署代码