DoubleForkSRMAnalysis.cs 14 KB
using HHECS.BllModel;
using HHECS.DAQHandle.Common.Enums;
using HHECS.DAQHandle.Common.Utils;
using HHECS.DAQHandle.Models;
using HHECS.EquipmentModel;

namespace HHECS.DAQHandle.EquipmentHandle
{
    /// <summary>
    /// 双叉堆垛机数据解析
    /// </summary>
    internal class DoubleForkSRMAnalysis : BaseAnalysis
    {
        public DoubleForkSRMAnalysis(EquipmentType equipmentType) : base(equipmentType) { }

        public override BllResult Execute(IEnumerable<EquipmentDataRecord> records)
        {
            try
            {
                var group = records.GroupBy(x => x.EquipmentCode);
                using var enumerator = group.GetEnumerator();
                enumerator.MoveNext();
                do
                {

                    var item = enumerator.Current;
                    var equipmentSN = item?.Key;
                    if (item != null)
                    {
                        Context.AttachRange(item);


                        var isSetValueSuccess = UpdateTagValue(item.OrderByDescending(x => x.Timestamp).FirstOrDefault());
                        foreach (var item1 in item)
                        {
                            //更新数据状态为设置数值报错
                            if (!isSetValueSuccess)
                            {
                                item1.HandleStage = (byte)(item1.HandleStage ^ EquipmentDataRecord.SET_VALUE_ERROR);
                            }
                            else
                            {
                                item1.HandleStage = (byte)(item1.HandleStage ^ EquipmentDataRecord.SET_VAULE_HANDLE);
                            }
                        }

                        ////性能太慢
                        ////更新状态到数据库
                        //if (item != null)
                        {
                            Context.UpdateRange(item);
                            Context.SaveChanges();
                        }
                    }

                    var orderItem = item?.OrderBy(x => x.Timestamp);
                    UpdateEquipmentAlarm(equipmentSN, orderItem);


                    UpdateEquipmentStatus(equipmentSN, orderItem);


                    //更新状态到数据库
                    if (item != null)
                    {
                        Context.UpdateRange(item);
                        Context.SaveChanges();
                    }


                } while (enumerator.MoveNext());
                return BllResultFactory.Success();
            }
            catch (Exception ex)
            {
                return BllResultFactory.Error($"[{nameof(SingleForkSRMAnalysis)}]解析出现异常:{ex}");
            }
        }



