1、增加推送到金马平台功能

This commit is contained in:
weidong 2024-01-07 19:41:48 +08:00
parent 624a3ce687
commit c67b4b4e22
8 changed files with 313 additions and 128 deletions

View File

@ -119,11 +119,10 @@
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 矩阵工具 -->
<dependency>
<groupId>org.ejml</groupId>
<artifactId>ejml-all</artifactId>
<version>0.41</version>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
</dependencies>

View File

@ -0,0 +1,46 @@
package com.imdroid.beidou_fwd.entity;
import lombok.Data;
/**
* @author Layton
* @date 2023/2/19 9:16
*/
@Data
public class KingMaData {
String dataTime;
String deviceId;
Integer flag;
String projectId;
Phys phys;
@lombok.Data
public static class Data {
private String sign;
private String unit;
private Double value;
public Data(String sign, String unit, Double value) {
this.sign = sign;
this.unit = unit;
this.value = value;
}
}
@lombok.Data
public static class Phys{
Data data1;
Data data2;
Data data3;
public Phys(Double e, Double n, Double d){
data1 = new Data("data1","mm",e);
data2 = new Data("data2","mm",n);
data3 = new Data("data3","mm",d);
}
}
}

View File

@ -1,4 +0,0 @@
package com.imdroid.beidou_fwd.service;
public class HTTPClient {
}

View File

