From 07ffaf7c113f7e2cc8a904b6fbeffced08eff6a1 Mon Sep 17 00:00:00 2001 From: weidong Date: Sun, 30 Mar 2025 13:24:48 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81ICCID=E6=A3=80=E6=9F=A5=E8=BD=AC?= =?UTF-8?q?=E7=A7=BB=E5=88=B0ehm=202=E3=80=81=E5=A2=9E=E5=8A=A0=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E4=B8=80=E8=87=B4=E6=80=A7=E6=A3=80=E6=9F=A5=E7=9A=84?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- readme.txt | 15 +- .../imdroid/secapi/dto/GnssStatusJoin.java | 2 + .../imdroid/secapi/dto/GnssStatusMapper.java | 12 +- .../com/imdroid/secapi/dto/WarningCfg.java | 2 + .../beidou_ehm/service/WarningService.java | 117 ++++++++++++++++ .../beidou_ehm}/simcard/BaseResponse.java | 2 +- .../beidou_ehm}/simcard/CardDetailData.java | 2 +- .../beidou_ehm}/simcard/CardInfoData.java | 2 +- .../beidou_ehm}/simcard/CardStatusData.java | 2 +- .../imdroid/beidou_ehm}/simcard/GprsData.java | 2 +- .../simcard/SimCardQueryService.java | 19 +++ .../simcard}/SimCardQueryServiceImpl.java | 29 ++-- .../beidou_ehm}/task/SimStatusChecker.java | 132 +++++++++++++----- .../sideslope/sal/DbDeviceServiceImpl.java | 1 - .../com/imdroid/sideslope/sal/Device.java | 2 - .../service/SimCardQueryService.java | 20 --- .../sideslope/service/WarningServiceImpl.java | 75 ---------- .../beidou/controller/APIController.java | 35 ++++- .../resources/templates/page/cmd_line.html | 1 + 19 files changed, 303 insertions(+), 169 deletions(-) create mode 100644 sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/service/WarningService.java rename {sec-beidou-rtcm/src/main/java/com/imdroid/sideslope => sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm}/simcard/BaseResponse.java (77%) rename {sec-beidou-rtcm/src/main/java/com/imdroid/sideslope => sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm}/simcard/CardDetailData.java (95%) rename {sec-beidou-rtcm/src/main/java/com/imdroid/sideslope => sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm}/simcard/CardInfoData.java (77%) rename {sec-beidou-rtcm/src/main/java/com/imdroid/sideslope => sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm}/simcard/CardStatusData.java (75%) rename {sec-beidou-rtcm/src/main/java/com/imdroid/sideslope => sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm}/simcard/GprsData.java (95%) create mode 100644 sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/simcard/SimCardQueryService.java rename {sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/service => sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/simcard}/SimCardQueryServiceImpl.java (87%) rename {sec-beidou-rtcm/src/main/java/com/imdroid/sideslope => sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm}/task/SimStatusChecker.java (63%) delete mode 100644 sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/service/SimCardQueryService.java diff --git a/readme.txt b/readme.txt index 1cebf0b4..833a3bbf 100644 --- a/readme.txt +++ b/readme.txt @@ -20,13 +20,14 @@ 6)用户设置:用户名、手机号、权限(管理员、普通),内置开发者用户。管理员可以增删改查,普通用户只能查 2024-6 -端口分配: - http netty -beidou 9901(外) -beidou-rtcm 9904 9902(外),9903(外) -beidou-fwd 9906 -ntrip-proxy 9910 11001(外) -beidou-exapi 9908(外) +功能定义、端口分配: + http netty 功能 +beidou 9901(外) UI、配置管理、状态管理 +beidou-rtcm 9904 9902(外),9903(外) 解算相关,包括解算、解算异常处理 +beidou-fwd 9906 解算结果推送 +ntrip-proxy 9910 11001(外) ntrip服务器代理 +beidou-exapi 9908(外) API +beidou-ehm 9912 健康检查、SIM卡检查 2024-9 算法: diff --git a/sec-api/src/main/java/com/imdroid/secapi/dto/GnssStatusJoin.java b/sec-api/src/main/java/com/imdroid/secapi/dto/GnssStatusJoin.java index 9080b3f6..29cd1d6c 100644 --- a/sec-api/src/main/java/com/imdroid/secapi/dto/GnssStatusJoin.java +++ b/sec-api/src/main/java/com/imdroid/secapi/dto/GnssStatusJoin.java @@ -94,4 +94,6 @@ public class GnssStatusJoin { Double longitude; @ExcelProperty("海拔") Double altitude; + @ExcelProperty("ICCID") + String iccid; } diff --git a/sec-api/src/main/java/com/imdroid/secapi/dto/GnssStatusMapper.java b/sec-api/src/main/java/com/imdroid/secapi/dto/GnssStatusMapper.java index ad3f42e0..4f24dbe2 100644 --- a/sec-api/src/main/java/com/imdroid/secapi/dto/GnssStatusMapper.java +++ b/sec-api/src/main/java/com/imdroid/secapi/dto/GnssStatusMapper.java @@ -19,26 +19,26 @@ public interface GnssStatusMapper extends MPJBaseMapper { @Update({"update gnssstatus set state=0,warning=#{warning},warningcode=#{warningcode} where deviceid=#{deviceid}"}) int setOfflineByDeviceId(GnssStatusJoin status); - @Select({"select s.*, d.devicetype, d.model, d.group_id, d.name, d.project_id from gnssstatus s ,gnssdevices d where s.deviceid=d.deviceid and s.state <> 0"}) + @Select({"select s.*, d.devicetype, d.model, d.group_id, d.name, d.project_id,d.iccid from gnssstatus s ,gnssdevices d where s.deviceid=d.deviceid and s.state <> 0"}) List queryOnline(); - @Select({"select s.*, d.devicetype, d.model, d.group_id, d.name, d.project_id from gnssstatus s ,gnssdevices d where " + + @Select({"select s.*, d.devicetype, d.model, d.group_id, d.name, d.project_id,d.iccid from gnssstatus s ,gnssdevices d where " + "s.deviceid=d.deviceid and d.tenantid<>0 and d.opmode=0"}) List queryDeployed(); - @Select({"select s.*, d.devicetype, d.model, d.group_id, d.name, d.project_id from gnssstatus s ,gnssdevices d where " + + @Select({"select s.*, d.devicetype, d.model, d.group_id, d.name, d.project_id,d.iccid from gnssstatus s ,gnssdevices d where " + "s.deviceid=d.deviceid and d.tenantid = #{tenantid} and d.opmode=0"}) List queryDeployedByTenant(int tenantid); //多个入参要用Param注解 - @Select({"select s.*, d.devicetype, d.model, d.group_id, d.name, d.project_id from gnssstatus s ,gnssdevices d where " + + @Select({"select s.*, d.devicetype, d.model, d.group_id, d.name, d.project_id,d.iccid from gnssstatus s ,gnssdevices d where " + "s.deviceid=d.deviceid and d.tenantid = #{tenantid} and d.opmode=0 and d.project_id = #{projectName}"}) List queryDeployedByProject(@Param("tenantid") int tenantid, @Param("projectName") String projectName); // 需要关联设备类型 - @Select({"select s.*, d.devicetype, d.model, d.group_id, d.name, d.project_id from gnssstatus s ,gnssdevices d where s.deviceid=d.deviceid and s.deviceid = #{deviceId}"}) + @Select({"select s.*, d.devicetype, d.model, d.group_id, d.name, d.project_id,d.iccid from gnssstatus s ,gnssdevices d where s.deviceid=d.deviceid and s.deviceid = #{deviceId}"}) GnssStatusJoin queryByDeviceId(String deviceId); - @Select({"select s.*, d.devicetype, d.model, d.group_id, d.name, d.project_id from gnssstatus s ,gnssdevices d where s.deviceid=d.deviceid"}) + @Select({"select s.*, d.devicetype, d.model, d.group_id, d.name, d.project_id,d.iccid from gnssstatus s ,gnssdevices d where s.deviceid=d.deviceid"}) GnssStatusJoin queryAll(); } diff --git a/sec-api/src/main/java/com/imdroid/secapi/dto/WarningCfg.java b/sec-api/src/main/java/com/imdroid/secapi/dto/WarningCfg.java index a0711628..93ffa9b0 100644 --- a/sec-api/src/main/java/com/imdroid/secapi/dto/WarningCfg.java +++ b/sec-api/src/main/java/com/imdroid/secapi/dto/WarningCfg.java @@ -50,6 +50,8 @@ public class WarningCfg { public static final String TYPE_NAME_XY_JUMP = "滤波结果水平跳变"; public static final int TYPE_Z_JUMP = 0x4000; public static final String TYPE_NAME_Z_JUMP = "滤波结果高程跳变"; + public static final int TYPE_CFG_ABNORMAL = 0x8000; + public static final String TYPE_NAME_CFG_ABNORMAL = "配置参数不一致"; // warning level definition public static final short LEVEL_0 = 0; //正常 diff --git a/sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/service/WarningService.java b/sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/service/WarningService.java new file mode 100644 index 00000000..03602e27 --- /dev/null +++ b/sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/service/WarningService.java @@ -0,0 +1,117 @@ +package com.imdroid.beidou_ehm.service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.imdroid.secapi.dto.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +@Service +public class WarningService { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + WarningCfgMapper warningCfgMapper; + @Autowired + WarningMsgMapper warningMsgMapper; + // warning type <-> level & value + Map cfgMap = new ConcurrentHashMap<>(); + int warningLevel2Code = 0; + + @PostConstruct + public void refreshCfg(){ + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("devicetype", WarningCfg.TYPE_GNSS); + List cfgList = warningCfgMapper.selectList(null); + cfgMap.clear(); + for(WarningCfg cfg: cfgList){ + cfgMap.put(cfg.getType(),new int[]{cfg.getLevel(),cfg.getValue()}); + if(cfg.getLevel() == WarningCfg.LEVEL_2){ + warningLevel2Code |= cfg.getType(); + } + } + } + + public boolean check(GnssStatus curStatus, int warningType, String warningName, + boolean isLessCmp, Integer value1, Integer value2, String auxInfo){ + boolean isUpdated=false; + int newWarningCode = 0; + int[] warningValues = cfgMap.get(warningType); + if(warningValues!=null){ + if(isLessCmp) { + if (value1 != null && value1 <= warningValues[1]) { + newWarningCode = warningType; + } + if (value2 != null && value2 <= warningValues[1]) { + newWarningCode = warningType; + } + } + else{ + if (value1 != null && value1 >= warningValues[1]) { + newWarningCode = warningType; + } + if (value2 != null && value2 >= warningValues[1]) { + newWarningCode = warningType; + } + } + } + + int oldWarningCode = curStatus.getWarningcode() & warningType; + if(newWarningCode != oldWarningCode){ + if(newWarningCode == 0){ + clearWarning(curStatus, warningType); + } + else { + WarningMsg warningMsg = new WarningMsg(); + warningMsg.setDeviceid(curStatus.getDeviceid()); + warningMsg.setTenantid(curStatus.getTenantid()); + warningMsg.setCreatetime(LocalDateTime.now()); + warningMsg.setDevicetype(WarningCfg.TYPE_GNSS); + warningMsg.setCode(warningType); + warningMsg.setLevel((short) warningValues[0]); + if(auxInfo ==null) { + auxInfo = warningName + ":" + value1; + if (value2 != null) auxInfo = auxInfo + "," + value2; + } + else auxInfo = warningName + ":" + auxInfo; + warningMsg.setInfo(auxInfo); + warningMsgMapper.insert(warningMsg); + //告警级别 + curStatus.setWarningcode(curStatus.getWarningcode() | warningType); + + // 新告警出现后,生成对应设备的 warning 日志文件 + //generate_warning_logs(curStatus.getDeviceid(),warningType,auxInfo); + } + isUpdated = true; + } + return isUpdated; + } + + public short getWarningLevel(int warningCode){ + if(warningCode == 0) return WarningCfg.LEVEL_0; + else if((warningCode & warningLevel2Code) !=0 ) return WarningCfg.LEVEL_2; + else return WarningCfg.LEVEL_1; + } + + public void clearWarning(GnssStatus status, int warningCode){ + status.setWarningcode(status.getWarningcode()&~warningCode); + logger.info("{} clearWarning code {},{}",status.getDeviceid(),warningCode,status.getWarningcode()); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("deviceid",status.getDeviceid()); + queryWrapper.eq("code",warningCode); + queryWrapper.orderByDesc("createtime"); + queryWrapper.last("limit 1"); + WarningMsg warningMsg = warningMsgMapper.selectOne(queryWrapper); + if(warningMsg!=null){ + warningMsg.setCleartime(LocalDateTime.now()); + warningMsgMapper.updateById(warningMsg); + } + } +} diff --git a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/simcard/BaseResponse.java b/sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/simcard/BaseResponse.java similarity index 77% rename from sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/simcard/BaseResponse.java rename to sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/simcard/BaseResponse.java index 6f6e42a9..65ddd96e 100644 --- a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/simcard/BaseResponse.java +++ b/sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/simcard/BaseResponse.java @@ -1,4 +1,4 @@ -package com.imdroid.sideslope.simcard; +package com.imdroid.beidou_ehm.simcard; import lombok.Data; diff --git a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/simcard/CardDetailData.java b/sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/simcard/CardDetailData.java similarity index 95% rename from sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/simcard/CardDetailData.java rename to sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/simcard/CardDetailData.java index 5f1a5b14..4f65388c 100644 --- a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/simcard/CardDetailData.java +++ b/sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/simcard/CardDetailData.java @@ -1,4 +1,4 @@ -package com.imdroid.sideslope.simcard; +package com.imdroid.beidou_ehm.simcard; import lombok.Data; diff --git a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/simcard/CardInfoData.java b/sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/simcard/CardInfoData.java similarity index 77% rename from sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/simcard/CardInfoData.java rename to sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/simcard/CardInfoData.java index 80db3d36..a6946d7b 100644 --- a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/simcard/CardInfoData.java +++ b/sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/simcard/CardInfoData.java @@ -1,4 +1,4 @@ -package com.imdroid.sideslope.simcard; +package com.imdroid.beidou_ehm.simcard; import lombok.Data; diff --git a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/simcard/CardStatusData.java b/sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/simcard/CardStatusData.java similarity index 75% rename from sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/simcard/CardStatusData.java rename to sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/simcard/CardStatusData.java index 43f8ec9f..72fc09b3 100644 --- a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/simcard/CardStatusData.java +++ b/sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/simcard/CardStatusData.java @@ -1,4 +1,4 @@ -package com.imdroid.sideslope.simcard; +package com.imdroid.beidou_ehm.simcard; import lombok.Data; diff --git a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/simcard/GprsData.java b/sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/simcard/GprsData.java similarity index 95% rename from sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/simcard/GprsData.java rename to sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/simcard/GprsData.java index caeb4041..e50610f4 100644 --- a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/simcard/GprsData.java +++ b/sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/simcard/GprsData.java @@ -1,4 +1,4 @@ -package com.imdroid.sideslope.simcard; +package com.imdroid.beidou_ehm.simcard; import lombok.Data; diff --git a/sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/simcard/SimCardQueryService.java b/sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/simcard/SimCardQueryService.java new file mode 100644 index 00000000..9a7d9ce7 --- /dev/null +++ b/sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/simcard/SimCardQueryService.java @@ -0,0 +1,19 @@ +package com.imdroid.beidou_ehm.simcard; + +import com.imdroid.secapi.dto.GnssStatusJoin; + +public interface SimCardQueryService { + + // 查询卡基本信息 + BaseResponse queryCardInfo(GnssStatusJoin device); + + // 查询卡状态 + BaseResponse queryCardStatus(GnssStatusJoin device); + + // 查询流量信息 + BaseResponse queryGprs(GnssStatusJoin device); + + // 查询卡详细信息 + BaseResponse queryCardDetail(GnssStatusJoin device); + +} diff --git a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/service/SimCardQueryServiceImpl.java b/sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/simcard/SimCardQueryServiceImpl.java similarity index 87% rename from sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/service/SimCardQueryServiceImpl.java rename to sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/simcard/SimCardQueryServiceImpl.java index d6bb0cec..9784c99c 100644 --- a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/service/SimCardQueryServiceImpl.java +++ b/sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/simcard/SimCardQueryServiceImpl.java @@ -1,13 +1,12 @@ -package com.imdroid.sideslope.service; +package com.imdroid.beidou_ehm.simcard; 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.simcard.*; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; @@ -39,26 +38,26 @@ public class SimCardQueryServiceImpl implements SimCardQueryService{ SimCardsMapper simCardsMapper; @Override - public BaseResponse queryCardInfo(Device device) { + public BaseResponse queryCardInfo(GnssStatusJoin device) { return executeQuery(device, "/api/Service/Cardinfo", CardInfoData.class); } @Override - public BaseResponse queryCardStatus(Device device) { + public BaseResponse queryCardStatus(GnssStatusJoin device) { return executeQuery(device, "/api/Service/QueryCardStatus", CardStatusData.class); } @Override - public BaseResponse queryGprs(Device device) { + public BaseResponse queryGprs(GnssStatusJoin device) { return executeQuery(device, "/api/Service/QueryGprs", GprsData.class); } @Override - public BaseResponse queryCardDetail(Device device) { + public BaseResponse queryCardDetail(GnssStatusJoin device) { return executeQuery(device, "/api/Service/QueryCard", CardDetailData.class); } - private BaseResponse executeQuery(Device device, String path, Class responseType) { + private BaseResponse executeQuery(GnssStatusJoin device, String path, Class responseType) { try { Map params = new HashMap<>(); params.put("username", USERNAME); @@ -72,7 +71,7 @@ public class SimCardQueryServiceImpl implements SimCardQueryService{ logger.info("Request params: {}", params); String response = sendHttpPost(path, params); logger.info("查询响应: 设备={}, ICCID={}, 响应={}", - device.getDeviceId(), device.getIccid(), response); + device.getDeviceid(), device.getIccid(), response); ObjectMapper mapper = new ObjectMapper(); mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true); @@ -96,7 +95,7 @@ public class SimCardQueryServiceImpl implements SimCardQueryService{ return mapper.readValue(response, type); } catch (Exception e) { - logger.error("查询失败: 设备={}, 错误={}", device.getDeviceId(), e.getMessage()); + logger.error("查询失败: 设备={}, 错误={}", device.getDeviceid(), e.getMessage()); return null; } } @@ -144,21 +143,21 @@ public class SimCardQueryServiceImpl implements SimCardQueryService{ } } - public boolean hasValidIccid(Device device) { + public boolean hasValidIccid(GnssStatusJoin device) { return device.getIccid() != null && !device.getIccid().trim().isEmpty(); } - public SimCard CreateOrUpdateSimCard(Device device) { - SimCard simCard = simCardsMapper.queryByDeviceId(device.getDeviceId()); + public SimCard CreateOrUpdateSimCard(GnssStatusJoin device) { + SimCard simCard = simCardsMapper.queryByDeviceId(device.getDeviceid()); if (simCard == null) { simCard = createNewSimCard(device); } return simCard; } - public SimCard createNewSimCard(Device device) { + public SimCard createNewSimCard(GnssStatusJoin device) { SimCard newCard = new SimCard(); - newCard.setDeviceid(device.getDeviceId()); + newCard.setDeviceid(device.getDeviceid()); newCard.setUpdatetime(new Date()); newCard.setIccid(device.getIccid()); newCard.setStatus(-1); diff --git a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/task/SimStatusChecker.java b/sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/task/SimStatusChecker.java similarity index 63% rename from sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/task/SimStatusChecker.java rename to sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/task/SimStatusChecker.java index 7b262bdd..b0060dd1 100644 --- a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/task/SimStatusChecker.java +++ b/sec-beidou-ehm/src/main/java/com/imdroid/beidou_ehm/task/SimStatusChecker.java @@ -1,16 +1,10 @@ -package com.imdroid.sideslope.task; +package com.imdroid.beidou_ehm.task; import com.alibaba.excel.util.StringUtils; +import com.imdroid.beidou_ehm.service.WarningService; +import com.imdroid.beidou_ehm.simcard.*; 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; @@ -19,8 +13,8 @@ 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.math.RoundingMode; import java.util.*; import java.util.concurrent.TimeUnit; @@ -37,17 +31,14 @@ public class SimStatusChecker { 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; + @Autowired + WarningService warningService; // 每小时执行一次状态检查调度 @Scheduled(cron = "0 0 * * * ?") @@ -61,7 +52,7 @@ public class SimStatusChecker { //logger.debug("- 设备: {}, SIM状态查询,延迟执行: {}秒", onlineDevice.getDeviceid(), delay); ThreadManager.getScheduledThreadPool().schedule( - () -> checkDeviceSimCardStatus(onlineDevice.getDeviceid()), + () -> checkDeviceSimCardStatus(onlineDevice), delay, TimeUnit.SECONDS ); @@ -79,16 +70,15 @@ public class SimStatusChecker { //logger.debug("- 设备: {}, SIM流量查询,延迟执行: {}秒", onlineDevice.getDeviceid(), delay); ThreadManager.getScheduledThreadPool().schedule( - () -> checkDeviceSimCardTraffic(onlineDevice.getDeviceid()), + () -> checkDeviceSimCardTraffic(onlineDevice), delay, TimeUnit.SECONDS ); } } - private void checkDeviceSimCardStatus(String deviceId) { + private void checkDeviceSimCardStatus(GnssStatusJoin device) { try { - Device device = deviceService.findByDeviceId(deviceId); // 不允许尚未从自检得到 ICCID 的设备参加 SIM 卡状态查询 if (!simCardQueryServiceImpl.hasValidIccid(device)) { return; @@ -98,13 +88,12 @@ public class SimStatusChecker { updateSimCardInfo(device, simCard); } catch (Exception e) { - logger.error("设备{}状态查询失败: ", deviceId, e); + logger.error("设备{}状态查询失败: ", device.getDeviceid(), e); } } - private void checkDeviceSimCardTraffic(String deviceId) { + private void checkDeviceSimCardTraffic(GnssStatusJoin device) { try { - Device device = deviceService.findByDeviceId(deviceId); // 不允许尚未从自检得到 ICCID 的设备参加 SIM 卡状态查询 if (!simCardQueryServiceImpl.hasValidIccid(device)) { return; @@ -118,11 +107,11 @@ public class SimStatusChecker { updateSimCardTrafficFromAPI(device, simCard); } catch (Exception e) { - logger.error("设备{}查询失败: ", deviceId, e); + logger.error("设备{}查询失败: ", device.getDeviceid(), e); } } - private void updateSimCardInfo(Device device, SimCard simCard) throws Exception { + private void updateSimCardInfo(GnssStatusJoin device, SimCard simCard) throws Exception { // 自检中只是获取保存了设备的 ICCID ,所有如果判断如果没有 MSISDN,先更新基本信息 if (StringUtils.isBlank(simCard.getMsisdn())) { updateSimCardBasicInfoFromAPI(device, simCard); @@ -130,7 +119,7 @@ public class SimStatusChecker { // 更新状态 updateSimCardStatusFromAPI(device, simCard); } - private void updateSimCardBasicInfoFromAPI(Device device, SimCard simCard) { + private void updateSimCardBasicInfoFromAPI(GnssStatusJoin device, SimCard simCard) { try { BaseResponse response = simCardQueryServiceImpl.queryCardInfo(device); if (!simCardQueryServiceImpl.isValidResponse(response)) { @@ -145,11 +134,11 @@ public class SimStatusChecker { logger.debug("更新SIM卡基本信息 - imsi: {}, msisdn: {}, iccid: {}", info.getImsi(), info.getMsisdn(), info.getIccid()); } catch (Exception e) { - logger.error("更新设备{}的SIM卡基本信息失败: ", device.getDeviceId(), e); + logger.error("更新设备{}的SIM卡基本信息失败: ", device.getDeviceid(), e); throw e; } } - private void updateSimCardStatusFromAPI(Device device, SimCard simCard) { + private void updateSimCardStatusFromAPI(GnssStatusJoin device, SimCard simCard) { try { BaseResponse response = simCardQueryServiceImpl.queryCardStatus(device); if (!simCardQueryServiceImpl.isValidResponse(response)) { @@ -160,17 +149,17 @@ public class SimStatusChecker { simCard.setStatus(status.getStatusCode()); simCardsMapper.updateCardStatusInfo(simCard); - warningService.checkSimCardStatus(device, simCard); + checkSimCardStatus(device, simCard); logger.debug("更新SIM卡状态 - Code: {}, 描述: {}", status.getStatusCode(), status.getStatusDesc()); } catch (Exception e) { - logger.error("更新设备{}的SIM卡状态失败: ", device.getDeviceId(), e); + logger.error("更新设备{}的SIM卡状态失败: ", device.getDeviceid(), e); // throw e; } } - private void updateSimCardTrafficFromAPI(Device device, SimCard simCard) { + private void updateSimCardTrafficFromAPI(GnssStatusJoin device, SimCard simCard) { try { BaseResponse response = simCardQueryServiceImpl.queryGprs(device); if (!simCardQueryServiceImpl.isValidResponse(response)) { @@ -180,7 +169,7 @@ public class SimStatusChecker { GprsData gprsData = response.getData(); GprsData.GprsUsage usage = gprsData.getFirstGprsUsage(); if (usage == null) { - logger.warn("无可用流量数据查询, deviceId: {}", device.getDeviceId()); + logger.warn("无可用流量数据查询, deviceId: {}", device.getDeviceid()); return; } @@ -190,7 +179,7 @@ public class SimStatusChecker { simCard.setTotal(BigDecimal.valueOf(usage.getTotal())); simCardsMapper.updateCardTrafficInfo(simCard); - warningService.checkSimCardTraffic(device, simCard); + checkSimCardTraffic(device, simCard); logger.debug("更新流量信息成功 - deviceId: {}, 剩余: {}MB, 总量: {}MB, 已用: {}MB", device.getIccid(), @@ -199,9 +188,82 @@ public class SimStatusChecker { simCard.getUsed()); } catch (Exception e) { - logger.error("设备{}更新SIM卡流量失败: ", device.getDeviceId(), e); + logger.error("设备{}更新SIM卡流量失败: ", device.getDeviceid(), e); //throw e; } } + public void checkSimCardTraffic(GnssStatusJoin 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 (warningService.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(warningService.getWarningLevel(status.getWarningcode())); + gnssStatusMapper.updateById(status); + } + } + + // 检查SIM卡状态 + public void checkSimCardStatus(GnssStatusJoin 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 (warningService.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) { + warningService.clearWarning(status, WarningCfg.TYPE_SIM_STATUS_ABNORMAL); + isUpdated = true; + } + } + + if (isUpdated) { + status.setWarning(warningService.getWarningLevel(status.getWarningcode())); + gnssStatusMapper.updateById(status); + } + } + } diff --git a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/sal/DbDeviceServiceImpl.java b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/sal/DbDeviceServiceImpl.java index 4ea65df1..b192aadf 100644 --- a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/sal/DbDeviceServiceImpl.java +++ b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/sal/DbDeviceServiceImpl.java @@ -44,7 +44,6 @@ public class DbDeviceServiceImpl implements DeviceService { device.setEcefy(gnssDevice.getEcefy()); device.setEcefz(gnssDevice.getEcefz()); device.setLoggingmode(gnssDevice.getLoggingmode()); - device.setIccid(gnssDevice.getIccid()); return device; } diff --git a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/sal/Device.java b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/sal/Device.java index 80e45b4f..70bad0b6 100644 --- a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/sal/Device.java +++ b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/sal/Device.java @@ -67,8 +67,6 @@ public class Device { Double iPose; Double iPosn; Double iPosd; - - String iccid; private BigDecimal remaining; private BigDecimal total; private BigDecimal used; diff --git a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/service/SimCardQueryService.java b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/service/SimCardQueryService.java deleted file mode 100644 index f2d12878..00000000 --- a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/service/SimCardQueryService.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.imdroid.sideslope.service; - -import com.imdroid.sideslope.sal.Device; -import com.imdroid.sideslope.simcard.*; - -public interface SimCardQueryService { - - // 查询卡基本信息 - BaseResponse queryCardInfo(Device device); - - // 查询卡状态 - BaseResponse queryCardStatus(Device device); - - // 查询流量信息 - BaseResponse queryGprs(Device device); - - // 查询卡详细信息 - BaseResponse queryCardDetail(Device device); - -} diff --git a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/service/WarningServiceImpl.java b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/service/WarningServiceImpl.java index a5ecc7fb..88ecc70c 100644 --- a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/service/WarningServiceImpl.java +++ b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/service/WarningServiceImpl.java @@ -13,8 +13,6 @@ import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import javax.annotation.PostConstruct; -import java.math.BigDecimal; -import java.math.RoundingMode; import java.time.Duration; import java.time.LocalDateTime; import java.util.List; @@ -264,79 +262,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); - } - } - public void generate_warning_logs(String device_id,int warning_type,String warning_type_name){ // 连续无固定解 和 掉电 警告 if (warning_type == WarningCfg.TYPE_NO_FIXED_RESULT || warning_type == WarningCfg.TYPE_LOW_VOLTAGE) { diff --git a/sec-beidou/src/main/java/com/imdroid/beidou/controller/APIController.java b/sec-beidou/src/main/java/com/imdroid/beidou/controller/APIController.java index a9b85e9b..0420ad28 100644 --- a/sec-beidou/src/main/java/com/imdroid/beidou/controller/APIController.java +++ b/sec-beidou/src/main/java/com/imdroid/beidou/controller/APIController.java @@ -1,6 +1,7 @@ package com.imdroid.beidou.controller; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.imdroid.common.util.ByteUtil; import com.imdroid.common.util.HexUtil; import com.imdroid.secapi.client.RtcmClient; import com.imdroid.secapi.dto.*; @@ -27,9 +28,9 @@ public class APIController extends BasicController{ @Autowired GnssMsgMapper msgMapper; @Autowired - GnssStatusMapper gnssStatusMapper; - @Autowired DeviceCacheCmdMapper cacheCmdMapper; + @Autowired + WarningMsgMapper warningMsgMapper; /****** config ack *******/ @PostMapping(value = "/api/config_ack") @@ -48,7 +49,8 @@ public class APIController extends BasicController{ } } else if(msgType == 0xd312){ - // 一致性检查 + // 工作周期一致性检查 + checkWorkCycle(device, configAck); } // 保存, debug 01 02上来的原始数据不保存 @@ -80,6 +82,33 @@ public class APIController extends BasicController{ return null; } + void checkWorkCycle(GnssDevice device, String cfgData){ + // d31200120081e76f010a09000001c2dd7ae1419ee148 + int pos = 10; + byte[] hexValues = ByteUtil.hexStringTobyte(cfgData); + byte workCycle = hexValues[pos++]; + byte workDur = hexValues[pos++]; + byte workOffset = hexValues[pos++]; + + GnssGroup gnssGroup = groupMapper.selectById(device.getGroup_id()); + if(gnssGroup != null){ + if(gnssGroup.getWork_cycle()!=workCycle || + gnssGroup.getActive_time()!=workDur || + gnssGroup.getActive_offset()!=workOffset){ + //产生告警 + WarningMsg warningMsg = new WarningMsg(); + warningMsg.setDeviceid(device.getDeviceid()); + warningMsg.setTenantid(device.getTenantid()); + warningMsg.setCreatetime(LocalDateTime.now()); + warningMsg.setDevicetype(WarningCfg.TYPE_GNSS); + warningMsg.setCode(WarningCfg.TYPE_CFG_ABNORMAL); + warningMsg.setLevel(WarningCfg.LEVEL_2); + warningMsg.setInfo(WarningCfg.TYPE_NAME_CFG_ABNORMAL); + warningMsgMapper.insert(warningMsg); + } + } + } + /****** device active *******/ @PostMapping(value = "/api/device_online") @ResponseBody diff --git a/sec-beidou/src/main/resources/templates/page/cmd_line.html b/sec-beidou/src/main/resources/templates/page/cmd_line.html index 85fca1dd..c99b5785 100644 --- a/sec-beidou/src/main/resources/templates/page/cmd_line.html +++ b/sec-beidou/src/main/resources/templates/page/cmd_line.html @@ -50,6 +50,7 @@ +