Browse Source

1、网关设备离线异常微信通知

dev
25604 1 week ago
parent
commit
74bd1c014d
  1. 2
      user-service/src/main/java/com/mh/user/entity/GatewayManageEntity.java
  2. 81
      user-service/src/main/java/com/mh/user/job/PushDataToWechatJob.java
  3. 12
      user-service/src/main/java/com/mh/user/mapper/chillers/GatewayManageMapper.java
  4. 2
      user-service/src/main/java/com/mh/user/netty/EchoServerHandler.java
  5. 9
      user-service/src/main/java/com/mh/user/service/GatewayManageService.java
  6. 17
      user-service/src/main/java/com/mh/user/service/impl/GatewayManageServiceImpl.java
  7. 2
      user-service/src/main/java/com/mh/user/service/wechat/WechatService.java
  8. 50
      user-service/src/main/java/com/mh/user/service/wechat/impl/WechatServiceImpl.java
  9. 66
      user-service/src/main/java/com/mh/user/utils/TemplateType.java
  10. 2
      user-service/src/main/resources/application-dev.yml
  11. 2
      user-service/src/main/resources/application.yml
  12. 2
      user-service/src/test/java/com/mh/user/WechatTest.java

2
user-service/src/main/java/com/mh/user/entity/GatewayManageEntity.java

@ -36,5 +36,7 @@ public class GatewayManageEntity extends BaseEntity {
private int grade; // 标志位(连接状态) 0:正常;1:不在线;2:异常
private Long systemId; // 系统类型id
private Long projectId; // 项目类型id
private Long sendWechatNum; // 发送次数
private Date sendWechatTime; // 发送时间次数
}

81
user-service/src/main/java/com/mh/user/job/PushDataToWechatJob.java

@ -1,9 +1,11 @@
package com.mh.user.job;
import com.mh.user.entity.EnergyDataEntity;
import com.mh.user.entity.GatewayManageEntity;
import com.mh.user.entity.ProjectInfoEntity;
import com.mh.user.entity.wechat.*;
import com.mh.user.service.EnergyDataService;
import com.mh.user.service.GatewayManageService;
import com.mh.user.service.ProjectInfoService;
import com.mh.user.service.wechat.WechatService;
import com.mh.user.utils.DateUtil;
@ -16,11 +18,14 @@ import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author LJF
@ -42,6 +47,51 @@ public class PushDataToWechatJob {
@Autowired
private WechatService wechatService;
@Autowired
private GatewayManageService gatewayManageService;
@Scheduled(cron = " 0 30 0/1 * * ? ")
public void pushGatewayOffLine() {
// 判断当前时间是不是凌晨00点
// 获取当前小时是否等于00点
LocalDateTime now = LocalDateTime.now();
boolean isMidnight = now.getHour() == 0;
if (isMidnight) {
// 执行凌晨特定逻辑,更新发送时间
gatewayManageService.updateSendTime();
}
// 每个小时提醒一次设备掉线,需要处理
// 1、查询当前小时不在线的网关
List<GatewayManageEntity> sendList = gatewayManageService.selectSendWechatData();
// 2、判读是否发送过三次了,三次的就过滤掉
List<GatewayManageEntity> collect = sendList.stream().filter(val -> val.getSendWechatNum() == null || val.getSendWechatNum() <= 3).collect(Collectors.toList());
// 3、遍历发送
for (GatewayManageEntity val : collect) {
// j7Z-9D0ViY0KXHR3ZX7ttuism1npGYXdewjvosTZy9Q
List<Map<String, Object>> proInfo = gatewayManageService.selectProjectInfoByGwId(val.getId());
for (Map<String, Object> map : proInfo) {
PushMsgEntity pushMsgEntity = new PushMsgEntity();
// 判断模板id种类
switch (map.get("template_id").toString()) {
case "LrSu6VlICV9sTIWZgl8SF7bFI7TfqbSpeJ-cvPaTe6I":
// 推送单种设备消息
pushOffLineGw(val, map, pushMsgEntity);
break;
default:
break;
}
wechatService.pushMsg(pushMsgEntity);
}
if (!proInfo.isEmpty()) {
// 不管成不成功,都更新推送次数和推送时间
val.setSendWechatNum(val.getSendWechatNum() == null ? 0 : val.getSendWechatNum() + 1);
val.setSendWechatTime(new Date());
gatewayManageService.update(val);
}
}
}
@Scheduled(cron = " 0 0 8 * * ? ") //每天八点钟推送上一天的数据能耗
public void pushDataToWechat() {
log.info("推送给微信公众号");
@ -76,7 +126,7 @@ public class PushDataToWechatJob {
default:
break;
}
wechatService.PushMsg(pushMsgEntity);
wechatService.pushMsg(pushMsgEntity);
}
}
}
@ -152,4 +202,33 @@ public class PushDataToWechatJob {
pushMsgEntity.setKey5(key5);
}
private static void pushOffLineGw(GatewayManageEntity gw, Map<String, Object> map, PushMsgEntity pushMsgEntity) {
// 站点名称 {{thing19.DATA}}
// 设备名称 {{thing25.DATA}}
// 设备编号 {{character_string7.DATA}}
// 报警原因 {{thing4.DATA}}
// 报警时间 {{time3.DATA}}
pushMsgEntity.setTouser(map.get("open_id").toString());
pushMsgEntity.setTemplateId(map.get("template_id").toString());
pushMsgEntity.setUrl("http://jnd2.mhwsh.net:8765/");
First first = new First();
first.setValue("设备报警提醒");
pushMsgEntity.setFirst(first);
Key1 key1 = new Key1();
key1.setValue(map.get("project_name").toString());
pushMsgEntity.setKey1(key1);
Key2 key2 = new Key2();
key2.setValue(gw.getGwName());
pushMsgEntity.setKey2(key2);
Key3 key3 = new Key3();
key3.setValue(gw.getGwAddr());
pushMsgEntity.setKey3(key3);
Key4 key4 = new Key4();
key4.setValue("设备已离线,请及时查看处理!");
pushMsgEntity.setKey4(key4);
Key5 key5 = new Key5();
key5.setValue(DateUtil.dateToString(gw.getConnectTime(), "yyyy-MM-dd HH:mm:ss"));
pushMsgEntity.setKey5(key5);
}
}

