using Furion.Logging;
|
using Microsoft.AspNetCore.SignalR;
|
|
namespace WCS.Application;
|
public static class PLCTaskAction
|
{
|
//服务运行状态
|
public static bool boRunningState = false;
|
|
private static readonly ISqlSugarClient _db = SqlSugarSetup.ITenant.GetConnectionScope(SqlSugarConst.MainConfigId);
|
|
private static List<WcsPlc> listPlc;
|
private static List<WcsDevice> listPlcDevice;
|
private static List<WcsPosition> listPlcStation;
|
|
private static List<PLCUtil> listPlcUtil = new List<PLCUtil>();
|
private static CancellationTokenSource cts;//取消线程标识
|
|
public static event EventHandler DeviceValueChangeEvent;
|
static PLCTaskAction()
|
{
|
//订阅事件
|
DeviceValueChangeEvent += PLCService.OnChangeEvent;
|
|
listPlc = _db.Queryable<WcsPlc>().ToList();
|
listPlcDevice = _db.Queryable<WcsDevice>().ToList();
|
listPlcStation = _db.Queryable<WcsPosition>().ToList();
|
}
|
/// <summary>
|
/// 初始化PLC连接
|
/// </summary>
|
public static void Init()
|
{
|
if (listPlcUtil.Count != 0)
|
{
|
cts.Cancel();
|
listPlc = _db.Queryable<WcsPlc>().ToList();
|
listPlcDevice = _db.Queryable<WcsDevice>().ToList();
|
listPlcStation = _db.Queryable<WcsPosition>().ToList();
|
//等待几秒钟,把已有线程取消掉再连接
|
Thread.Sleep(5000);
|
foreach (var modPlcUtil in listPlcUtil)
|
{
|
modPlcUtil.Close();
|
}
|
listPlcUtil.Clear();
|
}
|
foreach (var modPlc in listPlc)
|
{
|
var plc = new PLCUtil(modPlc);
|
listPlcUtil.Add(plc);
|
}
|
cts = new CancellationTokenSource();
|
boRunningState = true;
|
StartRead();
|
}
|
/// <summary>
|
/// 开启读取plc线程
|
/// </summary>
|
public static void StartRead()
|
{
|
foreach (var modPlc in listPlc)
|
{
|
Task.Run(() =>
|
{
|
var _modplc = modPlc;
|
while (true)
|
{
|
//取消线程 关闭PLC连接
|
if (cts.Token.IsCancellationRequested)
|
{
|
foreach (var modPlcUtil in listPlcUtil)
|
{
|
modPlcUtil.Close();
|
}
|
throw new OperationCanceledException();
|
}
|
try
|
{
|
var modPlcUtil = listPlcUtil.FirstOrDefault(s => s.PlcId == modPlc.Id);
|
if (modPlcUtil == null)
|
{
|
modPlcUtil = new PLCUtil(modPlc);
|
listPlcUtil.Add(modPlcUtil);
|
}
|
var listDevice = listPlcDevice.Where(s => s.PlcId == _modplc.Id).ToList();
|
//循环读设备
|
foreach (var modDevice in listDevice.Where(s => s.Level == DeviceLevelEnum.DB))
|
{
|
var (result, value) = modPlcUtil.GetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.PlcPos);
|
if (result.IsSucceed)
|
{
|
//无流程跳出
|
if (value == 0)
|
continue;
|
var dto = modDevice.Adapt<WcsDeviceDto>();
|
dto.Value = value;
|
dto.Type = _modplc.Type;
|
dto.PLCUtil = modPlcUtil;
|
dto.listStation = listPlcStation.Where(s => s.DeviceId == modDevice.Id).ToList();
|
dto.listDevice = listDevice.Where(s => s.StationNum == modDevice.StationNum).ToList();
|
//这里触发值变更事件
|
DeviceValueChangeEvent?.Invoke(dto, EventArgs.Empty);
|
}
|
else
|
{
|
//删除当前连接 下一次循环重新连接
|
Console.WriteLine("连接断开...");
|
modPlcUtil.Close();
|
listPlcUtil.Remove(modPlcUtil);
|
}
|
}
|
|
Thread.Sleep(3000);
|
}
|
catch (OperationCanceledException)
|
{
|
Console.WriteLine("中止线程");
|
}
|
catch (Exception ex)
|
{
|
Log.Error(ex.Message, ex);
|
}
|
}
|
}, cts.Token);
|
}
|
}
|
/// <summary>
|
/// 停止服务
|
/// </summary>
|
public static void Stop()
|
{
|
cts.Cancel();
|
boRunningState = false;
|
}
|
}
|