CommonService.cs 12.8 KB
using HHECS.DAQShared.Common.Enums;
using HHECS.DAQShared.Common.Utils;
using HHECS.DAQShared.Models;
using HHECS.EquipmentModel;
using Microsoft.Extensions.Caching.Distributed;

namespace HHECS.DAQServer.Services
{
    public class CommonService
    {
        private readonly IFreeSql _freeSql;
        private readonly IDistributedCache _cache;
        private readonly ILogger<CommonService> _logger;

        public CommonService(IFreeSql freeSql, IDistributedCache cache, ILogger<CommonService> logger)
        {
            _freeSql = freeSql;
            _cache = cache;
            _logger = logger;
        }

        /// <summary>
        /// 获取队列最大缓存数量
        /// </summary>
        /// <returns></returns>
        public long GetMaxCacheCount()
        {
            try
            {
                var cacheKey = nameof(GetMaxCacheCount);

                var cacheBytes = _cache.Get(cacheKey);
                if (cacheBytes != null)
                {
                    var oldVal = BitConverter.ToInt32(cacheBytes);
                    return oldVal;
                }

                //缓存配置
                var options = new DistributedCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromMinutes(1));
                var equipmentCount = _freeSql.Queryable<EquipmentExtend>().Count();
                var val = equipmentCount * 60 * 30;//每台设备缓存大概30分钟的数据
                _cache.Set(cacheKey, BitConverter.GetBytes(val), options);
                return val;
            }
            catch (Exception ex)
            {
                _logger.LogError($"[{nameof(CommonService)}方法[{nameof(GetMaxCacheCount)}]出现异常:{ex.Message}");
                return 1000000;//默认缓存100万条记录
            }
        }

        /// <summary>
        /// 获取设备状态
        /// </summary>
        /// <param name="equipment"></param>
        /// <returns></returns>
        public EquipmentStatus GetEquipmentStatus(EquipmentExtend equipment)
        {
            try
            {
                _ = Enum.TryParse<EquipmentTypeConst>(equipment.EquipmentType.Code, out var equipmentType);
                var srmCodes = new List<EquipmentTypeConst>
                {
                    EquipmentTypeConst.SingleForkSSRM,
                    EquipmentTypeConst.SingleForkSSRMV2,
                    EquipmentTypeConst.DoubleForkSRM,
                    EquipmentTypeConst.DoubleForkSRMV2,
                    EquipmentTypeConst.SingleForkSSRM,
                    EquipmentTypeConst.SingleForkSSRMV2,
                    EquipmentTypeConst.SingleForkSSRMV132,
                }.Select(x => x.ToString()).ToList();

                //堆垛机
                if (srmCodes.Contains(equipment.EquipmentType.Code))
                {
                    var totalError = equipment[SRMProps.TotalError.ToString()].Value;
                    var operationModel = equipment[SRMProps.OperationModel.ToString()].Value;
                    var fork1TaskExcuteStatus = equipment[SRMProps.Fork1TaskExcuteStatus.ToString()].Value;
                    //故障
                    if (totalError == bool.TrueString)
                    {
                        //维修状态下,不统计报警
                        if (operationModel == SRMOperationModel.Maintain.ToString())
                        {
                            return EquipmentStatus.Free;
                        }
                        return EquipmentStatus.Failure;
                    }

                    //运行
                    if (operationModel == SRMOperationModel.Online.GetIndexString() && fork1TaskExcuteStatus == SRMTaskExcuteStatus.TaskExecuting.GetIndexString())
                    {
                        return EquipmentStatus.Running;
                    }

                    //空闲
                    return EquipmentStatus.Free;
                }

                //焊接机器人
                if (equipmentType == EquipmentTypeConst.WeldRobot)
                {
                    var bootFlag = equipment[RobotProp.BootFlag.ToString()].Value;
                    var totalError = equipment[RobotProp.Alarm.ToString()].Value;
                    var workMode = equipment[RobotProp.Work_Mode.ToString()].Value;
                    var workTime = equipment[RobotProp.Work_Time.ToString()].Value;
                    var workFlag = equipment[RobotProp.WorkFlag.ToString()].Value;
                    if (bootFlag != bool.TrueString)
                    {
                        return EquipmentStatus.Offline;
                    }

                    //故障,T1、T2模式不记录报警
                    if (totalError == bool.TrueString && workTime != "1" && workTime != "2")
                    {
                        return EquipmentStatus.Failure;
                    }

                    //运行
                    if (workMode == "3" && (workFlag == bool.TrueString || workTime == bool.TrueString))
                    {
                        return EquipmentStatus.Running;
                    }

                    //待机
                    return EquipmentStatus.Free;
                }

                //AGV
                if (equipmentType == EquipmentTypeConst.AGVForklift)
                {
                    return EquipmentStatus.Offline;
                }

                //站台监控
                if (equipmentType == EquipmentTypeConst.StationMonitor)
                {
                    var totalError = equipment[StationProps.StationError.ToString()].Value;
                    var stationCorotation = false;
                    var stationReverse = false;

                    //故障
                    if (totalError == bool.TrueString)
                    {
                        return EquipmentStatus.Failure;
                    }

                    if (equipment.EquipmentProps.Exists(x => x.EquipmentTypePropTemplateCode == StationProps.StationCorotation.ToString()))
                    {
                        _ = bool.TryParse(equipment[StationProps.StationCorotation.ToString()].Value, out stationCorotation);
                    }

                    if (equipment.EquipmentProps.Exists(x => x.EquipmentTypePropTemplateCode == StationProps.StationReverse.ToString()))
                    {
                        _ = bool.TryParse(equipment[StationProps.StationReverse.ToString()].Value, out stationReverse);
                    }

                    //运行
                    if (stationCorotation || stationReverse)
                    {
                        return EquipmentStatus.Running;
                    }

                    //待机
                    return EquipmentStatus.Free;
                }

                //提升机
                if (equipmentType == EquipmentTypeConst.Hoist)
                {
                    var hoistStatus = equipment[HoistProps.HoistStatus.ToString()].Value;
                    if (string.IsNullOrWhiteSpace(hoistStatus))
                    {
                        return EquipmentStatus.Offline;
                    }

                    //故障
                    if (hoistStatus == "1")
                    {
                        return EquipmentStatus.Failure;
                    }
                    if (hoistStatus == "6")
                    {
                        return EquipmentStatus.Running;
                    }

                    return EquipmentStatus.Free;
                }

                //RGV站台
                if (equipmentType == EquipmentTypeConst.RGVStation)
                {
                    var totalError = equipment[RGVStationProps.Fault.ToString()].Value;
                    var autoMode = equipment[RGVStationProps.AutoMode.ToString()].Value;
                    var running = equipment[RGVStationProps.Running.ToString()].Value;
                    var stop = equipment[RGVStationProps.Stop.ToString()].Value;
                    var manual = equipment[RGVStationProps.Manual.ToString()].Value;
                    var airborne = equipment[RGVStationProps.Airborne.ToString()].Value;
                    var maintain = equipment[RGVStationProps.Maintain.ToString()].Value;

                    //无数据,视为离线
                    if (string.IsNullOrWhiteSpace(totalError))
                    {
                        return EquipmentStatus.Offline;
                    }

                    //故障
                    if (totalError == bool.TrueString)
                    {
                        return EquipmentStatus.Failure;
                    }

                    //运行
                    if (autoMode == bool.TrueString && running == bool.TrueString)
                    {
                        return EquipmentStatus.Running;
                    }

                    //待机
                    return EquipmentStatus.Free;
                }

                return EquipmentStatus.None;
            }
            catch (Exception)
            {
                return EquipmentStatus.None;
            }
        }

