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;
}
}
}