智能家居控制系统
● 开发背景:课程设计
● 开发时间:2021-06-21 ~ 2021-07-02
● 项目描述 :
用于监测家居环境, 使用了SpringBoot + Mybatis + Java + JavaScrpit + CSS + Html 编写写的网页及后端部分,但是传感器数据是由Java程序单独模拟出来传至服务器的。
● 工作内容 : 我在这个项目中负责的是整个项目的设计和开发。
● 页面展示
总体设计
系统采用java程序模拟的传感器数据上传到云服务器, 在云服务器上由使用Spring框架编写的服务程序接受数据之后存至服务器数据库,服务器还提供数据的实时显示和部分设备的实时控制服务。用户在pc端访问云服务器网页即可获得实时数据和控制部分设备的服务。流程图如下:
详细设计
● 模拟的传感器数据
首先使用java的 Math.random()方法随机生成数据,该方法将会生成[0,1)之间的小数,将这个数减去0.5 将会得到[-0.5,+0.5)之间的值,这样就可以模拟数据的波动。源码中的 random() - offset 可以进一步降低数据的波动幅度,使其更进一步的平稳模拟数据。
//偏移值作用类似于0.5 但是为了更逼真的模拟,限制一下波动范围
//波动范围 [-0.4,0.4)
static double offset = 0.4;
public static double random() {
return Math.random() * 0.8;//缩小生成随机数的范围
}
//数据生成的函数
public static void generatStart() {
//新建线程单独生成数据
(new Thread(() -> {
while (true) {
//定义数据的趋向稳定波动范围在指定值为centralAirConditioningControler的±2个单位之内
double scope = 2;
//获取当前传感器温度 和 控制温度(控制者期望到达的温度) 的差值
double temX = sd.centralAirConditioningControler - sd.airTemperatureInSide;
//如果差值大于 控制温度的可控波动范围的±2
if (temX > scope)
//数据直接 + random() 即 数据 + [0,0.8)
sd.airTemperatureInSide = dataFormater(sd.airTemperatureInSide + random(), 1);
if (temX < - scope)
sd.airTemperatureInSide = dataFormater(sd.airTemperatureInSide - random(), 1);
//如果数据在指定的范围内则进行随机加减 等价于 ‘数据’+ [-0.4 , 0.4)
if (temX >= - scope && temX <= scope)
sd.airTemperatureInSide = dataFormater(sd.airTemperatureInSide + random() - offset, 1);
//.....省略代码
这里实现了气温波动的控制,例如当用户从浏览器发出控制指令时centralAirConditioningControler将被指定为用户所指定的温度,这时温度就会不断的向指定温度靠近,最后停留在目标温度±2个单位之内
传输数据的种类:
double airTemperatureOutSide;//室外温度
double airTemperatureInSide;//室内温度
double humidity;//湿度
double internetSpeed;//网速
double lightingIntensity;//灯光亮度
double solarBattery;//太阳能
double waterTemperature;//水温
double powerConsumption;//功率
int deviceNumber;//设备数量
double waterTemperatureController;//水温调节
double lightingControler;//亮度调节
double centralAirConditioningControler;//中央空调控制
● 数据的传输协议
使用Http协议 method = HttpMethod.POST; 将数据转换为JSON字符串格式发送到服务器上,之后的等待服务器返回控制数据集。
//服务器地址
String url = "http://**.**.**.***:8080/student4/json/data";
//post请求
HttpMethod method = HttpMethod.POST;
//发送的json数据
String json = JSON.toJSONString(sd);
//发送http请求并返回结果
String result = HttpRestClient(url, method, json);
//接收反馈数据用于控制设备的模拟数据
SensorReturn sr = JSONObject.parseObject(result,SensorReturn.class);
● 数据的接收与储存
服务器端使用spring框架的controller来接收json数据,将json字符串解析之后调用SQL语句将数据插到数据库内储存
@ResponseBody//访问/json/data来传输数据
@RequestMapping(value = "/json/data", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
public String getByJSON(@RequestBody JSONObject jsonParam) {
//将json数据转化成java对象
SensorData sd = jsonParam.toJavaObject(SensorData.class);
//调用mapper中的sql语句
homeService.insertMsg(sd);
return JSON.toJSONString(sr).toString();
}
//将数据插入数据库
<insert id="insertMsg">
insert into smart_home(airTemperatureOutSide,airTemperatureInSide, humidity,internetSpeed,lightingIntensity,solarBattery,waterTemperature,
powerConsumption,deviceNumber,waterTemperatureController,lightingControler,centralAirConditioningControler)values(#{
airTemperatureOutSide},#{
airTemperatureInSide},#{
humidity},#{
internetSpeed},#{
lightingIntensity},#{
solarBattery},#{
waterTemperature},#{
powerConsumption},#{
deviceNumber},#{
waterTemperatureController},#{
lightingControler},#{
centralAirConditioningControler}
)
</insert>
● 数据的查询显示
浏览器网页访问 /mastercontrol 路径得到最新的数据与控制面板
@GetMapping("/mastercontrol")
public String mastercontrol(Model model) {
//查询最近的传感器数据
SensorData nearMsg = homeService.getNearMsg();
//将数据放入Attribute 以方便 js 访问数据
model.addAttribute("sensor", nearMsg);
model.addAttribute("sr", sr);
//返回页面
return "mastercontrol";
}
网页js中使用定时任务不断访问controller来刷新数据
setInterval(function () {
refresh();//刷新数据
}, 200); //200ms反复执行函数本身
function refresh(){
//发送请求刷新获得返回的数据并刷新指定标签
$.ajax({
url: basePath + '/index/refresh',
type: 'post',
dataType: 'text',
data: {
},
cache: false,
async: true,
success: function (data) {
$("#statusBar").empty();
$("#statusBar").append(data);
}
});
//....................省略代码
}
将获取的数据嵌入html 的属性中展示出来
<br/> <span class="status_data" th:text="${sensor.airTemperatureOutSide}"></span>
● 用户对设备的控制
在浏览器中获取用户输入的数据并通过访问controller将数据存在后台,每一次传感器发送数据到服务端之后就将储存的控制数据集发送给设备
$(function () {
//监听用户输入数据的动作
$("#range_waterTemperature").on("input", function () {
//获取用户输入的数据
var percent = $("#range_waterTemperature").val();
//将数据打包为json发给controller
$.ajax({
url: basePath + '/waterTemperatureControllerReturn',
type: 'post',
contentType: "application/json",
data: JSON.stringify(percent),
success: function (data) {
console.log(data)
}
});
cwSvgProgress.draw($("#cw_svg_waterTemperature"), percent / 100, '.path_waterTemperature');
});
cwSvgProgress.draw($('#cw_svg_waterTemperature'), $("#range_waterTemperature").val()/100, '.path_waterTemperature');
cwSvgProgress.draw($('#circleBg_waterTemperature'), 1, '.circleBg_path_waterTemperature');
});
@ResponseBody
@RequestMapping("/waterTemperatureControllerReturn")
public String waterTemperatureControllerReturn( @RequestBody Double percent) {
//将数据存在java对象中,等待发送
sr.waterTemperatureControllerReturn = percent;
return "null";
}
@ResponseBody//访问/json/data来传输数据
@RequestMapping(value = "/json/data", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
public String getByJSON(@RequestBody JSONObject jsonParam) {
//将json数据转化成java对象
SensorData sd = jsonParam.toJavaObject(SensorData.class);
//调用mapper中的sql语句
homeService.insertMsg(sd);
//将数据回传给设备
return JSON.toJSONString(sr).toString();
}
调试与测试
使用IntelliJ IDEA IDE来构建和调试 传感器模拟程序 和 要部署到服务器上的tomcat中运行的war包,使用Navicat来连接服务器MySQL数据库和在服务器数据库上部署数据库表,前端交互使用 Google chrome 和 Microsoft edge 浏览器来适配和调试前端界面。使用Xshell 和 Xftp 来连接云服务器和向服务器上传文件