Program.cs 7.89 KB
using HHECS.DAQHandle.Common.Enums;
using HHECS.DAQHandle.Common.Utils;
using HHECS.DAQHandle.DataAccess;
using HHECS.DAQHandle.Dto;
using HHECS.DAQHandle.EquipmentHandle;
using HHECS.DAQHandle.Models;
using HHECS.EquipmentModel;
using System.Configuration;
using System.Diagnostics;
using System.Xml.Linq;

internal class Program
{
    /// <summary>
    /// 单次处理的数据量
    /// </summary>
    private const int _limit = 100;
    private static long LastEquipmentCount = 0;
    private static long LastEquipmentPropTempCount = 0;
    private static List<EquipmentType> EquipmentTypes;
    //设备缓存数据
    public static Dictionary<string, EquipmentInfoDto> EquipmentInfos;


    private static void Main(string[] args)
    {
        try
        {
            Console.Title = "IOT数据处理端";

            var warehouseCode = ConfigurationManager.AppSettings["WarehouseCode"];
            if (string.IsNullOrWhiteSpace(warehouseCode))
            {
                SystemLog.PrintWarn("仓库编号未配置!");
                return;
            }

            var equipmentTypeCodes = ConfigurationManager.AppSettings["EquipmentType"].Split(',').ToList();
            if (equipmentTypeCodes == null || equipmentTypeCodes.Count == 0)
            {
                SystemLog.PrintWarn("设备类型未配置!");
                return;
            }

            using var context = new DataContext();
            EquipmentTypes = context.EquipmentType.Where(x => equipmentTypeCodes.Contains(x.Code)).IncludeMany(x => x.EquipmentTypePropTemplates).ToList();

            //刷新模板数据
            Task.Run(async () =>
            {
                while (true)
                {
                    try
                    {
                        if (IsDataChange())
                        {
                            InitData();
                        }
                        await Task.Delay(1000 * 60);
                    }
                    catch (Exception ex)
                    {
                        SystemLog.PrintError($"{ex}");
                    }

                }
            });


            Startup(EquipmentTypes);
        }
        catch (Exception ex)
        {
            SystemLog.PrintWarn($"程序启动出现异常:{ex.Message}");
        }
    }

    private static void Startup(IEnumerable<EquipmentType> equipmentTypes)
    {
        while (true)
        {
            try
            {
                var tasks = new List<Task>();
                foreach (var item in equipmentTypes)
                {
                    tasks.Add(Task.Run(() =>
                    {
                        Stopwatch stopwatch = Stopwatch.StartNew();
                        _ = Enum.TryParse<EquipmentTypeConst>(item.Code, out var equipmentTypeCode);
                        IAnalysis handle = equipmentTypeCode switch
                        {
                            EquipmentTypeConst.SingleForkSRM => new SingleForkSRMAnalysis(item),
                            EquipmentTypeConst.DoubleForkSRM => new DoubleForkSRMAnalysis(item),
                            EquipmentTypeConst.SingleForkSSRM => new SingleForkSSRMAnalysis(item),
                            EquipmentTypeConst.SingleForkSSRMV132 => new SingleForkSSRMV132Analysis(item),
                            EquipmentTypeConst.WeldRobot => new WeldRobotAnalysis(item),
                            EquipmentTypeConst.AGV => new AGVAnalysis(item),
                            EquipmentTypeConst.RGVStation => new RGVAnalysis(item),
                            EquipmentTypeConst.StationMonitor => new StationMonitorAnalysis(item),
                            _ => null
                        };
                        //未知类型,则跳过
                        if (handle is null)
                        {
                            SystemLog.PrintWarn($"未实现设备类型[{item.Code}]对应的处理方法");
                            return;
                        }
                        using var context = new DataContext();
                        var equipmentCodes = context.Equipment.Where(x => x.EquipmentTypeId == item.Id).ToList(x => x.Code);
                        var equipmentDataRecords = context.EquipmentDataRecord.Where(x => equipmentCodes.Contains(x.EquipmentCode) && !x.IsHandle).OrderBy(x => x.Timestamp).Take(_limit).ToList();
                        //if (equipmentDataRecords.Count == 0)
                        //{
                        //    SystemLog.PrintInfo($"设备类型[{item.Code}]队列数据为空,跳过解析");
                        //    return;
                        //}

                        var result = handle.Execute(equipmentDataRecords);
                        stopwatch.Stop();
                        if (!result.Success)
                        {
                            SystemLog.PrintError($"设备类型[{item.Code}]解析失败,{result.Msg},数量{equipmentDataRecords.Count},耗时{stopwatch.ElapsedMilliseconds}ms");
                            return;
                        }
                        SystemLog.PrintInfo($"设备类型[{item.Code}]解析完成,数量{equipmentDataRecords.Count},耗时{stopwatch.ElapsedMilliseconds}ms");
                    }));
                }
                Task.WaitAll(tasks.ToArray());
                Console.WriteLine($"————————————————————————————————————————————————————————");
            }
            catch (Exception ex)
            {
                SystemLog.PrintError($"程序异常:{ex}");
            }
        }
    }
    /// <summary>
    /// 初始化设备数据,并进行缓存
    /// </summary>
    private static void InitData()
    {

        using var context = new DataContext();
        var equipments = context.Equipment.Where(x => true).IncludeMany(x => x.EquipmentProps).Include(x=>x.EquipmentType).ToList();

        var equipmentPropTemps = context.EquipmentTypePropTemplate.Where(x => EquipmentTypes.Any(y => y.Id == x.EquipmentTypeId)).ToList();


        EquipmentInfos = equipments.Select(equipment => new EquipmentInfoDto()
        {
            Id = equipment.Id,
            Code = equipment.Code,
            Name = equipment.Name,
            EquipmentType = equipment.EquipmentType,
            //EquipmentPropTemps = x.EquipmentProps.Select(prop => new{prop.Address,Value=eq})
            EquipmentPropTemps =
            //equipment.EquipmentProps.ToDictionary(prop => prop.Address,
            //                               prop => equipmentPropTemps.Find(temp => temp.Code == prop.EquipmentTypePropTemplateCode)?.MonitorCompareValue)
            equipment.EquipmentProps.Select(prop =>
            {
                var temp = equipmentPropTemps.Find(temp => temp.Code == prop.EquipmentTypePropTemplateCode);
                if (temp == null)
                {
                    SystemLog.PrintError($"设备{equipment.Name}的属性{prop.EquipmentTypePropTemplateCode}在模板中不存在");
                }
                return (prop.Address, temp?.MonitorCompareValue, temp?.PropType, temp?.MonitorFailure,temp.Code);
            }).ToList(),
        }).ToDictionary(x => x.Code, x => x);
    }

    /// <summary>
    /// 判断设备数据或者设备模板数据是否发生改变
    /// </summary>
    /// <returns></returns>
    private static bool IsDataChange()
    {
        var flag = false;

        using var context = new DataContext();
        var lastEquipmentCount = context.Equipment.Where(x => true).Count();
        var lastEquipmentPropTempCount = context.EquipmentProp.Where(x => true).Count();

        if (lastEquipmentCount != LastEquipmentCount || lastEquipmentPropTempCount != LastEquipmentPropTempCount)
        {
            flag = true;
        }
        LastEquipmentCount = lastEquipmentCount;
        LastEquipmentPropTempCount = lastEquipmentPropTempCount;

        return flag;
    }
}