diff --git a/threecolor-modbus-collector/src/main/java/com/xujie/modbus/controller/ThreeColorLampTestController.java b/threecolor-modbus-collector/src/main/java/com/xujie/modbus/controller/ThreeColorLampTestController.java new file mode 100644 index 0000000..a7779bb --- /dev/null +++ b/threecolor-modbus-collector/src/main/java/com/xujie/modbus/controller/ThreeColorLampTestController.java @@ -0,0 +1,73 @@ +package com.xujie.modbus.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.xujie.modbus.controller.request.ThreeColorLampLocalCollectRequest; +import com.xujie.modbus.entity.Resource; +import com.xujie.modbus.service.ModbusCollectService; +import com.xujie.modbus.service.ResourceService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.HashMap; +import java.util.Map; + +@RestController +@RequestMapping("/threecolor/test") +public class ThreeColorLampTestController { + + @Autowired + private ResourceService resourceService; + + @Autowired + private ModbusCollectService modbusCollectService; + + /** + * 本地测试接口:不走采集器IP读取,直接喂三色灯状态到原业务逻辑 + */ + @PostMapping("/collect") + public boolean collectLocal(@RequestBody ThreeColorLampLocalCollectRequest req) { + if (req == null || StringUtils.isBlank(req.getSite()) || StringUtils.isBlank(req.getResourceId())) { + return false; + } + + LambdaQueryWrapper wrapper = new LambdaQueryWrapper() + .eq(Resource::getSite, req.getSite()) + .eq(Resource::getResourceId, req.getResourceId()) + .orderByDesc(Resource::getId); + + // SQLServer 不支持 "limit";这里按 id 倒序取一条即可 + Resource resource = resourceService.getOne(wrapper, false); + + if (resource == null) { + return false; + } + + Map registerData = buildRegisterData(req); + modbusCollectService.readHoldingRegistersLocal(resource, registerData); + return true; + } + + private Map buildRegisterData(ThreeColorLampLocalCollectRequest req) { + Map map = new HashMap<>(); + + if (StringUtils.isNotBlank(req.getLamp()) && req.getLamp().trim().length() >= 3) { + String lamp = req.getLamp().trim(); + map.put(0, lamp.charAt(0) == '1' ? 1 : 0); + map.put(1, lamp.charAt(1) == '1' ? 1 : 0); + map.put(2, lamp.charAt(2) == '1' ? 1 : 0); + return map; + } + + map.put(0, normalizeBit(req.getGreen())); + map.put(1, normalizeBit(req.getOrange())); + map.put(2, normalizeBit(req.getRed())); + return map; + } + + private int normalizeBit(Integer v) { + if (v == null) return 0; + return v != 0 ? 1 : 0; + } +} + diff --git a/threecolor-modbus-collector/src/main/java/com/xujie/modbus/controller/request/ThreeColorLampLocalCollectRequest.java b/threecolor-modbus-collector/src/main/java/com/xujie/modbus/controller/request/ThreeColorLampLocalCollectRequest.java new file mode 100644 index 0000000..4b96e4f --- /dev/null +++ b/threecolor-modbus-collector/src/main/java/com/xujie/modbus/controller/request/ThreeColorLampLocalCollectRequest.java @@ -0,0 +1,25 @@ +package com.xujie.modbus.controller.request; + +import lombok.Data; + +/** + * 本地测试采集请求:跳过采集器(IP)读数,直接提交三色灯状态 + */ +@Data +public class ThreeColorLampLocalCollectRequest { + private String site; + private String resourceId; + + /** + * 三色灯组合字符串,如 "100" / "001" / "011";优先级高于 green/orange/red + */ + private String lamp; + + /** + * 单独指定三色灯:1/0 + */ + private Integer green; + private Integer orange; + private Integer red; +} + diff --git a/threecolor-modbus-collector/src/main/java/com/xujie/modbus/mapper/ThreeColorLampDownlogMapper.java b/threecolor-modbus-collector/src/main/java/com/xujie/modbus/mapper/ThreeColorLampDownlogMapper.java index 5619a7b..8e394a1 100644 --- a/threecolor-modbus-collector/src/main/java/com/xujie/modbus/mapper/ThreeColorLampDownlogMapper.java +++ b/threecolor-modbus-collector/src/main/java/com/xujie/modbus/mapper/ThreeColorLampDownlogMapper.java @@ -5,9 +5,29 @@ import com.xujie.modbus.entity.ThreeColorLampDownlog; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; +import java.util.Date; + @Mapper public interface ThreeColorLampDownlogMapper extends BaseMapper { ThreeColorLampDownlog selectDownlogLast(@Param("site") String site, @Param("resourceId") String resourceId); - int updateDownLogEventDesc(String startTime, String endTime,String eventDesc); + /** + * hist.event_time 之后(按分钟粒度比较)是否存在 lamp=100 且持续超过 runTime 分钟的 downlog 段。 + */ + int countDownlogLamp100ExceedingRuntimeAfterHistEvent(@Param("site") String site, + @Param("seqNo") String seqNo, + @Param("eventTime") Date eventTime, + @Param("runTime") int runTime); + + int updateDownLogEventDesc(@Param("startTime") String startTime, + @Param("endTime") String endTime, + @Param("eventDesc") String eventDesc, + @Param("site") String site, + @Param("resourceId") String resourceId, + @Param("seqNo") String seqNo, + @Param("orderNo") String orderNo, + @Param("runTime") int runTime); + + ThreeColorLampDownlog selectThreeColorLampDownlogStartTime(String site, String resourceId, String seqNo); + } diff --git a/threecolor-modbus-collector/src/main/java/com/xujie/modbus/service/ModbusCollectService.java b/threecolor-modbus-collector/src/main/java/com/xujie/modbus/service/ModbusCollectService.java index b1d48fb..8faa70e 100644 --- a/threecolor-modbus-collector/src/main/java/com/xujie/modbus/service/ModbusCollectService.java +++ b/threecolor-modbus-collector/src/main/java/com/xujie/modbus/service/ModbusCollectService.java @@ -4,6 +4,8 @@ import com.xujie.modbus.entity.DeviceInfo; import com.xujie.modbus.entity.EquipmentFolderLocation; import com.xujie.modbus.entity.Resource; +import java.util.Map; + /** * Modbus采集服务接口 * @@ -26,5 +28,10 @@ public interface ModbusCollectService { void handleData(DeviceInfo deviceInfo); void readHoldingRegisters(Resource folderLocation); + + /** + * 本地测试:跳过 Modbus/IP 通讯,直接用给定的寄存器/离散输入数据走同一套业务逻辑 + */ + void readHoldingRegistersLocal(Resource folderLocation, Map registerData); } diff --git a/threecolor-modbus-collector/src/main/java/com/xujie/modbus/service/impl/ModbusCollectServiceImpl.java b/threecolor-modbus-collector/src/main/java/com/xujie/modbus/service/impl/ModbusCollectServiceImpl.java index 7b11591..afa1e62 100644 --- a/threecolor-modbus-collector/src/main/java/com/xujie/modbus/service/impl/ModbusCollectServiceImpl.java +++ b/threecolor-modbus-collector/src/main/java/com/xujie/modbus/service/impl/ModbusCollectServiceImpl.java @@ -17,11 +17,21 @@ import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.task.SimpleAsyncTaskExecutor; +import org.springframework.core.task.TaskExecutor; import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.http.*; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.text.SimpleDateFormat; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.*; import java.util.stream.Collectors; @@ -50,6 +60,30 @@ public class ModbusCollectServiceImpl @Autowired private ThreeColorLampDownlogMapper threeColorLampDownlogMapper; + @Autowired(required = false) + private TaskExecutor taskExecutor; + + @Value("${mes.sync.url:}") + private String mesSyncUrl; + + private final RestTemplate restTemplate = new RestTemplate(); + private final TaskExecutor fallbackExecutor = new SimpleAsyncTaskExecutor("mes-sync-"); + + private static final DateTimeFormatter MES_TIME_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + private static final ZoneId MES_ZONE = ZoneId.of("Asia/Shanghai"); + + private void fireAndForget(String taskName, Runnable task) { + TaskExecutor executor = (taskExecutor != null) ? taskExecutor : fallbackExecutor; + executor.execute(() -> { + try { + task.run(); + } catch (Exception ex) { + // 不影响主流程:仅记录异常 + logger.error("异步任务执行失败: {}", taskName, ex); + } + }); + } + @Override public void handleSignal(DeviceInfo deviceInfo) { @@ -184,8 +218,6 @@ public class ModbusCollectServiceImpl int port = folderLocation.getRegisterPort() != null ? folderLocation.getRegisterPort() : 502; int quantity = folderLocation.getRegisterNum() != null ? folderLocation.getRegisterNum() : 3; int offset = 0x00; - Integer failureTime = folderLocation.getFailureTime() != null ? folderLocation.getFailureTime() : 5; - Integer runTime = folderLocation.getRunTime() != null ? folderLocation.getRunTime() : 4; String cuttingSymbol = folderLocation.getCuttingSymbol(); if (StringUtils.isNotBlank(cuttingSymbol)) { try { @@ -199,6 +231,21 @@ public class ModbusCollectServiceImpl // 读取寄存器数据 Map registerData = ModbusUtil.readHoldingRegisters(ip,port, 1, offset, quantity); + handleHoldingRegisters(folderLocation, registerData); + } + + @Override + public void readHoldingRegistersLocal(Resource folderLocation, Map registerData) { + handleHoldingRegisters(folderLocation, registerData != null ? registerData : Collections.emptyMap()); + } + + private void handleHoldingRegisters(Resource folderLocation, Map registerData) { + if (registerData == null) { + registerData = Collections.emptyMap(); + } + + Integer failureTime = folderLocation.getFailureTime() != null ? folderLocation.getFailureTime() : 5; + Integer runTime = folderLocation.getRunTime() != null ? folderLocation.getRunTime() : 4; if (registerData.isEmpty()) { //如果读取不到数据 @@ -273,19 +320,37 @@ public class ModbusCollectServiceImpl if(greenInsertHist && isLastGreen){ SfdcTimeHist sfdcTimeHistByGreen = sfdcTimeHistMapper.selectSfdcTimeHistByNew(folderLocation.getSite(), resourceScheduled.getSeqNo(), "自动停机"); if(sfdcTimeHistByGreen != null){ - sfdcTimeHistByGreen.setTillTime(null); - sfdcTimeHistByGreen.setTillenteredTime(null); - sfdcTimeHistByGreen.setCompletedFlag("N"); - int i = sfdcTimeHistMapper.updateById(sfdcTimeHistByGreen); - if(i>0){ - UpdateWrapper updateWrapper = new UpdateWrapper<>(); - updateWrapper.eq("site", folderLocation.getSite()); - updateWrapper.eq("resource_id", folderLocation.getResourceId()); - updateWrapper.eq("seq_no", sfdcTimeHistByGreen.getSeqNo()); - updateWrapper.set("issend", "Y"); - updateWrapper.set("sfdcid",sfdcTimeHistByGreen.getId()); - resourceScheduledMapper.update(updateWrapper); - logger.info("停机恢复后正常运行时间未到指定时间,sfdcid变为之前的,id:{}",sfdcTimeHistByGreen.getId()); + boolean skipReopenHist = false; + if (sfdcTimeHistByGreen.getEventTime() != null && StringUtils.isNotBlank(resourceScheduled.getSeqNo())) { + int longGreenCount = threeColorLampDownlogMapper.countDownlogLamp100ExceedingRuntimeAfterHistEvent( + folderLocation.getSite(), + resourceScheduled.getSeqNo(), + sfdcTimeHistByGreen.getEventTime(), + runTime); + if (longGreenCount > 0) { + skipReopenHist = true; + logger.info("hist event_time 之后存在 lamp=100 且持续超过 runTime({} 分钟) 的 downlog,跳过清空 hist,histId:{}", + runTime, sfdcTimeHistByGreen.getId()); + } + } + if (!skipReopenHist) { + sfdcTimeHistByGreen.setTillTime(null); + sfdcTimeHistByGreen.setTillenteredTime(null); + sfdcTimeHistByGreen.setCompletedFlag("N"); + int i = sfdcTimeHistMapper.updateById(sfdcTimeHistByGreen); + if(i>0){ + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("site", folderLocation.getSite()); + updateWrapper.eq("resource_id", folderLocation.getResourceId()); + updateWrapper.eq("seq_no", sfdcTimeHistByGreen.getSeqNo()); + updateWrapper.set("issend", "Y"); + updateWrapper.set("sfdcid",sfdcTimeHistByGreen.getId()); + resourceScheduledMapper.update(updateWrapper); + logger.info("停机恢复后正常运行时间未到指定时间,sfdcid变为之前的,id:{}",sfdcTimeHistByGreen.getId()); + fireAndForget("syncMesFormStop", () -> + syncMesFormStop(folderLocation.getSite(), sfdcTimeHistByGreen.getSeqNo(), + sfdcTimeHistByGreen.getId(), sfdcTimeHistByGreen.getEventTime())); + } } } @@ -325,7 +390,9 @@ public class ModbusCollectServiceImpl sfdcTimeHist.setHistSeqno(histSeqno+1); Date currentTime = new Date(); Date fiveMinutesAgo = new Date(currentTime.getTime() - failureTime * 60 * 1000); - sfdcTimeHist.setEventTime(fiveMinutesAgo); + /* sfdcTimeHist.setEventTime(fiveMinutesAgo);*/ + ThreeColorLampDownlog sfdcTimeHistStartTime =threeColorLampDownlogMapper.selectThreeColorLampDownlogStartTime(folderLocation.getSite(), folderLocation.getResourceId(),resourceScheduled.getSeqNo()) ; + sfdcTimeHist.setEventTime(sfdcTimeHistStartTime.getStartDate() == null?fiveMinutesAgo:sfdcTimeHistStartTime.getStartDate()); sfdcTimeHist.setEnteredBy(null); sfdcTimeHist.setEventDesc(null); sfdcTimeHist.setDowntimeCode(null); @@ -359,6 +426,9 @@ public class ModbusCollectServiceImpl updateWrapper.set("sfdcid",sfdcTimeHist.getId()); resourceScheduledMapper.update(updateWrapper); logger.info("更新了中间表,变为X,sfdcid:{}",sfdcTimeHist.getId()); + fireAndForget("syncMesFormStop", () -> + syncMesFormStop(folderLocation.getSite(), resourceScheduled.getSeqNo(), + sfdcTimeHist.getId(), sfdcTimeHist.getEventTime())); } } @@ -376,7 +446,9 @@ public class ModbusCollectServiceImpl sfdcTimeHist.setHistSeqno(histSeqno+1); Date currentTime = new Date(); Date fiveMinutesAgo = new Date(currentTime.getTime() - failureTime * 60 * 1000); - sfdcTimeHist.setEventTime(fiveMinutesAgo); + /* sfdcTimeHist.setEventTime(fiveMinutesAgo);*/ + ThreeColorLampDownlog sfdcTimeHistStartTime =threeColorLampDownlogMapper.selectThreeColorLampDownlogStartTime(folderLocation.getSite(), folderLocation.getResourceId(),resourceScheduled.getSeqNo()) ; + sfdcTimeHist.setEventTime(sfdcTimeHistStartTime.getStartDate() == null?fiveMinutesAgo:sfdcTimeHistStartTime.getStartDate()); sfdcTimeHist.setEnteredBy(null); sfdcTimeHist.setEventDesc(null); sfdcTimeHist.setDowntimeCode(null); @@ -410,6 +482,9 @@ public class ModbusCollectServiceImpl updateWrapper.set("sfdcid",sfdcTimeHist.getId()); resourceScheduledMapper.update(updateWrapper); logger.info("更新了中间表,变为X,sfdcid:{}",sfdcTimeHist.getId()); + fireAndForget("syncMesFormStop", () -> + syncMesFormStop(folderLocation.getSite(), resourceScheduled.getSeqNo(), + sfdcTimeHist.getId(), sfdcTimeHist.getEventTime())); } } @@ -461,7 +536,9 @@ public class ModbusCollectServiceImpl sfdcTimeHist.setHistSeqno(histSeqno+1); Date currentTime = new Date(); Date fiveMinutesAgo = new Date(currentTime.getTime() - failureTime * 60 * 1000); - sfdcTimeHist.setEventTime(fiveMinutesAgo); + /* sfdcTimeHist.setEventTime(fiveMinutesAgo);*/ + ThreeColorLampDownlog sfdcTimeHistStartTime =threeColorLampDownlogMapper.selectThreeColorLampDownlogStartTime(folderLocation.getSite(), folderLocation.getResourceId(),resourceScheduled.getSeqNo()) ; + sfdcTimeHist.setEventTime(sfdcTimeHistStartTime.getStartDate() == null?fiveMinutesAgo:sfdcTimeHistStartTime.getStartDate()); sfdcTimeHist.setEnteredBy(null); sfdcTimeHist.setEventDesc(null); sfdcTimeHist.setDowntimeCode(null); @@ -495,6 +572,9 @@ public class ModbusCollectServiceImpl updateWrapper.set("sfdcid",sfdcTimeHist.getId()); resourceScheduledMapper.update(updateWrapper); logger.info("更新了中间表,变为X,sfdcid:{}",sfdcTimeHist.getId()); + fireAndForget("syncMesFormStop", () -> + syncMesFormStop(folderLocation.getSite(), resourceScheduled.getSeqNo(), + sfdcTimeHist.getId(), sfdcTimeHist.getEventTime())); } } @@ -512,7 +592,9 @@ public class ModbusCollectServiceImpl sfdcTimeHist.setHistSeqno(histSeqno+1); Date currentTime = new Date(); Date fiveMinutesAgo = new Date(currentTime.getTime() - failureTime * 60 * 1000); - sfdcTimeHist.setEventTime(fiveMinutesAgo); + /* sfdcTimeHist.setEventTime(fiveMinutesAgo);*/ + ThreeColorLampDownlog sfdcTimeHistStartTime =threeColorLampDownlogMapper.selectThreeColorLampDownlogStartTime(folderLocation.getSite(), folderLocation.getResourceId(),resourceScheduled.getSeqNo()) ; + sfdcTimeHist.setEventTime(sfdcTimeHistStartTime.getStartDate() == null?fiveMinutesAgo:sfdcTimeHistStartTime.getStartDate()); sfdcTimeHist.setEnteredBy(null); sfdcTimeHist.setEventDesc(null); sfdcTimeHist.setDowntimeCode(null); @@ -546,6 +628,9 @@ public class ModbusCollectServiceImpl updateWrapper.set("sfdcid",sfdcTimeHist.getId()); resourceScheduledMapper.update(updateWrapper); logger.info("更新了中间表,变为X,sfdcid:{}",sfdcTimeHist.getId()); + fireAndForget("syncMesFormStop", () -> + syncMesFormStop(folderLocation.getSite(), resourceScheduled.getSeqNo(), + sfdcTimeHist.getId(), sfdcTimeHist.getEventTime())); } } @@ -566,6 +651,151 @@ public class ModbusCollectServiceImpl } + //000的情况 + boolean whiteInsertHist = false; + if (colorLampLisByTime != null && colorLampLisByTime.size() > 0) { + // 只取最近 failureTime 条记录做判断 + whiteInsertHist = true; + for (ThreeColorLamp lamp3 : colorLampLisByTime) { + boolean isWhite = ("0".equals(lamp3.getGreen())) && + ("0".equals(lamp3.getOrange())) && + ("0".equals(lamp3.getRed())); + if (!isWhite) { + whiteInsertHist = false; + break; + } + } + } + + if (whiteInsertHist){ + if(!"X".equals(resourceScheduled.getIssend())){ + SfdcTimeHist timeHist = sfdcTimeHistMapper.selectSfdcTimeHistByNew(folderLocation.getSite(), resourceScheduled.getSeqNo(), "自动停机"); + if(timeHist == null){ + SoscheduledroutingVo soscheduled = threeColorLampMapper.getSoscheduled(resourceScheduled.getSeqNo()); + if(soscheduled != null){ + int histSeqno = threeColorLampMapper.selectHistSeqno(folderLocation.getSite(), resourceScheduled.getSeqNo()); + SfdcTimeHist sfdcTimeHist = new SfdcTimeHist(); + sfdcTimeHist.setSite(folderLocation.getSite()); + sfdcTimeHist.setOrderNo(soscheduled.getOrderno()); + sfdcTimeHist.setItemNo(Double.valueOf(soscheduled.getItemno())); + sfdcTimeHist.setSeqNo(soscheduled.getSeqno()); + sfdcTimeHist.setHistSeqno(histSeqno+1); + Date currentTime = new Date(); + Date fiveMinutesAgo = new Date(currentTime.getTime() - failureTime * 60 * 1000); + /* sfdcTimeHist.setEventTime(fiveMinutesAgo);*/ + ThreeColorLampDownlog sfdcTimeHistStartTime =threeColorLampDownlogMapper.selectThreeColorLampDownlogStartTime(folderLocation.getSite(), folderLocation.getResourceId(),resourceScheduled.getSeqNo()) ; + sfdcTimeHist.setEventTime(sfdcTimeHistStartTime.getStartDate() == null?fiveMinutesAgo:sfdcTimeHistStartTime.getStartDate()); + sfdcTimeHist.setEnteredBy(null); + sfdcTimeHist.setEventDesc(null); + sfdcTimeHist.setDowntimeCode(null); + sfdcTimeHist.setEventType("D"); + sfdcTimeHist.setLinkhistSeqno(null); + sfdcTimeHist.setTillenteredBy(null); + sfdcTimeHist.setCompletedFlag("N"); + if("T".equals(resourceScheduled.getStatus())){ + sfdcTimeHist.setDowntimePhasein("调机"); + }else{ + sfdcTimeHist.setDowntimePhasein("生产"); + } + + sfdcTimeHist.setRollNo(soscheduled.getRollNo()); + sfdcTimeHist.setCreatedDate(new Date()); + sfdcTimeHist.setCreatedBy("自动停机"); + sfdcTimeHist.setUpdatedDate(new Date()); + sfdcTimeHist.setDelflag("N"); + sfdcTimeHist.setVersion(1); + sfdcTimeHist.setReplaceFlag("0"); + sfdcTimeHist.setBatchNo(null); + sfdcTimeHist.setRemark(null); + int insert = sfdcTimeHistMapper.insert(sfdcTimeHist); + logger.info("停机红灯插入数据: {}", sfdcTimeHist); + if(insert >0){ + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("site", folderLocation.getSite()); + updateWrapper.eq("resource_id", folderLocation.getResourceId()); + updateWrapper.eq("seq_no", resourceScheduled.getSeqNo()); + updateWrapper.set("issend", "X"); + updateWrapper.set("sfdcid",sfdcTimeHist.getId()); + resourceScheduledMapper.update(updateWrapper); + logger.info("更新了中间表,变为X,sfdcid:{}",sfdcTimeHist.getId()); + fireAndForget("syncMesFormStop", () -> + syncMesFormStop(folderLocation.getSite(), resourceScheduled.getSeqNo(), + sfdcTimeHist.getId(), sfdcTimeHist.getEventTime())); + } + + } + + }else{ + if( "Y".equals(timeHist.getCompletedFlag())){ + SoscheduledroutingVo soscheduled = threeColorLampMapper.getSoscheduled(resourceScheduled.getSeqNo()); + if(soscheduled != null){ + int histSeqno = threeColorLampMapper.selectHistSeqno(folderLocation.getSite(), resourceScheduled.getSeqNo()); + SfdcTimeHist sfdcTimeHist = new SfdcTimeHist(); + sfdcTimeHist.setSite(folderLocation.getSite()); + sfdcTimeHist.setOrderNo(soscheduled.getOrderno()); + sfdcTimeHist.setItemNo(Double.valueOf(soscheduled.getItemno())); + sfdcTimeHist.setSeqNo(soscheduled.getSeqno()); + sfdcTimeHist.setHistSeqno(histSeqno+1); + Date currentTime = new Date(); + Date fiveMinutesAgo = new Date(currentTime.getTime() - failureTime * 60 * 1000); + /* sfdcTimeHist.setEventTime(fiveMinutesAgo);*/ + ThreeColorLampDownlog sfdcTimeHistStartTime =threeColorLampDownlogMapper.selectThreeColorLampDownlogStartTime(folderLocation.getSite(), folderLocation.getResourceId(),resourceScheduled.getSeqNo()) ; + sfdcTimeHist.setEventTime(sfdcTimeHistStartTime.getStartDate() == null?fiveMinutesAgo:sfdcTimeHistStartTime.getStartDate()); + sfdcTimeHist.setEnteredBy(null); + sfdcTimeHist.setEventDesc(null); + sfdcTimeHist.setDowntimeCode(null); + sfdcTimeHist.setEventType("D"); + sfdcTimeHist.setLinkhistSeqno(null); + sfdcTimeHist.setTillenteredBy(null); + sfdcTimeHist.setCompletedFlag("N"); + if("T".equals(resourceScheduled.getStatus())){ + sfdcTimeHist.setDowntimePhasein("调机"); + }else{ + sfdcTimeHist.setDowntimePhasein("生产"); + } + + sfdcTimeHist.setRollNo(soscheduled.getRollNo()); + sfdcTimeHist.setCreatedDate(new Date()); + sfdcTimeHist.setCreatedBy("自动停机"); + sfdcTimeHist.setUpdatedDate(new Date()); + sfdcTimeHist.setDelflag("N"); + sfdcTimeHist.setVersion(1); + sfdcTimeHist.setReplaceFlag("0"); + sfdcTimeHist.setBatchNo(null); + sfdcTimeHist.setRemark(null); + int insert = sfdcTimeHistMapper.insert(sfdcTimeHist); + logger.info("停机红灯插入数据: {}", sfdcTimeHist); + if(insert >0){ + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("site", folderLocation.getSite()); + updateWrapper.eq("resource_id", folderLocation.getResourceId()); + updateWrapper.eq("seq_no", resourceScheduled.getSeqNo()); + updateWrapper.set("issend", "X"); + updateWrapper.set("sfdcid",sfdcTimeHist.getId()); + resourceScheduledMapper.update(updateWrapper); + logger.info("更新了中间表,变为X,sfdcid:{}",sfdcTimeHist.getId()); + fireAndForget("syncMesFormStop", () -> + syncMesFormStop(folderLocation.getSite(), resourceScheduled.getSeqNo(), + sfdcTimeHist.getId(), sfdcTimeHist.getEventTime())); + } + + } + + } + } + + } + + }else{ + // 不满足连续 failureTime 条 0,0,0 的条件时,保持原有行为:将中间表发送状态置为 Y + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("site", folderLocation.getSite()); + updateWrapper.eq("resource_id", folderLocation.getResourceId()); + updateWrapper.eq("seq_no", resourceScheduled.getSeqNo()); + updateWrapper.set("issend", "Y"); + resourceScheduledMapper.update(updateWrapper); + } + } }else{ @@ -633,7 +863,16 @@ public class ModbusCollectServiceImpl if(StringUtils.isNotBlank(sfdcTimeHist1.getEventDesc())){ String startTime = sdf.format(sfdcTimeHist1.getEventTime()); String endTime = sdf.format(sfdcTimeHist1.getTillTime()); - threeColorLampDownlogMapper.updateDownLogEventDesc(startTime,endTime,sfdcTimeHist1.getEventDesc()); + threeColorLampDownlogMapper.updateDownLogEventDesc( + startTime, + endTime, + sfdcTimeHist1.getEventDesc(), + folderLocation.getSite(), + folderLocation.getResourceId(), + sfdcTimeHist1.getSeqNo(), + sfdcTimeHist1.getOrderNo(), + runTime + ); } } @@ -646,6 +885,9 @@ public class ModbusCollectServiceImpl updateWrapper.set("sfdcid",null); resourceScheduledMapper.update(updateWrapper); logger.info("更新了中间表,sfdcid变为null,id:{}",resourceScheduled.getId()); + fireAndForget("syncMesFormStart", () -> + syncMesFormStart(folderLocation.getSite(), resourceScheduled.getSeqNo(), + sfdcTimeHist.getId(), sfdcTimeHist.getEventTime())); } } @@ -846,5 +1088,55 @@ public class ModbusCollectServiceImpl } return sb.toString(); } + + private void syncMesFormStop(String site, String seqNo, Integer sfdcId, Date eventTime) { + postMesDowntimeEvent(site, seqNo, sfdcId, eventTime, "DOWN_TIME_INSERTED"); + } + + private void syncMesFormStart(String site, String seqNo, Integer sfdcId, Date eventTime) { + postMesDowntimeEvent(site, seqNo, sfdcId, eventTime, "DOWN_TIME_FINISHED"); + } + + private void postMesDowntimeEvent(String site, String seqNo, Integer sfdcId, Date eventTime, String event) { + if (StringUtils.isBlank(site) || StringUtils.isBlank(seqNo)) { + logger.warn("MES 同步跳过:site/seqNo 为空。event={}, site={}, seqNo={}", event, site, seqNo); + return; + } + if (StringUtils.isBlank(mesSyncUrl)) { + logger.warn("MES sync url 未配置,跳过同步。event={}, site={}, seqNo={}", event, site, seqNo); + return; + } + + + String finalEventTime = eventTime !=null + ? eventTime.toString() + : MES_TIME_FMT.format(ZonedDateTime.now(MES_ZONE)); + + Map body = new LinkedHashMap<>(); + body.put("site", site); + body.put("seqNo", seqNo); + body.put("downTimeId", sfdcId); + body.put("event", event); + body.put("eventTime", finalEventTime); + body.put("source", "RFID_JAR"); + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity> entity = new HttpEntity<>(body, headers); + + String url = UriComponentsBuilder.fromHttpUrl(mesSyncUrl).toUriString(); + try { + ResponseEntity resp = restTemplate.exchange(url, HttpMethod.POST, entity, String.class); + if (!resp.getStatusCode().is2xxSuccessful()) { + logger.warn("MES 同步失败。status={}, event={}, site={}, seqNo={}, downTimeId={}, resp={}", + resp.getStatusCodeValue(), event, site, seqNo, sfdcId, resp.getBody()); + } else { + logger.info("MES 同步成功。event={}, site={}, seqNo={}, downTimeId={}", event, site, seqNo, sfdcId); + } + } catch (RestClientException ex) { + logger.error("MES 同步异常。event={}, site={}, seqNo={}, downTimeId={}, url={}", + event, site, seqNo, sfdcId, url, ex); + } + } } diff --git a/threecolor-modbus-collector/src/main/resources/application-dev.yml b/threecolor-modbus-collector/src/main/resources/application-dev.yml index a4b8e06..76b46f6 100644 --- a/threecolor-modbus-collector/src/main/resources/application-dev.yml +++ b/threecolor-modbus-collector/src/main/resources/application-dev.yml @@ -5,8 +5,8 @@ spring: driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver type: com.alibaba.druid.pool.DruidDataSource # url: jdbc:sqlserver://192.168.1.90:1433;databaseName=CKT_MES_II_REAL - url: jdbc:sqlserver://xujiesoft.vicp.net:11515;databaseName=CKP_MES_Real_250207 - # url: jdbc:sqlserver://xujiesoft.vicp.net:11515;databaseName=ckp-srm + #url: jdbc:sqlserver://xujiesoft.vicp.net:11515;databaseName=CKP_MES_Real_250207 + url: jdbc:sqlserver://xujiesoft.vicp.net:11515;databaseName=CKT_MES_II_REAL username: sa password: XJsoft123 initial-size: 10 @@ -43,5 +43,12 @@ sys-file: task: data: threecolortime: 0 */1 * * * ? + threecolortime1: 0 0 0 29 2 ? + +# MES 停机事件同步(POST) +mes: + sync: + # 示例:'http://mes-host/api/downtime/event' + url: 'http://192.168.10.2:8089/produce/downTimeNotify' diff --git a/threecolor-modbus-collector/src/main/resources/dao/SfdcTimeHistMapper.xml b/threecolor-modbus-collector/src/main/resources/dao/SfdcTimeHistMapper.xml index 112eff3..0545cb4 100644 --- a/threecolor-modbus-collector/src/main/resources/dao/SfdcTimeHistMapper.xml +++ b/threecolor-modbus-collector/src/main/resources/dao/SfdcTimeHistMapper.xml @@ -8,6 +8,6 @@ \ No newline at end of file diff --git a/threecolor-modbus-collector/src/main/resources/dao/ThreeColorLampDownlogMapper.xml b/threecolor-modbus-collector/src/main/resources/dao/ThreeColorLampDownlogMapper.xml index 5585876..65c2db3 100644 --- a/threecolor-modbus-collector/src/main/resources/dao/ThreeColorLampDownlogMapper.xml +++ b/threecolor-modbus-collector/src/main/resources/dao/ThreeColorLampDownlogMapper.xml @@ -1,11 +1,28 @@ + + + update three_color_lamp_downlog set event_desc = #{eventDesc} where FORMAT(start_date, 'yyyy-MM-dd HH:mm') >= #{startTime} and FORMAT(end_date, 'yyyy-MM-dd HH:mm') <= #{endTime} + and site = #{site} + and resource_id = #{resourceId} + and seq_no = #{seqNo} + and order_no = #{orderNo} + \ No newline at end of file