using SHJX.Service.Control.Common.Assets; namespace SHJX.Service.Control.LiquidHandler.Handler.NormalLiquidHandler { /// /// 草酸钠 /// public class Sodium1OxalateNormalLiquidHandler : INormalLiquid { private static readonly object obj_locker = new(); private static readonly ILogger logger = LogFactory.BuildLogger(typeof(Sodium1OxalateNormalLiquidHandler)); public bool Execute(Action action = null, params object[] args) { do { Thread.Sleep(500); } while (!StateMachineName.Sodiumoxate_Lock_First); StateMachineName.Sodiumoxate_Lock_First = false; bool locker; do { StateMachine state = DataManagerInstance.QueryStateMachine(StateMachineName.SODIUMOXALATE_LOCK); locker = state.Status > 0; } while (locker); //using StateMachineDisposable stateMachine = new(StateMachineName.SODIUMOXALATE_LOCK); try { bool writeResponse = true; DataManagerInstance.IncreaseLock(StateMachineName.SODIUMOXALATE_LOCK); logger.LogInformation("正常任务----锁定----------------草酸钠1"); LiquidVolume liquidVolume = DataManagerInstance.GetLiquidVolume(EquipmentNames.Sodium1Oxalate); if (liquidVolume is null) { throw new ArgumentException($"{EquipmentNames.Sodium1Oxalate}查询Volume为空"); } if (!liquidVolume.Enable) { return true; } LiquidAmount liquidAmount = DataManagerInstance.GetLiquidAmount(EquipmentNames.Sodium1Oxalate); if (liquidAmount is null) { throw new ArgumentException($"{EquipmentNames.Sodium1Oxalate}查询Amount为空"); } #region Change Before double count = Math.Floor(liquidVolume.SampleVolume / liquidAmount.Capacity); double residue = liquidVolume.SampleVolume % liquidAmount.Capacity; int distance; //自动吸液代码 distance = Convert.ToInt32(Math.Round(liquidAmount.Capacity / liquidAmount.Amount * liquidAmount.ConvertRatio)); // bool arriveEndPoint = LiquidPipeSwitch.StartNew.SetLiquidName(EquipmentNames.Sodium1Oxalate).IsArriveEndPoint; //if (ConfigInstance.IsAutomaticInLiquid && !arriveEndPoint) //{ // writeResponse = writeResponse && LiquidPipeSwitch.StartNew.SetLiquidName(EquipmentNames.Sodium1Oxalate).ExecuteOxalate(LiquidSwitchPattern.Out, distance); //} //else //{ writeResponse = CheckWhetherArriveEndPointOxalate().ExecuteOxalate(distance); //} //自动吸液代码 for (int i = 1; i < count; i++)//上面出液一次所以i是从1开始 { distance = Convert.ToInt32(Math.Round(liquidAmount.Capacity / liquidAmount.Amount * liquidAmount.ConvertRatio)); writeResponse = writeResponse && CheckWhetherArriveEndPointOxalate().ExecuteOxalate(distance); } if (residue > 0) { distance = Convert.ToInt32(Math.Round(residue / liquidAmount.Amount * liquidAmount.ConvertRatio)); writeResponse = writeResponse && CheckWhetherArriveEndPointOxalate().ExecuteOxalate(distance); } #endregion #region Change After //int distance = Convert.ToInt32(Math.Round((liquidVolume.SampleVolume > liquidAmount.Capacity ? liquidAmount.Capacity : liquidVolume.SampleVolume) / liquidAmount.Amount * liquidAmount.ConvertRatio)); //bool arriveEndPoint = LiquidPipeSwitch.StartNew.SetLiquidName(EquipmentNames.Sodium1Oxalate).IsArriveEndPoint; ////if (ConfigInstance.IsAutomaticInLiquid) ////{ //if (arriveEndPoint) //{ // writeResponse = writeResponse && LiquidPipeSwitch.StartNew.SetLiquidName(EquipmentNames.Sodium1Oxalate).ExecuteOxalate(distance); //} //else //{ // writeResponse = writeResponse && LiquidPipeSwitch.StartNew.SetLiquidName(EquipmentNames.Sodium1Oxalate).LiquidMotorGoBackOxalate(LiquidSwitchPattern.Out); // writeResponse = writeResponse && LiquidPipeSwitch.StartNew.SetLiquidName(EquipmentNames.Sodium1Oxalate).ExecuteOxalate(distance); //} ////} ////else ////{ //// writeResponse = writeResponse && LiquidPipeSwitch.StartNew.SetLiquidName(EquipmentNames.Sodium1Oxalate).ExecuteOxalate(distance); ////} #endregion //Todo:这里做液体扣减 DataManagerInstance.DecreaseLiquidTotal("SodiumOxalate", liquidVolume.SampleVolume); DataManagerInstance.DecreaseLiquidReserve("SodiumOxalate"); DataManagerInstance.DecreaseLock(StateMachineName.SODIUMOXALATE_LOCK); StateMachineName.Sodiumoxate_Lock_First = true; logger.LogInformation("正常任务----解锁----------------草酸钠1"); return writeResponse; } finally { } } private bool IsArriveEndPointOxalate { get { lock (obj_locker) { char[] readRes = EquipmentNames.Sodium1Oxalate.MotorRead(); if (readRes is null or { Length: 0 }) { return false; } bool arriveEndPoint = readRes[2].Equals('0'); return arriveEndPoint; } } } private Sodium1OxalateNormalLiquidHandler CheckWhetherArriveEndPointOxalate(LiquidSwitchPattern pattern = LiquidSwitchPattern.In) { bool arriveEndPoint = IsArriveEndPointOxalate; if (!arriveEndPoint) { LiquidMotorGoBackOxalate(pattern);//如果不在原点,则切换为出液模式 } return this; } private bool LiquidMotorGoBackOxalate(LiquidSwitchPattern pattern) { try { if (pattern == LiquidSwitchPattern.In) { $"Sodium1OxalateSwitch1".RegisterOpen(); } else { $"Sodium1OxalateSwitch2".RegisterOpen(); } var res = EquipmentNames.Sodium1Oxalate.MotorGoBack(); logger.LogInformation("回原点/出液命令----------------草酸钠1"); Thread.Sleep(2000); int register = ConfigInstance.GetPortRegister(EquipmentNames.Sodium1Oxalate); int retryCount = 0; for (; ; ) { Thread.Sleep(5 * 100);//如果返回成功,则休眠两秒再次读取 char[] judgeRes = EquipmentNames.Sodium1Oxalate.MotorRead(); if (judgeRes is null or { Length: 0 }) { return false; } bool reread = false; reread = judgeRes[register - 1].Equals('0'); if (reread) { break; } retryCount++; logger.LogInformation($"下发返回原点成功后,再次读取原点信号为false,重发返回原点指令第{retryCount}次"); if (pattern == LiquidSwitchPattern.In) { $"Sodium1OxalateSwitch1".RegisterOpen(); } else { $"Sodium1OxalateSwitch2".RegisterOpen(); } res = EquipmentNames.Sodium1Oxalate.MotorGoBack(); logger.LogInformation("回原点/出液命令----------------草酸钠1"); } if (pattern == LiquidSwitchPattern.In) { $"Sodium1OxalateSwitch1".RegisterClose(); } else { $"Sodium1OxalateSwitch2".RegisterClose(); } return res; } catch (Exception ex) { logger.LogInformation($"Error:液体电机返回原点异常。Exception:{ex}"); return false; } } private bool ExecuteOxalate(object value) { bool res = ExecuteOxalateIn(LiquidSwitchPattern.In, value); return res && ExecuteOxalateOut(LiquidSwitchPattern.Out, value); } private bool ExecuteOxalateIn(LiquidSwitchPattern pattern, object value) { int writeData = pattern switch { LiquidSwitchPattern.In => -Math.Abs(Convert.ToInt32(value)), LiquidSwitchPattern.Out => Math.Abs(Convert.ToInt32(value)), _ => throw new ArgumentNullException(nameof(pattern)), }; Thread.Sleep(200); $"Sodium1OxalateSwitch1".RegisterOpen(); Thread.Sleep(200); bool res= EquipmentNames.Sodium1Oxalate.LiquidMotorMove(writeData); logger.LogInformation(writeData.ToString()+"---移动/吸液命令----------------草酸钠1"); $"Sodium1OxalateSwitch1".RegisterClose(); return res; } private bool ExecuteOxalateOut(LiquidSwitchPattern pattern, object value) { return LiquidMotorGoBackOxalate(pattern); } } }