@ -1,19 +1,35 @@
package com.imdroid.beidou_fwd.task;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.imdroid.secapi.dto.GnssGroupFwd;
import com.imdroid.secapi.dto.GnssGroupFwdMapper;
import com.imdroid.secapi.dto.*;
import org.springframework.beans.factory.annotation.Autowired;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Forwarder {
String name;
String description;
@Autowired
private GnssDeviceMapper deviceMapper;
@Autowired
private GnssCalcDataMapper gnssDataMapper;
@Autowired
private FwdRecordMapper fwdRecordsMapper;
@Autowired
GnssGroupFwdMapper fwdMapper;
void init(String name, String desc, GnssGroupFwdMapper fwdMapper){
void init(String name, String desc){
this.name = name;
this.description = desc;
this.fwdMapper = fwdMapper;
QueryWrapper<GnssGroupFwd> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name",name);
GnssGroupFwd gnssGroupFwd = fwdMapper.selectOne(queryWrapper);
@ -30,6 +46,110 @@ public class Forwarder {
}
}
void forwardCurrentGnss(String fwdGroupId) {
LocalDateTime nowTime = LocalDateTime.now();
ConcurrentHashMap<String, List<GnssCalcData>> projects = new ConcurrentHashMap<>();
// 转发数据
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String sendAfterTime = nowTime.minusMinutes(30).format(formatter);
QueryWrapper<GnssDevice> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("fwd_group_id", fwdGroupId);
List<GnssDevice> gnssDeviceList = deviceMapper.selectList(queryWrapper);
List<GnssCalcData> recordsToSend;
for(GnssDevice device:gnssDeviceList){
String projectId = device.getProject_id();
if(projectId == null) continue;
recordsToSend = projects.get(projectId);
if(recordsToSend == null){
recordsToSend = new ArrayList<>();
projects.put(projectId,recordsToSend);
}
QueryWrapper<GnssCalcData> gnssQueryWrapper = new QueryWrapper<>();
gnssQueryWrapper.eq("deviceid",device.getDeviceid());
gnssQueryWrapper.ge("createtime",sendAfterTime);
gnssQueryWrapper.orderByDesc("createtime");
List<GnssCalcData> records = gnssDataMapper.selectList(gnssQueryWrapper);
for(GnssCalcData record:records) {
if (record.getEnabled()) {
recordsToSend.add(record);
break;
}
}
}
// 按项目打包推送
int totalSendNum = 0;
for (Map.Entry<String, List<GnssCalcData>> entry: projects.entrySet()){
int sendNum = send(entry.getKey(), entry.getValue());
if(sendNum > 0) {
totalSendNum += sendNum;
// 记录推送
FwdRecord fwdRecord = new FwdRecord();
fwdRecord.setProject_id(entry.getKey());
fwdRecord.setTenantid(1);
fwdRecord.setDevicenum((short) entry.getValue().size());
fwdRecord.setStarttime(nowTime);
fwdRecord.setState(FwdRecord.STATE_FWD_DONE);
fwdRecord.setFwd_group_id(fwdGroupId);
fwdRecordsMapper.insert(fwdRecord);
}
}
// 更新推送信息
if(totalSendNum>0) updateFwd(totalSendNum, true);
}
void forwardHistoryGnss(String fwdGroupId) {
// 1.从转发记录表里检索待补传记录时间表含设备Id时间段
QueryWrapper<FwdRecord> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("fwd_group_id",fwdGroupId);
queryWrapper.eq("state",FwdRecord.STATE_UPLOAD_DONE);
List<FwdRecord> fwdRecordsList = fwdRecordsMapper.selectList(queryWrapper);
// 2.检索这个这个时间段的解算结果如果有数据则单个终端转发标志记录为已补传
for(FwdRecord fwdRecord:fwdRecordsList){
QueryWrapper<GnssCalcData> calcDataQueryWrapper = new QueryWrapper<>();
calcDataQueryWrapper.eq("deviceid", fwdRecord.getDeviceid());
calcDataQueryWrapper.ge("createtime", fwdRecord.getStarttime());
calcDataQueryWrapper.le("createtime", fwdRecord.getEndtime());
calcDataQueryWrapper.orderByAsc("createtime");
List<GnssCalcData> calcDataList = gnssDataMapper.selectList(calcDataQueryWrapper);
// 推送记录
sendBatch(fwdRecord.getProject_id(),calcDataList);
// 记录推送结果
fwdRecord.setState(FwdRecord.STATE_FWD_DONE);
fwdRecordsMapper.updateById(fwdRecord);
}
}
void sendBatch(String projectId, List<GnssCalcData> records){
if(records.size() == 0) return;
LocalDateTime lastTime = records.get(0).getCreatetime();
for(GnssCalcData calcData:records){
if(calcData.getEnabled() &&
calcData.getCreatetime().isAfter(lastTime.plusMinutes(28))){
// 推送
lastTime = calcData.getCreatetime();
}
else{
calcData.setEnabled(false);//借用来表示不推送不会保存到数据库
}
}
send(projectId, records);
}
int send(String projectId, List<GnssCalcData> records) {
return 0;
}
void updateFwd(int fwd_num, boolean isFwdOK){
QueryWrapper<GnssGroupFwd> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name",name);

View File

@ -1,6 +1,5 @@
package com.imdroid.beidou_fwd.task;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.imdroid.beidou_fwd.entity.XFZData;
import com.imdroid.beidou_fwd.service.TCPClient;
import com.imdroid.common.util.GsonUtil;
@ -16,12 +15,9 @@ import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Component
@Configuration
@ -29,30 +25,20 @@ import java.util.concurrent.ConcurrentHashMap;
public class GXXfzForwarder extends Forwarder{
private final Logger logger = LoggerFactory.getLogger(GXXfzForwarder.class);
static final String forwarderName = "广西新发展";
static final String FORWARDER_NAME = "广西新发展";
@Value("${xfz.server.host}")
private String host;
@Value("${xfz.server.port}")
private int port;
@Autowired
private GnssDeviceMapper deviceMapper;
@Autowired
private GnssCalcDataMapper gnssDataMapper;
private TCPClient xfzTcpClient;
@Autowired
private FwdRecordMapper fwdRecordsMapper;
final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@Autowired
private GnssGroupFwdMapper fwdMapper;
@PostConstruct
void registerMe(){
init(forwarderName, "TCP "+host+":"+port, fwdMapper);
init(FORWARDER_NAME, "TCP "+host+":"+port);
}
/**
* 每半小时转发GNSS解算结果
@ -66,91 +52,22 @@ public class GXXfzForwarder extends Forwarder{
xfzTcpClient.init(host, port);
xfzTcpClient.start();
}
forwardGnssToXFZ(forwarderName);
forwardCurrentGnss(FORWARDER_NAME);
}
@Scheduled(cron = "0 40 * * * ?") // 每小时的40分钟执行一次
//@Scheduled(cron = "0 0/20 * * * ?") // 每20分钟执行一次
private void forwardHistoryGnss() {
// 1.从转发记录表里检索待补传记录时间表含设备Id时间段
QueryWrapper<FwdRecord> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("fwd_group_id",forwarderName);
queryWrapper.eq("state",FwdRecord.STATE_UPLOAD_DONE);
List<FwdRecord> fwdRecordsList = fwdRecordsMapper.selectList(queryWrapper);
// 2.检索这个这个时间段的解算结果如果有数据则单个终端转发标志记录为已补传
for(FwdRecord fwdRecord:fwdRecordsList){
QueryWrapper<GnssCalcData> calcDataQueryWrapper = new QueryWrapper<>();
calcDataQueryWrapper.eq("deviceid", fwdRecord.getDeviceid());
calcDataQueryWrapper.ge("createtime", fwdRecord.getStarttime());
calcDataQueryWrapper.le("createtime", fwdRecord.getEndtime());
calcDataQueryWrapper.orderByAsc("createtime");
List<GnssCalcData> calcDataList = gnssDataMapper.selectList(calcDataQueryWrapper);
// 推送记录
BatchToXFZ(fwdRecord.getProject_id(),calcDataList);
// 记录推送结果
fwdRecord.setState(FwdRecord.STATE_FWD_DONE);
fwdRecordsMapper.updateById(fwdRecord);
if(xfzTcpClient == null){
xfzTcpClient = new TCPClient();
xfzTcpClient.init(host, port);
xfzTcpClient.start();
}
forwardHistoryGnss(FORWARDER_NAME);
}
private void forwardGnssToXFZ(String fwdGroupId) {
LocalDateTime nowTime = LocalDateTime.now();
ConcurrentHashMap<String, List<GnssCalcData>> projects = new ConcurrentHashMap<>();
// 转发新发展数据
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String sendAfterTime = nowTime.minusMinutes(30).format(formatter);
QueryWrapper<GnssDevice> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("fwd_group_id", fwdGroupId);
List<GnssDevice> gnssDeviceList = deviceMapper.selectList(queryWrapper);
List<GnssCalcData> recordsToSend;
for(GnssDevice device:gnssDeviceList){
String projectId = device.getProject_id();
if(projectId == null) continue;
recordsToSend = projects.get(projectId);
if(recordsToSend == null){
recordsToSend = new ArrayList<>();
projects.put(projectId,recordsToSend);
}
QueryWrapper<GnssCalcData> gnssQueryWrapper = new QueryWrapper<>();
gnssQueryWrapper.eq("deviceid",device.getDeviceid());
gnssQueryWrapper.ge("createtime",sendAfterTime);
gnssQueryWrapper.orderByDesc("createtime");
List<GnssCalcData> records = gnssDataMapper.selectList(gnssQueryWrapper);
for(GnssCalcData record:records) {
if (record.getEnabled()) {
recordsToSend.add(record);
break;
}
}
}
// 按项目打包推送
int totalSendNum = 0;
for (Map.Entry<String, List<GnssCalcData>> entry: projects.entrySet()){
int sendNum = SendToXFZ(entry.getKey(), entry.getValue());
if(sendNum > 0) {
totalSendNum += sendNum;
// 记录推送
FwdRecord fwdRecord = new FwdRecord();
fwdRecord.setProject_id(entry.getKey());
fwdRecord.setTenantid(1);
fwdRecord.setDevicenum((short) entry.getValue().size());
fwdRecord.setStarttime(nowTime);
fwdRecord.setState(FwdRecord.STATE_FWD_DONE);
fwdRecordsMapper.insert(fwdRecord);
}
}
// 更新推送信息
if(totalSendNum>0) updateFwd(totalSendNum, true);
}
int SendToXFZ(String projectId, List<GnssCalcData> records){
@Override
int send(String projectId, List<GnssCalcData> records){
int sendNum = 0;
if(records.size() == 0) return 0;
@ -181,24 +98,4 @@ public class GXXfzForwarder extends Forwarder{
return sendNum;
}
void BatchToXFZ(String projectId, List<GnssCalcData> records){
if(records.size() == 0) return;
LocalDateTime lastTime = records.get(0).getCreatetime();
for(GnssCalcData calcData:records){
if(calcData.getEnabled() &&
calcData.getCreatetime().isAfter(lastTime.plusMinutes(28))){
// 推送
lastTime = calcData.getCreatetime();
}
else{
calcData.setEnabled(false);//借用来表示不推送不会保存到数据库
}
}
SendToXFZ(projectId, records);
}
}

View File

@ -0,0 +1,122 @@
package com.imdroid.beidou_fwd.task;
import com.alibaba.fastjson.JSONObject;
import com.imdroid.beidou_fwd.entity.KingMaData;
import com.imdroid.common.util.GsonUtil;
import com.imdroid.common.util.HttpUtils;
import com.imdroid.secapi.dto.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
@Configuration
@EnableScheduling
public class KingMaForwarder extends Forwarder{
private final Logger logger = LoggerFactory.getLogger(KingMaForwarder.class);
static final String FORWARDER_NAME = "KingMa";
@Value("${kingma.server.login_user}")
private String login_user;
@Value("${kingma.server.login_pwd}")
private String login_pwd;
@Value("${kingma.server.login_host}")
private String login_host;
@Value("${kingma.server.data_host}")
private String data_host;
Map<String, String> header;
LocalDateTime lastTokenTime = LocalDateTime.now();
@PostConstruct
void registerMe(){
init(FORWARDER_NAME, data_host);
}
/**
* 每半小时转发GNSS解算结果
*/
@Scheduled(cron = "0 0/30 * * * ?") // 每30分钟执行一次
private void forwardGnss() {
forwardCurrentGnss(FORWARDER_NAME);
}
@Scheduled(cron = "0 40 * * * ?") // 每小时的40分钟执行一次
//@Scheduled(cron = "0 0/20 * * * ?") // 每20分钟执行一次
private void forwardHistoryGnss() {
forwardHistoryGnss(FORWARDER_NAME);
}
boolean updateToken(){
String jsonLogin = "{\"username\":\""+login_user+"\"," +
"\"password\":\""+login_pwd+"\"}";
String result = HttpUtils.postJson(login_host, jsonLogin);
if(result == null) return false;
String token = null;
try {
JSONObject obj = (JSONObject) JSONObject.parse(result);
obj = obj.getJSONObject("data");
token = obj.getString("token");
}
catch (Exception e){
}
if(token == null) return false;
if(header == null){
header = new HashMap<>();
}
header.put("Authorization", token);
return true;
}
@Override
int send(String projectId, List<GnssCalcData> records){
int sendNum = 0;
if(records.size() == 0) return 0;
// 检查token是否过期
LocalDateTime nowTime = LocalDateTime.now();
if(header == null || nowTime.isAfter(lastTokenTime.plusMinutes(59))){
if(!updateToken()){
logger.info("update token failed!");
return 0;
}
lastTokenTime = nowTime;
}
List<KingMaData> dataList = new ArrayList<>(records.size());
for(GnssCalcData locationRecord: records) {
if(!locationRecord.getEnabled()) continue;
KingMaData data = new KingMaData();
data.setDataTime(locationRecord.getCreatetime().toString());
data.setProjectId(projectId);
data.setDeviceId(locationRecord.getDeviceid());
data.setFlag(1);
data.setPhys(new KingMaData.Phys(locationRecord.getRb562e(),locationRecord.getRb562n(),locationRecord.getRb562d()));
dataList.add(data);
sendNum++;
}
String json = GsonUtil.toJson(dataList);
String result = HttpUtils.postJson(data_host,header,json);
logger.info("project " + projectId + ": push calculation result to Kingma");
logger.info(json);
logger.info("result: "+result);
return sendNum;
}
}

View File

@ -24,4 +24,9 @@ mybatis-plus.configuration.map-underscore-to-camel-case=false
#xfz.server.host = 171.106.48.63
#xfz.server.port = 52000
xfz.server.host = 115.236.153.174
xfz.server.port = 31035
xfz.server.port = 31035
kingma.server.login_user = ceshi
kingma.server.login_pwd = ceshi!123
kingma.server.login_host = https://www.everiaction.com/IOT-ADAPTER-CUSTOM/auth/anon/login
kingma.server.data_host = https://www.everiaction.com/IOT-DATA-GATHER/receive/data/formula

View File

@ -36,9 +36,9 @@
url: '/fwd/records',
toolbar: '#toolbarTable',
cols: [[
{field: 'deviceid', title: '设备号', sort: true},
{field: 'project_id', title: '项目号'},
{field: 'project_id', title: '项目号', sort: true},
{field: 'devicenum', title: '推送设备数'},
{field: 'deviceid', title: '设备号'},
{field: 'starttime', title: '起始时间', templet: "<div>{{layui.util.toDateString(d.starttime, 'yyyy-MM-dd HH:mm:ss')}}</div>"},
{field: 'endtime', title: '结束时间', templet: "<div>{{layui.util.toDateString(d.endtime, 'yyyy-MM-dd HH:mm:ss')}}</div>"},
{field: 'fwd_group_id', title: '推送组'},