Compare commits
No commits in common. "918fe5452dd001a442e449fe2192e47273de58e5" and "3c55673177f7633d6d4b9cce1c9d0ac0c568bad9" have entirely different histories.
918fe5452d
...
3c55673177
@ -17,7 +17,7 @@ public interface RtcmClient {
|
|||||||
@GetMapping(value = "/get_device_info")
|
@GetMapping(value = "/get_device_info")
|
||||||
public HttpResp getDeviceInfo(@RequestParam(name = "deviceId") String deviceId, @RequestParam(name = "cmd") String cmd);
|
public HttpResp getDeviceInfo(@RequestParam(name = "deviceId") String deviceId, @RequestParam(name = "cmd") String cmd);
|
||||||
@PostMapping("/device_param_changed")
|
@PostMapping("/device_param_changed")
|
||||||
HttpResp deviceParamChanged(@RequestParam(name = "deviceId") String deviceId,@RequestParam(name = "oldParentId") String oldParentId, @RequestParam("oldParentId1") String oldParentId1);
|
HttpResp deviceParamChanged(@RequestParam(name = "deviceId") String deviceId,@RequestParam(name = "oldParentId") String oldParentId);
|
||||||
|
|
||||||
@PostMapping("/group_param_changed")
|
@PostMapping("/group_param_changed")
|
||||||
HttpResp groupParamChanged();
|
HttpResp groupParamChanged();
|
||||||
|
|||||||
@ -40,7 +40,6 @@ public class GnssDevice {
|
|||||||
private String fwddeviceid; //推送的设备名
|
private String fwddeviceid; //推送的设备名
|
||||||
private String name;
|
private String name;
|
||||||
private String parentid;
|
private String parentid;
|
||||||
private String parentid1;
|
|
||||||
private Integer devicetype;
|
private Integer devicetype;
|
||||||
private String tenantname;
|
private String tenantname;
|
||||||
private String project_id;
|
private String project_id;
|
||||||
@ -66,8 +65,5 @@ public class GnssDevice {
|
|||||||
|
|
||||||
// 日志记录控制
|
// 日志记录控制
|
||||||
private Short loggingmode;
|
private Short loggingmode;
|
||||||
|
|
||||||
private String remark;
|
private String remark;
|
||||||
private String iccid;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,7 +22,6 @@ public class GnssDeviceJoin {
|
|||||||
private String fwddeviceid; //推送的设备名
|
private String fwddeviceid; //推送的设备名
|
||||||
private String name;
|
private String name;
|
||||||
private String parentid;
|
private String parentid;
|
||||||
private String parentid1;
|
|
||||||
private Integer devicetype;
|
private Integer devicetype;
|
||||||
private String tenantname;
|
private String tenantname;
|
||||||
private String project_id;
|
private String project_id;
|
||||||
|
|||||||
@ -25,7 +25,6 @@ public class GnssGroup implements Serializable {
|
|||||||
Short rs_adv; // reference station only
|
Short rs_adv; // reference station only
|
||||||
Short power_mode;
|
Short power_mode;
|
||||||
Integer device_num;
|
Integer device_num;
|
||||||
Short gnss_sample_s;
|
|
||||||
|
|
||||||
public String getConfigCmd(GnssDevice device){
|
public String getConfigCmd(GnssDevice device){
|
||||||
String cmd = "D3110009";
|
String cmd = "D3110009";
|
||||||
@ -34,8 +33,7 @@ public class GnssGroup implements Serializable {
|
|||||||
+HexUtil.Byte2HexString((byte) active_time.intValue())
|
+HexUtil.Byte2HexString((byte) active_time.intValue())
|
||||||
+HexUtil.Byte2HexString((byte) active_offset.intValue())
|
+HexUtil.Byte2HexString((byte) active_offset.intValue())
|
||||||
+((device.getDevicetype() == GnssDevice.TYPE_ROVER)?"00":HexUtil.Byte2HexString((byte) rs_adv.shortValue()))
|
+((device.getDevicetype() == GnssDevice.TYPE_ROVER)?"00":HexUtil.Byte2HexString((byte) rs_adv.shortValue()))
|
||||||
+HexUtil.Byte2HexString((byte) power_mode.shortValue())
|
+HexUtil.Byte2HexString((byte) power_mode.shortValue());
|
||||||
+HexUtil.Byte2HexString((byte) gnss_sample_s.shortValue());
|
|
||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,51 +0,0 @@
|
|||||||
package com.imdroid.secapi.dto;
|
|
||||||
|
|
||||||
import com.alibaba.excel.annotation.ExcelProperty;
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import lombok.Data;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@TableName(value = "simcards")
|
|
||||||
public class SimCard {
|
|
||||||
public static final int STATUS_UNKNOWN = -1; // 未知
|
|
||||||
public static final int STATUS_WAIT_ACTIVE = 1; // 待激活
|
|
||||||
public static final int STATUS_ACTIVATED = 2; // 已激活
|
|
||||||
public static final int STATUS_SUSPENDED = 3; // 停机
|
|
||||||
public static final int STATUS_CANCELLED = 4; // 注销
|
|
||||||
public static final int STATUS_IN_STOCK = 5; // 库存
|
|
||||||
public static final int STATUS_TESTABLE = 6; // 可测试
|
|
||||||
public static final int STATUS_INVALID = 7; // 失效
|
|
||||||
public static final int STATUS_NOT_EXIST = 99; // 号码不存在
|
|
||||||
|
|
||||||
@TableId(type = IdType.AUTO)
|
|
||||||
@ExcelProperty("ID")
|
|
||||||
private Integer id;
|
|
||||||
|
|
||||||
@ExcelProperty("更新时间")
|
|
||||||
private Date updatetime;
|
|
||||||
|
|
||||||
@ExcelProperty("ICCID")
|
|
||||||
private String iccid;
|
|
||||||
|
|
||||||
@ExcelProperty("物联卡号码")
|
|
||||||
private String msisdn;
|
|
||||||
|
|
||||||
@ExcelProperty("设备ID")
|
|
||||||
private String deviceid;
|
|
||||||
|
|
||||||
@ExcelProperty("状态")
|
|
||||||
private Integer status;
|
|
||||||
|
|
||||||
@ExcelProperty("剩余流量(MB)")
|
|
||||||
private BigDecimal remaining;
|
|
||||||
|
|
||||||
@ExcelProperty("总流量(MB)")
|
|
||||||
private BigDecimal total;
|
|
||||||
|
|
||||||
@ExcelProperty("已用流量(MB)")
|
|
||||||
private BigDecimal used;
|
|
||||||
}
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
package com.imdroid.secapi.dto;
|
|
||||||
|
|
||||||
import com.github.yulichang.base.MPJBaseMapper;
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
|
||||||
import org.apache.ibatis.annotations.Select;
|
|
||||||
import org.apache.ibatis.annotations.Update;
|
|
||||||
|
|
||||||
public interface SimCardsMapper extends MPJBaseMapper<SimCard>{
|
|
||||||
@Select({"select * from simcards where deviceid = #{deviceId} limit 1"})
|
|
||||||
SimCard queryByDeviceId(String deviceId);
|
|
||||||
|
|
||||||
@Select("select * from simcards where iccid = #{iccid} limit 1")
|
|
||||||
SimCard queryByIccid(String iccid);
|
|
||||||
|
|
||||||
@Update("UPDATE simcards SET " +
|
|
||||||
"updatetime = #{updatetime}, " +
|
|
||||||
"msisdn = #{msisdn}, " +
|
|
||||||
"status = #{status}, " +
|
|
||||||
"remaining = #{remaining}, " +
|
|
||||||
"total = #{total}, " +
|
|
||||||
"used = #{used} " +
|
|
||||||
"WHERE deviceid = #{deviceid}")
|
|
||||||
int updateSimCardInfo(SimCard simCard);
|
|
||||||
|
|
||||||
@Update("UPDATE simcards SET " +
|
|
||||||
"updatetime = #{updatetime}, " +
|
|
||||||
"msisdn = #{msisdn}, " +
|
|
||||||
"status = #{status} " +
|
|
||||||
"WHERE deviceid = #{deviceid}")
|
|
||||||
int updateCardStatusInfo(SimCard simCard);
|
|
||||||
|
|
||||||
@Update("UPDATE simcards SET " +
|
|
||||||
"updatetime = #{updatetime}, " +
|
|
||||||
"remaining = #{remaining}, " +
|
|
||||||
"total = #{total}, " +
|
|
||||||
"used = #{used} " +
|
|
||||||
"WHERE deviceid = #{deviceid}")
|
|
||||||
int updateCardTrafficInfo(SimCard simCard);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -42,15 +42,8 @@ public class WarningCfg {
|
|||||||
public static final String TYPE_NAME_CONT_INVALID_RESULT = "长时间无有效解";
|
public static final String TYPE_NAME_CONT_INVALID_RESULT = "长时间无有效解";
|
||||||
public static final int TYPE_INCLINE = 0x400;
|
public static final int TYPE_INCLINE = 0x400;
|
||||||
public static final String TYPE_NAME_INCLINE = "异常倾斜";
|
public static final String TYPE_NAME_INCLINE = "异常倾斜";
|
||||||
public static final int TYPE_SIM_STATUS_ABNORMAL = 0x800;
|
public static final int TYPE_JUMP = 0x800;
|
||||||
public static final String TYPE_NAME_SIM_STATUS_ABNORMAL = "流量卡状态异常";
|
public static final String TYPE_NAME_JUMP = "滤波结果跳变";
|
||||||
public static final int TYPE_SIM_LOW_TRAFFIC = 0x1000;
|
|
||||||
public static final String TYPE_NAME_SIM_LOW_TRAFFIC = "流量卡流量不足";
|
|
||||||
public static final int TYPE_XY_JUMP = 0x2000;
|
|
||||||
public static final String TYPE_NAME_XY_JUMP = "滤波结果水平跳变";
|
|
||||||
public static final int TYPE_Z_JUMP = 0x4000;
|
|
||||||
public static final String TYPE_NAME_Z_JUMP = "滤波结果高程跳变";
|
|
||||||
|
|
||||||
|
|
||||||
// warning level definition
|
// warning level definition
|
||||||
public static final short LEVEL_0 = 0; //正常
|
public static final short LEVEL_0 = 0; //正常
|
||||||
@ -77,8 +70,6 @@ public class WarningCfg {
|
|||||||
if((code & TYPE_NO_FIXED_RESULT) !=0) warningInfo.add(TYPE_NAME_NO_FIXED_RESULT);
|
if((code & TYPE_NO_FIXED_RESULT) !=0) warningInfo.add(TYPE_NAME_NO_FIXED_RESULT);
|
||||||
if((code & TYPE_CONT_INVALID_RESULT) !=0) warningInfo.add(TYPE_NAME_CONT_INVALID_RESULT);
|
if((code & TYPE_CONT_INVALID_RESULT) !=0) warningInfo.add(TYPE_NAME_CONT_INVALID_RESULT);
|
||||||
if((code & TYPE_INCLINE) !=0) warningInfo.add(TYPE_NAME_INCLINE);
|
if((code & TYPE_INCLINE) !=0) warningInfo.add(TYPE_NAME_INCLINE);
|
||||||
if((code & TYPE_SIM_STATUS_ABNORMAL) !=0) warningInfo.add(TYPE_NAME_SIM_STATUS_ABNORMAL);
|
|
||||||
if((code & TYPE_SIM_LOW_TRAFFIC) !=0) warningInfo.add(TYPE_NAME_SIM_LOW_TRAFFIC);
|
|
||||||
return warningInfo;
|
return warningInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import static com.imdroid.sideslope.bd.GeoCoordConverterUtil.*;
|
|||||||
*/
|
*/
|
||||||
public class FocusCalculator3 extends FocusCalculator1{
|
public class FocusCalculator3 extends FocusCalculator1{
|
||||||
//final static long scale = 100000000L;//地球1°:111km,放大到mm乘以100,000,000
|
//final static long scale = 100000000L;//地球1°:111km,放大到mm乘以100,000,000
|
||||||
final static int bad_change_mm = 300;//固定解跳变连续10次超过500mm,认为是周跳
|
final static int bad_change_mm = 500;//固定解跳变连续10次超过500mm,认为是周跳
|
||||||
final static int bad_duration = 10;
|
final static int bad_duration = 10;
|
||||||
|
|
||||||
int bad_count = 0;
|
int bad_count = 0;
|
||||||
@ -61,10 +61,10 @@ public class FocusCalculator3 extends FocusCalculator1{
|
|||||||
if(gga.isFixed()) {
|
if(gga.isFixed()) {
|
||||||
counterFixedResult++;
|
counterFixedResult++;
|
||||||
if(pointList.size()>0){
|
if(pointList.size()>0){
|
||||||
//double[] lastXyz = pointList.get(pointList.size()-1);
|
double[] lastXyz = pointList.get(pointList.size()-1);
|
||||||
if(Math.abs(end[0]-referPoint[0])>bad_change_mm ||
|
if(Math.abs(end[0]-lastXyz[0])>bad_change_mm ||
|
||||||
Math.abs(end[1]-referPoint[1])>bad_change_mm ||
|
Math.abs(end[1]-lastXyz[1])>bad_change_mm ||
|
||||||
Math.abs(end[2]-referPoint[2])>bad_change_mm){
|
Math.abs(end[2]-lastXyz[2])>bad_change_mm){
|
||||||
bad_count++;
|
bad_count++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,9 +5,6 @@ import com.imdroid.common.util.ByteUtil;
|
|||||||
import com.imdroid.common.util.StringUtil;
|
import com.imdroid.common.util.StringUtil;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static java.lang.Math.*;
|
import static java.lang.Math.*;
|
||||||
|
|
||||||
@ -16,110 +13,6 @@ public class RtcmGgaUtil {
|
|||||||
//gga样本:*后面跟的是校验和,其中76代表校验和,对$和*之间的数据(不包括这两个字符)按字节进行异或运算(二进制)的结果
|
//gga样本:*后面跟的是校验和,其中76代表校验和,对$和*之间的数据(不包括这两个字符)按字节进行异或运算(二进制)的结果
|
||||||
private static final String ggaExample = "$GNGGA,020850.50,2258.10508,N,11317.67958,E,4,12,0.74,3.9,M,-5.4,M,1.3,0000*76";
|
private static final String ggaExample = "$GNGGA,020850.50,2258.10508,N,11317.67958,E,4,12,0.74,3.9,M,-5.4,M,1.3,0000*76";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 提取多条rtcm
|
|
||||||
* 因为存在d331...rtcm...d331...rtcm..这样的数据
|
|
||||||
* 还存在d331...rtcm rtcm rtcm...这样的数据
|
|
||||||
* @param hex
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static List<String> getRtcms(String hex){
|
|
||||||
return splitStartWith(hex,"d300","d301","d302").stream()
|
|
||||||
.map(com.imdroid.sideslope.bd.RtcmGgaUtil::getRtcm)
|
|
||||||
.filter(s -> s != null && !s.isEmpty())
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 提取一条rtcm
|
|
||||||
* @param hex
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static String getRtcm(String hex){
|
|
||||||
try {
|
|
||||||
int index = getIndex(hex,"d300","d301","d302");
|
|
||||||
if (index != -1 && index < hex.length()-6) {
|
|
||||||
//d300数据长度
|
|
||||||
int length = Integer.parseInt(hex.substring(index + 3, index + 6), 16);
|
|
||||||
if(index + (3+length +3)*2 <= hex.length()){
|
|
||||||
return hex.substring(index, index + (3 + length + 3) * 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}catch (Exception e){
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getIndex(String... regex){
|
|
||||||
for (int i = 1; i < regex.length; i++) {
|
|
||||||
if(regex[0].contains(regex[i])){
|
|
||||||
return regex[0].indexOf(regex[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按前缀切割分段
|
|
||||||
* @param regex 第一个是要处理的数据,其他是要检测的前缀
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static List<String> splitStartWith(String... regex){
|
|
||||||
ArrayList<String> list = new ArrayList<>();
|
|
||||||
try{
|
|
||||||
List<Integer> indexs = getIndexs(regex);
|
|
||||||
int start = 0;
|
|
||||||
for (int i = 0; i < indexs.size(); i++) {
|
|
||||||
if(indexs.get(i) != 0){
|
|
||||||
list.add(regex[0].substring(start,indexs.get(i)));
|
|
||||||
start = indexs.get(i);
|
|
||||||
}
|
|
||||||
if(i == indexs.size() -1){
|
|
||||||
list.add(regex[0].substring(indexs.get(i)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}catch (Exception e){
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按多个规则搜索索引
|
|
||||||
* @param regex
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static List<Integer> getIndexs(String... regex){
|
|
||||||
List<Integer> list =new ArrayList<>();
|
|
||||||
for (int i = 1; i < regex.length; i++) {
|
|
||||||
list.addAll(findAllIndex(regex[0],0,regex[i]));
|
|
||||||
}
|
|
||||||
list.sort((o1, o2) -> o1-o2);
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按规则搜索所有索引
|
|
||||||
* @param string
|
|
||||||
* @param index
|
|
||||||
* @param findStr
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static List<Integer> findAllIndex(String string, int index, String findStr){
|
|
||||||
List<Integer> list =new ArrayList<>();
|
|
||||||
int num = string.indexOf(findStr,index);
|
|
||||||
if(num != -1){
|
|
||||||
list.add(num);
|
|
||||||
//递归进行查找
|
|
||||||
List myList = findAllIndex(string,num+1,findStr);
|
|
||||||
list.addAll(myList);
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取rtcm数据类型
|
* 获取rtcm数据类型
|
||||||
* @param bytes
|
* @param bytes
|
||||||
|
|||||||
@ -4,16 +4,13 @@ import com.imdroid.common.util.DataTypeUtil;
|
|||||||
import com.imdroid.common.util.ThreadManager;
|
import com.imdroid.common.util.ThreadManager;
|
||||||
import com.imdroid.secapi.client.BeidouClient;
|
import com.imdroid.secapi.client.BeidouClient;
|
||||||
import com.imdroid.secapi.dto.GnssDevice;
|
import com.imdroid.secapi.dto.GnssDevice;
|
||||||
import com.imdroid.common.util.ByteUtil;
|
|
||||||
import com.imdroid.sideslope.bd.Gga;
|
import com.imdroid.sideslope.bd.Gga;
|
||||||
import com.imdroid.sideslope.message.D331RtcmMessage;
|
import com.imdroid.sideslope.message.D331RtcmMessage;
|
||||||
import com.imdroid.sideslope.ntrip.UdpNtripServer;
|
|
||||||
import com.imdroid.sideslope.sal.Device;
|
import com.imdroid.sideslope.sal.Device;
|
||||||
import com.imdroid.sideslope.sal.DeviceService;
|
import com.imdroid.sideslope.sal.DeviceService;
|
||||||
import com.imdroid.sideslope.server.DeviceChannel;
|
import com.imdroid.sideslope.server.DeviceChannel;
|
||||||
import com.imdroid.sideslope.server.OnlineChannels;
|
import com.imdroid.sideslope.server.OnlineChannels;
|
||||||
import com.imdroid.sideslope.service.DataPersistService;
|
import com.imdroid.sideslope.service.DataPersistService;
|
||||||
import com.imdroid.sideslope.bd.RtcmGgaUtil;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -23,12 +20,7 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Layton
|
* @author Layton
|
||||||
@ -39,87 +31,39 @@ public class D331RtcmMessageExecutor implements Executor<D331RtcmMessage, Void>
|
|||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
private static final Map<String ,Boolean> deviceBackupStatus = new ConcurrentHashMap<>();
|
|
||||||
@Resource(name = "local")
|
@Resource(name = "local")
|
||||||
private DeviceService deviceService;
|
private DeviceService deviceService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private BeidouClient beidouClient;
|
private BeidouClient beidouClient;
|
||||||
@Autowired
|
@Autowired
|
||||||
private DataPersistService dataPersistService;
|
private DataPersistService dataPersistService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void execute(D331RtcmMessage message) {
|
public Void execute(D331RtcmMessage message) {
|
||||||
String id = message.getId();
|
String id = message.getId();
|
||||||
byte[] srcdata = message.getSrcData();
|
|
||||||
String rtcm = ByteUtil.bytesToHexString(srcdata);
|
|
||||||
// 补齐tenantId
|
// 补齐tenantId
|
||||||
Device deviceBs = deviceService.findByDeviceId(id);
|
Device deviceBs = deviceService.findByDeviceId(id);
|
||||||
if(deviceBs == null || deviceBs.getOpMode() == GnssDevice.OP_MODE_UNUSE) return null;
|
if(deviceBs == null || deviceBs.getOpMode() == GnssDevice.OP_MODE_UNUSE) return null;
|
||||||
|
|
||||||
// 添加NTRIP处理
|
|
||||||
ntrip(id, rtcm);
|
|
||||||
|
|
||||||
// 推送基站数据
|
// 推送基站数据
|
||||||
if(deviceBs.getOpMode() == GnssDevice.OP_MODE_USE) {
|
if(deviceBs.getOpMode() == GnssDevice.OP_MODE_USE) {
|
||||||
byte[] forwardBytes = message.getSrcData();
|
byte[] forwardBytes = message.getSrcData();
|
||||||
// 获取使用该基站(包括作为主基站和备选基站)的所有测站
|
// 要求快速转发,因此用缓存,不要每次都查数据库
|
||||||
List<Device> primaryDevices = deviceService.findByParentId(id);
|
List<Device> deviceList = deviceService.findByParentId(id);
|
||||||
List<Device> backupDevices = deviceService.findByParentId1(id);
|
//logger.debug("base station {} has {} rovers: ", message.getId(),deviceList.size());
|
||||||
|
|
||||||
// 合并两个列表
|
|
||||||
List<Device> allDevices = new ArrayList<>();
|
|
||||||
allDevices.addAll(primaryDevices);
|
|
||||||
allDevices.addAll(backupDevices);
|
|
||||||
|
|
||||||
DeviceChannel deviceChannel = null;
|
DeviceChannel deviceChannel = null;
|
||||||
for (Device device : allDevices) {
|
for (Device device : deviceList) {
|
||||||
if (device.getOpMode() != GnssDevice.OP_MODE_USE) continue;
|
if (device.getOpMode() != GnssDevice.OP_MODE_USE) continue;
|
||||||
String deviceId = device.getDeviceId();
|
String deviceId = device.getDeviceId();
|
||||||
|
|
||||||
// 检查该设备是否应该接收此基站的数据
|
|
||||||
String primaryBaseId = device.getParentId();
|
|
||||||
String backupBaseId = device.getParentId1();
|
|
||||||
|
|
||||||
// 如果当前基站是该设备的备选基站,需要检查主基站是否离线
|
|
||||||
if (id.equals(backupBaseId)) {
|
|
||||||
byte[] modifyData = forwardBytes.clone();
|
|
||||||
Device primaryBase = deviceService.findByDeviceId(primaryBaseId);
|
|
||||||
// 如果主基站仍然在线,则跳过备选基站的数据
|
|
||||||
if (primaryBase != null && isBaseStationOnline(primaryBase)) {
|
|
||||||
if(deviceBackupStatus.remove(deviceId) != null){
|
|
||||||
logger.info("设备 {} 从备用基站 {} 切换回主基站 {}",
|
|
||||||
deviceId, id, primaryBaseId);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
String hexPrimaryBase = String.format("%06x",Integer.parseInt(primaryBaseId));
|
|
||||||
if(deviceBackupStatus.putIfAbsent(deviceId,true) == null){
|
|
||||||
logger.info("设备 {} 从主基站 {} 切换到备用基站 {}",
|
|
||||||
deviceId, primaryBaseId, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
modifyData[5] = (byte) Integer.parseInt(hexPrimaryBase.substring(0,2),16);
|
|
||||||
modifyData[6] = (byte) Integer.parseInt(hexPrimaryBase.substring(2,4),16);
|
|
||||||
modifyData[7] = (byte) Integer.parseInt(hexPrimaryBase.substring(4,6),16);
|
|
||||||
|
|
||||||
forwardBytes = modifyData;
|
|
||||||
|
|
||||||
// 打印修改后的完整数据(16进制形式)
|
|
||||||
//logger.info("Modified D331 data (HEX): {}", ByteUtil.bytesToHexString(forwardBytes));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取设备通道并发送数据
|
|
||||||
if(device.getDataChannelType() == Device.CHANNEL_TYPE_UDP) {
|
if(device.getDataChannelType() == Device.CHANNEL_TYPE_UDP) {
|
||||||
deviceChannel = OnlineChannels.INSTANCE.getDataChannel(deviceId);
|
deviceChannel = OnlineChannels.INSTANCE.getDataChannel(deviceId);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
deviceChannel = OnlineChannels.INSTANCE.getConfigChannel(deviceId);
|
deviceChannel = OnlineChannels.INSTANCE.getConfigChannel(deviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(deviceChannel != null && deviceChannel.isOnline()) {
|
if(deviceChannel!=null && deviceChannel.isOnline()){
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("forward d331 rtcm from {} to device {}", id, deviceId);
|
logger.debug("forward d331 rtcm to device {}", deviceId);
|
||||||
}
|
}
|
||||||
if (deviceId.startsWith("2307")) {
|
if (deviceId.startsWith("2307")) {
|
||||||
forwardBytes[2] = (byte) (forwardBytes[2] & 0x07);//兼容不带序号的测站
|
forwardBytes[2] = (byte) (forwardBytes[2] & 0x07);//兼容不带序号的测站
|
||||||
@ -135,8 +79,8 @@ public class D331RtcmMessageExecutor implements Executor<D331RtcmMessage, Void>
|
|||||||
if(deviceBs.getD3xxbytes()>0){
|
if(deviceBs.getD3xxbytes()>0){
|
||||||
LocalDateTime now = LocalDateTime.now();
|
LocalDateTime now = LocalDateTime.now();
|
||||||
if(deviceBs.getLastRxTime().isBefore(now.minusMinutes(1)) &&
|
if(deviceBs.getLastRxTime().isBefore(now.minusMinutes(1)) &&
|
||||||
(deviceBs.getLastD3f2Time() == null ||
|
(deviceBs.getLastD3f2Time() == null ||
|
||||||
deviceBs.getLastD3f2Time().isBefore(now.minusMinutes(30)))) {
|
deviceBs.getLastD3f2Time().isBefore(now.minusMinutes(30)))) {
|
||||||
// new cycle
|
// new cycle
|
||||||
logger.info("device {} rx {} d331 in a cycle while not d3f0f2",deviceBs.getDeviceId(),deviceBs.getD3xxCount());
|
logger.info("device {} rx {} d331 in a cycle while not d3f0f2",deviceBs.getDeviceId(),deviceBs.getD3xxCount());
|
||||||
|
|
||||||
@ -171,9 +115,11 @@ public class D331RtcmMessageExecutor implements Executor<D331RtcmMessage, Void>
|
|||||||
Gga gga = message.getGga();
|
Gga gga = message.getGga();
|
||||||
if(gga != null) {
|
if(gga != null) {
|
||||||
deviceBs.updateSatelitesNum(gga.getSatellitesInUsed());
|
deviceBs.updateSatelitesNum(gga.getSatellitesInUsed());
|
||||||
deviceBs.setLatitude(gga.getLatitude());
|
//if(gga.isFixed()) { //基站的quality不会是4
|
||||||
deviceBs.setLongitude(gga.getLongitude());
|
deviceBs.setLatitude(gga.getLatitude());
|
||||||
deviceBs.setAltitude(gga.getAltitude());
|
deviceBs.setLongitude(gga.getLongitude());
|
||||||
|
deviceBs.setAltitude(gga.getAltitude());
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadManager.getFixedThreadPool().submit(() -> {
|
ThreadManager.getFixedThreadPool().submit(() -> {
|
||||||
@ -187,43 +133,8 @@ public class D331RtcmMessageExecutor implements Executor<D331RtcmMessage, Void>
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ntrip(String mountpoint, String hexData) {
|
|
||||||
try {
|
|
||||||
|
|
||||||
// 将原始字节转换为16进制字符串用于RTCM提取
|
|
||||||
//String hexData = ByteUtil.bytesToHexString(rawData);
|
|
||||||
System.out.println(hexData);
|
|
||||||
|
|
||||||
// 提取RTCM数据并发送到NtripServer,使用设备ID作为挂载点
|
|
||||||
Optional.ofNullable(RtcmGgaUtil.getRtcms(hexData))
|
|
||||||
.ifPresent(rtcm -> {
|
|
||||||
//System.out.println("挂载点: " + mountpoint);
|
|
||||||
//System.out.println("RTCM数据: " + rtcm);
|
|
||||||
UdpNtripServer.send(mountpoint, rtcm);
|
|
||||||
});
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("处理NTRIP数据失败, 挂载点: {}, 错误: {}", mountpoint, e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<?> getMessageType() {
|
public Class<?> getMessageType() {
|
||||||
return D331RtcmMessage.class;
|
return D331RtcmMessage.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断住基站是否在线
|
|
||||||
* @param baseStation 基站
|
|
||||||
* @return 是否在线
|
|
||||||
*/
|
|
||||||
|
|
||||||
private boolean isBaseStationOnline(Device baseStation){
|
|
||||||
if(baseStation == null) return false;
|
|
||||||
|
|
||||||
LocalDateTime now =LocalDateTime.now();
|
|
||||||
return baseStation.getLastRxTime() !=null &&
|
|
||||||
baseStation.getLastRxTime().isAfter(now.minusMinutes(10));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -4,7 +4,6 @@ import com.imdroid.common.util.DataTypeUtil;
|
|||||||
import com.imdroid.common.util.HexUtil;
|
import com.imdroid.common.util.HexUtil;
|
||||||
import com.imdroid.common.util.ThreadManager;
|
import com.imdroid.common.util.ThreadManager;
|
||||||
import com.imdroid.secapi.client.BeidouClient;
|
import com.imdroid.secapi.client.BeidouClient;
|
||||||
import com.imdroid.secapi.client.HttpResp;
|
|
||||||
import com.imdroid.secapi.dto.*;
|
import com.imdroid.secapi.dto.*;
|
||||||
import com.imdroid.sideslope.message.D3F0SelfCheckMessage;
|
import com.imdroid.sideslope.message.D3F0SelfCheckMessage;
|
||||||
import com.imdroid.sideslope.sal.Device;
|
import com.imdroid.sideslope.sal.Device;
|
||||||
@ -17,9 +16,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
|
||||||
@ -44,8 +41,6 @@ public class D3F0SelfCheckMessageExecutor implements Executor<D3F0SelfCheckMessa
|
|||||||
@Autowired
|
@Autowired
|
||||||
private DataPersistService dataPersistService;
|
private DataPersistService dataPersistService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private GnssDeviceMapper gnssDeviceMapper;
|
|
||||||
@Autowired
|
|
||||||
GnssMsgMapper msgMapper;
|
GnssMsgMapper msgMapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@ -71,8 +66,6 @@ public class D3F0SelfCheckMessageExecutor implements Executor<D3F0SelfCheckMessa
|
|||||||
device.updateRx(message.getHeader(),message.getLen(),1);
|
device.updateRx(message.getHeader(),message.getLen(),1);
|
||||||
|
|
||||||
ThreadManager.getFixedThreadPool().submit(() -> {
|
ThreadManager.getFixedThreadPool().submit(() -> {
|
||||||
// 检查是否需要更新设备的 ICCID
|
|
||||||
checkAndAskICCID(device);
|
|
||||||
// 检查是否需要对设备的F9P进行冷启动操作
|
// 检查是否需要对设备的F9P进行冷启动操作
|
||||||
if(device.getDeviceType() == Device.DEVICE_ROVER){
|
if(device.getDeviceType() == Device.DEVICE_ROVER){
|
||||||
if(device.getModel() == GnssDevice.MODEL_G505){
|
if(device.getModel() == GnssDevice.MODEL_G505){
|
||||||
@ -186,28 +179,6 @@ public class D3F0SelfCheckMessageExecutor implements Executor<D3F0SelfCheckMessa
|
|||||||
rtcmClient.config(device.getDeviceId(), sendCmd);
|
rtcmClient.config(device.getDeviceId(), sendCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkAndAskICCID(Device device){
|
|
||||||
// 如果设备的 ICCID 存在,那么就不用发送 "AT+ICCID" 指令
|
|
||||||
|
|
||||||
if(device.getIccid() != null && !device.getIccid().trim().isEmpty()){
|
|
||||||
GnssDevice gnssDevice = gnssDeviceMapper.queryByDeviceId(device.getDeviceId());
|
|
||||||
if(gnssDevice.getIccid() != null && !gnssDevice.getIccid().trim().isEmpty()){
|
|
||||||
// 状态和流量查询更新需要 1-2 小时,期间 DataPersistService 更新可能不及时
|
|
||||||
// 若是数据库的设备已经更新了 iccid 号,将它同步到 DataPersistService 缓存中
|
|
||||||
device.setIccid(gnssDevice.getIccid());
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String sendCmd = "AT+ICCID";
|
|
||||||
int msgType = 0xD310 + 10; // DTU
|
|
||||||
short len = (short) (sendCmd.length() + 5);
|
|
||||||
sendCmd = Integer.toHexString(msgType) + HexUtil.Short2HexString(len)+
|
|
||||||
HexUtil.Int2HexString(Integer.parseInt(device.getDeviceId()))+
|
|
||||||
"01"+HexUtil.String2HexString(sendCmd);
|
|
||||||
rtcmClient.config(device.getDeviceId(),sendCmd);
|
|
||||||
// TODO: 将这个消息写到 msg 表中
|
|
||||||
logger.info(sendCmd);
|
|
||||||
}
|
|
||||||
private void checkAndResetBTGnss(Device device){
|
private void checkAndResetBTGnss(Device device){
|
||||||
if(device.getNoFixedAndFloatResult()>0 &&device.getAbnormalD341Num()>10){
|
if(device.getNoFixedAndFloatResult()>0 &&device.getAbnormalD341Num()>10){
|
||||||
if(isBaseStationFwd(device)) startBTResetTask(device);
|
if(isBaseStationFwd(device)) startBTResetTask(device);
|
||||||
|
|||||||
@ -1,31 +0,0 @@
|
|||||||
package com.imdroid.sideslope.ntrip;
|
|
||||||
|
|
||||||
import com.imdroid.common.util.HttpUtils;
|
|
||||||
import com.imdroid.common.util.ThreadManager;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
/**
|
|
||||||
* @author likongyong
|
|
||||||
* @date 2023/10/19 11:49
|
|
||||||
*/
|
|
||||||
public class HttpNtripServer {
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(HttpNtripServer.class);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改挂载点获取xingyu差分的gga
|
|
||||||
* @param mount
|
|
||||||
* @param gga
|
|
||||||
*/
|
|
||||||
public static void sendGGA(String mount, String gga){
|
|
||||||
ThreadManager.getSingleThreadPool(HttpNtripServer.class.getName()).execute(()->{
|
|
||||||
try{
|
|
||||||
String url = "http://localhost:11001/ntrip/sendGGA/" + mount + "/" + gga;
|
|
||||||
String result = HttpUtils.getUrl(url);
|
|
||||||
logger.debug("{} send gga {} {}",mount, gga, result);
|
|
||||||
}catch (Exception e){
|
|
||||||
logger.error(e.toString());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,69 +0,0 @@
|
|||||||
package com.imdroid.sideslope.ntrip;
|
|
||||||
|
|
||||||
import com.imdroid.common.util.ByteUtil;
|
|
||||||
import com.imdroid.common.util.ThreadManager;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.net.DatagramPacket;
|
|
||||||
import java.net.DatagramSocket;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 本地udp发送差分数据到ntrip-forward-server项目
|
|
||||||
*/
|
|
||||||
public class UdpNtripServer {
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(UdpNtripServer.class);
|
|
||||||
|
|
||||||
private static DatagramSocket socket;
|
|
||||||
private static DatagramPacket outPacket;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 向某挂载点提供差分信息
|
|
||||||
* @param mount 挂载点名称
|
|
||||||
* @param hexRtcm 差分信息16进制字符串
|
|
||||||
*/
|
|
||||||
public static void send(String mount, String hexRtcm){
|
|
||||||
ThreadManager.getSingleThreadPool(UdpNtripServer.class.getName()).execute(()->{
|
|
||||||
try{
|
|
||||||
//随机端口
|
|
||||||
if(socket == null) socket = new DatagramSocket();
|
|
||||||
if(outPacket == null) outPacket = new DatagramPacket(new byte[0],0, InetAddress.getByName("localhost"),11100);
|
|
||||||
outPacket.setData(encode(ByteUtil.addBytes(mount.getBytes(), ByteUtil.hexStringTobyte(hexRtcm))));
|
|
||||||
socket.send(outPacket);
|
|
||||||
}catch (Exception e){
|
|
||||||
socket = null;
|
|
||||||
outPacket = null;
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 向某挂载点提供差分信息
|
|
||||||
* @param mount 挂载点名称
|
|
||||||
* @param hexRtcm 差分信息16进制字符串
|
|
||||||
*/
|
|
||||||
public static void send(String mount, List<String> hexRtcm){
|
|
||||||
logger.debug(mount + ":" + hexRtcm.size());
|
|
||||||
for (String s : hexRtcm) {
|
|
||||||
send(mount,s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//加入校验位,用于校验数据是否完整
|
|
||||||
private static byte[] encode(byte[] bytes) {
|
|
||||||
byte[] bytes1 = new byte[bytes.length + 1];
|
|
||||||
//校验位
|
|
||||||
byte b = bytes[0];
|
|
||||||
bytes1[0] = bytes[0];
|
|
||||||
for (int i = 1; i < bytes.length; i++) {
|
|
||||||
b ^= bytes[i];
|
|
||||||
bytes1[i] = bytes[i];
|
|
||||||
}
|
|
||||||
bytes1[bytes1.length - 1] = b;
|
|
||||||
return bytes1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -32,7 +32,6 @@ public class DbDeviceServiceImpl implements DeviceService {
|
|||||||
device.setDeviceType(gnssDevice.getDevicetype());
|
device.setDeviceType(gnssDevice.getDevicetype());
|
||||||
device.setModel(gnssDevice.getModel());
|
device.setModel(gnssDevice.getModel());
|
||||||
device.setParentId(gnssDevice.getParentid());
|
device.setParentId(gnssDevice.getParentid());
|
||||||
device.setParentId1(gnssDevice.getParentid1());
|
|
||||||
device.setName(gnssDevice.getName());
|
device.setName(gnssDevice.getName());
|
||||||
device.setProjectId(gnssDevice.getProject_id());
|
device.setProjectId(gnssDevice.getProject_id());
|
||||||
device.setCalcGroupId(gnssDevice.getCalc_group_id());
|
device.setCalcGroupId(gnssDevice.getCalc_group_id());
|
||||||
@ -45,7 +44,6 @@ public class DbDeviceServiceImpl implements DeviceService {
|
|||||||
device.setEcefy(gnssDevice.getEcefy());
|
device.setEcefy(gnssDevice.getEcefy());
|
||||||
device.setEcefz(gnssDevice.getEcefz());
|
device.setEcefz(gnssDevice.getEcefz());
|
||||||
device.setLoggingmode(gnssDevice.getLoggingmode());
|
device.setLoggingmode(gnssDevice.getLoggingmode());
|
||||||
device.setIccid(gnssDevice.getIccid());
|
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,36 +58,6 @@ public class DbDeviceServiceImpl implements DeviceService {
|
|||||||
device.setDeviceId(gnssDevice.getDeviceid());
|
device.setDeviceId(gnssDevice.getDeviceid());
|
||||||
device.setDeviceType(gnssDevice.getDevicetype());
|
device.setDeviceType(gnssDevice.getDevicetype());
|
||||||
device.setParentId(gnssDevice.getParentid());
|
device.setParentId(gnssDevice.getParentid());
|
||||||
device.setParentId1(gnssDevice.getParentid1());
|
|
||||||
device.setName(gnssDevice.getName());
|
|
||||||
device.setProjectId(gnssDevice.getProject_id());
|
|
||||||
device.setCalcGroupId(gnssDevice.getCalc_group_id());
|
|
||||||
device.setOpMode(gnssDevice.getOpmode());
|
|
||||||
device.setFwdId(gnssDevice.getFwd_group_id());
|
|
||||||
device.setIPose(gnssDevice.getIpose());
|
|
||||||
device.setIPosn(gnssDevice.getIposn());
|
|
||||||
device.setIPosd(gnssDevice.getIposd());
|
|
||||||
device.setEcefx(gnssDevice.getEcefx());
|
|
||||||
device.setEcefy(gnssDevice.getEcefy());
|
|
||||||
device.setEcefz(gnssDevice.getEcefz());
|
|
||||||
deviceList.add(device);
|
|
||||||
}
|
|
||||||
return deviceList;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Device> findByParentId1(String parentId1) {
|
|
||||||
QueryWrapper<GnssDevice> query = new QueryWrapper<>();
|
|
||||||
query.eq("parentid1", parentId1);
|
|
||||||
List<GnssDevice> gnssDeviceList = gnssDeviceRepository.selectList(query);
|
|
||||||
List<Device> deviceList = new ArrayList<>(gnssDeviceList.size());
|
|
||||||
|
|
||||||
for (GnssDevice gnssDevice : gnssDeviceList) {
|
|
||||||
Device device = new Device();
|
|
||||||
device.setDeviceId(gnssDevice.getDeviceid());
|
|
||||||
device.setDeviceType(gnssDevice.getDevicetype());
|
|
||||||
device.setParentId(gnssDevice.getParentid());
|
|
||||||
device.setParentId1(gnssDevice.getParentid1()); // 添加备选基站ID
|
|
||||||
device.setName(gnssDevice.getName());
|
device.setName(gnssDevice.getName());
|
||||||
device.setProjectId(gnssDevice.getProject_id());
|
device.setProjectId(gnssDevice.getProject_id());
|
||||||
device.setCalcGroupId(gnssDevice.getCalc_group_id());
|
device.setCalcGroupId(gnssDevice.getCalc_group_id());
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
package com.imdroid.sideslope.sal;
|
package com.imdroid.sideslope.sal;
|
||||||
|
|
||||||
import com.alibaba.excel.annotation.ExcelProperty;
|
|
||||||
import com.imdroid.secapi.dto.GnssDevice;
|
import com.imdroid.secapi.dto.GnssDevice;
|
||||||
import com.imdroid.sideslope.bd.Gga;
|
import com.imdroid.sideslope.bd.Gga;
|
||||||
import com.imdroid.sideslope.bd.UBXUtil;
|
import com.imdroid.sideslope.bd.UBXUtil;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,7 +35,6 @@ public class Device {
|
|||||||
private String deviceId;
|
private String deviceId;
|
||||||
|
|
||||||
private String parentId;
|
private String parentId;
|
||||||
private String parentId1;
|
|
||||||
private String projectId;
|
private String projectId;
|
||||||
private String fwdId;
|
private String fwdId;
|
||||||
|
|
||||||
@ -70,11 +67,6 @@ public class Device {
|
|||||||
Double iPosn;
|
Double iPosn;
|
||||||
Double iPosd;
|
Double iPosd;
|
||||||
|
|
||||||
String iccid;
|
|
||||||
private BigDecimal remaining;
|
|
||||||
private BigDecimal total;
|
|
||||||
private BigDecimal used;
|
|
||||||
|
|
||||||
LocalDateTime lastRxTime;
|
LocalDateTime lastRxTime;
|
||||||
LocalDateTime lastD3f2Time;
|
LocalDateTime lastD3f2Time;
|
||||||
short noFixedAndFloatResult=0;
|
short noFixedAndFloatResult=0;
|
||||||
|
|||||||
@ -11,6 +11,4 @@ public interface DeviceService {
|
|||||||
Device findByDeviceId(String deviceId);
|
Device findByDeviceId(String deviceId);
|
||||||
|
|
||||||
List<Device> findByParentId(String parentId);
|
List<Device> findByParentId(String parentId);
|
||||||
|
|
||||||
List<Device> findByParentId1(String parentId1);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import org.slf4j.LoggerFactory;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@ -58,22 +57,6 @@ public class LocalDeviceServiceImpl implements DeviceService {
|
|||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Device> findByParentId1(String parentId1) {
|
|
||||||
if (parentId1 == null || parentId1.trim().isEmpty()){
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
|
||||||
List<Device> device = subDeviceCache.getIfPresent("backup_" + parentId1); // 使用前缀区分备选基站的缓存
|
|
||||||
if (device == null) {
|
|
||||||
logger.debug("backup base station {} refresh: " + parentId1);
|
|
||||||
device = delegate.findByParentId1(parentId1);
|
|
||||||
if (device != null) {
|
|
||||||
subDeviceCache.put("backup_" + parentId1, device);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return device;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void refresh(String deviceId, String oldParentId){
|
public void refresh(String deviceId, String oldParentId){
|
||||||
Device device = deviceCache.getIfPresent(deviceId);
|
Device device = deviceCache.getIfPresent(deviceId);
|
||||||
if (device != null) {
|
if (device != null) {
|
||||||
@ -83,10 +66,6 @@ public class LocalDeviceServiceImpl implements DeviceService {
|
|||||||
subDeviceCache.invalidate(oldParentId);
|
subDeviceCache.invalidate(oldParentId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(device.getParentId1() != null && !device.getParentId1().trim().isEmpty()){
|
|
||||||
subDeviceCache.invalidate("back_"+device.getParentId1());
|
|
||||||
}
|
|
||||||
deviceCache.invalidate(deviceId);
|
deviceCache.invalidate(deviceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +0,0 @@
|
|||||||
package com.imdroid.sideslope.service;
|
|
||||||
|
|
||||||
import com.imdroid.sideslope.sal.Device;
|
|
||||||
import com.imdroid.sideslope.simcard.*;
|
|
||||||
|
|
||||||
public interface SimCardQueryService {
|
|
||||||
|
|
||||||
// 查询卡基本信息
|
|
||||||
BaseResponse<CardInfoData> queryCardInfo(Device device);
|
|
||||||
|
|
||||||
// 查询卡状态
|
|
||||||
BaseResponse<CardStatusData> queryCardStatus(Device device);
|
|
||||||
|
|
||||||
// 查询流量信息
|
|
||||||
BaseResponse<GprsData> queryGprs(Device device);
|
|
||||||
|
|
||||||
// 查询卡详细信息
|
|
||||||
BaseResponse<CardDetailData> queryCardDetail(Device device);
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,179 +0,0 @@
|
|||||||
package com.imdroid.sideslope.service;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JavaType;
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
|
||||||
import com.fasterxml.jackson.databind.MapperFeature;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.imdroid.secapi.dto.GnssStatusJoin;
|
|
||||||
import com.imdroid.secapi.dto.SimCard;
|
|
||||||
import com.imdroid.secapi.dto.SimCardsMapper;
|
|
||||||
import com.imdroid.sideslope.sal.Device;
|
|
||||||
import com.imdroid.sideslope.sal.DeviceService;
|
|
||||||
import com.imdroid.sideslope.simcard.*;
|
|
||||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
|
||||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
|
||||||
import org.apache.http.client.methods.HttpPost;
|
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
|
||||||
import org.apache.http.impl.client.HttpClients;
|
|
||||||
import org.apache.http.message.BasicNameValuePair;
|
|
||||||
import org.apache.http.util.EntityUtils;
|
|
||||||
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.math.BigDecimal;
|
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class SimCardQueryServiceImpl implements SimCardQueryService{
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
|
||||||
private static final String BASE_URL = "http://120.78.169.220:8089";
|
|
||||||
private static final String USERNAME = "gzyzdz";
|
|
||||||
private static final String KEY = "632629d1269a202c9d49a574623e4e4c";
|
|
||||||
|
|
||||||
@Resource(name = "local")
|
|
||||||
private DeviceService deviceService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
SimCardsMapper simCardsMapper;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BaseResponse<CardInfoData> queryCardInfo(Device device) {
|
|
||||||
return executeQuery(device, "/api/Service/Cardinfo", CardInfoData.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BaseResponse<CardStatusData> queryCardStatus(Device device) {
|
|
||||||
return executeQuery(device, "/api/Service/QueryCardStatus", CardStatusData.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BaseResponse<GprsData> queryGprs(Device device) {
|
|
||||||
return executeQuery(device, "/api/Service/QueryGprs", GprsData.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BaseResponse<CardDetailData> queryCardDetail(Device device) {
|
|
||||||
return executeQuery(device, "/api/Service/QueryCard", CardDetailData.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T> BaseResponse<T> executeQuery(Device device, String path, Class<T> responseType) {
|
|
||||||
try {
|
|
||||||
Map<String, String> params = new HashMap<>();
|
|
||||||
params.put("username", USERNAME);
|
|
||||||
params.put("key", KEY);
|
|
||||||
params.put("card", device.getIccid());
|
|
||||||
params.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
|
|
||||||
|
|
||||||
String signature = calculateSignature(params);
|
|
||||||
params.put("signature", signature);
|
|
||||||
|
|
||||||
logger.info("Request params: {}", params);
|
|
||||||
String response = sendHttpPost(path, params);
|
|
||||||
logger.info("查询响应: 设备={}, ICCID={}, 响应={}",
|
|
||||||
device.getDeviceId(), device.getIccid(), response);
|
|
||||||
|
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
|
||||||
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
|
|
||||||
|
|
||||||
// 特殊处理CardStatus的数组响应
|
|
||||||
if (responseType == CardStatusData.class) {
|
|
||||||
JsonNode root = mapper.readTree(response);
|
|
||||||
if (root.get("Status").asInt() == 1 && root.get("Data").isArray()) {
|
|
||||||
CardStatusData statusData = new CardStatusData();
|
|
||||||
statusData.setStatusCode(root.get("Data").get(0).asInt());
|
|
||||||
statusData.setStatusDesc(root.get("Data").get(1).asText());
|
|
||||||
BaseResponse<CardStatusData> baseResponse = new BaseResponse<>();
|
|
||||||
baseResponse.setStatus(1);
|
|
||||||
baseResponse.setMessage("Success");
|
|
||||||
baseResponse.setData(statusData);
|
|
||||||
return (BaseResponse<T>) baseResponse;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
JavaType type = mapper.getTypeFactory().constructParametricType(BaseResponse.class, responseType);
|
|
||||||
return mapper.readValue(response, type);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("查询失败: 设备={}, 错误={}", device.getDeviceId(), e.getMessage());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String calculateSignature(Map<String, String> params) {
|
|
||||||
try {
|
|
||||||
List<String> paramList = new ArrayList<>();
|
|
||||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
|
||||||
paramList.add(entry.getKey() + "=" + entry.getValue());
|
|
||||||
}
|
|
||||||
Collections.sort(paramList);
|
|
||||||
|
|
||||||
String paramString = String.join("&", paramList);
|
|
||||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
|
||||||
byte[] digest = md.digest(paramString.getBytes());
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
for (byte b : digest) {
|
|
||||||
sb.append(String.format("%02x", b));
|
|
||||||
}
|
|
||||||
String signature = sb.toString();
|
|
||||||
logger.debug("Signature: {}", signature);
|
|
||||||
return signature;
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("签名计算失败: {}", e.getMessage());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String sendHttpPost(String path, Map<String, String> params) throws Exception {
|
|
||||||
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
|
||||||
HttpPost httpPost = new HttpPost(BASE_URL + path);
|
|
||||||
|
|
||||||
List<BasicNameValuePair> pairs = new ArrayList<>();
|
|
||||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
|
||||||
pairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
httpPost.setEntity(new UrlEncodedFormEntity(pairs));
|
|
||||||
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
|
|
||||||
|
|
||||||
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
|
|
||||||
return EntityUtils.toString(response.getEntity());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasValidIccid(Device device) {
|
|
||||||
return device.getIccid() != null && !device.getIccid().trim().isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public SimCard CreateOrUpdateSimCard(Device device) {
|
|
||||||
SimCard simCard = simCardsMapper.queryByDeviceId(device.getDeviceId());
|
|
||||||
if (simCard == null) {
|
|
||||||
simCard = createNewSimCard(device);
|
|
||||||
}
|
|
||||||
return simCard;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SimCard createNewSimCard(Device device) {
|
|
||||||
SimCard newCard = new SimCard();
|
|
||||||
newCard.setDeviceid(device.getDeviceId());
|
|
||||||
newCard.setUpdatetime(new Date());
|
|
||||||
newCard.setIccid(device.getIccid());
|
|
||||||
newCard.setStatus(-1);
|
|
||||||
newCard.setMsisdn("");
|
|
||||||
newCard.setRemaining(BigDecimal.ZERO);
|
|
||||||
newCard.setUsed(BigDecimal.ZERO);
|
|
||||||
newCard.setTotal(BigDecimal.ZERO);
|
|
||||||
|
|
||||||
simCardsMapper.insert(newCard);
|
|
||||||
return newCard;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isValidResponse(BaseResponse<?> response) {
|
|
||||||
return response != null && response.getStatus() == 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -3,6 +3,7 @@ package com.imdroid.sideslope.service;
|
|||||||
import com.imdroid.secapi.dto.GnssCalcData;
|
import com.imdroid.secapi.dto.GnssCalcData;
|
||||||
import com.imdroid.secapi.dto.GnssStatus;
|
import com.imdroid.secapi.dto.GnssStatus;
|
||||||
import com.imdroid.secapi.dto.GnssStatusMsg;
|
import com.imdroid.secapi.dto.GnssStatusMsg;
|
||||||
|
import com.imdroid.secapi.dto.GnssTrxMsg;
|
||||||
import com.imdroid.sideslope.sal.Device;
|
import com.imdroid.sideslope.sal.Device;
|
||||||
|
|
||||||
public interface WarningService {
|
public interface WarningService {
|
||||||
|
|||||||
@ -12,8 +12,6 @@ import org.springframework.beans.factory.annotation.Value;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.RoundingMode;
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -67,7 +65,7 @@ public class WarningServiceImpl implements WarningService {
|
|||||||
isUpdated = true;
|
isUpdated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// b562少
|
// 无固定解少
|
||||||
if(check(status, WarningCfg.TYPE_LESS_B562,
|
if(check(status, WarningCfg.TYPE_LESS_B562,
|
||||||
WarningCfg.TYPE_NAME_LESS_B562,true,
|
WarningCfg.TYPE_NAME_LESS_B562,true,
|
||||||
device.getFixedNum(),null,
|
device.getFixedNum(),null,
|
||||||
@ -218,7 +216,7 @@ public class WarningServiceImpl implements WarningService {
|
|||||||
curStatus.setWarningcode(curStatus.getWarningcode() | warningType);
|
curStatus.setWarningcode(curStatus.getWarningcode() | warningType);
|
||||||
|
|
||||||
// 新告警出现后,生成对应设备的 warning 日志文件
|
// 新告警出现后,生成对应设备的 warning 日志文件
|
||||||
//generate_warning_logs(curStatus.getDeviceid(),warningType,warningName);
|
//generate_warning_logs(curStatus.getDeviceid(),warningType,auxInfo);
|
||||||
}
|
}
|
||||||
isUpdated = true;
|
isUpdated = true;
|
||||||
}
|
}
|
||||||
@ -261,152 +259,6 @@ public class WarningServiceImpl implements WarningService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
// 检查SIM卡状态
|
|
||||||
public void checkSimCardStatus(Device device, SimCard simCard) {
|
|
||||||
GnssStatus status = gnssStatusMapper.getByDeviceId(device.getDeviceId());
|
|
||||||
if (status == null) return;
|
|
||||||
|
|
||||||
boolean isUpdated = false;
|
|
||||||
|
|
||||||
// 检查SIM卡状态是否异常(停机、注销、失效)
|
|
||||||
if (simCard.getStatus() == SimCard.STATUS_SUSPENDED ||
|
|
||||||
simCard.getStatus() == SimCard.STATUS_CANCELLED ||
|
|
||||||
simCard.getStatus() == SimCard.STATUS_INVALID) {
|
|
||||||
|
|
||||||
String statusDesc;
|
|
||||||
switch(simCard.getStatus()) {
|
|
||||||
case SimCard.STATUS_SUSPENDED:
|
|
||||||
statusDesc = "停机";
|
|
||||||
break;
|
|
||||||
case SimCard.STATUS_CANCELLED:
|
|
||||||
statusDesc = "注销";
|
|
||||||
break;
|
|
||||||
case SimCard.STATUS_INVALID:
|
|
||||||
statusDesc = "失效";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
statusDesc = "未知状态";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (check(status, WarningCfg.TYPE_SIM_STATUS_ABNORMAL,
|
|
||||||
WarningCfg.TYPE_NAME_SIM_STATUS_ABNORMAL, false,
|
|
||||||
simCard.getStatus(), null,
|
|
||||||
"SIM卡状态: " + statusDesc)) {
|
|
||||||
isUpdated = true;
|
|
||||||
}
|
|
||||||
} else if (simCard.getStatus() == SimCard.STATUS_ACTIVATED) {
|
|
||||||
// 状态正常(已激活),清除告警
|
|
||||||
if ((status.getWarningcode() & WarningCfg.TYPE_SIM_STATUS_ABNORMAL) != 0) {
|
|
||||||
clearWarning(status, WarningCfg.TYPE_SIM_STATUS_ABNORMAL);
|
|
||||||
isUpdated = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isUpdated) {
|
|
||||||
status.setWarning(getWarningLevel(status.getWarningcode()));
|
|
||||||
gnssStatusMapper.updateById(status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkSimCardTraffic(Device device, SimCard simCard) {
|
|
||||||
GnssStatus status = gnssStatusMapper.getByDeviceId(device.getDeviceId());
|
|
||||||
if (status == null) return;
|
|
||||||
|
|
||||||
boolean isUpdated = false;
|
|
||||||
|
|
||||||
BigDecimal usedPercentage = simCard.getUsed()
|
|
||||||
.divide(simCard.getTotal(), 4, RoundingMode.HALF_UP)
|
|
||||||
.multiply(BigDecimal.valueOf(100));
|
|
||||||
|
|
||||||
// 检查流量使用情况
|
|
||||||
if (check(status, WarningCfg.TYPE_SIM_LOW_TRAFFIC,
|
|
||||||
WarningCfg.TYPE_NAME_SIM_LOW_TRAFFIC,
|
|
||||||
false, // 大于等于流量门限值,那么就报警
|
|
||||||
usedPercentage.intValue(),
|
|
||||||
null,
|
|
||||||
String.format("流量已使用 %.2f%%", usedPercentage.doubleValue()))) {
|
|
||||||
isUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isUpdated) {
|
|
||||||
status.setWarning(getWarningLevel(status.getWarningcode()));
|
|
||||||
gnssStatusMapper.updateById(status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// 检查SIM卡状态
|
|
||||||
public void checkSimCardStatus(Device device, SimCard simCard) {
|
|
||||||
GnssStatus status = gnssStatusMapper.getByDeviceId(device.getDeviceId());
|
|
||||||
if (status == null) return;
|
|
||||||
|
|
||||||
boolean isUpdated = false;
|
|
||||||
|
|
||||||
// 检查SIM卡状态是否异常(停机、注销、失效)
|
|
||||||
if (simCard.getStatus() == SimCard.STATUS_SUSPENDED ||
|
|
||||||
simCard.getStatus() == SimCard.STATUS_CANCELLED ||
|
|
||||||
simCard.getStatus() == SimCard.STATUS_INVALID) {
|
|
||||||
|
|
||||||
String statusDesc;
|
|
||||||
switch(simCard.getStatus()) {
|
|
||||||
case SimCard.STATUS_SUSPENDED:
|
|
||||||
statusDesc = "停机";
|
|
||||||
break;
|
|
||||||
case SimCard.STATUS_CANCELLED:
|
|
||||||
statusDesc = "注销";
|
|
||||||
break;
|
|
||||||
case SimCard.STATUS_INVALID:
|
|
||||||
statusDesc = "失效";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
statusDesc = "未知状态";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (check(status, WarningCfg.TYPE_SIM_STATUS_ABNORMAL,
|
|
||||||
WarningCfg.TYPE_NAME_SIM_STATUS_ABNORMAL, false,
|
|
||||||
simCard.getStatus(), null,
|
|
||||||
"SIM卡状态: " + statusDesc)) {
|
|
||||||
isUpdated = true;
|
|
||||||
}
|
|
||||||
} else if (simCard.getStatus() == SimCard.STATUS_ACTIVATED) {
|
|
||||||
// 状态正常(已激活),清除告警
|
|
||||||
if ((status.getWarningcode() & WarningCfg.TYPE_SIM_STATUS_ABNORMAL) != 0) {
|
|
||||||
clearWarning(status, WarningCfg.TYPE_SIM_STATUS_ABNORMAL);
|
|
||||||
isUpdated = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isUpdated) {
|
|
||||||
status.setWarning(getWarningLevel(status.getWarningcode()));
|
|
||||||
gnssStatusMapper.updateById(status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkSimCardTraffic(Device device, SimCard simCard) {
|
|
||||||
GnssStatus status = gnssStatusMapper.getByDeviceId(device.getDeviceId());
|
|
||||||
if (status == null) return;
|
|
||||||
|
|
||||||
boolean isUpdated = false;
|
|
||||||
|
|
||||||
BigDecimal usedPercentage = simCard.getUsed()
|
|
||||||
.divide(simCard.getTotal(), 4, RoundingMode.HALF_UP)
|
|
||||||
.multiply(BigDecimal.valueOf(100));
|
|
||||||
|
|
||||||
// 检查流量使用情况
|
|
||||||
if (check(status, WarningCfg.TYPE_SIM_LOW_TRAFFIC,
|
|
||||||
WarningCfg.TYPE_NAME_SIM_LOW_TRAFFIC,
|
|
||||||
false, // 大于等于流量门限值,那么就报警
|
|
||||||
usedPercentage.intValue(),
|
|
||||||
null,
|
|
||||||
String.format("流量已使用 %.2f%%", usedPercentage.doubleValue()))) {
|
|
||||||
isUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isUpdated) {
|
|
||||||
status.setWarning(getWarningLevel(status.getWarningcode()));
|
|
||||||
gnssStatusMapper.updateById(status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void generate_warning_logs(String device_id,int warning_type,String warning_type_name){
|
public void generate_warning_logs(String device_id,int warning_type,String warning_type_name){
|
||||||
// 连续无固定解 和 掉电 警告
|
// 连续无固定解 和 掉电 警告
|
||||||
@ -434,22 +286,9 @@ public class WarningServiceImpl implements WarningService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void checkFilteredResultJump(double[] latestRpos, GnssCalcData locationRecord){
|
public void checkFilteredResultJump(double[] latestRpos, GnssCalcData locationRecord){
|
||||||
int[] warningValuesXY = cfgMap.get(WarningCfg.TYPE_XY_JUMP);
|
if(Math.abs(locationRecord.getRpose()-latestRpos[0])>2 ||
|
||||||
int[] warningValuesZ = cfgMap.get(WarningCfg.TYPE_Z_JUMP);
|
Math.abs(locationRecord.getRposn()-latestRpos[1])>2 ||
|
||||||
int warningCode = 0;
|
Math.abs(locationRecord.getRposd()-latestRpos[2])>4){
|
||||||
if(warningValuesXY!=null){
|
|
||||||
if(Math.abs(locationRecord.getRpose()-latestRpos[0])>warningValuesXY[1] ||
|
|
||||||
Math.abs(locationRecord.getRposn()-latestRpos[1])>warningValuesXY[1]){
|
|
||||||
warningCode = WarningCfg.TYPE_XY_JUMP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(warningCode==0 && warningValuesZ!=null){
|
|
||||||
if(Math.abs(locationRecord.getRposd()-latestRpos[2])>warningValuesZ[1]){
|
|
||||||
warningCode = WarningCfg.TYPE_Z_JUMP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(warningCode!=0){
|
|
||||||
// 停止推送
|
// 停止推送
|
||||||
QueryWrapper<GnssDevice> queryWrapper = new QueryWrapper<>();
|
QueryWrapper<GnssDevice> queryWrapper = new QueryWrapper<>();
|
||||||
queryWrapper.eq("deviceid",locationRecord.getDeviceid());
|
queryWrapper.eq("deviceid",locationRecord.getDeviceid());
|
||||||
@ -461,13 +300,13 @@ public class WarningServiceImpl implements WarningService {
|
|||||||
!unFwdGroupName.equals(device.getFwd_group_id())){
|
!unFwdGroupName.equals(device.getFwd_group_id())){
|
||||||
device.setFwd_group_id(unFwdGroupName);
|
device.setFwd_group_id(unFwdGroupName);
|
||||||
device.setFwd_group_id2(unFwdGroupName);
|
device.setFwd_group_id2(unFwdGroupName);
|
||||||
//deviceMapper.updateById(device);
|
deviceMapper.updateById(device);
|
||||||
// 产生告警
|
// 产生告警
|
||||||
WarningMsg warningMsg = new WarningMsg();
|
WarningMsg warningMsg = new WarningMsg();
|
||||||
warningMsg.setDeviceid(device.getDeviceid());
|
warningMsg.setDeviceid(device.getDeviceid());
|
||||||
warningMsg.setTenantid(device.getTenantid());
|
warningMsg.setTenantid(device.getTenantid());
|
||||||
warningMsg.setCreatetime(LocalDateTime.now());
|
warningMsg.setCreatetime(LocalDateTime.now());
|
||||||
warningMsg.setCode(warningCode);
|
warningMsg.setCode(WarningCfg.TYPE_JUMP);
|
||||||
warningMsg.setLevel(WarningCfg.LEVEL_2);
|
warningMsg.setLevel(WarningCfg.LEVEL_2);
|
||||||
double deltaE = locationRecord.getRpose()-latestRpos[0];
|
double deltaE = locationRecord.getRpose()-latestRpos[0];
|
||||||
double deltaN = locationRecord.getRposn()-latestRpos[1];
|
double deltaN = locationRecord.getRposn()-latestRpos[1];
|
||||||
|
|||||||
@ -1,10 +0,0 @@
|
|||||||
package com.imdroid.sideslope.simcard;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class BaseResponse<T> {
|
|
||||||
private Integer status;
|
|
||||||
private String message;
|
|
||||||
private T data;
|
|
||||||
}
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
package com.imdroid.sideslope.simcard;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class CardDetailData {
|
|
||||||
private Integer operatortype;
|
|
||||||
private String activetime;
|
|
||||||
private String starttime;
|
|
||||||
private String stoptime;
|
|
||||||
private String silentdate;
|
|
||||||
private Integer status;
|
|
||||||
private String msisdn;
|
|
||||||
private String iccid;
|
|
||||||
private String imsi;
|
|
||||||
private Integer packageid;
|
|
||||||
private String packagename;
|
|
||||||
private String net;
|
|
||||||
|
|
||||||
private GprsInfo gprs;
|
|
||||||
private ApnInfo apn;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public static class GprsInfo {
|
|
||||||
private Double total;
|
|
||||||
private Double used;
|
|
||||||
private Double left;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public static class ApnInfo {
|
|
||||||
private String apnid;
|
|
||||||
private String status;
|
|
||||||
private String ip;
|
|
||||||
private String rat;
|
|
||||||
private String onoffstatus;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
package com.imdroid.sideslope.simcard;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class CardInfoData {
|
|
||||||
private String imsi;
|
|
||||||
private String msisdn;
|
|
||||||
private String iccid;
|
|
||||||
}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
package com.imdroid.sideslope.simcard;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class CardStatusData {
|
|
||||||
private Integer statusCode;
|
|
||||||
private String statusDesc;
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
package com.imdroid.sideslope.simcard;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class GprsData {
|
|
||||||
private Integer operatortype;
|
|
||||||
private List<GprsUsage> gps;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public static class GprsUsage {
|
|
||||||
private Double left;
|
|
||||||
private Double total;
|
|
||||||
private Double used;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 返回数据格式
|
|
||||||
// {
|
|
||||||
// "Status": 1,
|
|
||||||
// "Message": "Success",
|
|
||||||
// "Data": {
|
|
||||||
// "operatortype": 1,
|
|
||||||
// "GPS": [
|
|
||||||
// {
|
|
||||||
// "Left": "2023",
|
|
||||||
// "Total": "2.0",
|
|
||||||
// "Used": "25"
|
|
||||||
// }
|
|
||||||
// ]
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
public GprsUsage getFirstGprsUsage() {
|
|
||||||
if (gps != null && !gps.isEmpty()) {
|
|
||||||
return gps.get(0);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,209 +0,0 @@
|
|||||||
package com.imdroid.sideslope.task;
|
|
||||||
|
|
||||||
import com.alibaba.excel.util.StringUtils;
|
|
||||||
import com.imdroid.common.util.ThreadManager;
|
|
||||||
import com.imdroid.secapi.dto.*;
|
|
||||||
import com.imdroid.sideslope.sal.Device;
|
|
||||||
import com.imdroid.sideslope.sal.DeviceService;
|
|
||||||
import com.imdroid.sideslope.service.SimCardQueryServiceImpl;
|
|
||||||
import com.imdroid.sideslope.service.WarningServiceImpl;
|
|
||||||
import com.imdroid.sideslope.simcard.BaseResponse;
|
|
||||||
import com.imdroid.sideslope.simcard.CardInfoData;
|
|
||||||
import com.imdroid.sideslope.simcard.CardStatusData;
|
|
||||||
import com.imdroid.sideslope.simcard.GprsData;
|
|
||||||
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 javax.annotation.Resource;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
@Configuration
|
|
||||||
@EnableScheduling
|
|
||||||
public class SimStatusChecker {
|
|
||||||
// SIM 卡流量和状态查询定时任务
|
|
||||||
// 1. 每小时任务
|
|
||||||
// a. 通过CardInfo 检查 iccid 和 sim卡号
|
|
||||||
// b. 通过QueryCardStatus 检查SIM卡当前的状态
|
|
||||||
// 2. 每两小时任务
|
|
||||||
// a. QueryGprs 检查 SIM 流量
|
|
||||||
final Logger logger = LoggerFactory.getLogger(SimStatusChecker.class);
|
|
||||||
@Autowired
|
|
||||||
private GnssStatusMapper gnssStatusMapper;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private WarningServiceImpl warningService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private SimCardsMapper simCardsMapper;
|
|
||||||
@Resource(name = "local")
|
|
||||||
private DeviceService deviceService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private SimCardQueryServiceImpl simCardQueryServiceImpl;
|
|
||||||
|
|
||||||
// 每小时执行一次状态检查调度
|
|
||||||
@Scheduled(cron = "0 0 * * * ?")
|
|
||||||
//@Scheduled(cron = "0 */10 * * * ?")
|
|
||||||
private void scheduleSimCardStatusCheck() {
|
|
||||||
List<GnssStatusJoin> onlineDevices = gnssStatusMapper.queryOnline();
|
|
||||||
logger.info("当前在线设备数量: {}", onlineDevices.size());
|
|
||||||
|
|
||||||
for (GnssStatusJoin onlineDevice : onlineDevices) {
|
|
||||||
int delay = Math.abs(onlineDevice.getDeviceid().hashCode() % 3600 );
|
|
||||||
logger.info("- 设备: {}, SIM状态查询,延迟执行: {}秒", onlineDevice.getDeviceid(), delay);
|
|
||||||
|
|
||||||
ThreadManager.getScheduledThreadPool().schedule(
|
|
||||||
() -> checkDeviceSimCardStatus(onlineDevice.getDeviceid()),
|
|
||||||
delay,
|
|
||||||
TimeUnit.SECONDS
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 每两小时执行一次流量检查调度
|
|
||||||
@Scheduled(cron = "0 0 0/2 * * ?")
|
|
||||||
private void scheduleSimCardTrafficCheck() {
|
|
||||||
List<GnssStatusJoin> onlineDevices = gnssStatusMapper.queryOnline();
|
|
||||||
logger.info("当前在线设备数量: {}", onlineDevices.size());
|
|
||||||
|
|
||||||
for (GnssStatusJoin onlineDevice : onlineDevices) {
|
|
||||||
int delay = Math.abs(onlineDevice.getDeviceid().hashCode() % 7200);
|
|
||||||
logger.debug("- 设备: {}, SIM流量查询,延迟执行: {}秒", onlineDevice.getDeviceid(), delay);
|
|
||||||
|
|
||||||
ThreadManager.getScheduledThreadPool().schedule(
|
|
||||||
() -> checkDeviceSimCardTraffic(onlineDevice.getDeviceid()),
|
|
||||||
delay,
|
|
||||||
TimeUnit.SECONDS
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkDeviceSimCardStatus(String deviceId) {
|
|
||||||
try {
|
|
||||||
Device device = deviceService.findByDeviceId(deviceId);
|
|
||||||
// 不允许尚未从自检得到 ICCID 的设备参加 SIM 卡状态查询
|
|
||||||
if (!simCardQueryServiceImpl.hasValidIccid(device)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// SimCards 表中没有数据就初始化,这其实说明它在自检中刚获得属于自己的 ICCID 号
|
|
||||||
SimCard simCard = simCardQueryServiceImpl.CreateOrUpdateSimCard(device);
|
|
||||||
updateSimCardInfo(device, simCard);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("设备{}状态查询失败: ", deviceId, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkDeviceSimCardTraffic(String deviceId) {
|
|
||||||
try {
|
|
||||||
Device device = deviceService.findByDeviceId(deviceId);
|
|
||||||
// 不允许尚未从自检得到 ICCID 的设备参加 SIM 卡状态查询
|
|
||||||
if (!simCardQueryServiceImpl.hasValidIccid(device)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// SimCards 表中没有数据就初始化,这说明它在自检中获得属于自己的 ICCID 号
|
|
||||||
SimCard simCard = simCardQueryServiceImpl.CreateOrUpdateSimCard(device);
|
|
||||||
// 如果该卡状态不是已激活,而是其他状态,那么不运行它参与 SIM 卡流量检测
|
|
||||||
if(simCard.getStatus() != SimCard.STATUS_ACTIVATED){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
updateSimCardTrafficFromAPI(device, simCard);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("设备{}查询失败: ", deviceId, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateSimCardInfo(Device device, SimCard simCard) throws Exception {
|
|
||||||
// 自检中只是获取保存了设备的 ICCID ,所有如果判断如果没有 MSISDN,先更新基本信息
|
|
||||||
if (StringUtils.isBlank(simCard.getMsisdn())) {
|
|
||||||
updateSimCardBasicInfoFromAPI(device, simCard);
|
|
||||||
}
|
|
||||||
// 更新状态
|
|
||||||
updateSimCardStatusFromAPI(device, simCard);
|
|
||||||
}
|
|
||||||
private void updateSimCardBasicInfoFromAPI(Device device, SimCard simCard) {
|
|
||||||
try {
|
|
||||||
BaseResponse<CardInfoData> response = simCardQueryServiceImpl.queryCardInfo(device);
|
|
||||||
if (!simCardQueryServiceImpl.isValidResponse(response)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CardInfoData info = response.getData();
|
|
||||||
simCard.setUpdatetime(new Date());
|
|
||||||
simCard.setMsisdn(info.getMsisdn());
|
|
||||||
simCardsMapper.updateSimCardInfo(simCard);
|
|
||||||
|
|
||||||
logger.info("更新SIM卡基本信息 - imsi: {}, msisdn: {}, iccid: {}",
|
|
||||||
info.getImsi(), info.getMsisdn(), info.getIccid());
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("更新设备{}的SIM卡基本信息失败: ", device.getDeviceId(), e);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private void updateSimCardStatusFromAPI(Device device, SimCard simCard) {
|
|
||||||
try {
|
|
||||||
BaseResponse<CardStatusData> response = simCardQueryServiceImpl.queryCardStatus(device);
|
|
||||||
if (!simCardQueryServiceImpl.isValidResponse(response)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
CardStatusData status = response.getData();
|
|
||||||
simCard.setUpdatetime(new Date());
|
|
||||||
simCard.setStatus(status.getStatusCode());
|
|
||||||
simCardsMapper.updateCardStatusInfo(simCard);
|
|
||||||
|
|
||||||
warningService.checkSimCardStatus(device, simCard);
|
|
||||||
|
|
||||||
logger.info("更新SIM卡状态 - Code: {}, 描述: {}",
|
|
||||||
status.getStatusCode(), status.getStatusDesc());
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("更新设备{}的SIM卡状态失败: ", device.getDeviceId(), e);
|
|
||||||
// throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateSimCardTrafficFromAPI(Device device, SimCard simCard) {
|
|
||||||
try {
|
|
||||||
BaseResponse<GprsData> response = simCardQueryServiceImpl.queryGprs(device);
|
|
||||||
if (!simCardQueryServiceImpl.isValidResponse(response)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
GprsData gprsData = response.getData();
|
|
||||||
GprsData.GprsUsage usage = gprsData.getFirstGprsUsage();
|
|
||||||
if (usage == null) {
|
|
||||||
logger.warn("无可用流量数据查询, deviceId: {}", device.getDeviceId());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
simCard.setUpdatetime(new Date());
|
|
||||||
simCard.setRemaining(BigDecimal.valueOf(usage.getLeft()));
|
|
||||||
simCard.setUsed(BigDecimal.valueOf(usage.getUsed()));
|
|
||||||
simCard.setTotal(BigDecimal.valueOf(usage.getTotal()));
|
|
||||||
simCardsMapper.updateCardTrafficInfo(simCard);
|
|
||||||
|
|
||||||
warningService.checkSimCardTraffic(device, simCard);
|
|
||||||
|
|
||||||
logger.info("更新流量信息成功 - deviceId: {}, 剩余: {}MB, 总量: {}MB, 已用: {}MB",
|
|
||||||
device.getIccid(),
|
|
||||||
simCard.getRemaining(),
|
|
||||||
simCard.getTotal(),
|
|
||||||
simCard.getUsed());
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("设备{}更新SIM卡流量失败: ", device.getDeviceId(), e);
|
|
||||||
//throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -59,9 +59,6 @@ public class APIController extends BasicController{
|
|||||||
//转成字符串
|
//转成字符串
|
||||||
String dtuAck = configAck.substring(9*2);
|
String dtuAck = configAck.substring(9*2);
|
||||||
rxInfo += configAck+"("+HexUtil.HexString2String(dtuAck)+")";
|
rxInfo += configAck+"("+HexUtil.HexString2String(dtuAck)+")";
|
||||||
|
|
||||||
// 检查是否需要更新 ICCID
|
|
||||||
updateICCID(device,dtuAck);
|
|
||||||
}
|
}
|
||||||
else if(msgType == 0xd313&&configAck.length()>=100){
|
else if(msgType == 0xd313&&configAck.length()>=100){
|
||||||
//转成字符串
|
//转成字符串
|
||||||
@ -195,18 +192,4 @@ public class APIController extends BasicController{
|
|||||||
msgMapper.insert(gnssMsg);
|
msgMapper.insert(gnssMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateICCID(GnssDevice device, String dtuAck) {
|
|
||||||
// 只检查 "ICCID:" 的十六进制部分
|
|
||||||
if(!dtuAck.contains("49434349443a")){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String content = HexUtil.HexString2String(dtuAck);
|
|
||||||
if(content.contains("+ICCID:")){
|
|
||||||
System.out.println(content);
|
|
||||||
String iccid = content.substring(content.indexOf("+ICCID:") + 8).trim();
|
|
||||||
iccid = iccid.split("\r\n")[0].trim();
|
|
||||||
device.setIccid(iccid);
|
|
||||||
deviceMapper.updateById(device);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,6 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
|||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
import java.awt.*;
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
@ -55,44 +54,6 @@ public class GnssCalcDataController extends BasicController implements CommonExc
|
|||||||
return "/page/gnss_data_calc";
|
return "/page/gnss_data_calc";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ResponseBody
|
|
||||||
@RequestMapping("/page/gnssUpdateEnabled")
|
|
||||||
public String gnssUpdateEnabled(HttpSession session, HttpServletRequest request) {
|
|
||||||
try {
|
|
||||||
String deviceId = request.getParameter("deviceid");
|
|
||||||
String createTimeStr = request.getParameter("createtime");
|
|
||||||
String enabledStr = request.getParameter("enabled");
|
|
||||||
|
|
||||||
if (deviceId == null || createTimeStr == null || enabledStr == null) {
|
|
||||||
return "数据无效";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 转换为Boolean类型
|
|
||||||
Boolean enabled = "1".equals(enabledStr);
|
|
||||||
|
|
||||||
GnssCalcData updateData = new GnssCalcData();
|
|
||||||
updateData.setEnabled(enabled); // 使用Boolean类型
|
|
||||||
updateData.setUpdatetime(LocalDateTime.now());
|
|
||||||
|
|
||||||
QueryWrapper<GnssCalcData> queryWrapper = new QueryWrapper<>();
|
|
||||||
queryWrapper.eq("deviceid", deviceId)
|
|
||||||
.eq("createtime", createTimeStr);
|
|
||||||
|
|
||||||
int result = dataMapper.update(updateData, queryWrapper);
|
|
||||||
System.out.println(result);
|
|
||||||
|
|
||||||
if (result > 0) {
|
|
||||||
return "success";
|
|
||||||
} else {
|
|
||||||
return "更新失败";
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return "更新过程中发生错误: " + e.getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**** 推送数据 *****/
|
/**** 推送数据 *****/
|
||||||
@RequestMapping("/gnss/data/list_calc")
|
@RequestMapping("/gnss/data/list_calc")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
|
|||||||
@ -24,7 +24,6 @@ import javax.servlet.http.HttpSession;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class GnssDeviceController extends BasicController{
|
public class GnssDeviceController extends BasicController{
|
||||||
@ -116,11 +115,6 @@ public class GnssDeviceController extends BasicController{
|
|||||||
if (StringUtils.hasText(parentid)) {
|
if (StringUtils.hasText(parentid)) {
|
||||||
queryWrapper.like("parentid", parentid);
|
queryWrapper.like("parentid", parentid);
|
||||||
}
|
}
|
||||||
//备选基站
|
|
||||||
String parentid1 = search.getString("parentid1");
|
|
||||||
if (StringUtils.hasText(parentid1)){
|
|
||||||
queryWrapper.like("parentid1", parentid1);
|
|
||||||
}
|
|
||||||
//项目号
|
//项目号
|
||||||
String project_id = search.getString("project_id");
|
String project_id = search.getString("project_id");
|
||||||
if (StringUtils.hasText(project_id)) {
|
if (StringUtils.hasText(project_id)) {
|
||||||
@ -129,9 +123,7 @@ public class GnssDeviceController extends BasicController{
|
|||||||
//所属组织
|
//所属组织
|
||||||
String tenantname = search.getString("tenantname");
|
String tenantname = search.getString("tenantname");
|
||||||
if (StringUtils.hasText(tenantname)) {
|
if (StringUtils.hasText(tenantname)) {
|
||||||
if(tenantname.startsWith("非SAAS"))
|
queryWrapper.like("tenantname", tenantname);
|
||||||
queryWrapper.ne("tenantname",Tenant.SAAS_PROVIDER_NAME);
|
|
||||||
else queryWrapper.like("tenantname", tenantname);
|
|
||||||
}
|
}
|
||||||
//设备类型
|
//设备类型
|
||||||
Integer devicetype = search.getInteger("devicetype");
|
Integer devicetype = search.getInteger("devicetype");
|
||||||
@ -214,9 +206,7 @@ public class GnssDeviceController extends BasicController{
|
|||||||
OpLogManager.OP_OBJ_DEVICE,
|
OpLogManager.OP_OBJ_DEVICE,
|
||||||
device.getDeviceid() + " update: " + diff);
|
device.getDeviceid() + " update: " + diff);
|
||||||
device.setUpdatetime(LocalDateTime.now());
|
device.setUpdatetime(LocalDateTime.now());
|
||||||
if(!old_device.getGroup_id().equals(device.getGroup_id())||
|
if(!old_device.getGroup_id().equals(device.getGroup_id())){
|
||||||
!old_device.getParentid().equals(device.getParentid())||
|
|
||||||
!Objects.equals(old_device.getParentid1(),device.getParentid1())){
|
|
||||||
device.setSyn(false);
|
device.setSyn(false);
|
||||||
}
|
}
|
||||||
num = gnssDeviceMapper.updateById(device);
|
num = gnssDeviceMapper.updateById(device);
|
||||||
@ -237,7 +227,7 @@ public class GnssDeviceController extends BasicController{
|
|||||||
} else {
|
} else {
|
||||||
// 更新组参数的关联个数
|
// 更新组参数的关联个数
|
||||||
updateBasicGroupAssociatedNum(device,old_device);
|
updateBasicGroupAssociatedNum(device,old_device);
|
||||||
rtcmClient.deviceParamChanged(device.getDeviceid(), device.getParentid(), device.getParentid1());
|
rtcmClient.deviceParamChanged(device.getDeviceid(), device.getParentid());
|
||||||
return HttpResult.ok();
|
return HttpResult.ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -359,7 +349,7 @@ public class GnssDeviceController extends BasicController{
|
|||||||
if (num == 0) {
|
if (num == 0) {
|
||||||
return HttpResult.failed();
|
return HttpResult.failed();
|
||||||
} else{
|
} else{
|
||||||
rtcmClient.deviceParamChanged(del_id, null, null);
|
rtcmClient.deviceParamChanged(del_id, null);
|
||||||
return HttpResult.ok();
|
return HttpResult.ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,213 +0,0 @@
|
|||||||
package com.imdroid.beidou.controller;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONArray;
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
||||||
import com.imdroid.beidou.common.Role;
|
|
||||||
import com.imdroid.beidou.service.CommonExcelService;
|
|
||||||
import com.imdroid.secapi.dto.*;
|
|
||||||
import org.apache.http.HttpEntity;
|
|
||||||
import org.apache.http.util.EntityUtils;
|
|
||||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
|
||||||
import org.apache.http.client.methods.HttpGet;
|
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
|
||||||
import org.apache.http.impl.client.HttpClients;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.ui.Model;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import javax.servlet.http.HttpSession;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
@Controller
|
|
||||||
public class SimCardController extends BasicController {
|
|
||||||
// TODO:这里的常量应该写入 application.properties
|
|
||||||
private static final String BASE_URL = "http://120.78.169.220:8089";
|
|
||||||
private static final String USERNAME = "gzyzdz";
|
|
||||||
private static final String KEY = "632629d1269a202c9d49a574623e4e4c";
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private SimCardsMapper simCardsMapper;
|
|
||||||
|
|
||||||
@RequestMapping("/page/sim_status")
|
|
||||||
public String simStatus(Model m, HttpSession session) {
|
|
||||||
initModel(m, session);
|
|
||||||
|
|
||||||
return "/page/sim_status";
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping("/sim/list")
|
|
||||||
@ResponseBody
|
|
||||||
public JSONObject list(HttpSession session,
|
|
||||||
int page,
|
|
||||||
int limit,
|
|
||||||
String searchType,
|
|
||||||
String searchContent,
|
|
||||||
Integer status) {
|
|
||||||
Page<SimCard> pageable = new Page<>(page, limit);
|
|
||||||
|
|
||||||
QueryWrapper<SimCard> queryWrapper = new QueryWrapper<>();
|
|
||||||
|
|
||||||
|
|
||||||
if (!StringUtils.isEmpty(searchContent)) {
|
|
||||||
switch(searchType) {
|
|
||||||
case "deviceId":
|
|
||||||
queryWrapper.like("deviceid", searchContent.trim());
|
|
||||||
break;
|
|
||||||
case "iccid":
|
|
||||||
queryWrapper.like("iccid", searchContent.trim());
|
|
||||||
break;
|
|
||||||
case "simNumber":
|
|
||||||
queryWrapper.like("msisdn", searchContent.trim());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (status != null) {
|
|
||||||
queryWrapper.eq("status", status);
|
|
||||||
}
|
|
||||||
|
|
||||||
queryWrapper.orderByDesc("updatetime");
|
|
||||||
IPage<SimCard> cs = simCardsMapper.selectPage(pageable, queryWrapper);
|
|
||||||
|
|
||||||
JSONObject jsonObject = new JSONObject();
|
|
||||||
jsonObject.put("code", 0);
|
|
||||||
jsonObject.put("msg", "");
|
|
||||||
jsonObject.put("count", cs.getTotal());
|
|
||||||
jsonObject.put("data", cs.getRecords());
|
|
||||||
System.out.println(jsonObject.toString());
|
|
||||||
return jsonObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping("/page/sim_traffic_query")
|
|
||||||
public String simTrafficQuery(Model m, HttpSession session) {
|
|
||||||
initModel(m, session);
|
|
||||||
|
|
||||||
return "/page/sim_traffic_query";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 代理转发
|
|
||||||
@RequestMapping("/api/proxy/sim/query")
|
|
||||||
@ResponseBody
|
|
||||||
public JSONObject proxySimQuery(
|
|
||||||
@RequestParam String type,
|
|
||||||
@RequestParam String content
|
|
||||||
){
|
|
||||||
CloseableHttpClient httpClient = null;
|
|
||||||
CloseableHttpResponse response = null;
|
|
||||||
try {
|
|
||||||
Map<String, String> params = new HashMap<>();
|
|
||||||
params.put("username", USERNAME);
|
|
||||||
params.put("key", KEY);
|
|
||||||
|
|
||||||
switch(type) {
|
|
||||||
case "iccid":
|
|
||||||
params.put("card", content);
|
|
||||||
break;
|
|
||||||
case "deviceId":
|
|
||||||
if (content.trim().isEmpty()) {
|
|
||||||
throw new IllegalArgumentException("设备ID不能为空");
|
|
||||||
}
|
|
||||||
SimCard simCard = simCardsMapper.queryByDeviceId(content.trim());
|
|
||||||
if (simCard == null) {
|
|
||||||
throw new IllegalArgumentException("未找到该设备ID对应的SIM卡信息");
|
|
||||||
}
|
|
||||||
params.put("card", simCard.getIccid());
|
|
||||||
break;
|
|
||||||
case "simNumber":
|
|
||||||
params.put("card", content);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("无效的查询类型: " + type);
|
|
||||||
}
|
|
||||||
|
|
||||||
params.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
|
|
||||||
|
|
||||||
String signature = calculateSignature(params);
|
|
||||||
if (signature == null) {
|
|
||||||
throw new Exception("签名计算失败");
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder urlBuilder = new StringBuilder(BASE_URL);
|
|
||||||
urlBuilder.append("/api/Service/QueryCard?");
|
|
||||||
urlBuilder.append("username=").append(USERNAME);
|
|
||||||
urlBuilder.append("&key=").append(KEY);
|
|
||||||
urlBuilder.append("&card=").append(params.get("card"));
|
|
||||||
urlBuilder.append("×tamp=").append(params.get("timestamp"));
|
|
||||||
urlBuilder.append("&signature=").append(signature);
|
|
||||||
|
|
||||||
httpClient = HttpClients.createDefault();
|
|
||||||
HttpGet httpGet = new HttpGet(urlBuilder.toString());
|
|
||||||
|
|
||||||
// System.out.println("Sending request: " + urlBuilder.toString());
|
|
||||||
response = httpClient.execute(httpGet);
|
|
||||||
HttpEntity entity = response.getEntity();
|
|
||||||
|
|
||||||
|
|
||||||
String result = EntityUtils.toString(entity);
|
|
||||||
// System.out.println("Received response: " + result);
|
|
||||||
|
|
||||||
return JSONObject.parseObject(result);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
// System.out.println("Query failed: " + e.getMessage());
|
|
||||||
JSONObject errorResponse = new JSONObject();
|
|
||||||
errorResponse.put("Status", 0);
|
|
||||||
errorResponse.put("Message", "查询失败: " + e.getMessage());
|
|
||||||
return errorResponse;
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (response != null) {
|
|
||||||
response.close();
|
|
||||||
}
|
|
||||||
if (httpClient != null) {
|
|
||||||
httpClient.close();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String calculateSignature(Map<String, String> params) {
|
|
||||||
try {
|
|
||||||
List<String> paramList = new ArrayList<>();
|
|
||||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
|
||||||
paramList.add(entry.getKey() + "=" + entry.getValue());
|
|
||||||
}
|
|
||||||
Collections.sort(paramList);
|
|
||||||
|
|
||||||
String paramString = String.join("&", paramList);
|
|
||||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
|
||||||
byte[] digest = md.digest(paramString.getBytes());
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
for (byte b : digest) {
|
|
||||||
sb.append(String.format("%02x", b));
|
|
||||||
}
|
|
||||||
String signature = sb.toString();
|
|
||||||
// System.out.println("Signature: " + signature);
|
|
||||||
return signature;
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
//System.out.println("Signature: " + e.getMessage());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@ -47,14 +47,6 @@ public class WarningController extends BasicController implements CommonExcelSer
|
|||||||
warningMap.put(WarningCfg.TYPE_LOW_RSSI, WarningCfg.TYPE_NAME_LOW_RSSI);
|
warningMap.put(WarningCfg.TYPE_LOW_RSSI, WarningCfg.TYPE_NAME_LOW_RSSI);
|
||||||
warningMap.put(WarningCfg.TYPE_RX_MUCH_UNKNOWN, WarningCfg.TYPE_NAME_RX_MUCH_UNKNOWN);
|
warningMap.put(WarningCfg.TYPE_RX_MUCH_UNKNOWN, WarningCfg.TYPE_NAME_RX_MUCH_UNKNOWN);
|
||||||
warningMap.put(WarningCfg.TYPE_INCLINE, WarningCfg.TYPE_NAME_INCLINE);
|
warningMap.put(WarningCfg.TYPE_INCLINE, WarningCfg.TYPE_NAME_INCLINE);
|
||||||
warningMap.put(WarningCfg.TYPE_SIM_LOW_TRAFFIC, WarningCfg.TYPE_NAME_SIM_LOW_TRAFFIC);
|
|
||||||
warningMap.put(WarningCfg.TYPE_SIM_STATUS_ABNORMAL, WarningCfg.TYPE_NAME_SIM_STATUS_ABNORMAL);
|
|
||||||
|
|
||||||
|
|
||||||
warningMap.put(WarningCfg.TYPE_SIM_LOW_TRAFFIC, WarningCfg.TYPE_NAME_SIM_LOW_TRAFFIC);
|
|
||||||
warningMap.put(WarningCfg.TYPE_SIM_STATUS_ABNORMAL, WarningCfg.TYPE_NAME_SIM_STATUS_ABNORMAL);
|
|
||||||
warningMap.put(WarningCfg.TYPE_XY_JUMP, WarningCfg.TYPE_NAME_XY_JUMP);
|
|
||||||
warningMap.put(WarningCfg.TYPE_Z_JUMP, WarningCfg.TYPE_NAME_Z_JUMP);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**** 推送页面 *****/
|
/**** 推送页面 *****/
|
||||||
|
|||||||
@ -43,7 +43,6 @@ public class DeviceStatusChecker {
|
|||||||
@Autowired
|
@Autowired
|
||||||
GnssDeviceMapper deviceMapper;
|
GnssDeviceMapper deviceMapper;
|
||||||
|
|
||||||
|
|
||||||
static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
@Scheduled(cron = "0 18,48 * * * ?") // 每半时执行一次
|
@Scheduled(cron = "0 18,48 * * * ?") // 每半时执行一次
|
||||||
|
|||||||
@ -68,7 +68,6 @@ CREATE TABLE IF NOT EXISTS `gnssdevices` (
|
|||||||
`imei` varchar(16) DEFAULT NULL,
|
`imei` varchar(16) DEFAULT NULL,
|
||||||
`model` smallint DEFAULT 0,
|
`model` smallint DEFAULT 0,
|
||||||
`loggingmode` smallint DEFAULT 0 COMMENT '日志模式: 0-精简模式(仅D3F0和D3F2), 1-完整模式',
|
`loggingmode` smallint DEFAULT 0 COMMENT '日志模式: 0-精简模式(仅D3F0和D3F2), 1-完整模式',
|
||||||
`iccid` VARCHAR(36) DEFAULT NULL COMMENT 'ICCID号,唯一',
|
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
@ -79,7 +78,6 @@ CREATE TABLE IF NOT EXISTS `gnssgroup` (
|
|||||||
`active_time` int DEFAULT 6,
|
`active_time` int DEFAULT 6,
|
||||||
`active_offset` int DEFAULT 0,
|
`active_offset` int DEFAULT 0,
|
||||||
`rs_adv` smallint DEFAULT 0,
|
`rs_adv` smallint DEFAULT 0,
|
||||||
`gnss_sample_s` smallint DEFAULT 1,
|
|
||||||
`power_mode` smallint DEFAULT 0,
|
`power_mode` smallint DEFAULT 0,
|
||||||
`device_num` int DEFAULT 0,
|
`device_num` int DEFAULT 0,
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
@ -217,6 +215,7 @@ CREATE TABLE IF NOT EXISTS `gnsstrxmsg` (
|
|||||||
`uart2unknown` int DEFAULT NULL,
|
`uart2unknown` int DEFAULT NULL,
|
||||||
`b562bytes` int DEFAULT NULL,
|
`b562bytes` int DEFAULT NULL,
|
||||||
`d3xxbytes` int DEFAULT NULL,
|
`d3xxbytes` int DEFAULT NULL,
|
||||||
|
`b562count` int DEFAULT NULL,
|
||||||
`satelliteinuse` int DEFAULT 0,
|
`satelliteinuse` int DEFAULT 0,
|
||||||
`fixnum` int DEFAULT NULL,
|
`fixnum` int DEFAULT NULL,
|
||||||
`floatnum` int DEFAULT NULL,
|
`floatnum` int DEFAULT NULL,
|
||||||
@ -328,43 +327,20 @@ CREATE TABLE IF NOT EXISTS `ApiKey` (
|
|||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
/***
|
|
||||||
GNSS 单次解记录表
|
|
||||||
*/
|
|
||||||
CREATE TABLE IF NOT EXISTS `gnssdevicesinglerecords` (
|
CREATE TABLE IF NOT EXISTS `gnssdevicesinglerecords` (
|
||||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||||
`deviceid` varchar(64) NOT NULL COMMENT '设备ID',
|
`deviceid` varchar(64) NOT NULL COMMENT '设备ID',
|
||||||
`createtime` datetime(3) NOT NULL COMMENT '创建时间',
|
`createtime` datetime(3) NOT NULL COMMENT '创建时间',
|
||||||
`model` smallint NOT NULL COMMENT '设备型号: 0-F9P(G505), 1-博通(G510)',
|
`model` smallint NOT NULL COMMENT '设备型号: 0-F9P(G505), 1-博通(G510)',
|
||||||
`x` double NOT NULL COMMENT 'GGA时是latitude, ECEF时是x',
|
`x` double NOT NULL COMMENT 'GGA时是latitude, ECEF时是x',
|
||||||
`y` double NOT NULL COMMENT 'GGA时是longitude, ECEF时是y',
|
`y` double NOT NULL COMMENT 'GGA时是longitude, ECEF时是y',
|
||||||
`z` double NOT NULL COMMENT 'GGA时是altitude, ECEF时是z',
|
`z` double NOT NULL COMMENT 'GGA时是altitude, ECEF时是z',
|
||||||
`status` int NOT NULL DEFAULT '0' COMMENT 'GGA: 0初始化,1单点定位,2码差分,3无效PPS,4固定解,5浮点解,6估算,7人工固定,8模拟,9WAAS差分; ECEF: 0无B562,1浮点解,2固定解',
|
`status` int NOT NULL DEFAULT '0' COMMENT 'GGA: 0初始化,1单点定位,2码差分,3无效PPS,4固定解,5浮点解,6估算,7人工固定,8模拟,9WAAS差分; ECEF: 0无B562,1浮点解,2固定解',
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
KEY `idx_deviceid_createtime` (`deviceid`,`createtime`),
|
KEY `idx_deviceid_createtime` (`deviceid`,`createtime`),
|
||||||
KEY `idx_createtime` (`createtime`)
|
KEY `idx_createtime` (`createtime`)
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT='GNSS单次解算记录表';
|
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT='GNSS单次解算记录表';
|
||||||
|
|
||||||
/***
|
|
||||||
SIM卡记录表
|
|
||||||
*/
|
|
||||||
CREATE TABLE IF NOT EXISTS `simcards` (
|
|
||||||
`id` INT NOT NULL AUTO_INCREMENT COMMENT '主键,自增,唯一',
|
|
||||||
`updatetime` DATETIME DEFAULT NULL COMMENT '最新一次查询接口记录的时间',
|
|
||||||
`iccid` VARCHAR(36) NOT NULL COMMENT 'ICCID号,唯一',
|
|
||||||
`msisd` VARCHAR(20) NOT NULL COMMENT '物联卡号码,SIM号,唯一',
|
|
||||||
`deviceid` VARCHAR(20) DEFAULT NULL COMMENT '设备ID号',
|
|
||||||
`status` TINYINT DEFAULT -1 COMMENT 'SIM卡状态(-1:未知, 1:待激活, 2:已激活, 3:停机, 4:注销, 5:库存, 6:可测试, 7:失效, 99:号码不存在)',
|
|
||||||
`remaining` DECIMAL(10,2) DEFAULT 0.00 COMMENT '剩余流量,单位为MB,保留两位小数',
|
|
||||||
`total` DECIMAL(10,2) DEFAULT 0.00 COMMENT '总流量,单位为MB,保留两位小数',
|
|
||||||
`used` DECIMAL(10,2) DEFAULT 0.00 COMMENT '已用流量,单位为MB,保留两位小数',
|
|
||||||
PRIMARY KEY (`id`),
|
|
||||||
UNIQUE KEY `uk_iccid` (`iccid`),
|
|
||||||
UNIQUE KEY `uk_msisd` (`msisd`),
|
|
||||||
INDEX `idx_deviceid` (`deviceid`),
|
|
||||||
INDEX `idx_status` (`status`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='SIM卡信息表';
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `ehm` (
|
CREATE TABLE IF NOT EXISTS `ehm` (
|
||||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||||
`tenantid` int DEFAULT 0,
|
`tenantid` int DEFAULT 0,
|
||||||
|
|||||||
@ -117,26 +117,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"title": "SIM卡管理",
|
|
||||||
"href": "",
|
|
||||||
"icon": "fa fa-signal",
|
|
||||||
"target": "_self",
|
|
||||||
"child": [
|
|
||||||
{
|
|
||||||
"title": "总览",
|
|
||||||
"href": "page/sim_status",
|
|
||||||
"icon": "fa fa-minus",
|
|
||||||
"target": "_self"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"title": "卡信息查询",
|
|
||||||
"href": "page/sim_traffic_query",
|
|
||||||
"icon": "fa fa-minus",
|
|
||||||
"target": "_self"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"title": "数据推送",
|
"title": "数据推送",
|
||||||
"href": "",
|
"href": "",
|
||||||
|
|||||||
@ -93,26 +93,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"title": "SIM卡管理",
|
|
||||||
"href": "",
|
|
||||||
"icon": "fa fa-signal",
|
|
||||||
"target": "_self",
|
|
||||||
"child": [
|
|
||||||
{
|
|
||||||
"title": "总览",
|
|
||||||
"href": "page/sim_status",
|
|
||||||
"icon": "fa fa-minus",
|
|
||||||
"target": "_self"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"title": "卡信息查询",
|
|
||||||
"href": "page/sim_traffic_query",
|
|
||||||
"icon": "fa fa-minus",
|
|
||||||
"target": "_self"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"title": "数据推送",
|
"title": "数据推送",
|
||||||
"href": "",
|
"href": "",
|
||||||
|
|||||||
@ -97,11 +97,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script type="text/html" id="currentTableBar">
|
<script type="text/html" id="currentTableBar">
|
||||||
<a class="layui-btn layui-btn-normal layui-btn-xs data-count-edit" lay-event="edit">状态修改</a>
|
<a class="layui-btn layui-btn-normal layui-btn-xs data-count-edit" lay-event="cmd">命令行</a>
|
||||||
<!-- <a class="layui-btn layui-btn-xs layui-btn-danger data-count-delete" lay-event="delete">删除</a>-->
|
</script>
|
||||||
<!-- <a class="layui-btn layui-btn-normal layui-btn-xs data-count-edit" lay-event="cmd"></a>-->
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -131,8 +129,7 @@
|
|||||||
{field: 'r9250e', title: '拟合东', templet: "<div>{{d.r9250e==null?'':d.r9250e.toFixed(2)}}</div>"},
|
{field: 'r9250e', title: '拟合东', templet: "<div>{{d.r9250e==null?'':d.r9250e.toFixed(2)}}</div>"},
|
||||||
{field: 'r9250n', title: '拟合北', templet: "<div>{{d.r9250n==null?'':d.r9250n.toFixed(2)}}</div>"},
|
{field: 'r9250n', title: '拟合北', templet: "<div>{{d.r9250n==null?'':d.r9250n.toFixed(2)}}</div>"},
|
||||||
{field: 'r9250d', title: '拟合天', templet: "<div>{{d.r9250d==null?'':d.r9250d.toFixed(2)}}</div>"},
|
{field: 'r9250d', title: '拟合天', templet: "<div>{{d.r9250d==null?'':d.r9250d.toFixed(2)}}</div>"},
|
||||||
{field: 'enabled', title: '有效',templet: '#enabledTrans'},
|
{field: 'enabled', title: '有效',templet: '#enabledTrans'}
|
||||||
{title: '操作', toolbar: '#currentTableBar', fixed: "right", width: 120}
|
|
||||||
];
|
];
|
||||||
if([[${role}]] != "SUPER_ADMIN") {
|
if([[${role}]] != "SUPER_ADMIN") {
|
||||||
data_cols[9].hide = true;
|
data_cols[9].hide = true;
|
||||||
@ -177,63 +174,6 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 监听工具条事件
|
|
||||||
table.on('tool(currentTableFilter)', function(obj) {
|
|
||||||
var data = obj.data;
|
|
||||||
if (obj.event === 'edit') {
|
|
||||||
// 当前状态取反
|
|
||||||
var newEnabled = !data.enabled;
|
|
||||||
|
|
||||||
layer.confirm('确定要修改状态吗?', {
|
|
||||||
btn: ['确定', '取消']
|
|
||||||
}, function(index) {
|
|
||||||
$.ajax({
|
|
||||||
url: '/page/gnssUpdateEnabled',
|
|
||||||
type: 'POST',
|
|
||||||
data: {
|
|
||||||
deviceid: data.deviceid,
|
|
||||||
createtime: data.createtime,
|
|
||||||
enabled: newEnabled ? 1 : 0
|
|
||||||
},
|
|
||||||
success: function(res) {
|
|
||||||
if (res === 'success') {
|
|
||||||
layer.msg('修改成功');
|
|
||||||
// 更新表格数据
|
|
||||||
table.reload('currentTableId');
|
|
||||||
} else {
|
|
||||||
layer.msg('修改失败:' + res);
|
|
||||||
}
|
|
||||||
layer.close(index);
|
|
||||||
},
|
|
||||||
error: function(xhr) {
|
|
||||||
layer.msg('操作失败');
|
|
||||||
layer.close(index);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// else if (obj.event === 'delete') {
|
|
||||||
// layer.confirm('确定删除'+data.deviceid+"?", function(index){
|
|
||||||
// $.ajax({
|
|
||||||
// type:"POST",
|
|
||||||
// url:"/gnss/device/delete",
|
|
||||||
// data:{
|
|
||||||
// 'del_id':data.deviceid
|
|
||||||
// },
|
|
||||||
// success: function (data) {
|
|
||||||
// //data是cotroller相应处理函数的返回值
|
|
||||||
// table.reload('currentTableId');
|
|
||||||
// },
|
|
||||||
// error: function () {
|
|
||||||
// console.log("ajax error");
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// layer.close(index);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
// 监听搜索操作
|
// 监听搜索操作
|
||||||
form.on('submit(data-search-btn)', function (data) {
|
form.on('submit(data-search-btn)', function (data) {
|
||||||
var result = JSON.stringify(data.field);
|
var result = JSON.stringify(data.field);
|
||||||
|
|||||||
@ -30,12 +30,6 @@
|
|||||||
<input type="text" name="parentid" autocomplete="off" class="layui-input">
|
<input type="text" name="parentid" autocomplete="off" class="layui-input">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-inline">
|
|
||||||
<label class="layui-form-label">备选基站号</label>
|
|
||||||
<div class="layui-input-inline">
|
|
||||||
<input type="text" name="parentid1" autocomplete="off" class="layui-input">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="layui-inline">
|
<div class="layui-inline">
|
||||||
<label class="layui-form-label">项目号</label>
|
<label class="layui-form-label">项目号</label>
|
||||||
<div class="layui-input-inline">
|
<div class="layui-input-inline">
|
||||||
@ -47,7 +41,6 @@
|
|||||||
<div class="layui-input-inline">
|
<div class="layui-input-inline">
|
||||||
<select name="tenantname" id="tenantname" lay-search="">
|
<select name="tenantname" id="tenantname" lay-search="">
|
||||||
<option value="">全部</option>
|
<option value="">全部</option>
|
||||||
<option value="非SAAS服务商">非SAAS服务商</option>
|
|
||||||
<option th:each="item : ${tenant_list}" th:text="${item.name}" th:value="${item.name}"></option>
|
<option th:each="item : ${tenant_list}" th:text="${item.name}" th:value="${item.name}"></option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
@ -134,7 +127,6 @@
|
|||||||
{field: 'group_id', title: '基本参数组', width: 60, sort: true},
|
{field: 'group_id', title: '基本参数组', width: 60, sort: true},
|
||||||
{field: 'calc_group_id', title: '解算参数组', width: 60, sort: true},
|
{field: 'calc_group_id', title: '解算参数组', width: 60, sort: true},
|
||||||
{field: 'parentid', title: '基站编号', width: 80, sort: true},
|
{field: 'parentid', title: '基站编号', width: 80, sort: true},
|
||||||
{field: 'parentid1', title: '备选基站', width: 80, sort: true},
|
|
||||||
{field: 'tenantname', title: '所属组织', width: 120},
|
{field: 'tenantname', title: '所属组织', width: 120},
|
||||||
{field: 'fwd_group_id', title: '推送组', width: 80},
|
{field: 'fwd_group_id', title: '推送组', width: 80},
|
||||||
{field: 'fwd_group_id2', title: '推送2', width: 80},
|
{field: 'fwd_group_id2', title: '推送2', width: 80},
|
||||||
|
|||||||
@ -54,7 +54,6 @@
|
|||||||
{field: 'active_time', title: '激活时长(分钟)'},
|
{field: 'active_time', title: '激活时长(分钟)'},
|
||||||
{field: 'active_offset', title: '偏置(分钟)'},
|
{field: 'active_offset', title: '偏置(分钟)'},
|
||||||
{field: 'rs_adv', title: '基准站提前时间(分钟)'},
|
{field: 'rs_adv', title: '基准站提前时间(分钟)'},
|
||||||
{field: 'gnss_sample_s', title: 'GNSS上报(秒)'},
|
|
||||||
{field: 'power_mode', title: '功耗模式',templet: "<div>{{d.power_mode==0?'低功耗':'普通'}}</div>"},
|
{field: 'power_mode', title: '功耗模式',templet: "<div>{{d.power_mode==0?'低功耗':'普通'}}</div>"},
|
||||||
{field: 'device_num', title: '关联设备数'},
|
{field: 'device_num', title: '关联设备数'},
|
||||||
{title: '操作', toolbar: '#currentTableBar', align: "center"}
|
{title: '操作', toolbar: '#currentTableBar', align: "center"}
|
||||||
|
|||||||
@ -1,278 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>SIM卡信息查询</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">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="layuimini-container">
|
|
||||||
<div class="layuimini-main">
|
|
||||||
<fieldset class="table-search-fieldset">
|
|
||||||
<legend>搜索信息</legend>
|
|
||||||
<div style="margin: 10px 10px 10px 10px">
|
|
||||||
<form class="layui-form layui-form-pane" action="" id="searchForm">
|
|
||||||
<div class="layui-form-item">
|
|
||||||
<div class="layui-inline">
|
|
||||||
<label class="layui-form-label">查询类型</label>
|
|
||||||
<div class="layui-input-inline">
|
|
||||||
<select name="searchType" lay-verify="required">
|
|
||||||
<option value="deviceId">设备号</option>
|
|
||||||
<option value="iccid">ICCID</option>
|
|
||||||
<option value="simNumber">SIM卡号</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="layui-inline">
|
|
||||||
<label class="layui-form-label">搜索内容</label>
|
|
||||||
<div class="layui-input-inline">
|
|
||||||
<input type="text" name="searchContent" id="searchInput" autocomplete="off" class="layui-input">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="layui-inline">
|
|
||||||
<label class="layui-form-label">状态</label>
|
|
||||||
<div class="layui-input-inline">
|
|
||||||
<select name="status">
|
|
||||||
<option value="">全部</option>
|
|
||||||
<option value="1">待激活</option>
|
|
||||||
<option value="2">已激活</option>
|
|
||||||
<option value="3">停机</option>
|
|
||||||
<option value="4">注销</option>
|
|
||||||
<option value="5">库存</option>
|
|
||||||
<option value="6">可测试</option>
|
|
||||||
<option value="7">失效</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="layui-form-item">
|
|
||||||
<div class="layui-inline">
|
|
||||||
<button type="submit" class="layui-btn layui-btn-primary" lay-submit lay-filter="searchSubmit"><i class="layui-icon"></i> 搜 索</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
<div class="layui-tab layui-tab-card" lay-filter="data-tab">
|
|
||||||
<ul class="layui-tab-title">
|
|
||||||
<li class="layui-this">数据表格</li>
|
|
||||||
<li>流量图表</li>
|
|
||||||
</ul>
|
|
||||||
<div class="layui-tab-content">
|
|
||||||
<div class="layui-tab-item layui-show">
|
|
||||||
<table class="layui-hide" id="simTable" lay-filter="simTableFilter"></table>
|
|
||||||
</div>
|
|
||||||
<div class="layui-tab-item">
|
|
||||||
<div id="trafficChart" style="min-height:300px;padding: 10px"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<script src="../js/lay-module/echarts/echartsTheme.js" charset="utf-8"></script>
|
|
||||||
<script src="../js/lay-module/echarts/echarts.js" charset="utf-8"></script>
|
|
||||||
<script src="../lib/layui-v2.6.3/layui.js" charset="utf-8"></script>
|
|
||||||
<script type="text/html" id="statusTpl">
|
|
||||||
{{# if(d.status === 1){ }}
|
|
||||||
<span class="layui-badge layui-bg-orange">待激活</span>
|
|
||||||
{{# } else if(d.status === 2){ }}
|
|
||||||
<span class="layui-badge layui-bg-green">已激活</span>
|
|
||||||
{{# } else if(d.status === 3){ }}
|
|
||||||
<span class="layui-badge layui-bg-red">停机</span>
|
|
||||||
{{# } else if(d.status === 4){ }}
|
|
||||||
<span class="layui-badge layui-bg-black">注销</span>
|
|
||||||
{{# } else if(d.status === 5){ }}
|
|
||||||
<span class="layui-badge layui-bg-blue">库存</span>
|
|
||||||
{{# } else if(d.status === 6){ }}
|
|
||||||
<span class="layui-badge layui-bg-cyan">可测试</span>
|
|
||||||
{{# } else if(d.status === 7){ }}
|
|
||||||
<span class="layui-badge">失效</span>
|
|
||||||
{{# } }}
|
|
||||||
</script>
|
|
||||||
<script th:inline="javascript">
|
|
||||||
|
|
||||||
layui.use(['form', 'table','layer','element'], function () {
|
|
||||||
var table = layui.table
|
|
||||||
,form = layui.form
|
|
||||||
,layer = layui.layer
|
|
||||||
,element = layui.element;
|
|
||||||
|
|
||||||
var flowChart;
|
|
||||||
function initEcharts() {
|
|
||||||
if (!flowChart) {
|
|
||||||
flowChart = echarts.init(document.getElementById('trafficChart'), 'theme');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function updateFlowChart(simData) {
|
|
||||||
initEcharts();
|
|
||||||
|
|
||||||
var used = parseFloat(simData.used) || 0;
|
|
||||||
var remaining = parseFloat(simData.remaining) || 0;
|
|
||||||
var total = parseFloat(simData.total) || (used + remaining);
|
|
||||||
|
|
||||||
var option = {
|
|
||||||
title: {
|
|
||||||
text: 'SIM卡流量使用情况',
|
|
||||||
left: 'center',
|
|
||||||
top: 20,
|
|
||||||
textStyle: {
|
|
||||||
fontSize: 16
|
|
||||||
}
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'item',
|
|
||||||
formatter: '{a} <br/>{b}: {c}MB ({d}%)'
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
orient: 'horizontal', // 改为水平布局
|
|
||||||
bottom: 20, // 放在底部
|
|
||||||
left: 'center', // 居中对齐
|
|
||||||
itemWidth: 25,
|
|
||||||
itemHeight: 14
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: '流量使用情况',
|
|
||||||
type: 'pie',
|
|
||||||
radius: ['40%', '60%'], // 调整饼图大小
|
|
||||||
center: ['50%', '50%'], // 居中显示
|
|
||||||
avoidLabelOverlap: false,
|
|
||||||
label: {
|
|
||||||
show: true,
|
|
||||||
position: 'outside', // 标签位置改为外部
|
|
||||||
formatter: function(params) {
|
|
||||||
return params.name + '\n' +
|
|
||||||
params.value + 'MB\n' +
|
|
||||||
params.percent + '%';
|
|
||||||
},
|
|
||||||
fontSize: 14,
|
|
||||||
lineHeight: 20
|
|
||||||
},
|
|
||||||
labelLine: {
|
|
||||||
show: true,
|
|
||||||
length: 15,
|
|
||||||
length2: 10
|
|
||||||
},
|
|
||||||
emphasis: {
|
|
||||||
label: {
|
|
||||||
show: true,
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: 'bold'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data: [
|
|
||||||
{
|
|
||||||
value: used,
|
|
||||||
name: '已使用流量',
|
|
||||||
itemStyle: { color: '#FF5722' }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: remaining,
|
|
||||||
name: '剩余流量',
|
|
||||||
itemStyle: { color: '#009688' }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
document.getElementById('trafficChart').style.height = '400px';
|
|
||||||
|
|
||||||
flowChart.setOption(option);
|
|
||||||
flowChart.resize(); // 重新调整大小
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
var data_cols = [
|
|
||||||
{field: 'deviceid', title: '设备号'},
|
|
||||||
{field: 'iccid', title: 'ICCID'},
|
|
||||||
{field: 'msisdn', title: 'SIM 卡号'},
|
|
||||||
{field: 'updatetime', title: '更新时间',templet: "<div>{{layui.util.toDateString(d.updatetime, 'yyyy-MM-dd HH:mm:ss')}}</div>"},
|
|
||||||
{field: 'status', title: '状态',templet: '#statusTpl'},
|
|
||||||
{field: 'remaining', title: '剩余流量(MB)'},
|
|
||||||
{field: 'used', title: '已使用流量(MB)'},
|
|
||||||
{field: 'total', title: '总流量(MB)'}
|
|
||||||
|
|
||||||
];
|
|
||||||
|
|
||||||
form.render();
|
|
||||||
table.render({
|
|
||||||
elem: '#simTable',
|
|
||||||
url: '/sim/list',
|
|
||||||
toolbar: '#toolbarDemo', //开启头部工具栏
|
|
||||||
defaultToolbar: ['filter'],
|
|
||||||
cols: [
|
|
||||||
data_cols
|
|
||||||
],
|
|
||||||
limits: [20, 50, 100, 200, 300],
|
|
||||||
limit: 20,
|
|
||||||
page: true,
|
|
||||||
skin: 'line',
|
|
||||||
done: function(res) {
|
|
||||||
if(res.code !== 0) {
|
|
||||||
layer.msg(res.msg || '查询失败', {icon: 2});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
form.verify({
|
|
||||||
searchContent: function(value, item) {
|
|
||||||
var type = $('select[name="searchType"]').val();
|
|
||||||
if(!value) {
|
|
||||||
return '请输入搜索内容';
|
|
||||||
}
|
|
||||||
if(type === 'iccid' && !/^\d{19,20}$/.test(value)) {
|
|
||||||
return 'ICCID必须是19-20位数字';
|
|
||||||
}
|
|
||||||
if(type === 'simNumber' && !/^\d{11,13}$/.test(value)) {
|
|
||||||
return 'SIM卡号必须是11-13位数字';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
form.on('submit(searchSubmit)', function(data){
|
|
||||||
var loadIndex = layer.load(1);
|
|
||||||
table.reload('simTable', {
|
|
||||||
page: {
|
|
||||||
curr: 1
|
|
||||||
}
|
|
||||||
,where: {
|
|
||||||
searchType: data.field.searchType,
|
|
||||||
searchContent: data.field.searchContent,
|
|
||||||
status: data.field.status
|
|
||||||
}
|
|
||||||
,done: function(res) {
|
|
||||||
layer.close(loadIndex);
|
|
||||||
if(res.code !== 0) {
|
|
||||||
layer.msg(res.msg || '查询失败', {icon: 2});
|
|
||||||
} else if(res.count === 0) {
|
|
||||||
layer.msg('未找到符合条件的数据', {icon: 0});
|
|
||||||
}else if(res.count === 1) {
|
|
||||||
// 当查询结果只有一条数据时,使用该数据绘制饼图
|
|
||||||
updateFlowChart(res.data[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
//监听Tab切换,重新resize图表,否则显示不出来
|
|
||||||
element.on('tab(data-tab)', function(data){
|
|
||||||
if(data.index === 1 && flowChart) {
|
|
||||||
flowChart.resize();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 监听窗口大小变化
|
|
||||||
window.addEventListener('resize', function() {
|
|
||||||
if (flowChart) {
|
|
||||||
flowChart.resize();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,290 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>SIM卡信息查询</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">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="layuimini-container">
|
|
||||||
<div class="layuimini-main">
|
|
||||||
<fieldset class="table-search-fieldset">
|
|
||||||
<legend>SIM卡相关信息聚合查询</legend>
|
|
||||||
<div style="margin: 10px 10px 10px 10px">
|
|
||||||
<form class="layui-form layui-form-pane" action="" id="searchForm">
|
|
||||||
<div class="layui-form-item">
|
|
||||||
<label class="layui-form-label">搜索类型</label>
|
|
||||||
<div class="layui-input-inline">
|
|
||||||
<select id="searchType" name="searchType" lay-search="" lay-filter="searchType">
|
|
||||||
<option value="iccid">ICCID</option>
|
|
||||||
<option value="deviceId">设备ID</option>
|
|
||||||
<option value="simNumber">SIM卡号</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="layui-form-item">
|
|
||||||
<label class="layui-form-label">搜索内容</label>
|
|
||||||
<div class="layui-input-block">
|
|
||||||
<input type="text" id="searchInput" name="searchContent" autocomplete="off" placeholder="搜索内容" lay-verify="required" class="layui-input">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="layui-form-item">
|
|
||||||
<div class="layui-inline">
|
|
||||||
<button type="button" class="layui-btn" onclick="searchSIM()" lay-submit lay-filter="searchSubmit"><i class="layui-icon"></i>搜索</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
|
|
||||||
<div id="resultContainer" class="result-container layui-hide">
|
|
||||||
<div class="layui-card">
|
|
||||||
<div class="layui-card-body" id="resultContent">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<script src="../lib/layui-v2.6.3/layui.js" charset="utf-8"></script>
|
|
||||||
<script>
|
|
||||||
layui.use(['form', 'layer', 'element'], function(){
|
|
||||||
var form = layui.form;
|
|
||||||
var layer = layui.layer;
|
|
||||||
var element = layui.element;
|
|
||||||
|
|
||||||
form.render();
|
|
||||||
form.on('submit(searchSubmit)', function(data){
|
|
||||||
searchSIM();
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function searchSIM() {
|
|
||||||
const searchInput = document.getElementById('searchInput');
|
|
||||||
const searchContent = searchInput.value.trim();
|
|
||||||
const searchType = document.querySelector('select[name="searchType"]').value;
|
|
||||||
|
|
||||||
if (!searchContent) {
|
|
||||||
layer.msg('请输入搜索内容');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (searchType === 'iccid' && !/^\d{19,20}$/.test(searchContent)) {
|
|
||||||
layer.msg('ICCID必须是19-20位数字');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (searchType === 'simNumber' && !/^\d{11,13}$/.test(searchContent)) {
|
|
||||||
layer.msg('SIM卡号必须是11-13位数字');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const loadingIndex = layer.load(1, {
|
|
||||||
shade: [0.1, '#fff']
|
|
||||||
});
|
|
||||||
|
|
||||||
fetch(`/api/proxy/sim/query?type=${searchType}&content=${searchContent}`)
|
|
||||||
.then(response => {
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error('Network response was not ok');
|
|
||||||
}
|
|
||||||
return response.json();
|
|
||||||
})
|
|
||||||
.then(result => {
|
|
||||||
layer.close(loadingIndex);
|
|
||||||
console.log('API Response:', result);
|
|
||||||
|
|
||||||
if (result.Status === 1 && result.Data) {
|
|
||||||
displayResult(result.Data);
|
|
||||||
} else {
|
|
||||||
layer.msg(result.Message || '查询失败');
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
layer.close(loadingIndex);
|
|
||||||
console.error('Error:', error);
|
|
||||||
layer.msg('请求处理失败:' + error.message);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function displayResult(data) {
|
|
||||||
const resultContainer = document.getElementById('resultContainer');
|
|
||||||
const resultContent = document.getElementById('resultContent');
|
|
||||||
|
|
||||||
if (!resultContainer || !resultContent) {
|
|
||||||
console.error('Result container elements not found');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
resultContainer.classList.remove('layui-hide');
|
|
||||||
|
|
||||||
// 格式化状态和其他信息
|
|
||||||
const statusText = getStatusText(data.status);
|
|
||||||
const statusClass = getStatusClass(data.status);
|
|
||||||
const operatorText = getOperatorText(data.operatortype);
|
|
||||||
|
|
||||||
// 格式化流量数据
|
|
||||||
const gprsInfo = {
|
|
||||||
total: parseFloat(data.gprs?.total) || 0,
|
|
||||||
used: parseFloat(data.gprs?.used) || 0,
|
|
||||||
left: parseFloat(data.gprs?.left) || 0
|
|
||||||
};
|
|
||||||
|
|
||||||
const usagePercentage = calculateUsagePercentage(gprsInfo);
|
|
||||||
|
|
||||||
resultContent.innerHTML = `
|
|
||||||
<table class="layui-table">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td width="120">运营商</td>
|
|
||||||
<td>${operatorText}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>ICCID</td>
|
|
||||||
<td>${data.iccid || '-'}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>SIM卡号</td>
|
|
||||||
<td>${data.msisdn || '-'}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>IMSI</td>
|
|
||||||
<td>${data.imsi || '-'}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>套餐信息</td>
|
|
||||||
<td>
|
|
||||||
ID: ${data.packageid || '-'}<br>
|
|
||||||
名称: ${data.packagename || '-'}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>时间信息</td>
|
|
||||||
<td>
|
|
||||||
激活时间: ${data.activetime || '-'}<br>
|
|
||||||
有效期: ${data.starttime || '-'} 至 ${data.stoptime || '-'}<br>
|
|
||||||
沉默期结束: ${data.silentdate || '-'}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>状态</td>
|
|
||||||
<td><span class="layui-badge ${statusClass}">${statusText}</span></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>APN信息</td>
|
|
||||||
<td>
|
|
||||||
${data.apn ? `
|
|
||||||
<div>ID: ${data.apn.apnid || '-'}</div>
|
|
||||||
<div>状态: ${data.apn.status === '01' ?
|
|
||||||
'<span class="layui-badge layui-bg-green">在线</span>' :
|
|
||||||
'<span class="layui-badge layui-bg-gray">离线</span>'}</div>
|
|
||||||
<div>IP: ${data.apn.ip || '-'}</div>
|
|
||||||
<div>网络: ${getNetworkText(data.apn.rat)}</div>
|
|
||||||
<div>设备状态: ${data.apn.onoffstatus === '1' ?
|
|
||||||
'<span class="layui-badge layui-bg-green">开机</span>' :
|
|
||||||
'<span class="layui-badge layui-bg-gray">关机</span>'}</div>
|
|
||||||
` : '-'}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>GPRS流量</td>
|
|
||||||
<td>
|
|
||||||
<div class="layui-row">
|
|
||||||
<div class="layui-col-md4">总流量: ${formatFlowSize(gprsInfo.total)} MB</div>
|
|
||||||
<div class="layui-col-md4">已用: ${formatFlowSize(gprsInfo.used)} MB</div>
|
|
||||||
<div class="layui-col-md4">剩余: ${formatFlowSize(gprsInfo.left)} MB</div>
|
|
||||||
</div>
|
|
||||||
<div class="layui-progress layui-progress-big" style="margin-top: 10px;">
|
|
||||||
<div class="layui-progress-bar ${getProgressBarColor(gprsInfo)}"
|
|
||||||
style="width: ${usagePercentage}%">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
`;
|
|
||||||
|
|
||||||
// 重新渲染进度条
|
|
||||||
layui.element.render('progress');
|
|
||||||
}
|
|
||||||
|
|
||||||
function getStatusText(status) {
|
|
||||||
const statusMap = {
|
|
||||||
1: '待激活',
|
|
||||||
2: '已激活',
|
|
||||||
3: '停机',
|
|
||||||
4: '注销',
|
|
||||||
5: '库存',
|
|
||||||
6: '可测试',
|
|
||||||
7: '失效'
|
|
||||||
};
|
|
||||||
return statusMap[status] || '未知状态';
|
|
||||||
}
|
|
||||||
function getOperatorText(type) {
|
|
||||||
const operatorMap = {
|
|
||||||
1: '中国移动',
|
|
||||||
2: '中国联通',
|
|
||||||
3: '中国电信'
|
|
||||||
};
|
|
||||||
return operatorMap[type] || '未知运营商';
|
|
||||||
}
|
|
||||||
function getNetworkText(rat) {
|
|
||||||
const networkMap = {
|
|
||||||
'1': '3G',
|
|
||||||
'2': '2G',
|
|
||||||
'6': '4G',
|
|
||||||
'8': 'NB'
|
|
||||||
};
|
|
||||||
return networkMap[rat] || '未知网络';
|
|
||||||
}
|
|
||||||
function getStatusClass(status) {
|
|
||||||
const classMap = {
|
|
||||||
1: 'layui-bg-orange', // 待激活
|
|
||||||
2: 'layui-bg-green', // 已激活
|
|
||||||
3: 'layui-bg-red', // 停机
|
|
||||||
4: 'layui-bg-gray', // 注销
|
|
||||||
5: 'layui-bg-blue', // 库存
|
|
||||||
6: 'layui-bg-cyan', // 可测试
|
|
||||||
7: 'layui-bg-black' // 失效
|
|
||||||
};
|
|
||||||
return classMap[status] || 'layui-bg-gray';
|
|
||||||
}
|
|
||||||
|
|
||||||
function getProgressBarColor(gprsInfo) {
|
|
||||||
const percentage = calculateUsagePercentage(gprsInfo);
|
|
||||||
if (percentage >= 90) return 'layui-bg-red';
|
|
||||||
if (percentage >= 70) return 'layui-bg-orange';
|
|
||||||
return 'layui-bg-green';
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateUsagePercentage(gprsInfo) {
|
|
||||||
// 确保所有值都是数字,并且total不为0
|
|
||||||
const total = parseFloat(gprsInfo.total) || 0;
|
|
||||||
const used = parseFloat(gprsInfo.used) || 0;
|
|
||||||
|
|
||||||
if (total <= 0) return 0;
|
|
||||||
|
|
||||||
const percentage = (used / total) * 100;
|
|
||||||
return Math.min(100, Math.round(percentage));
|
|
||||||
}
|
|
||||||
function formatFlowSize(size) {
|
|
||||||
if (typeof size !== 'number' || isNaN(size)) return '0.00';
|
|
||||||
return size.toFixed(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 按回车键触发查询
|
|
||||||
document.getElementById('searchInput').addEventListener('keypress', function(e) {
|
|
||||||
if (e.key === 'Enter') {
|
|
||||||
e.preventDefault();
|
|
||||||
searchSIM();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -81,12 +81,6 @@
|
|||||||
<input type="number" name="parentid" id="parentid" placeholder="请输入关联基准站编号" value="" class="layui-input">
|
<input type="number" name="parentid" id="parentid" placeholder="请输入关联基准站编号" value="" class="layui-input">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-inline" >
|
|
||||||
<label class="layui-form-label">备选基站</label>
|
|
||||||
<div class="layui-input-block">
|
|
||||||
<input type="number" name="parentid1" id="parentid1" placeholder="请输入备选基准站编号" value="" class="layui-input">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item" id="ecef_div">
|
<div class="layui-form-item" id="ecef_div">
|
||||||
<div class="layui-inline">
|
<div class="layui-inline">
|
||||||
@ -213,12 +207,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="layui-form-item" th:if="${role=='SUPER_ADMIN'}">
|
|
||||||
<label class="layui-form-label">ICCID</label>
|
|
||||||
<div class="layui-input-block">
|
|
||||||
<input type="text" name="iccid" id="iccid" class="layui-input" placeholder="请输入19-20位的ICCID号码">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="layui-form-item" th:if="${role=='SUPER_ADMIN'}">
|
<div class="layui-form-item" th:if="${role=='SUPER_ADMIN'}">
|
||||||
<label class="layui-form-label">备注</label>
|
<label class="layui-form-label">备注</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
@ -313,7 +301,6 @@
|
|||||||
$('#name').val(data.name);
|
$('#name').val(data.name);
|
||||||
$('#devicetype').val(data.devicetype);
|
$('#devicetype').val(data.devicetype);
|
||||||
$('#parentid').val(data.parentid);
|
$('#parentid').val(data.parentid);
|
||||||
$('#parentid1').val(data.parentid1);
|
|
||||||
$('#tenantname').val(data.tenantname);
|
$('#tenantname').val(data.tenantname);
|
||||||
$('#project_id').val(data.project_id);
|
$('#project_id').val(data.project_id);
|
||||||
$('#project2_id').val(data.project2_id);
|
$('#project2_id').val(data.project2_id);
|
||||||
@ -333,7 +320,6 @@
|
|||||||
$('#model').val(data.model);
|
$('#model').val(data.model);
|
||||||
$('#sector').val(data.sector);
|
$('#sector').val(data.sector);
|
||||||
$('#remark').val(data.remark);
|
$('#remark').val(data.remark);
|
||||||
$('#iccid').val(data.iccid);
|
|
||||||
setEcefEditor();
|
setEcefEditor();
|
||||||
form.render();
|
form.render();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,12 +47,6 @@
|
|||||||
<input type="number" name="active_offset" id="active_offset" placeholder="请输入配置" value="0" class="layui-input">
|
<input type="number" name="active_offset" id="active_offset" placeholder="请输入配置" value="0" class="layui-input">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item">
|
|
||||||
<label class="layui-form-label">GNSS上报(秒)</label>
|
|
||||||
<div class="layui-input-block">
|
|
||||||
<input type="number" name="gnss_sample_s" id="gnss_sample_s" placeholder="请输入配置" value="0" class="layui-input">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label">基准站提前时间(分钟)</label>
|
<label class="layui-form-label">基准站提前时间(分钟)</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
@ -117,7 +111,6 @@
|
|||||||
$('#rs_adv').val(data.rs_adv);
|
$('#rs_adv').val(data.rs_adv);
|
||||||
$('#power_mode').val(data.power_mode);
|
$('#power_mode').val(data.power_mode);
|
||||||
$('#name').val(data.name);
|
$('#name').val(data.name);
|
||||||
$('#gnss_sample_s').val(data.gnss_sample_s);
|
|
||||||
form.render();
|
form.render();
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -67,13 +67,13 @@ public class BeidouDevice {
|
|||||||
executeAsD342("C:\\Users\\wd\\Desktop\\log\\2412254_0424_4xx.log");
|
executeAsD342("C:\\Users\\wd\\Desktop\\log\\2412254_0424_4xx.log");
|
||||||
executeAsD342("C:\\Users\\wd\\Desktop\\log\\2412254_0424_5xx.log");
|
executeAsD342("C:\\Users\\wd\\Desktop\\log\\2412254_0424_5xx.log");
|
||||||
*/
|
*/
|
||||||
execute("C:\\Users\\wd\\Desktop\\log\\2345076_0424_5xx.log");
|
//execute("C:\\Users\\wd\\Desktop\\log\\2345076_0424_5xx.log");
|
||||||
//executeAsD342("C:\\Users\\wd\\Desktop\\log\\b562_2412270_1xx.log");
|
//executeAsD342("C:\\Users\\wd\\Desktop\\log\\b562_2412270_1xx.log");
|
||||||
//executeAsD342("C:\\Users\\wd\\Desktop\\log\\b562_2412270_2xx.log");
|
//executeAsD342("C:\\Users\\wd\\Desktop\\log\\b562_2412270_2xx.log");
|
||||||
|
|
||||||
/* executeAsD342("C:\\Users\\wd\\Desktop\\log\\2345076_0424_1.log");
|
//execute("C:\\Users\\wd\\Desktop\\log\\2345076_0424_1.log");
|
||||||
executeAsD342("C:\\Users\\wd\\Desktop\\log\\2345076_0424_2.log");
|
execute("C:\\Users\\wd\\Desktop\\log\\2345076_0424_2.log");
|
||||||
executeAsD342("C:\\Users\\wd\\Desktop\\log\\2345076_0424_1xx.log");
|
/*executeAsD342("C:\\Users\\wd\\Desktop\\log\\2345076_0424_1xx.log");
|
||||||
executeAsD342("C:\\Users\\wd\\Desktop\\log\\2345076_0424_2xx.log");
|
executeAsD342("C:\\Users\\wd\\Desktop\\log\\2345076_0424_2xx.log");
|
||||||
executeAsD342("C:\\Users\\wd\\Desktop\\log\\2345076_0424_3xx.log");
|
executeAsD342("C:\\Users\\wd\\Desktop\\log\\2345076_0424_3xx.log");
|
||||||
executeAsD342("C:\\Users\\wd\\Desktop\\log\\2345076_0424_4xx.log");
|
executeAsD342("C:\\Users\\wd\\Desktop\\log\\2345076_0424_4xx.log");
|
||||||
@ -120,7 +120,12 @@ public class BeidouDevice {
|
|||||||
cycleCount++;
|
cycleCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
udpClient.sendData(ByteUtil.hexStringTobyte(arrs[2]));
|
if(arrs[2].startsWith("d3f2")){
|
||||||
|
b562Count = b562Count;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
udpClient.sendData(ByteUtil.hexStringTobyte(arrs[2]));
|
||||||
|
}
|
||||||
b562Count++;
|
b562Count++;
|
||||||
lastTime = time.getTime();
|
lastTime = time.getTime();
|
||||||
Thread.sleep(100);
|
Thread.sleep(100);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user