1、临时在RTCM微服务增加推送广西新发展的功能
This commit is contained in:
parent
1774ea61f6
commit
f72dda0ac8
@ -31,7 +31,7 @@ public class GnssDevice {
|
||||
private String parentid;
|
||||
private Integer devicetype;
|
||||
private String tenantname;
|
||||
private Integer project_id = 0;
|
||||
private String project_id;
|
||||
private Integer group_id = 1; //组参数,缓存自动下发
|
||||
private Integer calc_group_id = 1;
|
||||
private Integer fwd_group_id = 0;
|
||||
|
||||
@ -0,0 +1,114 @@
|
||||
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.sideslope.util.GsonUtil;
|
||||
import com.imdroid.sideslope.util.NumberUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author Layton
|
||||
* @date 2020/12/23 17:14
|
||||
*/
|
||||
@Component
|
||||
@Configuration
|
||||
@EnableScheduling
|
||||
public class ForwardGnssTask {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(ForwardGnssTask.class);
|
||||
|
||||
@Autowired
|
||||
private GnssDeviceMapper deviceMapper;
|
||||
|
||||
@Autowired
|
||||
private GnssCalcDataMapper gnssDataMapper;
|
||||
@Autowired
|
||||
private XFZTcpClient xfzTcpClient;
|
||||
/**
|
||||
* 每半小时转发GNSS解算结果
|
||||
*/
|
||||
@Scheduled(cron = "0 0/30 * * * ?") // 每30分钟执行一次
|
||||
private void forwardGnss() {
|
||||
forwardGnssToXFZ(1);
|
||||
}
|
||||
|
||||
private void forwardGnssToXFZ(int tenantId) {
|
||||
LocalDateTime nowTime = LocalDateTime.now();
|
||||
ConcurrentHashMap<String, List<GnssCalcData>> projects = new ConcurrentHashMap<>();
|
||||
|
||||
// 转发新发展数据
|
||||
QueryWrapper<GnssDevice> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("tenantid", tenantId);
|
||||
List<GnssDevice> gnssDeviceList = deviceMapper.selectList(queryWrapper);
|
||||
List<GnssCalcData> records;
|
||||
for(GnssDevice device:gnssDeviceList){
|
||||
String projectId = device.getProject_id();
|
||||
if(projectId == null) continue;
|
||||
|
||||
records = projects.get(projectId);
|
||||
if(records == null){
|
||||
records = new ArrayList<>();
|
||||
projects.put(projectId,records);
|
||||
}
|
||||
QueryWrapper<GnssCalcData> gnssQueryWrapper = new QueryWrapper<>();
|
||||
gnssQueryWrapper.eq("deviceid",device.getDeviceid());
|
||||
gnssQueryWrapper.orderByDesc("createtime");
|
||||
GnssCalcData record = gnssDataMapper.selectOne(gnssQueryWrapper);
|
||||
if(record != null && record.getEnabled()){
|
||||
if(nowTime.isBefore(record.getCreatetime().plusMinutes(40))) {
|
||||
records.add(record);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 按项目打包推送
|
||||
String sendTime = nowTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
for (Map.Entry<String, List<GnssCalcData>> entry: projects.entrySet()){
|
||||
SendToXFZ(entry.getKey(), entry.getValue(), sendTime);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SendToXFZ(String projectId, List<GnssCalcData> records, String sendTime){
|
||||
if(records.size() == 0) return;
|
||||
|
||||
XFZTcpMessage xfzTcpMessage = new XFZTcpMessage();
|
||||
xfzTcpMessage.setProjectID(projectId);
|
||||
xfzTcpMessage.setWorkPointID(projectId);
|
||||
|
||||
List<XFZTcpMessage.Data> dataList = new ArrayList<>(records.size());
|
||||
xfzTcpMessage.setData(dataList);
|
||||
|
||||
for(GnssCalcData locationRecord: records) {
|
||||
XFZTcpMessage.Data data = new XFZTcpMessage.Data();
|
||||
dataList.add(data);
|
||||
data.setDataTime(sendTime);
|
||||
data.setDevNum(locationRecord.getDeviceid());
|
||||
data.setDevtype("GNSS");
|
||||
// 单位由mm转化为m
|
||||
data.setX(NumberUtils.scale(locationRecord.getRb562e() * 0.001, 5));
|
||||
data.setY(NumberUtils.scale(locationRecord.getRb562n() * 0.001, 5));
|
||||
data.setZ(NumberUtils.scale(locationRecord.getRb562d() * 0.001, 5));
|
||||
}
|
||||
String json = GsonUtil.toJson(xfzTcpMessage);
|
||||
xfzTcpClient.writeAndFlush(json);
|
||||
logger.info("project " + projectId + ": push calculation result to XFZ");
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,116 @@
|
||||
package com.imdroid.sideslope.fwd;
|
||||
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.*;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author Layton
|
||||
* @date 2023/2/18 20:35
|
||||
*/
|
||||
@Component
|
||||
public class XFZTcpClient implements ApplicationRunner {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Value("${xfz.server.host}")
|
||||
private String host;
|
||||
|
||||
@Value("${xfz.server.port}")
|
||||
private int port;
|
||||
|
||||
@Value("${xfz.server.data.send}")
|
||||
private boolean send;
|
||||
|
||||
private Bootstrap bootstrap;
|
||||
private EventLoopGroup group;
|
||||
private Channel channel;
|
||||
|
||||
public void start() {
|
||||
new Thread(this::connect, "xfz-tcp-client").start();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
//客户端需要一个事件循环组
|
||||
group = new NioEventLoopGroup();
|
||||
//创建客户端启动对象
|
||||
// bootstrap 可重用, 只需在NettyClient实例化的时候初始化即可.
|
||||
bootstrap = new Bootstrap();
|
||||
bootstrap.group(group)
|
||||
.channel(NioSocketChannel.class)
|
||||
.handler(new ChannelInitializer<SocketChannel>() {
|
||||
@Override
|
||||
protected void initChannel(SocketChannel ch) throws Exception {
|
||||
//加入处理器
|
||||
ch.pipeline().addLast(new XFZTcpMessageHandler(XFZTcpClient.this));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void connect() {
|
||||
logger.info("netty client starting");
|
||||
//启动客户端去连接服务器端
|
||||
try {
|
||||
ChannelFuture cf = bootstrap.connect(host, port);
|
||||
cf.addListener(new ChannelFutureListener() {
|
||||
@Override
|
||||
public void operationComplete(ChannelFuture future) throws Exception {
|
||||
if (!future.isSuccess()) {
|
||||
//重连交给后端线程执行
|
||||
future.channel().eventLoop().schedule(() -> {
|
||||
logger.info("xfz tcp client reconnect");
|
||||
try {
|
||||
connect();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}, 3000, TimeUnit.MILLISECONDS);
|
||||
} else {
|
||||
logger.info("xfz tcp client start success!");
|
||||
}
|
||||
}
|
||||
});
|
||||
//对通道关闭进行监听
|
||||
this.channel = cf.channel();
|
||||
this.channel.closeFuture().sync();
|
||||
} catch (Exception e) {
|
||||
logger.error("xfz netty client error:", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void writeAndFlush(String json) {
|
||||
if (!send) {
|
||||
return;
|
||||
}
|
||||
String str = "#" + json + "!";
|
||||
ByteBuf buf = Unpooled.buffer();
|
||||
buf.writeBytes(str.getBytes(StandardCharsets.UTF_8));
|
||||
channel.writeAndFlush(buf).addListener(future -> {
|
||||
if (future.isSuccess()) {
|
||||
logger.info("send {} to xfz server succeed.", str);
|
||||
} else {
|
||||
logger.info("send {} to xfz server failed.", str);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
init();
|
||||
start();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,158 @@
|
||||
package com.imdroid.sideslope.fwd;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Layton
|
||||
* @date 2023/2/19 9:16
|
||||
*/
|
||||
public class XFZTcpMessage {
|
||||
|
||||
private String ProjectID;
|
||||
|
||||
private String WorkPointID;
|
||||
|
||||
private String WorkPointLng = "0";
|
||||
|
||||
private String WorkPointLat = "0";
|
||||
|
||||
private List<Data> data;
|
||||
|
||||
|
||||
public static class Data {
|
||||
private String DevNum;
|
||||
|
||||
private String Devtype;
|
||||
|
||||
private String DevLng = "0";
|
||||
|
||||
private String DevLat = "0";
|
||||
|
||||
private double x;
|
||||
|
||||
private double y;
|
||||
|
||||
private double z;
|
||||
|
||||
private String DataTime;
|
||||
|
||||
public Data() {
|
||||
|
||||
}
|
||||
|
||||
public Data(String devNum, String devtype, String devLng, String devLat, double x, double y, double z, String dataTime) {
|
||||
DevNum = devNum;
|
||||
Devtype = devtype;
|
||||
DevLng = devLng;
|
||||
DevLat = devLat;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
DataTime = dataTime;
|
||||
}
|
||||
|
||||
public String getDevNum() {
|
||||
return DevNum;
|
||||
}
|
||||
|
||||
public void setDevNum(String devNum) {
|
||||
DevNum = devNum;
|
||||
}
|
||||
|
||||
public String getDevtype() {
|
||||
return Devtype;
|
||||
}
|
||||
|
||||
public void setDevtype(String devtype) {
|
||||
Devtype = devtype;
|
||||
}
|
||||
|
||||
public String getDevLng() {
|
||||
return DevLng;
|
||||
}
|
||||
|
||||
public void setDevLng(String devLng) {
|
||||
DevLng = devLng;
|
||||
}
|
||||
|
||||
public String getDevLat() {
|
||||
return DevLat;
|
||||
}
|
||||
|
||||
public void setDevLat(String devLat) {
|
||||
DevLat = devLat;
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(double x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(double y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public double getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public void setZ(double z) {
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public String getDataTime() {
|
||||
return DataTime;
|
||||
}
|
||||
|
||||
public void setDataTime(String dataTime) {
|
||||
DataTime = dataTime;
|
||||
}
|
||||
}
|
||||
|
||||
public String getProjectID() {
|
||||
return ProjectID;
|
||||
}
|
||||
|
||||
public void setProjectID(String projectID) {
|
||||
ProjectID = projectID;
|
||||
}
|
||||
|
||||
public String getWorkPointID() {
|
||||
return WorkPointID;
|
||||
}
|
||||
|
||||
public void setWorkPointID(String workPointID) {
|
||||
WorkPointID = workPointID;
|
||||
}
|
||||
|
||||
public String getWorkPointLng() {
|
||||
return WorkPointLng;
|
||||
}
|
||||
|
||||
public void setWorkPointLng(String workPointLng) {
|
||||
WorkPointLng = workPointLng;
|
||||
}
|
||||
|
||||
public String getWorkPointLat() {
|
||||
return WorkPointLat;
|
||||
}
|
||||
|
||||
public void setWorkPointLat(String workPointLat) {
|
||||
WorkPointLat = workPointLat;
|
||||
}
|
||||
|
||||
public List<Data> getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(List<Data> data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
package com.imdroid.sideslope.fwd;
|
||||
|
||||
import com.imdroid.sideslope.util.DataTypeUtil;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Layton
|
||||
* @date 2023/2/18 20:36
|
||||
*/
|
||||
public class XFZTcpMessageHandler extends SimpleChannelInboundHandler<ByteBuf> {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private final XFZTcpClient tcpClient;
|
||||
|
||||
public XFZTcpMessageHandler(XFZTcpClient tcpClient) {
|
||||
this.tcpClient = tcpClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf buf) throws Exception {
|
||||
if (logger.isDebugEnabled()) {
|
||||
byte[] data = new byte[buf.readableBytes()];
|
||||
buf.getBytes(0, data);
|
||||
logger.debug("receive gxxfz server message:" + DataTypeUtil.getHexString(data));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||
logger.info("xfz tcp channel active");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
||||
logger.info("xfz tcp channel inactive");
|
||||
tcpClient.connect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
logger.error("XFZTcpMessageHandler error: {}", cause.toString());
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
}
|
||||
@ -28,4 +28,8 @@ app.format.date = yyyy-MM-dd
|
||||
app.format.time = HH:mm:ss
|
||||
app.format.datetime = yyyy-MM-dd HH:mm:ss
|
||||
|
||||
mybatis-plus.configuration.map-underscore-to-camel-case=false
|
||||
mybatis-plus.configuration.map-underscore-to-camel-case=false
|
||||
|
||||
xfz.server.host = 171.106.48.63
|
||||
xfz.server.port = 52000
|
||||
xfz.server.data.send = false
|
||||
@ -4,11 +4,7 @@ import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
@Controller
|
||||
public class LayuiController extends BasicController{
|
||||
@RequestMapping("/login")
|
||||
public String login(){
|
||||
return "/login";
|
||||
}
|
||||
public class IndexController extends BasicController{
|
||||
|
||||
@RequestMapping("/")
|
||||
public String index0() {
|
||||
@ -25,9 +21,4 @@ public class LayuiController extends BasicController{
|
||||
return "/page/device_overview";
|
||||
}
|
||||
|
||||
@RequestMapping("/page/gnss_data_tools")
|
||||
public String gnssDataTools() {
|
||||
return "/page/gnss_data_tools";
|
||||
}
|
||||
|
||||
}
|
||||
@ -13,6 +13,7 @@ import com.imdroid.beidou.entity.UserMapper;
|
||||
import com.imdroid.beidou.utils.BCryptPasswordEncoderUtil;
|
||||
import com.imdroid.beidou.utils.WXUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@ -25,8 +26,7 @@ import java.io.IOException;
|
||||
*
|
||||
* @author LiGang
|
||||
*/
|
||||
@RequestMapping
|
||||
@RestController
|
||||
@Controller
|
||||
public class LoginController {
|
||||
|
||||
@Autowired
|
||||
@ -41,6 +41,11 @@ public class LoginController {
|
||||
@Autowired
|
||||
private BCryptPasswordEncoderUtil bCryptPasswordEncoderUtil;
|
||||
|
||||
@RequestMapping("/login")
|
||||
public String login(){
|
||||
return "/login";
|
||||
}
|
||||
|
||||
@PostMapping(value = "/do_login")
|
||||
@ResponseBody
|
||||
public HttpResult login(UserLoginVO userLoginVO, HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
|
||||
@ -45,7 +45,7 @@ CREATE TABLE IF NOT EXISTS `gnssdevices` (
|
||||
`parentid` varchar(20) DEFAULT NULL,
|
||||
`devicetype` smallint DEFAULT 0,
|
||||
`tenantname` varchar(100) NOT NULL,
|
||||
`project_id` int NOT NULL DEFAULT 0 COMMENT '项目id',
|
||||
`project_id` varchar(64) DEFAULT NULL COMMENT '项目id',
|
||||
`group_id` int DEFAULT 1,
|
||||
`calc_group_id` int DEFAULT 1,
|
||||
`fwd_group_id` int DEFAULT 0,
|
||||
|
||||
@ -258,12 +258,6 @@
|
||||
"href": "page/gnss_data_raw",
|
||||
"icon": "fa fa-database",
|
||||
"target": "_self"
|
||||
},
|
||||
{
|
||||
"title": "测试工具",
|
||||
"href": "page/gnss_data_tools",
|
||||
"icon": "fa fa-wrench",
|
||||
"target": "_self"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@ -45,7 +45,7 @@
|
||||
<table class="layui-hide" id="currentTableId" lay-filter="currentTableFilter"></table>
|
||||
|
||||
<script type="text/html" id="currentTableBar">
|
||||
<a class="layui-btn layui-btn-normal layui-btn-xs data-count-edit" lay-event="cmd">命令行</a>
|
||||
<a class="layui-btn layui-btn-normal layui-btn-xs data-count-edit" lay-event="cmd">详细</a>
|
||||
</script>
|
||||
|
||||
</div>
|
||||
@ -84,17 +84,12 @@
|
||||
{field: 'devicetime', title: '设备时间'},
|
||||
{field: 'satelliteinview', title: '可见卫星'},
|
||||
{field: 'satelliteinuse', title: '使用卫星'},
|
||||
{field: 'd3xxbytes', title: 'D3XX字节数'},
|
||||
{field: 'b562bytes', title: 'B562字节数'},
|
||||
{field: 'state', title: '状态',templet: '#stateTrans'},
|
||||
{field: 'warning', title: '告警',templet: '#warningTrans'},
|
||||
{field: 'location', title: '位置'},
|
||||
{field: 'voltage', title: '电压'},
|
||||
{field: 'temperature', title: '温度'},
|
||||
{field: 'humidity', title: '湿度'},
|
||||
{field: 'roll', title: 'roll'},
|
||||
{field: 'pitch', title: 'pitch'},
|
||||
{field: 'yaw', title: 'yaw'},
|
||||
{field: 'rssi', title: '信号'},
|
||||
{title: '操作', toolbar: '#currentTableBar', align: "center"}
|
||||
]],
|
||||
|
||||
@ -38,9 +38,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">项目编号</label>
|
||||
<label class="layui-form-label">项目号</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="project_id" id="project_id" placeholder="请输入项目编号" value="" class="layui-input">
|
||||
<input type="text" name="project_id" id="project_id" placeholder="请输入项目编号" value="" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user