using SHJX.Service.Control.Common.Assets; namespace SHJX.Service.Control.LiquidHandler.Handler.NormalLiquidHandler { /// /// 草酸钠 /// public class Sodium2OxalateNormalLiquidHandler : INormalLiquid { private static readonly object obj_locker = new(); private static readonly ILogger logger = LogFactory.BuildLogger(typeof(Sodium2OxalateNormalLiquidHandler)); 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); try { bool writeResponse = true; DataManagerInstance.IncreaseLock(StateMachineName.SODIUMOXALATE_LOCK); logger.LogInformation("正常任务----锁定----------------草酸钠2"); LiquidVolume liquidVolume = DataManagerInstance.GetLiquidVolume(EquipmentNames.Sodium2Oxalate); if (liquidVolume is null) { throw new ArgumentException($"{EquipmentNames.Sodium2Oxalate}查询Volume为空"); } if (!liquidVolume.Enable) { return true; } LiquidAmount liquidAmount = DataManagerInstance.GetLiquidAmount(EquipmentNames.Sodium2Oxalate); if (liquidAmount is null) { throw new ArgumentException($"{EquipmentNames.Sodium2Oxalate}查询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.Sodium2Oxalate).IsArriveEndPoint; //if (ConfigInstance.IsAutomaticInLiquid && !arriveEndPoint) //{ // writeResponse = writeResponse && LiquidPipeSwitch.StartNew.SetLiquidName(EquipmentNames.Sodium2Oxalate).ExecuteOxalate(LiquidSwitchPattern.Out, distance); //} //else //{ writeResponse = writeResponse && CheckWhetherArriveEndPointOxalate().ExecuteOxalate(distance); //} //自动吸液代码 for (int i = 1; i < count; i++) { 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 //Todo:这里做液体扣减 DataManagerInstance.DecreaseLiquidTotal("SodiumOxalate", liquidVolume.SampleVolume); DataManagerInstance.DecreaseLiquidReserve("SodiumOxalate"); DataManagerInstance.DecreaseLock(StateMachineName.SODIUMOXALATE_LOCK); logger.LogInformation("正常任务----解锁----------------草酸钠2"); StateMachineName.Sodiumoxate_Lock_First = true; return writeResponse; } finally { } } private bool IsArriveEndPointOxalate { get { lock (obj_locker) { char[] readRes = EquipmentNames.Sodium2Oxalate.MotorRead(); if (readRes is null or { Length: 0 }) { return false; } bool arriveEndPoint = readRes[2].Equals('0'); return arriveEndPoint; } } } private Sodium2OxalateNormalLiquidHandler CheckWhetherArriveEndPointOxalate(LiquidSwitchPattern pattern = LiquidSwitchPattern.In) { bool arriveEndPoint = IsArriveEndPointOxalate; if (!arriveEndPoint) { LiquidMotorGoBackOxalate(pattern);//如果不在原点,则切换为出液模式 } return this ; } private bool LiquidMotorGoBackOxalate(LiquidSwitchPattern pattern) { try { if (pattern == LiquidSwitchPattern.In) { $"Sodium2OxalateSwitch1".RegisterOpen(); } else { $"Sodium2OxalateSwitch2".RegisterOpen(); } var res = EquipmentNames.Sodium2Oxalate.MotorGoBack(); logger.LogInformation("回原点/出液命令----------------草酸钠1"); Thread.Sleep(2000); int register = ConfigInstance.GetPortRegister(EquipmentNames.Sodium2Oxalate); int retryCount = 0; for (; ; ) { Thread.Sleep(5 * 100);//如果返回成功,则休眠两秒再次读取 char[] judgeRes = EquipmentNames.Sodium2Oxalate.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) { $"Sodium2OxalateSwitch1".RegisterOpen(); } else { $"Sodium2OxalateSwitch2".RegisterOpen(); } res = EquipmentNames.Sodium2Oxalate.MotorGoBack(); logger.LogInformation("回原点/出液命令----------------草酸钠1"); } if (pattern == LiquidSwitchPattern.In) { $"Sodium2OxalateSwitch1".RegisterClose(); } else { $"Sodium2OxalateSwitch2".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)), }; $"Sodium2OxalateSwitch1".RegisterOpen(); Thread.Sleep(200); bool res= EquipmentNames.Sodium2Oxalate.LiquidMotorMove(writeData); logger.LogInformation(writeData.ToString() + "---移动/吸液命令----------------草酸钠2"); $"Sodium2OxalateSwitch1".RegisterClose(); return res; } private bool ExecuteOxalateOut(LiquidSwitchPattern pattern, object value) { return LiquidMotorGoBackOxalate(pattern); } } }