讯飞摩飞语音设备开发实战java版

目的
语音控制灯等硬件设备,比如开灯,关灯
流程
语音 - 解析 -讯飞服务器 - 我们的后台 -控制硬件
研究
讯飞平台创建app 上面有appid 和key要推送到摩飞设备
http://aiui.xfyun.cn/apps/
电脑连接摩飞

adb devices 可以看到连接的摩飞设备

不行就是试一下adb kill-server

和 adb reconnect

cd 进入/Users/zhanglilong/Downloads/Morfei评估板开发包/Morfei 目录/tools

修改aiui.cfg文件中appid、key和scene的值,并保存

然后执行推送

adb push aiui.cfg /sdcard/AIUI/cfg/aiui.cfg

然后adb reboot 重启设备

通过adb pull /sdcard/AIUI/cfg/aiui.cfg

查看文件是否修改成功

注意 还有一个参数要改,main改为mian_box
、、、
“global”: {
“scene”: “main_box”
},
、、、
开始设置讯飞服务器调用的接口,自己定义的接口,每次语音说开灯,讯飞就调用你自己开发的接口,执行真实的开灯的操作
http://111.222.0.111:9000/api/mofei/test2
比如这个链接就是我们处理语音的接口,在 http://aiui.xfyun.cn/apps/
这里找到后处理链接处填写我们的接口

路由
、、、
GET /api/mofei/test2 thirdparty.MoFei.test
POST /api/mofei/test2 thirdparty.MoFei.xfjson
、、、

还有一个语音自定义技能需要添加

语料处可以这么加
{sth}[{dengName}][{jobName}][{sth}]

槽位标示jobName 对应实体@jobnames 实体里面我就设置了一个词条 “灯”

槽位标示 sth 代表通配实体,这样你说话加一点前缀或者后缀都没事了 @IFLYTEK.Wildcard [1,10]

槽位标示dengName 对应实体@dengName 实体里面我设置v6 v3 L这是灯的名称