        protected override void UpdateEquipmentAlarm(string equipmentSN, IEnumerable<EquipmentDataRecord> records)
        {
            base.UpdateEquipmentAlarm(equipmentSN, records);
            if (records == null || !records.Any()) return;

            records = records.Where(x => (x.HandleStage & EquipmentDataRecord.SET_ERROR_HANDLE) != EquipmentDataRecord.SET_ERROR_HANDLE);

            try
            {

                var lastAlarm = Context.EquipmentAlarmRecords.Where(x => x.EquipmentCode == equipmentSN)
                                           .OrderByDescending(x => x.UpdateTime)
                                           .Take(1).First();
                foreach (var equipmentInfo in records)
                {

                    try
                    {
                        Context.UnitOfWork.GetOrBeginTransaction();
                        DateTime acceptTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Local).AddSeconds(equipmentInfo.Timestamp);
                        if (lastAlarm != null)
                        {
                            //记录过期处理
                            if (acceptTime < lastAlarm.UpdateTime)
                            {
                                SystemLog.PrintWarn($"错误统计:记录{equipmentInfo.Id}已过期");
                                continue;
                            }
                        }
                        var alarmRecords = Context.EquipmentAlarmRecords.Where(x => x.EquipmentCode == equipmentInfo.EquipmentCode && x.IsEnd == false).ToList();
                        var alarms = EquipmentTypePropTemps.FindAll(x =>
                        {
                            return
                               x.PropType == EquipmentPropType.PLCMonitorAddress
                                && x.MonitorCompareValue != null
                               && equipmentInfo.Props[x.Address] != x.MonitorCompareValue;
                        });
                        //如果alarms考虑直接结束报警,目前是隔五秒刷新


                        foreach (var alarm in alarms)
                        {
                            //匹配数据库中已有记录,如果当前的时间戳小于已记录的异常,不做处理
                            var record = alarmRecords.Find(t => t.PropCode == alarm.Address);

                            if (record == null)
                            {
                                //说明记录中没有,或者超过5秒,则直接新增这个报警;
                                EquipmentAlarmRecord equipmentAlarm = new EquipmentAlarmRecord
                                {
                                    EquipmentCode = equipmentInfo.EquipmentCode,
                                    EquipmentName = equipmentInfo.EquipmentName,
                                    PropCode = alarm.Address,
                                    AlarmMessage = string.IsNullOrWhiteSpace(equipmentInfo.Props[alarm.Address]) ? "值为空" : alarm.MonitorFailure,
                                    CreateTime = acceptTime,
                                    UpdateTime = acceptTime,//确保不为null 
                                    HandleTime = DateTime.Now,
                                };
                                Context.EquipmentAlarmRecords.Add(equipmentAlarm);

                            }
                            else
                            {
                                //更新这个报警
                                record.UpdateTime = acceptTime;
                                record.ErrorDuration = (acceptTime - (DateTime)record.CreateTime).TotalSeconds;
                                Context.EquipmentAlarmRecords.Update(record);
                            }

                        }
                        //设置状态为已经处理
                        equipmentInfo.HandleStage = (byte)(equipmentInfo.HandleStage ^ EquipmentDataRecord.SET_ERROR_HANDLE);
                        Context.Update(equipmentInfo);
                        Context.SaveChanges();
                        Context.UnitOfWork.Commit();

                    }
                    catch (Exception ex)
                    {
                        Context.UnitOfWork.Rollback();
                        equipmentInfo.HandleStage = (byte)(equipmentInfo.HandleStage ^ EquipmentDataRecord.SET_ALARM_ERROR);
                        Context.Update(equipmentInfo);
                        Context.SaveChanges();
                        SystemLog.PrintError($"记录{equipmentInfo.Id}设置报警信息异常:{ex}");
                    }

                }

            }
            catch (Exception ex)
            {
                SystemLog.PrintError($"{ex}");
            }

        }

