BaseAnalysis.cs 12.6 KB
using HHECS.BllModel;
using HHECS.DAQHandle.Common.Enums;
using HHECS.DAQHandle.Common.Utils;
using HHECS.DAQHandle.DataAccess;
using HHECS.DAQHandle.Dto;
using HHECS.DAQHandle.Models;
using HHECS.EquipmentModel;
using System.Configuration;
using System.Text.Json;

namespace HHECS.DAQHandle.EquipmentHandle
{
    internal abstract class BaseAnalysis : IAnalysis
    {
        protected DataContext Context = new DataContext();
        protected static int AlarmTimeOut = int.Parse(ConfigurationManager.AppSettings["AlarmTimeOut"]);
        protected static int StatusTimeOut = int.Parse(ConfigurationManager.AppSettings["StatusTimeOut"]);

        protected EquipmentType EquipmentType;

        protected List<EquipmentTypePropTemplate> EquipmentTypePropTemps;

        protected BaseAnalysis(EquipmentType equipmentType)
        {
            EquipmentType = equipmentType;
            EquipmentTypePropTemps = equipmentType.EquipmentTypePropTemplates;
            var handleStage = EquipmentDataRecord.SET_ERROR_HANDLE | EquipmentDataRecord.SET_STATUS_HANDLE | EquipmentDataRecord.SET_VAULE_HANDLE;
            var count = Context.EquipmentDataRecord.Where(x => x.IsHandle && x.HandleStage == handleStage).Count();
            //保留9000-10000条数据
            if (count < 10000) return;
            var handleData = Context.EquipmentDataRecord.Where(x => x.IsHandle && x.HandleStage == handleStage).OrderBy(x => x.Timestamp).Take(1000).ToList();
            if (handleData.Count > 0)
            {
                try
                {
                    Context.EquipmentDataRecord.RemoveRange(handleData);
                    Context.SaveChanges();
                    SystemLog.PrintInfo($"清除了{handleData.Count}条已处理数据");
                }
                catch (Exception ex)
                {
                    SystemLog.PrintInfo($"清除已处理数据失败{ex}");
                }

            }

        }

        public virtual BllResult Execute(IEnumerable<EquipmentDataRecord> equipmentDataRecords)
        {
            return BllResultFactory.Success();
        }

        /// <summary>
        /// 更新设备属性值
        /// </summary>
        /// <param name="record">取最后一条记录</param>
        protected virtual bool UpdateTagValue(EquipmentDataRecord record)
        {
            try
            {

                if (record == null) return true;
                DateTime acceptTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Local).AddSeconds(record.Timestamp);
                //获取所有修改时间小于当前数据时间的属性
                var equipment = Context.Equipment.Where(x => x.Code == record.EquipmentCode).First();
                var props = Context.EquipmentProp.Where(x => x.EquipmentId == equipment.Id).ToList();

                if (props.Any(x => x.Updated != null && x.Updated > acceptTime))
                {
                    SystemLog.PrintError($"更新数据:记录{record.Id}已经过期");
                    return false;
                }

                foreach (var prop in props)
                {
                    if (record.Props.TryGetValue(prop.Address, out string value))
                    {
                        prop.Value = value;
                        prop.Updated = acceptTime;
                    }
                    //else
                    //{
                    //    SystemLog.PrintInfo($"设备[{record.EquipmentCode}]的属性{prop.EquipmentTypePropTemplateCode}不存在");

                    //}
                }
                //record.HandleStage = (byte)(record.HandleStage ^ EquipmentDataRecord.SET_VAULE_HANDLE);
                Context.EquipmentProp.UpdateRange(props);
                Context.SaveChanges();
                return true;
            }
            catch (Exception ex)
            {
                SystemLog.PrintError($"{ex}");
                return false;

            }
        }

