智能家电工具介绍与客户端开发:
此文章教程内容:
用安卓手机的APP客户端控制智能家电实现的小案例
本文章所需工具在文章末尾,请君自取,所用工具Android studio。
家居模拟器程序介绍 本程序实现了客厅、卧室、厨房三个房间的智能设备,包括:光亮传感器、LED灯、温度传感器、风扇等。
本程序模拟现在比较流程的智能设备,能够自动接入WIFI。通过手机、平板等安装的APP,自动发现这些智能设备。智能设备既可以自主广播数据(定时或者自身状态改变),也可以根据请求返回设备的状态。例如:光亮传感器,当光线亮度发生变化时会自动广播自己的当前状态。而温度传感器,则会每隔10秒钟自动广播自己的当前状态。而风扇和LED灯,既可以通过模拟程序控制,也可以通过手机和平板控制。
程序的使用: 运行程序后,点击“启动设备”按钮,启动TCP服务器。 手机、平板通过TCP连接到模拟程序,即可进行通信。 通信协议:
(1)通信协议采用JSON格式。
(2)模拟程序广播的数据格式:[{“Device”: “D0001”, “Value”: “50”,
“Value2”: “xx”},> …]。其中,Device为设备编号,D001代表光亮传感器,D0002代表LED灯,D0003代表温度传感器,D0004代表风扇。Value、Value1表示设备状态值。
(3)模拟程序接收的数据格式:[{“Device”: “D0001”, “Value”: “50”}, {“Device”:
“D0001”},
…]。如果存在Value、Value1属性,则表示设置指定的设备状态。如果不存在Value、Value1属性,则表示获取指定设备的状态。
(4)发现设备的数据格式:[]。即可返回智能设备的信息。
此处的智能设备有灯光,厨房的风扇,还有光线传感器,温度
点击启动设备即可启动,现在智能家居等待着客户端的连接,连接成功就会显示接收到某个客户端以及受到客户端发来的消息
客户端测试工具:
此客户端的协议类型默认为:TCP Client
远程主机默认为分配给智能家电的ip地址,或者用本地ip也可,即127.0.0.1
连接的智能家电的端口为1981,然后点击连接,发送[]\r\n
上面的智能家电显示客户端发送 “[]” 即可返回智能家电的设备信息
\r\n代表的是换行的意思,此客户端也默认发送消息换行
Device代表的是id号码
type代表设备的类型
value代表的是设备的状态,比如风扇的开关,空调的温度,
valuel代表的是辅助状态,因为空调可以具有温度也可以具有湿度,所以只能家居具有多种状态
下面在eclipse中采用socket的方式建立与智能家电的连接
实现代码(步骤中有有正确的解释):
i
```java
mport java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
public class TcpClient {
public static void main(String[] args) {
try {
// 采用socket建立链接,连接的IP为本地连接
// 用localhost或者127.0.0.1的本地IP地址,端口号为1981
Socket socket = new Socket("127.0.0.1",1981);
// 读取智能家电传送来的json信息
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 将信息写入到智能家电
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
// 采用线程休眠,在读取之后休眠3秒钟
Thread.sleep(3000);
// 智能家电提示用[]\r\n与其建立连接,此处将其写入
writer.write("[]\r\n");
// 采用每次的写入进行一次刷新
writer.flush();
// 刷新一次休眠0.5秒钟
Thread.sleep(500);
// 将数据的每一行读取出来放到控制台进行显示
String line = reader.readLine();
System.out.println(line);
} catch (Exception e) {
e.printStackTrace();
}
}
}
举个列子,控制灯泡的打开;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.Socket;
public class TcpClient {
public static void main(String[] args) {
try {
// 采用socket建立链接,连接的IP为本地连接
// 用localhost或者127.0.0.1的本地IP地址,端口号为1981
Socket socket = new Socket("127.0.0.1",1981);
// 读取智能家电传送来的json信息
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 将信息写入到智能家电
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
// 采用线程休眠,在读取之后休眠3秒钟
Thread.sleep(3000);
// 向智能家电传入json数据来控制灯的开启(on:开启;off:关闭;)
writer.write("[{\"Device\":\"D0002\",\"Value\":\"on\"}]\r\n");
writer.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
}
接下来是在Android studio中画开关的图纸,布局采用的是线性布局
实现代码:
在xml中:
首先修改xml文件中的Activity标签,将主页的设置为另外的Activity文件(如果此处新建Activity,否则不需要下面的步骤),然后申请网络权限,因为连接网络不是危险权限,所以不需要动态申请(此处很重要)
在java文件中的实现代码:
i
import androidx.appcompat.app.AppCompatActivity;
import android.gesture.GestureUtils;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
public class DeciceTestActivity extends AppCompatActivity implements View.OnClickListener {
// 声明连接按钮的变量与输入输出流的变量
private Button connectButton;
private BufferedReader reader;
private BufferedWriter writer;
private Socket socket;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_decice_test);
// 绑定事件
findViewById(R.id.connect_button).setOnClickListener(this);
findViewById(R.id.disconnect_button).setOnClickListener(this);
findViewById(R.id.find_device_button).setOnClickListener(this);
findViewById(R.id.led_on_button).setOnClickListener(this);
findViewById(R.id.led_off_button).setOnClickListener(this);
findViewById(R.id.low_button).setOnClickListener(this);
findViewById(R.id.middle_button).setOnClickListener(this);
findViewById(R.id.height_button).setOnClickListener(this);
findViewById(R.id.stop_space).setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.connect_button) {
// 连接服务器
connectToServer();
} else if (v.getId() == R.id.disconnect_button) {
// 断开服务器
disconnectFromServer();
} else if (v.getId() == R.id.find_device_button) {
// 查询设备
findDevices();
} else if (v.getId() == R.id.led_on_button) {
// 开灯
ledTurn("on");
} else if (v.getId() == R.id.led_off_button) {
// 关灯
ledTurn("off");
}else if(v.getId() == R.id.low_button){
lowspace();
}else if(v.getId() == R.id.middle_button){
midelespace();
}else if(v.getId() == R.id.height_button){
heighspace();
}else if (v.getId() == R.id.stop_space){
stopspace();
}
}
// 连接到服务器
private void connectToServer() {
if (socket != null) {
Toast.makeText(this, "已经连接到服务器", Toast.LENGTH_LONG).show();
return;
}
new Thread(new Runnable() {
@Override
public void run() {
try {
Socket socket = new Socket("192.168.1.9", 1981);
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
new Thread(new Runnable() {
@Override
public void run() {
String line;
try {
while ((line = reader.readLine()) != null) {
Log.d("TEST", line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
} catch (IOException e) {
e.printStackTrace();
Log.d("TEST", "连接服务器错误");
}
}
}).start();
}
// 断开连接
private void disconnectFromServer() {
if (socket == null) {
Toast.makeText(this, "请连接服务器", Toast.LENGTH_LONG).show();
return;
}
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 查询智能设备
private void findDevices() {
new Thread(new Runnable() {
@Override
public void run() {
try {
writer.write("[]\r\n");
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
/**
* 设置LED开或者关
*/
private void ledTurn(String status) {
if (socket != null){
Toast.makeText(this,"还未连接服务器",Toast.LENGTH_LONG).show();
return;
}
final String message = "[{\"Device\":\"D0002\",\"Value\":\""+ status +"\"}]\r\n";
new Thread(new Runnable() {
@Override
public void run() {
try {
writer.write(message);
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
// 风扇低速
private void lowspace(){
if (socket != null){
Toast.makeText(this,"还未连接服务器",Toast.LENGTH_LONG).show();
return;
}
final String message = "[{\"Device\":\"D0004\",\"Type\":null,\"Value\":\"low\",\"Value1\":null}]\r\n";
new Thread(new Runnable() {
@Override
public void run() {
try {
writer.write(message);
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
// 风扇中速
private void midelespace(){
if (socket != null){
Toast.makeText(this,"还未连接服务器",Toast.LENGTH_LONG).show();
return;
}
final String message = "[{\"Device\":\"D0004\",\"Type\":null,\"Value\":\"middle\",\"Value1\":null}]\r\n";
new Thread(new Runnable() {
@Override
public void run() {
try {
writer.write(message);
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
// 风扇高速
private void heighspace(){
if (socket != null){
Toast.makeText(this,"还未连接服务器",Toast.LENGTH_LONG).show();
return;
}
final String message = "[{\"Device\":\"D0004\",\"Type\":null,\"Value\":\"high\",\"Value1\":null}]\r\n";
new Thread(new Runnable() {
@Override
public void run() {
try {
writer.write(message);
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
// 停止风扇
private void stopspace(){
if (socket != null){
Toast.makeText(this,"还未连接服务器",Toast.LENGTH_LONG).show();
}
final String message = "[{\"Device\":\"D0004\",\"Type\":null,\"Value\":\"off\",\"Value1\":null}]\r\n";
new Thread(new Runnable() {
@Override
public void run() {
try {
writer.write(message);
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
最后晒两张运行图:
文中所需工具链接:
链接:https://pan.baidu.com/s/1PNlswFcqDLwdGyQFik52uw
提取码:jdad