using SHJX.Service.Control.Common.Assets; using SHJX.Service.Control.Disposables; using SHJX.Service.Control.Extends; namespace SHJX.Service.Control.Schedules { [EnableScheduling] public class ExtendScheduler : IScheduler { private static readonly ILogger logger = LogFactory.BuildLogger(typeof(ExtendScheduler)); private static IDataManager _dataManager; private static ReadConfigUtil _config; public ExtendScheduler(IDataManager dataManager, ReadConfigUtil config) { _dataManager = dataManager; _config = config; } /// /// 自动回原点 /// [Scheduled("AutomaticGoBack", 1000)] public void AutomaticGoBack() { bool haveStart = _dataManager.Query().Where(it => it.Start.Equals(true)).Any(); if (!haveStart) { return; } bool haveCache = _dataManager.Query().Any(); if (haveCache) { return; } #region 判断是否在消解位区域内 List motorMoves = _dataManager.Query().ToList(); Axis currentAxis = new() { LocationX = motorMoves.FirstOrDefault(it => it.MotorName.Equals(EquipmentNames.AxisX)).CurrentPosition, LocationY = motorMoves.FirstOrDefault(it => it.MotorName.Equals(EquipmentNames.AxisY)).CurrentPosition, LocationZ = 0, LocationZF = 0 }; List dissolveAreas = _dataManager.Query().Where(it => it.AreaName.Equals(AreaName.DISSOLVE_POSITION)).ToList(); bool inDissolveArea = false; Parallel.ForEach(dissolveAreas, area => { Axis axis = new() { LocationX = area.LocationX, LocationY = area.LocationY, LocationZ = 0, LocationZF = 0 }; if (axis.Equals(currentAxis)) { inDissolveArea = true; } }); DissolveDate dissolveDates = _dataManager.Query().Where(it => it.Start.Equals(true)).OrderBy(it => it.LastTryTime, OrderPattern.Asc).First(); if (dissolveDates != null) { ExecuteTime dissolveExecuteTime = _dataManager.Query().Where(it => it.TypeName.Equals(ExecuteTimeName.DISSOLVE_TIME)).First(); int taskSecondDate = dissolveDates.LastTryTime.GetSecondDifferenceValue(); TaskRuntime.Calculate(dissolveDates.PositionName, out double xNeedTime, out double yNeedTime, out double zNeedTime, out double zfNeedTime); double needTime = Math.Abs(xNeedTime) + Math.Abs(yNeedTime) + Math.Abs(zNeedTime) + Math.Abs(zfNeedTime); int sec = (int)DateTime.Now.Subtract(dissolveDates.LastTryTime).TotalSeconds; if (!inDissolveArea || dissolveExecuteTime.Value * 60 - taskSecondDate <= 2 * needTime) { return; } } #endregion StateMachine status = _dataManager.Query().Where(item => item.Name.Equals(StateMachineName.MOTOR_LOCK)).First(); if (status is null || status.Status >= 1) { return; } try { _dataManager.Update().Invoke(it => it.Status.Set(1))(it => it.Name.Equals(StateMachineName.MOTOR_LOCK)); string[] items = new string[] { EquipmentNames.AxisX, EquipmentNames.AxisY }; ParallelLoopResult result = Parallel.ForEach(items, item => { ExecuteCommand.MotorGoBackExecute(item); }); } finally { _dataManager.Update().Invoke(it => it.Status.Set(0))(it => it.Name.Equals(StateMachineName.MOTOR_LOCK)); } } ///// ///// 草酸钠自动吸液 ///// //[Scheduled("InLiquidSodium1Oxalate", 1000)] //public void InLiquidSodium1Oxalate() //{ // if (_config.AutomaticInLiquid) // { // EquipmentTask titrationTask = _dataManager.Query().Where(it => it.RouteStep.Equals(PipeName.TITRATION) && it.Status.In(TaskState.Titration, TaskState.Execute)).First(); // if (titrationTask is null) // { // return; // } // //bool arriveEndPoint = LiquidPipeSwitch.StartNew.SetLiquidName(EquipmentNames.Sodium1Oxalate).IsArriveEndPoint; // //if (!arriveEndPoint) // //{ // // return; // //} // StateMachine state = _dataManager.Query().Where(it => it.Name.Equals(StateMachineName.SODIUM1OXALATE_LOCK)).First(); // if (state.Status > 0) // { // return; // } // LiquidRecord record = _dataManager.Query().Where(it => it.Point.Equals(titrationTask.Source)).First(); // if (record is null) // { // LiquidRecord liquidRecord = new() // { // Point = titrationTask.Source // }; // _dataManager.Add(liquidRecord); // } // record = _dataManager.Query().Where(it => it.Point.Equals(titrationTask.Source)).First(); // if (titrationTask.RouteStep.Equals(PipeName.TITRATION) && record.TitrationSodiumOxalateStatus is null) // { // try // { // _dataManager.Update().Invoke(it => it.Status.Set(1))(it => it.Name.Equals(StateMachineName.SODIUM1OXALATE_LOCK)); // logger.LogInformation("自动吸液锁定草酸钠"); // LiquidVolume liquidVolume = _dataManager.Query().Where(it => it.LiquidName.Equals(EquipmentNames.Sodium1Oxalate)).First(); // LiquidAmount liquidAmount = _dataManager.Query().Where(it => it.LiquidName.Equals(EquipmentNames.Sodium1Oxalate)).First(); // int distance = Convert.ToInt32(Math.Round((liquidVolume.SampleVolume > liquidAmount.Capacity ? liquidAmount.Capacity : liquidVolume.SampleVolume) / liquidAmount.Amount * liquidAmount.ConvertRatio)); // LiquidPipeSwitch.StartNew.SetLiquidName(EquipmentNames.Sodium1Oxalate).CheckWhetherArriveEndPointOxalate().ExecuteOxalate(LiquidSwitchPattern.In, distance); // //LiquidPipeSwitch.StartNew.SetLiquidName(EquipmentNames.Sodium1Oxalate).SetPattern(LiquidSwitchPattern.Out); // _dataManager.Update().Invoke(it => it.TitrationSodiumOxalateStatus.Set(1))(it => it.Point.Equals(titrationTask.Source)); // } // finally // { // _dataManager.Update().Invoke(it => it.Status.Set(0))(it => it.Name.Equals(StateMachineName.SODIUM1OXALATE_LOCK)); // logger.LogInformation("自动吸液解锁草酸钠"); // } // } // } //} ///// ///// 草酸钠自动吸液 ///// //[Scheduled("InLiquidSodium1Oxalate", 1000)] //public void InLiquidSodium2Oxalate() //{ // if (_config.AutomaticInLiquid) // { // EquipmentTask titrationTask = _dataManager.Query().Where(it => it.RouteStep.Equals(PipeName.TITRATION2) && it.Status.In(TaskState.Titration2, TaskState.Execute)).First(); // if (titrationTask is null) // { // return; // } // //bool arriveEndPoint = LiquidPipeSwitch.StartNew.SetLiquidName(EquipmentNames.Sodium2Oxalate).IsArriveEndPoint; // //if (!arriveEndPoint) // //{ // // return; // //} // StateMachine state = _dataManager.Query().Where(it => it.Name.Equals(StateMachineName.SODIUM2OXALATE_LOCK)).First(); // if (state.Status > 0) // { // return; // } // LiquidRecord record = _dataManager.Query().Where(it => it.Point.Equals(titrationTask.Source)).First(); // if (record is null) // { // LiquidRecord liquidRecord = new() // { // Point = titrationTask.Source // }; // _dataManager.Add(liquidRecord); // } // record = _dataManager.Query().Where(it => it.Point.Equals(titrationTask.Source)).First(); // if (titrationTask.RouteStep.Equals(PipeName.TITRATION2) && record.TitrationSodiumOxalateStatus is null) // { // try // { // _dataManager.Update().Invoke(it => it.Status.Set(1))(it => it.Name.Equals(StateMachineName.SODIUM2OXALATE_LOCK)); // logger.LogInformation("自动吸液锁定草酸钠"); // LiquidVolume liquidVolume = _dataManager.Query().Where(it => it.LiquidName.Equals(EquipmentNames.Sodium2Oxalate)).First(); // LiquidAmount liquidAmount = _dataManager.Query().Where(it => it.LiquidName.Equals(EquipmentNames.Sodium2Oxalate)).First(); // int distance = Convert.ToInt32(Math.Round((liquidVolume.SampleVolume > liquidAmount.Capacity ? liquidAmount.Capacity : liquidVolume.SampleVolume) / liquidAmount.Amount * liquidAmount.ConvertRatio)); // LiquidPipeSwitch.StartNew.SetLiquidName(EquipmentNames.Sodium2Oxalate).CheckWhetherArriveEndPointOxalate().ExecuteOxalate(LiquidSwitchPattern.In, distance); // //LiquidPipeSwitch.StartNew.SetLiquidName(EquipmentNames.Sodium1Oxalate).SetPattern(LiquidSwitchPattern.Out); // _dataManager.Update().Invoke(it => it.TitrationSodiumOxalateStatus.Set(1))(it => it.Point.Equals(titrationTask.Source)); // } // finally // { // _dataManager.Update().Invoke(it => it.Status.Set(0))(it => it.Name.Equals(StateMachineName.SODIUM2OXALATE_LOCK)); // logger.LogInformation("自动吸液解锁草酸钠2"); // } // } // } //} ///// ///// 草酸钠自动吸液 (但滴定版本) ///// //[Scheduled("InLiquidSodiumOxalate", 1000)] //public void InLiquidSodiumOxalate() //{ // if (_config.AutomaticInLiquid) // { // bool existTitrationTask = _dataManager.Query().Where(it => it.RouteStep.Equals(PipeName.TITRATION) && it.Status.In(TaskState.Titration, TaskState.Execute)).Any(); // if (existTitrationTask) // { // return; // } // bool arriveEndPoint = LiquidPipeSwitch.StartNew.SetLiquidName(EquipmentNames.Sodium1Oxalate).IsArriveEndPoint; // if (!arriveEndPoint) // { // return; // } // StateMachine state = _dataManager.Query().Where(it => it.Name.Equals(StateMachineName.SODIUM1OXALATE_LOCK)).First(); // if (state.Status > 0) // { // return; // } // try // { // _dataManager.Update().Invoke(it => it.Status.Set(1))(it => it.Name.Equals(StateMachineName.SODIUM1OXALATE_LOCK)); // logger.LogInformation("自动吸液锁定草酸钠"); // LiquidVolume liquidVolume = _dataManager.Query().Where(it => it.LiquidName.Equals(EquipmentNames.Sodium1Oxalate)).First(); // LiquidAmount liquidAmount = _dataManager.Query().Where(it => it.LiquidName.Equals(EquipmentNames.Sodium1Oxalate)).First(); // int distance = Convert.ToInt32(Math.Round((liquidVolume.SampleVolume > liquidAmount.Capacity ? liquidAmount.Capacity : liquidVolume.SampleVolume) / liquidAmount.Amount * liquidAmount.ConvertRatio)); // LiquidPipeSwitch.StartNew.SetLiquidName(EquipmentNames.Sodium1Oxalate).ExecuteOxalate(LiquidSwitchPattern.In, distance); // //LiquidPipeSwitch.StartNew.SetLiquidName(EquipmentNames.Sodium1Oxalate).SetPattern(LiquidSwitchPattern.Out); // } // finally // { // _dataManager.Update().Invoke(it => it.Status.Set(0))(it => it.Name.Equals(StateMachineName.SODIUM1OXALATE_LOCK)); // logger.LogInformation("自动吸液解锁草酸钠"); // } // } //} /// /// 滴定1高猛酸自动吸液 /// [Scheduled("InLiquidPotassiumPermanganate", 1000)] public void InLiquidPotassiumPermanganate() { if (ConfigInstance.IsAutomaticInLiquid) { EquipmentTask titrationTask = _dataManager.Query().Where(it => it.RouteStep.Equals(PipeName.TITRATION) && it.Status.Equals(TaskState.Titration) || it.RouteStep.Equals(PipeName.TITRATION)&& it.Status.Equals(TaskState.Execute) ).First(); if (titrationTask is null) { return; } LiquidRecord record = _dataManager.Query().Where(it => it.Point.Equals(titrationTask.Source)).First(); if (record is null) { LiquidRecord liquidRecord = new() { Point = titrationTask.Source }; _dataManager.Add(liquidRecord); } record = _dataManager.Query().Where(it => it.Point.Equals(titrationTask.Source)).First(); if (titrationTask.RouteStep.Equals(PipeName.TITRATION) && record.TitrationPotassiumPermanganateStatus is null) { try { StateMachine state = _dataManager.Query().Where(it => it.Name.Equals(StateMachineName.POTASSIUM1PERMANGANATE_LOCK)).First(); if (state.Status > 0) { return; } _dataManager.Update().Invoke(it => it.Status.Set(1))(it => it.Name.Equals(StateMachineName.POTASSIUM1PERMANGANATE_LOCK)); if (titrationTask.RouteStep == PipeName.TITRATION) { _dataManager.Update().Invoke(it => it.TitrationPotassiumPermanganateStatus.Set(1))(it => it.Point.Equals(titrationTask.Source)); } logger.LogInformation(titrationTask.Source + "滴定1自动吸液锁定高锰酸盐"); LiquidAmount liquidAmount = _dataManager.Query().Where(it => it.LiquidName.Equals(EquipmentNames.Titration1PotassiumPermanganate)).First(); int distance = Convert.ToInt32(Math.Round(liquidAmount.Capacity / liquidAmount.Amount * liquidAmount.ConvertRatio)); LiquidPipeSwitch.StartNew.SetLiquidName(EquipmentNames.Titration1PotassiumPermanganate).CheckWhetherArriveEndPoint().Execute(LiquidSwitchPattern.In, distance); LiquidPipeSwitch.StartNew.SetLiquidName(EquipmentNames.Titration1PotassiumPermanganate).SetPattern(LiquidSwitchPattern.Out); _dataManager.Update().Invoke(it => it.Status.Set(0))(it => it.Name.Equals(StateMachineName.POTASSIUM1PERMANGANATE_LOCK)); logger.LogInformation(titrationTask.Source + "滴定1自动吸液解锁高锰酸盐"); } finally { } } } } ///// ///// 滴定2高猛酸自动吸液 ///// //[Scheduled("InLiquidPotassiumPermanganate2", 1000)] //public void InLiquidPotassiumPermanganate2() //{ // if (ConfigInstance.IsAutomaticInLiquid) // { // EquipmentTask titrationTask = _dataManager.Query().Where(it => it.RouteStep.Equals(PipeName.TITRATION2) && it.Status.In(TaskState.Titration2, TaskState.Execute)&& it.RouteID != 0).First(); // if (titrationTask is null) // { // return; // } // LiquidRecord record = _dataManager.Query().Where(it => it.Point.Equals(titrationTask.Source)).First(); // if (record is null) // { // LiquidRecord liquidRecord = new() // { // Point = titrationTask.Source // }; // _dataManager.Add(liquidRecord); // } // record = _dataManager.Query().Where(it => it.Point.Equals(titrationTask.Source)).First(); // if (titrationTask.RouteStep.Equals(PipeName.TITRATION2) && record.TitrationPotassiumPermanganateStatus is null) // { // try // { // StateMachine state = _dataManager.Query().Where(it => it.Name.Equals(StateMachineName.POTASSIUM2PERMANGANATE_LOCK)).First(); // if (state.Status > 0) // { // return; // } // _dataManager.Update().Invoke(it => it.Status.Set(1))(it => it.Name.Equals(StateMachineName.POTASSIUM2PERMANGANATE_LOCK)); // if (titrationTask.RouteStep == PipeName.TITRATION2) // { // _dataManager.Update().Invoke(it => it.TitrationPotassiumPermanganateStatus.Set(1))(it => it.Point.Equals(titrationTask.Source)); // } // logger.LogInformation(titrationTask.Source + "滴定2自动吸液锁定高锰酸盐"); // LiquidAmount liquidAmount = _dataManager.Query().Where(it => it.LiquidName.Equals(EquipmentNames.Titration2PotassiumPermanganate)).First(); // int distance = Convert.ToInt32(Math.Round(liquidAmount.Capacity / liquidAmount.Amount * liquidAmount.ConvertRatio)); // LiquidPipeSwitch.StartNew.SetLiquidName(EquipmentNames.Titration2PotassiumPermanganate).CheckWhetherArriveEndPoint().Execute(LiquidSwitchPattern.In, distance); // LiquidPipeSwitch.StartNew.SetLiquidName(EquipmentNames.Titration2PotassiumPermanganate).SetPattern(LiquidSwitchPattern.Out); // _dataManager.Update().Invoke(it => it.Status.Set(0))(it => it.Name.Equals(StateMachineName.POTASSIUM2PERMANGANATE_LOCK)); // logger.LogInformation(titrationTask.Source + "滴定2自动吸液解锁高锰酸盐"); // } // finally // { // } // } // } //} /// /// 加液高猛酸自动吸液 /// [Scheduled("InLiquidPotassiumPermanganate0", 1000)] public void InLiquidPotassiumPermanganate0() { if (ConfigInstance.IsAutomaticInLiquid) { EquipmentTask titrationTask = _dataManager.Query().Where(it => it.RouteStep.Equals(PipeName.ADD_LIQUID) && it.Status.In( TaskState.AddLiquid, TaskState.Execute)).First(); if (titrationTask is null) { return; } LiquidRecord record = _dataManager.Query().Where(it => it.Point.Equals(titrationTask.Source)).First(); if (record is null) { LiquidRecord liquidRecord = new() { Point = titrationTask.Source }; _dataManager.Add(liquidRecord); } record = _dataManager.Query().Where(it => it.Point.Equals(titrationTask.Source)).First(); if (titrationTask.RouteStep.Equals(PipeName.ADD_LIQUID) && record.AddliquidPotassiumPermanganateStatus is null) { try { StateMachine state = _dataManager.Query().Where(it => it.Name.Equals(StateMachineName.POTASSIUM2PERMANGANATE_LOCK)).First(); if (state.Status > 0) { return; } _dataManager.Update().Invoke(it => it.Status.Set(1))(it => it.Name.Equals(StateMachineName.POTASSIUM2PERMANGANATE_LOCK)); if (titrationTask.RouteStep == PipeName.ADD_LIQUID) { _dataManager.Update().Invoke(it => it.AddliquidPotassiumPermanganateStatus.Set(1))(it => it.Point.Equals(titrationTask.Source)); } logger.LogInformation(titrationTask.Source + "加液自动吸液锁定高锰酸盐"); LiquidAmount liquidAmount = _dataManager.Query().Where(it => it.LiquidName.Equals(EquipmentNames.Titration2PotassiumPermanganate)).First(); LiquidVolume liquidVolume = DataManagerInstance.GetLiquidVolume(EquipmentNames.Titration2PotassiumPermanganate); if (liquidVolume is null) { throw new ArgumentException($"{EquipmentNames.Titration2PotassiumPermanganate}查询Volume为空"); } int distance = 0; double count = Math.Floor(liquidVolume.SampleVolume / liquidAmount.Capacity); if (count < 1) { distance = Convert.ToInt32(Math.Round(liquidVolume.SampleVolume / liquidAmount.Amount * liquidAmount.ConvertRatio)); } else distance = Convert.ToInt32(Math.Round(liquidAmount.Capacity / liquidAmount.Amount * liquidAmount.ConvertRatio)); LiquidPipeSwitch.StartNew.SetLiquidName(EquipmentNames.Titration2PotassiumPermanganate).CheckWhetherArriveEndPoint().Execute(LiquidSwitchPattern.In, distance); LiquidPipeSwitch.StartNew.SetLiquidName(EquipmentNames.Titration2PotassiumPermanganate).SetPattern(LiquidSwitchPattern.Out); _dataManager.Update().Invoke(it => it.Status.Set(0))(it => it.Name.Equals(StateMachineName.POTASSIUM2PERMANGANATE_LOCK)); logger.LogInformation(titrationTask.Source + "加液自动吸液解锁高锰酸盐"); } finally { } } } } } }