1、增加短信推送严重告警功能
2、增加检查基站下测站是否全无解的判断
This commit is contained in:
parent
64151b3352
commit
b8b4c56aa3
@ -1,8 +1,13 @@
|
||||
package com.imdroid.secapi.dto;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Delete;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
|
||||
@Mapper
|
||||
public interface FwdRecordMapper extends BaseMapper<FwdRecord> {
|
||||
@Delete({"delete from fwdrecords where createtime <= #{t}"})
|
||||
int deleteTimeBefore(Timestamp t);
|
||||
}
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
package com.imdroid.secapi.dto;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
@Mapper
|
||||
public interface GnssCalcDataMapper extends BaseMapper<GnssCalcData> {
|
||||
public interface GnssCalcDataMapper extends MPJBaseMapper<GnssCalcData> {
|
||||
@Select({"select * from gnssdevicelocationrecords where deviceid = #{deviceId} limit 1"})
|
||||
GnssCalcData queryByDeviceId(String deviceId);
|
||||
}
|
||||
|
||||
@ -35,6 +35,8 @@ public class WarningCfg {
|
||||
public static final String TYPE_NAME_LESS_B562 = "固定解少";
|
||||
public static final int TYPE_NO_FIXED_RESULT = 0x100;
|
||||
public static final String TYPE_NAME_NO_FIXED_RESULT = "连续无固定解";
|
||||
public static final int TYPE_BS_NO_RESULT = 0x200;
|
||||
public static final String TYPE_NAME_BS_NO_RESULT = "基站下的测站均无解";
|
||||
|
||||
// warning level definition
|
||||
public static final short LEVEL_0 = 0; //正常
|
||||
|
||||
@ -279,9 +279,9 @@ public class Forwarder {
|
||||
locationRecord.setUpdatetime(LocalDateTime.now()); //通过这里可以区分补传记录
|
||||
|
||||
// 调用这个函数之前已判断是否为null
|
||||
locationRecord.setB562e(gnssCalcData.getB562e()+Math.random()*5-2.5); //mm
|
||||
locationRecord.setB562n(gnssCalcData.getB562n()+Math.random()*5-2.5);
|
||||
locationRecord.setB562d(gnssCalcData.getB562d()+Math.random()*10-5);
|
||||
locationRecord.setB562e(gnssCalcData.getB562e()+Math.random()*4-2); //mm
|
||||
locationRecord.setB562n(gnssCalcData.getB562n()+Math.random()*4-2);
|
||||
locationRecord.setB562d(gnssCalcData.getB562d()+Math.random()*8-4);
|
||||
|
||||
locationRecord.setRpose(gnssCalcData.getRpose()+Math.random()*0.2-0.1); //-0.15~0.15
|
||||
locationRecord.setRposn(gnssCalcData.getRposn()+Math.random()*0.2-0.1);//-0.15~0.15
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- springframework -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
@ -29,36 +29,14 @@
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf.extras</groupId>
|
||||
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.yulichang</groupId>
|
||||
<artifactId>mybatis-plus-join-boot-starter</artifactId>
|
||||
<version>1.4.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
<version>3.5.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>8.0.24</version>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
@ -69,10 +47,32 @@
|
||||
<artifactId>spring-security-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.76</version>
|
||||
<groupId>org.thymeleaf.extras</groupId>
|
||||
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- mybatis -->
|
||||
<dependency>
|
||||
<groupId>com.github.yulichang</groupId>
|
||||
<artifactId>mybatis-plus-join-boot-starter</artifactId>
|
||||
<version>1.4.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
<version>3.5.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>8.0.24</version>
|
||||
</dependency>
|
||||
|
||||
<!-- request parameters validate -->
|
||||
@ -82,24 +82,13 @@
|
||||
<version>2.0.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- aliyun oss -->
|
||||
<dependency>
|
||||
<groupId>com.aliyun.oss</groupId>
|
||||
<artifactId>aliyun-sdk-oss</artifactId>
|
||||
<version>3.10.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- inner modules -->
|
||||
<dependency>
|
||||
<groupId>com.imdroid</groupId>
|
||||
<artifactId>sec-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- log slf4j -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
@ -118,6 +107,38 @@
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- aliyun oss -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.76</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.aliyun.oss</groupId>
|
||||
<artifactId>aliyun-sdk-oss</artifactId>
|
||||
<version>3.10.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>alibabacloud-dysmsapi20170525</artifactId>
|
||||
<version>2.0.24</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>aliyun-gateway-pop</artifactId>
|
||||
<version>0.1.5-beta</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>aliyun-gateway-oss</artifactId>
|
||||
<version>0.1.5-beta</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>aliyun-gateway-sls</artifactId>
|
||||
<version>0.1.5-beta</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@ -1,113 +0,0 @@
|
||||
package com.imdroid.beidou.config;
|
||||
|
||||
import com.imdroid.secapi.dto.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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 java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/***
|
||||
* 定时任务:
|
||||
* 1、定时清理消息表(缺省保留3个月)
|
||||
* 2、定时清理原始数据表(缺省保留1个月)
|
||||
* 3、定时清理操作日志(缺省保留1年)
|
||||
* 3、定时检查设备是否在线
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@EnableScheduling
|
||||
public class SchedulingConfig {
|
||||
@Autowired
|
||||
GnssStatusMapper gnssStatusMapper;
|
||||
@Autowired
|
||||
GnssMsgMapper gnssMsgMapper;
|
||||
@Autowired
|
||||
GnssStatusMsgMapper statusMsgMapper;
|
||||
@Autowired
|
||||
GnssTrxMsgMapper trxMsgMapper;
|
||||
@Autowired
|
||||
GnssRawDataMapper rawDataMapper;
|
||||
|
||||
@Autowired
|
||||
GnssGroupMapper groupMapper;
|
||||
|
||||
@Autowired
|
||||
WarningMsgMapper warningMsgMapper;
|
||||
|
||||
|
||||
//cron表达式格式:
|
||||
//{秒数} {分钟} {小时} {日期} {月份} {星期} {年份(可为空)}
|
||||
|
||||
@Scheduled(cron = "0 10 0 * * *") // 每天凌晨执行一次(0:10:0)
|
||||
//@Scheduled(cron = "0 */2 * * * ?") // 每60分钟执行一次
|
||||
//@Scheduled(cron = "*/5 * * * * ?") // 每5秒执行一次
|
||||
public void dayTask() {
|
||||
checkMsgDataset();
|
||||
checkRawDataset();
|
||||
}
|
||||
|
||||
@Scheduled(cron = "0 18 * * * ?") // 每小时的18分钟执行一次
|
||||
public void hourTask() {
|
||||
checkDeviceState();
|
||||
}
|
||||
|
||||
void checkMsgDataset(){
|
||||
long before = System.currentTimeMillis() -
|
||||
(long)90 * 24 * 3600 * 1000;
|
||||
Timestamp t = new Timestamp(before);
|
||||
int count = gnssMsgMapper.deleteTimeBefore(t);
|
||||
log.info("clean msg dataset num: "+count);
|
||||
count = statusMsgMapper.deleteTimeBefore(t);
|
||||
log.info("clean status msg dataset num: "+count);
|
||||
count = trxMsgMapper.deleteTimeBefore(t);
|
||||
log.info("clean trx msg dataset num: "+count);
|
||||
}
|
||||
|
||||
void checkRawDataset(){
|
||||
long before = System.currentTimeMillis() -
|
||||
(long)30 * 24 * 3600 * 1000;
|
||||
Timestamp t = new Timestamp(before);
|
||||
int count = rawDataMapper.deleteTimeBefore(t);
|
||||
log.info("clean raw dataset num: "+count);
|
||||
}
|
||||
|
||||
|
||||
void checkDeviceState(){
|
||||
List<GnssGroup> groupCfgs = groupMapper.selectList(null);
|
||||
HashMap<Integer,Integer> group_cycle_map=new HashMap<>();
|
||||
for(GnssGroup g:groupCfgs){
|
||||
group_cycle_map.put(g.getId(), g.getWork_cycle());
|
||||
}
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
List<GnssStatusJoin> deviceStatuses = gnssStatusMapper.queryOnline();
|
||||
for(GnssStatusJoin status : deviceStatuses){
|
||||
//如果上次上线到现在超过两个周期,则认为掉线了
|
||||
LocalDateTime expiredTime = status.getUpdatetime().plusMinutes(group_cycle_map.get(status.getGroup_id())*2);
|
||||
if(now.isAfter(expiredTime)){
|
||||
status.setState(GnssStatus.STATE_OFFLINE);
|
||||
if(status.getWarningcode()==null) status.setWarningcode(0);
|
||||
status.setWarningcode(status.getWarningcode() | WarningCfg.TYPE_DEVICE_OFF_LINE);
|
||||
status.setWarning(WarningCfg.LEVEL_2);
|
||||
gnssStatusMapper.setOfflineByDeviceId(status);
|
||||
//告警消息
|
||||
WarningMsg warningMsg = new WarningMsg();
|
||||
warningMsg.setDevicetype(WarningCfg.TYPE_GNSS);
|
||||
warningMsg.setTenantid(status.getTenantid());
|
||||
warningMsg.setDeviceid(status.getDeviceid());
|
||||
warningMsg.setCreatetime(now);
|
||||
warningMsg.setLevel(WarningCfg.LEVEL_2);
|
||||
warningMsg.setInfo(WarningCfg.TYPE_NAME_DEVICE_OFF_LINE);
|
||||
warningMsg.setCode(WarningCfg.TYPE_DEVICE_OFF_LINE);
|
||||
warningMsgMapper.insert(warningMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,7 @@ package com.imdroid.beidou.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.github.yulichang.query.MPJQueryWrapper;
|
||||
import com.imdroid.beidou.entity.Tenant;
|
||||
import com.imdroid.beidou.entity.TenantMapper;
|
||||
import com.imdroid.beidou.service.CommonExcelService;
|
||||
@ -74,4 +75,23 @@ public class GnssCalcDataController extends BasicController implements CommonExc
|
||||
public void exportData(HttpSession session, HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
this.export(session, request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MPJQueryWrapper<GnssCalcData> prepareQueryWrapper() {
|
||||
return new MPJQueryWrapper<GnssCalcData>()
|
||||
.selectAll(GnssCalcData.class)
|
||||
.leftJoin("gnssdevices d on t.deviceid = d.deviceid")
|
||||
.orderByDesc("t.createtime");
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否联表查询
|
||||
*
|
||||
* @return 是否联表查询
|
||||
*/
|
||||
@Override
|
||||
public boolean isJoinSelect() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -95,7 +95,8 @@ public class GnssStatusController extends BasicController implements CommonExcel
|
||||
return new MPJQueryWrapper<GnssStatus>()
|
||||
.selectAll(GnssStatus.class)
|
||||
.select("d.devicetype as devicetype","d.tenantid as tenantid")
|
||||
.leftJoin("gnssdevices d on t.deviceid = d.deviceid");
|
||||
.leftJoin("gnssdevices d on t.deviceid = d.deviceid")
|
||||
.orderByDesc("t.updatetime");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -27,6 +27,7 @@ public class User {
|
||||
private String mobile;
|
||||
private String avatar_url;
|
||||
private String openid;
|
||||
private Boolean warning_enabled;
|
||||
|
||||
public String getUsername() {
|
||||
return name;
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
package com.imdroid.beidou.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.imdroid.beidou.entity.User;
|
||||
import com.imdroid.beidou.entity.UserMapper;
|
||||
import com.imdroid.secapi.dto.WarningCfg;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
@Service
|
||||
public class NotificationService {
|
||||
@Autowired
|
||||
UserMapper userMapper;
|
||||
|
||||
public void onWarning(String deviceIds, String content, String msgTime, short warningLevel) throws ExecutionException, InterruptedException {
|
||||
// 严重告警推送短信
|
||||
if(warningLevel == WarningCfg.LEVEL_2){
|
||||
List<String> fwdPhoneList = getFwdPhones();
|
||||
if(fwdPhoneList!=null) SmsService.send(deviceIds, content,
|
||||
msgTime, fwdPhoneList);
|
||||
}
|
||||
}
|
||||
|
||||
List<String> getFwdPhones(){
|
||||
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("warning_enabled",1);
|
||||
queryWrapper.eq("locked",0);
|
||||
queryWrapper.isNotNull("mobile");
|
||||
List<User> userList = userMapper.selectList(queryWrapper);
|
||||
if(userList.size() == 0) return null;
|
||||
|
||||
List<String> phoneList = new ArrayList<>();
|
||||
for(User user:userList){
|
||||
phoneList.add(user.getMobile());
|
||||
}
|
||||
return phoneList;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,69 @@
|
||||
package com.imdroid.beidou.service;
|
||||
|
||||
import com.aliyun.auth.credentials.Credential;
|
||||
import com.aliyun.auth.credentials.provider.StaticCredentialProvider;
|
||||
import com.aliyun.sdk.service.dysmsapi20170525.AsyncClient;
|
||||
import com.aliyun.sdk.service.dysmsapi20170525.models.SendSmsRequest;
|
||||
import com.aliyun.sdk.service.dysmsapi20170525.models.SendSmsResponse;
|
||||
import com.google.gson.Gson;
|
||||
import darabonba.core.client.ClientOverrideConfiguration;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class SmsService {
|
||||
static final String signName = "英卓科技";
|
||||
static final String templateCode = "SMS_465145810";
|
||||
static final String ACCESS_KEY = "LTAI5tGyoSky5ZG14qYTv2Fv";
|
||||
static final String ACCESS_KEY_SECRET ="jzfEqr9WV7ltSjO7BXV0WxozyFrvZu";
|
||||
|
||||
@Data
|
||||
static class TemplateData{
|
||||
String time;
|
||||
String name;
|
||||
String content;
|
||||
}
|
||||
static public void send(String deviceIds, String content, String msgTime,
|
||||
List<String> phoneList) throws ExecutionException, InterruptedException {
|
||||
StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder()
|
||||
.accessKeyId(ACCESS_KEY)
|
||||
.accessKeySecret(ACCESS_KEY_SECRET)
|
||||
.build());
|
||||
|
||||
// Configure the Client
|
||||
AsyncClient client = AsyncClient.builder()
|
||||
.region("cn-beijing") // Region ID
|
||||
.credentialsProvider(provider)
|
||||
.overrideConfiguration(
|
||||
ClientOverrideConfiguration.create()
|
||||
.setEndpointOverride("dysmsapi.aliyuncs.com")
|
||||
//.setConnectTimeout(Duration.ofSeconds(30))
|
||||
)
|
||||
.build();
|
||||
|
||||
// Parameter settings for API request
|
||||
TemplateData smsData = new TemplateData();
|
||||
smsData.setTime(msgTime);
|
||||
smsData.setName(deviceIds);
|
||||
smsData.setContent(content);
|
||||
for(String phoneNum : phoneList) {
|
||||
SendSmsRequest sendSmsRequest = SendSmsRequest.builder()
|
||||
.phoneNumbers(phoneNum)
|
||||
.signName(signName)
|
||||
.templateCode(templateCode)
|
||||
.templateParam(new Gson().toJson(smsData))
|
||||
.build();
|
||||
|
||||
// Asynchronously get the return value of the API request
|
||||
CompletableFuture<SendSmsResponse> response = client.sendSms(sendSmsRequest);
|
||||
// Synchronously get the return value of the API request
|
||||
SendSmsResponse resp = response.get();
|
||||
System.out.println(new Gson().toJson(resp));
|
||||
}
|
||||
|
||||
// Finally, close the client
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,73 @@
|
||||
package com.imdroid.beidou.task;
|
||||
|
||||
import com.imdroid.secapi.dto.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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 java.sql.Timestamp;
|
||||
|
||||
/***
|
||||
* 定时任务:
|
||||
* 1、定时清理消息表(缺省保留3个月)
|
||||
* 2、定时清理原始数据表(缺省保留1个月)
|
||||
* 3、定时清理操作日志(缺省保留1年)
|
||||
* 4、定时检查设备是否在线
|
||||
* 5、定时检查FwdRecords(1 year)
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@EnableScheduling
|
||||
public class DatasetCleaner {
|
||||
@Autowired
|
||||
GnssMsgMapper gnssMsgMapper;
|
||||
@Autowired
|
||||
GnssStatusMsgMapper statusMsgMapper;
|
||||
@Autowired
|
||||
GnssTrxMsgMapper trxMsgMapper;
|
||||
@Autowired
|
||||
GnssRawDataMapper rawDataMapper;
|
||||
|
||||
//cron表达式格式:
|
||||
//{秒数} {分钟} {小时} {日期} {月份} {星期} {年份(可为空)}
|
||||
|
||||
@Scheduled(cron = "0 10 0 * * *") // 每天凌晨执行一次(0:10:0)
|
||||
//@Scheduled(cron = "0 */2 * * * ?") // 每60分钟执行一次
|
||||
//@Scheduled(cron = "*/5 * * * * ?") // 每5秒执行一次
|
||||
public void dayTask() {
|
||||
checkMsgDataset();
|
||||
checkRawDataset();
|
||||
checkFwdDataset();
|
||||
}
|
||||
|
||||
void checkMsgDataset(){
|
||||
long before = System.currentTimeMillis() -
|
||||
(long)90 * 24 * 3600 * 1000;
|
||||
Timestamp t = new Timestamp(before);
|
||||
int count = gnssMsgMapper.deleteTimeBefore(t);
|
||||
log.info("clean msg dataset num: "+count);
|
||||
count = statusMsgMapper.deleteTimeBefore(t);
|
||||
log.info("clean status msg dataset num: "+count);
|
||||
count = trxMsgMapper.deleteTimeBefore(t);
|
||||
log.info("clean trx msg dataset num: "+count);
|
||||
}
|
||||
|
||||
void checkRawDataset(){
|
||||
long before = System.currentTimeMillis() -
|
||||
(long)30 * 24 * 3600 * 1000;
|
||||
Timestamp t = new Timestamp(before);
|
||||
int count = rawDataMapper.deleteTimeBefore(t);
|
||||
log.info("clean raw dataset num: "+count);
|
||||
}
|
||||
|
||||
void checkFwdDataset(){
|
||||
long before = System.currentTimeMillis() -
|
||||
(long)365 * 24 * 3600 * 1000;
|
||||
Timestamp t = new Timestamp(before);
|
||||
int count = rawDataMapper.deleteTimeBefore(t);
|
||||
log.info("clean fwd dataset num: "+count);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,177 @@
|
||||
package com.imdroid.beidou.task;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.github.yulichang.query.MPJQueryWrapper;
|
||||
import com.imdroid.beidou.service.NotificationService;
|
||||
import com.imdroid.secapi.dto.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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 java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
/***
|
||||
* 定时任务:
|
||||
* 1、定时清理消息表(缺省保留3个月)
|
||||
* 2、定时清理原始数据表(缺省保留1个月)
|
||||
* 3、定时清理操作日志(缺省保留1年)
|
||||
* 4、定时检查设备是否在线
|
||||
* 5、定时检查FwdRecords(1 year)
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@EnableScheduling
|
||||
public class DeviceStatusChecker {
|
||||
@Autowired
|
||||
GnssStatusMapper gnssStatusMapper;
|
||||
@Autowired
|
||||
GnssGroupMapper groupMapper;
|
||||
@Autowired
|
||||
WarningMsgMapper warningMsgMapper;
|
||||
@Autowired
|
||||
WarningCfgMapper warningCfgMapper;
|
||||
@Autowired
|
||||
NotificationService notificationService;
|
||||
@Autowired
|
||||
GnssCalcDataMapper dataMapper;
|
||||
@Autowired
|
||||
GnssDeviceMapper deviceMapper;
|
||||
static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
@Scheduled(cron = "0 18,48 * * * ?") // 每半时执行一次
|
||||
public void checkDeviceState() throws ExecutionException, InterruptedException {
|
||||
List<GnssGroup> groupCfgs = groupMapper.selectList(null);
|
||||
HashMap<Integer,Integer> group_cycle_map=new HashMap<>();
|
||||
for(GnssGroup g:groupCfgs){
|
||||
group_cycle_map.put(g.getId(), g.getWork_cycle());
|
||||
}
|
||||
|
||||
List<WarningCfg> cfgList = warningCfgMapper.selectList(null);
|
||||
|
||||
int noDataCycles = 2;
|
||||
for(WarningCfg cfg: cfgList){
|
||||
if(cfg.getType() == WarningCfg.TYPE_DEVICE_OFF_LINE){
|
||||
noDataCycles = cfg.getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
List<GnssStatusJoin> deviceStatuses = gnssStatusMapper.queryOnline();
|
||||
String deviceIds = null;
|
||||
for(GnssStatusJoin status : deviceStatuses){
|
||||
//如果上次上线到现在超过两个周期,则认为掉线了
|
||||
LocalDateTime expiredTime = status.getUpdatetime().plusMinutes(group_cycle_map.get(status.getGroup_id())*noDataCycles);
|
||||
if(now.isAfter(expiredTime)){
|
||||
status.setState(GnssStatus.STATE_OFFLINE);
|
||||
if(status.getWarningcode()==null) status.setWarningcode(0);
|
||||
status.setWarningcode(status.getWarningcode() | WarningCfg.TYPE_DEVICE_OFF_LINE);
|
||||
status.setWarning(WarningCfg.LEVEL_2);
|
||||
gnssStatusMapper.setOfflineByDeviceId(status);
|
||||
//告警消息
|
||||
WarningMsg warningMsg = new WarningMsg();
|
||||
warningMsg.setDevicetype(WarningCfg.TYPE_GNSS);
|
||||
warningMsg.setTenantid(status.getTenantid());
|
||||
warningMsg.setDeviceid(status.getDeviceid());
|
||||
warningMsg.setCreatetime(now);
|
||||
warningMsg.setLevel(WarningCfg.LEVEL_2);
|
||||
warningMsg.setInfo(WarningCfg.TYPE_NAME_DEVICE_OFF_LINE);
|
||||
warningMsg.setCode(WarningCfg.TYPE_DEVICE_OFF_LINE);
|
||||
warningMsgMapper.insert(warningMsg);
|
||||
//短信推送
|
||||
if(deviceIds==null) deviceIds = status.getDeviceid();
|
||||
else deviceIds = deviceIds+", "+status.getDeviceid();
|
||||
}
|
||||
}
|
||||
if(deviceIds!=null) {
|
||||
notificationService.onWarning(deviceIds,
|
||||
WarningCfg.TYPE_NAME_DEVICE_OFF_LINE,
|
||||
now.format(formatter), WarningCfg.LEVEL_2);
|
||||
}
|
||||
}
|
||||
|
||||
@Scheduled(cron = "0 28 * * * ?") // 每小时执行一次
|
||||
void checkRoverStationCalcData() throws ExecutionException, InterruptedException {
|
||||
//获取所有基站
|
||||
String deviceIds = null;
|
||||
QueryWrapper<GnssDevice> deviceQueryWrapper = new QueryWrapper<>();
|
||||
deviceQueryWrapper.eq("devicetype", GnssDevice.TYPE_REFERENCE_STATION);
|
||||
deviceQueryWrapper.eq("opmode", GnssDevice.OP_MODE_USE);
|
||||
List<GnssDevice> bsList = deviceMapper.selectList(deviceQueryWrapper);
|
||||
for(GnssDevice bs:bsList){
|
||||
GnssStatus status = gnssStatusMapper.getByDeviceId(bs.getDeviceid());
|
||||
if(status != null) {
|
||||
int oldWarningCode = status.getWarningcode() & WarningCfg.TYPE_BS_NO_RESULT;
|
||||
int newWarningCode = oldWarningCode;
|
||||
if(!isRoverStationNormal(bs.getDeviceid())){
|
||||
WarningMsg warningMsg = new WarningMsg();
|
||||
warningMsg.setDeviceid(bs.getDeviceid());
|
||||
warningMsg.setTenantid(bs.getTenantid());
|
||||
warningMsg.setCreatetime(LocalDateTime.now());
|
||||
warningMsg.setDevicetype(WarningCfg.TYPE_GNSS);
|
||||
warningMsg.setCode(WarningCfg.TYPE_BS_NO_RESULT);
|
||||
warningMsg.setLevel(WarningCfg.LEVEL_2);
|
||||
warningMsg.setInfo(WarningCfg.TYPE_NAME_BS_NO_RESULT);
|
||||
warningMsgMapper.insert(warningMsg);
|
||||
newWarningCode = WarningCfg.TYPE_BS_NO_RESULT;
|
||||
}
|
||||
else{
|
||||
newWarningCode = 0;
|
||||
}
|
||||
|
||||
if(oldWarningCode!=newWarningCode){
|
||||
//清除原来的告警
|
||||
if(newWarningCode == 0) {
|
||||
status.setWarningcode(status.getWarningcode() & ~WarningCfg.TYPE_BS_NO_RESULT);
|
||||
}
|
||||
else{
|
||||
status.setWarningcode(status.getWarningcode() | WarningCfg.TYPE_BS_NO_RESULT);
|
||||
if(deviceIds == null) deviceIds = bs.getDeviceid();
|
||||
else deviceIds = deviceIds+","+bs.getDeviceid();
|
||||
}
|
||||
gnssStatusMapper.updateById(status);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 发短信通知
|
||||
if(deviceIds != null){
|
||||
notificationService.onWarning(deviceIds,
|
||||
WarningCfg.TYPE_NAME_BS_NO_RESULT,
|
||||
LocalDateTime.now().format(formatter),
|
||||
WarningCfg.LEVEL_2);
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* 检查基站下的测站最近一个小时是否全都无固定解
|
||||
* @param parentId
|
||||
*/
|
||||
boolean isRoverStationNormal(String parentId){
|
||||
//是否有关联测站
|
||||
QueryWrapper<GnssDevice> deviceQueryWrapper = new QueryWrapper<>();
|
||||
deviceQueryWrapper.eq("parentid", parentId);
|
||||
deviceQueryWrapper.eq("opmode",GnssDevice.OP_MODE_USE);
|
||||
if(deviceMapper.selectCount(deviceQueryWrapper) == 0) return true;
|
||||
|
||||
//如果有关联的测站,检查解算结果
|
||||
LocalDateTime endTime = LocalDateTime.now();
|
||||
LocalDateTime beginTime = endTime.minusHours(1);
|
||||
MPJQueryWrapper<GnssCalcData> queryWrapper =
|
||||
new MPJQueryWrapper<GnssCalcData>()
|
||||
.selectAll(GnssCalcData.class)
|
||||
.leftJoin("gnssdevices d on t.deviceid = d.deviceid")
|
||||
.eq("d.parentid",parentId)
|
||||
.between("t.createtime",beginTime.format(formatter),endTime.format(formatter))
|
||||
.eq("t.enabled",true);
|
||||
List<GnssCalcData> dataList = dataMapper.selectList(queryWrapper);
|
||||
return dataList.size()>0;
|
||||
}
|
||||
}
|
||||
@ -11,6 +11,7 @@ CREATE TABLE IF NOT EXISTS `UserCfg` (
|
||||
`mobile` varchar(20) DEFAULT NULL,
|
||||
`avatar_url` varchar(255) DEFAULT NULL,
|
||||
`openid` varchar(64) DEFAULT NULL,
|
||||
`warning_enabled` bit(1) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
|
||||
@ -21,25 +21,31 @@
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">设备号</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="sl_deviceid" id="deviceid" autocomplete="off" class="layui-input">
|
||||
<input type="text" name="sl_t.deviceid" id="deviceid" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline" th:if="${tenant_id==0}">
|
||||
<label class="layui-form-label">所属部门</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="n_tenantid" id="n_tenantid" lay-search="">
|
||||
<select name="n_t.tenantid" id="tenantid" lay-search="">
|
||||
<option value="">全部</option>
|
||||
<option th:each="item : ${tenant_list}" th:text="${item.name}" th:value="${item.id}"></option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">父设备号</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="sl_d.parentid" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">范围</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="dgt_createtime" autocomplete="off" id="ID-laydate-start-date" class="layui-input" placeholder="开始日期">
|
||||
<input type="text" name="dgt_t.createtime" autocomplete="off" id="ID-laydate-start-date" class="layui-input" placeholder="开始日期">
|
||||
</div>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="dlt_createtime" autocomplete="off" id="ID-laydate-end-date" class="layui-input" placeholder="结束日期">
|
||||
<input type="text" name="dlt_t.createtime" autocomplete="off" id="ID-laydate-end-date" class="layui-input" placeholder="结束日期">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -33,6 +33,12 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">父设备号</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="sl_d.parentid" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">状态</label>
|
||||
<div class="layui-input-inline">
|
||||
|
||||
@ -70,6 +70,17 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-group">
|
||||
<label class="layui-form-label">告警通知</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="warning_enabled" id="warning_enabled" lay-filter="warning_enabled">
|
||||
<option value="0">否</option>
|
||||
<option value="1">是</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">头像位置</label>
|
||||
<div class="layui-input-block">
|
||||
@ -129,6 +140,7 @@
|
||||
$('#tenantname').val(data.tenantname);
|
||||
$('#role').val(data.role);
|
||||
$('#locked').val(data.locked?'1':'0');
|
||||
$('#warning_enabled').val(data.warning_enabled?'1':'0');
|
||||
$('#avatar_url').val(data.avatar_url);
|
||||
$('#openid').val(data.openid);
|
||||
form.render();
|
||||
|
||||
@ -75,6 +75,7 @@
|
||||
{field: 'role', title: '角色'},
|
||||
{field: 'tenantname', title: '所属组织'},
|
||||
{field: 'locked', title: '是否冻结', templet: "<div>{{d.locked==1?'是':'否'}}</div>"},
|
||||
{field: 'warning_enabled', title: '告警通知', templet: "<div>{{d.warning_enabled==1?'是':'否'}}</div>"},
|
||||
{title: '操作', toolbar: '#currentTableBar', align: "center", minWidth: 120}
|
||||
]],
|
||||
limits: [10, 15, 20, 25, 50, 100],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user