11 changed files with 921 additions and 197 deletions
@ -1,235 +1,558 @@ |
|||||
package org.nl.acs.opc; |
package org.nl.acs.opc; |
||||
|
|
||||
import cn.hutool.core.date.DateUtil; |
import cn.hutool.core.date.DateUtil; |
||||
import cn.hutool.core.util.ObjectUtil; |
import cn.hutool.core.util.ObjectUtil; |
||||
import cn.hutool.core.util.StrUtil; |
import cn.hutool.core.util.StrUtil; |
||||
|
import com.alibaba.fastjson.JSON; |
||||
import lombok.extern.slf4j.Slf4j; |
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.nl.acs.AcsConfig; |
||||
import org.nl.acs.udw.UnifiedDataAccessor; |
import org.nl.acs.udw.UnifiedDataAccessor; |
||||
import org.nl.acs.udw.UnifiedDataAccessorFactory; |
import org.nl.acs.udw.UnifiedDataAccessorFactory; |
||||
|
import org.nl.acs.udw.UnifiedDataAppService; |
||||
import org.nl.modules.wql.util.SpringContextHolder; |
import org.nl.modules.wql.util.SpringContextHolder; |
||||
import org.openscada.opc.lib.da.Group; |
import org.openscada.opc.lib.da.*; |
||||
import org.openscada.opc.lib.da.Item; |
|
||||
import org.openscada.opc.lib.da.ItemState; |
|
||||
import org.openscada.opc.lib.da.Server; |
|
||||
|
|
||||
import java.util.*; |
import java.util.*; |
||||
|
|
||||
@Slf4j |
@Slf4j |
||||
public class DeviceOpcProtocolRunable implements Runnable { |
public class DeviceOpcProtocolRunable implements Runnable, DataCallback, ServerConnectionStateListener { |
||||
OpcServerService opcServerService = SpringContextHolder.getBean(OpcServerServiceImpl.class); |
OpcServerService opcServerService = SpringContextHolder.getBean(OpcServerServiceImpl.class); |
||||
|
|
||||
|
|
||||
List<OpcItemDto> protocols; |
List<OpcItemDto> protocols; |
||||
OpcServerManageDto OpcServer; |
OpcServerManageDto OpcServer; |
||||
int error_num; |
int error_num; |
||||
String message; |
String message; |
||||
|
|
||||
Group group; |
Group group; |
||||
|
private Server server; |
||||
|
private int all_null; |
||||
|
|
||||
public DeviceOpcProtocolRunable() { |
public DeviceOpcProtocolRunable() { |
||||
this.error_num = 0; |
this.error_num = 0; |
||||
this.message = null; |
this.message = null; |
||||
} |
} |
||||
|
|
||||
public List<OpcItemDto> getProtocols() { |
public List<OpcItemDto> getProtocols() { |
||||
return this.protocols; |
return this.protocols; |
||||
} |
} |
||||
|
|
||||
public void setProtocols(List<OpcItemDto> protocols) { |
public void setProtocols(List<OpcItemDto> protocols) { |
||||
this.protocols = protocols; |
this.protocols = protocols; |
||||
} |
} |
||||
|
|
||||
public OpcServerManageDto getOpcServer() { |
public OpcServerManageDto getOpcServer() { |
||||
return this.OpcServer; |
return this.OpcServer; |
||||
} |
} |
||||
|
|
||||
public void setOpcServer(OpcServerManageDto opcServer) { |
public void setOpcServer(OpcServerManageDto opcServer) { |
||||
this.OpcServer = opcServer; |
this.OpcServer = opcServer; |
||||
} |
} |
||||
|
|
||||
OpcItemDto getItem(String item) { |
OpcItemDto getItem(String item) { |
||||
Iterator var2 = this.protocols.iterator(); |
Iterator var2 = this.protocols.iterator(); |
||||
|
|
||||
OpcItemDto dto; |
OpcItemDto dto; |
||||
do { |
do { |
||||
if (!var2.hasNext()) { |
if (!var2.hasNext()) { |
||||
return null; |
return null; |
||||
} |
} |
||||
|
|
||||
dto = (OpcItemDto) var2.next(); |
dto = (OpcItemDto) var2.next(); |
||||
} while (!StrUtil.equals(item, dto.getItem_code())); |
} while (!StrUtil.equals(item, dto.getItem_code())); |
||||
|
|
||||
return dto; |
return dto; |
||||
} |
} |
||||
|
|
||||
@Override |
/*@Override |
||||
public void run() { |
public void run() { |
||||
while (true) { |
while (true) { |
||||
try { |
try { |
||||
group= opcServerService.getServer(this.OpcServer.getOpc_code()); |
group = opcServerService.getServer(this.OpcServer.getOpc_code()); |
||||
|
|
||||
List<String> itemsString = new ArrayList(); |
List<String> itemsString = new ArrayList(); |
||||
Iterator it = this.protocols.iterator(); |
Iterator it = this.protocols.iterator(); |
||||
|
|
||||
|
while (it.hasNext()) { |
||||
|
OpcItemDto protocol = (OpcItemDto) it.next(); |
||||
|
String item = protocol.getItem_code(); |
||||
|
itemsString.add(item); |
||||
|
} |
||||
|
|
||||
|
Map<String, Item> itemsMap = new LinkedHashMap(); |
||||
|
boolean is_error = false; |
||||
|
StringBuilder err_message = new StringBuilder(); |
||||
|
Iterator var7 = itemsString.iterator(); |
||||
|
|
||||
|
while (var7.hasNext()) { |
||||
|
String string = (String) var7.next(); |
||||
|
|
||||
|
try { |
||||
|
itemsMap.put(string, group.addItem(string)); |
||||
|
log.trace("添加成功 {}", string); |
||||
|
} catch (Exception var29) { |
||||
|
err_message.append(string + ":" + var29.getMessage()); |
||||
|
if (!is_error) { |
||||
|
is_error = true; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (is_error) { |
||||
|
log.info("设备OPC数据同步配置异常," + err_message); |
||||
|
} |
||||
|
|
||||
|
if (!OpcStartTag.is_run) { |
||||
|
OpcStartTag.is_run = true; |
||||
|
} |
||||
|
|
||||
|
// 线程名
|
||||
|
String tag = Thread.currentThread().getName(); |
||||
|
if (this.OpcServer != null) { |
||||
|
tag = tag + this.OpcServer.getOpc_code(); |
||||
|
} |
||||
|
UnifiedDataAccessor accessor_value = |
||||
|
UnifiedDataAccessorFactory.getAccessor(OpcConfig.udw_opc_value_key); |
||||
|
|
||||
|
boolean time_out = false; |
||||
|
|
||||
|
label97: |
||||
|
while (true) { |
||||
|
// System.out.println("label97");
|
||||
|
long begin = System.currentTimeMillis(); |
||||
|
Map<Item, ItemState> itemStatus = null; |
||||
|
|
||||
|
try { |
||||
|
itemStatus = group.read(true, (Item[]) itemsMap.values().toArray(new Item[0])); |
||||
|
} catch (Exception e) { |
||||
|
try { |
||||
|
itemStatus = group.read(true, (Item[]) itemsMap.values().toArray(new Item[0])); |
||||
|
} catch (Exception e2) { |
||||
|
itemStatus = group.read(true, (Item[]) itemsMap.values().toArray(new Item[0])); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
//TODO 读完释放server可行否?
|
||||
|
|
||||
|
long end = System.currentTimeMillis(); |
||||
|
log.trace("{} 开始记时{}", tag, DateUtil.now()); |
||||
|
long duration = end - begin; |
||||
|
log.trace("{} 读取耗时:{}", tag, duration); |
||||
|
if (duration > 1000L) { |
||||
|
if (!time_out) { |
||||
|
log.warn(" {} 读取超时 : {} ", tag, duration); |
||||
|
} |
||||
|
|
||||
|
time_out = true; |
||||
|
} else { |
||||
|
time_out = false; |
||||
|
} |
||||
|
|
||||
|
// A1_HK_04.A1_HK_04.A1_HK_04_3.door 列表
|
||||
|
Set<Item> items = itemStatus.keySet(); |
||||
|
Iterator var18 = items.iterator(); |
||||
|
|
||||
|
while (true) { |
||||
|
Item item; |
||||
|
// A1_HK_04.A1_HK_04.A1_HK_04_3.door
|
||||
|
// 当前值
|
||||
|
Object value; |
||||
|
// 旧的值
|
||||
|
Object his; |
||||
|
do { |
||||
|
if (!var18.hasNext()) { |
||||
|
end = System.currentTimeMillis(); |
||||
|
log.trace("{}", itemsString); |
||||
|
log.trace("{} 计算完成耗时{}", tag, end - begin); |
||||
|
Thread.sleep((long) OpcConfig.synchronized_millisecond); |
||||
|
if (this.error_num != 0) { |
||||
|
this.error_num = 0; |
||||
|
this.message = null; |
||||
|
} |
||||
|
// 所有信号读完并且没有变化的值
|
||||
|
continue label97; |
||||
|
} |
||||
|
|
||||
|
item = (Item) var18.next(); |
||||
|
ItemState itemState = itemStatus.get(item); |
||||
|
value = OpcUtl.getValue(item, itemState); |
||||
|
his = accessor_value.getValue(item.getId()); |
||||
|
if (!ObjectUtil.equal(itemState.getQuality(), QualityTypeValue.OPC_QUALITY_GOOD) |
||||
|
&& his != null) { |
||||
|
log.warn("opc 值不健康 item: {}, 状态: {}", item.getId(), itemState.getQuality()); |
||||
|
} |
||||
|
} while (ObjectUtil.equal(value, his)); // 如果两次的值相等,不走下面的代码
|
||||
|
|
||||
|
OpcItemDto itemDto = this.getItem(item.getId()); |
||||
|
if (itemDto.getNeed_log() != null && itemDto.getNeed_log()) { |
||||
|
StringBuilder sb = new StringBuilder(); |
||||
|
// 设备的ITEM项
|
||||
|
List<String> relate_items = itemDto.getRelate_items(); |
||||
|
Iterator var26 = relate_items.iterator(); |
||||
|
|
||||
|
while (var26.hasNext()) { |
||||
|
String relate = (String) var26.next(); |
||||
|
Object obj = accessor_value.getValue(relate); |
||||
|
sb.append("key:" + relate + "value:" + obj + ";"); |
||||
|
} |
||||
|
|
||||
|
log.info("信号{}变更从{}->{};信号快照:{}", new Object[]{item.getId(), his, value, sb}); |
||||
|
} |
||||
|
// 设置值
|
||||
|
//accessor_value.setValue(item.getId(), value);
|
||||
|
if (!ObjectUtil.isEmpty(value) || !"".equals(value)) { |
||||
|
accessor_value.setValue(item.getId(), value); |
||||
|
} |
||||
|
if (ObjectUtil.isEmpty(value) && "".equals(value)) { |
||||
|
accessor_value.removeValue(item.getId()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} catch (Exception var30) { |
||||
|
|
||||
|
if (group != null) { |
||||
|
try { |
||||
|
group.getServer().dispose(); |
||||
|
group.clear(); |
||||
|
group.remove(); |
||||
|
} catch (Exception var6) { |
||||
|
} |
||||
|
this.group = null; |
||||
|
} |
||||
|
|
||||
while (it.hasNext()) { |
|
||||
OpcItemDto protocol = (OpcItemDto) it.next(); |
|
||||
String item = protocol.getItem_code(); |
|
||||
itemsString.add(item); |
|
||||
} |
|
||||
|
|
||||
Map<String, Item> itemsMap = new LinkedHashMap(); |
String error_message = "设备信息同步异常"; |
||||
boolean is_error = false; |
if (!StrUtil.equals(this.message, error_message)) { |
||||
StringBuilder err_message = new StringBuilder(); |
log.warn("", var30); |
||||
Iterator var7 = itemsString.iterator(); |
} |
||||
|
|
||||
while (var7.hasNext()) { |
try { |
||||
String string = (String) var7.next(); |
Thread.sleep((long) (OpcConfig.synchronized_exception_wait_second * 1000)); |
||||
|
} catch (InterruptedException e) { |
||||
try { |
e.printStackTrace(); |
||||
itemsMap.put(string, group.addItem(string)); |
} |
||||
log.trace("添加成功 {}", string); |
++this.error_num; |
||||
} catch (Exception var29) { |
if (this.error_num > 3 && !StrUtil.equals(this.message, error_message)) { |
||||
err_message.append(string + ":" + var29.getMessage()); |
log.info("设备同步通信异常"); |
||||
if (!is_error) { |
this.message = error_message; |
||||
is_error = true; |
} |
||||
} |
} |
||||
} |
|
||||
} |
} |
||||
|
}*/ |
||||
if (is_error) { |
|
||||
log.info("设备OPC数据同步配置异常," + err_message); |
@Override |
||||
|
public void run() { |
||||
|
if (OpcConfig.opc_item_read_using_callback) { |
||||
|
this.runNew(); |
||||
|
} else { |
||||
|
this.runOld(); |
||||
} |
} |
||||
|
} |
||||
|
|
||||
if (!OpcStartTag.is_run) { |
|
||||
OpcStartTag.is_run = true; |
|
||||
} |
|
||||
|
|
||||
// 线程名
|
private void runOld() { |
||||
String tag = Thread.currentThread().getName(); |
OpcServerService opcServerService = SpringContextHolder.getBean(OpcServerService .class); |
||||
if (this.OpcServer != null) { |
while (true) { |
||||
tag = tag + this.OpcServer.getOpc_code(); |
start: |
||||
|
try { |
||||
|
if (this.group != null) { |
||||
|
group.clear(); |
||||
|
group.remove(); |
||||
|
log.trace("清理group..."); |
||||
|
} |
||||
|
if (this.server != null) { |
||||
|
server.disconnect(); |
||||
|
log.trace("清理server..."); |
||||
|
} |
||||
|
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(); |
||||
|
|
||||
|
while (var3.hasNext()) { |
||||
|
OpcItemDto protocol = (OpcItemDto) var3.next(); |
||||
|
String item = protocol.getItem_code(); |
||||
|
itemsString.add(item); |
||||
|
} |
||||
|
|
||||
|
Map<String, Item> itemsMap = new LinkedHashMap(); |
||||
|
boolean is_error = false; |
||||
|
StringBuilder err_message = new StringBuilder(); |
||||
|
Iterator var6 = itemsString.iterator(); |
||||
|
|
||||
|
while (var6.hasNext()) { |
||||
|
String string = (String) var6.next(); |
||||
|
|
||||
|
try { |
||||
|
Item item = group.addItem(string); |
||||
|
itemsMap.put(string, item); |
||||
|
log.trace("添加成功 {}", string); |
||||
|
} catch (Exception var26) { |
||||
|
err_message.append(string + ":" + var26.getMessage()); |
||||
|
if (!is_error) { |
||||
|
is_error = true; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
String tag; |
||||
|
if (is_error) { |
||||
|
tag = err_message.toString(); |
||||
|
log.warn("{}:{}", OpcConfig.resource_code, tag); |
||||
|
} |
||||
|
|
||||
|
if (!OpcStartTag.is_run) { |
||||
|
OpcStartTag.is_run = true; |
||||
|
} |
||||
|
|
||||
|
tag = ""; |
||||
|
if (log.isWarnEnabled()) { |
||||
|
tag = Thread.currentThread().getName(); |
||||
|
if (this.OpcServer != null) { |
||||
|
tag = tag + "," + this.getOpcGroupID(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
UnifiedDataAccessor accessor_value = UnifiedDataAccessorFactory.getAccessor(OpcConfig.udw_opc_value_key); |
||||
|
boolean time_out = false; |
||||
|
|
||||
|
while (DeviceOpcSynchronizeAutoRun.isRun) { |
||||
|
long begin = System.currentTimeMillis(); |
||||
|
if (log.isTraceEnabled()) { |
||||
|
log.trace("{} 开始记时{}", tag, DateUtil.now()); |
||||
|
} |
||||
|
|
||||
|
Map<Item, ItemState> itemStatus = group.read(true, (Item[]) itemsMap.values().toArray(new Item[0])); |
||||
|
long end = System.currentTimeMillis(); |
||||
|
long duration = end - begin; |
||||
|
if (log.isTraceEnabled()) { |
||||
|
log.trace("{} 读取耗时:{}", tag, duration); |
||||
|
} |
||||
|
|
||||
|
if (duration > 1000L) { |
||||
|
if (!time_out) { |
||||
|
log.warn("{} 读取超时 : {}", tag, duration); |
||||
|
} |
||||
|
|
||||
|
time_out = true; |
||||
|
} else { |
||||
|
time_out = false; |
||||
|
} |
||||
|
|
||||
|
boolean valueAllNotNull = false; |
||||
|
Set<Item> items = itemStatus.keySet(); |
||||
|
Iterator var18 = items.iterator(); |
||||
|
|
||||
|
while (var18.hasNext()) { |
||||
|
Item item = (Item) var18.next(); |
||||
|
ItemState itemState = (ItemState) itemStatus.get(item); |
||||
|
Object value = OpcUtl.getValue(item, itemState); |
||||
|
if (value != null) { |
||||
|
valueAllNotNull = true; |
||||
|
} else { |
||||
|
log.info("item:{},velue为空,value:{}", item.getId(), value); |
||||
|
} |
||||
|
|
||||
|
String itemId = item.getId(); |
||||
|
Object his = accessor_value.getValue(itemId); |
||||
|
if (ObjectUtil.notEqual(itemState.getQuality(), QualityTypeValue.OPC_QUALITY_GOOD) && his != null) { |
||||
|
log.warn("opc 值不健康 item: {}, 状态: {}", itemId, itemState.getQuality()); |
||||
|
valueAllNotNull = false; |
||||
|
} |
||||
|
|
||||
|
if (!UnifiedDataAppService.isEquals(value, his)) { |
||||
|
OpcItemDto itemDto = this.getItem(itemId); |
||||
|
if (true) { |
||||
|
// this.logItemChanged(itemId, accessor_value, value, itemDto);
|
||||
|
} |
||||
|
if(!ObjectUtil.isEmpty(value) || "".equals(value)){ |
||||
|
accessor_value.setValue(itemId, value); |
||||
|
} |
||||
|
if(ObjectUtil.isEmpty(value) && !"".equals(value)){ |
||||
|
accessor_value.removeValue(itemId); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
end = System.currentTimeMillis(); |
||||
|
if (log.isTraceEnabled()) { |
||||
|
log.trace("{}", itemsString); |
||||
|
log.trace("{} 计算完成耗时{}", tag, end - begin); |
||||
|
} |
||||
|
|
||||
|
ThreadUtl.sleep((long) OpcConfig.synchronized_millisecond); |
||||
|
if (this.error_num != 0) { |
||||
|
this.error_num = 0; |
||||
|
this.message = null; |
||||
|
} |
||||
|
|
||||
|
if (!valueAllNotNull) { |
||||
|
if (this.all_null < 3) { |
||||
|
if (log.isWarnEnabled()) { |
||||
|
log.warn("OPC数据源: {} 所有内容都为空,检查网络, all_null:{} ,暂定{}s", tag, all_null,3); |
||||
|
} |
||||
|
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,3); |
||||
|
} |
||||
|
ThreadUtl.sleep(3000); |
||||
|
break start; |
||||
|
} else if (this.all_null < 12) { |
||||
|
if (log.isWarnEnabled()) { |
||||
|
log.warn(tag + "重新创建server"); |
||||
|
log.warn("{} 所有内容都为空, all_null:{} ,暂定{}s", tag, all_null,3); |
||||
|
} |
||||
|
ThreadUtl.sleep(3000); |
||||
|
break start; |
||||
|
} else { |
||||
|
if (log.isWarnEnabled()) { |
||||
|
log.warn("{} 所有内容都为空, all_null:{} ,暂定{}ms", tag, all_null, 5000); |
||||
|
} |
||||
|
ThreadUtl.sleep((long) (5000)); |
||||
|
break start; |
||||
|
} |
||||
|
|
||||
|
// ++this.all_null;
|
||||
|
} else { |
||||
|
this.all_null = 0; |
||||
|
} |
||||
|
// break start;
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
log.warn("opc线程停止。。。"); |
||||
|
return; |
||||
|
} catch (Exception var27) { |
||||
|
if (this.server != null) { |
||||
|
try { |
||||
|
this.server.disconnect(); |
||||
|
} catch (Exception var25) { |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
this.server = null; |
||||
|
if (!DeviceOpcSynchronizeAutoRun.isRun) { |
||||
|
log.warn("opc线程停止2。。。"); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
String error_message = "设备信息同步异常"; |
||||
|
if (!StrUtil.equals(this.message, error_message)) { |
||||
|
log.warn(error_message, var27); |
||||
|
} |
||||
|
|
||||
|
ThreadUtl.sleep((long) (OpcConfig.synchronized_exception_wait_second * 1000)); |
||||
|
++this.error_num; |
||||
|
if (this.error_num > 3 && !StrUtil.equals(this.message, error_message)) { |
||||
|
this.message = error_message; |
||||
|
} |
||||
|
} |
||||
} |
} |
||||
UnifiedDataAccessor accessor_value = |
} |
||||
UnifiedDataAccessorFactory.getAccessor(OpcConfig.udw_opc_value_key); |
|
||||
|
|
||||
boolean time_out = false; |
|
||||
|
|
||||
label97: |
private void runNew() { |
||||
|
Async20Access accessor = null; |
||||
|
|
||||
while (true) { |
while (true) { |
||||
// System.out.println("label97");
|
String opcGroupId = this.getOpcGroupID(); |
||||
long begin = System.currentTimeMillis(); |
|
||||
Map<Item, ItemState> itemStatus =null; |
try { |
||||
|
if (this.server == null) { |
||||
try{ |
this.server = OpcServerUtl.getServerWithOutException(this.OpcServer.getOpc_host(), this.OpcServer.getCls_id(), this.OpcServer.getUser(), this.OpcServer.getPassword(), this.OpcServer.getDomain()); |
||||
itemStatus=group.read(true, (Item[]) itemsMap.values().toArray(new Item[0])); |
this.server.addStateListener((ServerConnectionStateListener) this); |
||||
}catch (Exception e){ |
accessor = new Async20Access(this.server, OpcConfig.synchronized_millisecond, true); |
||||
try{ |
Iterator var9 = this.protocols.iterator(); |
||||
itemStatus=group.read(true, (Item[]) itemsMap.values().toArray(new Item[0])); |
|
||||
}catch (Exception e2){ |
while (var9.hasNext()) { |
||||
itemStatus=group.read(true, (Item[]) itemsMap.values().toArray(new Item[0])); |
OpcItemDto protocol = (OpcItemDto) var9.next(); |
||||
} |
String itemId = protocol.getItem_code(); |
||||
} |
accessor.addItem(itemId, (DataCallback) this); |
||||
|
} |
||||
|
|
||||
//TODO 读完释放server可行否?
|
accessor.bind(); |
||||
|
log.info("Async20Access bind {}", opcGroupId); |
||||
long end = System.currentTimeMillis(); |
} |
||||
log.trace("{} 开始记时{}", tag, DateUtil.now()); |
|
||||
long duration = end - begin; |
Thread.sleep((long) (OpcConfig.synchronized_exception_wait_second * 1000)); |
||||
log.trace("{} 读取耗时:{}", tag, duration); |
} catch (Exception var8) { |
||||
if (duration > 1000L) { |
if (accessor != null) { |
||||
if (!time_out) { |
try { |
||||
log.warn(" {} 读取超时 : {} ", tag, duration); |
log.warn("Async20Access unbind {}", opcGroupId); |
||||
} |
accessor.unbind(); |
||||
|
} catch (Exception var7) { |
||||
|
var7.printStackTrace(); |
||||
|
} |
||||
|
|
||||
|
accessor = null; |
||||
|
} |
||||
|
|
||||
|
if (this.server != null) { |
||||
|
try { |
||||
|
this.server.disconnect(); |
||||
|
} catch (Exception var6) { |
||||
|
} |
||||
|
|
||||
|
this.server = null; |
||||
|
} |
||||
|
|
||||
|
if (var8 instanceof InterruptedException) { |
||||
|
log.warn("OPC 同步线程(%s)被中断", opcGroupId); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
log.warn("设备信息同步异常", var8); |
||||
|
ThreadUtl.sleep((long) (OpcConfig.synchronized_exception_wait_second * 1000)); |
||||
|
String error_message = var8.getMessage(); |
||||
|
if (error_message == null) { |
||||
|
error_message = var8.toString(); |
||||
|
} |
||||
|
|
||||
time_out = true; |
++this.error_num; |
||||
} else { |
if (this.error_num > 3 && !StrUtil.equals(this.message, error_message)) { |
||||
time_out = false; |
this.message = error_message; |
||||
} |
} |
||||
|
|
||||
// A1_HK_04.A1_HK_04.A1_HK_04_3.door 列表
|
|
||||
Set<Item> items = itemStatus.keySet(); |
|
||||
Iterator var18 = items.iterator(); |
|
||||
|
|
||||
while (true) { |
|
||||
Item item; |
|
||||
// A1_HK_04.A1_HK_04.A1_HK_04_3.door
|
|
||||
// 当前值
|
|
||||
Object value; |
|
||||
// 旧的值
|
|
||||
Object his; |
|
||||
do { |
|
||||
if (!var18.hasNext()) { |
|
||||
end = System.currentTimeMillis(); |
|
||||
log.trace("{}", itemsString); |
|
||||
log.trace("{} 计算完成耗时{}", tag, end - begin); |
|
||||
Thread.sleep((long) OpcConfig.synchronized_millisecond); |
|
||||
if (this.error_num != 0) { |
|
||||
this.error_num = 0; |
|
||||
this.message = null; |
|
||||
} |
|
||||
// 所有信号读完并且没有变化的值
|
|
||||
continue label97; |
|
||||
} |
|
||||
|
|
||||
item = (Item) var18.next(); |
|
||||
ItemState itemState = itemStatus.get(item); |
|
||||
value = OpcUtl.getValue(item, itemState); |
|
||||
his = accessor_value.getValue(item.getId()); |
|
||||
if (!ObjectUtil.equal(itemState.getQuality(), QualityTypeValue.OPC_QUALITY_GOOD) |
|
||||
&& his != null) { |
|
||||
log.warn("opc 值不健康 item: {}, 状态: {}", item.getId(), itemState.getQuality()); |
|
||||
} |
|
||||
} while (ObjectUtil.equal(value, his)); // 如果两次的值相等,不走下面的代码
|
|
||||
|
|
||||
OpcItemDto itemDto = this.getItem(item.getId()); |
|
||||
if (itemDto.getNeed_log() != null && itemDto.getNeed_log()) { |
|
||||
StringBuilder sb = new StringBuilder(); |
|
||||
// 设备的ITEM项
|
|
||||
List<String> relate_items = itemDto.getRelate_items(); |
|
||||
Iterator var26 = relate_items.iterator(); |
|
||||
|
|
||||
while (var26.hasNext()) { |
|
||||
String relate = (String) var26.next(); |
|
||||
Object obj = accessor_value.getValue(relate); |
|
||||
sb.append("key:" + relate + "value:" + obj + ";"); |
|
||||
} |
|
||||
|
|
||||
log.info("信号{}变更从{}->{};信号快照:{}", new Object[] {item.getId(), his, value, sb}); |
|
||||
} |
} |
||||
// 设置值
|
|
||||
accessor_value.setValue(item.getId(), value); |
|
||||
} |
|
||||
} |
|
||||
} catch (Exception var30) { |
|
||||
|
|
||||
if (group != null) { |
|
||||
try { |
|
||||
group.getServer().dispose(); |
|
||||
group.clear(); |
|
||||
group.remove(); |
|
||||
} catch (Exception var6) { |
|
||||
} |
|
||||
this.group = null; |
|
||||
} |
} |
||||
|
} |
||||
|
|
||||
|
|
||||
String error_message = "设备信息同步异常"; |
private String getOpcGroupID() { |
||||
if (!StrUtil.equals(this.message, error_message)) { |
String var10000 = this.OpcServer.getOpc_code(); |
||||
log.warn("", var30); |
return var10000 + "(" + this.protocols.size() + " items)"; |
||||
} |
} |
||||
|
|
||||
|
@Override |
||||
|
public void changed(Item item, ItemState itemState) { |
||||
|
String itemId = item.getId(); |
||||
try { |
try { |
||||
Thread.sleep((long) (OpcConfig.synchronized_exception_wait_second * 1000)); |
Object value = OpcUtl.getValue(item, itemState); |
||||
} catch (InterruptedException e) { |
UnifiedDataAccessor accessor_value = UnifiedDataAccessorFactory.getAccessor(OpcConfig.udw_opc_value_key); |
||||
e.printStackTrace(); |
accessor_value.setValue(itemId, value); |
||||
|
log.trace("Item {} new value: {}, Timestamp: {}", new Object[]{itemId, itemState.getValue(), itemState.getTimestamp().getTime()}); |
||||
|
OpcItemDto itemDto = this.getItem(itemId); |
||||
|
this.logItemChanged(itemId, accessor_value, value, itemDto); |
||||
|
|
||||
|
} catch (Exception var7) { |
||||
|
log.error(itemId, var7); |
||||
} |
} |
||||
++this.error_num; |
} |
||||
if (this.error_num > 3 && !StrUtil.equals(this.message, error_message)) { |
|
||||
log.info("设备同步通信异常"); |
@Override |
||||
this.message = error_message; |
public void connectionStateChanged(boolean connected) { |
||||
|
if (!connected) { |
||||
|
this.server = null; |
||||
} |
} |
||||
} |
log.warn("opc server {} {}", this.getOpcGroupID(), connected ? "connected" : "disconnected"); |
||||
} |
} |
||||
} |
|
||||
|
private void logItemChanged(String itemId, UnifiedDataAccessor accessor_value, Object value, OpcItemDto itemDto) { |
||||
|
|
||||
|
} |
||||
|
|
||||
} |
} |
||||
|
@ -0,0 +1,45 @@ |
|||||
|
|
||||
|
package org.nl.acs.udw.rest; |
||||
|
|
||||
|
|
||||
|
import cn.dev33.satoken.annotation.SaIgnore; |
||||
|
import io.swagger.annotations.Api; |
||||
|
import io.swagger.annotations.ApiOperation; |
||||
|
import lombok.RequiredArgsConstructor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.nl.acs.udw.service.UdwManageService; |
||||
|
import org.springframework.data.domain.Pageable; |
||||
|
import org.springframework.http.HttpStatus; |
||||
|
import org.springframework.http.ResponseEntity; |
||||
|
import org.springframework.web.bind.annotation.GetMapping; |
||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||
|
import org.springframework.web.bind.annotation.RequestParam; |
||||
|
import org.springframework.web.bind.annotation.RestController; |
||||
|
|
||||
|
import java.util.Map; |
||||
|
|
||||
|
@RestController |
||||
|
@RequiredArgsConstructor |
||||
|
@Api(tags = "内存点位管理") |
||||
|
@RequestMapping("/api/udw") |
||||
|
@Slf4j |
||||
|
public class UdwManagerController { |
||||
|
|
||||
|
private final UdwManageService udwManageService; |
||||
|
|
||||
|
// @GetMapping
|
||||
|
// @Log("查询内存点位")
|
||||
|
// @ApiOperation("查询内存点位")
|
||||
|
// @SaIgnore
|
||||
|
// public ResponseEntity<Object> query(@RequestParam JSONObject whereJson) {
|
||||
|
// return new ResponseEntity<>(udwManageService.queryByConditions(whereJson), HttpStatus.OK);
|
||||
|
// }
|
||||
|
|
||||
|
@GetMapping |
||||
|
@ApiOperation("查询内存点位") |
||||
|
@SaIgnore |
||||
|
//@PreAuthorize("@el.check('device:list')")
|
||||
|
public ResponseEntity<Object> query(@RequestParam Map whereJson, Pageable page) { |
||||
|
return new ResponseEntity<>(udwManageService.queryAll(whereJson, page), HttpStatus.OK); |
||||
|
} |
||||
|
} |
@ -0,0 +1,27 @@ |
|||||
|
import request from '@/utils/request' |
||||
|
|
||||
|
export function add(data) { |
||||
|
return request({ |
||||
|
url: 'api/deviceErrorLog', |
||||
|
method: 'post', |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
export function del(ids) { |
||||
|
return request({ |
||||
|
url: 'api/deviceErrorLog/', |
||||
|
method: 'delete', |
||||
|
data: ids |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
export function edit(data) { |
||||
|
return request({ |
||||
|
url: 'api/deviceErrorLog', |
||||
|
method: 'put', |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
export default { add, edit, del } |
@ -0,0 +1,28 @@ |
|||||
|
import request from '@/utils/request' |
||||
|
|
||||
|
export function add(data) { |
||||
|
return request({ |
||||
|
url: 'api/task', |
||||
|
method: 'post', |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
export function del(ids) { |
||||
|
return request({ |
||||
|
url: 'api/task/', |
||||
|
method: 'delete', |
||||
|
data: ids |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
export function edit(data) { |
||||
|
return request({ |
||||
|
url: 'api/task', |
||||
|
method: 'put', |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
export default { edit, del } |
||||
|
|
@ -0,0 +1,181 @@ |
|||||
|
<template> |
||||
|
<div class="app-container"> |
||||
|
<!--工具栏--> |
||||
|
<div class="head-container"> |
||||
|
<div v-if="crud.props.searchToggle"> |
||||
|
<!-- 搜索 --> |
||||
|
<el-select |
||||
|
v-model="form.unified_key" |
||||
|
placeholder="unified_key" |
||||
|
class="filter-item" |
||||
|
clearable |
||||
|
filterable |
||||
|
size="small" |
||||
|
@change="crud.toQuery" |
||||
|
> |
||||
|
<el-option v-for="(item,index) in unified_key" :key="index" :label="item.label" :value="item.value" /> |
||||
|
</el-select> |
||||
|
<el-input |
||||
|
v-model="query.code" |
||||
|
size="small" |
||||
|
clearable |
||||
|
placeholder="编号" |
||||
|
style="width: 200px;" |
||||
|
class="filter-item" |
||||
|
@keyup.enter.native="crud.toQuery" |
||||
|
/> |
||||
|
</div> |
||||
|
<!--如果想在工具栏加入更多按钮,可以使用插槽方式, slot = 'left' or 'right'--> |
||||
|
<crudOperation :permission="permission" /> |
||||
|
<!--表单组件--> |
||||
|
<el-dialog |
||||
|
:close-on-click-modal="false" |
||||
|
:before-close="crud.cancelCU" |
||||
|
:visible.sync="crud.status.cu > 0" |
||||
|
:title="crud.status.title" |
||||
|
width="500px" |
||||
|
> |
||||
|
<el-form ref="form" :model="form" :rules="rules" size="small" label-width="80px"> |
||||
|
<el-form-item label="unified_key"> |
||||
|
<el-input v-model="form.unified_key" style="width: 370px;" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="编号"> |
||||
|
<el-input v-model="form.key" style="width: 370px;" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="值"> |
||||
|
<el-input v-model="form.value" style="width: 370px;" /> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
<div slot="footer" class="dialog-footer"> |
||||
|
<el-button type="text" @click="crud.cancelCU">取消</el-button> |
||||
|
<el-button :loading="crud.cu === 2" type="primary" @click="crud.submitCU">确认</el-button> |
||||
|
</div> |
||||
|
</el-dialog> |
||||
|
<!--表格渲染--> |
||||
|
<el-table |
||||
|
ref="table" |
||||
|
v-loading="crud.loading" |
||||
|
:data="crud.data" |
||||
|
size="small" |
||||
|
style="width: 100%;" |
||||
|
@selection-change="crud.selectionChangeHandler" |
||||
|
> |
||||
|
<el-table-column prop="unified_key" label="unified_key" /> |
||||
|
<el-table-column prop="key" label="编号" /> |
||||
|
<el-table-column prop="value" label="值" /> |
||||
|
<el-table-column |
||||
|
v-permission="['admin','instruction:edit','instruction:del']" |
||||
|
fixed="left" |
||||
|
label="操作" |
||||
|
width="150px" |
||||
|
align="center" |
||||
|
> |
||||
|
<template> |
||||
|
<el-button slot="right" size="mini" style="margin-left: -1px;margin-right: 2px" type="text" @click="dialogFormVisible = true"> |
||||
|
查询历史 |
||||
|
</el-button> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
<!--分页组件--> |
||||
|
<pagination /> |
||||
|
<!--弹窗设置设备与图标绑定与角度--> |
||||
|
<el-dialog title="历史" :visible.sync="dialogFormVisible" width="35%"> |
||||
|
<el-form :model="form" size="small"> |
||||
|
<el-form-item label="unified_key" prop="unified_key" label-width="100px"> |
||||
|
<el-input v-model="form.unified_key" :disabled="true" /> |
||||
|
</el-form-item> |
||||
|
|
||||
|
<el-form-item label="code" prop="key" label-width="100px"> |
||||
|
<el-input v-model="form.key" :disabled="true" /> |
||||
|
</el-form-item> |
||||
|
|
||||
|
</el-form> |
||||
|
</el-dialog> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import pagination from '@crud/Pagination' |
||||
|
import crudUdwData from '@/api/acs/history/udwData' |
||||
|
import CRUD, { crud, form, header, presenter } from '@crud/crud' |
||||
|
import crudOperation from '@crud/CRUD.operation' |
||||
|
import { getDicts } from '@/api/system/dict' |
||||
|
|
||||
|
const defaultForm = { |
||||
|
unified_key: '', |
||||
|
key: null, |
||||
|
value: null, |
||||
|
last_modify_date: null |
||||
|
} |
||||
|
export default { |
||||
|
dicts: [], |
||||
|
name: 'UdwData', |
||||
|
components: { pagination, crudOperation }, |
||||
|
mixins: [presenter(), header(), form(defaultForm), crud()], |
||||
|
cruds() { |
||||
|
return CRUD({ |
||||
|
title: '数据源', |
||||
|
url: 'api/udw/', |
||||
|
idField: 'key', |
||||
|
sort: 'key', |
||||
|
query: {}, |
||||
|
crudMethod: { ...crudUdwData }, |
||||
|
optShow: { |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
unified_key: [ |
||||
|
{ |
||||
|
value: '1', |
||||
|
label: 'opc_value' |
||||
|
}, |
||||
|
{ |
||||
|
value: '2', |
||||
|
label: 'cached' |
||||
|
}, |
||||
|
{ |
||||
|
value: '3', |
||||
|
label: 'socket' |
||||
|
} |
||||
|
], |
||||
|
permission: { |
||||
|
}, |
||||
|
dialogFormVisible: false, |
||||
|
rules: { |
||||
|
}, |
||||
|
form: { |
||||
|
unified_key: 'opc_value', |
||||
|
key: null, |
||||
|
value: null, |
||||
|
last_modify_date: null |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
created() { |
||||
|
getDicts().then(data => { |
||||
|
this.dicts = data |
||||
|
}) |
||||
|
}, |
||||
|
methods: { |
||||
|
// 钩子:在获取表格数据之前执行,false 则代表不获取数据 |
||||
|
[CRUD.HOOK.beforeRefresh]() { |
||||
|
return true |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.el-dropdown-link { |
||||
|
cursor: pointer; |
||||
|
color: #409EFF; |
||||
|
} |
||||
|
|
||||
|
.el-icon-arrow-down { |
||||
|
font-size: 12px; |
||||
|
} |
||||
|
</style> |
Loading…
Reference in new issue