        /// <summary>
        /// 更新设备状态记录
        /// </summary>
        /// <param name="records"></param>
        protected virtual void UpdateEquipmentStatus(string equipmentSN, IEnumerable<EquipmentDataRecord> records)
        {
            var first = records?.FirstOrDefault();
            DateTime acceptTime = DateTime.Now;
            if (first != null)
            {
                acceptTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Local).AddSeconds(first.Timestamp);
            }

            var endRecords = Context.EquipmentStatusRecordHistorys.Where(x => !x.IsEnd && (acceptTime - (DateTime)x.UpdateTime).TotalSeconds > StatusTimeOut).ToList();
            var addRecords = new List<EquipmentStatusRecordHistory>();
            endRecords.ForEach(x =>
            {
                if (x.Status != EquipmentStatusRecordStatus.Free.ToString())
                {
                    var updatetime = first == null ? x.UpdateTime : acceptTime;
                    x.UpdateTime = updatetime;
                    x.IsEnd = true;
                    x.StatusDuration = (acceptTime - (DateTime)x.CreateTime).TotalSeconds;
                    var newStatus = new EquipmentStatusRecordHistory()
                    {
                        CreateTime = updatetime,
                        UpdateTime = updatetime,
                        Status = EquipmentStatusRecordStatus.Free.ToString(),
                        EquipmentCode = x.EquipmentCode,
                        EquipmentName = x.EquipmentName,
                        IsEnd = false,
                        WarehouseCode = x.WarehouseCode,
                        Remark = "超过超时时间未上传数据,重置设备状态为空闲",
                    };
                    addRecords.Add(newStatus);
                }
            });
            if (endRecords.Count > 0)
            {
                Context.UnitOfWork.GetOrBeginTransaction();
                try
                {
                    Context.EquipmentStatusRecordHistorys.UpdateRange(endRecords);
                    if (addRecords.Count > 0)
                    {
                        Context.EquipmentStatusRecordHistorys.AddRange(addRecords);
                        //移除原有数据
                        Context.EquipmentStatusRecords.Remove(x => addRecords.Any(y => y.EquipmentCode == x.EquipmentCode));
                        //插入新数据
                        Context.EquipmentStatusRecords.AddRange(addRecords);

                    }
                    Context.SaveChanges();
                    Context.UnitOfWork.Commit();
                }
                catch (Exception ex)
                {
                    SystemLog.PrintError($"{ex}");
                    Context.UnitOfWork.Rollback();
                }


            }
        }

        /// <summary>
        /// 更新设备报警记录
        /// </summary>
        /// <param name="records"></param>
        protected virtual void UpdateEquipmentAlarm(string equipmentSN, IEnumerable<EquipmentDataRecord> records)
        {
            var first = records?.FirstOrDefault();
            var acceptTime = DateTime.Now;
            if (first != null)
            {
                acceptTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Local).AddSeconds(first.Timestamp);
            }

            var endRecords = Context.EquipmentAlarmRecords.Where(x => !x.IsEnd && (acceptTime - (DateTime)x.UpdateTime).TotalSeconds > AlarmTimeOut).ToList();

            if (endRecords.Count > 0)
            {
                endRecords.ForEach(x =>
                {
                    //x.UpdateTime = DateTime.Now;
                    x.ErrorDuration = ((DateTime)x.UpdateTime - (DateTime)x.CreateTime).TotalSeconds;
                    x.IsEnd = true;
                });
                Context.UpdateRange(endRecords);
                Context.SaveChanges();
            }

        }

        /// <summary>
        /// 记录设备状态
        /// </summary>
        /// <param name="srm"></param>
        /// <param name="records"></param>
        /// <param name="equipmentStatusRecordStatus"></param>
        public void RecordEquipmentStatus(EquipmentDataRecord srm, List<EquipmentStatusRecordHistory> records, EquipmentStatusRecordStatus equipmentStatusRecordStatus)
        {

            var record = records.Find(t => t.Status == equipmentStatusRecordStatus.ToString());
            var equipment = Context.Equipment.Where(x => x.Code == srm.EquipmentCode).First();
            DateTime acceptTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Local).AddSeconds(srm.Timestamp);
            EquipmentStatusRecordHistory equipmentStatusRecord = new EquipmentStatusRecordHistory();
            //Context.EquipmentStatusRecords.Where(x=>true);
            try
            {
                Context.UnitOfWork.GetOrBeginTransaction();

                if (record == null)
                {
                    //新建
                    equipmentStatusRecord.EquipmentCode = srm.EquipmentCode;
                    equipmentStatusRecord.EquipmentName = equipment.Name;
                    equipmentStatusRecord.Status = equipmentStatusRecordStatus.ToString();
                    equipmentStatusRecord.UpdateTime = acceptTime;
                    equipmentStatusRecord.CreateTime = acceptTime;
                    equipmentStatusRecord.HandleTime = DateTime.Now;
                    //更新上一个状态
                    var lastRecord = records.FirstOrDefault();
                    if (lastRecord != null)
                    {
                        lastRecord.UpdateTime = acceptTime;
                        lastRecord.IsEnd = true;
                        lastRecord.StatusDuration = (acceptTime - (DateTime)lastRecord.CreateTime).TotalSeconds;
                        Context.EquipmentStatusRecordHistorys.Update(lastRecord);
                    }
                    Context.EquipmentStatusRecordHistorys.Add(equipmentStatusRecord);
                }
                else
                {
                    //更新
                    record.UpdateTime = acceptTime;
                    record.StatusDuration = (acceptTime - (DateTime)record.CreateTime).TotalSeconds;
                    Context.EquipmentStatusRecordHistorys.Update(record);

                }
                //更新实时状态
                EquipmentStatusRecord currStatus = record ?? equipmentStatusRecord;
                //EquipmentStatusRecord currStatus = Context.EquipmentStatusRecords.Where(x => x.EquipmentCode == srm.EquipmentCode).First();
                //currStatus.Status = (record ?? equipmentStatusRecord).Status;
                //currStatus.UpdateTime = acceptTime;
                //Context.EquipmentStatusRecords.AddOrUpdate(currStatus);
                Context.EquipmentStatusRecords.Remove(x => x.EquipmentCode == srm.EquipmentCode);
                Context.EquipmentStatusRecords.Add(currStatus);

                Context.SaveChanges();
                Context.UnitOfWork.Commit();
            }
            catch (Exception ex)
            {
                Context.UnitOfWork.Rollback();
                //修改数据记录
                srm.HandleStage = (byte)(srm.HandleStage ^ EquipmentDataRecord.SET_STATUS_ERROR);
                SystemLog.PrintError($"记录{srm.Id}更新设备状态失败{ex}");
            }
            //  srm.IsHandle = true;

        }

        /// <summary>
        /// Json转<see cref="TagItemDto"/>集合
        /// </summary>
        /// <param name="json">Json数据</param>
        /// <returns><see cref="BllResult{T}"/></returns>
        protected static BllResult<List<TagItemDto>> JsonConvertToTagList(string json)
        {
            try
            {
                var jsonOption = new JsonSerializerOptions
                {
                    PropertyNameCaseInsensitive = true,
                };
                var tags = JsonSerializer.Deserialize<List<TagItemDto>>(json);
                return BllResultFactory.Success(tags);
            }
            catch (Exception ex)
            {
                return BllResultFactory.Error<List<TagItemDto>>($"Json数据转换成Tag集合失败!{ex.Message}");
            }
        }

        /// <summary>
        /// 时间戳转 <see cref="DateTime"/>
        /// </summary>
        /// <param name="timestamp"></param>
        /// <returns><see cref="BllResult{T}"/></returns>
        protected static BllResult<DateTime> ConvertToDateTime(long timestamp)
        {
            try
            {
                var time = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Local).AddSeconds(timestamp);
                return BllResultFactory.Success(time);
            }
            catch (Exception ex)
            {
                return BllResultFactory.Error<DateTime>(ex.Message);
            }
        }
    }
}