using HMI.Core.Util;
|
using HslCommunication;
|
using HslCommunication.Core.Pipe;
|
using HslCommunication.Profinet.Siemens;
|
using PLCHelper.Entity;
|
using System;
|
using System.Collections.Concurrent;
|
using System.Collections.Generic;
|
using System.Collections.ObjectModel;
|
using System.IO;
|
|
namespace PLCHelper
|
{
|
public class S7Context
|
{
|
private static ConcurrentDictionary<string, SiemensS7Net> cache = new ConcurrentDictionary<string, SiemensS7Net>();
|
private static ConcurrentDictionary<SiemensS7Net, int> failedCount = new ConcurrentDictionary<SiemensS7Net, int>();
|
|
private static Dictionary<string, PLCTagData> dataCache = new Dictionary<string, PLCTagData>();
|
public static ObservableCollection<PLCTagData> Datasource = new ObservableCollection<PLCTagData>();
|
|
private static string Ip;
|
private static int Port;
|
|
private static readonly object lockObj = new object();
|
|
public static void Init(string ip, int port)
|
{
|
Ip = ip;
|
Port = port;
|
LoadTagData();
|
}
|
|
public static void LoadTagData()
|
{
|
lock (lockObj)
|
{
|
dataCache.Clear();
|
try
|
{
|
string path = Path.Combine(PathHelper.ConfigFolder, "CurrentSensorControl", "BurnInSettingData.data");
|
if (File.Exists(path))
|
{
|
Datasource = XmlHelper.DeserializeFromXml<ObservableCollection<PLCTagData>>(path);
|
}
|
else
|
{
|
Datasource = new ObservableCollection<PLCTagData>();
|
}
|
}
|
catch (Exception ex)
|
{
|
Datasource = new ObservableCollection<PLCTagData>();
|
}
|
foreach (var data in Datasource)
|
{
|
dataCache[data.Name] = data;
|
}
|
}
|
}
|
|
public static SiemensS7Net Get(string name)
|
{
|
if (!cache.ContainsKey(name))
|
{
|
var client = new SiemensS7Net(SiemensPLCS.S1500);
|
cache[name] = client;
|
PipeTcpNet pipeTcpNet = new PipeTcpNet(Ip, Port);
|
pipeTcpNet.ConnectTimeOut = 200;
|
pipeTcpNet.ReceiveTimeOut = 200;
|
client.CommunicationPipe = pipeTcpNet;
|
client.ConnectServer();
|
failedCount[client] = 0;
|
}
|
return cache[name];
|
}
|
|
private static bool GetS7Data(SiemensS7Net api, PLCTagData data, string name, out object val)
|
{
|
val = null;
|
string address = data.Address;
|
|
if (data.Type == PLCTagType.BOOL)
|
{
|
var res = api.ReadBool(address);
|
val = res.Content;
|
return res.IsSuccess;
|
}
|
else if (data.Type == PLCTagType.SHORT)
|
{
|
var res = api.ReadInt16(address);
|
val = res.Content;
|
return res.IsSuccess;
|
}
|
else if (data.Type == PLCTagType.INT)
|
{
|
var res = api.ReadInt32(address);
|
val = res.Content;
|
return res.IsSuccess;
|
}
|
else if (data.Type == PLCTagType.FLOAT)
|
{
|
var res = api.ReadFloat(address);
|
val = res.Content;
|
return res.IsSuccess;
|
}
|
return false;
|
}
|
|
public static bool GetData(SiemensS7Net api, string name, out object val)
|
{
|
val = null;
|
if (dataCache.ContainsKey(name))
|
{
|
var data = dataCache[name];
|
if (data.ConnectionType == ConnectionType.PLC_S7)
|
{
|
if (failedCount[api] >= 3)
|
{
|
return false;
|
}
|
var res = GetS7Data(api, data, name, out val);
|
if (!res) failedCount[api]++;
|
return res;
|
}
|
else if (data.ConnectionType == ConnectionType.MODBUS)
|
{
|
return ModbusHelper.ReadData(data, out val, out _);
|
}
|
else if (data.ConnectionType == ConnectionType.NXI_5010)
|
{
|
return NXI_5010Helper.ReadData(data, name, out val);
|
}
|
return false;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
|
public static bool GetData(string apiName, string name, out object val)
|
{
|
val = null;
|
if (dataCache.ContainsKey(name))
|
{
|
var data = dataCache[name];
|
if (data.ConnectionType == ConnectionType.PLC_S7)
|
{
|
var api = Get(apiName);
|
if (failedCount[api] >= 3)
|
{
|
return false;
|
}
|
var res = GetS7Data(api, data, name, out val);
|
if (!res) failedCount[api]++;
|
return res;
|
}
|
else if (data.ConnectionType == ConnectionType.MODBUS)
|
{
|
return ModbusHelper.ReadData(data, out val, out _);
|
}
|
else if (data.ConnectionType == ConnectionType.NXI_5010)
|
{
|
return NXI_5010Helper.ReadData(data, name, out val);
|
}
|
return false;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
|
private static bool WriteS7Data(SiemensS7Net api, PLCTagData data, string name, object val)
|
{
|
string address = data.Address;
|
OperateResult res;
|
switch (data.Type)
|
{
|
case PLCTagType.BOOL:
|
res = api.Write(address, (bool)val);
|
break;
|
case PLCTagType.SHORT:
|
res = api.Write(address, (short)val);
|
break;
|
case PLCTagType.USHORT:
|
res = api.Write(address, (ushort)val);
|
break;
|
case PLCTagType.INT:
|
res = api.Write(address, (int)val);
|
break;
|
case PLCTagType.FLOAT:
|
res = api.Write(address, (float)val);
|
break;
|
default:
|
return false;
|
}
|
return res.IsSuccess;
|
}
|
|
private static bool WriteS7Data2(SiemensS7Net api, PLCTagData data, string name, object val, out string errMsg)
|
{
|
errMsg = string.Empty;
|
string address = data.Address;
|
OperateResult res;
|
switch (data.Type)
|
{
|
case PLCTagType.BOOL:
|
res = api.Write(address, (bool)val);
|
break;
|
case PLCTagType.SHORT:
|
res = api.Write(address, (short)val);
|
break;
|
case PLCTagType.USHORT:
|
res = api.Write(address, (ushort)val);
|
break;
|
case PLCTagType.INT:
|
res = api.Write(address, (int)val);
|
break;
|
case PLCTagType.FLOAT:
|
res = api.Write(address, (float)val);
|
break;
|
default:
|
return false;
|
}
|
errMsg = res.Message;
|
return res.IsSuccess;
|
}
|
|
public static bool WriteData(SiemensS7Net api, string name, object val)
|
{
|
if (dataCache.ContainsKey(name))
|
{
|
var data = dataCache[name];
|
|
string address = data.Address;
|
if (data.ConnectionType == ConnectionType.PLC_S7)
|
{
|
if (failedCount[api] >= 3)
|
{
|
return false;
|
}
|
var res = WriteS7Data(api, data, name, val);
|
if (!res) failedCount[api]++;
|
return res;
|
}
|
else if (data.ConnectionType == ConnectionType.MODBUS)
|
{
|
return ModbusHelper.WriteData(data, val, out _);
|
}
|
return false;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
|
public static bool WriteData(string apiName, string name, object val, out string errMsg)
|
{
|
errMsg = string.Empty;
|
if (dataCache.ContainsKey(name))
|
{
|
var data = dataCache[name];
|
string address = data.Address;
|
if (data.ConnectionType == ConnectionType.PLC_S7)
|
{
|
var api = Get(apiName);
|
if (failedCount[api] >= 3)
|
{
|
errMsg = "超过重试次数";
|
return false;
|
}
|
var res = WriteS7Data2(api, data, name, val, out errMsg);
|
if (!res) failedCount[api]++;
|
return res;
|
}
|
else if (data.ConnectionType == ConnectionType.MODBUS)
|
{
|
return ModbusHelper.WriteData(data, val, out errMsg);
|
}
|
errMsg = "不支持的类型";
|
return false;
|
}
|
else
|
{
|
errMsg = $"未找到标签[{name}]";
|
return false;
|
}
|
}
|
|
public static void Release()
|
{
|
foreach (var client in cache.Values)
|
{
|
client.Dispose();
|
}
|
cache.Clear();
|
|
ModbusHelper.Release();
|
NXI_5010Helper.Release();
|
}
|
|
public static void ResetFailCount()
|
{
|
foreach (var client in failedCount.Keys)
|
{
|
failedCount[client] = 0;
|
}
|
}
|
}
|
}
|