        /// <summary>
        /// 时间戳转本地时间
        /// </summary>
        /// <param name="timestamp">时间戳</param>
        /// <returns></returns>
        public DateTime TimestampConvertToLocalDateTime(long timestamp)
        {
            var timestampLength = Math.Abs(timestamp).ToString().Length;

            DateTime time = default;

            //时间戳为秒
            if (timestampLength == 10)
            {
                time = DateTimeOffset.FromUnixTimeSeconds(timestamp).LocalDateTime;
            }
            //时间戳为毫秒
            else if (timestampLength == 13)
            {
                time = DateTimeOffset.FromUnixTimeMilliseconds(timestamp).LocalDateTime;
            }

            //其他情况,无效数据
            return time;
        }

        /// <summary>
        /// 获取报警信息
        /// </summary>
        /// <param name="equipment"></param>
        /// <returns></returns>
        public (string, List<string>) GetEquipmentAlarmInfo(EquipmentExtend equipment)
        {
            try
            {
                var status = GetEquipmentStatus(equipment);
                //无报警
                if (status != EquipmentStatus.Failure)
                {
                    return (string.Empty, new List<string>());
                }

                _ = Enum.TryParse<EquipmentTypeConst>(equipment.EquipmentType.Code, out var equipmentTypeCode);
                //存在报警
                var mainAlarm = string.Empty;
                var detailAlarms = new List<string>();

                if (equipmentTypeCode == EquipmentTypeConst.AGVForklift)
                {
                    return (mainAlarm, detailAlarms);
                }

                //其他设备通用逻辑
                var mainAlarmPropCode = equipmentTypeCode switch
                {
                    EquipmentTypeConst.SingleForkSRM => SRMProps.TotalError.ToString(),
                    EquipmentTypeConst.DoubleForkSRM => SRMProps.TotalError.ToString(),
                    EquipmentTypeConst.SingleForkSSRM => SRMProps.TotalError.ToString(),
                    EquipmentTypeConst.SingleForkSSRMV132 => SRMProps.TotalError.ToString(),
                    EquipmentTypeConst.WeldRobot => RobotProp.Alarm.ToString(),
                    EquipmentTypeConst.RGVStation => RGVStationProps.Fault.ToString(),
                    EquipmentTypeConst.StationMonitor => StationProps.StationError.ToString(),
                    EquipmentTypeConst.Hoist => HoistProps.HoistStatus.ToString(),
                    _ => string.Empty,
                };

                if (string.IsNullOrWhiteSpace(mainAlarmPropCode))
                {
                    return (mainAlarm, detailAlarms);
                }

                var mainAlarmProp = equipment.EquipmentProps.Where(x => x.EquipmentTypePropTemplateCode == mainAlarmPropCode).FirstOrDefault();
                //存在报警
                if (mainAlarmProp != null && mainAlarmProp.Value == bool.TrueString)
                {
                    mainAlarm = mainAlarmProp.EquipmentTypePropTemplate.MonitorFailure;
                    var props = equipment.EquipmentProps.Where(x => x.EquipmentTypePropTemplate.PropType == EquipmentPropType.PLCMonitorAddress).ToList();
                    detailAlarms = props.Where(x =>
                    {
                        if (x.EquipmentTypePropTemplate.MonitorCompareValue == x.Value)
                        {
                            return false;
                        }
                        return true;
                    }).Select(x => x.EquipmentTypePropTemplate.MonitorFailure).ToList();
                }

                return (mainAlarm, detailAlarms);
            }
            catch (Exception)
            {
                return (string.Empty, new List<string>());
            }
        }
    }
}