1、任务执行新增,更具目标库位判断是否为电梯库位进行呼梯操作

2、放货确认接口新增代码逻辑
This commit is contained in:
alex
2023-09-27 17:58:13 +08:00
parent c34762b0b3
commit 471d614cf2
12 changed files with 489 additions and 166 deletions

View File

@@ -6,6 +6,7 @@ using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using JNPF;
using JNPF.Common.Extension;
using JNPF.DependencyInjection;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
@@ -15,13 +16,16 @@ using Newtonsoft.Json.Linq;
using Tnb.Common.Extension;
using Tnb.Common.Utils;
using Tnb.WarehouseMgr.Entities.Configs;
using Tnb.WarehouseMgr.Entities.Consts;
using Tnb.WarehouseMgr.Entities.Enums;
using Tnb.WarehouseMgr.Interfaces;
namespace Tnb.WarehouseMgr
{
/// <summary>
/// 电梯控制业务服务类
/// </summary>
public class ElevatorControlService : BaseWareHouseService
public class ElevatorControlService : BaseWareHouseService, IElevatorControlService
{
private readonly ElevatorControlConfiguration _elevatorCtlCfg = new();
private readonly BackgroundService _agvHeartbeatMonitor;
@@ -41,53 +45,57 @@ namespace Tnb.WarehouseMgr
[HttpPost]
public async Task<dynamic> FirstFloorElevatorFlow(string value)
{
CancellationTokenSource cts = new CancellationTokenSource();//扩展用
//获取电梯状态
(int sysStatus, int runStatus, int floorNo) multi = (-1, -1, -1);
do
{
multi = await GetElevatorStatus(CancellationToken.None);
await Task.Delay(2000);
} while (multi.sysStatus != 3 && multi.runStatus != 0);
if (multi.sysStatus == 3 && multi.runStatus == 0 && multi.floorNo != 1)
{
//如果不是1楼,判断电梯状态,如果电梯是空闲的向电梯发送一个到一楼的指令
var wirteRes = await SetAgvControlStatus(0);
JObject jo = JObject.Parse(wirteRes);
//CancellationTokenSource cts = new CancellationTokenSource();//扩展用
////如果不是1楼,判断电梯状态,如果电梯是空闲的向电梯发送一个到一楼的指令
//var wirteRes = await SetAgvControlStatus(1);
//JObject jo = JObject.Parse(wirteRes);
//var propName = "IsStarted";
//if (!_fetchStartedStausValue.TryGetValue(propName, out var func))
//{
// var isStartedProp = _agvHeartbeatMonitor.GetType().GetProperty(propName);
// var paramExp = Expression.Parameter(typeof(BackgroundService), "_agvHeartbeatMonitor");
// var propExp = Expression.Property(Expression.ConvertChecked(paramExp, isStartedProp.DeclaringType), isStartedProp);
// var body = Expression.Lambda<System.Func<BackgroundService, Boolean>>(propExp, paramExp);
// func = body.Compile();
// _fetchStartedStausValue[propName] = func;
//}
//var isStarted = func(_agvHeartbeatMonitor);
//if (!isStarted)
//{
// _agvHeartbeatMonitor.StartAsync(cts.Token);
//}
if (true) //此处为Agv到一楼开门位通知操作目前默认为true
{
var propName = "IsStarted";
if (!_fetchStartedStausValue.TryGetValue(propName, out var func))
{
var isStartedProp = _agvHeartbeatMonitor.GetType().GetProperty(propName);
var paramExp = Expression.Parameter(typeof(BackgroundService), "_agvHeartbeatMonitor");
var propExp = Expression.Property(Expression.ConvertChecked(paramExp, isStartedProp.DeclaringType), isStartedProp);
var body = Expression.Lambda<System.Func<BackgroundService, Boolean>>(propExp, paramExp);
func = body.Compile();
_fetchStartedStausValue[propName] = func;
}
var isStarted = func(_agvHeartbeatMonitor);
if (!isStarted)
{
_agvHeartbeatMonitor.StartAsync(cts.Token);
}
//向电梯发送前门开门指令
await SendOpenCloseCmd(3);
//获取门状态 是否为 开门到位保持
var doorStatus = await GetTagAsync("DoorStatus");
if (doorStatus == 3)
{
//通知Agv进入电梯放货,默认为true
if (true)
{
//向电梯发送关门指令
await SendOpenCloseCmd(4);
}
}
////获取电梯状态
//(int sysStatus, int runStatus, int floorNo) multi = (-1, -1, -1);
//do
//{
// //multi = await GetElevatorStatus(CancellationToken.None);
// await Task.Delay(2000);
//} while (multi.sysStatus != 3 && multi.runStatus != 0);
//if (multi.sysStatus == 3 && multi.runStatus == 0 && multi.floorNo != 1)
//{
// await WriteTagAsync("FloorExecute", 1);
}
}
// if (true) //此处为Agv到一楼开门位通知操作目前默认为true
// {
// //向电梯发送前门开门指令
// await SendOpenCloseCmd(3);
// //获取门状态 是否为 开门到位保持
// var doorStatus = await GetTagAsync("DoorStatus");
// if (doorStatus == 3)
// {
// //通知Agv进入电梯放货,默认为true
// if (true)
// {
// //向电梯发送关门指令
// await SendOpenCloseCmd(4);
// }
// }
// }
//}
return Task.FromResult(0);
}
/// <summary>
@@ -97,78 +105,59 @@ namespace Tnb.WarehouseMgr
[HttpPost]
public async Task<dynamic> ThreeFloorElevatorFlow()
{
//test by close door
_agvHeartbeatMonitor.StartAsync(CancellationToken.None);
//await SendOpenCloseCmd(4);
//await SetAgvControlStatus(1);
//监听电梯门是否为关闭的状态
var dataStatus = 0;
do
{
dataStatus = await GetTagAsync("DoorStatus");
} while (dataStatus != 4);
if (dataStatus == 4)
{
//根据状态确认关闭后向电梯发送指令从1~3楼 //FloorExecute 楼层触发
await WriteTagAsync("FloorExecute", 48);
//获取电梯到达3楼的到位信号
(_, int runStatus, int floorNo) = (-1, -1, -1);
do
{
var multi = await GetElevatorStatus(CancellationToken.None);
runStatus = multi.sysStatus; floorNo = multi.floorNo;
} while (runStatus != 0 && floorNo != 3);
// 控制电梯到达指定楼层默认开门的行为,改为默认不开门 条件Agv 到达3楼开门位时为true
if (true)//3楼Agv到达开门位后,向电梯发送开门指令, 默认true 当前
{
//var dataStatus = 0;
//do
//{
// dataStatus = await GetTagAsync("DoorStatus");
//} while (dataStatus != 4);
//if (dataStatus == 4)
//{
// //根据状态确认关闭后向电梯发送指令从1~3楼 //FloorExecute 楼层触发
// await WriteTagAsync("FloorExecute", 1);
// //获取电梯到达3楼的到位信号
// (_, int runStatus, int floorNo) = (-1, -1, -1);
// do
// {
// var multi = await GetElevatorStatus(CancellationToken.None);
// runStatus = multi.sysStatus; floorNo = multi.floorNo;
// } while (runStatus != 0 && floorNo != 3);
// // 控制电梯到达指定楼层默认开门的行为,改为默认不开门 条件:Agv 到达3楼开门位时,为true
// if (true)//3楼Agv到达开门位后向电梯发送开门指令, 默认true 当前
// {
//向电梯发送前门开门指令
await SendOpenCloseCmd(3);
//获取门状态 是否为 开门到位保持
var doorStatus = await GetTagAsync("DoorStatus");
if (doorStatus == 3) //开门到位保持状态
{
//通知Agv进入电梯取货
//向电梯发送关门指令
await SendOpenCloseCmd(4);
doorStatus = await GetTagAsync("DoorStatus");
if (doorStatus == 4) //门状态,为关门到位保持
{
//解锁Agv状态将其至为
var agvStatus = await GetTagAsync("AGVStatus");
if (agvStatus != 2)
{
await SetAgvControlStatus(0);
}
}
}
}
}
// //向电梯发送前门开门指令
// await SendOpenCloseCmd(3);
// //获取门状态 是否为 开门到位保持
// var doorStatus = await GetTagAsync("DoorStatus");
// if (doorStatus == 3) //开门到位保持状态
// {
// //通知Agv进入电梯取货
// //向电梯发送关门指令
// await SendOpenCloseCmd(4);
// doorStatus = await GetTagAsync("DoorStatus");
// if (doorStatus == 4) //门状态,为关门到位保持
// {
// //解锁Agv状态将其至为
// var agvStatus = await GetTagAsync("AGVStatus");
// if (agvStatus != 2)
// {
// await SetAgvControlStatus(0);
// }
// }
// }
// }
//}
return Task.FromResult(0);
}
/// <summary>
/// x2server测试
/// </summary>
/// <returns></returns>
[HttpGet]
public async Task<dynamic> X2ServerTest()
{
//var r = new Random();
int currentValue = 0;
while (true)
{
var readRes = await GetElevatorStatus(CancellationToken.None);
await Console.Out.WriteLineAsync($"接收结果:{readRes}");
currentValue = 1 - currentValue; // 切换为0或1
dynamic obj = new ExpandoObject();
obj.TagName = "AGVControl";
obj.Value = currentValue;
var parameter = await SetParameter(obj);
var wirteRes = await HttpClientHelper.GetAsync(_elevatorCtlCfg.WriteTagUrl, pars: parameter);
await Console.Out.WriteLineAsync($"写入结果:{wirteRes}");
await Task.Delay(1000);
}
}
private Task<object> SetRequestParameter(string tagName, object value)
{
@@ -206,14 +195,23 @@ namespace Tnb.WarehouseMgr
/// </summary>
/// <param name="value">开关门指令</param>
/// <returns></returns>
private async Task SendOpenCloseCmd(int value)
public async Task<bool> SendOpenCloseCmd(string devName, int value)
{
var dicCommand = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
dicCommand["DevName"] = _elevatorCtlCfg.DevName;
dicCommand["DevName"] = devName;
dicCommand["token"] = _elevatorCtlCfg.token;
dicCommand["TagName"] = "DoorExecute";
dicCommand["Value"] = value.ToString();
await HttpClientHelper.GetAsync(_elevatorCtlCfg.WriteTagUrl, pars: dicCommand);
var result = await HttpClientHelper.GetAsync(_elevatorCtlCfg.WriteTagUrl, pars: dicCommand);
if (result.IsNotEmptyOrNull())
{
JObject jo = JObject.Parse(result);
if (jo != null)
{
return jo.Value<string>("Result").Equals("Ok", StringComparison.OrdinalIgnoreCase);
}
}
return false;
}
/// <summary>
/// 设置Agv控制请求状态
@@ -225,9 +223,9 @@ namespace Tnb.WarehouseMgr
{
var dicCommand = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
dicCommand["DevName"] = _elevatorCtlCfg.DevName;
dicCommand["token"] = _elevatorCtlCfg.token;
dicCommand["TagName"] = "AGVControl";
dicCommand["Value"] = value.ToString();
dicCommand["token"] = _elevatorCtlCfg.token;
return await HttpClientHelper.GetAsync(_elevatorCtlCfg.WriteTagUrl, pars: dicCommand);
}
@@ -237,10 +235,10 @@ namespace Tnb.WarehouseMgr
/// <param name="tagName"></param>
/// <param name="value"></param>
/// <returns></returns>
private async Task<dynamic> WriteTagAsync(string tagName, int value)
public async Task<dynamic> WriteTagAsync(string devName, string tagName, int value)
{
var dicCommand = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
dicCommand["DevName"] = _elevatorCtlCfg.DevName;
dicCommand["DevName"] = devName;
dicCommand["token"] = _elevatorCtlCfg.token;
dicCommand["TagName"] = tagName;
dicCommand["Value"] = value.ToString();
@@ -253,10 +251,10 @@ namespace Tnb.WarehouseMgr
/// <param name="tagName"></param>
/// <returns></returns>
private async Task<int> GetTagAsync(string tagName)
public async Task<int> GetTagAsync(string devName, string tagName)
{
var dicCommand = new Dictionary<string, string>();
dicCommand["DevName"] = _elevatorCtlCfg.DevName;
dicCommand["DevName"] = devName;
dicCommand["token"] = _elevatorCtlCfg.token;
dicCommand["TagName"] = tagName;
var result = await HttpClientHelper.GetAsync(_elevatorCtlCfg.GetTagUrl, pars: dicCommand);
@@ -264,47 +262,17 @@ namespace Tnb.WarehouseMgr
return jo.Value<int>("V");
}
/// <summary>
/// 获取Agv状态 0正常状态 1等待进入 AGV 状态 2 AGV 运行状态
/// </summary>
/// <returns></returns>
//private async Task<int> GetAgvStatus()
//{
// var dicCommand = new Dictionary<string, string>();
// dicCommand["DevName"] = _elevatorCtlCfg.DevName;
// dicCommand["token"] = _elevatorCtlCfg.token;
// dicCommand["TagName"] = "AGVStatus";
// var result = await HttpClientHelper.GetAsync(_elevatorCtlCfg.GetTagUrl, pars: dicCommand);
// JObject jo = JObject.Parse(result);
// return jo.Value<int>("V");
//}
/// <summary>
/// 获取门状态
/// </summary>
/// <returns></returns>
//private async Task<int> GetDoorStatus()
//{
// var doorStatusParam = new Dictionary<string, string>();
// doorStatusParam["DevName"] = _elevatorCtlCfg.DevName;
// doorStatusParam["token"] = _elevatorCtlCfg.token;
// doorStatusParam["TagName"] = "DoorStatus";
// var result = await HttpClientHelper.GetAsync(_elevatorCtlCfg.GetTagUrl, pars: doorStatusParam);
// JObject jo = JObject.Parse(result);
// return jo.Value<int>("V");
//}
/// <summary>
/// 获取电梯状态
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
private async Task<(int sysStatus, int runStatus, int floorNo)> GetElevatorStatus(CancellationToken token)
public async Task<(int sysStatus, int runStatus, int floorNo, int doorStatus, int agvStatus)> GetElevatorStatus(string devName, CancellationToken token)
{
(int sysStatus, int runStatus, int floorNo) multi = (-1, -1, -1);
(int sysStatus, int runStatus, int floorNo, int doorStatus, int agvStatus) multi = (-1, -1, -1, -1, -1);
var pars = new Dictionary<string, string>();
pars["DevName"] = _elevatorCtlCfg.DevName;
pars["DevName"] = devName;
pars["Pos"] = "1";
pars["Count"] = "4";
pars["token"] = _elevatorCtlCfg.token;
@@ -318,11 +286,38 @@ namespace Tnb.WarehouseMgr
&& objs[1].Value<string>("Name").Equals("RunStatus")
&& objs[3].Value<string>("Name").Equals("FloorNo"))
{
multi = ((objs[0].Value<int>("V")), objs[1].Value<int>("V"), objs[2].Value<int>("V"));
multi = (objs[0].Value<int>("V"), objs[1].Value<int>("V"), objs[3].Value<int>("V"), objs[2].Value<int>("V"), objs[10].Value<int>("V"));
}
}
return multi;
}
/// <summary>
/// 检查Agv状态
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<bool> CheckAgvStatus(string devName, CancellationToken cancellationToken)
{
var isInAgvStatus = false;
var agvStatus = await GetTagAsync(devName, ElevatorConsts.AGVStatus);
if (agvStatus.ToEnum<EnumAgvStatus>() != EnumAgvStatus.AGV运行状态)
{
var result = await WriteTagAsync(devName, ElevatorConsts.AGVControl, 1);
JObject jo = JObject.Parse(result);
if (jo != null && jo.Value<string>("Result").Equals("Ok", StringComparison.OrdinalIgnoreCase))
{
isInAgvStatus = true;
}
}
return isInAgvStatus;
}
}
public class ElevatorData
{
public string name { get; set; }
public string value { get; set; }
}
}