        protected override void UpdateEquipmentStatus(string equipmentSN, IEnumerable<EquipmentDataRecord> records)
        {
            base.UpdateEquipmentStatus(equipmentSN, records);

            if (records == null || !records.Any()) return;
            records = records.Where(x => (x.HandleStage & EquipmentDataRecord.SET_STATUS_HANDLE) != EquipmentDataRecord.SET_STATUS_HANDLE);
            foreach (var srm in records)
            {
                try
                {
                    //与此设备相关的所有状态记录
                    var statusRecords = Context.EquipmentStatusRecordHistorys.Where(t => t.EquipmentCode == srm.EquipmentCode && t.IsEnd == false).OrderBy(x => x.UpdateTime).ToList();
                    if (statusRecords.Count > 1)
                    {

                        SystemLog.PrintError($"设备{srm.EquipmentCode}同时存在多条未结束的状态;{string.Join(",", statusRecords.Select(x => x.Status))}");
                        var statusRecord = statusRecords.First();
                        statusRecord.IsEnd = true;
                        statusRecord.Remark = $"同时存在多条未结束的状态,结束较早的数据{DateTime.Now}";
                        statusRecords.Remove(statusRecord);
                        Context.Update(statusRecord);
                        Context.SaveChanges();
                    }

                    DateTime acceptTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Local).AddSeconds(srm.Timestamp);
                    //记录过期处理
                    if (statusRecords.Count != 0 && acceptTime < statusRecords.First().UpdateTime)
                    {
                        SystemLog.PrintWarn($"状态记录:记录{srm.Id}已过期");
                        continue;
                    }

                    EquipmentStatusRecordStatus? equipmentStatus = null;

                    var totalError = EquipmentTypePropTemps.Where(x => x.Code == SRMProps.TotalError.ToString()).First().Address;
                    //故障
                    if (string.IsNullOrWhiteSpace(srm.Props[totalError]))
                    {
                        SystemLog.PrintError($"记录{srm.Id}的totalError属性无有效数据");
                    }
                    else if (srm.Props[totalError] == "True")
                    {
                        equipmentStatus = EquipmentStatusRecordStatus.Error;

                        //  RecordEquipmentStatus(srm, statusRecords, EquipmentStatusRecordStatus.Error);
                    }
                    else
                    {
                        var operationModel = EquipmentTypePropTemps.Where(x => x.Code == SRMProps.OperationModel.ToString()).First().Address;
                        var fork1TaskExcuteStatus = EquipmentTypePropTemps.Where(x => x.Code == SRMProps.Fork1TaskExcuteStatus.ToString()).First().Address;

                        if (string.IsNullOrWhiteSpace(srm.Props[operationModel]) || string.IsNullOrWhiteSpace(fork1TaskExcuteStatus))
                        {
                            SystemLog.PrintError($"记录{srm.Id}的operationModel属性无有效数据{srm.Props[operationModel]}或fork1TaskExcuteStatus 无有效数据{srm.Props[fork1TaskExcuteStatus]}");
                        }
                        //空闲等
                        if (srm.Props[operationModel] == SRMOperationModel.Maintain.GetIndexString())
                        {
                            equipmentStatus = EquipmentStatusRecordStatus.Maintain;

                            //维修
                            //RecordEquipmentStatus(srm, statusRecords, EquipmentStatusRecordStatus.Maintain);
                        }
                        else if (srm.Props[operationModel] == SRMOperationModel.Manual.GetIndexString()
                        || srm.Props[operationModel] == SRMOperationModel.StandAlone.GetIndexString()
                        || srm.Props[operationModel] == SRMOperationModel.Airborne.GetIndexString())
                        {
                            equipmentStatus = EquipmentStatusRecordStatus.Manual;

                            //手动
                            //RecordEquipmentStatus(srm, statusRecords, EquipmentStatusRecordStatus.Manual);
                        }
                        else if (srm.Props[operationModel] == SRMOperationModel.Online.GetIndexString()
                        && srm.Props[fork1TaskExcuteStatus] == SRMTaskExcuteStatus.TaskExecuting.GetIndexString())
                        {

                            equipmentStatus = EquipmentStatusRecordStatus.Running;

                            //运行中
                            //RecordEquipmentStatus(srm, statusRecords, EquipmentStatusRecordStatus.Running);
                        }
                        else if (srm.Props[operationModel] == SRMOperationModel.Online.GetIndexString()
                        && srm.Props[fork1TaskExcuteStatus] == SRMTaskExcuteStatus.Standby.GetIndexString())
                        {
                            equipmentStatus = EquipmentStatusRecordStatus.Free;

                            // RecordEquipmentStatus(srm, statusRecords, EquipmentStatusRecordStatus.Free);
                        }
                        else if (srm.Props[operationModel] == SRMOperationModel.Online.GetIndexString()
                        && (srm.Props[fork1TaskExcuteStatus] == SRMTaskExcuteStatus.TaskInterruptError.GetIndexString()
                            || srm.Props[fork1TaskExcuteStatus] == SRMTaskExcuteStatus.TaskSendError.GetIndexString()))
                        {
                            equipmentStatus = EquipmentStatusRecordStatus.TaskExcuteError;

                            // RecordEquipmentStatus(srm, statusRecords, EquipmentStatusRecordStatus.TaskExcuteError);
                        }


                    }
                    if (equipmentStatus != null)
                    {
                        RecordEquipmentStatus(srm, statusRecords, (EquipmentStatusRecordStatus)equipmentStatus);
                    }
                    srm.HandleStage = (byte)(srm.HandleStage ^ EquipmentDataRecord.SET_STATUS_HANDLE);
                }
                catch (Exception ex)
                {
                    SystemLog.PrintError($"记录{srm.Id}状态记录处理失败:{ex}");
                    srm.HandleStage = (byte)(srm.HandleStage ^ EquipmentDataRecord.SET_STATUS_ERROR);
                }
                finally
                {
                    //设置状态为已经处理
                    srm.IsHandle = true;
                    Context.Update(srm);
                    Context.SaveChanges();
                }
            }

        }



    }
}