private bool IsPumpRunningAndTdDataUpdated(IRedisClient redisClient, Guid ppGuid)
        {
            //判断机泵是否在运行
            var isRun = redisClient.IsPumpRunning(ppGuid);

            Log.Inform(isRun
                ? $">>>>>>>>> 机组{ppGuid} 正在运行 >>>>>>>>"
                : $"--------- 机组{ppGuid} 未运行 ---------");
            if (!isRun)
            {
                return(false);
            }

            //找出机泵下所有传感器,检查数据更新状态
            //如果都没更新, 那就不进行诊断
            //如果存在更新了数据的传感器,那就需要进行诊断
            var ppsys      = RuntimeRepo.PumpSysList.First(ps => GuidExt.IsSameGuid(ppGuid, ps.Guid));
            var hasNewData = false;

            foreach (var td in ppsys.Transducers)
            {
                var isUpdated = redisClient.IsTdDataUpdated(td);
                hasNewData |= isUpdated;
            }
            if (!hasNewData)
            {
                Log.Inform($"--------- 机组{ppGuid} 所有传感器未更新数值 ---------");
            }
            return(hasNewData);
        }
Ejemplo n.º 2
0
        public void TestMutateUBitArray()
        {
            const int    keyCount        = 27;
            const int    switchableCount = 1000;
            const double mutationRate    = 0.3;

            var switchableGroup = Rando.Fast(123).ToSwitchableGroup <bool[]>(Guid.NewGuid(), keyCount, switchableCount);

            var mutant = switchableGroup.Mutate(Rando.Fast(222), mutationRate, GuidExt.NewGuids()).First();

            var diffs = switchableGroup.Switchables.GetDifferentItems(mutant.Switchables).ToList();

            Assert.AreEqual(mutant.KeyCount, keyCount);
            Assert.AreEqual(mutant.Switchables.Count, switchableCount);
            Assert.IsTrue(diffs.Count < 350);
            Assert.IsTrue(diffs.Count > 250);
        }
        public void RunDiagnose()
        {
            foreach (var guid in RuntimeRepo.RunningPumpGuids)
            {
                Log.Inform();
                Log.Inform($"********* 开始诊断机组:{guid} *********", true);
                Log.Inform();
                var ppsys = RuntimeRepo.PumpSysList.First(ps => GuidExt.IsSameGuid(guid, ps.Guid));
                _ctParser.TdUpdateTime = RuntimeRepo.PumpSysTimeDict[guid] ?? DateTime.Now;
                DiagnoseRunningPump_Round1(ppsys);
                DiagnoseRunningPump_Round2(ppsys);
                FindMainVibraSpec(ppsys);
#if DEBUG
                RabbitToPandas(ppsys);
#endif
                Log.Inform();
                Log.Inform($"********* 机组:{guid} 诊断结束 ********", true);
                Log.Inform();
            }
        }
