bklLiudl
2024-09-03 efd177828ad3b7bbf04b2d48a118f2056abf0926
Admin.NET/WCS.Application/PLC/PLCTaskAction.cs
@@ -1,4 +1,5 @@
using Admin.NET.Core.Service;
using DocumentFormat.OpenXml.Drawing;
using Furion.Logging;
using Microsoft.AspNetCore.SignalR;
@@ -16,12 +17,13 @@
    private static readonly SysCacheService sysCacheService = App.GetRequiredService<SysCacheService>();
    private static readonly IHubContext<PlcHub, IPlcHub> _plcHubContext = App.GetService<IHubContext<PlcHub, IPlcHub>>();
    private static List<WcsPlc> listPlc;
    private static List<WcsDevice> listPlcDevice;
    private static List<WcsPosition> listPlcStation;
    private static List<WcsPlc> listPlc = new List<WcsPlc>();
    private static List<WcsDevice> listPlcDevice = new List<WcsDevice>();
    private static List<WcsPosition> listPlcStation = new List<WcsPosition>();
    private static List<WcsAlarmInfo> listAlarmInfo = new List<WcsAlarmInfo>();
    private static List<PLCUtil> listPlcUtil = new List<PLCUtil>();
    private static CancellationTokenSource cts;//取消线程标识
    private static CancellationTokenSource cts = new CancellationTokenSource();//取消线程标识
    //对外公布连接状态
    public static List<PLCUtil> listPlcConn
    {
@@ -32,10 +34,6 @@
    {
        //订阅事件
        DeviceValueChangeEvent += PLCService.OnChangeEvent;
        listPlc = _db.Queryable<WcsPlc>().ToList();
        listPlcDevice = _db.Queryable<WcsDevice>().ToList();
        listPlcStation = _db.Queryable<WcsPosition>().ToList();
    }
    /// <summary>
    /// 初始化PLC连接
@@ -48,6 +46,7 @@
            listPlc = _db.Queryable<WcsPlc>().Where(s => s.Type == PLCTypeEnum.StackingMachine || s.Type == PLCTypeEnum.ConveyorLine || s.Type == PLCTypeEnum.BoxConveyorLine).ToList();
            listPlcDevice = _db.Queryable<WcsDevice>().ToList();
            listPlcStation = _db.Queryable<WcsPosition>().ToList();
            listAlarmInfo = _db.Queryable<WcsAlarmInfo>().ToList();
            //等待几秒钟,把已有线程取消掉再连接
            Thread.Sleep(5000);
            foreach (var modPlcUtil in listPlcUtil)
@@ -64,6 +63,8 @@
        cts = new CancellationTokenSource();
        boRunningState = true;
        StartRead();
        ConnectionStatus();
        StartWatchAlarm();
    }
    /// <summary>
    /// 开启读取plc线程
