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.Common.Extension;
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;
using Tnb.WarehouseMgr.Entities.Configs;
using Tnb.WarehouseMgr.Entities.Consts;
using Tnb.WarehouseMgr.Entities.Enums;
using Tnb.WarehouseMgr.Interfaces;
namespace Tnb.WarehouseMgr
{
///
/// 电梯控制业务服务类
///
public class ElevatorControlService : BaseWareHouseService, IElevatorControlService
{
private readonly ElevatorControlConfiguration _elevatorCtlCfg = new();
private readonly BackgroundService _agvHeartbeatMonitor;
private static Dictionary> _fetchStartedStausValue = new();
private bool isFrontDoorBit = false; //是否到前门位
public ElevatorControlService(BackgroundService agvHeartbeatMonitorService)
{
_elevatorCtlCfg = App.Configuration.Build();
_agvHeartbeatMonitor = agvHeartbeatMonitorService;
}
///
/// 一楼电梯操作流程
///
///
[HttpPost]
public async Task FirstFloorElevatorFlow(string value)
{
//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>(propExp, paramExp);
// func = body.Compile();
// _fetchStartedStausValue[propName] = func;
//}
//var isStarted = func(_agvHeartbeatMonitor);
//if (!isStarted)
//{
// _agvHeartbeatMonitor.StartAsync(cts.Token);
//}
////获取电梯状态
//(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);
}
///
/// 三楼电梯操作流程
///
///
[HttpPost]
public async Task 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", 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);
// }
// }
// }
// }
//}
return Task.FromResult(0);
}
private Task