diff --git a/business/src/main/java/com/fizz/business/comm/OPC/MessageSubscriptionRunner.java b/business/src/main/java/com/fizz/business/comm/OPC/MessageSubscriptionRunner.java index 86eaf66..9a5dfa6 100644 --- a/business/src/main/java/com/fizz/business/comm/OPC/MessageSubscriptionRunner.java +++ b/business/src/main/java/com/fizz/business/comm/OPC/MessageSubscriptionRunner.java @@ -1,13 +1,28 @@ package com.fizz.business.comm.OPC; +import com.fizz.business.constants.enums.ExitCutTypeEnum; +import com.fizz.business.constants.enums.OpcMessageType; +import com.fizz.business.domain.msg.*; +import com.fizz.business.service.hanle.OpcReceiverHandler; +import com.kangaroohy.milo.model.ReadWriteEntity; import com.kangaroohy.milo.service.MiloService; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.compress.utils.Lists; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; +import org.springframework.stereotype.Component; import javax.annotation.Resource; +import java.lang.reflect.Field; +import java.time.Duration; +import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; + +import static com.fizz.business.service.manager.OpcMessageIdsManager.*; //@Component @Slf4j @@ -15,25 +30,118 @@ public class MessageSubscriptionRunner implements ApplicationRunner { @Resource private MiloService miloService; + @Resource + private OpcReceiverHandler opcReceiverHandler; @Override public void run(ApplicationArguments args) { - subEntryMove(); + sub(); } - private void subEntryMove() { + private void sub() { try { - List ids = Lists.newArrayList(); - ids.add("GA.T1.T1001R"); - ids.add("GA.T1.String"); - miloService.subscriptionFromOpcUa(ids, (id, value) -> { - log.info("subscription 点位:{} 订阅到消息:{}", id, value); + LocalDateTime localDateTime = LocalDateTime.now(); + AtomicBoolean isFirstRun = new AtomicBoolean(false); + //入口移动,剪切、出口移动、出口称重 + miloService.subscriptionFromOpcUa(msgTriggers, 500,(id, value) -> { + if(!isFirstRun.get()){ + Duration duration = Duration.between(localDateTime, LocalDateTime.now()); + if(duration.getSeconds() > 10){ + isFirstRun.set(true); + }else{ + return; + } + } + String nodeName = id.getNodeId().toString(); + if (nodeName.contains(entryMoveIds.get("trigger"))) { + log.info("接收到Entry Move信号,subscription 点位:{} 订阅到消息:{}", nodeName, value.getValue().toString()); + readEntryMove(); + } else if (nodeName.contains(exitCutIds.get("trigger"))) { + log.info("接收到Exit Cut信号,subscription 点位:{} 订阅到消息:{}", nodeName, value.getValue().toString()); + readExitCut(); + } else if (nodeName.contains(exitMoveIds.get("trigger"))) { + log.info("接收到Exit Move信号,subscription 点位:{} 订阅到消息:{}", nodeName, value.getValue().toString()); + readExitMove(); + } else if (nodeName.contains(exitMeasureIds.get("trigger"))) { + log.info("接收到Weight Measure信号,subscription 点位:{} 订阅到消息:{}", nodeName, value.getValue().toString()); + readExitMeasure(); + } else { + log.info("error ids,subscription 点位:{} 订阅到消息:{}", nodeName, value.getValue().toString()); + } }); } catch (Exception e) { log.error("EntryMove 订阅失败:{0}",e.getMessage()); } - - } + + private void readEntryMove() + { + try { + EntryMovementMessage msg =new EntryMovementMessage(); + writeMessage( msg,entryMoveIds); + log.info("接收入口移动信号:从 {} 移动到 {} ", msg.getMaterialPlaceSource(), msg.getMaterialPlaceDestination()); + //opcReceiverHandler.onMessageReceived(OpcMessageType.ENTRY_MOVEMENT,msg); + } catch (Exception e) { + } + } + + private void readExitCut() + { + try { + ExitCutMessage msg = new ExitCutMessage(); + writeMessage( msg,exitCutIds); + log.info("接收到出口剪切信号:剪切类型 {},剪切长度{} ", msg.getCutType().toString(), msg.getCutLength()); +// opcReceiverHandler.onMessageReceived(OpcMessageType.EXIT_CUT,msg); + } catch (Exception e) { + } + } + + private void readExitMove() + { + try { + ExitMovementMessage msg = new ExitMovementMessage(); + writeMessage( msg,exitMoveIds); + log.info("接收出口移动信号:从 {} 移动到 {} ", msg.getExSrc(), msg.getExDesc()); +// opcReceiverHandler.onMessageReceived(OpcMessageType.EXIT_MOVEMENT,msg); + } catch (Exception e) { + } + } + + private void readExitMeasure() + { + try { + ExitMeasureMessage msg = new ExitMeasureMessage(); + writeMessage(msg,exitMoveIds); + log.info("接收出口称重信号:重量 {} ", msg.getWeight()); +// opcReceiverHandler.onMessageReceived(OpcMessageType.EXIT_MEASURE,msg); + } catch (Exception e) { + } + } + + private void writeMessage(OpcMessage msg,Map msgIds) throws Exception { + List ids = new ArrayList<>(msgIds.keySet()); + ids.remove("trigger"); + List nodes = miloService.readFromOpcUa(ids); + nodes.forEach(item->{ + String fieldName = msgIds.get(item.getIdentifier()); + if (fieldName != null) { + try { + Field field = msg.getClass().getDeclaredField(fieldName); + if (field.getType() == ExitCutTypeEnum.class) { + // 使用枚举类的自定义方法 + field.setAccessible(true); + ExitCutTypeEnum enumValue = ExitCutTypeEnum.fromCode((int)item.getValue()); + field.set(msg, enumValue); + } else { + // 其他类型正常处理 + BeanUtils.setProperty(msg, fieldName, item.getValue()); + } + } catch (Exception e) { + log.error("BeanUtils设置属性失败: {}", fieldName, e); + } + } + }); + } + } \ No newline at end of file diff --git a/business/src/main/java/com/fizz/business/comm/OPC/MessageTestSchedule.java b/business/src/main/java/com/fizz/business/comm/OPC/MessageTestSchedule.java new file mode 100644 index 0000000..8199d8d --- /dev/null +++ b/business/src/main/java/com/fizz/business/comm/OPC/MessageTestSchedule.java @@ -0,0 +1,108 @@ +package com.fizz.business.comm.OPC; + +import com.fizz.business.constants.enums.OpcMessageType; +import com.fizz.business.domain.msg.*; +import com.fizz.business.scheduled.BaseSchedule; +import com.fizz.business.service.hanle.OpcReceiverHandler; +import com.kangaroohy.milo.model.ReadWriteEntity; +import com.kangaroohy.milo.service.MiloService; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.Random; + +@Slf4j +@Component +@AllArgsConstructor +public class MessageTestSchedule extends BaseSchedule { + + @Resource + private OpcReceiverHandler opcReceiverHandler; + + public static boolean measureStart = false; + public static boolean measureReStart = false; + + public static BigDecimal welderLength1 = BigDecimal.valueOf(0); + public static int payOffReelNumber = 1; + public static BigDecimal celLength = BigDecimal.valueOf(500); + public static BigDecimal maxCelLength = new BigDecimal(5000); + public static BigDecimal welderLength2 = BigDecimal.valueOf(0); + public static BigDecimal welderLength3 = BigDecimal.valueOf(0); + public static BigDecimal welderLength4 = BigDecimal.valueOf(0); + public static BigDecimal cxlLength = BigDecimal.valueOf(1000); + + + @Scheduled(fixedDelay = 1000) + public void L1L2LineMeasure() { + try { + if(measureReStart){ + resetValue(); + measureReStart = false; + measureStart = true; + return; + } + + if(!measureStart) return; + + addValue(); + + Random rand = new Random(); + + AppMeasureMessage appMeasureMessage = new AppMeasureMessage(); + AppMeasureEntryMessage entryMsg = new AppMeasureEntryMessage(); + entryMsg.setStripLocation(welderLength1); + entryMsg.setPayOffReelNumber(payOffReelNumber); + entryMsg.setTensionPorBr1(BigDecimal.valueOf(rand.nextDouble()*100)); + entryMsg.setTensionBr1Br2(BigDecimal.valueOf(rand.nextDouble()*100)); + entryMsg.setTensionBr2Br3(BigDecimal.valueOf(rand.nextDouble()*100)); + entryMsg.setStripSpeed(BigDecimal.valueOf(rand.nextDouble()*300)); + entryMsg.setTensionCel(BigDecimal.valueOf(rand.nextDouble()*100)); + entryMsg.setCelLength(celLength); + entryMsg.setCelCapacity(celLength.divide(maxCelLength)); + + AppMeasureFurnaceMessage furMsg = new AppMeasureFurnaceMessage(); + furMsg.setStripLocation(welderLength2); + furMsg.setStripSpeed(BigDecimal.valueOf(rand.nextDouble()*100)); + + AppMeasureCoatMessage coatMsg = new AppMeasureCoatMessage(); + coatMsg.setStripLocation(welderLength3); + + AppMeasureExitMessage exitMsg = new AppMeasureExitMessage(); + exitMsg.setStripLocation(welderLength4); + exitMsg.setCxlLength(cxlLength); + exitMsg.setCxlLength(cxlLength.divide(maxCelLength)); + + appMeasureMessage.setAppMeasureEntryMessage(entryMsg); + appMeasureMessage.setAppMeasureFurnaceMessage(furMsg); + appMeasureMessage.setAppMeasureCoatMessage(coatMsg); + appMeasureMessage.setAppMeasureExitMessage(exitMsg); + + log.info("receive"); +// opcReceiverHandler.onMessageReceived(OpcMessageType.APP_MEASURE,appMeasureMessage); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private void resetValue(){ + welderLength1 = BigDecimal.valueOf(0); + payOffReelNumber = 1; + celLength = BigDecimal.valueOf(500); + + welderLength2 = BigDecimal.valueOf(0); + } + + private void addValue(){ + + Random rand = new Random(); + double nextLength = rand.nextDouble()*10; + welderLength1.add(BigDecimal.valueOf(nextLength)); + welderLength2.add(BigDecimal.valueOf(nextLength)); + } +} diff --git a/business/src/main/java/com/fizz/business/constants/enums/ExitCutTypeEnum.java b/business/src/main/java/com/fizz/business/constants/enums/ExitCutTypeEnum.java index 157ca7c..c47e8a7 100644 --- a/business/src/main/java/com/fizz/business/constants/enums/ExitCutTypeEnum.java +++ b/business/src/main/java/com/fizz/business/constants/enums/ExitCutTypeEnum.java @@ -1,8 +1,14 @@ package com.fizz.business.constants.enums; +import com.baomidou.mybatisplus.annotation.IEnum; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; import lombok.AllArgsConstructor; import lombok.Getter; +import java.util.HashMap; +import java.util.Map; + /** * * @author chenhao @@ -10,6 +16,36 @@ import lombok.Getter; */ @Getter @AllArgsConstructor -public enum ExitCutTypeEnum { - WELDER_CUT, SPLIT_CUT +public enum ExitCutTypeEnum implements IEnum{ + WELDER_CUT(0), SPLIT_CUT(1); + + private final Integer code; + + private static final Map MAP = new HashMap<>(5); + + static { + for (ExitCutTypeEnum e : ExitCutTypeEnum.values()) { + MAP.put(e.getValue(), e); + } + } + + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + public static ExitCutTypeEnum getByValue(String value) { + return MAP.get(value); + } + + @JsonValue + @Override + public String getValue() { + return this.name(); + } + + public static ExitCutTypeEnum fromCode(int code) { + for (ExitCutTypeEnum unit : values()) { + if (unit.getCode() == code) { + return unit; + } + } + return null; + } } diff --git a/business/src/main/java/com/fizz/business/controller/MessageTestController.java b/business/src/main/java/com/fizz/business/controller/MessageTestController.java new file mode 100644 index 0000000..1994714 --- /dev/null +++ b/business/src/main/java/com/fizz/business/controller/MessageTestController.java @@ -0,0 +1,76 @@ +package com.fizz.business.controller; + +import com.fizz.business.constants.enums.OpcMessageType; +import com.fizz.business.domain.msg.EntryMovementMessage; +import com.fizz.business.domain.msg.ExitCutMessage; +import com.fizz.business.domain.msg.ExitMeasureMessage; +import com.fizz.business.domain.msg.ExitMovementMessage; +import com.fizz.business.form.ModSetupResultForm; +import com.fizz.business.service.hanle.OpcReceiverHandler; +import com.fizz.business.vo.ModSetupResultVO; +import com.ruoyi.common.annotation.Anonymous; +import com.ruoyi.common.core.domain.R; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.List; + +import static com.fizz.business.comm.OPC.MessageTestSchedule.measureReStart; +import static com.fizz.business.comm.OPC.MessageTestSchedule.measureStart; + +@RestController +@RequestMapping("/api/msgtest") +@Tag(name ="通讯测试") +@Anonymous +public class MessageTestController { + + @Resource + private OpcReceiverHandler opcReceiverHandler; + + @PostMapping("/entryMove") + @Operation(summary = "入口移动信号") + public void entryMove(@RequestBody EntryMovementMessage msg) { + opcReceiverHandler.onMessageReceived(OpcMessageType.ENTRY_MOVEMENT,msg); + } + + @PostMapping("/exitCut") + @Operation(summary = "出口剪切信号") + public void exitCut(@RequestBody ExitCutMessage msg) { + opcReceiverHandler.onMessageReceived(OpcMessageType.EXIT_CUT,msg); + } + + @PostMapping("/exitMove") + @Operation(summary = "出口移动信号") + public void exitMove(@RequestBody ExitMovementMessage msg) { + opcReceiverHandler.onMessageReceived(OpcMessageType.EXIT_MOVEMENT,msg); + } + + @PostMapping("/exitMeasure") + @Operation(summary = "出口称重信号") + public void exitMeasure(@RequestBody ExitMeasureMessage msg) { + opcReceiverHandler.onMessageReceived(OpcMessageType.EXIT_MEASURE,msg); + } + + @PostMapping("/lineMeasure/start") + @Operation(summary = "测量信号-开始") + public void lineMeasureStart() { + measureStart = true; + } + + @PostMapping("/lineMeasure/stop") + @Operation(summary = "测量信号-停止") + public void lineMeasureStop() { + measureStart = false; + } + + @PostMapping("/lineMeasure/restart") + @Operation(summary = "测量信号-重置") + public void lineMeasureRestart() { + measureReStart = true; + } +} diff --git a/business/src/main/java/com/fizz/business/domain/msg/EntryMovementMessage.java b/business/src/main/java/com/fizz/business/domain/msg/EntryMovementMessage.java index a6759dd..67c7cfc 100644 --- a/business/src/main/java/com/fizz/business/domain/msg/EntryMovementMessage.java +++ b/business/src/main/java/com/fizz/business/domain/msg/EntryMovementMessage.java @@ -1,12 +1,13 @@ package com.fizz.business.domain.msg; -import lombok.Data; -import lombok.EqualsAndHashCode; +import lombok.*; -@Data +@Getter +@Setter @EqualsAndHashCode(callSuper = true) public class EntryMovementMessage extends OpcMessage { private Integer counter; private Integer materialPlaceSource; private Integer materialPlaceDestination; + } \ No newline at end of file diff --git a/business/src/main/java/com/fizz/business/domain/msg/PdiSetup.java b/business/src/main/java/com/fizz/business/domain/msg/PdiSetup.java index c2c88a3..5f28210 100644 --- a/business/src/main/java/com/fizz/business/domain/msg/PdiSetup.java +++ b/business/src/main/java/com/fizz/business/domain/msg/PdiSetup.java @@ -10,7 +10,7 @@ import java.math.BigDecimal; @Schema(description = "设定电文") public class PdiSetup { @Schema(description = "钢卷号") - private String coilNo; + private String coilId; @Schema(description = "开卷机号") private Integer PORFlag; @@ -62,7 +62,7 @@ public class PdiSetup { @Schema(description = "炉区张力1") private BigDecimal tensionFur1; @Schema(description = "炉区张力2") - private BigDecimal tensionFur3; + private BigDecimal tensionFur2; @Schema(description = "BR4- BR5 张力") private BigDecimal tensionBR4BR5; @Schema(description = "目标锌层重量-上表面") diff --git a/business/src/main/java/com/fizz/business/service/manager/OpcMessageIdsManager.java b/business/src/main/java/com/fizz/business/service/manager/OpcMessageIdsManager.java index e988abb..1a62670 100644 --- a/business/src/main/java/com/fizz/business/service/manager/OpcMessageIdsManager.java +++ b/business/src/main/java/com/fizz/business/service/manager/OpcMessageIdsManager.java @@ -1,18 +1,26 @@ package com.fizz.business.service.manager; +import com.fizz.business.constants.enums.OpcMessageType; +import com.google.common.collect.Lists; import com.google.common.collect.Maps; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; +import java.util.List; import java.util.Map; @Component public class OpcMessageIdsManager { - private static Map lineMeasureIds = Maps.newHashMap(); - private static Map entryMoveIds = Maps.newHashMap(); - private static Map exitCutIds = Maps.newHashMap(); - private static Map exitMeasureIds = Maps.newHashMap(); - private static Map exitMoveIds = Maps.newHashMap(); + + public static List msgTriggers = Lists.newArrayList(); + + public static Map lineMeasureIds = Maps.newHashMap(); + public static Map entryMoveIds = Maps.newHashMap(); + public static Map exitCutIds = Maps.newHashMap(); + public static Map exitMoveIds = Maps.newHashMap(); + public static Map exitMeasureIds = Maps.newHashMap(); + + public static String DEVICE_NAME = "ns=2;s=通道 1."; @PostConstruct public static void init() { @@ -20,24 +28,44 @@ public class OpcMessageIdsManager { //TODO load from database loadEntryMoveIds(); loadExitCutIds(); - loadExitMeasureIds(); loadExitMoveIds(); + loadExitMeasureIds(); + + loadMsgTriggers(); } + public static void loadEntryMoveIds(){ - entryMoveIds.put("ns=2;s=通道 2.LockStautsRead.lockStauts1","materialPlaceSource"); - entryMoveIds.put("ns=2;s=通道 2.LockStautsRead.lockStauts1","materialPlaceDestination"); + entryMoveIds.put("trigger","PLCLine.EntryMove.counter"); + entryMoveIds.put("ns=2;s=通道 1.PLCLine.EntryMove.src","materialPlaceSource"); + entryMoveIds.put("ns=2;s=通道 1.PLCLine.EntryMove.des","materialPlaceDestination"); } public static void loadExitCutIds(){ - - } - - public static void loadExitMeasureIds(){ - + exitCutIds.put("trigger","PLCLine.ExitCut.counter"); + exitCutIds.put("ns=2;s=通道 1.PLCLine.ExitCut.cutType","cutType"); + exitCutIds.put("ns=2;s=通道 1.PLCLine.ExitCut.cutLength","cutLength"); + exitCutIds.put("ns=2;s=通道 1.PLCLine.ExitCut.outerDiameter","outerDiameter"); + exitCutIds.put("ns=2;s=通道 1.PLCLine.ExitCut.leftLength","leftLength"); + exitCutIds.put("ns=2;s=通道 1.PLCLine.ExitCut.breakPosition","breakPosition"); } public static void loadExitMoveIds(){ + exitMoveIds.put("trigger","PLCLine.ExitMove.counter"); + exitMoveIds.put("ns=2;s=通道 1.PLCLine.ExitMove.src","exSrc"); + exitMoveIds.put("ns=2;s=通道 1.PLCLine.ExitMove.des","exDesc"); + } + public static void loadExitMeasureIds(){ + exitMeasureIds.put("trigger","PLCLine.ExitMeasure.counter"); + exitMeasureIds.put("ns=2;s=通道 1.PLCLine.ExitMeasure.weight","weight"); + } + + + public static void loadMsgTriggers(){ + msgTriggers.add(DEVICE_NAME+entryMoveIds.get("trigger")); + msgTriggers.add(DEVICE_NAME+exitCutIds.get("trigger")); + msgTriggers.add(DEVICE_NAME+exitMoveIds.get("trigger")); + msgTriggers.add(DEVICE_NAME+exitMeasureIds.get("trigger")); } }