Ejemplo n.º 4
0
        public PumpSystem(Guid ppGuid)
        {
            Guid = ppGuid;

            Log.Inform();
            Log.Inform($"--------- 开始构建机泵系统{Guid.ToFormatedString()} ---------");
            Log.Inform();

            #region 构建机泵部件

            //部件部分
            Pump = new Component(Guid, CompType.Pump)
            {
                NameRemark = "水泵"
            };
            Motor = new Component(Guid, CompType.Motor)
            {
                NameRemark = "电机"
            };
            Coupler = new Component(Guid, CompType.Coupler)
            {
                NameRemark = "联轴器"
            };


            //振动传感器部分
            var vibrasensors = Repo.SensorList.Where(s => GuidExt.IsSameGuid(s.PPGUID, Guid)).ToList();
            foreach (var vibrasensor in vibrasensors)
            {
                var td = new VibraTransducer(vibrasensor.SSGUID)
                {
                    Signal     = vibrasensor.ITEMCODE,
                    NameRemark = vibrasensor.SSNAME,
                    Position   = PubFuncs.FindTdPosFromSignal(vibrasensor.ITEMCODE)
                };
                Transducers.Add(td);
                Log.Inform($"添加振动传感器({td.NameRemark}): 信号量:{td.Signal}  位置:{td.Position}");
            }

            //非振动部分
            foreach (var phydefnovibra in Repo.PhyDefNoVibra.Where(s => GuidExt.IsSameGuid(s.PPGUID, Guid)))
            {
                var type = PubFuncs.ParseSignalType(phydefnovibra.ITEMCODE);
                if (type.HasValue)
                {
                    var td = new NonVibraTransducer(phydefnovibra.PPGUID, type.Value, phydefnovibra.ID)
                    {
                        Signal     = phydefnovibra.ITEMCODE,
                        NameRemark = phydefnovibra.PDNVNAME,
                        Position   = PubFuncs.FindTdPosFromSignal(phydefnovibra.ITEMCODE)
                    };
                    Transducers.Add(td);
                    Log.Inform($"添加非振动传感器({td.NameRemark}): 信号量:{td.Signal}  位置:{td.Position}");
                }
            }

            //还有一枚单独的转速变送器
            var speedTd = new SpeedTransducer(Guid);
            Transducers.Add(speedTd);
            Log.Inform($"添加转速传感器({speedTd.NameRemark}): 信号量:{speedTd.Signal}  位置:{speedTd.Position}");

            //            var ta = Repo.PhyDefNoVibra.Select(p => p.ITEMCODE).ToList();
            Add(Pump);
            Add(Motor);
            Add(Coupler);
            AddRange(Transducers);

            #endregion

            #region 构建部件间接属性

            foreach (DataRow row in PumpSysLib.TableIndirectProperty.Rows)
            {
                var prop = new Property {
                    Name     = row["PropertyName"].ToString(),
                    Value    = row["DefaultValue"].ToString(),
                    Variable = row["Variable"].ToString()
                };
                AllocateProperty(prop, row);
            }

            //连接点属性是间接属性的一部分,所以也加入
            foreach (DataRow row in PumpSysLib.TableConnectorPointProperty.Rows)
            {
                var prop = new Property {
                    Name = row["PropertyName"].ToString(),
//                    Value = row["DefaultValue"].ToString(),
                    Variable = row["Variable"].ToString()
                };
                AllocateProperty(prop, row);
            }

            #endregion

            #region 绑定传感器的自带信号量

            foreach (var transducer in Transducers)
            {
                transducer.BindSignal();
            }

            #endregion


            #region 设置振动传感器的图谱的信号量

            foreach (var tdv in Transducers.Where(t => t.Type == CompType.Td_V))
            {
                foreach (var gType in Enum.GetNames(typeof(GraphType)))
                {
                    var prop = tdv.Properties.Find(p => p.Variable == "@" + gType);
                    prop.Value = PubFuncs.FormatGraphSignal(tdv.Code, (GraphType)Enum.Parse(typeof(GraphType), gType));
                }
            }

            #endregion


            #region 根据引用属性,将间接属性的值绑定到信号量

            foreach (DataRow row in PumpSysLib.TableRefProperty.Rows)
            {
                //找到要设置属性值的组件
                BaseComponent comp   = null;
                var           cpType = Repo.Map.TypeToEnum[row["TypeName"].ToString()];
                switch (cpType)
                {
                case CompType.Pump:
                    comp = Pump;
                    break;

                case CompType.Motor:
                    comp = Motor;
                    break;

                case CompType.Coupler:
                    comp = Coupler;
                    break;
                }
                //找到要设置的属性值
                var prop = comp?.Properties.Find(p => p.Variable == row["IndirectVariable"].ToString());
                if (prop != null)
                {
                    //先找是哪个类型的传感器
                    var tdtype = Repo.Map.TypeToEnum[row["RefType"].ToString()];

                    //再根据位置找到该传感器
                    var tdpos = (TdPos)Enum.Parse(typeof(TdPos), row["Position"].ToString());

                    var td = Transducers.Find(t => t.Type == tdtype && t.Position == tdpos);

                    //再找到传感器上的属性
                    var rp = td?.Properties.Find(p => p.Variable == row["RefVariable"].ToString());
                    if (rp != null)
                    {
                        prop.Value = rp.Value;
                    }
                }
            }

            #endregion


            #region 根据水泵guid,设置水泵轴承和电机轴承的各自的4个缺陷频率

            foreach (var pumpBrInfo in DataDetailsOp.GetPumpBearingInfos(Guid))
            {
                Pump.Properties.First(p => p.Variable == pumpBrInfo.Key).Value = pumpBrInfo.Value.ToString();
            }

            foreach (var motorBrInfo in DataDetailsOp.GetMotorBearingInfos(Guid))
            {
                Motor.Properties.First(p => p.Variable == motorBrInfo.Key).Value = motorBrInfo.Value.ToString();
            }

            #endregion

            #region 根据水泵guid,设置水泵叶片数

            Pump.Properties.First(p => p.Variable == "@BladeNum").Value = DataDetailsOp.GetPumpFanCount(Guid).ToString();

            #endregion

            Log.Inform();
            Log.Inform($"--------- 机泵系统{ppGuid} 构建结束---------");
            Log.Inform();
        }
        /// <summary>
        /// 机泵实时数据
        /// </summary>
        public void UpdateRtData()
        {
            using (var redisClient = RedisManager.GetClient())
            {
                RuntimeRepo.RunningPumpGuids.Clear();

                try {
                    RuntimeRepo.RunningPumpGuids.AddRange(Repo.PumpGuids.Where(g => IsPumpRunningAndTdDataUpdated(redisClient, g)).ToList());
                } catch (ServiceStack.Redis.RedisException ex) {
                    Log.Error("实时数据更新失败! " + ex.Message);
                    return;
                }

                //更新每个ppsys的实时数据时间, 以所有传感器中最新的数据作为该时间
                RuntimeRepo.PumpSysTimeDict.Clear();
                foreach (var guid in RuntimeRepo.RunningPumpGuids)
                {
                    var ppsys   = RuntimeRepo.PumpSysList.First(ps => GuidExt.IsSameGuid(guid, ps.Guid));
                    var maxTime = DateTime.MinValue;
                    foreach (var td in ppsys.Transducers)
                    {
                        DateTime?time;
                        if (redisClient.TryGetTdPickTime(td, out time))
                        {
                            if (time > maxTime)
                            {
                                maxTime = time.Value;
                            }
                        }
                    }
                    RuntimeRepo.PumpSysTimeDict.Add(guid, maxTime);
                }


                //构建要获取的实时数据的结构
                RuntimeRepo.RtData = new RtData();

                Log.Inform("--------------------------读取数据----------------------------");
                foreach (var item in RuntimeRepo.RtData.RedisKeyMap)
                {
                    var value = redisClient.GetValue(item.Key);
                    if (!string.IsNullOrEmpty(value))
                    {
                        if (item.Value.Contains("$Ua") || item.Value.Contains("$Ub") || item.Value.Contains("$Uc"))
                        //     || item.Value.Contains("$P_In") || item.Value.Contains("$P_Out"))
                        {
                            RuntimeRepo.RtData.SpData[item.Value] = Convert.ToDouble(value) * 1000;
                        }
                        else
                        {
//                            if (item.Value.Contains("peed") && Convert.ToDouble(value) < 300)
//                            {
//                                var a = 1;
//                            }
                            RuntimeRepo.RtData.SpData[item.Value] = Convert.ToDouble(value);
                        }
                    }
                }
                //[vibration realtime data Example]:
                var specs = new List <Spectrum>();
                RuntimeRepo.SpecAnalyser.Specs.Clear();
                foreach (var graph in RuntimeRepo.RtData.Graphs)
                {
//                    var sgn = "{" + _waveDatasRedisKey[item.DeviceCode].ToUpper() + "}_" +
//                              (item.Type == "spectrum" ? "TimeWave" : "Spectrum");
                    var value = redisClient.GetValue(graph.Signal);
                    if (string.IsNullOrEmpty(value))
                    {
                        Log.Warn($"从Redis中获取不到 {graph.Signal} 对应的图谱");
                        continue;
                    }
                    graph.Time = DateTime.Parse(value.Split('|')[0].Replace(@"""", string.Empty));
                    var datas = value.Split('[')[1]
                                .Replace(@"\", string.Empty)
                                .Replace(@"""", string.Empty)
                                .Replace("]", string.Empty)
                                .Replace("}", string.Empty)
                                .Split(',')
                                .Select(double.Parse)
                                .ToList();
                    //不去掉第一个无效值0, 为了保证计算时索引和线保持一致
//                    if(datas[0] == 0D)
//                        datas.RemoveAt(0);
                    graph.UpdateData(datas.ToArray());
                    if (graph.Type == GraphType.Spectrum)
                    {
                        var speed = RuntimeRepo.GetSpeed();
                        specs.Add(new Spectrum(speed, graph.Data, graph.Pos));
                    }
                }
                RuntimeRepo.SpecAnalyser.UpdateSpecs(specs);
            }
        }