12
user-service/src/main/java/com/mh/user/mapper/chillers/GatewayManageMapper.java

@ -7,6 +7,7 @@ import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
/**
* author: ljf
@ -75,5 +76,16 @@ public interface GatewayManageMapper extends BaseMapper<GatewayManageEntity> {
@Select("select project_Name from project_info a join gateway_manage b on a.id=b.project_id and b.port=#{str} ")
String selectProjectName(@Param("str") String str);
@Select("SELECT * FROM gateway_manage WHERE connect_time < DATEADD(HOUR, DATEDIFF(HOUR, 0, GETDATE()), 0) ")
List<GatewayManageEntity> selectSendWechatData();
@Update("update gateway_manage set send_wechat_time = getdate() where send_wechat_time = DATEADD(HOUR, DATEDIFF(HOUR, 0, GETDATE()), 0)")
void updateSendTime();
@Select("select pi.project_name,wt.template_id,wui.open_id from wechat_template_project wtp join " +
" project_info pi on wtp.project_id = pi.id " +
" join wechat_template wt on wtp.template_id = wt.id " +
" join wechat_user_info wui on wtp.wechat_user_id = wui.id " +
" where wtp.gw_id = #{id} and wui.is_status = 1 ")
List<Map<String, Object>> selectProjectInfoByGwId(Long id);
}

2
user-service/src/main/java/com/mh/user/netty/EchoServerHandler.java

@ -204,6 +204,8 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
// 解析采集的报文,并保存到数据库
AnalysisReceiveOrder485 analysisReceiveOrder485 = new AnalysisReceiveOrder485();
analysisReceiveOrder485.analysisReceiveOrder485(receiveStr, deviceCodeParamEntity);
// 根据项目id更新网关在线
gatewayManageService.updateGatewayManage2(deviceCodeParamEntity.getDataPort());
});
}

9
user-service/src/main/java/com/mh/user/service/GatewayManageService.java

@ -2,6 +2,9 @@ package com.mh.user.service;
import com.mh.user.entity.GatewayManageEntity;
import java.util.List;
import java.util.Map;
/**
* 新增网关服务管理
*/
@ -9,4 +12,10 @@ public interface GatewayManageService extends BaseService<GatewayManageEntity> {
String selectProjectName(String port);
void updateGatewayManage2(String port);
List<GatewayManageEntity> selectSendWechatData();
void updateSendTime();
List<Map<String, Object>> selectProjectInfoByGwId(Long id);
}

