天益Wms新增,电梯调度相关操作
This commit is contained in:
@@ -163,15 +163,12 @@ Global
|
||||
{9FA1FB84-71AB-42A7-9570-F856A4B1EBAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9FA1FB84-71AB-42A7-9570-F856A4B1EBAB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9FA1FB84-71AB-42A7-9570-F856A4B1EBAB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9FA1FB84-71AB-42A7-9570-F856A4B1EBAB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{135D0C0A-9B95-45F2-BE5F-01286F6BB234}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{135D0C0A-9B95-45F2-BE5F-01286F6BB234}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{135D0C0A-9B95-45F2-BE5F-01286F6BB234}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{135D0C0A-9B95-45F2-BE5F-01286F6BB234}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D1135D42-7CD0-4579-82B3-D2B121FCE954}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D1135D42-7CD0-4579-82B3-D2B121FCE954}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D1135D42-7CD0-4579-82B3-D2B121FCE954}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D1135D42-7CD0-4579-82B3-D2B121FCE954}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8D3E0381-4B3D-4F44-81C8-535E28418A1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8D3E0381-4B3D-4F44-81C8-535E28418A1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8D3E0381-4B3D-4F44-81C8-535E28418A1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@@ -283,15 +280,12 @@ Global
|
||||
{EE11B516-1B20-44E0-8691-A532B6F7B2EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EE11B516-1B20-44E0-8691-A532B6F7B2EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EE11B516-1B20-44E0-8691-A532B6F7B2EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EE11B516-1B20-44E0-8691-A532B6F7B2EC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{461075DC-9C3A-45BB-97CC-939A2EBCEA4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{461075DC-9C3A-45BB-97CC-939A2EBCEA4E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{461075DC-9C3A-45BB-97CC-939A2EBCEA4E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{461075DC-9C3A-45BB-97CC-939A2EBCEA4E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3CCF286D-4C49-49E3-8AB1-2B1216E0ACFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3CCF286D-4C49-49E3-8AB1-2B1216E0ACFA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3CCF286D-4C49-49E3-8AB1-2B1216E0ACFA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3CCF286D-4C49-49E3-8AB1-2B1216E0ACFA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{CA896F39-32F4-44C9-B512-A21A0363EB95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CA896F39-32F4-44C9-B512-A21A0363EB95}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CA896F39-32F4-44C9-B512-A21A0363EB95}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Tnb.WarehouseMgr.Entities.Configs
|
||||
{
|
||||
public class ElevatorControlConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备名称
|
||||
/// </summary>
|
||||
public string DevName { get; set; }
|
||||
public string token { get; set; }
|
||||
/// <summary>
|
||||
/// 获取设备标签列表url
|
||||
/// </summary>
|
||||
public string GetTagListUrl { get; set; }
|
||||
/// <summary>
|
||||
/// 获取设备单个标签url
|
||||
/// </summary>
|
||||
public string GetTagUrl { get; set; }
|
||||
/// <summary>
|
||||
/// 写入设备标签属性url
|
||||
/// </summary>
|
||||
public string WriteTagUrl { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
59
WarehouseMgr/Tnb.WarehouseMgr/AgvHeartbeatMonitorService.cs
Normal file
59
WarehouseMgr/Tnb.WarehouseMgr/AgvHeartbeatMonitorService.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using JNPF;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Tnb.Common.Extension;
|
||||
using Tnb.Common.Utils;
|
||||
using Tnb.WarehouseMgr.Entities.Configs;
|
||||
|
||||
namespace Tnb.WarehouseMgr
|
||||
{
|
||||
/// <summary>
|
||||
/// Agv心跳检测服务
|
||||
/// </summary>
|
||||
public class AgvHeartbeatMonitorService : BackgroundService
|
||||
{
|
||||
private readonly ElevatorControlConfiguration _elevatorControlConfiguration;
|
||||
public bool IsStarted { get; set; }
|
||||
|
||||
public AgvHeartbeatMonitorService()
|
||||
{
|
||||
_elevatorControlConfiguration = App.Configuration.Build<ElevatorControlConfiguration>();
|
||||
}
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
IsStarted = true;
|
||||
var parameter = new Dictionary<string, string>();
|
||||
parameter["DevName"] = _elevatorControlConfiguration.DevName;
|
||||
parameter["TagName"] = "AGVKeepalive";
|
||||
parameter["Value"] = "123";
|
||||
parameter["token"] = _elevatorControlConfiguration.token;
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
await HttpClientHelper.GetAsync(_elevatorControlConfiguration.WriteTagUrl, parameter);
|
||||
await Task.Delay(TimeSpan.FromMinutes(1));
|
||||
}
|
||||
}
|
||||
|
||||
public override Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
IsStarted = false;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
public static class AgvHeartbeatMonitorServiceExtenstions
|
||||
{
|
||||
public static IServiceCollection AddAgvHeartbeatMonitor(this IServiceCollection services)
|
||||
{
|
||||
return services.AddSingleton<BackgroundService, AgvHeartbeatMonitorService>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
328
WarehouseMgr/Tnb.WarehouseMgr/ElevatorControlService.cs
Normal file
328
WarehouseMgr/Tnb.WarehouseMgr/ElevatorControlService.cs
Normal file
@@ -0,0 +1,328 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using JNPF;
|
||||
using JNPF.DependencyInjection;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using MimeKit.Cryptography;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Tnb.Common.Extension;
|
||||
using Tnb.Common.Utils;
|
||||
using Tnb.WarehouseMgr.Entities.Configs;
|
||||
|
||||
namespace Tnb.WarehouseMgr
|
||||
{
|
||||
/// <summary>
|
||||
/// 电梯控制业务服务类
|
||||
/// </summary>
|
||||
public class ElevatorControlService : BaseWareHouseService
|
||||
{
|
||||
private readonly ElevatorControlConfiguration _elevatorCtlCfg = new();
|
||||
private readonly BackgroundService _agvHeartbeatMonitor;
|
||||
private static Dictionary<string, Func<BackgroundService, bool>> _fetchStartedStausValue = new();
|
||||
private bool isFrontDoorBit = false; //是否到前门位
|
||||
|
||||
public ElevatorControlService(BackgroundService agvHeartbeatMonitorService)
|
||||
{
|
||||
_elevatorCtlCfg = App.Configuration.Build<ElevatorControlConfiguration>();
|
||||
_agvHeartbeatMonitor = agvHeartbeatMonitorService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 一楼电梯操作流程
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
/// <summary>
|
||||
/// 三楼电梯操作流程
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<dynamic> ThreeFloorElevatorFlow()
|
||||
{
|
||||
//监听电梯门是否为关闭的状态
|
||||
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 当前
|
||||
{
|
||||
|
||||
|
||||
//向电梯发送前门开门指令
|
||||
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)
|
||||
{
|
||||
var tcs = new TaskCompletionSource<object>();
|
||||
dynamic reqParam = new ExpandoObject();
|
||||
reqParam.DevName = _elevatorCtlCfg.DevName;
|
||||
reqParam.TagName = tagName;
|
||||
reqParam.value = value;
|
||||
reqParam.token = _elevatorCtlCfg.token;
|
||||
tcs.SetResult(reqParam);
|
||||
return tcs.Task;
|
||||
|
||||
}
|
||||
|
||||
private Task<Dictionary<string, string>> SetParameter(dynamic obj)
|
||||
{
|
||||
var parameters = new Dictionary<string, string>()
|
||||
{
|
||||
["DevName"] = _elevatorCtlCfg.DevName,
|
||||
["token"] = _elevatorCtlCfg.token,
|
||||
};
|
||||
var dynamicDic = obj as IDictionary<string, object>;
|
||||
if (dynamicDic != null)
|
||||
{
|
||||
foreach (var (k, v) in dynamicDic)
|
||||
{
|
||||
parameters[k] = v?.ToString() ?? string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
return Task.FromResult(parameters);
|
||||
}
|
||||
/// <summary>
|
||||
/// 向系统发送开关门指令
|
||||
/// </summary>
|
||||
/// <param name="value">开关门指令</param>
|
||||
/// <returns></returns>
|
||||
private async Task SendOpenCloseCmd(int value)
|
||||
{
|
||||
var dicCommand = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
dicCommand["DevName"] = _elevatorCtlCfg.DevName;
|
||||
dicCommand["token"] = _elevatorCtlCfg.token;
|
||||
dicCommand["TagName"] = "DoorExecute";
|
||||
dicCommand["Value"] = value.ToString();
|
||||
await HttpClientHelper.GetAsync(_elevatorCtlCfg.WriteTagUrl, pars: dicCommand);
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置Agv控制请求状态
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
private async Task<dynamic> SetAgvControlStatus(int value)
|
||||
{
|
||||
var dicCommand = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
dicCommand["DevName"] = _elevatorCtlCfg.DevName;
|
||||
dicCommand["token"] = _elevatorCtlCfg.token;
|
||||
dicCommand["TagName"] = "AGVControl";
|
||||
dicCommand["Value"] = value.ToString();
|
||||
return await HttpClientHelper.GetAsync(_elevatorCtlCfg.WriteTagUrl, pars: dicCommand);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 向指定的标签属性写入值
|
||||
/// </summary>
|
||||
/// <param name="tagName"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<dynamic> WriteTagAsync(string tagName, int value)
|
||||
{
|
||||
var dicCommand = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
dicCommand["DevName"] = _elevatorCtlCfg.DevName;
|
||||
dicCommand["token"] = _elevatorCtlCfg.token;
|
||||
dicCommand["TagName"] = tagName;
|
||||
dicCommand["Value"] = value.ToString();
|
||||
return await HttpClientHelper.GetAsync(_elevatorCtlCfg.WriteTagUrl, pars: dicCommand);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据标签名称获取标签值
|
||||
/// </summary>
|
||||
/// <param name="tagName"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
private async Task<int> GetTagAsync(string tagName)
|
||||
{
|
||||
var dicCommand = new Dictionary<string, string>();
|
||||
dicCommand["DevName"] = _elevatorCtlCfg.DevName;
|
||||
dicCommand["token"] = _elevatorCtlCfg.token;
|
||||
dicCommand["TagName"] = tagName;
|
||||
var result = await HttpClientHelper.GetAsync(_elevatorCtlCfg.GetTagUrl, pars: dicCommand);
|
||||
JObject jo = JObject.Parse(result);
|
||||
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)
|
||||
{
|
||||
(int sysStatus, int runStatus, int floorNo) multi = (-1, -1, -1);
|
||||
var pars = new Dictionary<string, string>();
|
||||
pars["DevName"] = _elevatorCtlCfg.DevName;
|
||||
pars["Pos"] = "1";
|
||||
pars["Count"] = "4";
|
||||
pars["token"] = _elevatorCtlCfg.token;
|
||||
var url = _elevatorCtlCfg.GetTagListUrl;
|
||||
var systemInfo = await HttpClientHelper.GetAsync(url, pars: pars);
|
||||
var jo = JObject.Parse(systemInfo);
|
||||
var objs = jo["Items"].Values<JObject>().ToList();
|
||||
if (objs?.Count == 4)
|
||||
{
|
||||
if (objs[0].Value<string>("Name").Equals("SysStatus")
|
||||
&& 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"));
|
||||
}
|
||||
}
|
||||
return multi;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"DevName": "Elevator1",
|
||||
"token": "780BE4144636CF47DDF3920B0F1D069B",
|
||||
"GetTagListUrl": "http://192.168.11.110:9100/Dev/GetTagList",
|
||||
"GetTagUrl": "http://192.168.11.110:9100/Dev/GetTag",
|
||||
"WriteTagUrl": "http://192.168.11.110:9100/Dev/writeTag"
|
||||
}
|
||||
@@ -67,6 +67,8 @@ public class Startup : AppStartup
|
||||
|
||||
//定时任务
|
||||
services.AddTimedTaskService();
|
||||
//Agv心跳监听服务
|
||||
services.AddAgvHeartbeatMonitor();
|
||||
//services.AddHostedService<TimedTaskBackgroundService>();
|
||||
|
||||
}
|
||||
|
||||
@@ -114,6 +114,7 @@ namespace Tnb.Common.Utils
|
||||
if (pars?.Count > 0)
|
||||
{
|
||||
reqUri = QueryHelpers.AddQueryString(url, pars);
|
||||
//await Console.Out.WriteLineAsync(reqUri);
|
||||
}
|
||||
if (headers?.Count > 0)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user