|
|
@ -3,25 +3,25 @@ package org.nl.acs.opc; |
|
|
|
import cn.hutool.core.date.DateUtil; |
|
|
|
import cn.hutool.core.util.ObjectUtil; |
|
|
|
import cn.hutool.core.util.StrUtil; |
|
|
|
import com.alicp.jetcache.anno.method.SpringCacheContext; |
|
|
|
import com.alibaba.fastjson.JSON; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
import org.apache.commons.collections4.bag.SynchronizedSortedBag; |
|
|
|
import org.nl.acs.AcsConfig; |
|
|
|
import org.nl.acs.instruction.service.InstructionService; |
|
|
|
import org.nl.acs.opc.service.dto.OpcServerManageDto; |
|
|
|
import org.nl.acs.udw.UnifiedDataAccessor; |
|
|
|
import org.nl.acs.udw.UnifiedDataAccessorFactory; |
|
|
|
import org.nl.acs.udw.UnifiedDataAppService; |
|
|
|
import org.nl.common.enums.LogTypeEnum; |
|
|
|
import org.nl.config.SpringContextHolder; |
|
|
|
import org.nl.system.service.lucene.dto.LuceneLogDto; |
|
|
|
import org.nl.system.service.param.ISysParamService; |
|
|
|
import org.openscada.opc.lib.da.*; |
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
|
|
|
|
import java.util.*; |
|
|
|
import java.util.regex.Pattern; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* @author 20220102CG\noblelift |
|
|
|
*/ |
|
|
|
@Slf4j |
|
|
|
@Service |
|
|
|
public class DeviceOpcProtocolRunable implements Runnable, DataCallback, ServerConnectionStateListener { |
|
|
|
List<OpcItemDto> protocols; |
|
|
|
OpcServerManageDto OpcServer; |
|
|
@ -34,9 +34,6 @@ public class DeviceOpcProtocolRunable implements Runnable, DataCallback, ServerC |
|
|
|
private int all_null; |
|
|
|
private Map<String, OpcItemDto> itemSearchCache; |
|
|
|
|
|
|
|
// @Autowired
|
|
|
|
// OpcServerService opcServerService;
|
|
|
|
|
|
|
|
|
|
|
|
public DeviceOpcProtocolRunable() { |
|
|
|
this.error_num = 0; |
|
|
@ -93,6 +90,7 @@ public class DeviceOpcProtocolRunable implements Runnable, DataCallback, ServerC |
|
|
|
|
|
|
|
|
|
|
|
private void runOld() { |
|
|
|
OpcServerService opcServerService = SpringContextHolder.getBean(OpcServerService .class); |
|
|
|
while (true) { |
|
|
|
start: |
|
|
|
try { |
|
|
@ -105,11 +103,9 @@ public class DeviceOpcProtocolRunable implements Runnable, DataCallback, ServerC |
|
|
|
server.disconnect(); |
|
|
|
log.trace("清理server..."); |
|
|
|
} |
|
|
|
OpcServerService opcServerService = SpringContextHolder.getBean(OpcServerService.class); |
|
|
|
group = opcServerService.getServer(this.getOpcServer().getOpc_code()); |
|
|
|
// this.server = OpcServerUtl.getServerWithOutException(this.OpcServer.getOpc_host(), this.OpcServer.getCls_id(), this.OpcServer.getUser(), this.OpcServer.getPassword(), this.OpcServer.getDomain());
|
|
|
|
// this.server.addStateListener(this);
|
|
|
|
// group = this.server.addGroup();
|
|
|
|
this.server = OpcServerUtl.getServerWithOutException(this.OpcServer.getOpc_host(), this.OpcServer.getCls_id(), this.OpcServer.getUser(), this.OpcServer.getPassword(), this.OpcServer.getDomain()); |
|
|
|
this.server.addStateListener(this); |
|
|
|
group = this.server.addGroup(); |
|
|
|
List<String> itemsString = new ArrayList(); |
|
|
|
Iterator var3 = this.protocols.iterator(); |
|
|
|
|
|
|
@ -199,7 +195,7 @@ public class DeviceOpcProtocolRunable implements Runnable, DataCallback, ServerC |
|
|
|
Object his = accessor_value.getValue(itemId); |
|
|
|
if (!ObjectUtl.isEquals(itemState.getQuality(), QualityTypeValue.OPC_QUALITY_GOOD) && his != null) { |
|
|
|
log.warn("opc 值不健康 item: {}, 状态: {}", itemId, itemState.getQuality()); |
|
|
|
valueAllNotNull = true; |
|
|
|
valueAllNotNull = false; |
|
|
|
} |
|
|
|
|
|
|
|
if (!UnifiedDataAppService.isEquals(value, his)) { |
|
|
@ -207,9 +203,12 @@ public class DeviceOpcProtocolRunable implements Runnable, DataCallback, ServerC |
|
|
|
if (true) { |
|
|
|
this.logItemChanged(itemId, accessor_value, value, itemDto); |
|
|
|
} |
|
|
|
if (!ObjectUtil.isEmpty(value)) { |
|
|
|
if(!ObjectUtil.isEmpty(value) || "".equals(value)){ |
|
|
|
accessor_value.setValue(itemId, value); |
|
|
|
} |
|
|
|
if(ObjectUtil.isEmpty(value) && !"".equals(value)){ |
|
|
|
accessor_value.removeValue(itemId); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -230,30 +229,30 @@ public class DeviceOpcProtocolRunable implements Runnable, DataCallback, ServerC |
|
|
|
random *= 1000; |
|
|
|
if (this.all_null < 3) { |
|
|
|
if (log.isWarnEnabled()) { |
|
|
|
log.warn("{} 所有内容都为空, all_null:{} ,暂定{}s", tag, all_null, 5000 + random); |
|
|
|
log.warn("{} 所有内容都为空, all_null:{} ,暂定{}s", tag, all_null,3); |
|
|
|
} |
|
|
|
|
|
|
|
ThreadUtl.sleep((long) (5000 + random)); |
|
|
|
ThreadUtl.sleep( 3000); |
|
|
|
break start; |
|
|
|
} else if (this.all_null < 6) { |
|
|
|
if (log.isWarnEnabled()) { |
|
|
|
log.warn(tag + "重新创建server"); |
|
|
|
log.warn("{} 所有内容都为空, all_null:{} ,暂定{}s", tag, all_null, 30000 + random); |
|
|
|
log.warn("{} 所有内容都为空, all_null:{} ,暂定{}s", tag, all_null,3); |
|
|
|
} |
|
|
|
// ThreadUtl.sleep((long) (30000 + random));
|
|
|
|
ThreadUtl.sleep((long) ((new Random()).nextInt(3) + 1) * 1000); |
|
|
|
ThreadUtl.sleep(3000); |
|
|
|
break start; |
|
|
|
} else if (this.all_null < 12) { |
|
|
|
if (log.isWarnEnabled()) { |
|
|
|
log.warn("{} 所有内容都为空, all_null:{} ,暂定{}ms", tag, all_null, '\uea60' + random); |
|
|
|
log.warn(tag + "重新创建server"); |
|
|
|
log.warn("{} 所有内容都为空, all_null:{} ,暂定{}s", tag, all_null,3); |
|
|
|
} |
|
|
|
|
|
|
|
ThreadUtl.sleep((long) ('\uea60' + random)); |
|
|
|
ThreadUtl.sleep(3000); |
|
|
|
break start; |
|
|
|
} else { |
|
|
|
if (log.isWarnEnabled()) { |
|
|
|
log.warn("{} 所有内容都为空, all_null:{} ,暂定{}ms", tag, all_null, 120000 + random); |
|
|
|
log.warn("{} 所有内容都为空, all_null:{} ,暂定{}ms", tag, all_null, 5000); |
|
|
|
} |
|
|
|
|
|
|
|
ThreadUtl.sleep((long) (120000 + random)); |
|
|
|
ThreadUtl.sleep((long) (5000)); |
|
|
|
} |
|
|
|
|
|
|
|
++this.all_null; |
|
|
@ -295,6 +294,7 @@ public class DeviceOpcProtocolRunable implements Runnable, DataCallback, ServerC |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void runNew() { |
|
|
|
Async20Access accessor = null; |
|
|
|
|
|
|
@ -392,20 +392,8 @@ public class DeviceOpcProtocolRunable implements Runnable, DataCallback, ServerC |
|
|
|
Object value = OpcUtl.getValue(item, itemState); |
|
|
|
UnifiedDataAccessor accessor_value = UnifiedDataAccessorFactory.getAccessor(OpcConfig.udw_opc_value_key); |
|
|
|
accessor_value.setValue(itemId, value); |
|
|
|
|
|
|
|
// if (value != null) {
|
|
|
|
// if (log.isTraceEnabled()) {
|
|
|
|
// log.trace("Item {} new value: {}, Timestamp: {}", new Object[]{itemId, itemState.getValue(), itemState.getTimestamp().getTime()});
|
|
|
|
// }
|
|
|
|
// } else if (log.isInfoEnabled()) {
|
|
|
|
// log.info("Item {} new value: {}, Timestamp: {}, Quality: {}", new Object[]{itemId, itemState.getValue(), itemState.getTimestamp().getTime(), itemState.getQuality()});
|
|
|
|
// }
|
|
|
|
log.trace("Item {} new value: {}, Timestamp: {}", new Object[]{itemId, itemState.getValue(), itemState.getTimestamp().getTime()}); |
|
|
|
|
|
|
|
OpcItemDto itemDto = this.getItem(itemId); |
|
|
|
// if (Boolean.TRUE.equals(itemDto.getNeed_log())) {
|
|
|
|
// this.logItemChanged(itemId, accessor_value, value, itemDto);
|
|
|
|
// }
|
|
|
|
this.logItemChanged(itemId, accessor_value, value, itemDto); |
|
|
|
|
|
|
|
} catch (Exception var7) { |
|
|
@ -415,6 +403,7 @@ public class DeviceOpcProtocolRunable implements Runnable, DataCallback, ServerC |
|
|
|
} |
|
|
|
|
|
|
|
private void logItemChanged(String itemId, UnifiedDataAccessor accessor_value, Object value, OpcItemDto itemDto) { |
|
|
|
ISysParamService paramService = SpringContextHolder.getBean(ISysParamService.class); |
|
|
|
Object his = accessor_value.getValue(itemId); |
|
|
|
List<String> relate_items = itemDto.getRelate_items(); |
|
|
|
if (relate_items != null && !relate_items.isEmpty()) { |
|
|
@ -426,22 +415,35 @@ public class DeviceOpcProtocolRunable implements Runnable, DataCallback, ServerC |
|
|
|
Object obj = accessor_value.getValue(relate); |
|
|
|
sb.append("key:" + relate + "value:" + obj + ";"); |
|
|
|
} |
|
|
|
log.warn("设备:{}信号{}变更从{}->{};信号快照:{}", new Object[]{itemDto.getDevice_code(), itemId, his, value, sb}); |
|
|
|
// this.businessLogger.setResource(itemDto.getDevice_code(), itemDto.getDevice_name()).log("信号{}变更从{}->{};信号快照:{}", new Object[]{itemId, his, value, sb});
|
|
|
|
} else { |
|
|
|
if(his instanceof int[]){ |
|
|
|
if(!Arrays.equals((long[]) his, (long[]) value)){ |
|
|
|
log.warn("设备:{}信号{}变更从{}->{};信号快照:{}", new Object[]{itemDto.getDevice_code(), itemId, his, value}); |
|
|
|
if (!itemDto.getItem_code().endsWith("heartbeat") && !itemDto.getItem_code().endsWith("time") && !itemDto.getItem_code().endsWith("consumption")) { |
|
|
|
// 存在上次点位值为null情况 则不记录日志
|
|
|
|
if(!(his instanceof Float) && !(value instanceof Float)){ |
|
|
|
// LuceneLogDto luceneLogDto = new LuceneLogDto(itemDto.getOpc_server_code(), itemDto.getOpc_plc_code(),4, itemDto.getDevice_code(), itemDto.getItem_code().substring(itemDto.getItem_code().lastIndexOf(".") + 1),
|
|
|
|
// String.valueOf(his), String.valueOf(value));
|
|
|
|
// luceneLogDto.setLogType(LogTypeEnum.DEVICE_LOG.getDesc());
|
|
|
|
// String logLevel = paramService.findByCode(AcsConfig.LOGLEVEL).getValue();
|
|
|
|
// if(StrUtil.isNotEmpty(logLevel) && isNumeric(logLevel) && (luceneLogDto.getLog_level() >= Integer.parseInt(logLevel))){
|
|
|
|
// log.info("{}", JSON.toJSONString(luceneLogDto));
|
|
|
|
// }
|
|
|
|
} |
|
|
|
} else if(his instanceof String){ |
|
|
|
if(!StrUtil.equals((CharSequence) his, (CharSequence) value)){ |
|
|
|
log.warn("设备:{}信号{}变更从{}->{};信号快照:{}", new Object[]{itemDto.getDevice_code(), itemId, his, value}); |
|
|
|
} |
|
|
|
} else { |
|
|
|
log.warn("设备:{}信号{}变更从{}->{};信号快照:{}", new Object[]{itemDto.getDevice_code(), itemId, his, value}); |
|
|
|
if (!itemDto.getItem_code().endsWith("heartbeat") && !itemDto.getItem_code().endsWith("time") && !itemDto.getItem_code().endsWith("consumption")) { |
|
|
|
if(!(his instanceof Float) && !(value instanceof Float)){ |
|
|
|
// LuceneLogDto luceneLogDto = new LuceneLogDto(itemDto.getOpc_server_code(), itemDto.getOpc_plc_code(),4, itemDto.getDevice_code(), itemDto.getItem_code().substring(itemDto.getItem_code().lastIndexOf(".") + 1),
|
|
|
|
// String.valueOf(his), String.valueOf(value));
|
|
|
|
// luceneLogDto.setLogType(LogTypeEnum.DEVICE_LOG.getDesc());
|
|
|
|
// String logLevel = paramService.findByCode(AcsConfig.LOGLEVEL).getValue();
|
|
|
|
// if(StrUtil.isNotEmpty(logLevel) && isNumeric(logLevel) && (luceneLogDto.getLog_level() >= Integer.parseInt(logLevel))){
|
|
|
|
// log.info("{}", JSON.toJSONString(luceneLogDto));
|
|
|
|
// }
|
|
|
|
} |
|
|
|
} |
|
|
|
// this.businessLogger.setResource(itemDto.getDevice_code(), itemDto.getDevice_name()).log("信号{}变更从{}->{}", new Object[]{itemId, his, value});
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public static boolean isNumeric(String str) { |
|
|
|
return Pattern.compile("^[0-9]+$").matcher(str).matches(); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|