@@ -82,9 +83,11 @@
                    {
                        foreach (var modPlcUtil in listPlcUtil)
                        {
                            modPlcUtil.Close();
                            if (modPlcUtil != null && modPlcUtil.Connected)
                                modPlcUtil.Close();
                        }
                        throw new OperationCanceledException();
                        break;
                        //throw new OperationCanceledException();
                    }
                    try
                    {
@@ -94,7 +97,7 @@
                            modPlcUtil = new PLCUtil(modPlc);
                            listPlcUtil.Add(modPlcUtil);
                        }
                        var listDevice = listPlcDevice.Where(s => s.PlcId == _modplc.Id).ToList();
                        var listDevice = listPlcDevice.Where(s => s.PlcId == _modplc.Id && s.DeviceType == DeviceTypeEnum.Business).ToList();
                        //循环读设备
                        foreach (var modDevice in listDevice.Where(s => s.Level == DeviceLevelEnum.DB))
                        {
@@ -109,9 +112,9 @@
                                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();
                                dto.listDevice = listDevice.Where(s => s.StationNum == modDevice.StationNum && s.Level == DeviceLevelEnum.Station).ToList();
                                //这里触发值变更事件
                                DeviceValueChangeEvent?.Invoke(dto, EventArgs.Empty);
                                //DeviceValueChangeEvent?.Invoke(dto, EventArgs.Empty);
                            }
                            else
                            {
@@ -146,35 +149,41 @@
        {
            try
            {
                //取消线程 关闭PLC连接
                if (cts.Token.IsCancellationRequested)
                while (true)
                {
                    foreach (var modPlcUtil in listPlcUtil)
                    //取消线程 关闭PLC连接
                    if (cts.Token.IsCancellationRequested)
                    {
                        modPlcUtil.Close();
                    }
                    throw new OperationCanceledException();
                }
                //获取每个PLC连接状态
                foreach (var modPlc in listPlc)
                {
                    var modPlcUtil = listPlcUtil.FirstOrDefault(s => s.PlcId == modPlc.Id);
                    if (modPlcUtil == null)
                        modPlc.IsConn = false;
                    else
                        modPlc.IsConn = modPlcUtil.Connected;
                    if (sysCacheService.ExistKey("PLCCONN" + modPlc.Id))
                    {
                        var cachePlc = sysCacheService.Get<WcsPlc>("PLCCONN" + modPlc.Id);
                        if (cachePlc.IsConn != modPlc.IsConn)
                        foreach (var modPlcUtil in listPlcUtil)
                        {
                            //连接状态变更 通知前端
                            _plcHubContext.Clients.All.PublicPlcConn(modPlc);
                            if (modPlcUtil != null && modPlcUtil.Connected)
                                modPlcUtil.Close();
                        }
                        break;
                        //throw new OperationCanceledException();
                    }
                    sysCacheService.Set("PLCCONN" + modPlc.Id, modPlc);
                    //获取每个PLC连接状态
                    foreach (var modPlc in listPlc)
                    {
                        var modPlcUtil = listPlcUtil.FirstOrDefault(s => s.PlcId == modPlc.Id);
                        if (modPlcUtil == null)
                            modPlc.IsConn = false;
                        else
                            modPlc.IsConn = modPlcUtil.Connected;
                        if (sysCacheService.ExistKey("PLCCONN" + modPlc.Id))
                        {
                            var cachePlc = sysCacheService.Get<WcsPlc>("PLCCONN" + modPlc.Id);
                            if (cachePlc.IsConn != modPlc.IsConn)
                            {
                                //连接状态变更 通知前端
                                _plcHubContext.Clients.All.PublicPlcConn(modPlc);
                            }
                        }
                        sysCacheService.Set("PLCCONN" + modPlc.Id, modPlc);
                    }
                    Thread.Sleep(1000);
                }
                Thread.Sleep(3000);
            }
            catch (OperationCanceledException)
            {
@@ -189,6 +198,70 @@
        });
    }
    /// <summary>
    /// 开启报警监控
    /// </summary>
    public static void StartWatchAlarm()
    {
        Task.Run(() =>
        {
            var listPlc = listAlarmInfo.GroupBy(s => new { s.PlcIP, s.PlcPort }).ToList();
            List<PLCUtil> listPlcUtil = new List<PLCUtil>();
            int i = 0;
            foreach (var modPlc in listPlc)
            {
                listPlcUtil.Add(new PLCUtil(new WcsPlc() { Id = i++, IP = modPlc.Key.PlcIP, Port = modPlc.Key.PlcPort, PLCType = PLCEnum.S7_1500 }));
            }
            while (true)
            {
                //取消线程 关闭PLC连接
                if (cts.Token.IsCancellationRequested)
                {
                    foreach (var modPlcUtil in listPlcUtil)
                    {
                        if (modPlcUtil != null && modPlcUtil.Connected)
                            modPlcUtil.Close();
                    }
                    break;
                    //throw new OperationCanceledException();
                }
                foreach (var modUtil in listPlcUtil)
                {
                    //报警点位
                    var listAlarm = listAlarmInfo.Where(s => s.PlcIP == modUtil.PlcId.ToString());
                    foreach (var modAlarm in listAlarm)
                    {
                        (var result, var value) = modUtil.GetPlcDBValue(PLCDataTypeEnum.Short, modAlarm.AlarmCode, "");
                        if (result.IsSucceed)
                        {
                            //假设不为0就算报警
                            if (value != 0)
                            {
                                //修改报警状态同时记录报警日志
                                modAlarm.AlarmTime = DateTime.Now;
                                modAlarm.Status = YesNoEnum.Y;
                                _db.Updateable(modAlarm).ExecuteCommand();
                                WcsAlarmLog modLog = modAlarm.Adapt<WcsAlarmLog>();
                                _db.Insertable(modLog).ExecuteCommand();
                                //下发报警状态
                                _plcHubContext.Clients.All.PublicAlarm(modAlarm.Adapt<WcsAlarmInfoOutput>());
                            }
                            //取消报警
                            else if (modAlarm.Status == YesNoEnum.Y)
                            {
                                modAlarm.AlarmTime = null;
                                modAlarm.Status = YesNoEnum.N;
                                _db.Updateable(modAlarm).ExecuteCommand();
                            }
                        }
                    }
                }
                Thread.Sleep(1000);
            }
        }, cts.Token);
    }
    /// <summary>
    /// 停止服务
    /// </summary>