|
|
using Autofac;
|
|
|
using Entity.Attr;
|
|
|
using Entity.Constant;
|
|
|
using Entity.DbModel.Station;
|
|
|
using HybirdFrameworkCore.Autofac;
|
|
|
using HybirdFrameworkCore.Configuration;
|
|
|
using log4net;
|
|
|
using Newtonsoft.Json;
|
|
|
using Service.Execute.Api;
|
|
|
using Service.Execute.Model;
|
|
|
using Service.Execute.Model.Tbox;
|
|
|
using Service.Execute.SwapException;
|
|
|
using Service.Execute.Utils;
|
|
|
using Service.Init;
|
|
|
using Service.Led;
|
|
|
using Service.Padar.Client;
|
|
|
using Service.Sound.SoundClient;
|
|
|
using Swapping.Business.Common;
|
|
|
using System.Media;
|
|
|
|
|
|
namespace Service.Execute.Step;
|
|
|
|
|
|
public class StationReadyState : IState
|
|
|
{
|
|
|
private readonly ILog _log = LogManager.GetLogger(typeof(StationReadyState));
|
|
|
|
|
|
|
|
|
private readonly CommonMgr _CommonMgr = AppInfo.Container.Resolve<CommonMgr>();
|
|
|
|
|
|
public static SoundClient? SoundClient { get; set; }
|
|
|
|
|
|
public static bool CanWelcomeInfo = true;
|
|
|
|
|
|
public StateResult Handle(SwappingStateMachine machine)
|
|
|
{
|
|
|
_log.Info($"'goto stationReady");
|
|
|
|
|
|
machine.Reset();
|
|
|
|
|
|
|
|
|
//判断换电站是否具备换电条件 前端页面
|
|
|
if (!IsAutoSwapping())
|
|
|
{
|
|
|
return null;
|
|
|
}
|
|
|
_CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.Idel,
|
|
|
machine);
|
|
|
|
|
|
|
|
|
////开启雷达
|
|
|
var beginRadar = ControlRadar(machine, 1);
|
|
|
if (InvokeStatus.Done != beginRadar)
|
|
|
{
|
|
|
return SwappingStateMachine.ReturnWithInvokeErr(beginRadar, ExceptionReason.None);
|
|
|
}
|
|
|
|
|
|
////调整车辆
|
|
|
var adjustCarByRadar = AdjustCarByRadar(machine);
|
|
|
if (InvokeStatus.Done != adjustCarByRadar)
|
|
|
{
|
|
|
return SwappingStateMachine.ReturnWithInvokeErr(adjustCarByRadar, ExceptionReason.None);
|
|
|
}
|
|
|
|
|
|
|
|
|
//plc是否是自动模式
|
|
|
var plcIsAuto = PlcIsAuto(machine);
|
|
|
if (InvokeStatus.Done != plcIsAuto)
|
|
|
{
|
|
|
return SwappingStateMachine.ReturnWithInvokeErr(plcIsAuto, ExceptionReason.None);
|
|
|
}
|
|
|
|
|
|
////plc是否是远程模式
|
|
|
var plcIsRemote = PlcIsRemote(machine);
|
|
|
if (InvokeStatus.Done != plcIsRemote)
|
|
|
{
|
|
|
return SwappingStateMachine.ReturnWithInvokeErr(plcIsRemote, ExceptionReason.None);
|
|
|
}
|
|
|
|
|
|
_CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.Plc,
|
|
|
machine);
|
|
|
|
|
|
|
|
|
//手动模式
|
|
|
if (StaticStationInfo.VehicleManually == 1)
|
|
|
{
|
|
|
var rfidPrepared = WaitVinPrepare(machine);
|
|
|
if (InvokeStatus.Done != rfidPrepared)
|
|
|
{
|
|
|
return SwappingStateMachine.ReturnWithInvokeErr(rfidPrepared, ExceptionReason.None);
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//开始读rifd
|
|
|
var beginRfid = BeginRead(machine);
|
|
|
if (InvokeStatus.Done != beginRfid)
|
|
|
{
|
|
|
return SwappingStateMachine.ReturnWithInvokeErr(beginRfid, ExceptionReason.None);
|
|
|
}
|
|
|
|
|
|
|
|
|
// 读取rfid
|
|
|
var readRfid = ReadRfid(machine);
|
|
|
if (InvokeStatus.Done != readRfid)
|
|
|
{
|
|
|
return SwappingStateMachine.ReturnWithInvokeErr(readRfid, ExceptionReason.ReadRfidError);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return new StateResult()
|
|
|
{
|
|
|
SwappingState = SwappingState.CarPrepare,
|
|
|
};
|
|
|
}
|
|
|
|
|
|
public InvokeStatus PlcIsAuto(SwappingStateMachine machine)
|
|
|
{
|
|
|
int a = 0;
|
|
|
bool isAuto = false;
|
|
|
return Invoker.Invoke("check plc auto", 1000, 5, machine.IsCanceled, () => isAuto,
|
|
|
() =>
|
|
|
{
|
|
|
if (PlcApi.IsAuto())
|
|
|
{
|
|
|
isAuto = true;
|
|
|
}
|
|
|
},
|
|
|
() =>
|
|
|
{
|
|
|
SoundClient = AppInfo.Container.Resolve<SoundClient>();
|
|
|
//SoundClient.SoundPlay(AppSettingsHelper.GetContent("SoundAddr", "Address25"));
|
|
|
if (a == 0)
|
|
|
{
|
|
|
SoundClient.SoundPlay(SoundEnum.music65);
|
|
|
a = 1;
|
|
|
}
|
|
|
|
|
|
//SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.InfoStationModel) ;
|
|
|
LedClient.SendMsgByKey(InfoEnum.SwapInfo.InfoStationModel.GetLed());
|
|
|
}, true,
|
|
|
() => { }, 5, InvokeStatus.None);
|
|
|
}
|
|
|
|
|
|
|
|
|
public InvokeStatus PlcIsRemote(SwappingStateMachine machine)
|
|
|
{
|
|
|
bool isRemote = false;
|
|
|
return Invoker.Invoke("check plc remote", 1000, 5, machine.IsCanceled, () => isRemote,
|
|
|
() =>
|
|
|
{
|
|
|
if (PlcApi.IsRemote())
|
|
|
{
|
|
|
if (!PlcApi.IsInit())
|
|
|
{
|
|
|
//下发初始化
|
|
|
PlcApi.Init();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//LED显示-欢迎光临_换电站点_正在营业
|
|
|
//string welcomeContent = "欢迎光临换电站!(正在营业)";
|
|
|
|
|
|
//SoundClient.SoundPlay(AppSettingsHelper.GetContent("SoundAddr", "Address01"));
|
|
|
//if(SoundClient.SoundPlay!=null)
|
|
|
//{
|
|
|
// SoundClient.SoundPlay(SoundEnum.music41);
|
|
|
//}
|
|
|
|
|
|
// SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.WelcomeInfo);
|
|
|
// LedClient.SendMsgByKey(InfoEnum.SwapInfo.WelcomeInfo.GetLed());
|
|
|
isRemote = true;
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
() =>
|
|
|
{
|
|
|
SoundClient = AppInfo.Container.Resolve<SoundClient>();
|
|
|
//SoundClient.SoundPlay(AppSettingsHelper.GetContent("SoundAddr", "Address26"));
|
|
|
SoundClient.SoundPlay(SoundEnum.music66);
|
|
|
// SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.InfoStationModelRemoteErr)
|
|
|
;
|
|
|
}, true, () => { }, 5, InvokeStatus.None);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 控制雷达启停
|
|
|
/// </summary>
|
|
|
/// <param name="machine"></param>
|
|
|
/// <param name="flag"></param>
|
|
|
/// <returns></returns>
|
|
|
public InvokeStatus ControlRadar(SwappingStateMachine machine, byte flag)
|
|
|
{
|
|
|
return Invoker.Invoke("begin Radar", 1000, 20, machine.IsCanceled, () => PadarMgr._PadarClient?.CarState > 0,
|
|
|
() => { PadarMgr._PadarClient?.PadarControl(flag); });
|
|
|
}
|
|
|
|
|
|
|
|
|
public InvokeStatus AdjustCarByRadar(SwappingStateMachine machine)
|
|
|
{
|
|
|
int che = 0;
|
|
|
return Invoker.Invoke("adjust Radar", 1000, 20, machine.IsCanceled,
|
|
|
() =>
|
|
|
{
|
|
|
LedClient.SendMsgByKey(InfoEnum.SwapInfo.InfoCarInPosition.GetLed());
|
|
|
|
|
|
|
|
|
StationSoftMgr.PutDeviceLog((int)StationConstant.DeviceCode.Radar,SwapConstant.RadarProtocol.CarStatus,
|
|
|
|
|
|
null,(int)SwapConstant.CommunicationType.Receive);
|
|
|
|
|
|
if (PadarMgr._PadarClient?.CarState == 6)
|
|
|
{
|
|
|
LedClient.SendMsgByKey(InfoEnum.SwapInfo.diparkir.GetLed());
|
|
|
_CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.RadarInFlag,
|
|
|
machine);
|
|
|
|
|
|
}
|
|
|
|
|
|
return PadarMgr._PadarClient?.CarState == 6;
|
|
|
},
|
|
|
() =>
|
|
|
{
|
|
|
switch (PadarMgr._PadarClient?.CarState)
|
|
|
{
|
|
|
case 1:
|
|
|
_log.Info("radar 无车");
|
|
|
break;
|
|
|
case 2:
|
|
|
_log.Info("radar 无电池");
|
|
|
break;
|
|
|
case 3:
|
|
|
_log.Info("radar 角度偏移过大");
|
|
|
if (che == 0)
|
|
|
{
|
|
|
LedClient.SendMsgByKey(InfoEnum.SwapInfo.upcar.GetLed());
|
|
|
SoundClient.SoundPlay(SoundEnum.music100);
|
|
|
Thread.Sleep(3000);
|
|
|
SoundClient.SoundPlay(SoundEnum.music101);
|
|
|
che = 1;
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
case 4:
|
|
|
_log.Info("radar 车辆靠后");
|
|
|
LedClient.SendMsgByKey(InfoEnum.SwapInfo.Muka.GetLed());
|
|
|
break;
|
|
|
case 5:
|
|
|
_log.Info("radar 车辆靠前");
|
|
|
LedClient.SendMsgByKey(InfoEnum.SwapInfo.Mundur.GetLed());
|
|
|
break;
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
public InvokeStatus BeginRead(SwappingStateMachine machine)
|
|
|
{
|
|
|
return Invoker.Invoke(" BeginRead read rfid", 1000, 20, machine.IsCanceled,
|
|
|
() => machine.BeginRfidReadFlag, () =>
|
|
|
{
|
|
|
Task<bool> open = RfidApi.Connect();
|
|
|
|
|
|
if (open.Result)
|
|
|
{
|
|
|
machine.RfidConnectFlag = true;
|
|
|
Task<bool> beginRead = RfidApi.BeginRead();
|
|
|
beginRead.Wait();
|
|
|
if (!beginRead.Result)
|
|
|
{
|
|
|
_log.Info("begin read rfid error");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
machine.ExceptionReason = ExceptionReason.None;
|
|
|
_log.Info("begin read done");
|
|
|
machine.BeginRfidReadFlag = true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
}, () =>
|
|
|
{
|
|
|
machine.LedTool.WriteProgramContent(InfoEnum.SwapInfo.ErrorReadRfid.GetLed());
|
|
|
SoundClient = AppInfo.Container.Resolve<SoundClient>();
|
|
|
|
|
|
}, false, () => { machine.ExceptionReason = ExceptionReason.ReadRfidError; }
|
|
|
, 3, InvokeStatus.None);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 判断换电站是否具备换电的条件
|
|
|
/// 1、换电站状态:
|
|
|
/// 2、换电站方式:
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
private bool IsAutoSwapping()
|
|
|
{
|
|
|
|
|
|
var statusDes =
|
|
|
BaseEnumExtensions.GetEnumDescriptionByCode<StationConstant.StationStatus>(
|
|
|
StaticStationInfo.StationStatus);
|
|
|
_log.Info($"站控处于{statusDes}状态");
|
|
|
var wayDes =
|
|
|
BaseEnumExtensions.GetEnumDescriptionByCode<StationConstant.StationWay>(
|
|
|
StaticStationInfo.StationWay);
|
|
|
_log.Info($"站控处于{wayDes}模式");
|
|
|
|
|
|
if (StationConstant.StationStatus.Run ==
|
|
|
BaseEnumExtensions.GetEnumByCode<StationConstant.StationStatus>(StaticStationInfo.StationStatus)
|
|
|
&& StationConstant.StationWay.Auto ==
|
|
|
BaseEnumExtensions.GetEnumByCode<StationConstant.StationWay>(StaticStationInfo.StationWay))
|
|
|
{
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
private InvokeStatus ReadRfid(SwappingStateMachine machine)
|
|
|
{
|
|
|
//开始读rifd
|
|
|
return Invoker.Invoke("read rfid", 3000, 10, machine.IsCanceled,
|
|
|
() => machine.RfidReadFlag, () =>
|
|
|
{
|
|
|
Task<RfidReadModel?> rfidReadModel = RfidApi.ReadRfid();
|
|
|
rfidReadModel.Wait();
|
|
|
var machineRfidReadModel = rfidReadModel.Result;
|
|
|
|
|
|
|
|
|
if (rfidReadModel.IsCompletedSuccessfully && machineRfidReadModel != null
|
|
|
&& machineRfidReadModel.Result == 1
|
|
|
&& !string.IsNullOrEmpty(machineRfidReadModel.VelVin))
|
|
|
{
|
|
|
machine.RfidReadModel = machineRfidReadModel;
|
|
|
_log.Info($"read rfid={JsonConvert.SerializeObject(machine.RfidReadModel)}");
|
|
|
|
|
|
machine.ExceptionReason = ExceptionReason.None;
|
|
|
machine.BusinessSwappingStateUpdateTime = DateTime.Now;
|
|
|
_log.Info($"BusinessSwappingForCloudState={machine.BusinessSwappingForCloudState}");
|
|
|
|
|
|
//新增换电订单
|
|
|
machine.SwapOrder = _CommonMgr.SaveOrder(BuildOrder(machine.RfidReadModel));
|
|
|
//新增小步
|
|
|
_CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.RfidReadFlag,
|
|
|
machine,param:JsonConvert.SerializeObject(machine.RfidReadModel));
|
|
|
|
|
|
RfidApi.StopRead();
|
|
|
_log.Info("stop read rfid");
|
|
|
RfidApi.DisConnect();
|
|
|
machine.RfidConnectFlag = false;
|
|
|
machine.RfidReadFlag = true;
|
|
|
}
|
|
|
}, () =>
|
|
|
{
|
|
|
machine.LedTool!.WriteProgramContent(InfoEnum.SwapInfo.ErrorReadRfid.GetLed());
|
|
|
SoundClient = AppInfo.Container.Resolve<SoundClient>();
|
|
|
SoundClient.SoundPlay(SoundEnum.music42);
|
|
|
}, false, () => { machine.ExceptionReason = ExceptionReason.ReadRfidError; }, 30,
|
|
|
InvokeStatus.None);
|
|
|
}
|
|
|
|
|
|
|
|
|
private InvokeStatus WaitVinPrepare(SwappingStateMachine machine)
|
|
|
{
|
|
|
int e = 0;
|
|
|
//开始读rifd
|
|
|
return Invoker.Invoke("Wait Vin Prepare", 3000, 10, machine.IsCanceled,
|
|
|
() => machine.RfidReadFlag && machine.BeginRfidReadFlag, () =>
|
|
|
{
|
|
|
if (machine.BeginRfidReadFlag && machine.RfidReadModel != null)
|
|
|
{
|
|
|
_log.Info($"Wait Vin Prepare ={JsonConvert.SerializeObject(machine.RfidReadModel)}");
|
|
|
|
|
|
machine.ExceptionReason = ExceptionReason.None;
|
|
|
machine.BusinessSwappingStateUpdateTime = DateTime.Now;
|
|
|
_log.Info($"BusinessSwappingForCloudState={machine.BusinessSwappingForCloudState}");
|
|
|
|
|
|
//新增换电订单
|
|
|
machine.SwapOrder = _CommonMgr.SaveOrder(BuildOrder(machine.RfidReadModel));
|
|
|
//新增小步
|
|
|
_CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.RfidReadFlag,
|
|
|
machine,"手动填写车辆vin",JsonConvert.SerializeObject(machine.RfidReadModel),
|
|
|
(int)SwapConstant.StepType.MANUAL);
|
|
|
|
|
|
|
|
|
_log.Info("stop Wait Vin Prepare");
|
|
|
|
|
|
machine.RfidReadFlag = true;
|
|
|
}
|
|
|
}, () =>
|
|
|
{
|
|
|
machine.LedTool!.WriteProgramContent(InfoEnum.SwapInfo.ErrorReadRfid.GetLed());
|
|
|
SoundClient = AppInfo.Container.Resolve<SoundClient>();
|
|
|
SoundClient.SoundPlay(SoundEnum.music42);
|
|
|
}, false, () => { machine.ExceptionReason = ExceptionReason.ReadRfidError; }, 30,
|
|
|
InvokeStatus.None);
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private SwapOrder BuildOrder(RfidReadModel rfidReadModel)
|
|
|
{
|
|
|
SwapOrder swapOrder = new SwapOrder()
|
|
|
{
|
|
|
Sn = SwapOrderNoGenerator.GenerateOrderNo(StaticStationInfo.StationNo),
|
|
|
VehicleVin = rfidReadModel.VelVin,
|
|
|
VehicleMac = rfidReadModel.VelMac,
|
|
|
VehicleNo = rfidReadModel.VelNo,
|
|
|
VehicleEnterTime = DateTime.Now,
|
|
|
};
|
|
|
|
|
|
return swapOrder;
|
|
|
}
|
|
|
} |