using Polly; using System; using System.Threading; using SHJX.Service.ServerClient; using SHJX.Service.Model.Control; namespace SHJX.Service.Control.PortOperate.Interface { /// /// 泵操作 /// public abstract class PortOperateImp { protected readonly OptClient _client; protected string OpName { get; set; } public PortOperateImp(OptClient optClient) { _client = optClient; } /// /// 操作液体的方式 /// /// 体积 /// public virtual bool LiquidOperation(string pipeName, long quantity) { CutPipe(pipeName); return MotorWrite(quantity); //吸液 } /// /// 返回原点 /// /// 管道名称 public virtual void GoBackOriginalPosition(string pipeName) { CutPipe(pipeName); GoBack(); } /// /// 返回原点 /// private void GoBack() { PortArgs gobackArg = new() { TypeName = OpName, WriteWay = WriteWay.GoBack }; bool gb_write; do { gb_write = _client.Factory(OpName).Write(gobackArg); Thread.Sleep(2000); } while (!gb_write); bool res; do { char[] readRes = Read(); if (readRes is null or { Length: 0 }) { Thread.Sleep(1000); res = false; continue; }; res = readRes[2].Equals('0'); } while (!res); } /// /// 到达限位 /// /// public bool ArriveEndPoint() { var readRes = Read(); if (readRes is null or { Length: 0 }) return false; return readRes[2].Equals('0'); } /// /// 读取寄存器 /// /// protected char[] Read() { PortArgs readArgs = new() { TypeName = OpName }; var readRes = _client.Factory(OpName).Read(readArgs) as char[]; return readRes; } /// /// 切换管道 /// /// protected virtual void CutPipe(string pipeName) { var readRes = Read(); if (readRes is null or { Length: 0 }) return; OptPipe(() => { var readRes = Read(); if (readRes is null or { Length: 0 }) { Thread.Sleep(1000); return false; } var res = pipeName switch { "In" => readRes[5].Equals('0'), "Out" => readRes[6].Equals('0'), _ => false, }; return res; }); } /// /// 选择管道(出 or 吸) /// /// protected void OptPipe(Func func) { var res = func.Invoke(); if (res) return; #region 打开寄存器 PortArgs switchArg = new() { TypeName = OpName, WriteWay = WriteWay.Normotopia }; bool openRes; do { openRes = _client.Factory(OpName).Write(switchArg); Thread.Sleep(1000); } while (!openRes); #endregion Policy.HandleResult(arg => arg.Equals(false)) .RetryForever(_ => { MotorWrite(-100); }) .Execute(func); #region 关闭该寄存器 switchArg.WriteWay = WriteWay.Antiposition; do { openRes = _client.Factory(OpName).Write(switchArg); Thread.Sleep(1000); } while (!openRes); #endregion } /// /// 写入脉冲 /// /// protected bool MotorWrite(long distance) { PortArgs args = new() { TypeName = OpName, WriteWay = WriteWay.Move, Distance = distance }; var res = _client.Factory(OpName).Write(args); int speedWaitTime = OpName switch { "SilverSulfate" => 300, _ => 500, }; Thread.Sleep((int)(Math.Abs(distance) / 20000 * speedWaitTime)); return res; } } }