diff --git a/ems-framework/src/main/java/com/xzzn/framework/aspectj/DeviceChangeLogAspect.java b/ems-framework/src/main/java/com/xzzn/framework/aspectj/DeviceChangeLogAspect.java new file mode 100644 index 0000000..7b5c608 --- /dev/null +++ b/ems-framework/src/main/java/com/xzzn/framework/aspectj/DeviceChangeLogAspect.java @@ -0,0 +1,97 @@ +package com.xzzn.framework.aspectj; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.xzzn.common.utils.StringUtils; +import com.xzzn.ems.domain.EmsDeviceChangeLog; +import com.xzzn.ems.domain.MqttSyncLog; +import com.xzzn.ems.mapper.EmsMqttTopicConfigMapper; +import com.xzzn.ems.mapper.MqttSyncLogMapper; +import com.xzzn.framework.web.service.MqttPublisher; +import org.apache.juli.logging.Log; +import org.apache.juli.logging.LogFactory; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Date; +import java.util.UUID; + +/** + * 设备运行状态变更日志同步 + * 本地 - 云端 + */ +@Aspect +@Component +public class DeviceChangeLogAspect { + + private static final Log logger = LogFactory.getLog(DeviceChangeLogAspect.class); + @Autowired + private MqttPublisher mqttPublisher; + + private static final ObjectMapper objectMapper = new ObjectMapper(); + private static final String MQTT_TOPIC = "DEVICE_CHANGE_LOG_UP"; + private static final String TABLE_NAME = "ems_device_change_log"; + @Autowired + private MqttSyncLogMapper mqttSyncLogMapper; + @Autowired + private EmsMqttTopicConfigMapper emsMqttTopicConfigMapper; + + // 定义切点:拦截策略相关表的Mapper方法 + @Pointcut("(execution(* com.xzzn.ems.mapper.EmsDeviceChangeLogMapper.insertEmsDeviceChangeLog(..)) && args(insertEntity)) ") + public void insertPointCut(EmsDeviceChangeLog insertEntity) { + logger.info("【新增设备运行状态变更日志】DeviceChangeLogAspect 实例化"); + } + + // 方法执行成功后发布同步消息 + @AfterReturning(pointcut = "insertPointCut(insertEntity)", returning = "result") + public void afterInsert(JoinPoint joinPoint, EmsDeviceChangeLog insertEntity, Integer result) { + logger.info("【新增设备运行状态变更日志下发数据切面进入成功】"); + if (result == 0 || insertEntity == null) { + return; + } + + // 校验是否配置监听topic-监听则不发布 + String topic = emsMqttTopicConfigMapper.checkTopicIsExist(MQTT_TOPIC); + if (!StringUtils.isEmpty(topic)) { + return; + } + + // 解析方法名,获取操作类型(INSERT/UPDATE/DELETE)和表名 + String operateType = "INSERT"; + String siteId = insertEntity.getSiteId(); + + // 构建日志同步消息 + MqttSyncLog message = createMessageObject(operateType,siteId); + + try { + // 数据转换 + String content = objectMapper.writeValueAsString(insertEntity); + message.setContent(content); + + // mqtt同步到云端 + mqttPublisher.publish(MQTT_TOPIC, objectMapper.writeValueAsString(message), 1); + } catch (Exception e) { + message.setStatus("FAIL"); + message.setErrorMsg(e.getMessage()); + } + // 存储同步信息 + mqttSyncLogMapper.insertMqttSyncLog(message); + } + + // 构建同步信息 + private MqttSyncLog createMessageObject(String operateType, String siteId) { + MqttSyncLog message = new MqttSyncLog(); + message.setSyncId(UUID.randomUUID().toString()); + message.setOperateType(operateType); + message.setTableName(TABLE_NAME); + message.setCreateTime(new Date()); + message.setTopic(MQTT_TOPIC); + message.setStatus("SUCCESS"); + message.setSyncObject(siteId); + message.setTarget("CLOUD"); + return message; + } +} \ No newline at end of file diff --git a/ems-quartz/src/main/java/com/xzzn/quartz/task/ModbusPoller.java b/ems-quartz/src/main/java/com/xzzn/quartz/task/ModbusPoller.java index 4032535..3e121d0 100644 --- a/ems-quartz/src/main/java/com/xzzn/quartz/task/ModbusPoller.java +++ b/ems-quartz/src/main/java/com/xzzn/quartz/task/ModbusPoller.java @@ -1,9 +1,12 @@ package com.xzzn.quartz.task; import com.xzzn.common.enums.DeviceRunningStatus; +import com.xzzn.ems.domain.EmsDeviceChangeLog; import com.xzzn.ems.domain.EmsDevicesSetting; +import com.xzzn.ems.mapper.EmsDeviceChangeLogMapper; import com.xzzn.ems.mapper.EmsDevicesSettingMapper; import com.xzzn.ems.mapper.EmsMqttMessageMapper; +import com.xzzn.ems.service.impl.EmsDeviceSettingServiceImpl; import com.xzzn.framework.manager.ModbusConnectionManager; import com.xzzn.framework.manager.ModbusConnectionWrapper; import com.xzzn.framework.manager.MqttLifecycleManager; @@ -14,7 +17,9 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.util.Date; import java.util.List; +import java.util.UUID; /** * 轮询设备-通过modbus协议读取数据 @@ -33,6 +38,10 @@ public class ModbusPoller { private EmsDevicesSettingMapper deviceRepo; @Autowired private EmsMqttMessageMapper emsMqttMessageMapper; + @Autowired + private EmsDeviceSettingServiceImpl emsDeviceSettingServiceImpl; + @Autowired + private EmsDeviceChangeLogMapper emsDeviceChangeLogMapper; @Autowired public ModbusPoller(MqttLifecycleManager mqttLifecycleManager) { @@ -41,8 +50,9 @@ public class ModbusPoller { public void pollAllDevices() { logger.info("开始执行Modbus设备轮询..."); - - List activeDevices = deviceRepo.selectEmsDevicesSettingList(null); + EmsDevicesSetting selectEntity = new EmsDevicesSetting(); + selectEntity.setRunningStatus(DeviceRunningStatus.RUNNING.getCode()); + List activeDevices = deviceRepo.selectEmsDevicesSettingList(selectEntity); EmsDevicesSetting device = activeDevices.get(0); try { @@ -91,16 +101,39 @@ public class ModbusPoller { wrapper.close(); connectionManager.removeConnection(Integer.parseInt(device.getDeviceId())); } - throw new RuntimeException("轮询设备失败", e); + + // 设备轮询不到修改运行状态 + String beforeStatus = device.getRunningStatus(); + device.setRunningStatus(DeviceRunningStatus.SHUTDOWN.getCode()); + emsDeviceSettingServiceImpl.updateDevice(device); + + // 轮询设备,设备状态变更日志 + EmsDeviceChangeLog log = createLogEntity(beforeStatus,device); + emsDeviceChangeLogMapper.insertEmsDeviceChangeLog(log); + + throw new RuntimeException("轮询设备失败", e); } } // 处理获取到的数据 private void processData(EmsDevicesSetting device, int[] data) throws MqttException { + String beforeStatus = device.getRunningStatus(); + Boolean error = true; if (data == null || data.length == 0) { logger.warn("设备{}返回空数据", device.getId()); // 设备读取不到-设置设备故障 device.setRunningStatus(DeviceRunningStatus.FAULT.getCode()); + error = false; + } else { + // 恢复设备状态 - 运行 + device.setRunningStatus(DeviceRunningStatus.RUNNING.getCode()); + } + emsDeviceSettingServiceImpl.updateDevice(device); + // 轮询设备,设备状态变更日志 + EmsDeviceChangeLog log = createLogEntity(beforeStatus,device); + emsDeviceChangeLogMapper.insertEmsDeviceChangeLog(log); + // 错误数据-不处理直接返回 + if (!error) { return; } @@ -116,8 +149,6 @@ public class ModbusPoller { /* String siteId = device.getSiteId(); if (siteId.startsWith("021_DDS")) { - ems_devices_setting - dDSDataProcessService.handleDdsData(message); } else if (siteId.startsWith("021_FXX")) { fXXDataProcessService.handleFxData(message); @@ -132,4 +163,17 @@ public class ModbusPoller { // 将设备数据下发到mqtt服务器上 mqttLifecycleManager.publish(topic, dataJson, 0);*/ } + + private EmsDeviceChangeLog createLogEntity(String beforeStatus, EmsDevicesSetting device) { + EmsDeviceChangeLog log = new EmsDeviceChangeLog(); + log.setLogId(UUID.randomUUID().toString()); + log.setLogTime(new Date()); + log.setSiteId(device.getSiteId()); + log.setDeviceId(device.getDeviceId()); + log.setBeforeStatus(beforeStatus); + log.setAfterStatus(device.getRunningStatus()); + log.setCreateBy("sys"); + log.setCreateTime(new Date()); + return log; + } } \ No newline at end of file diff --git a/ems-system/src/main/java/com/xzzn/ems/domain/EmsDeviceChangeLog.java b/ems-system/src/main/java/com/xzzn/ems/domain/EmsDeviceChangeLog.java new file mode 100644 index 0000000..350c8e2 --- /dev/null +++ b/ems-system/src/main/java/com/xzzn/ems/domain/EmsDeviceChangeLog.java @@ -0,0 +1,134 @@ +package com.xzzn.ems.domain; + +import java.util.Date; + +import com.xzzn.common.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.xzzn.common.annotation.Excel; + +/** + * 设备状态变更记录对象 ems_device_change_log + * + * @author xzzn + * @date 2025-11-15 + */ +public class EmsDeviceChangeLog extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** $column.columnComment */ + private Long id; + + /** 日志ID(UUID) */ + @Excel(name = "日志ID", readConverterExp = "U=UID") + private String logId; + + /** 日志时间(精确到秒) */ + @Excel(name = "日志时间", readConverterExp = "精=确到秒") + private Date logTime; + + /** 站点id */ + @Excel(name = "站点id") + private String siteId; + + /** 设备id */ + @Excel(name = "设备id") + private String deviceId; + + /** 变更前状态:0-离线、1-待机、2-运行、3-故障、4-停机 */ + @Excel(name = "变更前状态:0-离线、1-待机、2-运行、3-故障、4-停机") + private String beforeStatus; + + /** 变更后状态:0-离线、1-待机、2-运行、3-故障、4-停机 */ + @Excel(name = "变更后状态:0-离线、1-待机、2-运行、3-故障、4-停机") + private String afterStatus; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + + public void setLogId(String logId) + { + this.logId = logId; + } + + public String getLogId() + { + return logId; + } + + public void setLogTime(Date logTime) + { + this.logTime = logTime; + } + + public Date getLogTime() + { + return logTime; + } + + public void setSiteId(String siteId) + { + this.siteId = siteId; + } + + public String getSiteId() + { + return siteId; + } + + public void setDeviceId(String deviceId) + { + this.deviceId = deviceId; + } + + public String getDeviceId() + { + return deviceId; + } + + public void setBeforeStatus(String beforeStatus) + { + this.beforeStatus = beforeStatus; + } + + public String getBeforeStatus() + { + return beforeStatus; + } + + public void setAfterStatus(String afterStatus) + { + this.afterStatus = afterStatus; + } + + public String getAfterStatus() + { + return afterStatus; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("logId", getLogId()) + .append("logTime", getLogTime()) + .append("siteId", getSiteId()) + .append("deviceId", getDeviceId()) + .append("beforeStatus", getBeforeStatus()) + .append("afterStatus", getAfterStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ems-system/src/main/java/com/xzzn/ems/mapper/EmsDeviceChangeLogMapper.java b/ems-system/src/main/java/com/xzzn/ems/mapper/EmsDeviceChangeLogMapper.java new file mode 100644 index 0000000..bf81415 --- /dev/null +++ b/ems-system/src/main/java/com/xzzn/ems/mapper/EmsDeviceChangeLogMapper.java @@ -0,0 +1,65 @@ +package com.xzzn.ems.mapper; + +import java.util.List; +import com.xzzn.ems.domain.EmsDeviceChangeLog; +import com.xzzn.ems.domain.EmsFaultIssueLog; + +/** + * 设备状态变更记录Mapper接口 + * + * @author xzzn + * @date 2025-11-15 + */ +public interface EmsDeviceChangeLogMapper +{ + /** + * 查询设备状态变更记录 + * + * @param id 设备状态变更记录主键 + * @return 设备状态变更记录 + */ + public EmsDeviceChangeLog selectEmsDeviceChangeLogById(Long id); + + /** + * 查询设备状态变更记录列表 + * + * @param emsDeviceChangeLog 设备状态变更记录 + * @return 设备状态变更记录集合 + */ + public List selectEmsDeviceChangeLogList(EmsDeviceChangeLog emsDeviceChangeLog); + + /** + * 新增设备状态变更记录 + * + * @param emsDeviceChangeLog 设备状态变更记录 + * @return 结果 + */ + public int insertEmsDeviceChangeLog(EmsDeviceChangeLog emsDeviceChangeLog); + + /** + * 修改设备状态变更记录 + * + * @param emsDeviceChangeLog 设备状态变更记录 + * @return 结果 + */ + public int updateEmsDeviceChangeLog(EmsDeviceChangeLog emsDeviceChangeLog); + + /** + * 删除设备状态变更记录 + * + * @param id 设备状态变更记录主键 + * @return 结果 + */ + public int deleteEmsDeviceChangeLogById(Long id); + + /** + * 批量删除设备状态变更记录 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteEmsDeviceChangeLogByIds(Long[] ids); + + // 根据logId获取日志 + public EmsDeviceChangeLog selectDeviceChangeLogByLogId(String logId); +} diff --git a/ems-system/src/main/java/com/xzzn/ems/service/IEmsDeviceChangeLogService.java b/ems-system/src/main/java/com/xzzn/ems/service/IEmsDeviceChangeLogService.java new file mode 100644 index 0000000..ba6e7d7 --- /dev/null +++ b/ems-system/src/main/java/com/xzzn/ems/service/IEmsDeviceChangeLogService.java @@ -0,0 +1,64 @@ +package com.xzzn.ems.service; + +import java.util.List; +import com.xzzn.ems.domain.EmsDeviceChangeLog; + +/** + * 设备状态变更记录Service接口 + * + * @author xzzn + * @date 2025-11-15 + */ +public interface IEmsDeviceChangeLogService +{ + /** + * 查询设备状态变更记录 + * + * @param id 设备状态变更记录主键 + * @return 设备状态变更记录 + */ + public EmsDeviceChangeLog selectEmsDeviceChangeLogById(Long id); + + /** + * 查询设备状态变更记录列表 + * + * @param emsDeviceChangeLog 设备状态变更记录 + * @return 设备状态变更记录集合 + */ + public List selectEmsDeviceChangeLogList(EmsDeviceChangeLog emsDeviceChangeLog); + + /** + * 新增设备状态变更记录 + * + * @param emsDeviceChangeLog 设备状态变更记录 + * @return 结果 + */ + public int insertEmsDeviceChangeLog(EmsDeviceChangeLog emsDeviceChangeLog); + + /** + * 修改设备状态变更记录 + * + * @param emsDeviceChangeLog 设备状态变更记录 + * @return 结果 + */ + public int updateEmsDeviceChangeLog(EmsDeviceChangeLog emsDeviceChangeLog); + + /** + * 批量删除设备状态变更记录 + * + * @param ids 需要删除的设备状态变更记录主键集合 + * @return 结果 + */ + public int deleteEmsDeviceChangeLogByIds(Long[] ids); + + /** + * 删除设备状态变更记录信息 + * + * @param id 设备状态变更记录主键 + * @return 结果 + */ + public int deleteEmsDeviceChangeLogById(Long id); + + // 处理本地端同步设备状态变更数据 + public void dealSyncData(String content, String operateType); +} diff --git a/ems-system/src/main/java/com/xzzn/ems/service/impl/EmsDeviceChangeLogServiceImpl.java b/ems-system/src/main/java/com/xzzn/ems/service/impl/EmsDeviceChangeLogServiceImpl.java new file mode 100644 index 0000000..87354e6 --- /dev/null +++ b/ems-system/src/main/java/com/xzzn/ems/service/impl/EmsDeviceChangeLogServiceImpl.java @@ -0,0 +1,128 @@ +package com.xzzn.ems.service.impl; + +import java.util.List; + +import com.alibaba.fastjson2.JSON; +import com.xzzn.common.utils.DateUtils; +import com.xzzn.common.utils.StringUtils; +import com.xzzn.ems.domain.EmsFaultIssueLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.xzzn.ems.mapper.EmsDeviceChangeLogMapper; +import com.xzzn.ems.domain.EmsDeviceChangeLog; +import com.xzzn.ems.service.IEmsDeviceChangeLogService; + +/** + * 设备状态变更记录Service业务层处理 + * + * @author xzzn + * @date 2025-11-15 + */ +@Service +public class EmsDeviceChangeLogServiceImpl implements IEmsDeviceChangeLogService +{ + @Autowired + private EmsDeviceChangeLogMapper emsDeviceChangeLogMapper; + + /** + * 查询设备状态变更记录 + * + * @param id 设备状态变更记录主键 + * @return 设备状态变更记录 + */ + @Override + public EmsDeviceChangeLog selectEmsDeviceChangeLogById(Long id) + { + return emsDeviceChangeLogMapper.selectEmsDeviceChangeLogById(id); + } + + /** + * 查询设备状态变更记录列表 + * + * @param emsDeviceChangeLog 设备状态变更记录 + * @return 设备状态变更记录 + */ + @Override + public List selectEmsDeviceChangeLogList(EmsDeviceChangeLog emsDeviceChangeLog) + { + return emsDeviceChangeLogMapper.selectEmsDeviceChangeLogList(emsDeviceChangeLog); + } + + /** + * 新增设备状态变更记录 + * + * @param emsDeviceChangeLog 设备状态变更记录 + * @return 结果 + */ + @Override + public int insertEmsDeviceChangeLog(EmsDeviceChangeLog emsDeviceChangeLog) + { + emsDeviceChangeLog.setCreateTime(DateUtils.getNowDate()); + return emsDeviceChangeLogMapper.insertEmsDeviceChangeLog(emsDeviceChangeLog); + } + + /** + * 修改设备状态变更记录 + * + * @param emsDeviceChangeLog 设备状态变更记录 + * @return 结果 + */ + @Override + public int updateEmsDeviceChangeLog(EmsDeviceChangeLog emsDeviceChangeLog) + { + emsDeviceChangeLog.setUpdateTime(DateUtils.getNowDate()); + return emsDeviceChangeLogMapper.updateEmsDeviceChangeLog(emsDeviceChangeLog); + } + + /** + * 批量删除设备状态变更记录 + * + * @param ids 需要删除的设备状态变更记录主键 + * @return 结果 + */ + @Override + public int deleteEmsDeviceChangeLogByIds(Long[] ids) + { + return emsDeviceChangeLogMapper.deleteEmsDeviceChangeLogByIds(ids); + } + + /** + * 删除设备状态变更记录信息 + * + * @param id 设备状态变更记录主键 + * @return 结果 + */ + @Override + public int deleteEmsDeviceChangeLogById(Long id) + { + return emsDeviceChangeLogMapper.deleteEmsDeviceChangeLogById(id); + } + + @Override + public void dealSyncData(String content, String operateType) { + if (StringUtils.isEmpty(content)) { + return; + } + + EmsDeviceChangeLog changeLog = JSON.parseObject(content, EmsDeviceChangeLog.class); + String logId = changeLog.getLogId(); + if (checkLogIsExist(logId)) { + return; + } + switch(operateType) { + case "INSERT": + insertEmsDeviceChangeLog(changeLog); + break; + default: + break; + } + } + + private boolean checkLogIsExist(String logId) { + EmsDeviceChangeLog changeLog = emsDeviceChangeLogMapper.selectDeviceChangeLogByLogId(logId); + if (changeLog != null) { + return true; + } + return false; + } +} diff --git a/ems-system/src/main/resources/mapper/ems/EmsDeviceChangeLogMapper.xml b/ems-system/src/main/resources/mapper/ems/EmsDeviceChangeLogMapper.xml new file mode 100644 index 0000000..48c9a56 --- /dev/null +++ b/ems-system/src/main/resources/mapper/ems/EmsDeviceChangeLogMapper.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + select id, log_id, log_time, siteId, deviceId, before_status, after_status, create_by, create_time, update_by, update_time, remark from ems_device_change_log + + + + + + + + insert into ems_device_change_log + + log_id, + log_time, + siteId, + deviceId, + before_status, + after_status, + create_by, + create_time, + update_by, + update_time, + remark, + + + #{logId}, + #{logTime}, + #{siteId}, + #{deviceId}, + #{beforeStatus}, + #{afterStatus}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{remark}, + + + + + update ems_device_change_log + + log_id = #{logId}, + log_time = #{logTime}, + siteId = #{siteId}, + deviceId = #{deviceId}, + before_status = #{beforeStatus}, + after_status = #{afterStatus}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + remark = #{remark}, + + where id = #{id} + + + + delete from ems_device_change_log where id = #{id} + + + + delete from ems_device_change_log where id in + + #{id} + + + + + \ No newline at end of file