BoardController.cs 19.6 KB
using DataAcquisition.Common.Enums;
using DataAcquisition.DataAccess;
using DataAcquisition.Models;
using DataAcquisition.Services;
using DataAcquisition.ViewModels.Board;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace DataAcquisition.ApiControllers
{
    /// <summary>
    /// 看板接口
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class BoardController : ControllerBase
    {
        private readonly IDbContextFactory<DataContext> _dbContextFactory;
        private readonly DataCacheService _dataCacheService;

        public BoardController(IDbContextFactory<DataContext> dbContextFactory, DataCacheService dataCacheService)
        {
            _dbContextFactory = dbContextFactory;
            _dataCacheService = dataCacheService;
        }

        /// <summary>
        /// 焊接看板
        /// </summary>
        /// <param name="robotNo">机器人编号</param>
        /// <returns></returns>
        [HttpGet]
        [Route("WeldBoard/{robotNo:int}")]
        public ActionResult<BoardResult<dynamic>> GetWeldBoard1Data(int robotNo = 1)
        {
            var result = new BoardResult<dynamic>();
            try
            {
                //本月开始时间
                var monthStartTime = DateTime.Today.AddDays(1 - DateTime.Today.Day).Date;
                using var context = _dbContextFactory.CreateDbContext();
                var robotEquipment = robotNo switch
                {
                    1 => _dataCacheService.Equipments.Find(x => x.Code == EquipmentConst.Kuka_1.ToString())!,
                    2 => _dataCacheService.Equipments.Find(x => x.Code == EquipmentConst.Kuka_2.ToString())!,
                    3 => _dataCacheService.Equipments.Find(x => x.Code == EquipmentConst.Kuka_3.ToString())!,
                    4 => _dataCacheService.Equipments.Find(x => x.Code == EquipmentConst.Kuka_4.ToString())!,
                    5 => _dataCacheService.Equipments.Find(x => x.Code == EquipmentConst.Efort_1.ToString())!,
                    6 => _dataCacheService.Equipments.Find(x => x.Code == EquipmentConst.Fanuc_1.ToString())!,
                    _ => throw new NotImplementedException($"未找到编号为“{robotNo}”的设备数据!"),
                };
                var plc = robotNo switch
                {
                    1 or 2 => _dataCacheService.Equipments.Find(x => x.Code == EquipmentConst.SiemensPLC_1.ToString())!,
                    3 => _dataCacheService.Equipments.Find(x => x.Code == EquipmentConst.SiemensPLC_2.ToString())!,
                    4 => _dataCacheService.Equipments.Find(x => x.Code == EquipmentConst.SiemensPLC_3.ToString())!,
                    5 => _dataCacheService.Equipments.Find(x => x.Code == EquipmentConst.SiemensPLC_4.ToString())!,
                    6 => _dataCacheService.Equipments.Find(x => x.Code == EquipmentConst.SiemensPLC_5.ToString())!,
                    _ => throw new NotImplementedException($"未找到编号为“{robotNo}”的PLC设备数据!"),
                };

                _ = double.TryParse(robotEquipment[RobotProps.Pos_X.ToString()].Value, out var pos_X);
                _ = double.TryParse(robotEquipment[RobotProps.Pos_Y.ToString()].Value, out var pos_Y);
                _ = double.TryParse(robotEquipment[RobotProps.Pos_Z.ToString()].Value, out var pos_Z);
                _ = double.TryParse(robotEquipment[RobotProps.Pos_A.ToString()].Value, out var pos_A);
                _ = double.TryParse(robotEquipment[RobotProps.Pos_B.ToString()].Value, out var pos_B);
                _ = double.TryParse(robotEquipment[RobotProps.Pos_C.ToString()].Value, out var pos_C);
                _ = double.TryParse(robotEquipment[RobotProps.Pos_E1.ToString()].Value, out var pos_E1);
                _ = double.TryParse(robotEquipment[RobotProps.Pos_E2.ToString()].Value, out var pos_E2);
                _ = double.TryParse(robotEquipment[RobotProps.Pos_E3.ToString()].Value, out var pos_E3);
                _ = double.TryParse(robotEquipment[RobotProps.Pos_E4.ToString()].Value, out var pos_E4);

                _ = bool.TryParse(robotEquipment[RobotProps.Weld_CleanGun.ToString()].Value, out var weld_CleanGun);
                _ = bool.TryParse(robotEquipment[RobotProps.WeldFlag.ToString()].Value, out var weldFlag);
                _ = bool.TryParse(robotEquipment[RobotProps.Weld_Gas.ToString()].Value, out var weld_Gas);
                _ = bool.TryParse(robotEquipment[RobotProps.WeldCompleteFlag.ToString()].Value, out var weldCompleteFlag);
                _ = bool.TryParse(robotEquipment[RobotProps.BootFlag.ToString()].Value, out var bootFalgValue);
                _ = bool.TryParse(robotEquipment[RobotProps.Alarm.ToString()].Value, out var alarmValue);
                _ = bool.TryParse(robotEquipment[RobotProps.WorkFlag.ToString()].Value, out var workFlagValue);

                _ = float.TryParse(robotEquipment[RobotProps.Weld_V.ToString()].Value, out var weld_V);
                _ = float.TryParse(robotEquipment[RobotProps.Weld_I.ToString()].Value, out var weld_I);
                _ = float.TryParse(robotEquipment[RobotProps.Weld_Speed.ToString()].Value, out var weld_Speed);
                _ = int.TryParse(robotEquipment[RobotProps.Work_Mode.ToString()].Value, out var work_Mode);
                _ = int.TryParse(robotEquipment[RobotProps.Program_No.ToString()].Value, out var program_no);
                _ = int.TryParse(robotEquipment[RobotProps.Type.ToString()].Value, out var type);

                var equipmentState = "在线";
                if (!bootFalgValue)
                {
                    equipmentState = "离线";
                }
                //仅自动模式显示
                else if (alarmValue && work_Mode >= 3)
                {
                    equipmentState = "报警";
                }
                else if (workFlagValue)
                {
                    equipmentState = "工作";
                }

                //加工状态
                var productStateName = "空闲";
                var timeSum = 0d;
                if (weldFlag)
                {
                    productStateName = weldCompleteFlag ? "加工" : "完工";
                    timeSum = Math.Round(TimeSpan.FromTicks(context.WorkpieceProcessingRecords.Where(x => x.EquipmentCode == robotEquipment.Code && x.ProgramNo == type).OrderByDescending(x => x.CreateTime).Select(x => x.UpdateTime.Ticks - x.CreateTime.Ticks).FirstOrDefault()).TotalMinutes, 2);
                }

                //功率
                double kw = 0;
                if (1 <= robotNo && robotNo <= 4)
                {
                    _ = double.TryParse(plc[SiemensPLCProps.P_KW.ToString()].Value, out kw);
                }

                var days = 7;//显示最近N天的数据
                var xAxisData = Enumerable.Range(0, days).Select(x => DateTime.Today.AddDays(-x)).OrderBy(x => x).ToList();
                var bootFalgTicks = context.EquipmentPropertyRecords.Where(x => x.EquipmentCode == robotEquipment.Code && x.EquipmentPropertyCode == RobotProps.BootFlag.ToString()).Sum(x => x.UpdateTime.Ticks - x.CreateTime.Ticks);
                var vm = new Board1VM
                {
                    NowDayCountLeft = new NowDayCountLeft
                    {
                        WorkTime = Math.Round(TimeSpan.FromTicks(context.EquipmentPropertyRecords.Where(x => x.EquipmentCode == robotEquipment.Code && x.EquipmentPropertyCode == RobotProps.WorkFlag.ToString() && x.CreateTime >= DateTime.Today).Sum(x => x.UpdateTime.Ticks - x.CreateTime.Ticks)).TotalHours, 2),

                        ArcingTime = Math.Round(TimeSpan.FromTicks(context.EquipmentPropertyRecords.Where(x => x.EquipmentCode == robotEquipment.Code && x.EquipmentPropertyCode == RobotProps.WeldFlag.ToString() && x.CreateTime >= DateTime.Today).Sum(x => x.UpdateTime.Ticks - x.CreateTime.Ticks)).TotalHours, 2),

                        FinishCount = context.WorkpieceProcessingRecords.Where(x => x.EquipmentCode == robotEquipment.Code && x.CreateTime >= DateTime.Today && x.IsEnd).Count(),

                        PowerTime = Math.Round(TimeSpan.FromTicks(context.EquipmentPropertyRecords.Where(x => x.EquipmentCode == robotEquipment.Code && x.EquipmentPropertyCode == RobotProps.BootFlag.ToString() && x.CreateTime >= DateTime.Today).Sum(x => x.UpdateTime.Ticks - x.CreateTime.Ticks)).TotalHours, 2)
                    },
                    EqCenter = new EquipmentStatusVM
                    {
                        EqCode = robotEquipment.Code,
                        EqName = robotEquipment.Name,
                        EqState = equipmentState,
                        Eqmode = work_Mode switch
                        {
                            1 => "T1模式",
                            2 => "T2模式",
                            3 => "自动模式",
                            4 => "外部自动模式",
                            _ => "无数据"
                        },
                        MonthDaoDian = $"0/个",

                        MonthWeld = Math.Round(context.EquipmentPropertyRecords.Where(x => x.EquipmentCode == robotEquipment.Code && x.EquipmentPropertyCode == RobotProps.Weld_Speed.ToString() && x.CreateTime >= monthStartTime).Select(x => x.Value).AsEnumerable().Sum(Convert.ToSingle), 2),

                        MonthVoltage = Math.Round(context.EquipmentPropertyRecords.Where(x => x.EquipmentCode == plc.Code && x.EquipmentPropertyCode == SiemensPLCProps.Electricity.ToString() && x.CreateTime >= monthStartTime).Select(x => x.Value).AsEnumerable().Sum(Convert.ToSingle), 2),

                        NowDayVoltage = Math.Round(context.EquipmentPropertyRecords.Where(x => x.EquipmentCode == plc.Code && x.EquipmentPropertyCode == SiemensPLCProps.Electricity.ToString() && x.CreateTime >= DateTime.Today).Select(x => x.Value).AsEnumerable().Sum(Convert.ToSingle), 2),

                        MonthWeldVoltage = Math.Round(context.EquipmentPropertyRecords.Where(x => x.EquipmentCode == robotEquipment.Code && x.EquipmentPropertyCode == $"{RobotProps.WeldFlag}_{SiemensPLCProps.Electricity}" && x.CreateTime >= monthStartTime).Select(x => x
                        .Value).AsEnumerable().Sum(Convert.ToSingle), 2),

                        TodayWeldVoltage = Math.Round(context.EquipmentPropertyRecords.Where(x => x.EquipmentCode == robotEquipment.Code && x.EquipmentPropertyCode == $"{RobotProps.WeldFlag}_{SiemensPLCProps.Electricity}" && x.CreateTime >= DateTime.Today).Select(x => x
                        .Value).AsEnumerable().Sum(Convert.ToSingle), 2),

                        MonthGas = $"{context.EquipmentPropertyRecords.Where(x => x.EquipmentCode == robotEquipment.Code && x.EquipmentPropertyCode == RobotProps.Gas_Flow.ToString() && x.CreateTime >= monthStartTime).Select(x => x.Value).AsEnumerable().Sum(Convert.ToSingle):N2}/L",

                        P_KW = kw,
                    },
                    MonthCountRight = new MonthCountRight
                    {
                        WorkTime = Math.Round(TimeSpan.FromTicks(context.EquipmentPropertyRecords.Where(x => x.EquipmentCode == robotEquipment.Code && x.EquipmentPropertyCode == RobotProps.WorkFlag.ToString() && x.CreateTime >= monthStartTime).Sum(x => x.UpdateTime.Ticks - x.CreateTime.Ticks)).TotalHours, 2),

                        ArcingTime = Math.Round(TimeSpan.FromTicks(context.EquipmentPropertyRecords.Where(x => x.EquipmentCode == robotEquipment.Code && x.EquipmentPropertyCode == RobotProps.WeldFlag.ToString() && x.CreateTime >= monthStartTime).Sum(x => x.UpdateTime.Ticks - x.CreateTime.Ticks)).TotalHours, 2),

                        PowerTime = Math.Round(TimeSpan.FromTicks(context.EquipmentPropertyRecords.Where(x => x.EquipmentCode == robotEquipment.Code && x.EquipmentPropertyCode == RobotProps.BootFlag.ToString() && x.CreateTime >= monthStartTime).Sum(x => x.UpdateTime.Ticks - x.CreateTime.Ticks)).TotalHours, 2),

                        AlarmTime = Math.Round(TimeSpan.FromTicks(context.EquipmentPropertyRecords.Where(x => x.EquipmentCode == robotEquipment.Code && x.EquipmentPropertyCode == RobotProps.Alarm.ToString() && x.CreateTime >= monthStartTime).Sum(x => x.UpdateTime.Ticks - x.CreateTime.Ticks)).TotalHours, 2),
                    },

                    EqInfoLeft = new EquipmentInfoLeftVM
                    {
                        ClearSpearState = weld_CleanGun,
                        ArcingState = weldFlag,
                        AspiratedState = weld_Gas,
                        NowProject = type == 0 ? "无" : $"程序{type}",
                        ProjectRow = program_no,
                        X = Math.Round(pos_X, 1),
                        Y = Math.Round(pos_Y, 1),
                        Z = Math.Round(pos_Z, 1),
                        A = Math.Round(pos_A, 1),
                        B = Math.Round(pos_B, 1),
                        C = Math.Round(pos_C, 1),
                        E1 = Math.Round(pos_E1, 1),
                        E2 = Math.Round(pos_E2, 1),
                        E3 = Math.Round(pos_E3, 1),
                        E4 = Math.Round(pos_E4, 1),
                        SsSpeed = Math.Round(weld_Speed, 1),
                        Current = Math.Round(weld_I, 1),
                        Voltage = Math.Round(weld_V, 1),
                    },
                    EqInfoRight = new EquipmentInfoRight
                    {
                        EfficiencyList = new Efficiency
                        {
                            Arcing = xAxisData.Select(x => Convert.ToInt32(TimeSpan.FromTicks(context.EquipmentPropertyRecords.Where(r => r.EquipmentCode == robotEquipment.Code && r.EquipmentPropertyCode == RobotProps.WeldFlag.ToString() && r.CreateTime.Date == x).Sum(r => r.UpdateTime.Ticks - r.CreateTime.Ticks)).TotalMinutes)).ToList(),

                            PowerOn = xAxisData.Select(x => Convert.ToInt32(TimeSpan.FromTicks(context.EquipmentPropertyRecords.Where(r => r.EquipmentCode == robotEquipment.Code && r.EquipmentPropertyCode == RobotProps.BootFlag.ToString() && r.CreateTime.Date == x).Sum(r => r.UpdateTime.Ticks - r.CreateTime.Ticks)).TotalMinutes)).ToList(),

                            Work = xAxisData.Select(x => Convert.ToInt32(TimeSpan.FromTicks(context.EquipmentPropertyRecords.Where(r => r.EquipmentCode == robotEquipment.Code && r.EquipmentPropertyCode == RobotProps.Work_Time.ToString() && r.CreateTime.Date == x).Sum(r => r.UpdateTime.Ticks - r.CreateTime.Ticks)).TotalMinutes)).ToList(),
                            XAxisData = xAxisData.Select(x => x.ToString("M")).ToList(),
                        },
                        WeldFlagData = xAxisData.Select(x => new BoardChart
                        {
                            Name = x.ToString("M"),
                            Value = GetWeldFlagRate(context, robotEquipment, x)
                        }).ToList(),
                        ProductInfo = type.ToString(),
                        ProductState = productStateName,
                        TimeSum = timeSum,
                        YieldList = new YieldListVM
                        {
                            XAxisData = xAxisData.Select(x => x.ToString("M")).ToList(),
                            Yield = xAxisData.Select(x => context.WorkpieceProcessingRecords.Where(w => w.EquipmentCode == robotEquipment.Code && w.CreateTime.Date == x.Date && w.IsEnd).Count()).ToList(),
                        }
                    },

                    CurrentList = Math.Round(weld_I, 1),
                    EqEfficiencyCenter = new EquipmentEfficiencyCenter
                    {
                        AlarmRate = GetAlarmRate(context, robotEquipment),
                        AutoRate = GetAutoRate(context, robotEquipment),
                        OnLineRate = GetOnLineRate(context, robotEquipment),
                        UtilizeRate = UtilizeRate(context, robotEquipment),
                    },
                    VoltagetList = Math.Round(weld_V, 1),
                };

                //故障率
                int GetAlarmRate(DataContext context, Equipment robotEquipment)
                {
                    if (bootFalgTicks == 0) return 0;
                    return Convert.ToInt32(context.EquipmentPropertyRecords.Where(x => x.EquipmentCode == robotEquipment.Code && x.EquipmentPropertyCode == RobotProps.Alarm.ToString()).Sum(x => x.UpdateTime.Ticks - x.CreateTime.Ticks) * 100 / bootFalgTicks);
                }

                int UtilizeRate(DataContext context, Equipment robotEquipment)
                {
                    if (bootFalgTicks == 0) return 0;
                    return Convert.ToInt32(context.EquipmentPropertyRecords.Where(x => x.EquipmentCode == robotEquipment.Code && x.EquipmentPropertyCode == RobotProps.WorkFlag.ToString()).Sum(x => x.UpdateTime.Ticks - x.CreateTime.Ticks) * 100 / bootFalgTicks);
                }

                int GetAutoRate(DataContext context, Equipment robotEquipment)
                {
                    if (bootFalgTicks == 0) return 0;
                    return Convert.ToInt32(context.EquipmentPropertyRecords.Where(x => x.EquipmentCode == robotEquipment.Code && x.EquipmentPropertyCode == RobotProps.WeldFlag.ToString()).Sum(x => x.UpdateTime.Ticks - x.CreateTime.Ticks) * 100 / bootFalgTicks);
                }

                //在线率
                int GetOnLineRate(DataContext context, Equipment robotEquipment)
                {
                    var bootFlagStartDay = context.EquipmentPropertyRecords.Where(x => x.EquipmentCode == robotEquipment.Code && x.EquipmentPropertyCode == RobotProps.BootFlag.ToString()).OrderBy(x => x.CreateTime).Select(x => x.CreateTime).FirstOrDefault();
                    if (bootFlagStartDay == default) return 0;
                    else if (bootFlagStartDay <= DateTime.Today.AddMonths(-1))
                    {
                        bootFlagStartDay = DateTime.Today.AddMonths(-1);
                    }
                    return Convert.ToInt32(context.EquipmentPropertyRecords.Where(x => x.EquipmentCode == robotEquipment.Code && x.EquipmentPropertyCode == RobotProps.BootFlag.ToString()).Sum(x => x.UpdateTime.Ticks - x.CreateTime.Ticks) * 100 / (DateTime.Now - bootFlagStartDay).Ticks);
                }

                //燃弧率
                int GetWeldFlagRate(DataContext context, Equipment robotEquipment, DateTime date)
                {
                    var weldTicks = context.EquipmentPropertyRecords.Where(p => p.EquipmentCode == robotEquipment.Code && p.EquipmentPropertyCode == RobotProps.WeldFlag.ToString() && p.CreateTime.Date == date).Sum(s => s.UpdateTime.Ticks - s.CreateTime.Ticks);
                    if (weldTicks == 0) return 0;
                    var runTicks = context.EquipmentPropertyRecords.Where(p => p.EquipmentCode == robotEquipment.Code && p.EquipmentPropertyCode == RobotProps.BootFlag.ToString() && p.CreateTime.Date == date).Sum(s => s.UpdateTime.Ticks - s.CreateTime.Ticks);
                    return Convert.ToInt32(weldTicks * 100 / runTicks);
                };

                result.Data = new
                {
                    Head = new
                    {
                        vm.NowDayCountLeft,
                        vm.EqCenter,
                        vm.MonthCountRight,
                    },
                    Center = new
                    {
                        vm.EqInfoLeft,
                        vm.EqInfoRight,
                    },
                    Footer = new
                    {
                        vm.CurrentList,
                        vm.EqEfficiencyCenter,
                        vm.VoltagetList,
                    }
                };
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.Message;
            }
            return Ok(result);
        }
    }
}