小优机器人WIFI+SSDP入网具体实现
Posted canbot
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小优机器人WIFI+SSDP入网具体实现相关的知识,希望对你有一定的参考价值。
小优入网实现
1. 小优响应设备查询服务
当小优连接网络时,开启一个SSDP后台服务后,除了向局域网广播通知自己存在,还创建了一个广播监听线程,当收到智能网关发来的设备查询服务广播时,如下:
SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: “ssdp:discover”
MX: 120
ST: ssdp:all
广播监听线程会立刻响应查询服务,发送小优存在广告通知,信息内容跟入网时发的一样,如下:
NOTIFY * HTTP/1.1
Host: 239.255.255.250:1900
NT: urn:schemas-upnp-org:device:CanbotRobot:1
NTS: ssdp:alive
USN:uuid:Upnp-KL-U03S-1_0-04e67647e222::urn:schemas-upnp-org:device:CanbotRobot
Cache-Control: max-age = 1800
通过收到的设备查询服务广播,小优可以获取智能网关的ip地址,为接下来的通信提供目标地址,最后当网络断开时,会停止SSDP后台服务,再次连接网络时再启动。
2. 小优端声控指令转字符串
小优端获取到声音指令后,转化为字符串,对字符串做判断比较,是否符合本地指令,符合的就本地处理,不符合的字符串,就把它发送到智能网关处理。
小优端核心代码如下:
LanSend类主要实现ssdp加入多播组、监听发现服务并单播响应信息
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import android.content.Context;
import android.util.Log;
public class LanSend {
/**
* @param args
* @throws Exception
*/
//广播地址
private static final String BROADCAST_IP = SSDPUtils.ADDRESS;//广播IP
private static final int BROADCAST_INT_PORT = SSDPUtils.PORT; // 不同的port对应不同的socket发送端和接收端
MulticastSocket broadSocket ;//用于接收广播信息
public static boolean work=false;//循环监听因子
InetAddress broadAddress ;//广播地址
//DatagramSocket数据报Socket
DatagramSocket sender ;//数据流套接字 相当于码头,用于发送信息
private Context context;
// private InetSocketAddress mMulticastGroup;
public LanSend(Context contex) {
try {
this.context=contex;
//初始化
broadSocket=new MulticastSocket(BROADCAST_INT_PORT); //多播Socket
// mMulticastGroup = new InetSocketAddress(SSDPUtils.ADDRESS, SSDPUtils.PORT);
broadAddress = InetAddress.getByName(BROADCAST_IP);//获取网络多播地址
sender = new DatagramSocket();
} catch (Exception e) {
// TODO: handle exception
System.out.println("*****lanSend初始化失败*****"+e.toString());
}
}
public void join() {
try{
Log.e("LanSend", "join");
broadSocket.joinGroup(broadAddress); //把套接字socket加入到组播地址,这样就能接收到组播信息
new Thread(new GetPacket()).start(); //新建一个线程,用于循环侦听端口信息
}catch (Exception e) {
// TODO: handle exception
System.out.println("*****加入组播失败*****");
}
}
//广播发送查找在线用户
void sendGetUserMsg() {
byte[] b=new byte[1024];
DatagramPacket packet; //数据包,相当于集装箱,封装信息
try{
b = SSDPUtils.buildSSDPSearchString().getBytes();
packet = new DatagramPacket(b, b.length, broadAddress, BROADCAST_INT_PORT); //广播信息到指定端口
sender.send(packet);//单播信息会给目标主机
System.out.println("*****已发送请求*****");
}catch (Exception e) {
System.out.println("*****查找出错*****");
}
}
//当局域网内的在线机子收到广播信息时响应并向发送广播的ip地址(此处广播自己的存在来响应)主机发送返还信息,达到交换信息的目的
void returnUserMsg(String mac){
byte[] b=new byte[1024];
DatagramPacket packet;
try {
b=SSDPUtils.buildSSDPAliveString(mac).getBytes();
packet = new DatagramPacket(b,b.length,broadAddress, BROADCAST_INT_PORT);
sender.send(packet);
System.out.print("发送信息成功!");
} catch (Exception e) {
// TODO: handle exception
System.out.println("*****发送返还信息失败*****"+e);
}
}
//当局域网内的在线机子收到广播信息时响应并向发送广播的ip地址主机发送返还信息,达到交换信息的目的
void returnUserMsg(String mac,InetAddress inetaddress,int port){
byte[] b=new byte[1024];
DatagramPacket packet;
try {
b=SSDPUtils.buildSSDPAliveString(mac).getBytes();
packet = new DatagramPacket(b,b.length,inetaddress, port);
sender.send(packet);
System.out.print("发送信息成功!");
} catch (Exception e) {
// TODO: handle exception
System.out.println("*****发送返还信息失败*****"+e);
}
}
//当局域网某机子下线是需要广播发送下线通知
void offLine(){
byte[] b=new byte[1024];
DatagramPacket packet;
try {
b=SSDPUtils.buildSSDPByebyeString().getBytes();
packet = new DatagramPacket(b,b.length,broadAddress, BROADCAST_INT_PORT);
sender.send(packet);
System.out.println("*****已离线*****");
} catch (Exception e) {
// TODO: handle exception
System.out.println("*****离线异常*****");
}
}
class GetPacket implements Runnable { //新建的线程,用于侦听,packet数据包
public void run() {
DatagramPacket inPacket;
work=true;
String[] message;
while(work){
try {
Log.e("LanSend", "GetPacket while");
inPacket=new DatagramPacket(new byte[1024], 1024);
broadSocket.receive(inPacket); //接收广播信息并将信息封装到inPacket中
// inPacket.getData()
// message=new String(inPacket.getData(),0,inPacket.getLength()).split("@"); //获取信息,并切割头部,判断是何种信息(find--上线,retn--回答,offl--下线)
String data=new String(inPacket.getData()).trim();
if (data!=null) {
String socketAddress=inPacket.getSocketAddress().toString();
String[] datas=data.split(SSDPUtils.NEWLINE);
for (int i = 0; i < datas.length; i++) {
Log.e("LanSend", "datas["+i+"] = "+datas[i]);
if (datas[i].trim().equalsIgnoreCase("ST: ssdp:all")) {
Log.e("ALIVE", "response");
String mac=SSDPUtils.getUserId(context);
InetAddress sourceip=inPacket.getAddress();
int port=inPacket.getPort();
returnUserMsg(mac,sourceip,port);
break;
}
}
Log.e("LanSend", "收到的数据包的 data :"+data+" 数据包的socketAddress:"+socketAddress);
System.out.println("收到的数据包的 data :"+data+" 数据包的socketAddress:"+socketAddress);
}
} catch (Exception e) {
// TODO: handle exception
System.out.println("线程出错 "+e);
}
}
}
}
}
SSDPUtils 为SSDP工具类,主要实现小优ssdp信息的生成
import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.util.Log;
/**
* Created by florent.noel on 6/14/13.
*/
public class SSDPUtils {
private static String TAG = SSDPUtils.class.getName();
public static final String ADDRESS = "239.255.255.250";
public static final int PORT = 1900;
public static final int MAX_REPLY_TIME = 5;
public static final int MSG_TIMEOUT = MAX_REPLY_TIME * 1000 + 1000;
public static final String STRING_MSEARCH = "M-SEARCH * HTTP/1.1";
public static final String NOTIFY_MSEARCH = "NOTIFY * HTTP/1.1";
// public static final String STRING_RootDevice = "ST: upnp:rootdevice";
public static final String STRING_AllDevice = "ST: ssdp:all";
public static final String NEWLINE = "\\r\\n";
public static final String MAN = "Man:\\"ssdp:discover\\"";
public static String LOCATION_TEXT = "LOCATION: http://";
public static String buildSSDPSearchString(){
StringBuilder content = new StringBuilder();
content.append(STRING_MSEARCH).append(NEWLINE);
content.append("Host: " + ADDRESS + ":" + PORT).append(NEWLINE);
content.append(MAN).append(NEWLINE);
content.append("MX: " + MAX_REPLY_TIME).append(NEWLINE);
content.append(STRING_AllDevice).append(NEWLINE);
content.append(NEWLINE);
Log.e(TAG, content.toString());
return content.toString();
}
/**
* 方法描述:获取本地userId方法
* @param String app_name
* @return
* @see RobotUtil
*/
public static String getUserId(Context context) {
WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
if (!wifi.isWifiEnabled()) {
wifi.setWifiEnabled(true);
}
WifiInfo info = wifi.getConnectionInfo();
String mac = info.getMacAddress();
if(mac==null)
{
if (!wifi.isWifiEnabled()) {
wifi.setWifiEnabled(true);
}
long starttime = System.currentTimeMillis();
while(true&&System.currentTimeMillis()-starttime<5000){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
info = wifi.getConnectionInfo();
mac = info.getMacAddress();
if(mac!=null)
{
break;
}
}
if (mac==null) {
Log.e("getUserId","getUserId失败 ");
return null;
}
}
Log.e("getUserId","getUserId "+mac);
String str=mac.replace(":", "");
// StringBuffer a = new StringBuffer(mac);
// a.deleteCharAt(2).deleteCharAt(4).deleteCharAt(6).deleteCharAt(8)
// .deleteCharAt(10);
// mac = a.toString();
return str;
}
/**
* NOTIFY * HTTP/1.1
ST: urn: schemas-upnp-org:device: 设备名称:1
HOST: 239.255.255.250:1900
EXT:
CACHE-CONTROL: max-age=1800
LOCATION: http://127.0.0.1:8008/ssdp/device-desc.xml
CONFIGID.UPNP.ORG: 7339
BOOTID.UPNP.ORG: 7339
USN: uuid: Upnp-设备系列号-设备识别号::urn:schemas-upnp-org:device:设备名称
*/
public static String buildSSDPAliveString(String mac){
StringBuilder content = new StringBuilder();
// content.append("HTTP/1.1 200 OK").append(NEWLINE);
content.append(NOTIFY_MSEARCH).append(NEWLINE);
content.append("ST: urn:schemas-upnp-org:device:设备名称:1").append(NEWLINE);
content.append("Host: " + ADDRESS + ":" + PORT).append(NEWLINE);
content.append("Cache-Control: max-age=1800").append(NEWLINE);
content.append("CONFIGID.UPNP.ORG: 7339").append(NEWLINE);
content.append("BOOTID.UPNP.ORG: 7339").append(NEWLINE);
content.append("USN: uuid:Upnp-设备系列号-"+mac+"::urn:schemas-upnp-org:device:设备名称").append(NEWLINE);
content.append(NEWLINE);
/**
* NOTIFY * HTTP/1.1
ST: urn: schemas-upnp-org:device: 设备名称:1
HOST: 239.255.255.250:1900
EXT:
CACHE-CONTROL: max-age=1800
LOCATION: http://127.0.0.1:8008/ssdp/device-desc.xml
CONFIGID.UPNP.ORG: 7339
BOOTID.UPNP.ORG: 7339
USN: uuid: Upnp-设备系列号-设备识别号::urn:schemas-upnp-org:device:设备名称
*/
Log.e(TAG, content.toString());
return content.toString();
}
public static String buildSSDPByebyeString(){
StringBuilder content = new StringBuilder();
content.append(NOTIFY_MSEARCH).append(NEWLINE);
content.append("Host: " + ADDRESS + ":" + PORT).append(NEWLINE);
content.append("NT: someunique:idscheme3").append(NEWLINE);
content.append("NTS: ssdp:byebye").append(NEWLINE);
content.append("USN: someunique:idscheme3").append(NEWLINE);
content.append(NEWLINE);
Log.e(TAG, content.toString());
return content.toString();
}
public static String parseIP(String msearchAnswer){
String ip = "0.0.0.0";
//find the index of "LOCATION: http://"
int loactionLinePos = msearchAnswer.indexOf(LOCATION_TEXT);
if(loactionLinePos != -1){
//position the index right after "LOCATION: http://"
loactionLinePos += LOCATION_TEXT.length();
//find the next semi-colon (would be the one that separate IP from PORT nr)
int locColon = msearchAnswer.indexOf(":", loactionLinePos);
//grab IP
ip = msearchAnswer.substring(loactionLinePos, locColon);
}
return ip;
}
}
HuaweiSmartGateway 类主要实现ServerSocket,并对声控结果指令、智能网关指令信息的处理
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import org.json.JSONException;
import org.json.JSONObject;
import android.R.integer;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast;
import com.unisrobot.rsk.MainApplication;
import com.unisrobot.rsk.R;
import com.unisrobot.rsk.preference.ConstUtils;
import com.unisrobot.rsk.util.Logger;
public class HuaweiSmartGateway {
//广播地址
private static final String TAG = "HuaweiSmartGateway";
public static final String ACTION_HEALTH_MANAGEMENT_DATA="识别string";
public static final String ACTION_SMARTHOME_CMD="识别string2";
private static final int BROADCAST_INT_PORT = SSDPUtils.PORT; // 不同的port对应不同的socket发送端和接收端
public static String responseMsg;//成功返回智能家居的执行成功结果,小优播放的文本语音(测试用)
public static String speakresponseMsg=null;//成功返回智能家居的执行成功结果,保存用,小优播放的文本语音(测试用)
private Context mContext;
private LanSend lSend;
private TextToSpeech mTextToSpeech;
private MyReceiver mReceiverResult;
private Dialog dialog;
Handler mHander = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case 4:
Toast.makeText(mContext, (String)msg.obj, Toast.LENGTH_SHORT).show();
break;
case 5:
// Toast.makeText(mContext, (String)msg.obj, Toast.LENGTH_SHORT).show();
String str=(String)msg.obj;
if (str!=null&&!str.isEmpty()) {
createDialog((String)msg.obj);
}
break;
case 6:
// Toast.makeText(mContext, (String)msg.obj, Toast.LENGTH_SHORT).show();
String str2=(String)msg.obj;
if (str2!=null&&!str2.isEmpty()) {
createDialog((String)msg.obj);
}
int rs=msg.arg1;
if (rs!=0) {
playhuaweiVoice2(mContext, rs);
}
break;
}
}
};
public HuaweiSmartGateway(Context contex) {
this.mContext=contex;
}
public void init() {
if (mTextToSpeech==null) {
mTextToSpeech = new TextToSpeech(mContext, new OnInitListener() {
@Override
public void onInit(int status) {
// TODO Auto-generated method stub
}
});
mTextToSpeech.setOnUtteranceCompletedListener(new OnUtteranceCompletedListener() {
@Override
public void onUtteranceCompleted(String utteranceId) {
cancelDialog();
// TODO Auto-generated method stub
// startvoice();
}
});
}
//针对华为智能网关
SSDPNotify();
initServerSocket();
registerResult();
}
public void destroy(){
// mHander.removeMessages(6);
unRegisterBroadcastResult();
}
private void registerResult() {
if (mReceiverResult == null) {
mReceiverResult = new MyReceiver();
}
Logger.d(TAG, "注册---识别结果广播");
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_HEALTH_MANAGEMENT_DATA);
filter.addAction(ACTION_SMARTHOME_CMD);
mContext.registerReceiver(mReceiverResult, filter);
}
private void unRegisterBroadcastResult() {
if (mReceiverResult != null) {
Logger.d(TAG, "反注册---识别结果广播");
mContext.unregisterReceiver(mReceiverResult);
}
}
/**
* 创建内容提示框
* @param tip
*/
public void createDialog(String tip){
if (dialog==null) {
dialog = new Dialog(mContext,R.style.dialog);
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
View viewDialog = layoutInflater.inflate(
R.layout.dialog_center3, null);
TextView tv = (TextView)viewDialog.findViewById(R.id.tv_dialogcenter);
tv.setText(tip);
dialog.setContentView(viewDialog);
dialog.setCanceledOnTouchOutside(false);
// dialog.setCancelable(false);
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
dialog.show();
}
}
/**
* 取消提示框
*/
public void cancelDialog(){
if (dialog!=null) {
if (dialog.isShowing()) {
dialog.cancel();
}
dialog=null;
}
}
/**
* 监听ssdp查询服务
*/
public void SSDPNotify(){
if (lSend==null) {
try {
lSend=new LanSend(mContext);
lSend.join(); //加入组播,并创建线程侦听
} catch (Exception e) {
System.out.println("*****加入组播失败*****");
}
}
}
/**
* 初始化小优端ServerSocket
*/
private ServerSocket mServerSocket;
private Socket socket;
public void initServerSocket(){
if (mServerSocket==null) {
new Thread() {
public void run() {
try {
mServerSocket = new ServerSocket(socket通信端口号);
while (true) {
Log.e(TAG, "111111111");
socket=mServerSocket.accept();
handle(socket);
}
} catch (IOException e) {
e.printStackTrace();
}
};
}.start();
}
}
DataOutputStream out ;
private DataInputStream mDataInputStream;
private MediaPlayer mphw;
void handle(Socket socket) throws IOException {
Log.e("myrobotSocket", "new socket");
try {
out = new DataOutputStream(socket.getOutputStream());
mDataInputStream = new DataInputStream(
socket.getInputStream());
while (true) {
Log.e("myrobotSocket", "true");
final String cmd = mDataInputStream.readUTF();
JSONObject jsonO2 = new JSONObject(cmd) ;
String type=jsonO2.getString("type");
String action_cmd=jsonO2.getString("action_cmd");
Log.e("myrobotSocket", "type : "+type+" ::: cmd : "+action_cmd);
if (type!=null&&!type.isEmpty()&&action_cmd!=null&&!action_cmd.isEmpty()) {
Message msg=new Message();
msg.what=4;
msg.obj="type : "+type+" ::: cmd : "+action_cmd;
mHander.sendMessage(msg);
}
if("001".equals(type)){
if (action_cmd.contains("0X")) {
int action = Integer.valueOf(action_cmd.replace("0X", ""), 16);
MainApplication.getInstance().sendActionCmd((byte) action);
}else if(action_cmd.contains("0x")){
int action = Integer.valueOf(action_cmd.replace("0x", ""), 16);
MainApplication.getInstance().sendActionCmd((byte) action);
}
}else if("002".equals(type)) {//播放插件响应,返回结果
JSONObject jsonCMD = new JSONObject(action_cmd) ;
String rsp=jsonCMD.getString("rsp");
String content=jsonCMD.getString("content");
if (content!=null&&!content.equals("")&&!content.isEmpty()) {
boolean blplay=false;
int resid = 0;
// Turn on the living room lights.
// Turn off the living room lights.
if (content.equals("success")&&speakresponseMsg!=null&&!speakresponseMsg.equals("")) {
if (speakresponseMsg.contains("turn on")&&speakresponseMsg.contains("living room")
&&speakresponseMsg.contains("light")) {
blplay=true;
resid=R.raw.livingroom_on;
content="The living room lights have been turned on.";
}else if (speakresponseMsg.contains("turn off")&&speakresponseMsg.contains("living room")
&&speakresponseMsg.contains("light")) {
blplay=true;
resid=R.raw.livingroom_off;
content="The living room lights have been turned off.";
}else {
content=speakresponseMsg;
}
}
else if (content.equals("ALARM_DOOR_OPEN")) {
blplay=true;
resid=R.raw.door_open2;
// content="欢迎光临智慧沃家体验馆!";
// createDialog(content);
// playhuaweiVoice2(mContext, resid);
// continue;
// content="Warning! The door is open.";
}
else if (content.equals("ALARM_DOOR_CLOSE")) {
blplay=false;
content="";
// blplay=true;
// resid=R.raw.door_close;
// content="The door is closed.";
}
else if (content.equals("ALARM_FALL")) {//老人看护,有人跌倒
blplay=true;
resid=R.raw.someone_felldown;
content="Warning! Someone fell down.";
}
if (content!=null&&!content.isEmpty()) {
Message msg=new Message();
msg.what=4;
msg.obj=content;
mHander.sendMessage(msg);
}
if (blplay) {
if (content!=null&&!content.isEmpty()) {
if (content.equals("ALARM_DOOR_OPEN")) {
content="欢迎光临智慧沃家体验馆!";
Message msg=new Message();
msg.what=6;
msg.obj=content;
msg.arg1=resid;
mHander.sendMessage(msg);
// mHander.sendMessageDelayed(msg, 6*1000);
}else {
Message msg=new Message();
msg.what=5;
msg.obj=content;
mHander.sendMessage(msg);
// createDialog(content);
if (resid!=0) {
playhuaweiVoice(mContext, resid);
}
}
}
}else {
if (mTextToSpeech!=null) {
if (content!=null&&!content.isEmpty()) {
Log.e("myrobotSocket", "type : "+type+" :mTextToSpeech : "+content);
mTextToSpeech.speak(content, TextToSpeech.QUEUE_FLUSH, null);
}
}
}
}
}
}
// }
} catch (IOException e) {
e.printStackTrace();
Log.e(TAG, "" + e.toString());
out.close();
mDataInputStream.close();
socket.close();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
out.close();
mDataInputStream.close();
socket.close();
}
}
/**
* 播放华为定制的语音2
* @param mContext
* @param resid
*/
public void playhuaweiVoice2(final Context mContext,int resid){
if (mphw != null) {
mphw.release();
mphw = null;
}
if (mphw == null) {
mphw = MediaPlayer.create(mContext, resid);
mphw.start();
mphw.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp2) {
// TODO Auto-generated method stub
if(mphw!=null){
mphw.release();
mphw=null;
}
cancelDialog();
// String path=Environment.getExternalStorageDirectory()+"/ai/qnqn/myrobot/uushow/action/roundDance.mp3";
// File file=new File(path);
// if (file.exists()) {
// Uri uri=Uri.parse(path);
// mphw = MediaPlayer.create(mContext, uri);
// if (mphw!=null) {
// mphw.start();
// mphw.setOnCompletionListener(new OnCompletionListener() {
// @Override
// public void onCompletion(MediaPlayer mp) {
// // TODO Auto-generated method stub
// if(mphw!=null){
// mphw.release();
// mphw=null;
// }
// cancelDialog();
// }
// });
// int action = Integer.valueOf("2B", 16);
// MainApplication.getInstance().sendActionCmd((byte) action);
// MainApplication.getInstance().sendActionCmd((byte) action);
//
// }else {
// cancelDialog();
// }
// }else {
// cancelDialog();
// }
// startvoice();
// handler.sendEmptyMessage(rtcode);
}
});
}
}
/**
* 播放华为定制的语音
* @param mContext
* @param resid
*/
public void playhuaweiVoice(Context mContext,int resid){
if (mphw != null) {
mphw.release();
mphw = null;
}
if (mphw == null) {
mphw = MediaPlayer.create(mContext, resid);
mphw.start();
mphw.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp2) {
// TODO Auto-generated method stub
if(mphw!=null){
mphw.release();
mphw=null;
}
cancelDialog();
// startvoice();
// handler.sendEmptyMessage(rtcode);
}
});
}
}
class MyReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.e(TAG, "onReceive " + action);
if (ACTION_HEALTH_MANAGEMENT_DATA.equals(action)) {//上报健康管理数据
if (out!=null&&socket!=null) {
try{
socket.sendUrgentData(0xFF);//发送一个字节判断是否为空,此字节服务端会自动舍弃
String healthData=intent.getStringExtra("health_data");
Log.e(TAG, "healthData = " + healthData);
JSONObject datajs=new JSONObject();
JSONObject healthjs=new JSONObject(healthData.trim());
datajs.put("datatype", "health_data");
datajs.put("datacontent", healthjs);
String device=healthjs.getString("device").trim();
Log.e(TAG, "device = " + device);
if (device.equals("BloodPressure")) {
out.writeUTF(datajs.toString());
out.flush();
// Toast.makeText(mContext, "上传血压数据成功", Toast.LENGTH_SHORT).show();
}
else if(device.equals("Temperature")){
out.writeUTF(datajs.toString());
out.flush();
Log.e("myrobotSocket", "healthData = " + healthData);
Log.e("myrobotSocket", "datajs = " + datajs.toString());
// Toast.makeText(mContext, "上传体温数据成功", Toast.LENGTH_SHORT).show();
}
else if(device.equals("Weighting")){
out.writeUTF(datajs.toString());
out.flush();
}
return;
}catch(Exception ex){
Toast.makeText(mContext, "网关不通,上传数据失败", Toast.LENGTH_SHORT).show();
return;
}
}else {
Toast.makeText(mContext, "socket=null,上传数据失败", Toast.LENGTH_SHORT).show();
return;
}
}else if(ACTION_SMARTHOME_CMD.equals(action)) {//智能家居命令上报
if (out!=null&&socket!=null) {
try{
socket.sendUrgentData(0xFF);//发送一个字节判断是否为空,此字节服务端会自动舍弃
String smarthomeCMD=intent.getStringExtra("smarthome_cmd");
Log.e(TAG, "smarthomeCMD = " + smarthomeCMD);
JSONObject smarthomejs=new JSONObject();
smarthomejs.put("datatype", "smarthome_data");
smarthomejs.put("datacontent", smarthomeCMD.trim());
out.writeUTF(smarthomejs.toString());
out.flush();
// Toast.makeText(mContext, "上报智能家居指令成功", Toast.LENGTH_SHORT).show();
Intent i= new Intent(ConstUtils.ACTION_SMARTHOME_CMD_HANDLE_EXCEPTION) ;
mContext.sendBroadcast(i);
// startvoice();
return;
}catch(Exception ex){
ex.printStackTrace();
Toast.makeText(mContext, "网关不通,上报智能家居指令失败", Toast.LENGTH_SHORT).show();
Intent i= new Intent(ConstUtils.ACTION_SMARTHOME_CMD_HANDLE_EXCEPTION) ;
mContext.sendBroadcast(i);
// startvoice();
return;
}
}else {
Toast.makeText(mContext, "socket=null,上报智能家居指令失败", Toast.LENGTH_SHORT).show();
Intent i= new Intent(ConstUtils.ACTION_SMARTHOME_CMD_HANDLE_EXCEPTION) ;
mContext.sendBroadcast(i);
// startvoice();
return;
}
}
}
} ;
}
智能网关小优驱动插件实现
3. 智能网关插件上报指令信息
智能网关插件收到小优端、手机端、其他智能设备发过来字符串信息,就对其进行语义分析,如果能跟智能网关上的事件信息匹配上,把此事件上报给智能网关处理,否则不上报。
核心代码如下(其中部分代码为华为Openlife平台提供):
CanbotDeviceListener 类为小优的设备监听类,起一个循环测试线程,每隔6秒测试一次socket是否通,不通重连,监听到设备端发来的事件信息并作出处理
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import org.json.JSONObject;
import com.huawei.smarthome.api.event.IDeviceEventListener;
import com.huawei.smarthome.driver.IDeviceService;
import com.huawei.smarthome.driver.ip.AbstractSsdpDeviceDriverAdapter;
import com.huawei.smarthome.log.LogService;
import com.huawei.smarthome.log.LogServiceFactory;
/**
* <div class="English">
* 设备监听器,当机器人上线时与机器人进行连接
* </div>
*
* <div class="Chinese">
*
* </div>
* <br>
* @author Lixin
* @since NetOpen 1.0
* 2015年12月30日
*/
public 以上是关于小优机器人WIFI+SSDP入网具体实现的主要内容,如果未能解决你的问题,请参考以下文章
浅谈智慧家庭小优机器人通过WIFI+SSDP方式接入华为智能网关