Compare commits
13 Commits
e6c2b0aec2
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| bcea5255e6 | |||
| a718557762 | |||
| 6db871f99b | |||
| 82cffb7ea3 | |||
| f8b7d6b813 | |||
| d8f0e102c9 | |||
| a6756bc7db | |||
| cd192d86ba | |||
| b5dfb0c9b4 | |||
| 675dd43262 | |||
| 53e4635506 | |||
| a3e46674b3 | |||
| 65d9f59ac4 |
@@ -115,6 +115,12 @@
|
||||
<version>3.1.4.0.6.15</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.xingshuangs</groupId>
|
||||
<artifactId>iot-communication</artifactId>
|
||||
<version>1.5.5</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.alibaba</groupId>-->
|
||||
|
||||
@@ -86,7 +86,7 @@ public class MessageSubscriptionRunner implements ApplicationRunner {
|
||||
EntryMovementMessage msg =new EntryMovementMessage();
|
||||
writeMessage( msg,entryMoveIds);
|
||||
log.info("接收入口移动信号:从 {} 移动到 {} ", msg.getMaterialPlaceSource(), msg.getMaterialPlaceDestination());
|
||||
logDataService.logInfo("TRACK","Received entry movement signal: from {} to {}", msg.getMaterialPlaceSource(), msg.getMaterialPlaceDestination());
|
||||
logDataService.logInfo("TRACK","Received entry movement signal: from " + msg.getMaterialPlaceSource() + " to " + msg.getMaterialPlaceDestination());
|
||||
opcReceiverHandler.onMessageReceived(OpcMessageType.ENTRY_MOVEMENT,msg);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
@@ -98,7 +98,7 @@ public class MessageSubscriptionRunner implements ApplicationRunner {
|
||||
ExitCutMessage msg = new ExitCutMessage();
|
||||
writeMessage(msg,exitCutIds);
|
||||
log.info("接收到出口剪切信号:剪切类型 {},剪切长度{} ", msg.getCutType().toString(), msg.getCutLength());
|
||||
logDataService.logInfo("TRACK","Received exit cut signal: cut type {}, cut length {}", msg.getCutType().toString(), msg.getCutLength());
|
||||
logDataService.logInfo("TRACK","Received exit cut signal: cut type " + msg.getCutType().toString() + ", cut length " + msg.getCutLength());
|
||||
opcReceiverHandler.onMessageReceived(OpcMessageType.EXIT_CUT,msg);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
@@ -110,7 +110,7 @@ public class MessageSubscriptionRunner implements ApplicationRunner {
|
||||
ExitMovementMessage msg = new ExitMovementMessage();
|
||||
writeMessage( msg,exitMoveIds);
|
||||
log.info("接收出口移动信号:从 {} 移动到 {} ", msg.getExSrc(), msg.getExDesc());
|
||||
logDataService.logInfo("TRACK","Received exit movement signal: from {} to {}", msg.getExSrc(), msg.getExDesc());
|
||||
logDataService.logInfo("TRACK","Received exit movement signal: from " + msg.getExSrc() + " to " + msg.getExDesc());
|
||||
opcReceiverHandler.onMessageReceived(OpcMessageType.EXIT_MOVEMENT,msg);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
@@ -122,7 +122,7 @@ public class MessageSubscriptionRunner implements ApplicationRunner {
|
||||
ExitMeasureMessage msg = new ExitMeasureMessage();
|
||||
writeMessage(msg,exitMeasureIds);
|
||||
log.info("接收出口称重信号:重量 {} ", msg.getWeight());
|
||||
logDataService.logInfo("TRACK","Received exit weight signal: weight {}", msg.getWeight());
|
||||
logDataService.logInfo("TRACK","Received exit weight signal: weight " + msg.getWeight());
|
||||
opcReceiverHandler.onMessageReceived(OpcMessageType.EXIT_MEASURE,msg);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.fizz.business.domain.msg.OpcMessage;
|
||||
import com.fizz.business.domain.msg.PdiSetup;
|
||||
import com.kangaroohy.milo.model.ReadWriteEntity;
|
||||
import com.kangaroohy.milo.service.MiloService;
|
||||
import com.fizz.business.service.LogDataService;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -25,6 +26,9 @@ public class OpcMessageSend {
|
||||
@Resource
|
||||
private MiloService miloService;
|
||||
|
||||
@Resource
|
||||
private LogDataService logDataService;
|
||||
|
||||
private void sendPdiSetup(PdiSetup pdiSetup) {
|
||||
try {
|
||||
List<ReadWriteEntity> entities = getWriteEntities(pdiSetup, pdiSetupIds);
|
||||
@@ -111,43 +115,6 @@ public class OpcMessageSend {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量写数据方法:通过字段名向多个点位写入数据
|
||||
* @param fieldDataMap 字段名和值的映射,key 为 fieldName,value 为要写入的值
|
||||
* @return 是否全部写入成功
|
||||
*/
|
||||
public boolean batchWriteDataByFieldName(Map<String, Object> fieldDataMap) {
|
||||
try {
|
||||
if (fieldDataMap == null || fieldDataMap.isEmpty()) {
|
||||
log.warn("批量写数据:数据映射为空,跳过写入");
|
||||
return false;
|
||||
}
|
||||
List<ReadWriteEntity> entities = new ArrayList<>();
|
||||
for (Map.Entry<String, Object> entry : fieldDataMap.entrySet()) {
|
||||
String fieldName = entry.getKey();
|
||||
String identifier = findIdentifierByFieldName(fieldName);
|
||||
if (identifier == null) {
|
||||
log.warn("未找到字段名对应的 OPC 节点路径,fieldName={},跳过该字段", fieldName);
|
||||
continue;
|
||||
}
|
||||
entities.add(ReadWriteEntity.builder()
|
||||
.identifier(identifier)
|
||||
.value(entry.getValue())
|
||||
.build());
|
||||
}
|
||||
if (entities.isEmpty()) {
|
||||
log.warn("批量写数据:没有有效的字段映射,跳过写入");
|
||||
return false;
|
||||
}
|
||||
miloService.writeToOpcUa(entities);
|
||||
log.info("批量写入 OPC 数据成功,共 {} 个点位", entities.size());
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error("批量写入 OPC 数据失败,原因:{}", e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量写数据方法:向多个点位写入数据(直接使用节点路径)
|
||||
* @param dataMap 点位标识符和值的映射,key 为 identifier,value 为要写入的值
|
||||
@@ -155,10 +122,6 @@ public class OpcMessageSend {
|
||||
*/
|
||||
public boolean batchWriteData(Map<String, Object> dataMap) {
|
||||
try {
|
||||
if (dataMap == null || dataMap.isEmpty()) {
|
||||
log.warn("批量写数据:数据映射为空,跳过写入");
|
||||
return false;
|
||||
}
|
||||
List<ReadWriteEntity> entities = new ArrayList<>();
|
||||
for (Map.Entry<String, Object> entry : dataMap.entrySet()) {
|
||||
entities.add(ReadWriteEntity.builder()
|
||||
@@ -167,10 +130,10 @@ public class OpcMessageSend {
|
||||
.build());
|
||||
}
|
||||
miloService.writeToOpcUa(entities);
|
||||
log.info("批量写入 OPC 数据成功,共 {} 个点位", entities.size());
|
||||
logDataService.logInfo("WRITE","批量写入 OPC 数据成功,共"+ entities.size()+ "个点位");
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error("批量写入 OPC 数据失败,原因:{}", e.getMessage(), e);
|
||||
logDataService.logInfo("WRITE","批量写入 OPC 数据失败,原因:"+ e.getMessage()+","+ e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,38 +14,58 @@ import java.util.*;
|
||||
@Getter
|
||||
public enum DeviceEnum {
|
||||
// === Entry section / 入口段 ===
|
||||
POR1(0, "Uncoiler #1", 0.0, SectionType.ENTRY, SourceType.ENTRY, Arrays.asList("tensionPorBr1", "stripSpeed")),
|
||||
POR2(1, "Uncoiler #2", 0.0, SectionType.ENTRY, SourceType.ENTRY, Arrays.asList("tensionPorBr2", "stripSpeed")),
|
||||
POR1(0, "Uncoiler #1", 0.0, SectionType.ENTRY, SourceType.ENTRY, Arrays.asList("tensionPorBr1", "stripSpeed","tensionBr45Br6")),
|
||||
POR2(1, "Uncoiler #2", 0.0, SectionType.ENTRY, SourceType.ENTRY, Arrays.asList("tensionPorBr2", "stripSpeed","tensionBr45Br6")),
|
||||
WELDER(2, "Welder", 4.98, SectionType.ENTRY, SourceType.ENTRY, Arrays.asList("weldStatus")),
|
||||
ENL1(3, "Entry Looper #1", 19.04, SectionType.PROCESS, SourceType.ENTRY, Arrays.asList("celLength", "celCapacity", "tensionCel")),
|
||||
ENL2(4, "Entry Looper #2", 167.09, SectionType.PROCESS, SourceType.ENTRY, Arrays.asList("celLength", "celCapacity", "tensionCel")),
|
||||
ENL3(5, "Entry Looper #3", 198.19, SectionType.PROCESS, SourceType.ENTRY, Arrays.asList("celLength", "celCapacity", "tensionCel")),
|
||||
ENL1(3, "Entry Looper #1", 19.041, SectionType.PROCESS, SourceType.ENTRY, Arrays.asList("celLength", "celCapacity", "tensionCel")),
|
||||
ENL2(4, "Entry Looper #2", 167.091, SectionType.PROCESS, SourceType.ENTRY, Arrays.asList("celLength", "celCapacity", "tensionCel")),
|
||||
ENL3(5, "Entry Looper #3", 198.191, SectionType.PROCESS, SourceType.ENTRY, Arrays.asList("celLength", "celCapacity", "tensionCel","tensionBr45Br6")),
|
||||
|
||||
// === Process section / 工艺段 ===
|
||||
CLEAN(6, "Cleaning Section", 264.803, SectionType.PROCESS, SourceType.FURNACE, Arrays.asList("cleaningVoltage", "cleaningCurrent", "alkaliConcentration", "alkaliTemperature")),
|
||||
FUR1(7, "Annealing Furnace - Preheating", 302.837, SectionType.PROCESS, SourceType.FURNACE, Arrays.asList("phfExitStripTemp", "potTemperature", "gasConsumption")),
|
||||
FUR2(8, "Annealing Furnace - Heating", 381.057, SectionType.PROCESS, SourceType.FURNACE, Arrays.asList("rtfExitStripTemp", "zincPotPower")),
|
||||
FUR3(9, "Annealing Furnace - Cooling", 416.837, SectionType.PROCESS, SourceType.FURNACE, Arrays.asList("jcsExitStripTemp", "coolingTowerStripTemp")),
|
||||
FUR4(10, "Annealing Furnace - Equalizing", 432.16, SectionType.PROCESS, SourceType.FURNACE, Arrays.asList("scsExitStripTemp")),
|
||||
POT(11, "Zinc Pot", 442.994, SectionType.PROCESS, SourceType.COAT, Arrays.asList("scsExitStripTemp")),
|
||||
TOWER(12, "Cooling Tower", 563.594, SectionType.PROCESS, SourceType.COAT, Arrays.asList("scsExitStripTemp")),
|
||||
TM(13, "Temper Mill", 586.529, SectionType.PROCESS, SourceType.COAT, Arrays.asList("tensionBr5Tm", "stripSpeedTmExit")),
|
||||
TL(14, "Tension Leveler", 612.909, SectionType.PROCESS, SourceType.COAT, Arrays.asList("tlElongation", "tensionTlBr7")),
|
||||
COAT(15, "Post-treatment Section", 712.699, SectionType.PROCESS, SourceType.COAT, Arrays.asList(
|
||||
FUR1(7, "Annealing Furnace - Preheating", 302.837, SectionType.PROCESS, SourceType.FURNACE, Arrays.asList(
|
||||
"phFurnaceTemperatureActual",
|
||||
"nof1FurnaceTemperatureActual", "nof2FurnaceTemperatureActual", "nof3FurnaceTemperatureActual", "nof4FurnaceTemperatureActual",
|
||||
"nofPlateTemperatureActual",
|
||||
"nofFurnacePressureActual"
|
||||
)),
|
||||
FUR2(8, "Annealing Furnace - Heating", 381.057, SectionType.PROCESS, SourceType.FURNACE, Arrays.asList(
|
||||
"rtf1FurnaceTemperatureActual", "rtf2FurnaceTemperatureActual",
|
||||
"rtfPlateTemperatureActual",
|
||||
"rtfFurnacePressureActual"
|
||||
)),
|
||||
FUR3(9, "Annealing Furnace - Cooling", 398.947, SectionType.PROCESS, SourceType.FURNACE, Arrays.asList(
|
||||
"jcf1FurnaceTemperatureActual",
|
||||
"jcfFan1ActualSpeed", "jcfFan2ActualSpeed", "jcfFan3ActualSpeed", "jcfFan4ActualSpeed"
|
||||
)),
|
||||
FUR4(10, "Annealing Furnace - Equalizing", 414.27, SectionType.PROCESS, SourceType.FURNACE, Arrays.asList(
|
||||
"lthFurnaceTemperatureActual",
|
||||
"tdsFurnaceTemperatureActual",
|
||||
"lbzFurnaceTemperatureActual",
|
||||
"tdsPlateTemperatureActual",
|
||||
"tdsFurnacePressureActual"
|
||||
)),
|
||||
|
||||
POT(11, "Zinc Pot", 425.104, SectionType.PROCESS, SourceType.COAT, Arrays.asList("potTemperature")),
|
||||
TOWER(12, "Cooling Tower", 545.659, SectionType.PROCESS, SourceType.COAT, Arrays.asList("coolingTowerTemperature")),
|
||||
TM(13, "Temper Mill", 568.639, SectionType.PROCESS, SourceType.COAT, Arrays.asList("tensionBr5Tm", "stripSpeedTmExit")),
|
||||
TL(14, "Tension Leveler", 595.019, SectionType.PROCESS, SourceType.COAT, Arrays.asList("tlElongation", "tensionTlBr7")),
|
||||
COAT(15, "Post-treatment Section", 694.809, SectionType.PROCESS, SourceType.COAT, Arrays.asList(
|
||||
"avrCoatingWeightTop","stdCoatingWeightTop","maxCoatingWeightTop","minCoatingWeightTop",
|
||||
"avrCoatingWeightBottom","stdCoatingWeightBottom","maxCoatingWeightBottom","minCoatingWeightBottom",
|
||||
"airKnifePressure","airKnifeFlow","airKnifeGap","stripSpeedTmExit","tensionBr8Tm",
|
||||
"tensionTmBr9","tensionBr8Br9","tmMask","tmElongation","rollForceOperator","rollForceDrive",
|
||||
"motorTorque","bendingForce","antiCrimpingRollMesh","billyRollMesh",
|
||||
"tensionTlBr10Br11","tensionBr9toBr10Br11","tlFlag","tlElongation","levelingUnit1Mesh","levelingUnit2Mesh",
|
||||
"antiCrossBowUnitMesh","tensionBr10Br11toBr12","stripSpeedAfp","stripTempAfp"
|
||||
"antiCrossBowUnitMesh","tensionBr10Br11Br12","stripSpeedAfp","stripTempAfp",
|
||||
"potTemperature","coolingTowerTemperature","potPower"
|
||||
)),
|
||||
|
||||
// === Exit section / 出口段 ===
|
||||
CXL1(16, "Exit Looper #1", 720.709, SectionType.EXIT, SourceType.EXIT, Arrays.asList("cxlLength", "cxlCapacity", "tensionCxl")),
|
||||
CXL2(17, "Exit Looper #2", 888.789, SectionType.EXIT, SourceType.EXIT, Arrays.asList("cxlLength", "cxlCapacity", "tensionCxl")),
|
||||
CXL1(16, "Exit Looper #1", 702.819, SectionType.EXIT, SourceType.EXIT, Arrays.asList("cxlLength", "cxlCapacity", "tensionCxl")),
|
||||
CXL2(17, "Exit Looper #2", 870.899, SectionType.EXIT, SourceType.EXIT, Arrays.asList("cxlLength", "cxlCapacity", "tensionCxl")),
|
||||
// INS(18, "Inspection Station", 940.561, SectionType.EXIT, SourceType.EXIT, Arrays.asList("inspectionStatus")),
|
||||
TR(18, "Recoiler", 952.819, SectionType.EXIT, SourceType.EXIT, Arrays.asList("coilLength", "speedExitSection", "tensionBr9Tr")),
|
||||
TR(18, "Recoiler", 934.929, SectionType.EXIT, SourceType.EXIT, Arrays.asList("coilLength", "speedExitSection", "tensionBr9Tr")),
|
||||
EXC(19, "Coil Car", 9999999.0, SectionType.EXIT, SourceType.EXIT, Collections.emptyList()),
|
||||
WEIGHT(20, "Weighing Saddle", 9999999.0, SectionType.EXIT, SourceType.EXIT, Collections.emptyList());
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.fizz.business.service.CrmPdiPlanService;
|
||||
import com.fizz.business.comm.OPC.OpcMessageSend;
|
||||
import com.fizz.business.service.client.RedisCacheManager;
|
||||
import com.fizz.business.service.impl.BeanFactory;
|
||||
import com.fizz.business.service.strip.SegmentTrackerService;
|
||||
import com.fizz.business.utils.MatmapUtil;
|
||||
import com.fizz.business.utils.WebSocketUtil;
|
||||
import com.fizz.business.vo.CrmPdiPlanVO;
|
||||
@@ -40,6 +41,14 @@ public enum L1OperateMatEnum implements IEnum<String>, IOperateMat<L1OperateMatF
|
||||
MatmapUtil.setMatmap(form.getPorIdx(), form.getEntryMatId(), form.getPlanId(), form.getPlanNo());
|
||||
// 钢卷上线时, 缓存工艺规程
|
||||
// BeanFactory.getBean(RedisCacheManager.class).setCoilSetup(form.getPlanId());
|
||||
// ONLINE 时同步下发入口参数 + 张力下一设定值
|
||||
try {
|
||||
BeanFactory.getBean(SegmentTrackerService.class)
|
||||
.sendAllPdiOnOnline(form.getEntryMatId(), form.getPorIdx());
|
||||
} catch (Exception e) {
|
||||
BeanFactory.getBean(com.fizz.business.service.LogDataService.class)
|
||||
.logWarn("L1-ONLINE", "ONLINE下发异常, coilId={}, porIdx={}, err={}", form.getEntryMatId(), form.getPorIdx(), e.toString());
|
||||
}
|
||||
WebSocketUtil.sendSignalMsg(form);
|
||||
WebSocketUtil.sendMatmapMsg();
|
||||
}
|
||||
@@ -80,11 +89,11 @@ public enum L1OperateMatEnum implements IEnum<String>, IOperateMat<L1OperateMatF
|
||||
PAY_OVER("甩尾") {
|
||||
@Override
|
||||
public void operate(L1OperateMatForm form) {
|
||||
ArrayList<String> status = Lists.newArrayList(PlanStatusEnum.PRODUCING.name(), PlanStatusEnum.PRODUCT.name());
|
||||
// ArrayList<String> status = Lists.newArrayList(PlanStatusEnum.PRODUCING.name(), PlanStatusEnum.PRODUCT.name());
|
||||
CrmPdiPlanService planClient = BeanFactory.getBean(CrmPdiPlanService.class);
|
||||
CrmPdiPlanVO plan = planClient.getByCoilIdAndOperId(form.getEntryMatId());
|
||||
Assert.notNull(plan, "计划[{}]不存在", plan.getId());
|
||||
Assert.isTrue(status.contains(plan.getStatus()), "当前状态[{}]不支持甩尾", plan.getStatus());
|
||||
// Assert.isTrue(status.contains(plan.getStatus()), "当前状态[{}]不支持甩尾", plan.getStatus());
|
||||
MatmapUtil.clearMatmap(form.getPorIdx());
|
||||
WebSocketUtil.sendSignalMsg(form);
|
||||
WebSocketUtil.sendMatmapMsg();
|
||||
@@ -122,10 +131,14 @@ public enum L1OperateMatEnum implements IEnum<String>, IOperateMat<L1OperateMatF
|
||||
private void syncPlanStatus(String planId, String matId) {
|
||||
CrmPdiPlanService planClient = BeanFactory.getBean(CrmPdiPlanService.class);
|
||||
|
||||
planClient.changeStatus(ChangePlanStatusForm.builder()
|
||||
boolean ok = planClient.changeStatus(ChangePlanStatusForm.builder()
|
||||
.operation(this.name())
|
||||
.id(planId)
|
||||
.matId(matId)
|
||||
.build());
|
||||
|
||||
if (!ok) {
|
||||
throw new IllegalStateException(String.format("计划状态同步失败, operation=%s, planId=%s, matId=%s", this.name(), planId, matId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.fizz.business.controller;
|
||||
import com.fizz.business.domain.ProStoppage;
|
||||
import com.fizz.business.form.ProStoppageForm;
|
||||
import com.fizz.business.service.ProStoppageService;
|
||||
import com.fizz.business.service.ProStoppageTypeService;
|
||||
import com.fizz.business.domain.vo.ProStoppageTypeVO;
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
@@ -22,6 +24,9 @@ public class ProStoppageController {
|
||||
@Resource
|
||||
private ProStoppageService proStoppageService;
|
||||
|
||||
@Resource
|
||||
private ProStoppageTypeService proStoppageTypeService;
|
||||
|
||||
// @PostMapping("/add")
|
||||
// @ApiOperation("新增停机记录")
|
||||
// public R<Boolean> add(@RequestBody ProStoppage proStoppage) {
|
||||
@@ -51,4 +56,15 @@ public class ProStoppageController {
|
||||
public R<List<Object>> calc(@RequestBody ProStoppageForm form) {
|
||||
return R.ok(proStoppageService.calc(form));
|
||||
}
|
||||
|
||||
@GetMapping("/types")
|
||||
@Operation(summary = "查询停机类型")
|
||||
public R<List<ProStoppageTypeVO>> types() {
|
||||
return R.ok(proStoppageTypeService.listAll().stream().map(item -> {
|
||||
ProStoppageTypeVO vo = new ProStoppageTypeVO();
|
||||
vo.setStopType(item.getStopType());
|
||||
vo.setRemark(item.getRemark());
|
||||
return vo;
|
||||
}).collect(java.util.stream.Collectors.toList()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.fizz.business.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@TableName("pro_stoppage_type")
|
||||
public class ProStoppageType {
|
||||
|
||||
@TableId(value = "STOP_TYPE", type = IdType.INPUT)
|
||||
private Integer stopType;
|
||||
|
||||
@TableField("REMARK")
|
||||
private String remark;
|
||||
|
||||
@TableField("INSDATE")
|
||||
private LocalDateTime insdate;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,9 @@ public class AppMeasureEntryMessage extends OpcMessage {
|
||||
@Schema(description = "钢带张力 BR2 – BR3 (daN)")
|
||||
private BigDecimal tensionBr2Br3;
|
||||
|
||||
@Schema(description = "钢带张力 BR4/5 – BR6 (daN)")
|
||||
private BigDecimal tensionBr45Br6;
|
||||
|
||||
@Schema(description = "钢带速度 (m/min)")
|
||||
private BigDecimal stripSpeed;
|
||||
|
||||
@@ -74,6 +77,4 @@ public class AppMeasureEntryMessage extends OpcMessage {
|
||||
@Schema(description = "热风压力 (Pa)")
|
||||
private BigDecimal hotAirPressure;
|
||||
|
||||
@Schema(description = "钢带张力 BR4/5 – BR6 (daN)")
|
||||
private BigDecimal bR4or5toBR6Tension;
|
||||
}
|
||||
@@ -120,6 +120,56 @@ public class PdiSetup extends OpcMessage{
|
||||
@Schema(description = "BR9-TR 张力")
|
||||
private BigDecimal tensionBR9TR;
|
||||
|
||||
// 新增的张力设定值字段
|
||||
@Schema(description = "开卷机1当前张力")
|
||||
private BigDecimal tensionPor1Current;
|
||||
@Schema(description = "开卷机1下一设定张力")
|
||||
private BigDecimal tensionPor1Next;
|
||||
@Schema(description = "开卷机2当前张力")
|
||||
private BigDecimal tensionPor2Current;
|
||||
@Schema(description = "开卷机2下一设定张力")
|
||||
private BigDecimal tensionPor2Next;
|
||||
@Schema(description = "入口活套当前张力")
|
||||
private BigDecimal tensionEnLpCurrent;
|
||||
@Schema(description = "入口活套下一设定张力")
|
||||
private BigDecimal tensionEnLpNext;
|
||||
@Schema(description = "清洗段当前张力")
|
||||
private BigDecimal tensionCleaningCurrent;
|
||||
@Schema(description = "清洗段下一设定张力")
|
||||
private BigDecimal tensionCleaningNext;
|
||||
@Schema(description = "炉区当前张力")
|
||||
private BigDecimal tensionFuranceCurrent;
|
||||
@Schema(description = "炉区下一设定张力")
|
||||
private BigDecimal tensionFuranceNext;
|
||||
@Schema(description = "镀后冷却当前张力")
|
||||
private BigDecimal tensionGalvanizingCoolCurrent;
|
||||
@Schema(description = "镀后冷却下一设定张力")
|
||||
private BigDecimal tensionGalvanizingCoolNext;
|
||||
@Schema(description = "光整机入口当前张力")
|
||||
private BigDecimal tensionTmEntryCurrent;
|
||||
@Schema(description = "光整机入口下一设定张力")
|
||||
private BigDecimal tensionTmEntryNext;
|
||||
@Schema(description = "光整机出口当前张力")
|
||||
private BigDecimal tensionTmExitCurrent;
|
||||
@Schema(description = "光整机出口下一设定张力")
|
||||
private BigDecimal tensionTmExitNext;
|
||||
@Schema(description = "拉矫机当前张力")
|
||||
private BigDecimal tensionTlCurrent;
|
||||
@Schema(description = "拉矫机下一设定张力")
|
||||
private BigDecimal tensionTlNext;
|
||||
@Schema(description = "涂敷段当前张力")
|
||||
private BigDecimal tensionCoatingCurrent;
|
||||
@Schema(description = "涂敷段下一设定张力")
|
||||
private BigDecimal tensionCoatingNext;
|
||||
@Schema(description = "出口活套当前张力")
|
||||
private BigDecimal tensionExLpCurrent;
|
||||
@Schema(description = "出口活套下一设定张力")
|
||||
private BigDecimal tensionExLpNext;
|
||||
@Schema(description = "卷取机当前张力")
|
||||
private BigDecimal tensionTrCurrent;
|
||||
@Schema(description = "卷取机下一设定张力")
|
||||
private BigDecimal tensionTrNext;
|
||||
|
||||
@Schema(description = "涂油投入")
|
||||
private Integer oilingFlag;
|
||||
@Schema(description = "上表面涂油量")
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.fizz.business.domain.s7;
|
||||
|
||||
import com.github.xingshuangs.iot.common.enums.EDataType;
|
||||
import com.github.xingshuangs.iot.protocol.s7.serializer.S7Variable;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DB35501Data {
|
||||
@S7Variable(address = "DB35501.0", type = EDataType.STRING, count = 20)
|
||||
private String coilId;
|
||||
|
||||
@S7Variable(address = "DB35501.30", type = EDataType.FLOAT32)
|
||||
private float entryCoilWeight;
|
||||
|
||||
@S7Variable(address = "DB35501.34", type = EDataType.FLOAT32)
|
||||
private float entryCoilLength;
|
||||
|
||||
@S7Variable(address = "DB35501.38", type = EDataType.FLOAT32)
|
||||
private float entryCoilWidth;
|
||||
|
||||
@S7Variable(address = "DB35501.42", type = EDataType.FLOAT32)
|
||||
private float entryCoilThick;
|
||||
|
||||
@S7Variable(address = "DB35501.46", type = EDataType.FLOAT32)
|
||||
private float entryCoilInnerDia;
|
||||
|
||||
@S7Variable(address = "DB35501.50", type = EDataType.FLOAT32)
|
||||
private float entryCoilOuterDia;
|
||||
|
||||
@S7Variable(address = "DB35501.54", type = EDataType.BYTE)
|
||||
private byte alloyCode;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.fizz.business.domain.s7;
|
||||
|
||||
import com.github.xingshuangs.iot.common.enums.EDataType;
|
||||
import com.github.xingshuangs.iot.protocol.s7.serializer.S7Variable;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DB35502Data {
|
||||
@S7Variable(address = "DB35502.114", type = EDataType.FLOAT32)
|
||||
private float tensionPor1Next;
|
||||
|
||||
@S7Variable(address = "DB35502.122", type = EDataType.FLOAT32)
|
||||
private float tensionPor2Next;
|
||||
|
||||
@S7Variable(address = "DB35502.130", type = EDataType.FLOAT32)
|
||||
private float tensionEnLpNext;
|
||||
|
||||
@S7Variable(address = "DB35502.138", type = EDataType.FLOAT32)
|
||||
private float tensionCleaningNext;
|
||||
|
||||
@S7Variable(address = "DB35502.162", type = EDataType.FLOAT32)
|
||||
private float tensionGalvanizingCoolNext;
|
||||
|
||||
@S7Variable(address = "DB35502.266", type = EDataType.FLOAT32)
|
||||
private float tensionExLpNext;
|
||||
|
||||
@S7Variable(address = "DB35502.232", type = EDataType.FLOAT32)
|
||||
private float tensionTlNext;
|
||||
|
||||
@S7Variable(address = "DB35502.198", type = EDataType.FLOAT32)
|
||||
private float tensionTmExitNext;
|
||||
|
||||
@S7Variable(address = "DB35502.146", type = EDataType.FLOAT32)
|
||||
private float tensionFuranceNext;
|
||||
|
||||
@S7Variable(address = "DB35502.274", type = EDataType.FLOAT32)
|
||||
private float tensionTrNext;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.fizz.business.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ProStoppageTypeVO {
|
||||
|
||||
private Integer stopType;
|
||||
|
||||
private String remark;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.fizz.business.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.fizz.business.domain.ProStoppageType;
|
||||
|
||||
public interface ProStoppageTypeMapper extends BaseMapper<ProStoppageType> {
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ public interface CrmPdiPlanService extends IService<CrmPdiPlan> {
|
||||
*/
|
||||
CrmPdiPlan getFirstUnProducedCoil();
|
||||
|
||||
void changeStatus(ChangePlanStatusForm build);
|
||||
boolean changeStatus(ChangePlanStatusForm build);
|
||||
|
||||
/**
|
||||
* 获取当前正在线上的钢卷(优先级:ONLINE > PRODUCING > READY/NEW)
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.fizz.business.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.fizz.business.domain.ProStoppageType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ProStoppageTypeService extends IService<ProStoppageType> {
|
||||
|
||||
List<ProStoppageType> listAll();
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.fizz.business.domain.msg.ExitCutMessage;
|
||||
import com.fizz.business.dto.ExitCoilInfoDTO;
|
||||
import com.fizz.business.dto.MatmapDTO;
|
||||
import com.fizz.business.form.L1OperateMatForm;
|
||||
import com.fizz.business.service.LogDataService;
|
||||
import com.fizz.business.service.OpcMessageHandler;
|
||||
import com.fizz.business.service.PdoExCoilService;
|
||||
import com.fizz.business.service.TrackService;
|
||||
@@ -32,13 +33,15 @@ public class ExitCutHandler implements OpcMessageHandler<ExitCutMessage> {
|
||||
private final TrackService trackService;
|
||||
@Resource
|
||||
private OpcReceiverHandler opcReceiverHandler;
|
||||
private final LogDataService logDataService;
|
||||
@Override
|
||||
public void handle(ExitCutMessage message) {
|
||||
// 1. 获取卷取机 (TR) 上的物料信息
|
||||
MatmapDTO trMatmap = MatmapUtil.getMatmap(TR.getIdx());
|
||||
|
||||
if (trMatmap == null) {
|
||||
log.error("卷取机不存在");
|
||||
com.fizz.business.service.impl.BeanFactory.getBean(com.fizz.business.service.LogDataService.class)
|
||||
.logInfo("EXIT_CUT", "卷取机不存在");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -53,24 +56,17 @@ public class ExitCutHandler implements OpcMessageHandler<ExitCutMessage> {
|
||||
pdoExCoilService.saveExCoil(exitCoilInfo);
|
||||
|
||||
if (exitCoilInfo.isLastFlag()) {
|
||||
|
||||
logDataService.logInfo("TRACK", "当前trMatmap的值为 -> matId=" + trMatmap.getMatId() + ", planId=" + trMatmap.getPlanId());
|
||||
trackService.l1OperateMat(L1OperateMatForm.builder()
|
||||
.trIdx(TR.getIdx())
|
||||
.entryMatId(trMatmap.getMatId())
|
||||
.planId(trMatmap.getPlanId())
|
||||
.entryMatId(exitCoilInfo.getEntryMatId())
|
||||
.planId(exitCoilInfo.getPlanId())
|
||||
.operation(L1OperateMatEnum.PRODUCT)
|
||||
.build());
|
||||
|
||||
// wangyu 配合二级发一个甩尾信号 01全甩一下
|
||||
EntryMovementMessage msg = new EntryMovementMessage();
|
||||
msg.setCounter(message.getCounter());
|
||||
msg.setMaterialPlaceSource(0);
|
||||
msg.setMaterialPlaceDestination(200);
|
||||
opcReceiverHandler.onMessageReceived(OpcMessageType.ENTRY_MOVEMENT,msg);
|
||||
msg.setMaterialPlaceSource(1);
|
||||
opcReceiverHandler.onMessageReceived(OpcMessageType.ENTRY_MOVEMENT,msg);
|
||||
|
||||
logDataService.logInfo("EXIT_CUT", "成功处理 EXIT_CUT 消息,已保存成品卷 -> exitMatId=" + exitCoilInfo.getExitMatId() + ", planId=" + exitCoilInfo.getPlanId() + ", entryMatId=" + trMatmap.getMatId());
|
||||
}
|
||||
|
||||
log.info("成功处理 EXIT_CUT 消息,已保存成品卷: " + exitCoilInfo.getExitMatId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,20 +7,26 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.fizz.business.domain.CrmPdiPlan;
|
||||
import com.fizz.business.form.ChangePlanStatusForm;
|
||||
import com.fizz.business.constants.enums.PlanStatusEnum;
|
||||
import com.fizz.business.form.PlanQueryForm;
|
||||
import com.fizz.business.mapper.CrmPdiPlanMapper;
|
||||
import com.fizz.business.service.CrmPdiPlanService;
|
||||
import com.fizz.business.service.LogDataService;
|
||||
import com.fizz.business.vo.CrmPdiPlanVO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class CrmPdiPlanServiceImpl extends ServiceImpl<CrmPdiPlanMapper, CrmPdiPlan> implements CrmPdiPlanService {
|
||||
|
||||
@javax.annotation.Resource
|
||||
private LogDataService logDataService;
|
||||
|
||||
|
||||
/**
|
||||
* 根据卷ID和操作员ID查询单个记录
|
||||
@@ -150,23 +156,61 @@ public class CrmPdiPlanServiceImpl extends ServiceImpl<CrmPdiPlanMapper, CrmPdiP
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeStatus(ChangePlanStatusForm build) {
|
||||
public boolean changeStatus(ChangePlanStatusForm build) {
|
||||
|
||||
if (build == null) {
|
||||
if (logDataService != null) {
|
||||
logDataService.logInfo("PLAN", "changeStatus 参数为空");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QueryWrapper<CrmPdiPlan> wrapper = new QueryWrapper<>();
|
||||
|
||||
if (StrUtil.isBlank(build.getMatId())) {
|
||||
|
||||
logDataService.logInfo("PLAN", "changeStatus matId为空, planId=" + build.getId() + ", operation=" + build.getOperation());
|
||||
return false;
|
||||
}
|
||||
|
||||
wrapper.eq("coilid", build.getMatId());
|
||||
wrapper.eq("planid", build.getId());
|
||||
|
||||
// planId 非空时:matId + planId 精确匹配
|
||||
// planId 为空时:仅用 matId 匹配(coilid 唯一)
|
||||
if (StrUtil.isNotBlank(build.getId())) {
|
||||
wrapper.eq("planid", build.getId());
|
||||
}
|
||||
|
||||
CrmPdiPlan pdiPlan = baseMapper.selectOne(wrapper);
|
||||
|
||||
if (pdiPlan == null) {
|
||||
log.error("未找到ID为{}的计划记录", build.getId());
|
||||
return;
|
||||
logDataService.logInfo("PLAN", "未找到计划记录, matId=" + build.getMatId() + ", planId=" + build.getId() + ", operation=" + build.getOperation());
|
||||
return false;
|
||||
}
|
||||
|
||||
pdiPlan.setStatus(build.getOperation());
|
||||
String oldStatus = pdiPlan.getStatus();
|
||||
String newStatus = build.getOperation();
|
||||
|
||||
baseMapper.updateById(pdiPlan);
|
||||
log.info("计划状态更新成功,ID: {}, 新状态: {}", build.getId(), build.getOperation());
|
||||
// 状态机保护:禁止已完成(PRODUCT)的计划回退到生产中(PRODUCING)
|
||||
if (PlanStatusEnum.PRODUCT.name().equals(oldStatus) && PlanStatusEnum.PRODUCING.name().equals(newStatus)) {
|
||||
logDataService.logWarn("PLAN", "拦截计划状态回退: matId=" + build.getMatId() + ", planId=" + build.getId() + ", " + oldStatus + " -> " + newStatus);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 幂等:同状态重复更新直接放行(避免重复写库导致的误判)
|
||||
if (Objects.equals(oldStatus, newStatus)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
pdiPlan.setStatus(newStatus);
|
||||
|
||||
int rows = baseMapper.updateById(pdiPlan);
|
||||
if (rows <= 0) {
|
||||
logDataService.logInfo("PLAN", "计划状态更新失败, matId=" + build.getMatId() + ", planId=" + build.getId() + ", operation=" + newStatus);
|
||||
return false;
|
||||
}
|
||||
logDataService.logInfo("PLAN", "计划状态更新成功, matId=" + build.getMatId() + ", planId=" + build.getId() + ", {} -> {}", oldStatus, newStatus);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -77,9 +77,6 @@ public class LogDataServiceImpl extends ServiceImpl<LogDataMapper, LogData> impl
|
||||
@Override
|
||||
public void logInfo(String module, String content, Object... args) {
|
||||
try {
|
||||
if (args.length > 0) {
|
||||
content = formatMessage(content, args);
|
||||
}
|
||||
saveLogData("INFORMATION", module, content);
|
||||
} catch (Exception e) {
|
||||
log.error("没存进去,没事,{}",e);
|
||||
@@ -88,9 +85,6 @@ public class LogDataServiceImpl extends ServiceImpl<LogDataMapper, LogData> impl
|
||||
|
||||
@Override
|
||||
public void logWarn(String module, String content, Object... args) {
|
||||
if (args.length > 0) {
|
||||
content = formatMessage(content, args);
|
||||
}
|
||||
saveLogData("WARN", module, content);
|
||||
}
|
||||
|
||||
@@ -105,34 +99,4 @@ public class LogDataServiceImpl extends ServiceImpl<LogDataMapper, LogData> impl
|
||||
save(logData);
|
||||
}
|
||||
|
||||
private String formatMessage(String pattern, Object[] arguments) {
|
||||
if (pattern == null) {
|
||||
return null;
|
||||
}
|
||||
if (arguments == null || arguments.length == 0) {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int argIndex = 0;
|
||||
int i = 0;
|
||||
|
||||
while (i < pattern.length()) {
|
||||
char c = pattern.charAt(i);
|
||||
if (c == '{' && i + 1 < pattern.length() && pattern.charAt(i + 1) == '}') {
|
||||
if (argIndex < arguments.length) {
|
||||
sb.append(String.valueOf(arguments[argIndex++]));
|
||||
} else {
|
||||
sb.append("{}");
|
||||
}
|
||||
i += 2;
|
||||
} else {
|
||||
sb.append(c);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.fizz.business.service.impl;
|
||||
import com.fizz.business.comm.OPC.OpcMessageSend;
|
||||
import com.fizz.business.form.OpcBatchWriteDataForm;
|
||||
import com.fizz.business.form.OpcWriteDataForm;
|
||||
import com.fizz.business.service.LogDataService;
|
||||
import com.fizz.business.service.OpcDataService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -22,6 +23,7 @@ import java.util.stream.Collectors;
|
||||
public class OpcDataServiceImpl implements OpcDataService {
|
||||
|
||||
private final OpcMessageSend opcMessageSend;
|
||||
private final LogDataService logDataService;
|
||||
|
||||
@Override
|
||||
public boolean writeData(OpcWriteDataForm form) {
|
||||
@@ -36,13 +38,44 @@ public class OpcDataServiceImpl implements OpcDataService {
|
||||
@Override
|
||||
public boolean batchWriteData(OpcBatchWriteDataForm form) {
|
||||
try {
|
||||
|
||||
int rawSize = form.getDataList().size();
|
||||
|
||||
int nullItemCount = 0;
|
||||
int nullFieldNameCount = 0;
|
||||
int nullValueCount = 0;
|
||||
StringBuilder nullValueFields = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < form.getDataList().size(); i++) {
|
||||
OpcWriteDataForm d = form.getDataList().get(i);
|
||||
if (d == null) {
|
||||
nullItemCount++;
|
||||
continue;
|
||||
}
|
||||
if (d.getFieldName() == null) {
|
||||
nullFieldNameCount++;
|
||||
continue;
|
||||
}
|
||||
if (d.getValue() == null) {
|
||||
nullValueCount++;
|
||||
if (nullValueFields.length() < 1500) {
|
||||
if (nullValueFields.length() > 0) {
|
||||
nullValueFields.append(",");
|
||||
}
|
||||
nullValueFields.append(d.getFieldName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> fieldDataMap = form.getDataList().stream()
|
||||
.filter(d -> d != null && d.getFieldName() != null)
|
||||
.collect(Collectors.toMap(
|
||||
OpcWriteDataForm::getFieldName,
|
||||
OpcWriteDataForm::getValue,
|
||||
(v1, v2) -> v2 // 如果有重复的 key,保留后面的值
|
||||
));
|
||||
return opcMessageSend.batchWriteDataByFieldName(fieldDataMap);
|
||||
|
||||
return opcMessageSend.batchWriteData(fieldDataMap);
|
||||
} catch (Exception e) {
|
||||
log.error("批量写入 OPC 数据异常", e);
|
||||
return false;
|
||||
|
||||
@@ -45,7 +45,7 @@ public class ProStoppageServiceImpl extends ServiceImpl<ProStoppageMapper, ProSt
|
||||
|
||||
@Override
|
||||
public boolean deleteProStoppage(Long stopid) {
|
||||
return this.deleteProStoppage(stopid);
|
||||
return this.removeById(stopid);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.fizz.business.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.fizz.business.domain.ProStoppageType;
|
||||
import com.fizz.business.mapper.ProStoppageTypeMapper;
|
||||
import com.fizz.business.service.ProStoppageTypeService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class ProStoppageTypeServiceImpl extends ServiceImpl<ProStoppageTypeMapper, ProStoppageType> implements ProStoppageTypeService {
|
||||
|
||||
@Override
|
||||
public List<ProStoppageType> listAll() {
|
||||
return baseMapper.selectList(null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import com.fizz.business.form.L1OperateMatForm;
|
||||
import com.fizz.business.form.WebOperateMatForm;
|
||||
import com.fizz.business.service.CrmPdiPlanService;
|
||||
import com.fizz.business.comm.OPC.OpcMessageSend;
|
||||
import com.fizz.business.service.strip.SegmentTrackerService;
|
||||
import com.fizz.business.service.ProMatmapService;
|
||||
import com.fizz.business.service.TrackService;
|
||||
import com.fizz.business.service.client.RedisCacheManager;
|
||||
@@ -64,6 +65,10 @@ public class TrackServiceImpl implements TrackService {
|
||||
proMatmapService.flushMatmap();
|
||||
}
|
||||
|
||||
@Autowired
|
||||
@org.springframework.context.annotation.Lazy
|
||||
private SegmentTrackerService segmentTrackerService;
|
||||
|
||||
@Override
|
||||
public void l1OperateMat(L1OperateMatForm form) {
|
||||
|
||||
|
||||
@@ -114,9 +114,10 @@ public class OpcMessageIdsManager {
|
||||
entryLineMeasureIds.put("ns=2;s=ProcessCGL.PLCLine.EntryLineMeasure.rinseConductivity","rinseConductivity");
|
||||
entryLineMeasureIds.put("ns=2;s=ProcessCGL.PLCLine.EntryLineMeasure.rinseTemperature","rinseTemperature");
|
||||
entryLineMeasureIds.put("ns=2;s=ProcessCGL.PLCLine.EntryLineMeasure.dryingTemperature","dryingTemperature");
|
||||
|
||||
entryLineMeasureIds.put("ns=2;s=ProcessCGL.PLCLine.EntryLineMeasure.BR4or5toBR6Tension","tensionBr45Br6");
|
||||
entryLineMeasureIds.put("ns=2;s=ProcessCGL.PLCLine.EntryLineMeasure.hotAirFlow","hotAirFlow");
|
||||
entryLineMeasureIds.put("ns=2;s=ProcessCGL.PLCLine.EntryLineMeasure.hotAirPressure","hotAirPressure");
|
||||
entryLineMeasureIds.put("ns=2;s=ProcessCGL.PLCLine.EntryLineMeasure.BR4or5toBR6Tension","bR4or5toBR6Tension");
|
||||
}
|
||||
|
||||
public static void loadProcLineMeasureIds(){
|
||||
@@ -406,6 +407,34 @@ public class OpcMessageIdsManager {
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.exitLength4", "exitLength4");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.exitLength5", "exitLength5");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.exitLength6", "exitLength6");
|
||||
// 张力设定值(LepServer TagName,按 DB 地址与工艺语义对齐)
|
||||
// DB35502 段:Current/Next
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.1kjjtensionsetting", "tensionPor1Current");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.1kjjtensionsettingnext", "tensionPor1Next");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.2kjjtensionsetting", "tensionPor2Current");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.2kjjtensionsettingnext", "tensionPor2Next");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.rkhttensionsetting", "tensionEnLpCurrent");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.rkhttensionsettingnext", "tensionEnLpNext");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.qxdtensionsetting", "tensionCleaningCurrent");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.qxdtensionsettingnext", "tensionCleaningNext");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.thltensionsetting", "tensionFuranceCurrent");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.thltensionsettingnext", "tensionFuranceNext");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.dhlqdtensionsetting", "tensionGalvanizingCoolCurrent");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.dhlqdtensionsettingnext", "tensionGalvanizingCoolNext");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.gzjrktensionsetting", "tensionTmEntryCurrent");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.gzjrktensionsettingnext", "tensionTmEntryNext");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.gzjcktensionsetting", "tensionTmExitCurrent");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.gzjcktensionsettingnext", "tensionTmExitNext");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.ljjtensionsetting", "tensionTlCurrent");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.ljjtensionsettingnext", "tensionTlNext");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.dhdtensionsetting", "tensionCoatingCurrent");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.dhdtensionsettingnext", "tensionCoatingNext");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.ckhttensionsetting", "tensionExLpCurrent");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.ckhttensionsettingnext", "tensionExLpNext");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.sjjtensionsetting", "tensionTrCurrent");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.sjjtensionsettingnext", "tensionTrNext");
|
||||
|
||||
// DB35501 段:原有张力字段(保持兼容)
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.tensionPorBR1", "tensionPorBR1");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.tensionBR1BR2", "tensionBR1BR2");
|
||||
pdiSetupIds.put("ns=2;s=ProcessCGL.PLCLine.L2Setup.tensionBR2BR3", "tensionBR2BR3");
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.fizz.business.service.strip;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.fizz.business.constants.enums.DeviceEnum;
|
||||
import com.fizz.business.constants.enums.L1OperateMatEnum;
|
||||
import com.fizz.business.domain.PdiSetups;
|
||||
import com.fizz.business.domain.msg.AppMeasureCoatMessage;
|
||||
import com.fizz.business.domain.msg.AppMeasureEntryMessage;
|
||||
import com.fizz.business.domain.msg.AppMeasureExitMessage;
|
||||
@@ -10,18 +11,27 @@ import com.fizz.business.domain.msg.AppMeasureFurnaceMessage;
|
||||
import com.fizz.business.dto.MatmapDTO;
|
||||
import com.fizz.business.dto.SegValue;
|
||||
import com.fizz.business.dto.SegmentDTO;
|
||||
import com.fizz.business.domain.s7.DB35501Data;
|
||||
import com.fizz.business.domain.s7.DB35502Data;
|
||||
import com.fizz.business.form.L1OperateMatForm;
|
||||
import com.fizz.business.service.CrmPdiPlanService;
|
||||
import com.fizz.business.service.IPdiSetupService;
|
||||
import com.fizz.business.service.LogDataService;
|
||||
import com.fizz.business.service.ProMatmapService;
|
||||
import com.fizz.business.service.TrackService;
|
||||
import com.fizz.business.service.impl.SegmentService;
|
||||
import com.fizz.business.utils.MatmapUtil;
|
||||
import com.fizz.business.utils.WebSocketUtil;
|
||||
import com.fizz.business.vo.CrmPdiPlanVO;
|
||||
import com.github.xingshuangs.iot.protocol.s7.enums.EPlcType;
|
||||
import com.github.xingshuangs.iot.protocol.s7.service.S7PLC;
|
||||
import com.github.xingshuangs.iot.protocol.s7.serializer.S7Serializer;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Field;
|
||||
import java.math.BigDecimal;
|
||||
@@ -42,6 +52,40 @@ public class SegmentTrackerService {
|
||||
private final LogDataService logDataService; // 注入新创建的段服务
|
||||
private final ProMatmapService proMatmapService; // 注入新创建的段服务
|
||||
|
||||
private final CrmPdiPlanService crmPdiPlanService;
|
||||
private final IPdiSetupService pdiSetupService;
|
||||
|
||||
private static final String PLC_IP = "192.168.0.223";
|
||||
private static final int COIL_ID_MAX_LEN = 20;
|
||||
|
||||
private S7PLC s7PLC;
|
||||
private S7Serializer s7Serializer;
|
||||
|
||||
@PostConstruct
|
||||
public void initS7() {
|
||||
// PLC机型是1500,IP 192.168.0.223,rack/slot 默认
|
||||
this.s7PLC = new S7PLC(EPlcType.S1500, PLC_IP);
|
||||
this.s7Serializer = S7Serializer.newInstance(s7PLC);
|
||||
}
|
||||
|
||||
private String trimToLen(String s, int maxLen) {
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
return s.length() <= maxLen ? s : s.substring(0, maxLen);
|
||||
}
|
||||
|
||||
private float toFloat(BigDecimal v) {
|
||||
return v == null ? 0.0f : v.floatValue();
|
||||
}
|
||||
|
||||
private byte toByte(String s) {
|
||||
if (s == null || s.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
return (byte) s.charAt(0);
|
||||
}
|
||||
|
||||
private static final long intervalTime = 10000; // 每 10 秒写一次
|
||||
private int traceCount = 0;
|
||||
private boolean firstMeasure = true;
|
||||
@@ -79,7 +123,7 @@ public class SegmentTrackerService {
|
||||
try {
|
||||
trackCoilHeadPosition(coilId, entryLengthAtWelder, entry, exit);
|
||||
} catch (Exception e) {
|
||||
logDataService.logInfo("ERROR","coidId="+coilId+", e="+ e);
|
||||
logDataService.logInfo("TRACK", "trackCoilHeadPosition异常, coilId=" + coilId + ", err=" + String.valueOf(e));
|
||||
}
|
||||
|
||||
Long lastTime = lastLogTimeMap.get(coilId);
|
||||
@@ -98,13 +142,14 @@ public class SegmentTrackerService {
|
||||
firstMeasure = false;
|
||||
listSegment.clear();
|
||||
coilReachedDevices.remove(coilId);
|
||||
coilReachedDevices.remove(coilId + "#POR1");
|
||||
coilReachedDevices.remove(coilId + "#POR2");
|
||||
|
||||
long now1 = System.currentTimeMillis();
|
||||
Long lastTime1 = lastNewCoilLogTimeMap.get(coilId);
|
||||
if (lastTime1 == null || now1 - lastTime1 > intervalTime) {
|
||||
lastNewCoilLogTimeMap.put(coilId, now1);
|
||||
log.info("【WELDER】检测到新钢卷或初始化 -> CoilId: {}", coilId);
|
||||
logDataService.logInfo("WELDER", "Detected new coil or initialized -> CoilId: " + coilId);
|
||||
logDataService.logInfo("WELDER", "检测到新钢卷或初始化, CoilId=" + coilId);
|
||||
}
|
||||
} else {
|
||||
weldDev = entryLengthAtWelder.subtract(weldLength);
|
||||
@@ -127,8 +172,7 @@ public class SegmentTrackerService {
|
||||
|
||||
|
||||
// 5. 完成日志
|
||||
log.info("【TRACK-END】CoilId: {}, 当前长度: {}, 已生成段数: {}", coilId, entryLengthAtWelder, coilSegNum);
|
||||
logDataService.logInfo("TRACK", "Process completed -> CoilId: " + coilId + ", CurrentLength: " + entryLengthAtWelder + ", SegmentCount: " + coilSegNum);
|
||||
logDataService.logInfo("TRACK", "处理完成, CoilId=" + coilId + ", 当前长度=" + entryLengthAtWelder + ", 已生成段数=" + coilSegNum);
|
||||
}
|
||||
|
||||
|
||||
@@ -144,7 +188,7 @@ public class SegmentTrackerService {
|
||||
BigDecimal weldDev) {
|
||||
if (listSegment.isEmpty()) {
|
||||
// === 【处理开始日志】===
|
||||
log.warn("【TRACK-TREAT】,listSegment为空,直接返回");
|
||||
logDataService.logWarn("TRACK", "treatSeg: listSegment为空,直接返回, coilSegNum=" + coilSegNum);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -152,9 +196,10 @@ public class SegmentTrackerService {
|
||||
BigDecimal celLength = entry != null ? entry.getCelLength() : BigDecimal.ZERO;
|
||||
BigDecimal cxlLength = exit != null ? exit.getCxlLength() : BigDecimal.ZERO;
|
||||
|
||||
// payOffReelNumber=1/2 代表当前跟踪的是哪一路开卷机入口。
|
||||
// 这里做保护,避免 entry 为空或值异常导致误写 matmap。
|
||||
// === 【处理开始日志】===
|
||||
log.info("【TRACK-TREAT】开始处理段数据,共 {} 段,weldDev={},celLength = {},cxlLength = {}。 ", listSegment.size(), weldDev, celLength, cxlLength);
|
||||
logDataService.logInfo("TRACK", "Start processing segments: count=" + listSegment.size() + ", weldDev=" + weldDev);
|
||||
logDataService.logInfo("TRACK", "开始处理段数据, count=" + listSegment.size() + ", weldDev=" + weldDev + ", celLength=" + celLength + ", cxlLength=" + cxlLength);
|
||||
|
||||
Iterator<SegmentDTO> iterator = listSegment.descendingIterator();
|
||||
while (iterator.hasNext()) {
|
||||
@@ -180,14 +225,12 @@ public class SegmentTrackerService {
|
||||
if (segment.getHeadPos().compareTo(BigDecimal.valueOf(currentDevicePos)) > 0 &&
|
||||
segment.getTailPos().compareTo(BigDecimal.valueOf(currentDevicePos)) < 0) {
|
||||
|
||||
log.info("【TRACK-TREAT】段 {} 进入设备区域 [{}],当前设备长度:{}", segment.getSegNo(), device.name(), currentDevicePos);
|
||||
logDataService.logInfo("TRACK",
|
||||
"Segment " + segment.getSegNo() + " entered device area [" + device.name() + "], devicePos=" + currentDevicePos);
|
||||
"段进入设备区域, segNo={}, device={}, devicePos={}", segment.getSegNo(), device.name(), currentDevicePos);
|
||||
double currentSpeed = getSpeedForDevice(device, entry, coat, exit);
|
||||
if (currentSpeed > LOWSPEEDLIMIT) {
|
||||
log.info("【TRACK-TREAT】段 {} 速度大于基准速度, 进入设备区域 [{}],当前速度:{}", segment.getSegNo(), device.name(), currentSpeed);
|
||||
logDataService.logInfo("TRACK",
|
||||
"Segment " + segment.getSegNo() + " entered device area [" + device.name() + "], speed=" + currentSpeed);
|
||||
"段速度满足条件并进入设备区域, segNo={}, device={}, speed={}", segment.getSegNo(), device.name(), currentSpeed);
|
||||
for (String fieldName : device.getParamFields()) {
|
||||
Object message = getMessageForDevice(device, entry, furnace, coat, exit);
|
||||
if (message != null) {
|
||||
@@ -202,10 +245,9 @@ public class SegmentTrackerService {
|
||||
|
||||
double exitPlantPos = stripPositionService.calculate(DeviceEnum.TR, celLength, cxlLength);
|
||||
if (segment.getTailPos().compareTo(BigDecimal.valueOf(exitPlantPos)) >= 0) {
|
||||
log.info("【TRACK-END】钢卷 {} 的段号 {} 已离开产线,开始持久化数据{}。",
|
||||
segment.getEnCoilID(), segment.getSegNo(), JSONUtil.toJsonStr(segment.getTotalValues()));
|
||||
logDataService.logInfo("SEGMENT",
|
||||
"Coil " + segment.getEnCoilID() + " segment " + segment.getSegNo() + " left the line, start persisting data.");
|
||||
"段离开产线并开始持久化, coilId={}, segNo={}, values={}",
|
||||
segment.getEnCoilID(), segment.getSegNo(), JSONUtil.toJsonStr(segment.getTotalValues()));
|
||||
segmentService.saveTotalSegment(segment); // 调用服务进行持久化
|
||||
iterator.remove();
|
||||
}
|
||||
@@ -364,14 +406,20 @@ public class SegmentTrackerService {
|
||||
public void trackCoilHeadPosition(String coilId, BigDecimal headPos,
|
||||
AppMeasureEntryMessage entry, AppMeasureExitMessage exit) {
|
||||
|
||||
log.warn(">>> trackCoilHeadPosition 当前线程:{}", Thread.currentThread().getName());
|
||||
logDataService.logInfo("MATMAP-TRACK", "trackCoilHeadPosition 当前线程=" + Thread.currentThread().getName());
|
||||
|
||||
if (LogRateLimiter.shouldLog("TRACK:" + coilId, 5000)) {
|
||||
log.info("焊缝位置匹配逻辑,当前焊缝长度{},", headPos);
|
||||
logDataService.logInfo("MATMAP-TRACK", "CoilId=" + coilId + "Weld position matching logic, current weld length ="+headPos);
|
||||
logDataService.logInfo("MATMAP-TRACK", "焊缝位置匹配逻辑, coilId=" + coilId + ", weldLen=" + headPos);
|
||||
}
|
||||
|
||||
Set<DeviceEnum> prevReached = coilReachedDevices.computeIfAbsent(coilId,
|
||||
Integer payOffReelNumber = entry != null ? entry.getPayOffReelNumber() : null;
|
||||
if (payOffReelNumber == null || payOffReelNumber < 1) {
|
||||
logDataService.logWarn("MATMAP-TRACK", "trackCoilHeadPosition: invalid payOffReelNumber=" + payOffReelNumber + ", coilId=" + coilId);
|
||||
return;
|
||||
}
|
||||
|
||||
String reachKey = coilId + "#POR" + payOffReelNumber;
|
||||
Set<DeviceEnum> prevReached = coilReachedDevices.computeIfAbsent(reachKey,
|
||||
k -> Collections.newSetFromMap(new ConcurrentHashMap<>()));
|
||||
|
||||
if (LogRateLimiter.shouldLog("TRACK:" + coilId, 5000)) {
|
||||
@@ -383,19 +431,50 @@ public class SegmentTrackerService {
|
||||
|
||||
for (DeviceEnum d : DeviceEnum.values()) {
|
||||
double dynPos = stripPositionService.calculate(d, celLength, cxlLength);
|
||||
log.info("焊缝位置匹配逻辑,当前焊缝长度{},当前计算的设备长度:{}", headPos, dynPos);
|
||||
if (LogRateLimiter.shouldLog("TRACK:DYNPOS:" + coilId, 5000)) {
|
||||
logDataService.logInfo("MATMAP-TRACK", "焊缝位置匹配, coilId=" + coilId + ", headPos=" + headPos + ", device=" + d.name() + ", dynPos=" + dynPos);
|
||||
}
|
||||
|
||||
if (headPos.compareTo(BigDecimal.valueOf(dynPos)) >= 0 && !prevReached.contains(d)) {
|
||||
boolean positionReached = headPos.compareTo(BigDecimal.valueOf(dynPos)) >= 0;
|
||||
|
||||
MatmapDTO matmap = MatmapUtil.getMatmap(entry.getPayOffReelNumber());
|
||||
MatmapUtil.setMatId(d.getIdx(), coilId,matmap.getPlanId());
|
||||
// --- 针对大辊缝时 stripLocation 更新延迟的补偿逻辑 ---
|
||||
// 只要入口段速度 > 阈值,就认为已经开始进入生产状态,可以触发 WELDER 到达
|
||||
boolean welderIsMoving = false;
|
||||
if (d == DeviceEnum.WELDER && entry != null && entry.getStripSpeed() != null) {
|
||||
if (entry.getStripSpeed().doubleValue() > LOWSPEEDLIMIT) {
|
||||
welderIsMoving = true;
|
||||
logDataService.logInfo("MATMAP-TRACK", "WELDER速度触发状态变更, coilId=" + coilId + ", speed=" + entry.getStripSpeed().doubleValue() + ", limit=" + LOWSPEEDLIMIT);
|
||||
}
|
||||
}
|
||||
|
||||
if ((positionReached || welderIsMoving) && !prevReached.contains(d)) {
|
||||
|
||||
MatmapDTO matmap = MatmapUtil.getMatmap(payOffReelNumber - 1);
|
||||
|
||||
// 关键点:POR1/POR2 是两路入口,各自有独立的 matmap 槽位。
|
||||
// 设备到达时只更新该入口对应的设备槽位,避免把另一入口(另一开卷机/活套)覆盖。
|
||||
int targetIdx = d.getIdx();
|
||||
if (payOffReelNumber == 1) {
|
||||
// 仅在开卷机位置做 1/2 路隔离。
|
||||
// 入口/出口活套已合并为单套,ENL1/2/3、CXL1/2 为同一活套内不同测点,不再按入口分路。
|
||||
if (d == DeviceEnum.POR2) {
|
||||
continue;
|
||||
}
|
||||
} else if (payOffReelNumber == 2) {
|
||||
if (d == DeviceEnum.POR1) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
MatmapUtil.setMatId(targetIdx, coilId, matmap.getPlanId());
|
||||
|
||||
if (d == DeviceEnum.WELDER) {
|
||||
logDataService.logInfo("MATMAP-TRACK", "Coil reached welder, update plan status. coil=" + coilId + ", headPos=" + headPos);
|
||||
|
||||
trackService.l1OperateMat(L1OperateMatForm.builder()
|
||||
.entryMatId(coilId)
|
||||
.planId(matmap.getPlanId())
|
||||
.porIdx(entry.getPayOffReelNumber())
|
||||
.porIdx(entry.getPayOffReelNumber() - 1)
|
||||
.operation(L1OperateMatEnum.PRODUCING)
|
||||
.build());
|
||||
} else {
|
||||
@@ -410,6 +489,65 @@ public class SegmentTrackerService {
|
||||
}
|
||||
|
||||
|
||||
private PdiSetups loadPdiSetup(String coilId, String planId) {
|
||||
if (planId == null) {
|
||||
return null;
|
||||
}
|
||||
com.fizz.business.domain.PdiSetups query = new com.fizz.business.domain.PdiSetups();
|
||||
query.setCoilid(coilId);
|
||||
query.setPlanid(planId);
|
||||
List<com.fizz.business.domain.PdiSetups> setups = pdiSetupService.selectPdiSetupList(query);
|
||||
return (setups != null && !setups.isEmpty()) ? setups.get(0) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* NEW/READY -> ONLINE:入口卷参数 + 全线张力“下一设定值”(Next) 一次性下发 (通过 S7 协议直连 PLC)
|
||||
*/
|
||||
public void sendAllPdiOnOnline(String coilId, Integer porIdx) {
|
||||
try {
|
||||
CrmPdiPlanVO plan = crmPdiPlanService.getByCoilIdAndOperId(coilId);
|
||||
PdiSetups setup = loadPdiSetup(coilId, plan.getPlanid());
|
||||
|
||||
// 1. 组装 DB35501 数据 (入口卷参数)
|
||||
DB35501Data d35501 = new DB35501Data();
|
||||
d35501.setCoilId(trimToLen(coilId, COIL_ID_MAX_LEN));
|
||||
d35501.setEntryCoilWeight(toFloat(plan.getEntryWeight()));
|
||||
d35501.setEntryCoilLength(toFloat(plan.getEntryLength()));
|
||||
d35501.setEntryCoilWidth(toFloat(plan.getEntryWidth()));
|
||||
d35501.setEntryCoilThick(toFloat(plan.getEntryThick()));
|
||||
d35501.setEntryCoilInnerDia(toFloat(plan.getEntryInnerDiameter()));
|
||||
d35501.setEntryCoilOuterDia(toFloat(plan.getEntryOuterDiameter()));
|
||||
d35501.setAlloyCode(toByte(plan.getSteelGrade()));
|
||||
|
||||
// 2. 组装 DB35502 数据 (全线张力 Next)
|
||||
DB35502Data d35502 = new DB35502Data();
|
||||
if (setup != null) {
|
||||
if (porIdx != null && porIdx == 0) {
|
||||
d35502.setTensionPor1Next(toFloat(setup.getPorTension()));
|
||||
} else if (porIdx != null && porIdx == 1) {
|
||||
d35502.setTensionPor2Next(toFloat(setup.getPorTension()));
|
||||
}
|
||||
d35502.setTensionEnLpNext(toFloat(setup.getCelTension()));
|
||||
d35502.setTensionCleaningNext(toFloat(setup.getCleanTension()));
|
||||
d35502.setTensionGalvanizingCoolNext(toFloat(setup.getPassivationTension()));
|
||||
d35502.setTensionExLpNext(toFloat(setup.getCxlTension()));
|
||||
d35502.setTensionTlNext(toFloat(setup.getLevelerEntryTension()));
|
||||
d35502.setTensionTmExitNext(toFloat(setup.getStraightenerExitTension()));
|
||||
d35502.setTensionFuranceNext(toFloat(setup.getFurTension()));
|
||||
d35502.setTensionTrNext(toFloat(setup.getTrTension()));
|
||||
}
|
||||
|
||||
// 3. 执行 S7 序列化写入
|
||||
s7Serializer.write(d35501);
|
||||
s7Serializer.write(d35502);
|
||||
|
||||
logDataService.logInfo("MATMAP-TRACK", "ONLINE S7下发完成(入口参数+张力Next), coilId=" + coilId + ", PLC=" + PLC_IP);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("S7下发异常: {}", e.getMessage(), e);
|
||||
logDataService.logInfo("MATMAP-TRACK", "ONLINE S7下发失败, coilId=" + coilId + ", err=" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.fizz.business.constants.CommonConstants;
|
||||
import com.fizz.business.constants.enums.WsTypeEnum;
|
||||
import com.fizz.business.domain.msg.AppMeasureEntryMessage;
|
||||
import com.fizz.business.domain.msg.AppMeasureMessage;
|
||||
import com.fizz.business.dto.CoilPositionDTO;
|
||||
import com.fizz.business.dto.DeviceChartDataDTO;
|
||||
@@ -46,11 +45,13 @@ public class WebSocketUtil {
|
||||
Map<String, WebSocketSession> clients = trackWsHandler.getClients().getOrDefault(type.name(), Maps.newConcurrentMap());
|
||||
TextMessage message = new TextMessage(text);
|
||||
clients.values().forEach(s -> {
|
||||
try {
|
||||
s.sendMessage(message);
|
||||
synchronized (s) {
|
||||
try {
|
||||
s.sendMessage(message);
|
||||
// log.info("[websocket]向客户端[{}]推送消息:{}", type + "-" + s.getId(), text);
|
||||
} catch (IOException e) {
|
||||
log.error("[websocket]向客户端[{}]推送消息异常:{}", type + "-" + s.getId(), text);
|
||||
} catch (IOException e) {
|
||||
log.error("[websocket]向客户端[{}]推送消息异常:{}", type + "-" + s.getId(), text);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user