作者 钟来

修改bug

... ... @@ -40,6 +40,11 @@
<groupId>com.zhonglai.luhui</groupId>
<artifactId>lh-mqtt-service</artifactId>
</dependency>
<!-- 定时-->
<dependency>
<groupId>com.zhonglai.luhui</groupId>
<artifactId>lh-quartz</artifactId>
</dependency>
<!-- 文档 -->
<dependency >
<groupId>io.springfox</groupId>
... ... @@ -82,6 +87,20 @@
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
</dependency>
</dependencies>
<build>
... ...
... ... @@ -10,8 +10,10 @@ import org.springframework.context.annotation.ComponentScan;
"com.ruoyi.system",
"com.ruoyi.framework",
"com.ruoyi.generator",
"com.ruoyi.quartz",
"com.zhonglai.luhui.admin.config",
"com.zhonglai.luhui.admin.service",
"com.zhonglai.luhui.admin.task",
"com.zhonglai.luhui.admin.controller",
"com.zhonglai.luhui.mqtt.comm.service.redis",
"com.zhonglai.luhui.mqtt.service.db.mode"
... ...
package com.zhonglai.luhui.admin.controller.iot;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.IotAlert;
import com.ruoyi.system.service.IIotAlertService;
import com.zhonglai.luhui.admin.dto.AlarmActionConfig;
import com.zhonglai.luhui.admin.dto.AlarmTriggersConfig;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
... ... @@ -18,6 +23,7 @@ import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Optional;
/**
* 设备告警Controller
... ... @@ -80,6 +86,14 @@ public class IotAlertController extends BaseController
@PostMapping
public AjaxResult add(@RequestBody IotAlert alert)
{
if (checkTriggers(alert))
{
return AjaxResult.error("触发器参数必填");
}
if (checkActions(alert))
{
return AjaxResult.error("执行动作参数必填");
}
return toAjax(alertService.insertAlert(alert));
}
... ... @@ -92,6 +106,14 @@ public class IotAlertController extends BaseController
@PutMapping
public AjaxResult edit(@RequestBody IotAlert alert)
{
if (checkTriggers(alert))
{
return AjaxResult.error("触发器参数必填");
}
if (checkActions(alert))
{
return AjaxResult.error("执行动作参数必填");
}
return toAjax(alertService.updateAlert(alert));
}
... ... @@ -106,4 +128,34 @@ public class IotAlertController extends BaseController
{
return toAjax(alertService.deleteAlertByAlertIds(alertIds));
}
/**
* 检验触发器
* @return
*/
private boolean checkTriggers(IotAlert alert)
{
String triggers = Optional.ofNullable(alert).orElse(new IotAlert()).getTriggers();
if(StringUtils.isNotEmpty(triggers))
{
AlarmTriggersConfig alarmTriggersConfig = JSONObject.parseObject(triggers, AlarmTriggersConfig.class);
return BeanUtil.hasNullField(alarmTriggersConfig,"cron");
}
return false;
}
/**
* 检验执行动作
* @return
*/
private boolean checkActions(IotAlert alert)
{
String actions = Optional.ofNullable(alert).orElse(new IotAlert()).getActions();
if(StringUtils.isNotEmpty(actions))
{
AlarmActionConfig alarmActionConfig = JSONObject.parseObject(actions, AlarmActionConfig.class);
return BeanUtil.hasNullField(alarmActionConfig);
}
return false;
}
}
... ...
... ... @@ -69,39 +69,4 @@ public class IotAlertLogController extends BaseController
return AjaxResult.success(alertLogService.selectAlertLogByAlertLogId(alertLogId));
}
/**
* 新增设备告警
*/
@ApiOperation("新增设备告警")
@PreAuthorize("@ss.hasPermi('iot:alert:add')")
@Log(title = "设备告警", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody IotAlertLog alertLog)
{
return toAjax(alertLogService.insertAlertLog(alertLog));
}
/**
* 修改设备告警
*/
@ApiOperation("修改设备告警")
@PreAuthorize("@ss.hasPermi('iot:alert:edit')")
@Log(title = "设备告警", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody IotAlertLog alertLog)
{
return toAjax(alertLogService.updateAlertLog(alertLog));
}
/**
* 删除设备告警
*/
@ApiOperation("删除设备告警")
@PreAuthorize("@ss.hasPermi('iot:alert:remove')")
@Log(title = "设备告警", businessType = BusinessType.DELETE)
@DeleteMapping("/{alertLogIds}")
public AjaxResult remove(@PathVariable Long[] alertLogIds)
{
return toAjax(alertLogService.deleteAlertLogByAlertLogIds(alertLogIds));
}
}
... ...
package com.zhonglai.luhui.admin.dto;
import com.ruoyi.system.domain.IotThingsModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel("告警执行动作配置参数")
public class AlarmActionConfig {
@ApiModelProperty("条件类型(1属性,2功能)")
private String conditionType;
@ApiModelProperty("条件模型(对应物模型表)")
private IotThingsModel iotThingsModel;
@ApiModelProperty("值")
private Object value;
public String getConditionType() {
return conditionType;
}
public void setConditionType(String conditionType) {
this.conditionType = conditionType;
}
public IotThingsModel getIotThingsModel() {
return iotThingsModel;
}
public void setIotThingsModel(IotThingsModel iotThingsModel) {
this.iotThingsModel = iotThingsModel;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
}
... ...
package com.zhonglai.luhui.admin.dto;
import com.ruoyi.system.domain.IotThingsModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel("告警触发器配置参数")
public class AlarmTriggersConfig {
@ApiModelProperty("触发器类型(1设备触发,2定时触发)")
private Integer type;
@ApiModelProperty("条件类型(1属性,2功能,3事件,4设备上线,5设备下线)")
private String conditionType;
@ApiModelProperty("条件模型(对应物模型表)")
private IotThingsModel iotThingsModel;
@ApiModelProperty("条件逻辑符号(1等于(=),2不等于(!=),3大于(>),4小于(<),5大于等于(>=),6小于等于(<=),7包含(contain),8不包含(not contain))")
private String conditionLogic;
@ApiModelProperty("值")
private Object value;
@ApiModelProperty("定时器配置")
private String cron;
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
public String getConditionType() {
return conditionType;
}
public void setConditionType(String conditionType) {
this.conditionType = conditionType;
}
public String getConditionLogic() {
return conditionLogic;
}
public void setConditionLogic(String conditionLogic) {
this.conditionLogic = conditionLogic;
}
public IotThingsModel getIotThingsModel() {
return iotThingsModel;
}
public void setIotThingsModel(IotThingsModel iotThingsModel) {
this.iotThingsModel = iotThingsModel;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
public String getCron() {
return cron;
}
public void setCron(String cron) {
this.cron = cron;
}
}
... ...
package com.zhonglai.luhui.admin.task;
import org.springframework.stereotype.Component;
/**
* 告警定时器
*/
@Component("alarmTask")
public class AlarmTask {
}
... ...
package com.zhonglai.luhui.admin.task;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.domain.IotDevice;
import com.ruoyi.system.service.PublicService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@Component("deviceTask")
public class DeviceTask {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private PublicService publicService;
/**
* 终端在线状态检测
*/
public void terminalOnline()
{
int time = DateUtils.getNowTimeMilly()-6*60;
List<Map<String,Object>> list = publicService.getObjectListBySQL("SELECT id FROM `iot_terminal` a LEFT JOIN `iot_device` b ON a.`device_id`=b.`client_id` WHERE "+time+"-a.`data_update_time`>=b.`device_life` AND online=3");
StringBuffer stringBuffer = new StringBuffer();
Optional.ofNullable(list).orElse(new ArrayList<>()).forEach(stringObjectMap -> {
if(stringBuffer.length() != 0)
{
stringBuffer.append(",");
}
stringBuffer.append("'"+stringObjectMap.get("id")+"'");
});
int i = 0;
if(stringBuffer.length() != 0)
{
i = publicService.updateBySql("UPDATE `iot_terminal` SET online=4 WHERE id IN("+ stringBuffer +")");
}
logger.info("更新离线终端设备{}条",i);
}
/**
* 网关在线状态检测
*/
public void deviceOnline()
{
int time = DateUtils.getNowTimeMilly();
List<Map<String,Object>> list = publicService.getObjectListBySQL("SELECT client_id FROM `iot_device` WHERE "+time+"-data_update_time>=device_life AND status=3");
StringBuffer stringBuffer = new StringBuffer();
Optional.ofNullable(list).orElse(new ArrayList<>()).forEach(stringObjectMap -> {
if(stringBuffer.length() != 0)
{
stringBuffer.append(",");
}
stringBuffer.append("'"+stringObjectMap.get("client_id")+"'");
});
int i = 0;
if(stringBuffer.length() != 0)
{
i = publicService.updateBySql("UPDATE `iot_device` SET `status`=4 WHERE client_id IN("+ stringBuffer +")");
}
logger.info("更新离线网关设备{}条",i);
}
}
... ...
package com.zhonglai.luhui.admin.task;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.ssh.ChannelType;
import cn.hutool.extra.ssh.JschUtil;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSchException;
import com.zhonglai.luhui.mqtt.comm.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.io.*;
/**
* 日志定时器
*/
@Component("logTask")
public class LogTask {
/**
* mq设备服务日志采集
*/
public void mqDeviceServiceLogGather()
{
String cmd = "tail -f /root/hivemq-ce-2021.2/log/hivemq.log";
com.jcraft.jsch.Session session = JschUtil.createSession("175.24.61.68",22,"root","Luhui586");
try {
session.connect();
ChannelExec channel = (ChannelExec)JschUtil.createChannel(session, ChannelType.EXEC);
channel.setCommand(StrUtil.bytes(cmd, CharsetUtil.CHARSET_UTF_8));
channel.connect();
InputStream inputStream = channel.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuffer stringBuffer = new StringBuffer();
String lineOne = null;
String imei = null;
boolean islog = false;
while ((lineOne=bufferedReader.readLine())!=null)
{
if(lineOne.indexOf("》》【")>=0)
{
islog = true;
imei = lineOne.substring(lineOne.indexOf("|<")+2,lineOne.indexOf(">|"));
}
if(islog)
{
stringBuffer.append(lineOne);
}
if(lineOne.indexOf("】《《")>=0)
{
System.out.println(imei);
System.out.println(stringBuffer.toString());
islog=false;
imei = null;
stringBuffer = new StringBuffer();
}
}
} catch (JSchException | IOException e) {
throw new RuntimeException(e);
}finally {
JschUtil.close(session);
}
}
}
... ...
package com.zhonglai.luhui.admin.task;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.extra.mail.MailUtil;
import cn.hutool.extra.ssh.JschUtil;
import org.springframework.stereotype.Component;
import java.util.regex.Pattern;
/**
* 服务监听定时器
*/
@Component("serviceListenTask")
public class ServiceListenTask {
/**
* 检测hivemq服务是否正常运行
*/
public void mqDeviceServiceRunListen()
{
String cmd = "ps -ef|grep hivemq.jar";
com.jcraft.jsch.Session session = JschUtil.createSession("175.24.61.68",22,"root","Luhui586");
try {
String cmdbarck = JschUtil.exec(session,cmd,CharsetUtil.CHARSET_UTF_8);
String[] cmdbarcks = cmdbarck.split("\n");
boolean isrun = false;
if(null != cmdbarcks && cmdbarcks.length !=0)
{
for(String cs:cmdbarcks)
{
if(ReUtil.isMatch(getRunJar("hivemq.jar"), cs))
{
isrun = true;
}
}
}
if(!isrun)
{
String barckStr = JschUtil.exec(session,"systemctl restart hivemq.service", CharsetUtil.CHARSET_UTF_8);
MailUtil.send("harck24@qq.com","hivemq服务器异常提醒","hivemq服务器异常,以发送重启指令,指令返回结果:"+barckStr,false);
}
} catch (Exception e) {
throw new RuntimeException(e);
}finally {
JschUtil.close(session);
}
}
/**
* 匹配执行java程序
*/
public static Pattern getRunJar(String jarServiceName)
{
return Pattern.compile(".*java.* -jar .*"+jarServiceName);
}
}
... ...
# 邮件服务器的SMTP地址,可选,默认为smtp.<发件人邮箱后缀>可以自定义
host = smtp.qq.com
# 邮件服务器的SMTP端口,可选,默认25 465
port = 587
# 发件人邮箱地址
from = 409188680@qq.com
# 用户名,默认为发件人邮箱前缀
user = 409188680
# 密码(注意,某些邮箱需要为SMTP服务单独设置授权码 比如QQ邮箱)
pass = yczuddwwztcbcabe
#使用 STARTTLS安全连接,STARTTLS是对纯文本通信协议的扩展
starttlsEnable = true
# 需要设置为false 否则QQ邮箱测试邮件发送报错
sslEnable = false
\ No newline at end of file
... ...