add feature about ota
This commit is contained in:
parent
e983f5ba1d
commit
8121e7bbea
|
@ -181,6 +181,7 @@
|
|||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<mainClass>com.aiit.xiuos.XiuosApplication</mainClass>
|
||||
<excludes>
|
||||
<exclude>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
|
@ -189,6 +190,15 @@
|
|||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<fork>true</fork>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!--mybatis自动生成代码插件-->
|
||||
<plugin>
|
||||
<groupId>org.mybatis.generator</groupId>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
package com.aiit.xiuos.Utils;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
package com.aiit.xiuos.Utils;
|
||||
|
||||
import com.aiit.xiuos.mqtt.MqttConfiguration;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import okhttp3.Credentials;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.checkerframework.checker.units.qual.A;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.IOException;
|
||||
@Component
|
||||
public class EmqxApiUtil {
|
||||
@Autowired
|
||||
MqttConfiguration mqttConfiguration;
|
||||
|
||||
|
||||
public String getClientInfo(String clientId){
|
||||
try {
|
||||
OkHttpClient client = new OkHttpClient();
|
||||
Request request = new Request.Builder()
|
||||
.url(mqttConfiguration.getApiurl()+"/api/v5/clients/"+clientId)
|
||||
.header("Content-Type", "application/json")
|
||||
.header("Authorization", Credentials.basic(mqttConfiguration.getApikey(), mqttConfiguration.getSecretkey()))
|
||||
.build();
|
||||
|
||||
Response response = client.newCall(request).execute();
|
||||
return response.body().string();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@ package com.aiit.xiuos.Utils;
|
|||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import java.io.RandomAccessFile;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
|
@ -168,6 +169,7 @@ public class HexUtil {
|
|||
bit = bs[i] & 0x0f; // 低四位, 与操作 0000 1111
|
||||
sb.append(chars[bit]);
|
||||
sb.append(' ');//每个Byte之间空格分隔
|
||||
|
||||
}
|
||||
return sb.toString().trim();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
package com.aiit.xiuos.Utils;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class OTAFileUtil {
|
||||
public static byte[] getFile(String fileName, int offset,int size) {
|
||||
byte[] buffer = new byte[size];
|
||||
File file = new File(System.getProperty("user.dir") + "/otafiles/" + fileName);
|
||||
byte[] chunk;
|
||||
RandomAccessFile randomAccessFile =null;
|
||||
try {
|
||||
randomAccessFile = new RandomAccessFile(file, "r");
|
||||
int bytesRead;
|
||||
randomAccessFile.seek(offset);
|
||||
if ((bytesRead = randomAccessFile.read(buffer)) != -1) {
|
||||
if (bytesRead < size) {
|
||||
chunk = new byte[bytesRead];
|
||||
System.arraycopy(buffer, 0, chunk, 0, bytesRead);
|
||||
} else {
|
||||
chunk = new byte[size];
|
||||
System.arraycopy(buffer, 0, chunk, 0, size);
|
||||
}
|
||||
return chunk;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if(randomAccessFile!=null){
|
||||
try{
|
||||
randomAccessFile.close();
|
||||
System.out.println("文件流关闭"+"offset="+offset);
|
||||
}catch (IOException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void main(String rgs[]) {
|
||||
|
||||
byte[] chunk = OTAFileUtil.getFile("2_ota_refresh.svg", 0,1024);
|
||||
System.out.println();
|
||||
String filePath = System.getProperty("user.dir") + "/otafiles/" + "2_ota_refresh.svg";
|
||||
|
||||
FileUtil.del(filePath);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -15,7 +15,11 @@ import org.springframework.scheduling.annotation.EnableScheduling;
|
|||
public class XiuosApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(XiuosApplication.class, args);
|
||||
try {
|
||||
SpringApplication.run(XiuosApplication.class, args);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package com.aiit.xiuos.controller;
|
||||
|
||||
import com.aiit.xiuos.Utils.Constant;
|
||||
import com.aiit.xiuos.Utils.EmqxApiUtil;
|
||||
import com.aiit.xiuos.Utils.ResultRespons;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api")
|
||||
public class EmqxApiController {
|
||||
@Autowired
|
||||
EmqxApiUtil emqxApiUtil;
|
||||
@GetMapping("/getClient")
|
||||
public ResultRespons selectDevice(@RequestParam("clientId") String clientId){
|
||||
String res= emqxApiUtil.getClientInfo(clientId);
|
||||
if(StringUtils.contains(res,"clientid")){
|
||||
return new ResultRespons(Constant.SUCCESS_CODE,"查询设备状态成功");
|
||||
}else{
|
||||
return new ResultRespons(Constant.ERROR_CODE,"设备不在线!");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -103,11 +103,9 @@ public class FirmwareController {
|
|||
String fileName = firmwareInfo.getFileName();
|
||||
String version = firmwareInfo.getFileVersion();
|
||||
String filePath = System.getProperty("user.dir") + "/otafiles/" + version+"_"+fileName;
|
||||
Boolean flag = FileUtil.del(filePath);
|
||||
|
||||
Boolean flag = FileUtil.del(filePath);
|
||||
if (flag) {
|
||||
int res = firmwareInfoService.deleteFirmware(id);
|
||||
|
||||
if (1 == res) {
|
||||
otaInfoService.deleteOtaInfo(fileName,version);
|
||||
return new ResultRespons(Constant.SUCCESS_CODE, "删除成功");
|
||||
|
@ -116,7 +114,7 @@ public class FirmwareController {
|
|||
}
|
||||
|
||||
} else {
|
||||
return new ResultRespons(Constant.ERROR_CODE, "固件不存在");
|
||||
return new ResultRespons(Constant.ERROR_CODE, "删除失败");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,79 +1,105 @@
|
|||
package com.aiit.xiuos.controller;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
|
||||
import com.aiit.xiuos.Utils.Constant;
|
||||
import com.aiit.xiuos.Utils.ResultRespons;
|
||||
import com.aiit.xiuos.model.FirmwareInfo;
|
||||
import com.aiit.xiuos.model.OtaInfo;
|
||||
import com.aiit.xiuos.model.UserInfo;
|
||||
import com.aiit.xiuos.mqtt.MyMqttClient;
|
||||
import com.aiit.xiuos.service.FirmwareInfoService;
|
||||
import com.aiit.xiuos.service.OtaInfoService;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URLEncoder;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/ota")
|
||||
@Slf4j
|
||||
public class OTAController {
|
||||
@Autowired
|
||||
private MyMqttClient myMqttClient;
|
||||
@Autowired
|
||||
OtaInfoService otaInfoService;
|
||||
@Autowired
|
||||
FirmwareInfoService firmwareInfoService;
|
||||
|
||||
/*
|
||||
上传接口
|
||||
*/
|
||||
//MultipartFile用于接受前端传过来的file对象
|
||||
@PostMapping("/upload")
|
||||
public ResultRespons upload(MultipartFile file) throws IOException {
|
||||
String md5 = SecureUtil.md5(file.getInputStream());
|
||||
System.out.println("文件的md5是:"+md5);
|
||||
String filename = file.getOriginalFilename();//获取文件的名称
|
||||
// String flag = IdUtil.fastSimpleUUID();//通过Hutool工具包的IdUtil类获取uuid作为前缀
|
||||
String rootFilePath = System.getProperty("user.dir") + "/otafiles/" + filename;
|
||||
FileUtil.writeBytes(file.getBytes(), rootFilePath);//使用Hutool工具包将我们接收到文件保存到rootFilePath中
|
||||
return new ResultRespons(Constant.SUCCESS_CODE, "上传成功", filename);
|
||||
@GetMapping("/getAll")
|
||||
public ResultRespons getAllJob(@RequestParam("fileName") String fileName,@RequestParam("fileVersion") String fileVersion,HttpServletRequest request) {
|
||||
UserInfo userInfo = (UserInfo) request.getSession().getAttribute("user");
|
||||
List<OtaInfo> otaInfos = otaInfoService.getALL(fileName,fileVersion ,userInfo.getOrg());
|
||||
return new ResultRespons(Constant.SUCCESS_CODE, "查询成功", otaInfos);
|
||||
}
|
||||
|
||||
@PostMapping("/overJob")
|
||||
public ResultRespons overJob(@RequestBody OtaInfo otaInfo) {
|
||||
otaInfo.setStatus(0);
|
||||
otaInfoService.updateOtaInfo(otaInfo);
|
||||
return new ResultRespons(Constant.SUCCESS_CODE, "更新成功");
|
||||
}
|
||||
|
||||
@PostMapping("/reTryJob")
|
||||
public ResultRespons reTryJob(@RequestBody OtaInfo otaInfo) {
|
||||
String clientId =otaInfo.getDeviceId();
|
||||
String version =otaInfo.getFileVersion();
|
||||
String fileName =otaInfo.getFileName();
|
||||
FirmwareInfo firmwareInfo= firmwareInfoService.getByNameAndVersion(fileName,version);
|
||||
String md5 = firmwareInfo.getFileMd5();
|
||||
long size = firmwareInfo.getFileSize();
|
||||
int id =firmwareInfo.getId();
|
||||
JSONObject payload =new JSONObject();
|
||||
payload.put("fileId",id);
|
||||
payload.put("version",version);
|
||||
payload.put("md5",md5);
|
||||
payload.put("fileSize",size);
|
||||
myMqttClient.publish("ota/"+clientId+"/update",payload.toJSONString());
|
||||
//状态置为进行中
|
||||
otaInfo.setStatus(2);
|
||||
otaInfoService.updateOtaInfo(otaInfo);
|
||||
return new ResultRespons(Constant.SUCCESS_CODE, "开始下发");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
下载接口
|
||||
*/
|
||||
@GetMapping("/download/{name}")
|
||||
public ResultRespons getFiles(@PathVariable String name, HttpServletResponse response) {
|
||||
OutputStream os;//新建一个输出流对象
|
||||
String basePath = System.getProperty("user.dir") + "/otafiles/"; //定义文件上传的根路径
|
||||
List<String> fileNames = FileUtil.listFileNames(basePath);//获取所有的文件名称
|
||||
String fileName = fileNames.stream().filter(filename -> filename.contains(name)).findAny().orElse("");//找到跟参数一致的文件
|
||||
try {
|
||||
if (StrUtil.isNotEmpty(fileName)) {
|
||||
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
|
||||
response.setContentType("application/octet-stream");
|
||||
byte[] bytes = FileUtil.readBytes(basePath + fileName);//通过文件的路径读取文件字节流
|
||||
os = response.getOutputStream();//通过response的输出流返回文件
|
||||
os.write(bytes);
|
||||
os.flush();
|
||||
os.close();
|
||||
return new ResultRespons(Constant.SUCCESS_CODE, "下载成功");
|
||||
}else{
|
||||
return new ResultRespons(Constant.ERROR_CODE, "文件名不存在");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return new ResultRespons(Constant.ERROR_CODE, "下载失败");
|
||||
|
||||
@PostMapping("/addJob")
|
||||
public ResultRespons addJob(@RequestBody OtaInfo otaInfo, HttpServletRequest request){
|
||||
OtaInfo lastOta = otaInfoService.getJobById(otaInfo.getDeviceId());
|
||||
if(lastOta!=null){
|
||||
return new ResultRespons(Constant.ERROR_CODE,"新增升级任务失败,存在进行中的任务,请检查!");
|
||||
}
|
||||
UserInfo userInfo = (UserInfo) request.getSession().getAttribute("user");
|
||||
otaInfo.setOrg(userInfo.getOrg());
|
||||
otaInfo.setCurrentProcess(0);
|
||||
//立即执行
|
||||
if(otaInfo.getUpdateType()==0){
|
||||
String clientId =otaInfo.getDeviceId();
|
||||
String version =otaInfo.getFileVersion();
|
||||
String fileName =otaInfo.getFileName();
|
||||
FirmwareInfo firmwareInfo= firmwareInfoService.getByNameAndVersion(fileName,version);
|
||||
String md5 = firmwareInfo.getFileMd5();
|
||||
long size = firmwareInfo.getFileSize();
|
||||
int id =firmwareInfo.getId();
|
||||
JSONObject payload =new JSONObject();
|
||||
payload.put("fileId",id);
|
||||
payload.put("version",version);
|
||||
payload.put("md5",md5);
|
||||
payload.put("fileSize",size);
|
||||
myMqttClient.publish(1,false,"ota/"+clientId+"/update",payload.toJSONString());
|
||||
//状态置为进行中
|
||||
otaInfo.setStatus(2);
|
||||
}else{
|
||||
//状态设置未开始
|
||||
otaInfo.setStatus(3);
|
||||
}
|
||||
int res = otaInfoService.addOtaInfo(otaInfo);
|
||||
if(1==res){
|
||||
return new ResultRespons(Constant.SUCCESS_CODE,"新增升级任务成功");
|
||||
}
|
||||
return new ResultRespons(Constant.ERROR_CODE,"新增升级任务失败");
|
||||
|
||||
}
|
||||
|
||||
@PostMapping("/delete/{name}")
|
||||
public ResultRespons deleteFile(@PathVariable String name) throws IOException {
|
||||
String filePath =System.getProperty("user.dir") + "/otafiles/"+name;
|
||||
Boolean flag =FileUtil.isFile(filePath);
|
||||
if(flag){
|
||||
FileUtil.del(filePath);
|
||||
return new ResultRespons(Constant.SUCCESS_CODE, "删除成功");
|
||||
}else{
|
||||
return new ResultRespons(Constant.ERROR_CODE, "文件不存在");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,9 +5,12 @@ import com.aiit.xiuos.model.DeviceInfo;
|
|||
import com.aiit.xiuos.model.ProtocolProductInfo;
|
||||
import com.aiit.xiuos.model.UserInfo;
|
||||
import com.aiit.xiuos.model.VO.ProtocolProductVo;
|
||||
import com.aiit.xiuos.mqtt.MqttConfiguration;
|
||||
import com.aiit.xiuos.mqtt.MyMqttClient;
|
||||
import com.aiit.xiuos.service.DeviceInfoService;
|
||||
import com.aiit.xiuos.service.ProtocolService;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.tomcat.util.http.fileupload.IOUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -27,13 +30,12 @@ import java.util.Map;
|
|||
public class ProtocolProductInfoController {
|
||||
@Autowired
|
||||
private ProtocolService protocolService;
|
||||
@Autowired
|
||||
MyMqttClient myMqttClient;
|
||||
|
||||
@PostMapping("/add")
|
||||
public ResultRespons addProtocolProduct(@RequestBody ProtocolProductVo protocolProductVo, HttpServletRequest request) throws ParseException {
|
||||
UserInfo userInfo =(UserInfo) request.getSession().getAttribute("user");
|
||||
if(userInfo==null){
|
||||
return new ResultRespons(Constant.SessionTimeOut_CODE,"用户尚未登录,请先登录!");
|
||||
}
|
||||
ProtocolProductInfo productInfo = protocolService.getProtocolByName(protocolProductVo.getProductName());
|
||||
|
||||
if (productInfo != null) {
|
||||
|
@ -62,9 +64,6 @@ public class ProtocolProductInfoController {
|
|||
@GetMapping("/selectAll")
|
||||
public ResultRespons selectProtocolProductList(HttpServletRequest request) throws ParseException {
|
||||
UserInfo userInfo =(UserInfo) request.getSession().getAttribute("user");
|
||||
if(userInfo==null){
|
||||
return new ResultRespons(Constant.SessionTimeOut_CODE,"用户尚未登录,请先登录!");
|
||||
}
|
||||
List<ProtocolProductInfo> protocolProductInfos = protocolService.getProtocolAll(userInfo.getOrg());
|
||||
List<ProtocolProductVo> protocolProductVos= new ArrayList<>();
|
||||
if (protocolProductInfos != null && protocolProductInfos.size() >= 0) {
|
||||
|
@ -119,4 +118,13 @@ public class ProtocolProductInfoController {
|
|||
}
|
||||
return new ResultRespons(Constant.ERROR_CODE, "导出csv成功!");
|
||||
}
|
||||
|
||||
@PostMapping("/publish")
|
||||
public ResultRespons publish(@RequestBody Map<String, Object> jsonMap) {
|
||||
String clientId =jsonMap.get("clientId").toString();
|
||||
String jsonString =jsonMap.get("jsonString").toString();
|
||||
log.info("发送的配方消息是:"+jsonString);
|
||||
myMqttClient.publish("protocol/"+clientId+"/files",jsonString);
|
||||
return new ResultRespons(Constant.SUCCESS_CODE, "协议已推送!");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,15 +21,15 @@ public interface FirmwareInfoMapper {
|
|||
|
||||
int updateByPrimaryKey(FirmwareInfo record);
|
||||
|
||||
@Select("select * from firmware_info where org=#{org}")
|
||||
@Select("select * from firmware_info where org=#{org} order by id desc")
|
||||
List<FirmwareInfo> getAll(@Param("org") String org);
|
||||
|
||||
@Select("select * from firmware_info where org=#{org} and verify=#{verify}")
|
||||
@Select("select * from firmware_info where org=#{org} and verify=#{verify} order by id desc")
|
||||
List<FirmwareInfo> getByVerify(@Param("org") String org,@Param("verify") String verify);
|
||||
|
||||
@Select("select * from firmware_info where file_name=#{name}")
|
||||
@Select("select * from firmware_info where file_name=#{name} order by id desc")
|
||||
List<FirmwareInfo> getByName(@Param("name") String name);
|
||||
|
||||
@Select("select * from firmware_info where file_name=#{name} and file_version=#{version}")
|
||||
@Select("select * from firmware_info where file_name=#{name} and file_version=#{version} ")
|
||||
FirmwareInfo getByNameAndVersion(@Param("name") String name,@Param("version") String version);
|
||||
}
|
|
@ -1,7 +1,14 @@
|
|||
package com.aiit.xiuos.dao.mappers;
|
||||
|
||||
import com.aiit.xiuos.model.FirmwareInfo;
|
||||
import com.aiit.xiuos.model.OtaInfo;
|
||||
import org.apache.ibatis.annotations.Delete;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
@Repository
|
||||
public interface OtaInfoMapper {
|
||||
int deleteByPrimaryKey(Integer id);
|
||||
|
||||
|
@ -14,4 +21,16 @@ public interface OtaInfoMapper {
|
|||
int updateByPrimaryKeySelective(OtaInfo record);
|
||||
|
||||
int updateByPrimaryKey(OtaInfo record);
|
||||
|
||||
@Select("select * from ota_info where file_name=#{name} and file_version =#{version} and org=#{org} order by create_time desc")
|
||||
List<OtaInfo> getAll(@Param("name") String name,@Param("version") String version,@Param("org") String org);
|
||||
|
||||
@Select("select * from ota_info where update_type=1 and status =3")
|
||||
List<OtaInfo> getJob();
|
||||
|
||||
@Select("select * from ota_info where device_id =#{device_id} and status =2")
|
||||
OtaInfo getOtaInfo(@Param("device_id") String deviceId);
|
||||
|
||||
@Delete("delete from ota_info where file_name=#{name} and file_version =#{version}")
|
||||
int deleteOtaInfo(@Param("name") String name,@Param("version") String version);
|
||||
}
|
|
@ -6,10 +6,10 @@ import lombok.Data;
|
|||
@Data
|
||||
@Builder
|
||||
public class DeviceInfo {
|
||||
private String id;
|
||||
|
||||
private String no;
|
||||
|
||||
private String id;
|
||||
|
||||
private String productname;
|
||||
|
||||
private String type;
|
||||
|
@ -56,9 +56,9 @@ public class DeviceInfo {
|
|||
|
||||
private String org;
|
||||
|
||||
public DeviceInfo(String id, String no, String productname, String type, Integer activestatus, String updatetime, String devicedesc, Integer runstatus, String statusdesc, String kernel, String webversion, String ipaddr, String netmask, String gateway, String dnsserver0, String dnsserver1, String topic, String serveraddr, String serverport, String username, String clientid, String privateserveraddr, String privateserverport, String privateserverusername, String org) {
|
||||
this.id = id;
|
||||
public DeviceInfo(String no, String id, String productname, String type, Integer activestatus, String updatetime, String devicedesc, Integer runstatus, String statusdesc, String kernel, String webversion, String ipaddr, String netmask, String gateway, String dnsserver0, String dnsserver1, String topic, String serveraddr, String serverport, String username, String clientid, String privateserveraddr, String privateserverport, String privateserverusername, String org) {
|
||||
this.no = no;
|
||||
this.id = id;
|
||||
this.productname = productname;
|
||||
this.type = type;
|
||||
this.activestatus = activestatus;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package com.aiit.xiuos.model;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
|
@ -16,7 +18,7 @@ public class OtaInfo {
|
|||
private Integer currentProcess;
|
||||
|
||||
private Integer status;
|
||||
|
||||
@JsonFormat(pattern ="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
|
||||
private Date createTime;
|
||||
|
||||
private Integer updateType;
|
||||
|
@ -25,7 +27,9 @@ public class OtaInfo {
|
|||
|
||||
private String fileVersion;
|
||||
|
||||
public OtaInfo(Integer id, String fileName, String deviceId, Integer currentProcess, Integer status, Date createTime, Integer updateType, Date timeout, String fileVersion) {
|
||||
private String org;
|
||||
|
||||
public OtaInfo(Integer id, String fileName, String deviceId, Integer currentProcess, Integer status, Date createTime, Integer updateType, Date timeout, String fileVersion, String org) {
|
||||
this.id = id;
|
||||
this.fileName = fileName;
|
||||
this.deviceId = deviceId;
|
||||
|
@ -35,6 +39,7 @@ public class OtaInfo {
|
|||
this.updateType = updateType;
|
||||
this.timeout = timeout;
|
||||
this.fileVersion = fileVersion;
|
||||
this.org = org;
|
||||
}
|
||||
|
||||
public OtaInfo() {
|
||||
|
|
|
@ -3,20 +3,16 @@ package com.aiit.xiuos.mqtt;
|
|||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
||||
@Component
|
||||
@ConfigurationProperties("mqtt")
|
||||
@Setter
|
||||
@Getter
|
||||
@Slf4j
|
||||
public class MqttConfiguration {
|
||||
@Autowired
|
||||
private MyMqttClient myMqttClient;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
|
@ -47,12 +43,19 @@ public class MqttConfiguration {
|
|||
*/
|
||||
private int keepalive;
|
||||
|
||||
private String apikey;
|
||||
private String secretkey;
|
||||
private String apiurl;
|
||||
|
||||
@Bean
|
||||
public MyMqttClient getMqttPushClient() {
|
||||
MyMqttClient myMqttClient =new MyMqttClient();
|
||||
myMqttClient.connect(hostUrl, clientId, username, password, timeout, keepalive);
|
||||
// 以/#结尾表示订阅所有以test开头的主题
|
||||
myMqttClient.subscribe(defaultTopic, 0);
|
||||
log.info("订阅成功"+defaultTopic);
|
||||
myMqttClient.subscribe("$SYS/brokers/+/clients/+/#", 1);
|
||||
log.info("订阅成功,clientId:"+clientId);
|
||||
return myMqttClient;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,47 @@
|
|||
package com.aiit.xiuos.scheduled;
|
||||
|
||||
import com.aiit.xiuos.model.FirmwareInfo;
|
||||
import com.aiit.xiuos.model.OtaInfo;
|
||||
import com.aiit.xiuos.mqtt.MyMqttClient;
|
||||
import com.aiit.xiuos.service.FirmwareInfoService;
|
||||
import com.aiit.xiuos.service.OtaInfoService;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import netscape.javascript.JSObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class OTATaskScheduled {
|
||||
@Autowired
|
||||
MyMqttClient myMqttClient;
|
||||
@Autowired
|
||||
FirmwareInfoService firmwareInfoService;
|
||||
@Autowired
|
||||
OtaInfoService otaInfoService;
|
||||
@Scheduled(cron = "0 0 0 * * ?")//每日凌晨
|
||||
public void startOta(){
|
||||
List<OtaInfo> lists = otaInfoService.getNightJob();
|
||||
for(int i=0;i<lists.size();i++){
|
||||
OtaInfo otaInfo = lists.get(i);
|
||||
String fileName =otaInfo.getFileName();
|
||||
String version = otaInfo.getFileVersion();
|
||||
FirmwareInfo firmwareInfo =firmwareInfoService.getByNameAndVersion(fileName,version);
|
||||
String md5 = firmwareInfo.getFileMd5();
|
||||
long size =firmwareInfo.getFileSize();
|
||||
String clientId =otaInfo.getDeviceId();
|
||||
JSONObject payload =new JSONObject();
|
||||
payload.put("fileName",fileName);
|
||||
payload.put("version",version);
|
||||
payload.put("md5",md5);
|
||||
payload.put("fileSize",size);
|
||||
myMqttClient.publish("ota/"+clientId+"/update",payload.toJSONString());
|
||||
otaInfo.setStatus(2);
|
||||
otaInfoService.updateOtaInfo(otaInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,16 @@
|
|||
package com.aiit.xiuos.service;
|
||||
|
||||
import com.aiit.xiuos.model.OtaInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface OtaInfoService {
|
||||
List<OtaInfo> getALL(String name,String version ,String org);
|
||||
int addOtaInfo(OtaInfo info);
|
||||
List<OtaInfo> getNightJob();
|
||||
int updateOtaInfo(OtaInfo info);
|
||||
OtaInfo getJobById(String clientId);
|
||||
int deleteOtaInfo(String name,String version);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,43 @@
|
|||
package com.aiit.xiuos.service.impl;
|
||||
|
||||
public class OtaInfoServiceImpl {
|
||||
import com.aiit.xiuos.dao.mappers.OtaInfoMapper;
|
||||
import com.aiit.xiuos.model.OtaInfo;
|
||||
import com.aiit.xiuos.service.OtaInfoService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
@Service
|
||||
public class OtaInfoServiceImpl implements OtaInfoService {
|
||||
@Autowired
|
||||
OtaInfoMapper otaInfoMapper;
|
||||
@Override
|
||||
public List<OtaInfo> getALL(String name,String version,String org) {
|
||||
return otaInfoMapper.getAll(name,version,org);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int addOtaInfo(OtaInfo info) {
|
||||
return otaInfoMapper.insertSelective(info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OtaInfo> getNightJob() {
|
||||
return otaInfoMapper.getJob();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateOtaInfo(OtaInfo info) {
|
||||
return otaInfoMapper.updateByPrimaryKeySelective(info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OtaInfo getJobById(String clientId) {
|
||||
return otaInfoMapper.getOtaInfo(clientId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deleteOtaInfo(String name, String version) {
|
||||
return otaInfoMapper.deleteOtaInfo(name,version);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,9 +76,11 @@ mqtt:
|
|||
#默认主题
|
||||
default-topic: xiuosiot/#
|
||||
#api key
|
||||
apikey: 6eea245a7f531f2f
|
||||
apikey: ac527c699ec31245
|
||||
#secret key
|
||||
secretkey: XsyKpCXGvPfWifwOjsK2J2JP3E9AouxezXm8SqaJXcYP
|
||||
secretkey: UEqxxgyY9Ba3Kebl2zlEu9Bq67n9AR9CdxDQ0iYz802XsbO
|
||||
#api url
|
||||
apiurl: http://8.140.53.225:18083
|
||||
|
||||
tdengine:
|
||||
url: jdbc:TAOS://taosnode1:6030/xiuosiot?user=root&password=taosdata
|
||||
|
|
|
@ -57,7 +57,7 @@ mybatis:
|
|||
#MQTT Config
|
||||
mqtt:
|
||||
#MQTT-服务器连接地
|
||||
hostUrl: tcp://localhost:1883
|
||||
hostUrl: tcp://115.238.53.59:1883
|
||||
#MQTT-连接服务器默认客户端ID
|
||||
clientId: xiuosiot-client
|
||||
#MQTT-用户名
|
||||
|
@ -74,6 +74,8 @@ mqtt:
|
|||
apikey: 13e1c0be6d573f86
|
||||
#secret key
|
||||
secretkey: 9BLxyWslygS5oFTz8TX5ssJ7JMiBY9CefU9B35uWx3ltqN
|
||||
#api url
|
||||
apiurl: http://115.238.53.59:18083
|
||||
tdengine:
|
||||
url: jdbc:TAOS://xiuosiot.taosnode1:6030/xiuosiot?user=root&password=taosdata
|
||||
|
||||
|
|
|
@ -27,13 +27,13 @@
|
|||
</rollingPolicy>
|
||||
</appender>
|
||||
<!--创建一个具体的日志输出-->
|
||||
<logger name="com.aiit" level="info" additivity="true">
|
||||
<logger name="com.aiit" level="debug" additivity="true">
|
||||
<!--可以有多个appender-ref,即将日志记录到不同的位置-->
|
||||
<appender-ref ref="STDOUT"/>
|
||||
<appender-ref ref="fileLog"/>
|
||||
</logger>
|
||||
|
||||
<!--基础的日志输出-->
|
||||
<root level="info">
|
||||
<root level="debug">
|
||||
</root>
|
||||
</configuration>
|
|
@ -0,0 +1,155 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.aiit.xiuos.dao.mappers.OtaInfoMapper">
|
||||
<resultMap id="BaseResultMap" type="com.aiit.xiuos.model.OtaInfo">
|
||||
<constructor>
|
||||
<idArg column="id" javaType="java.lang.Integer" jdbcType="INTEGER" />
|
||||
<arg column="file_name" javaType="java.lang.String" jdbcType="VARCHAR" />
|
||||
<arg column="device_id" javaType="java.lang.String" jdbcType="VARCHAR" />
|
||||
<arg column="current_process" javaType="java.lang.Integer" jdbcType="INTEGER" />
|
||||
<arg column="status" javaType="java.lang.Integer" jdbcType="INTEGER" />
|
||||
<arg column="create_time" javaType="java.util.Date" jdbcType="TIMESTAMP" />
|
||||
<arg column="update_type" javaType="java.lang.Integer" jdbcType="INTEGER" />
|
||||
<arg column="timeout" javaType="java.util.Date" jdbcType="TIMESTAMP" />
|
||||
<arg column="file_version" javaType="java.lang.String" jdbcType="VARCHAR" />
|
||||
<arg column="org" javaType="java.lang.String" jdbcType="VARCHAR" />
|
||||
</constructor>
|
||||
</resultMap>
|
||||
<sql id="Base_Column_List">
|
||||
id, file_name, device_id, current_process, status, create_time, update_type, timeout,
|
||||
file_version, org
|
||||
</sql>
|
||||
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
|
||||
select
|
||||
<include refid="Base_Column_List" />
|
||||
from ota_info
|
||||
where id = #{id,jdbcType=INTEGER}
|
||||
</select>
|
||||
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
|
||||
delete from ota_info
|
||||
where id = #{id,jdbcType=INTEGER}
|
||||
</delete>
|
||||
<insert id="insert" parameterType="com.aiit.xiuos.model.OtaInfo">
|
||||
insert into ota_info (id, file_name, device_id,
|
||||
current_process, status, create_time,
|
||||
update_type, timeout, file_version,
|
||||
org)
|
||||
values (#{id,jdbcType=INTEGER}, #{fileName,jdbcType=VARCHAR}, #{deviceId,jdbcType=VARCHAR},
|
||||
#{currentProcess,jdbcType=INTEGER}, #{status,jdbcType=INTEGER}, #{createTime,jdbcType=TIMESTAMP},
|
||||
#{updateType,jdbcType=INTEGER}, #{timeout,jdbcType=TIMESTAMP}, #{fileVersion,jdbcType=VARCHAR},
|
||||
#{org,jdbcType=VARCHAR})
|
||||
</insert>
|
||||
<insert id="insertSelective" parameterType="com.aiit.xiuos.model.OtaInfo">
|
||||
insert into ota_info
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="id != null">
|
||||
id,
|
||||
</if>
|
||||
<if test="fileName != null">
|
||||
file_name,
|
||||
</if>
|
||||
<if test="deviceId != null">
|
||||
device_id,
|
||||
</if>
|
||||
<if test="currentProcess != null">
|
||||
current_process,
|
||||
</if>
|
||||
<if test="status != null">
|
||||
status,
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
create_time,
|
||||
</if>
|
||||
<if test="updateType != null">
|
||||
update_type,
|
||||
</if>
|
||||
<if test="timeout != null">
|
||||
timeout,
|
||||
</if>
|
||||
<if test="fileVersion != null">
|
||||
file_version,
|
||||
</if>
|
||||
<if test="org != null">
|
||||
org,
|
||||
</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="id != null">
|
||||
#{id,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="fileName != null">
|
||||
#{fileName,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="deviceId != null">
|
||||
#{deviceId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="currentProcess != null">
|
||||
#{currentProcess,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="status != null">
|
||||
#{status,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
#{createTime,jdbcType=TIMESTAMP},
|
||||
</if>
|
||||
<if test="updateType != null">
|
||||
#{updateType,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="timeout != null">
|
||||
#{timeout,jdbcType=TIMESTAMP},
|
||||
</if>
|
||||
<if test="fileVersion != null">
|
||||
#{fileVersion,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="org != null">
|
||||
#{org,jdbcType=VARCHAR},
|
||||
</if>
|
||||
</trim>
|
||||
</insert>
|
||||
<update id="updateByPrimaryKeySelective" parameterType="com.aiit.xiuos.model.OtaInfo">
|
||||
update ota_info
|
||||
<set>
|
||||
<if test="fileName != null">
|
||||
file_name = #{fileName,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="deviceId != null">
|
||||
device_id = #{deviceId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="currentProcess != null">
|
||||
current_process = #{currentProcess,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="status != null">
|
||||
status = #{status,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
create_time = #{createTime,jdbcType=TIMESTAMP},
|
||||
</if>
|
||||
<if test="updateType != null">
|
||||
update_type = #{updateType,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="timeout != null">
|
||||
timeout = #{timeout,jdbcType=TIMESTAMP},
|
||||
</if>
|
||||
<if test="fileVersion != null">
|
||||
file_version = #{fileVersion,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="org != null">
|
||||
org = #{org,jdbcType=VARCHAR},
|
||||
</if>
|
||||
</set>
|
||||
where id = #{id,jdbcType=INTEGER}
|
||||
</update>
|
||||
<update id="updateByPrimaryKey" parameterType="com.aiit.xiuos.model.OtaInfo">
|
||||
update ota_info
|
||||
set file_name = #{fileName,jdbcType=VARCHAR},
|
||||
device_id = #{deviceId,jdbcType=VARCHAR},
|
||||
current_process = #{currentProcess,jdbcType=INTEGER},
|
||||
status = #{status,jdbcType=INTEGER},
|
||||
create_time = #{createTime,jdbcType=TIMESTAMP},
|
||||
update_type = #{updateType,jdbcType=INTEGER},
|
||||
timeout = #{timeout,jdbcType=TIMESTAMP},
|
||||
file_version = #{fileVersion,jdbcType=VARCHAR},
|
||||
org = #{org,jdbcType=VARCHAR}
|
||||
where id = #{id,jdbcType=INTEGER}
|
||||
</update>
|
||||
</mapper>
|
Loading…
Reference in New Issue