1、增加缓存指令下发功能
This commit is contained in:
parent
f92e2748b7
commit
af3d394b39
@ -0,0 +1,34 @@
|
||||
package com.imdroid.secapi.dto;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* GNSS收发统计消息,每个工作周期结束的时候统计一次
|
||||
*
|
||||
* @author LiGang
|
||||
*/
|
||||
@Data
|
||||
@TableName(value = "cachecmd")
|
||||
public class DeviceCacheCmd {
|
||||
// device type definition
|
||||
public static final short TYPE_GNSS = 0;
|
||||
public static final short TYPE_DTU = 1;
|
||||
public static final short TYPE_MPU = 2;
|
||||
public static final short TYPE_DEBUG = 3;
|
||||
|
||||
public static final short MAX_CMD_LEN = 350;
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
Long id;
|
||||
LocalDateTime updatetime;
|
||||
String deviceid;
|
||||
Boolean syn;
|
||||
Short type;
|
||||
Integer msgtype;
|
||||
String cmd;
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package com.imdroid.secapi.dto;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
|
||||
@Mapper
|
||||
public interface DeviceCacheCmdMapper extends BaseMapper<DeviceCacheCmd> {
|
||||
|
||||
}
|
||||
@ -4,12 +4,15 @@ import com.imdroid.common.util.ThreadManager;
|
||||
import com.imdroid.secapi.dto.GnssCalcData;
|
||||
import com.imdroid.sideslope.bd.*;
|
||||
import com.imdroid.sideslope.message.D341LocationMessage;
|
||||
import com.imdroid.sideslope.sal.Device;
|
||||
import com.imdroid.sideslope.sal.DeviceService;
|
||||
import com.imdroid.sideslope.service.WarningService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
@ -41,6 +44,9 @@ public class SingleLineGNSSCalcService implements GNSSDataCalcService {
|
||||
@Autowired
|
||||
GNSSCalcFilterService gnssCalcFilterService;
|
||||
|
||||
@Resource(name = "local")
|
||||
private DeviceService deviceService;
|
||||
|
||||
@Override
|
||||
public double[] calcSingle(D341LocationMessage message, boolean completeWhenIdle) {
|
||||
String deviceId = message.getId();
|
||||
@ -92,6 +98,9 @@ public class SingleLineGNSSCalcService implements GNSSDataCalcService {
|
||||
future = ThreadManager.getScheduledThreadPool().schedule(() -> {
|
||||
try {
|
||||
calCycleResult(deviceId, tenantId, date);
|
||||
// 清除统计
|
||||
Device device = deviceService.findByDeviceId(deviceId);
|
||||
if(device != null) device.clearStat();
|
||||
} catch (Exception e) {
|
||||
logger.error(e.toString());
|
||||
}
|
||||
|
||||
@ -1,15 +1,18 @@
|
||||
package com.imdroid.sideslope.executor;
|
||||
|
||||
import com.imdroid.secapi.client.BeidouClient;
|
||||
import com.imdroid.secapi.dto.GnssDevice;
|
||||
import com.imdroid.sideslope.bd.Gga;
|
||||
import com.imdroid.sideslope.message.D331RtcmMessage;
|
||||
import com.imdroid.sideslope.sal.Device;
|
||||
import com.imdroid.sideslope.sal.DeviceService;
|
||||
import com.imdroid.sideslope.server.DeviceChannel;
|
||||
import com.imdroid.sideslope.server.OnlineChannels;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
@ -26,6 +29,8 @@ public class D331RtcmMessageExecutor implements Executor<D331RtcmMessage, Void>
|
||||
|
||||
@Resource(name = "local")
|
||||
private DeviceService deviceService;
|
||||
@Autowired
|
||||
private BeidouClient beidouClient;
|
||||
|
||||
@Override
|
||||
public Void execute(D331RtcmMessage message) {
|
||||
@ -73,6 +78,20 @@ public class D331RtcmMessageExecutor implements Executor<D331RtcmMessage, Void>
|
||||
" quality: "+gga.getQuality());*/
|
||||
}
|
||||
|
||||
// 收到第一个数据包,如果控制通道没连接,也通知上线
|
||||
if(device1.getD3xxCount() == 1){
|
||||
DeviceChannel channel = OnlineChannels.INSTANCE.getConfigChannel(device1.getDeviceId());
|
||||
if(channel == null || !channel.isOnline()){
|
||||
// 通知上线
|
||||
try{
|
||||
beidouClient.onDeviceActive(device1.getDeviceId(), device1.getTenantId());
|
||||
}
|
||||
catch (Exception e){
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
package com.imdroid.sideslope.executor;
|
||||
|
||||
import com.imdroid.secapi.client.BeidouClient;
|
||||
import com.imdroid.sideslope.bd.Gga;
|
||||
import com.imdroid.sideslope.calc.GNSSDataCalcService;
|
||||
import com.imdroid.sideslope.message.D341LocationMessage;
|
||||
import com.imdroid.sideslope.sal.Device;
|
||||
import com.imdroid.sideslope.sal.DeviceService;
|
||||
import com.imdroid.common.util.ThreadManager;
|
||||
import com.imdroid.sideslope.server.DeviceChannel;
|
||||
import com.imdroid.sideslope.server.OnlineChannels;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -26,7 +29,8 @@ public class D341LocationMessageExecutor implements Executor<D341LocationMessage
|
||||
private GNSSDataCalcService gnssCalcService;
|
||||
@Resource(name = "local")
|
||||
private DeviceService deviceService;
|
||||
|
||||
@Autowired
|
||||
private BeidouClient beidouClient;
|
||||
@Override
|
||||
public Void execute(D341LocationMessage message) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
@ -47,6 +51,20 @@ public class D341LocationMessageExecutor implements Executor<D341LocationMessage
|
||||
}
|
||||
}
|
||||
|
||||
// 收到第一个数据包,如果控制通道没连接,也通知上线
|
||||
if(device.getD341Count() == 1){
|
||||
DeviceChannel channel = OnlineChannels.INSTANCE.getConfigChannel(device.getDeviceId());
|
||||
if(channel == null || !channel.isOnline()){
|
||||
// 通知上线
|
||||
try{
|
||||
beidouClient.onDeviceActive(device.getDeviceId(), device.getTenantId());
|
||||
}
|
||||
catch (Exception e){
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ThreadManager.getFixedThreadPool().submit(() -> {
|
||||
gnssCalcService.calcSingle(message,true);
|
||||
});
|
||||
|
||||
@ -86,7 +86,7 @@ public class Device {
|
||||
}
|
||||
}
|
||||
|
||||
void clearStat(){
|
||||
public void clearStat(){
|
||||
d3xxCount = 0;
|
||||
d3xxbytes = 0;
|
||||
d341Count = 0;
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.imdroid.beidou.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.imdroid.secapi.client.RtcmClient;
|
||||
import com.imdroid.secapi.dto.*;
|
||||
import com.imdroid.secapi.utils.HexUtil;
|
||||
@ -26,6 +27,8 @@ public class APIController extends BasicController{
|
||||
GnssMsgMapper msgMapper;
|
||||
@Autowired
|
||||
GnssStatusMapper gnssStatusMapper;
|
||||
@Autowired
|
||||
DeviceCacheCmdMapper cacheCmdMapper;
|
||||
|
||||
/****** config ack *******/
|
||||
@PostMapping(value = "/api/config_ack")
|
||||
@ -117,6 +120,19 @@ public class APIController extends BasicController{
|
||||
}
|
||||
}
|
||||
|
||||
// 检查有没有待发送的指令
|
||||
QueryWrapper<DeviceCacheCmd> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("deviceid",deviceId);
|
||||
queryWrapper.eq("syn",false);
|
||||
DeviceCacheCmd cacheCmd = cacheCmdMapper.selectOne(queryWrapper);
|
||||
if(cacheCmd != null){
|
||||
rtcmClient.config(deviceId, cacheCmd.getCmd());
|
||||
cacheCmd.setSyn(true);
|
||||
cacheCmdMapper.updateById(cacheCmd);
|
||||
// 保存
|
||||
saveMsg(deviceId, tenantId,cacheCmd.getMsgtype(), cacheCmd.getCmd(), true);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@ -27,6 +27,8 @@ public class CmdLineController extends BasicController{
|
||||
GnssMsgMapper msgMapper;
|
||||
@Autowired
|
||||
DeviceCmdMapper deviceCmdMapper;
|
||||
@Autowired
|
||||
DeviceCacheCmdMapper cacheCmdMapper;
|
||||
|
||||
/**** 推送页面 *****/
|
||||
@RequestMapping("/page/cmd_line")
|
||||
@ -43,6 +45,13 @@ public class CmdLineController extends BasicController{
|
||||
return "/page/table/frequent_cmd";
|
||||
}
|
||||
|
||||
@RequestMapping("/page/table/q_cache_cmd")
|
||||
public String queryCacheCmd(Model m, HttpSession session) {
|
||||
initModel(m, session);
|
||||
|
||||
return "/page/table/q_cache_cmd";
|
||||
}
|
||||
|
||||
/****** 发送指令 *******/
|
||||
@PostMapping(value = "/gnss/config_cmd")
|
||||
@ResponseBody
|
||||
@ -92,9 +101,48 @@ public class CmdLineController extends BasicController{
|
||||
return HttpResult.success(txInfo);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/gnss/cache_cmd")
|
||||
@ResponseBody
|
||||
public HttpResult cacheCmd(HttpSession session,
|
||||
@RequestParam("tx_win") String cmd,
|
||||
@RequestParam("device_id") String deviceId,
|
||||
@RequestParam("cmd_type") int cmdType) {
|
||||
String sendCmd = cmd.replaceAll(" +","");
|
||||
short len = 0;
|
||||
int msgType;
|
||||
if(cmdType == 1){ // DTU,string format
|
||||
msgType = 0xD31A;
|
||||
len = (short) (sendCmd.length() + 5);
|
||||
sendCmd = "D31A"+ HexUtil.Short2HexString(len)+
|
||||
HexUtil.Int2HexString(Integer.parseInt(deviceId))+
|
||||
"01"+HexUtil.String2HexString(sendCmd);
|
||||
}
|
||||
else{ //hex format
|
||||
msgType = 0xD310+cmdType;
|
||||
len = (short) (sendCmd.length()/2+4);
|
||||
sendCmd = Integer.toHexString(msgType) + HexUtil.Short2HexString(len)+
|
||||
HexUtil.Int2HexString(Integer.parseInt(deviceId))+sendCmd;
|
||||
}
|
||||
|
||||
// 保存
|
||||
if(sendCmd.length() >= DeviceCacheCmd.MAX_CMD_LEN) {
|
||||
return HttpResult.fail("指令过长,不能超过325字节");
|
||||
}
|
||||
DeviceCacheCmd cacheCmd = new DeviceCacheCmd();
|
||||
cacheCmd.setDeviceid(deviceId);
|
||||
cacheCmd.setUpdatetime(LocalDateTime.now());
|
||||
cacheCmd.setType((short) cmdType);
|
||||
cacheCmd.setSyn(false);
|
||||
cacheCmd.setCmd(sendCmd);
|
||||
cacheCmd.setMsgtype(msgType);
|
||||
cacheCmdMapper.insert(cacheCmd);
|
||||
|
||||
return HttpResult.success("OK");
|
||||
}
|
||||
|
||||
@RequestMapping("/gnss/cmd/list")
|
||||
@ResponseBody
|
||||
public JSONObject list(int page, int limit) {
|
||||
public JSONObject listCmd(int page, int limit) {
|
||||
Page<DeviceCmd> pageable = new Page<>(page, limit);
|
||||
IPage<DeviceCmd> cs = deviceCmdMapper.selectPage(pageable, null);
|
||||
|
||||
@ -106,9 +154,23 @@ public class CmdLineController extends BasicController{
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
@RequestMapping("/gnss/cache_cmd/list")
|
||||
@ResponseBody
|
||||
public JSONObject listCacheCmd(int page, int limit) {
|
||||
Page<DeviceCacheCmd> pageable = new Page<>(page, limit);
|
||||
IPage<DeviceCacheCmd> cs = cacheCmdMapper.selectPage(pageable, null);
|
||||
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("code", 0);
|
||||
jsonObject.put("msg", "");
|
||||
jsonObject.put("count", cs.getTotal());
|
||||
jsonObject.put("data", cs.getRecords());
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
@PostMapping("/gnss/cmd/add")
|
||||
@ResponseBody
|
||||
public String add(@RequestBody JSONObject object) throws Exception {
|
||||
public String addCmd(@RequestBody JSONObject object) throws Exception {
|
||||
DeviceCmd deviceCmd = JSONObject.toJavaObject(object,DeviceCmd.class);
|
||||
int num = deviceCmdMapper.insert(deviceCmd);
|
||||
|
||||
@ -121,10 +183,19 @@ public class CmdLineController extends BasicController{
|
||||
|
||||
@PostMapping("/gnss/cmd/delete")
|
||||
@ResponseBody
|
||||
public String delete(@RequestParam int del_id) throws Exception {
|
||||
public String deleteCmd(@RequestParam int del_id) throws Exception {
|
||||
int num = deviceCmdMapper.deleteById(del_id);
|
||||
if (num == 0) {
|
||||
return HttpResult.failed();
|
||||
} else return HttpResult.ok();
|
||||
}
|
||||
|
||||
@PostMapping("/gnss/cache_cmd/delete")
|
||||
@ResponseBody
|
||||
public String deleteCacheCmd(@RequestParam int del_id) throws Exception {
|
||||
int num = cacheCmdMapper.deleteById(del_id);
|
||||
if (num == 0) {
|
||||
return HttpResult.failed();
|
||||
} else return HttpResult.ok();
|
||||
}
|
||||
}
|
||||
|
||||
@ -281,3 +281,17 @@ CREATE TABLE IF NOT EXISTS `devicecmd` (
|
||||
`content` varchar(800) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
/***
|
||||
常用指令
|
||||
*/
|
||||
CREATE TABLE IF NOT EXISTS `cachecmd` (
|
||||
`id` bigint AUTO_INCREMENT,
|
||||
`updatetime` datetime DEFAULT NULL,
|
||||
`deviceid` varchar(20) NOT NULL,
|
||||
`syn` bit(1) DEFAULT 0 COMMENT '是否已同步',
|
||||
`type` smallint NOT NULL,
|
||||
`msgtype` int default 0,
|
||||
`cmd` varchar(350) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
@ -37,7 +37,7 @@
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">设备ID</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="device_id" lay-verify="required|number" autocomplete="off" class="layui-input">
|
||||
<input type="text" name="device_id" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
@ -54,10 +54,12 @@
|
||||
</div>
|
||||
|
||||
<div class="layui-inline">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn" lay-submit="" lay-filter="send_btn">发送</button>
|
||||
<div class="layui-input-block" style="float:right">
|
||||
<button class="layui-btn" lay-submit="" lay-filter="send_btn">立即发送</button>
|
||||
<button class="layui-btn" lay-submit="" lay-filter="cache_btn">缓存发送</button>
|
||||
<button class="layui-btn" lay-submit="" lay-filter="clear_btn">清屏</button>
|
||||
<button class="layui-btn" lay-submit="" lay-filter="frequent_btn">常用指令</button>
|
||||
<button class="layui-btn" lay-submit="" lay-filter="q_cache_btn">待发指令</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -108,11 +110,42 @@
|
||||
return false;
|
||||
});
|
||||
|
||||
form.on('submit(cache_btn)', function (data) {
|
||||
$.ajax({
|
||||
type:"POST",
|
||||
url:"/gnss/cache_cmd",
|
||||
data:data.field,
|
||||
success: function (result) {
|
||||
if(result.code == 0) layer.msg('指令已缓存,收到终端数据时下发');
|
||||
else layer.alert(result.msg);
|
||||
},
|
||||
error: function () {
|
||||
console.log("ajax error");
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
form.on('submit(clear_btn)', function (data) {
|
||||
rxWin.val("");
|
||||
return false;
|
||||
});
|
||||
|
||||
form.on('submit(q_cache_btn)', function (data) {
|
||||
var index = layer.open({
|
||||
title: '待发送指令',
|
||||
type: 2,
|
||||
shade: 0.2,
|
||||
maxmin:true,
|
||||
shadeClose: true,
|
||||
offset: 'rb',
|
||||
anim: 2,
|
||||
area: ['50%', '100%'],
|
||||
content: '../page/table/q_cache_cmd',
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
form.on('submit(frequent_btn)', function (data) {
|
||||
var index = layer.open({
|
||||
title: '常用指令',
|
||||
|
||||
@ -189,6 +189,7 @@
|
||||
});
|
||||
|
||||
form.on('submit(initLocBtn)', function (data) {
|
||||
layer.confirm('确定重新取初值?', function(index){
|
||||
$.ajax({
|
||||
type:"POST",
|
||||
url:"/gnss/device/init_loc",
|
||||
@ -204,6 +205,7 @@
|
||||
console.log("ajax error");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
@ -0,0 +1,95 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>待发送指令</title>
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<link rel="stylesheet" href="../../lib/layui-v2.6.3/css/layui.css" media="all">
|
||||
<link rel="stylesheet" href="../../css/public.css" media="all">
|
||||
<style>
|
||||
body {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="layui-form layuimini-form">
|
||||
<table class="layui-hide" id="currentTableId" lay-filter="currentTableFilter"></table>
|
||||
</div>
|
||||
|
||||
<script src="../../lib/layui-v2.6.3/layui.js" charset="utf-8"></script>
|
||||
|
||||
<script type="text/html" id="currentTableBar">
|
||||
<a class="layui-btn layui-btn-xs layui-btn-danger data-count-delete" lay-event="delete">删除</a>
|
||||
</script>
|
||||
|
||||
<script th:inline="none">
|
||||
layui.use(['form', 'table'], function () {
|
||||
var $ = layui.$,
|
||||
form = layui.form,
|
||||
table = layui.table;
|
||||
var iframeIndex = parent.layer.getFrameIndex(window.name);
|
||||
/**
|
||||
* 初始化表单,要加上,不然刷新部分组件可能会不加载
|
||||
*/
|
||||
form.render();
|
||||
|
||||
table.render({
|
||||
elem: '#currentTableId',
|
||||
url: '/gnss/cache_cmd/list',
|
||||
cols: [[
|
||||
{field: 'deviceid', title: '设备编号'},
|
||||
{field: 'updatetime', title: '更新时间', templet: "<div>{{layui.util.toDateString(d.updatetime, 'yyyy-MM-dd HH:mm:ss')}}</div>"},
|
||||
{field: 'syn', title: '已发送',templet: "<div>{{d.syn==1?'是':'否'}}</div>"},
|
||||
{field: 'type', title: '类型',templet: '#typeTrans'},
|
||||
{field: 'cmd', title: '指令',width:'35%'},
|
||||
{title: '操作', toolbar: '#currentTableBar', fixed: "right", minWidth: 60}
|
||||
]],
|
||||
limits: [10, 20, 50],
|
||||
limit: 10,
|
||||
page: true,
|
||||
skin: 'line'
|
||||
});
|
||||
|
||||
table.on('tool(currentTableFilter)', function (obj) {
|
||||
var data = obj.data;
|
||||
if (obj.event === 'delete') {
|
||||
layer.confirm('确定删除该条指令?', function(index){
|
||||
$.ajax({
|
||||
type:"POST",
|
||||
url:"/gnss/cache_cmd/delete",
|
||||
data:{
|
||||
'del_id':data.id
|
||||
},
|
||||
success: function (data) {
|
||||
//data是cotroller相应处理函数的返回值
|
||||
table.reload('currentTableId');
|
||||
},
|
||||
error: function () {
|
||||
console.log("ajax error");
|
||||
}
|
||||
});
|
||||
layer.close(index);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="typeTrans">
|
||||
{{# if(d.type == 0){ }}
|
||||
<span>GNSS</span>
|
||||
{{# } else if(d.type == 1){ }}
|
||||
<span >DTU</span>
|
||||
{{# } else if(d.type == 2){ }}
|
||||
<span >MPU</span>
|
||||
{{# } else { }}
|
||||
<span >DEBUG</span>
|
||||
{{# } }}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
x
Reference in New Issue
Block a user