|
|
using HighWayIot.Config;
|
|
|
using HighWayIot.Log4net;
|
|
|
using HighWayIot.Plc.Impl;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Threading.Tasks;
|
|
|
using System.Timers;
|
|
|
|
|
|
namespace HighWayIot.Plc
|
|
|
{
|
|
|
public sealed class PlcPool
|
|
|
{
|
|
|
private AppConfig appConfig = AppConfig.Instance;
|
|
|
|
|
|
private PlcConfig plcConfig = PlcConfig.Instance;
|
|
|
|
|
|
|
|
|
private static readonly Lazy<PlcPool> lazy = new Lazy<PlcPool>(() => new PlcPool());
|
|
|
public static PlcPool Instance
|
|
|
{
|
|
|
get
|
|
|
{
|
|
|
return lazy.Value;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private LogHelper logHelper = LogHelper.Instance;
|
|
|
|
|
|
public Dictionary<string, IPlc> keyValuePairs = new Dictionary<string, IPlc>();
|
|
|
|
|
|
private PlcPool() { }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 初始化Plc
|
|
|
/// </summary>
|
|
|
/// <param name="plcType"></param>
|
|
|
/// <param name="ip"></param>
|
|
|
/// <param name="port"></param>
|
|
|
/// <param name="key"></param>
|
|
|
public async void InitPlc(string plcType, string ip, int port, string key)
|
|
|
{
|
|
|
if (!keyValuePairs.ContainsKey(key))
|
|
|
{
|
|
|
IPlc _plc = null;
|
|
|
switch (plcType)
|
|
|
{
|
|
|
case "InovancePlc":
|
|
|
_plc = new InovancePlc();
|
|
|
break;
|
|
|
case "MelsecBinaryPlc":
|
|
|
_plc = new MelsecBinaryPlc();
|
|
|
break;
|
|
|
case "OmronNJPlc":
|
|
|
_plc = new OmronNJPlc();
|
|
|
break;
|
|
|
case "SiemensPlc":
|
|
|
_plc = new SiemensPlc();
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
var connectResult = _plc.Connect(ip, port);
|
|
|
if (connectResult)
|
|
|
{
|
|
|
keyValuePairs.Add(key, _plc);
|
|
|
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#region 心跳
|
|
|
public async Task StartMelsecPlcAsync()
|
|
|
{
|
|
|
System.Timers.Timer timer = new System.Timers.Timer(3000);
|
|
|
timer.Elapsed += new System.Timers.ElapsedEventHandler(ExecMelsecMcHeartTask); //到达时间的时候执行事件;
|
|
|
timer.AutoReset = true;//设置是执行一次(false)还是一直执行(true);
|
|
|
timer.Enabled = true;//需要调用 timer.Start()或者timer.Enabled = true来启动它,
|
|
|
timer.Start();//timer.Start()的内部原理还是设置timer.Enabled = true;
|
|
|
await Task.CompletedTask;
|
|
|
}
|
|
|
|
|
|
private async void ExecMelsecMcHeartTask(object sender, ElapsedEventArgs e)
|
|
|
{
|
|
|
if (keyValuePairs.Count == 0)
|
|
|
{
|
|
|
this.InitPlc("MelsecBinaryPlc", plcConfig.foam_Plc_Ip, plcConfig.foam_Plc_Port, appConfig.foamStoreCode);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
IPlc _plc = keyValuePairs[appConfig.foamStoreCode];
|
|
|
if (_plc != null)
|
|
|
{
|
|
|
var result = _plc.ReadHeart("M100").Result;
|
|
|
if (result)
|
|
|
{
|
|
|
logHelper.Info("PLC连接成功!");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
logHelper.Info("PLC连接失败!");
|
|
|
keyValuePairs.Clear();
|
|
|
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取PLC
|
|
|
/// </summary>
|
|
|
/// <param name="key"></param>
|
|
|
/// <returns></returns>
|
|
|
public IPlc GetPlcByKey(string key)
|
|
|
{
|
|
|
return keyValuePairs[key];
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取所有PLC信息
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
public Dictionary<string, IPlc> GetAll()
|
|
|
{
|
|
|
return keyValuePairs;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 关闭所有连接
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
public bool disConnectAll()
|
|
|
{
|
|
|
bool result = false;
|
|
|
try
|
|
|
{
|
|
|
foreach (var kv in keyValuePairs)
|
|
|
{
|
|
|
if (kv.Value != null)
|
|
|
{
|
|
|
kv.Value.DisConnect();
|
|
|
}
|
|
|
}
|
|
|
result = true;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
logHelper.Error("关闭PLC连接异常", ex);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
}
|
|
|
}
|