17
user-service/src/main/java/com/mh/user/service/impl/GatewayManageServiceImpl.java

@ -13,8 +13,10 @@ import com.mh.user.service.GatewayManageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @author LJF
@ -82,4 +84,19 @@ public class GatewayManageServiceImpl implements GatewayManageService {
public void updateGatewayManage2(String port) {
gatewayManageMapper.updateGatewayManage2(port);
}
@Override
public List<GatewayManageEntity> selectSendWechatData() {
return gatewayManageMapper.selectSendWechatData();
}
@Override
public void updateSendTime() {
gatewayManageMapper.updateSendTime();
}
@Override
public List<Map<String, Object>> selectProjectInfoByGwId(Long id) {
return gatewayManageMapper.selectProjectInfoByGwId(id);
}
}

2
user-service/src/main/java/com/mh/user/service/wechat/WechatService.java

@ -12,7 +12,7 @@ import java.util.Map;
*/
public interface WechatService {
void PushMsg(PushMsgEntity pushMsgEntity);
void pushMsg(PushMsgEntity pushMsgEntity);
List<Map<String, Object>> queryWechatUser(String projectId);
}

50
user-service/src/main/java/com/mh/user/service/wechat/impl/WechatServiceImpl.java

@ -7,6 +7,7 @@ import com.mh.user.entity.wechat.PushMsgEntity;
import com.mh.user.mapper.wechat.WechatMapper;
import com.mh.user.service.wechat.WechatService;
import com.mh.user.utils.CacheUtil;
import com.mh.user.utils.TemplateType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
@ -58,12 +59,12 @@ public class WechatServiceImpl implements WechatService {
}
@Override
public void PushMsg(PushMsgEntity pushMsgEntity) {
public void pushMsg(PushMsgEntity pushMsgEntity) {
// 判断cache中是否存在access_token
CacheUtil instance = CacheUtil.getInstance();
Cache<Object, Object> cache = instance.getCache("accessToken");
String accessToken = "";
if (cache != null ) {
if (cache != null) {
log.info("ConcurrentHashMap中存在access_token的cache,直接使用");
// 再次判断是否存在access_token
if (cache.getIfPresent("accessToken") == null) {
@ -73,7 +74,7 @@ public class WechatServiceImpl implements WechatService {
accessToken = Objects.requireNonNull(cache.getIfPresent("accessToken")).toString();
}
} else {
String tokenResult = restTemplate.getForObject(wechatMpConfig.getAccessTokenUrl(),String.class);
String tokenResult = restTemplate.getForObject(wechatMpConfig.getAccessTokenUrl(), String.class);
JSONObject jsonObj = JSONObject.parseObject(tokenResult);
if (jsonObj == null || !jsonObj.containsKey("access_token")) {
return;
@ -83,39 +84,30 @@ public class WechatServiceImpl implements WechatService {
if (accessToken.isEmpty()) {
return;
}
// 封装推送内容
JSONObject jsonObject = new JSONObject();
jsonObject.put("touser",pushMsgEntity.getTouser());
jsonObject.put("template_id",pushMsgEntity.getTemplateId());
jsonObject.put("url",pushMsgEntity.getUrl());
jsonObject.put("touser", pushMsgEntity.getTouser());
jsonObject.put("template_id", pushMsgEntity.getTemplateId());
jsonObject.put("url", pushMsgEntity.getUrl());
JSONObject data = new JSONObject();
data.put("first",pushMsgEntity.getFirst());
data.put("thing1",pushMsgEntity.getKey1());
// 判断模板id属于哪一个,切换对应的参数
switch (pushMsgEntity.getTemplateId()) {
case "qG3Odr74o4BRx8QigZuoiguLNSkw7QJ0zQI3LaHtMY8":
// 推送单种设备消息
data.put("character_string7", pushMsgEntity.getKey2());
data.put("character_string8", pushMsgEntity.getKey3());
data.put("character_string9", pushMsgEntity.getKey4());
break;
case "qG3Odr74o4BRx8QigZuoil3l3ZC2aAdDeO49robRLC8":
// 推送用电量、用冷量、EER数据
data.put("character_string2", pushMsgEntity.getKey2());
data.put("character_string3", pushMsgEntity.getKey3());
data.put("character_string4", pushMsgEntity.getKey4());
break;
default:
break;
data.put("first", pushMsgEntity.getFirst());
// 使用枚举处理不同模板的数据填充
TemplateType templateType = TemplateType.fromTemplateId(pushMsgEntity.getTemplateId());
if (templateType != null) {
templateType.fillData(data, pushMsgEntity);
}
data.put("time5",pushMsgEntity.getKey5());
data.put("remark",pushMsgEntity.getRemark());
jsonObject.put("data",data);
data.put("remark", pushMsgEntity.getRemark());
jsonObject.put("data", data);
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json");
HttpEntity<Object> entity = new HttpEntity<Object>(jsonObject, headers);
String result = restTemplate.postForObject(wechatMpConfig.getPushMsgUrl(accessToken),entity,String.class);
HttpEntity<Object> entity = new HttpEntity<>(jsonObject, headers);
String result = restTemplate.postForObject(wechatMpConfig.getPushMsgUrl(accessToken), entity, String.class);
log.info("推送结果:{}", result);
}
}

66
user-service/src/main/java/com/mh/user/utils/TemplateType.java

@ -0,0 +1,66 @@
package com.mh.user.utils;
import com.alibaba.fastjson2.JSONObject;
import com.mh.user.entity.wechat.PushMsgEntity;
/**
* @author LJF
* @version 1.0
* @project mh_esi
* @description 微信模板枚举类
* @date 2025-09-08 13:58:43
*/
public enum TemplateType {
SINGLE_DEVICE("qG3Odr74o4BRx8QigZuoiguLNSkw7QJ0zQI3LaHtMY8") {
@Override
public void fillData(JSONObject data, PushMsgEntity pushMsgEntity) {
data.put("thing1", pushMsgEntity.getKey1());
data.put("character_string7", pushMsgEntity.getKey2());
data.put("character_string8", pushMsgEntity.getKey3());
data.put("character_string9", pushMsgEntity.getKey4());
data.put("time5", pushMsgEntity.getKey5());
}
},
ENERGY_DATA("qG3Odr74o4BRx8QigZuoil3l3ZC2aAdDeO49robRLC8") {
@Override
public void fillData(JSONObject data, PushMsgEntity pushMsgEntity) {
data.put("thing1", pushMsgEntity.getKey1());
data.put("character_string2", pushMsgEntity.getKey2());
data.put("character_string3", pushMsgEntity.getKey3());
data.put("character_string4", pushMsgEntity.getKey4());
data.put("time5", pushMsgEntity.getKey5());
}
},
DEVICE_OFFLINE("LrSu6VlICV9sTIWZgl8SF7bFI7TfqbSpeJ-cvPaTe6I") {
@Override
public void fillData(JSONObject data, PushMsgEntity pushMsgEntity) {
data.put("thing19", pushMsgEntity.getKey1());
data.put("thing25", pushMsgEntity.getKey2());
data.put("character_string7", pushMsgEntity.getKey3());
data.put("thing4", pushMsgEntity.getKey4());
data.put("time3", pushMsgEntity.getKey5());
}
};
private final String templateId;
TemplateType(String templateId) {
this.templateId = templateId;
}
public String getTemplateId() {
return templateId;
}
public abstract void fillData(JSONObject data, PushMsgEntity pushMsgEntity);
public static TemplateType fromTemplateId(String templateId) {
for (TemplateType type : values()) {
if (type.getTemplateId().equals(templateId)) {
return type;
}
}
return null;
}
}

2
user-service/src/main/resources/application-dev.yml

@ -1,5 +1,5 @@
server:
port: 8766 #8764新珠江,8766广合科技,8767广大科技,8768珠江国际,8769保利山庄,8770东莞迎宾馆
port: 8762 #8764新珠江,8766广合科技,8767广大科技,8768珠江国际,8769保利山庄,8770东莞迎宾馆
spring:
application:
name: jnd-user-service

2
user-service/src/main/resources/application.yml

@ -1,6 +1,6 @@
spring:
profiles:
active: prod
active: dev
servlet:
multipart:
max-file-size: 50MB

2
user-service/src/test/java/com/mh/user/WechatTest.java

@ -46,6 +46,6 @@ public class WechatTest extends UserServiceApplicationTests{
@Test
public void pushWechatMsg()
{
pushDataToWechatJob.pushDataToWechat();
pushDataToWechatJob.pushGatewayOffLine();
}
}

Loading…
Cancel
Save