From 02f2196ebe4bd25b7d993ff8ca88e2edce8a98b3 Mon Sep 17 00:00:00 2001 From: weidong Date: Mon, 11 Dec 2023 11:17:12 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=A1=A5=E4=BC=A0=E6=8E=A8?= =?UTF-8?q?=E9=80=81=E7=AC=AC=E4=B8=89=E6=96=B9=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/imdroid/secapi/dto/FwdRecord.java | 30 ++++++++ .../imdroid/secapi/dto/FwdRecordMapper.java | 8 +++ .../calc/MultiLineGNSSCalcService.java | 32 +++++++++ .../executor/D342LocationMessageExecutor.java | 1 + .../sideslope/fwd/ForwardGnssTask.java | 70 +++++++++++++++++-- .../message/D342LocationMessage.java | 1 + .../sideslope/sal/DbDeviceServiceImpl.java | 2 + .../com/imdroid/sideslope/sal/Device.java | 1 + sec-beidou/src/main/resources/db/schema.sql | 15 ++++ 9 files changed, 154 insertions(+), 6 deletions(-) create mode 100644 sec-api/src/main/java/com/imdroid/secapi/dto/FwdRecord.java create mode 100644 sec-api/src/main/java/com/imdroid/secapi/dto/FwdRecordMapper.java diff --git a/sec-api/src/main/java/com/imdroid/secapi/dto/FwdRecord.java b/sec-api/src/main/java/com/imdroid/secapi/dto/FwdRecord.java new file mode 100644 index 00000000..adc635c4 --- /dev/null +++ b/sec-api/src/main/java/com/imdroid/secapi/dto/FwdRecord.java @@ -0,0 +1,30 @@ +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 = "fwdrecords") +public class FwdRecord { + public static final short STATE_READY = 1; + public static final short STATE_UPLOADING = 2; + public static final short STATE_UPLOAD_DONE = 3; + public static final short STATE_FWD_DONE = 0; + @TableId(value = "id", type = IdType.AUTO) + Long id; + Integer tenantid; + String deviceid; + String project_id; + LocalDateTime starttime; + LocalDateTime endtime; + Short state; +} diff --git a/sec-api/src/main/java/com/imdroid/secapi/dto/FwdRecordMapper.java b/sec-api/src/main/java/com/imdroid/secapi/dto/FwdRecordMapper.java new file mode 100644 index 00000000..1661e2a8 --- /dev/null +++ b/sec-api/src/main/java/com/imdroid/secapi/dto/FwdRecordMapper.java @@ -0,0 +1,8 @@ +package com.imdroid.secapi.dto; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface FwdRecordMapper extends BaseMapper { +} diff --git a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/calc/MultiLineGNSSCalcService.java b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/calc/MultiLineGNSSCalcService.java index f062b11c..0acf2761 100644 --- a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/calc/MultiLineGNSSCalcService.java +++ b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/calc/MultiLineGNSSCalcService.java @@ -1,5 +1,7 @@ package com.imdroid.sideslope.calc; +import com.imdroid.secapi.dto.FwdRecord; +import com.imdroid.secapi.dto.FwdRecordMapper; import com.imdroid.sideslope.message.BaseMessage; import com.imdroid.sideslope.message.D341LocationMessage; import com.imdroid.sideslope.message.D342LocationMessage; @@ -17,11 +19,16 @@ import java.util.concurrent.ConcurrentHashMap; public class MultiLineGNSSCalcService { private static final Logger logger = LoggerFactory.getLogger(SingleLineGNSSCalcService.class); private static final Map deviceMap = new ConcurrentHashMap<>(); + private static final Map fwdRecordMap = new ConcurrentHashMap<>(); + @Autowired SingleLineGNSSCalcService calcService; @Autowired private GNSSDeviceLocationRecordService dataPersistService; + @Autowired + private FwdRecordMapper fwdRecordMapper; + public void calc(D342LocationMessage d342Message){ // 如果时间跨度大于1分钟,或者不含d341,则计算平滑值 String deviceId = d342Message.getId(); @@ -30,12 +37,25 @@ public class MultiLineGNSSCalcService { int d341Count = d342Message.getMessageList().size(); if(msgTime!=null) logger.info("proc D342: "+msgTime+" D341 num: "+d341Count); + // 如果序号为0,则创建一条转发记录表 + if(d342Message.getSeq() == 0){ + createFwdReord(d342Message); + } + if(lastDate != null){ if(d341Count == 0){ // 计算上轮结果 calcService.calSingleDone(deviceId, d342Message.getTenantId(),lastDate); // 重算最近的 dataPersistService.updateRb562(deviceId,lastDate); + // 记录转发表更新为upload done + FwdRecord fwdRecord = fwdRecordMap.get(deviceId); + if(fwdRecord != null){ + fwdRecord.setEndtime(lastDate); + fwdRecord.setState(FwdRecord.STATE_UPLOAD_DONE); + fwdRecordMapper.insert(fwdRecord); + fwdRecordMap.remove(deviceId); + } } else if(msgTime!=null && msgTime.isAfter(lastDate.plusMinutes(1))){ // 计算上轮结果 @@ -51,4 +71,16 @@ public class MultiLineGNSSCalcService { } } + + void createFwdReord(D342LocationMessage d342Message){ + String deviceId = d342Message.getId(); + // 查找这个设备是否有项目号 + FwdRecord fwdRecord = new FwdRecord(); + fwdRecord.setDeviceid(deviceId); + fwdRecord.setTenantid(d342Message.getTenantId()); + fwdRecord.setProject_id(d342Message.getProjectId()); + fwdRecord.setState(FwdRecord.STATE_UPLOADING); + fwdRecord.setStarttime(d342Message.getOriginalTime()); + fwdRecordMap.put(deviceId, fwdRecord); + } } diff --git a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/executor/D342LocationMessageExecutor.java b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/executor/D342LocationMessageExecutor.java index a3942d4a..a0b983ef 100644 --- a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/executor/D342LocationMessageExecutor.java +++ b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/executor/D342LocationMessageExecutor.java @@ -29,6 +29,7 @@ public class D342LocationMessageExecutor implements Executor { gnssCalcService.calc(message); diff --git a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/fwd/ForwardGnssTask.java b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/fwd/ForwardGnssTask.java index 5166daa1..a6957769 100644 --- a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/fwd/ForwardGnssTask.java +++ b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/fwd/ForwardGnssTask.java @@ -1,10 +1,7 @@ package com.imdroid.sideslope.fwd; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.imdroid.secapi.dto.GnssCalcData; -import com.imdroid.secapi.dto.GnssCalcDataMapper; -import com.imdroid.secapi.dto.GnssDevice; -import com.imdroid.secapi.dto.GnssDeviceMapper; +import com.imdroid.secapi.dto.*; import com.imdroid.sideslope.util.GsonUtil; import com.imdroid.sideslope.util.NumberUtils; import org.slf4j.Logger; @@ -40,6 +37,11 @@ public class ForwardGnssTask { private GnssCalcDataMapper gnssDataMapper; @Autowired private XFZTcpClient xfzTcpClient; + + @Autowired + private FwdRecordMapper fwdRecordsMapper; + final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + /** * 每半小时转发GNSS解算结果 */ @@ -50,11 +52,28 @@ public class ForwardGnssTask { forwardGnssToXFZ(1); } - @Scheduled(cron = "0 10 * * * ?") // 每小时的10分钟执行一次 + //@Scheduled(cron = "0 40 * * * ?") // 每小时的40分钟执行一次 + @Scheduled(cron = "0 0/20 * * * ?") // 每20分钟执行一次 private void forwardHistoryGnss() { // 1.从转发记录表里检索待补传记录时间表,含设备Id,时间段 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("tenantid",1); + queryWrapper.eq("state",FwdRecord.STATE_UPLOAD_DONE); + List fwdRecordsList = fwdRecordsMapper.selectList(queryWrapper); // 2.检索这个这个时间段的解算结果,如果有数据则单个终端转发,标志记录为已补传 - //forwardGnssToXFZ(1); + for(FwdRecord fwdRecord:fwdRecordsList){ + QueryWrapper calcDataQueryWrapper = new QueryWrapper<>(); + calcDataQueryWrapper.eq("deviceid", fwdRecord.getDeviceid()); + calcDataQueryWrapper.ge("createtime", fwdRecord.getStarttime()); + calcDataQueryWrapper.le("createtime", fwdRecord.getEndtime()); + calcDataQueryWrapper.orderByAsc("createtime"); + List calcDataList = gnssDataMapper.selectList(calcDataQueryWrapper); + // 推送记录 + BatchToXFZ(fwdRecord.getProject_id(),calcDataList); + // 记录推送结果 + fwdRecord.setState(FwdRecord.STATE_FWD_DONE); + fwdRecordsMapper.updateById(fwdRecord); + } } private void forwardGnssToXFZ(int tenantId) { @@ -126,4 +145,43 @@ public class ForwardGnssTask { logger.info(json); } + void BatchToXFZ(String projectId, List records){ + if(records.size() == 0) return; + + LocalDateTime lastTime = records.get(0).getCreatetime(); + + for(GnssCalcData calcData:records){ + if(calcData.getEnabled() && + calcData.getCreatetime().isAfter(lastTime.plusMinutes(30))){ + // 推送 + SendOneToXFZ(projectId, calcData,lastTime.format(dateFormatter)); + lastTime = calcData.getCreatetime(); + } + } + + } + + void SendOneToXFZ(String projectId, GnssCalcData calcData, String sendTime){ + XFZTcpMessage xfzTcpMessage = new XFZTcpMessage(); + xfzTcpMessage.setProjectID(projectId); + xfzTcpMessage.setWorkPointID(projectId); + + List dataList = new ArrayList<>(); + xfzTcpMessage.setData(dataList); + + XFZTcpMessage.Data data = new XFZTcpMessage.Data(); + dataList.add(data); + data.setDataTime(sendTime); + data.setDevNum("1"); + data.setDevtype("GNSS"); + // 单位由mm转化为m + data.setX(NumberUtils.scale(calcData.getRb562e() * 0.001, 5)); + data.setY(NumberUtils.scale(calcData.getRb562n() * 0.001, 5)); + data.setZ(NumberUtils.scale(calcData.getRb562d() * 0.001, 5)); + String json = GsonUtil.toJson(xfzTcpMessage); + xfzTcpClient.writeAndFlush(json); + logger.info("project " + projectId + ": push one calculation result to XFZ"); + logger.info(json); + } + } diff --git a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/message/D342LocationMessage.java b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/message/D342LocationMessage.java index b8b71bed..99ad7c04 100644 --- a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/message/D342LocationMessage.java +++ b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/message/D342LocationMessage.java @@ -17,6 +17,7 @@ import java.util.List; public class D342LocationMessage extends BaseMessage { LocalDateTime originalTime; //补传前记录的时间 List messageList = new ArrayList<>(); + String projectId; @Override public void decodeBody(ByteBuf src) { // d3 51 length(2048+6) device_id(4bytes) seq(2bytes) data diff --git a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/sal/DbDeviceServiceImpl.java b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/sal/DbDeviceServiceImpl.java index c741159d..45c43248 100644 --- a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/sal/DbDeviceServiceImpl.java +++ b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/sal/DbDeviceServiceImpl.java @@ -43,6 +43,7 @@ public class DbDeviceServiceImpl implements DeviceService { device.setDeviceType(gnssDevice.getDevicetype()); device.setParentId(gnssDevice.getParentid()); device.setName(gnssDevice.getName()); + device.setProjectId(gnssDevice.getProject_id()); return device; } @@ -58,6 +59,7 @@ public class DbDeviceServiceImpl implements DeviceService { device.setDeviceType(gnssDevice.getDevicetype()); device.setParentId(gnssDevice.getParentid()); device.setName(gnssDevice.getName()); + device.setProjectId(gnssDevice.getProject_id()); deviceList.add(device); } return deviceList; 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 2cda4295..5b30424a 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 @@ -27,6 +27,7 @@ public class Device { private String deviceId; private String parentId; + private String projectId; private Integer deviceType; diff --git a/sec-beidou/src/main/resources/db/schema.sql b/sec-beidou/src/main/resources/db/schema.sql index ff7ccf39..ec7a034b 100644 --- a/sec-beidou/src/main/resources/db/schema.sql +++ b/sec-beidou/src/main/resources/db/schema.sql @@ -234,3 +234,18 @@ CREATE TABLE IF NOT EXISTS `warningcfg` ( `value` int NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +/*** + 推送记录表:根据补传指令填写补传数据的设备id、数据时间段 + state状态值:1准备传送,2传送中,3传送结束待推送,0已推送 + */ +CREATE TABLE IF NOT EXISTS `fwdrecords` ( + `id` bigint AUTO_INCREMENT, + `tenantid` int NOT NULL, + `deviceid` varchar(20) NOT NULL, + `project_id` varchar(64) DEFAULT NULL COMMENT '项目id', + `starttime` datetime DEFAULT NULL, + `endtime` datetime DEFAULT NULL, + `state` smallint DEFAULT 0, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;