调用的接口相关代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
package controllers.thirdparty;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.commons.io.IOUtils;
import com.jd.open.api.sdk.internal.util.codec.Base64;
import jobs.LightJob;
import jobs.NewTask;
import jobs.SocketJob;
import models.Ams_archives;
import models.Device_manage;
import models.Front_User;
import models.TaskInfo;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import utils.mofei.AESUtils;
import utils.mofei.Sha1EncodeUtils;
public class MoFei extends Application {
//这个我已瞎写的,请自己替换
private static final String token = "b54db7ffffff83b7";
private static final String aeskey = "24235c1fffff9cc5";
public static void xfjson(String encrypttype) {
System.out.println("encrypttype:"+encrypttype);
// NOTE !!!!
// AES decrypt and encrypt may mot be used in your server
// you may debug it again and again to make it.
// welcome to email me: lmliu@iflytek.com if something wrong with you.
if (encrypttype.equals("aes")) {
System.out.println("AES Decrypt Mode.");
String jsonstr;
try {
jsonstr = IOUtils.toString(request.body);
System.out.println(jsonstr);
JSONObject obj = JSONObject.fromObject(jsonstr);
// String alarm_type_name = obj.getString("alarm_type_name");//报警类型
renderJSON(AESUtils.encrypt(aeskey, aeskey, jsonstr.toString()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// response.setContentType("application/json;charset=utf-8");
// response.getWriter().append(AESUtils.encrypt(aeskey, aeskey, customData.toString()));
} else {
//aiui.log(Level.INFO, "Normal Mode.");
System.out.println("Normal Mode.");
String jsonstr="";
try {
jsonstr = IOUtils.toString(request.body);
System.out.println(jsonstr);
JSONObject obj = JSONObject.fromObject(jsonstr);
JSONObject msgJson = obj.getJSONObject("Msg");
String content = msgJson.getString("Content");
content = new String(Base64.decodeBase64(content.getBytes()));
System.out.println(content);
JSONObject obj1 = JSONObject.fromObject(content);
System.out.println(obj1);
JSONObject obj2 = obj1.getJSONObject("intent");
if(obj2.containsKey("semantic")){
JSONArray semantic = obj2.getJSONArray("semantic");
JSONObject slots = semantic.getJSONObject(0);
System.out.println(slots.getString("intent"));
String action =slots.getString("intent");
if ("deng".equals(action)) { //开v3 v6 L 灯
String dengName="";
JSONArray array = slots.getJSONArray("slots");
for(int i=0;i<array.size();i++){
JSONObject job = array.getJSONObject(i);
if ("dengName".equals(job.getString("name"))) {
dengName = job.getString("normValue");
}
}
if ("V3".equals(dengName)) {
new LightJob("open", "192.168.1.154").now();
}else if ("V6".equals(dengName)) {
new LightJob("open", "192.168.1.156").now();
}else if ("L".equals(dengName)) {
new LightJob("open", "192.168.1.153").now();
}else {
try {
new LightJob("open", "192.168.1.153").now();
Thread.sleep(300);
new LightJob("open", "192.168.1.154").now();
Thread.sleep(300);
new LightJob("open", "192.168.1.156").now();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}else if ("closed".equals(action)) { //关v3 v6 L 灯
String dengName="";
JSONArray array = slots.getJSONArray("slots");
for(int i=0;i<array.size();i++){
JSONObject job = array.getJSONObject(i);
if ("dengName".equals(job.getString("name"))) {
dengName = job.getString("normValue");
}
}
if ("V3".equals(dengName)) {
new LightJob("close", "192.168.1.154").now();
}else if ("V6".equals(dengName)) {
new LightJob("close", "192.168.1.156").now();
}else if ("L".equals(dengName)) {
new LightJob("close", "192.168.1.153").now();
}else {
try {
new LightJob("close", "192.168.1.153").now();
Thread.sleep(300);
new LightJob("close", "192.168.1.154").now();
Thread.sleep(300);
new LightJob("close", "192.168.1.156").now();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//JSONArray array = slots.getJSONArray("slots");
//System.out.println("slots:normValue"+array.getJSONObject(0).getString("normValue"));
}
renderJSON(jsonstr.toString());
} catch (IOException e) {
e.printStackTrace();
renderJSON(jsonstr.toString());
}
}
}
public static void test(String signature,String timestamp,String rand) {
if (signature == null || timestamp == null || rand == null) {
return;
}
if (signature.isEmpty() || rand.isEmpty() || timestamp.isEmpty()) {
return;
}
List<String> list = new ArrayList<String>();
list.add(token);
list.add(timestamp);
list.add(rand);
Collections.sort(list);
String localSig = "";
for (int i = 0; i < list.size(); i++) {
localSig += list.get(i);
}
String sigtureSha1 = Sha1EncodeUtils.encode(localSig);
if (sigtureSha1.equals(signature)) {
//renderJSON(Sha1EncodeUtils.encode(token));
renderHtml(Sha1EncodeUtils.encode(token));
} else {
// renderJSON("check token failed" + sigtureSha1);
renderHtml("check token failed" + sigtureSha1);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package utils.mofei;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.security.Security;
public class AESUtils {
// u8 charset
protected static final Charset CHARSET_U8 = Charset.forName("utf-8");
// u8 string
protected static final String CHARSET_U8_STR = "utf-8";
/**
* AES加密
*
* @param serectKey 秘钥
* @param ivKey 向量偏移量
* @param content 要加密的文本
* @return
*/
public static String encrypt ( String serectKey, String ivKey, String content) {
String encryptMode = "AES/CBC/PKCS7Padding";
String encyptedContent = null;
try {
String encyptType = encryptMode;
SecretKeySpec keyspec = new SecretKeySpec(serectKey.getBytes(CHARSET_U8), "AES");
Cipher cipher = Cipher.getInstance(encyptType,"BC");
IvParameterSpec iv = new IvParameterSpec(ivKey.getBytes(CHARSET_U8));
cipher.init(Cipher.ENCRYPT_MODE, keyspec, iv);
byte[] byte_encode = content.getBytes(CHARSET_U8_STR);
byte_encode = cipher.doFinal(byte_encode);
encyptedContent = new String(byte_encode);
} catch (Exception e) {
}
return encyptedContent;
}
public static String decrypt(String secretKey, String ivKey, byte[] content){
String encryptMode = "AES/CBC/PKCS7Padding";
byte[] secrecKeyByte = secretKey.getBytes(CHARSET_U8);
String decryptContent = null;
try {
Security.addProvider(new BouncyCastleProvider());
SecretKeySpec keyspec = new SecretKeySpec(secrecKeyByte, "AES");
Cipher cipher = Cipher.getInstance(encryptMode, "BC");
IvParameterSpec iv = new IvParameterSpec(ivKey.getBytes(CHARSET_U8));
cipher.init(Cipher.DECRYPT_MODE, keyspec, iv);
byte[] byte_content = cipher.doFinal(content);
decryptContent = new String(byte_content, CHARSET_U8_STR);
} catch (Exception e) {
e.printStackTrace();
}
return decryptContent;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package utils.mofei;
import java.security.MessageDigest;
public class Sha1EncodeUtils {
private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
private static String getFormattedText(byte[] bytes) {
int len = bytes.length;
StringBuilder buf = new StringBuilder(len * 2);
// 把密文转换成十六进制的字符串形式
for (int j = 0; j < len; j++) {
buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
}
return buf.toString();
}
public static String encode(String str) {
if (str == null) {
return null;
}
try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
messageDigest.update(str.getBytes());
return getFormattedText(messageDigest.digest());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}