using SHJX.Service.Control.Common.Assets; namespace SHJX.Service.Control.Execute { public class LiquidPipeSwitchTitration1 { #region Fields private string _liquidName; private static readonly object obj_locker = new(); private static readonly ILogger logger = LogFactory.BuildLogger(typeof(LiquidPipeSwitch)); #endregion private LiquidPipeSwitchTitration1() { } public static LiquidPipeSwitchTitration1 StartNew { get { lock (obj_locker) { return new(); } } } /// /// 是否原点 /// public bool IsArriveEndPoint { get { lock (obj_locker) { char[] readRes = _liquidName.MotorRead(); if (readRes is null or { Length: 0 }) { return false; } bool arriveEndPoint = readRes[2].Equals('0'); return arriveEndPoint; } } } /// /// 设置液体名称 /// /// /// public LiquidPipeSwitchTitration1 SetLiquidName(string liquidName) { _liquidName = liquidName; return this; } /// /// 检查是否在原点 /// /// public LiquidPipeSwitchTitration1 CheckWhetherArriveEndPoint(LiquidSwitchPattern pattern = LiquidSwitchPattern.In) { bool arriveEndPoint = IsArriveEndPoint; if (!arriveEndPoint ) { LiquidMotorGoBack(pattern);//如果不在原点,则切换为出液模式 } return this; } /// /// 液体电机返回原点 /// /// /// public bool LiquidMotorGoBack(LiquidSwitchPattern pattern) { SetPattern(pattern); //如果不在原点,则切换为出液模式 var res = _liquidName.MotorGoBack(); try { int register = ConfigInstance.GetPortRegister(_liquidName); int retryCount = 0; for (; ; ) { Thread.Sleep(2 * 1000);//如果返回成功,则休眠两秒再次读取 char[] judgeRes = _liquidName.MotorRead(); if (judgeRes is null or not { Length: 8 }) { return false; } bool reread = judgeRes[register - 1].Equals('0'); if (reread) { break; } retryCount++; logger.LogInformation($"下发返回原点成功后,再次读取原点信号为false,重发返回原点指令第{retryCount}次"); res = _liquidName.MotorGoBack(); } return res; } catch (Exception ex) { logger.LogInformation($"Error:液体电机返回原点异常。Exception:{ex}"); return false; } } /// /// 执行液体操作 /// /// /// public bool Execute(object value) { bool res = Execute(LiquidSwitchPattern.In, value); return res && Execute(LiquidSwitchPattern.Out, value); } public bool Execute(LiquidSwitchPattern pattern, object value) { SetPattern(pattern); int writeData = pattern switch { LiquidSwitchPattern.In => -Math.Abs(Convert.ToInt32(value)), LiquidSwitchPattern.Out => Math.Abs(Convert.ToInt32(value)), _ => throw new ArgumentNullException(nameof(pattern)), }; logger.LogInformation(_liquidName + "*****高锰酸钾1移动*****" + pattern.ToString() + writeData.ToString()); return _liquidName.LiquidMotorMove(writeData); } /// /// 设置液体模式 /// /// public void SetPattern(LiquidSwitchPattern pattern) { char[] states = _liquidName.MotorRead(); if (states is null or { Length: 0 }) { throw new ArgumentException($"{pattern}无法读取数据!"); } OptPipe(() => { char[] readRes = _liquidName.MotorRead(); if (readRes is null or { Length: 0 }) { Thread.Sleep(1000); return false; } bool res = pattern switch { LiquidSwitchPattern.In => readRes[6].Equals('0'), LiquidSwitchPattern.Out => readRes[7].Equals('0'), _ => false, }; return res; }, pattern.Equals(LiquidSwitchPattern.In) ? -1 : 1); } /// /// 选择管道(出 or 吸) /// /// private void OptPipe(Func func, int orientation) { bool res = func.Invoke(); if (res) { return; } Thread.Sleep(1000); OpenRegister(); Thread.Sleep(1000); _liquidName.LiquidMotorMove(50 * orientation); Policy.HandleResult(arg => arg.Equals(false)).RetryForever(_ => { _liquidName.LiquidMotorMove(110 * orientation); }).Execute(func); Thread.Sleep(1000); CloseRegister(); Thread.Sleep(2000); } /// /// 打开寄存器 /// private void OpenRegister() { bool openRes; do { openRes = string.Concat(_liquidName, "Switch").RegisterOpen(); Thread.Sleep(1000); } while (!openRes); } /// /// 关闭寄存器 /// private void CloseRegister() { bool closeRes; do { closeRes = string.Concat(_liquidName, "Switch").RegisterClose(); Thread.Sleep(1000); } while (!closeRes); } } }