package com.billion.main.plc.sub;
|
|
|
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.util.ObjUtil;
|
import cn.hutool.core.util.StrUtil;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.billion.main.da.domain.DaCollectionParamConf;
|
import com.billion.main.da.domain.DaParamCollection;
|
import com.billion.main.da.domain.DaStationCollection;
|
import com.billion.main.da.domain.DaTightenCollection;
|
import com.billion.main.da.service.IDaCollectionParamConfService;
|
import com.billion.main.da.service.IDaParamCollectionService;
|
import com.billion.main.da.service.IDaStationCollectionService;
|
import com.billion.main.da.service.IDaTightenCollectionService;
|
import com.billion.main.plc.constant.Constants;
|
import com.billion.main.sc.domain.ScCollectionParamConf;
|
import com.billion.main.sc.service.IScCollectionParamConfService;
|
import com.billion.system.domain.SysNotice;
|
import com.billion.system.service.impl.SysNoticeServiceImpl;
|
import com.kangaroohy.milo.model.ReadWriteEntity;
|
import com.kangaroohy.milo.runner.subscription.SubscriptionCallback;
|
import com.kangaroohy.milo.service.MiloService;
|
import lombok.extern.slf4j.Slf4j;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.stereotype.Component;
|
|
import java.text.ParseException;
|
import java.text.SimpleDateFormat;
|
import java.util.*;
|
import java.util.concurrent.CompletableFuture;
|
import java.util.stream.Collectors;
|
import java.lang.reflect.Field;
|
|
|
@Slf4j
|
@Component
|
public class OPCUaSubscription implements SubscriptionCallback {
|
private static final Logger logger = LoggerFactory.getLogger("sys-user");
|
|
public static MiloService miloService;
|
public static IScCollectionParamConfService collectionParamConfService;
|
public static IDaParamCollectionService paramCollectionService;
|
public static IDaStationCollectionService stationCollectionService;
|
public static IDaCollectionParamConfService daCollectionParamConfService;
|
public static IDaTightenCollectionService daTightenCollectionService;
|
public static SysNoticeServiceImpl sysNoticeService;
|
|
public OPCUaSubscription(MiloService miloService, IScCollectionParamConfService collectionParamConfService
|
,IDaParamCollectionService paramCollectionService,IDaStationCollectionService stationCollectionService,SysNoticeServiceImpl sysNoticeService
|
,IDaCollectionParamConfService daCollectionParamConfService,IDaTightenCollectionService daTightenCollectionService) {
|
OPCUaSubscription.miloService = miloService;
|
OPCUaSubscription.collectionParamConfService = collectionParamConfService;
|
OPCUaSubscription.paramCollectionService = paramCollectionService;
|
OPCUaSubscription.stationCollectionService = stationCollectionService;
|
OPCUaSubscription.sysNoticeService = sysNoticeService;
|
OPCUaSubscription.daCollectionParamConfService = daCollectionParamConfService;
|
OPCUaSubscription.daTightenCollectionService = daTightenCollectionService;
|
}
|
|
@Override
|
public void onSubscribe(String identifier, Object value) {
|
log.info("地址:"+identifier+"值:"+value);
|
try {
|
if(ObjUtil.isNotNull(value) && !Constants.ZERO.equals(value.toString())) {
|
String[] nodes = identifier.split("[.]");
|
String thoroughfare = nodes[0];//通道
|
String device = nodes[1];//设备
|
String tab = nodes[2];//标记
|
String valueString = value.toString();//地址值
|
|
CompletableFuture<Void> cp1 = CompletableFuture.runAsync(() -> {
|
subHandle(thoroughfare,device,tab,valueString);
|
});
|
|
}
|
} catch (Exception e) {
|
log.error(e.getMessage());
|
}
|
}
|
|
public void subHandle(String thoroughfare,String device,String tab,String valueString){
|
try{
|
//监听recordData
|
if(tab.equals(Constants.RECORD_DATA)){
|
if(valueString.equals(Constants.ONE)){
|
// Object StationStatusObject = miloService.readFromOpcUa(thoroughfare + "." + device + ".StationStatus").getValue();
|
// if (ObjUtil.isNotNull(StationStatusObject)){
|
// String StationStatus = StationStatusObject.toString();
|
// if (!Constants.ONE.equals(StationStatus)){
|
// miloService.writeToOpcShort(ReadWriteEntity.builder().identifier(thoroughfare + "." + device + ".RecordDataDone").value(Constants.INTEGER_ONE_TWO).build());
|
// } else {
|
// miloService.writeToOpcShort(ReadWriteEntity.builder().identifier(thoroughfare + "." + device + ".RecordDataDone").value(Constants.INTEGER_ONE_ONE).build());
|
// }
|
// }
|
|
miloService.writeToOpcShort(ReadWriteEntity.builder().identifier(thoroughfare + "." + device + ".RecordDataDone").value(Constants.INTEGER_ONE_ONE).build());
|
|
} else if(valueString.equals(Constants.TWO)){
|
//如果是2做出站处理
|
Object SNCodeObject = miloService.readFromOpcUa(thoroughfare + "." + device + ".SNCode").getValue();
|
if (ObjUtil.isNotNull(SNCodeObject)){
|
String SnCode = SNCodeObject.toString();
|
if (StrUtil.isNotBlank(SnCode)){
|
savePassingStation(thoroughfare,device,SnCode);
|
saveParamCollection(device, SnCode, "stationStatus");
|
}
|
}
|
Integer result = Constants.INTEGER_TWO_ONE;
|
miloService.writeToOpcShort(ReadWriteEntity.builder().identifier(thoroughfare + "." + device + ".RecordDataDone").value(result).build());
|
}
|
} else if (tab.startsWith("OP")){
|
//处理设备报警
|
if (Constants.FIVE.equals(valueString)){
|
//重置
|
List<SysNotice> list = sysNoticeService.list(new LambdaQueryWrapper<SysNotice>()
|
.eq(SysNotice::getNoticeTitle, tab)
|
.eq(SysNotice::getStatus, Constants.ONE)
|
.eq(SysNotice::getNoticeType,valueString));
|
if (CollUtil.isNotEmpty(list)){
|
list.forEach(x ->{
|
x.setStatus(Constants.ZERO);
|
});
|
sysNoticeService.updateBatchById(list);
|
}
|
} else {
|
SysNotice sysNotice = new SysNotice();
|
sysNotice.setNoticeTitle(tab);
|
sysNotice.setNoticeType(valueString);
|
String type = "";
|
if (Constants.ONE.equals(valueString)){
|
type = "缺料";
|
} else if (Constants.TWO.equals(valueString)){
|
type = "故障";
|
} else if (Constants.THREE.equals(valueString)){
|
type = "设备";
|
} else if (Constants.FOUR.equals(valueString)){
|
type = "急停";
|
}
|
String content = tab + "工位" +type+ "报警";
|
sysNotice.setNoticeContent(content);
|
sysNotice.setStatus(Constants.ONE);
|
sysNoticeService.insertNotice(sysNotice);
|
}
|
|
}
|
}catch (Exception e) {
|
log.error(e.getMessage());
|
}
|
}
|
|
/**
|
* 保存过站数据
|
*
|
* @param device 工位
|
* @param snCode 产品序列号
|
* @return Integer
|
* @throws Exception e
|
*/
|
private static void savePassingStation(String thoroughfare, String device, String snCode){
|
try {
|
DaStationCollection daStationCollection = new DaStationCollection();
|
daStationCollection.setSfcCode(snCode);
|
daStationCollection.setLocationCode(device);
|
daStationCollection.setInboundTime(new Date());
|
daStationCollection.setOutboundTime(new Date());
|
Object StationStatusObject = miloService.readFromOpcUa(thoroughfare + "." + device + ".StationStatus").getValue();
|
if (ObjUtil.isNotNull(StationStatusObject)){
|
String StationStatus = StationStatusObject.toString();
|
daStationCollection.setStatus(StationStatus);
|
}
|
daStationCollection.setCollectTime(new Date());
|
stationCollectionService.insertDaStationCollection(daStationCollection);
|
} catch (Exception e) {
|
throw new RuntimeException(e);
|
}
|
}
|
|
/**
|
* 保存参数数据和发送工厂MES
|
* @param device 工位
|
* @param snCode 产品SN
|
* @param stationStatus 站状态
|
* @return result
|
* @throws Exception e
|
*/
|
private static void saveParamCollection(String device, String snCode, String stationStatus) {
|
try {
|
// 查询参数配置表
|
List<DaCollectionParamConf> list = daCollectionParamConfService.list(new LambdaQueryWrapper<DaCollectionParamConf>()
|
.eq(DaCollectionParamConf::getProcessesCode, device)
|
.eq(DaCollectionParamConf::getRemarks, Constants.ONE)
|
.orderByAsc(DaCollectionParamConf::getGatherSequence)
|
);
|
|
if (CollUtil.isNotEmpty(list)) {
|
// 获取参数值
|
List<String> collect = list.stream()
|
.map(DaCollectionParamConf::getGatherAddress)
|
.map(String::trim)
|
.collect(Collectors.toList());
|
List<ReadWriteEntity> readWriteEntityList = miloService.readFromOpcUa(collect);
|
|
// 保存采集数据
|
saveCollectionData(device, snCode, list, readWriteEntityList);
|
|
// // 创建工位对象并赋值
|
// Object stationObject = createStationObject(device, list, readWriteEntityList);
|
// if (stationObject != null) {
|
// System.out.println("工位" + device + "对象创建成功:" + stationObject);
|
// // 这里可以对创建的对象进行进一步处理
|
//
|
// }
|
}
|
|
} catch (Exception e) {
|
log.error("保存数据异常", e);
|
throw new RuntimeException("保存数据异常");
|
}
|
}
|
|
/**
|
* 保存采集数据
|
*/
|
private static void saveCollectionData(String device, String snCode,
|
List<DaCollectionParamConf> list, List<ReadWriteEntity> readWriteEntityList) {
|
ArrayList<DaParamCollection> collectionList = new ArrayList<>();
|
|
if(Constants.TIGHTENCOLLECTION_LIST.contains(device)){
|
//存拧紧数据
|
try {
|
LinkedHashMap<String, Map<String, Object>> groupMap = new LinkedHashMap<>();
|
for (int i = 0; i < list.size(); i += 3) {
|
try {
|
String groupKey = String.valueOf(i/3);
|
String paramSetName = list.get(i).getParameterSetName();
|
int secondSlash = paramSetName.indexOf("/", paramSetName.indexOf("/") + 1);
|
paramSetName = secondSlash > 0 ? paramSetName.substring(0, secondSlash) : paramSetName;
|
|
Map<String, Object> paramMap = new HashMap<>();
|
|
// 获取扭矩值
|
Object torqueObj = readWriteEntityList.get(i).getValue();
|
String torqueValue = torqueObj == null ? null : torqueObj.toString();
|
if (torqueValue != null && !"0.0".equals(torqueValue)) {
|
paramMap.put("torque", Double.parseDouble(torqueValue));
|
}
|
|
// 获取角度值
|
Object angleObj = readWriteEntityList.get(i + 1).getValue();
|
String angleValue = angleObj == null ? null : angleObj.toString();
|
if (angleValue != null && !"0.0".equals(angleValue)) {
|
paramMap.put("angle", Double.parseDouble(angleValue));
|
}
|
|
// 获取状态值
|
Object statusObj = readWriteEntityList.get(i + 2).getValue();
|
String statusValue = statusObj == null ? null : statusObj.toString();
|
if (statusValue != null && !"0.0".equals(statusValue)) {
|
paramMap.put("angleStatus", statusValue);
|
paramMap.put("paramSetName", paramSetName);
|
groupMap.put(groupKey, paramMap);
|
}
|
} catch (Exception e) {
|
logger.error("{}发动机拧紧数据第{}组处理失败: {}", snCode, i/3, e.getMessage());
|
}
|
}
|
|
List<DaTightenCollection> tightenList = new ArrayList<>();
|
for (Map<String, Object> paramMap : groupMap.values()) {
|
try {
|
DaTightenCollection tighten = new DaTightenCollection();
|
tighten.setSfcCode(snCode);
|
tighten.setLocationCode(device);
|
tighten.setParamSetName((String) paramMap.get("paramSetName"));
|
tighten.setTorque(paramMap.get("torque") != null ? paramMap.get("torque").toString() : null);
|
tighten.setAngle(paramMap.get("angle") != null ? paramMap.get("angle").toString() : null);
|
tighten.setAngleStatus((String) paramMap.get("angleStatus"));
|
tighten.setCollectTime(new Date());
|
tightenList.add(tighten);
|
} catch (Exception e) {
|
logger.error("{}发动机拧紧数据对象转换失败: {}", snCode, e.getMessage());
|
}
|
}
|
if(tightenList.size()>0){
|
try {
|
daTightenCollectionService.saveBeachDaTightenCollection(tightenList);
|
logger.info("{}发动机存拧紧数据保存完成",snCode);
|
} catch (Exception e) {
|
logger.error("{}发动机拧紧数据批量保存失败: {}", snCode, e.getMessage());
|
}
|
}
|
} catch (Exception e) {
|
logger.error("{}发动机拧紧数据处理异常: {}", snCode, e.getMessage());
|
}
|
}else {
|
for (int i = 0; i < readWriteEntityList.size(); i++) {
|
DaParamCollection daParamCollection = new DaParamCollection();
|
daParamCollection.setSfcCode(snCode);
|
daParamCollection.setLocationCode(device);
|
daParamCollection.setParamCode(list.get(i).getParameterSetCode());
|
daParamCollection.setParamName(list.get(i).getParameterSetName());
|
daParamCollection.setParamValue(readWriteEntityList.get(i).getValue().toString());
|
daParamCollection.setCollectTime(new Date());
|
collectionList.add(daParamCollection);
|
}
|
paramCollectionService.insertBatch(collectionList);
|
}
|
|
}
|
|
/**
|
* 创建工位对象并赋值
|
*/
|
private static Object createStationObject(String device,
|
List<ScCollectionParamConf> list, List<ReadWriteEntity> readWriteEntityList) {
|
try {
|
// 构建完整的类名
|
String className = "com.billion.main.api.domain.Station" + device;
|
Class<?> stationClass = Class.forName(className);
|
Object stationObject = stationClass.newInstance();
|
|
// 获取所有属性
|
Field[] fields = stationClass.getDeclaredFields();
|
|
// 创建参数值Map,方便查找
|
Map<String, String> paramValueMap = new HashMap<>();
|
for (int i = 0; i < list.size(); i++) {
|
paramValueMap.put(list.get(i).getParamCode(),
|
readWriteEntityList.get(i).getValue().toString());
|
}
|
|
// 按顺序给属性赋值
|
for (Field field : fields) {
|
field.setAccessible(true);
|
String paramCode = field.getName(); // 假设属性名与参数编码一致
|
String value = paramValueMap.get(paramCode);
|
|
if (value != null) {
|
// 根据字段类型转换值
|
Object convertedValue = convertValue(value, field.getType());
|
field.set(stationObject, convertedValue);
|
}
|
}
|
|
return stationObject;
|
} catch (Exception e) {
|
log.error("创建工位对象失败:" + device, e);
|
return null;
|
}
|
}
|
|
/**
|
* 根据字段类型转换值
|
*/
|
private static Object convertValue(String value, Class<?> type) {
|
if (type == String.class) {
|
return value;
|
} else if (type == Integer.class || type == int.class) {
|
return Integer.parseInt(value);
|
} else if (type == Double.class || type == double.class) {
|
return Double.parseDouble(value);
|
} else if (type == Float.class || type == float.class) {
|
return Float.parseFloat(value);
|
} else if (type == Long.class || type == long.class) {
|
return Long.parseLong(value);
|
} else if (type == Boolean.class || type == boolean.class) {
|
return Boolean.parseBoolean(value);
|
} else if (type == Date.class) {
|
try {
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
return sdf.parse(value);
|
} catch (ParseException e) {
|
return null;
|
}
|
}
|
return value;
|
}
|
|
}
|