From af3d394b39b5e259958528c6b75a402ebc0fe3df Mon Sep 17 00:00:00 2001 From: weidong Date: Mon, 8 Apr 2024 10:57:14 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E5=A2=9E=E5=8A=A0=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E6=8C=87=E4=BB=A4=E4=B8=8B=E5=8F=91=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../imdroid/secapi/dto/DeviceCacheCmd.java | 34 +++++++ .../secapi/dto/DeviceCacheCmdMapper.java | 10 ++ .../calc/SingleLineGNSSCalcService.java | 9 ++ .../executor/D331RtcmMessageExecutor.java | 19 ++++ .../executor/D341LocationMessageExecutor.java | 20 +++- .../com/imdroid/sideslope/sal/Device.java | 2 +- .../beidou/controller/APIController.java | 16 ++++ .../beidou/controller/CmdLineController.java | 77 ++++++++++++++- sec-beidou/src/main/resources/db/schema.sql | 16 +++- .../resources/templates/page/cmd_line.html | 39 +++++++- .../templates/page/table/gnss_add_dev.html | 30 +++--- .../templates/page/table/q_cache_cmd.html | 95 +++++++++++++++++++ 12 files changed, 344 insertions(+), 23 deletions(-) create mode 100644 sec-api/src/main/java/com/imdroid/secapi/dto/DeviceCacheCmd.java create mode 100644 sec-api/src/main/java/com/imdroid/secapi/dto/DeviceCacheCmdMapper.java create mode 100644 sec-beidou/src/main/resources/templates/page/table/q_cache_cmd.html diff --git a/sec-api/src/main/java/com/imdroid/secapi/dto/DeviceCacheCmd.java b/sec-api/src/main/java/com/imdroid/secapi/dto/DeviceCacheCmd.java new file mode 100644 index 00000000..914d4fda --- /dev/null +++ b/sec-api/src/main/java/com/imdroid/secapi/dto/DeviceCacheCmd.java @@ -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; +} diff --git a/sec-api/src/main/java/com/imdroid/secapi/dto/DeviceCacheCmdMapper.java b/sec-api/src/main/java/com/imdroid/secapi/dto/DeviceCacheCmdMapper.java new file mode 100644 index 00000000..4e50e35f --- /dev/null +++ b/sec-api/src/main/java/com/imdroid/secapi/dto/DeviceCacheCmdMapper.java @@ -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 { + +} diff --git a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/calc/SingleLineGNSSCalcService.java b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/calc/SingleLineGNSSCalcService.java index baa553e7..7c51bf59 100644 --- a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/calc/SingleLineGNSSCalcService.java +++ b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/calc/SingleLineGNSSCalcService.java @@ -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()); } diff --git a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/executor/D331RtcmMessageExecutor.java b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/executor/D331RtcmMessageExecutor.java index caa241ad..0a017c33 100644 --- a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/executor/D331RtcmMessageExecutor.java +++ b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/executor/D331RtcmMessageExecutor.java @@ -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 @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 " 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; } diff --git a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/executor/D341LocationMessageExecutor.java b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/executor/D341LocationMessageExecutor.java index 74943cc4..6d00dc18 100644 --- a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/executor/D341LocationMessageExecutor.java +++ b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/executor/D341LocationMessageExecutor.java @@ -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 { gnssCalcService.calcSingle(message,true); }); diff --git a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/sal/Device.java b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/sal/Device.java index 259e95d5..dfe84491 100644 --- a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/sal/Device.java +++ b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/sal/Device.java @@ -86,7 +86,7 @@ public class Device { } } - void clearStat(){ + public void clearStat(){ d3xxCount = 0; d3xxbytes = 0; d341Count = 0; diff --git a/sec-beidou/src/main/java/com/imdroid/beidou/controller/APIController.java b/sec-beidou/src/main/java/com/imdroid/beidou/controller/APIController.java index 0a2cf6f8..480e0384 100644 --- a/sec-beidou/src/main/java/com/imdroid/beidou/controller/APIController.java +++ b/sec-beidou/src/main/java/com/imdroid/beidou/controller/APIController.java @@ -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 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; } diff --git a/sec-beidou/src/main/java/com/imdroid/beidou/controller/CmdLineController.java b/sec-beidou/src/main/java/com/imdroid/beidou/controller/CmdLineController.java index 7c9601fe..55af070c 100644 --- a/sec-beidou/src/main/java/com/imdroid/beidou/controller/CmdLineController.java +++ b/sec-beidou/src/main/java/com/imdroid/beidou/controller/CmdLineController.java @@ -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 pageable = new Page<>(page, limit); IPage 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 pageable = new Page<>(page, limit); + IPage 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(); + } } diff --git a/sec-beidou/src/main/resources/db/schema.sql b/sec-beidou/src/main/resources/db/schema.sql index d5c947fe..15a5ecbe 100644 --- a/sec-beidou/src/main/resources/db/schema.sql +++ b/sec-beidou/src/main/resources/db/schema.sql @@ -280,4 +280,18 @@ CREATE TABLE IF NOT EXISTS `devicecmd` ( `type` smallint NOT NULL, `content` varchar(800) NOT NULL, PRIMARY KEY (`id`) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; \ No newline at end of file + ) 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; \ No newline at end of file diff --git a/sec-beidou/src/main/resources/templates/page/cmd_line.html b/sec-beidou/src/main/resources/templates/page/cmd_line.html index 2c29f4bb..1b0f02be 100644 --- a/sec-beidou/src/main/resources/templates/page/cmd_line.html +++ b/sec-beidou/src/main/resources/templates/page/cmd_line.html @@ -37,7 +37,7 @@
- +
@@ -54,10 +54,12 @@
-
- +
+ + +
@@ -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: '常用指令', diff --git a/sec-beidou/src/main/resources/templates/page/table/gnss_add_dev.html b/sec-beidou/src/main/resources/templates/page/table/gnss_add_dev.html index 645a983f..42ad0bd4 100644 --- a/sec-beidou/src/main/resources/templates/page/table/gnss_add_dev.html +++ b/sec-beidou/src/main/resources/templates/page/table/gnss_add_dev.html @@ -189,20 +189,22 @@ }); form.on('submit(initLocBtn)', function (data) { - $.ajax({ - type:"POST", - url:"/gnss/device/init_loc", - data:{ - 'deviceid':$('#deviceid').val() - }, - success: function (result) { - $('#ipose').val(result.ipose); - $('#iposn').val(result.iposn); - $('#iposd').val(result.iposd); - }, - error: function () { - console.log("ajax error"); - } + layer.confirm('确定重新取初值?', function(index){ + $.ajax({ + type:"POST", + url:"/gnss/device/init_loc", + data:{ + 'deviceid':$('#deviceid').val() + }, + success: function (result) { + $('#ipose').val(result.ipose); + $('#iposn').val(result.iposn); + $('#iposd').val(result.iposd); + }, + error: function () { + console.log("ajax error"); + } + }); }); return false; diff --git a/sec-beidou/src/main/resources/templates/page/table/q_cache_cmd.html b/sec-beidou/src/main/resources/templates/page/table/q_cache_cmd.html new file mode 100644 index 00000000..9cdebf42 --- /dev/null +++ b/sec-beidou/src/main/resources/templates/page/table/q_cache_cmd.html @@ -0,0 +1,95 @@ + + + + + 待发送指令 + + + + + + + + + +
+
+
+ + + + + + + + + + \ No newline at end of file