日志分文件记录 人工操作换电结果开发 分开云平台上报换电订单和 修改downBatteryInfo task

master
lxw 6 months ago
parent c2ec091b1b
commit 4b9687832f

@ -0,0 +1,30 @@
using System.ComponentModel.DataAnnotations;
namespace Entity.Api.Req;
/// <summary>
///
/// </summary>
public class OperateModelReq
{
/// <summary>
/// 操作人员名称
/// </summary>
[Required]
public string? Operator { get; set; }
/// <summary>
/// 操作原因
/// </summary>
[Required]
public string? Reason { get; set; }
/// <summary>
/// 操作类型 1人工确认成功;2人工确认失败
/// </summary>
[Required]
public int Type { get; set; }
}

@ -0,0 +1,43 @@
using SqlSugar;
namespace Entity.DbModel.Station;
/// <summary>
/// 人工操作表
/// </summary>
[SugarTable("manual_operation_record")]
public class ManualOperationRecord : BaseModel
{
/// <summary>
/// Desc:id
/// Default:
/// Nullable:False
/// </summary>
[SugarColumn(IsPrimaryKey = true, ColumnName = "id")]
public int Id { get; set; }
/// <summary>
/// 换电订单
/// </summary>
[SugarColumn(IsPrimaryKey = true, ColumnName = "swap_order_sn")]
public string? SwapOrderSn { get; set; }
/// <summary>
/// 原因
/// </summary>
[SugarColumn(IsPrimaryKey = true, ColumnName = "reason")]
public string? Reason { get; set; }
/// <summary>
/// 操作类型 1人工确认成功;2人工确认失败
/// </summary>
[SugarColumn(IsPrimaryKey = true, ColumnName = "type")]
public int Type { get; set; }
/// <summary>
/// 操作人员
/// </summary>
[SugarColumn(IsPrimaryKey = true, ColumnName = "operator")]
public string? Operator { get; set; }
}

@ -0,0 +1,14 @@
using Entity.DbModel.Station;
using HybirdFrameworkCore.Autofac.Attribute;
using SqlSugar;
namespace Repository.Station;
[Scope("SingleInstance")]
public class ManualOperationRecordRepository:BaseRepository<ManualOperationRecord>
{
public ManualOperationRecordRepository(ISqlSugarClient sqlSugar) : base(sqlSugar)
{
}
}

@ -5,10 +5,12 @@ using Newtonsoft.Json.Linq;
using Service.Execute.Model;
namespace Service.Execute.Api;
/// <summary>
/// chargeApi
/// </summary>
public class ChargeApi
{
private static readonly ILog Log = LogManager.GetLogger(typeof(ChargeApi));
private static readonly ILog Log = LogManager.GetLogger("ChargeApi");
private static readonly string BASE_URL = "http://localhost:5035";
@ -19,7 +21,7 @@ public class ChargeApi
public static async Task<bool> StopCharge(string binNo)
{
Log.Info("StopCharge");
Log.Info($" ChargeApi StopCharge binNo={binNo}");
string url = BASE_URL + "/api/Charge/StopChargeByBinNo/" + binNo;
try
{
@ -27,6 +29,8 @@ public class ChargeApi
if (!String.IsNullOrWhiteSpace(s))
{
Result<bool>? succ = JsonConvert.DeserializeObject<Result<bool>>(s);
Log.Info($" ChargeApi StopCharge binNo={binNo} resp={succ.IsSuccess}");
if (succ.IsSuccess)
{
return true;
@ -39,7 +43,7 @@ public class ChargeApi
}
catch (Exception e)
{
Console.WriteLine(e);
Log.Error($" ChargeApi StopCharge binNo={binNo} ,e={e}");
return false;
}
}

@ -1,6 +1,7 @@
using Entity.Constant;
using Entity.DbModel.Station;
using log4net;
using Newtonsoft.Json;
using Service.Cloud.Client;
using Service.Cloud.Msg.Cloud.Req;
using Service.Cloud.Msg.Cloud.Resp;
@ -14,6 +15,8 @@ public abstract class CloudApi
{
private const int TimeSpan = 60;
private static readonly ILog Log = LogManager.GetLogger("CloudApi");
/// <summary>
/// 云平台车辆认证
/// </summary>
@ -25,19 +28,23 @@ public abstract class CloudApi
VehicleCertification vehicleCertification = new()
{
ty = 2,
rfid=rfidReadModel.VelVin,
rfid = rfidReadModel.VelVin,
cn = rfidReadModel.VelNo,
vi = rfidReadModel.VelVin,
// mac = rfidReadModel.VelMac,
// mac = rfidReadModel.VelMac,
en = 0,
dt = swapOrder.VehicleEnterTime,
mode = 0,
};
Log.Info(
$" CloudApi VehicleCheck SendVehicleCertification param={JsonConvert.SerializeObject(vehicleCertification)}");
VehicleCertificationResp? sendVehicleCertification =
CloudClientMgr.CloudClient?.SendVehicleCertification(vehicleCertification,
global::System.TimeSpan.FromSeconds(TimeSpan));
Log.Info(
$" CloudApi VehicleCheck SendVehicleCertification resp={JsonConvert.SerializeObject(sendVehicleCertification)}");
if (sendVehicleCertification == null)
{
return -1;
@ -57,8 +64,8 @@ public abstract class CloudApi
{
UploadSwapOrder uploadSwapOrder = new()
{
rfid=swapOrder.VehicleVin,
sn=StaticStationInfo.StationNo,
rfid = swapOrder.VehicleVin,
sn = StaticStationInfo.StationNo,
son = swapOrder.CloudSn,
cn = swapOrder.VehicleNo,
so = seq,
@ -67,7 +74,7 @@ public abstract class CloudApi
dbid = swapOrderBattery.UpBatteryNo,
deno = swapOrderBattery.UpBatteryBinNo,
dsoc = swapOrderBattery.UpBatterySoc.ToInt(),
// dsoe = swapOrderBattery.UpBatterySoe.ToInt(),
// dsoe = swapOrderBattery.UpBatterySoe.ToInt(),
et = swapOrder.SwapEndTime,
od = 0,
ot = swapOrder.VehicleLeaveTime,
@ -77,22 +84,26 @@ public abstract class CloudApi
ubid = swapOrderBattery.DownBatteryNo,
ueno = swapOrderBattery.DownBatteryBinNo,
usoc = swapOrderBattery.DownBatterySoc.ToInt(),
// usoe = swapOrderBattery.DownBatterySoe.ToInt(),
// usoe = swapOrderBattery.DownBatterySoe.ToInt(),
vin = swapOrder.VehicleVin,
wt = new TimeSpan((swapOrder.SwapEndTime.ToDateTime().Ticks - swapOrder.SwapBeginTime.ToDateTime().Ticks))
.TotalSeconds.ToInt(),
};
Log.Info(
$" CloudApi UploadSwapOrder seq={seq} SendUploadPowerChangeOrder param={JsonConvert.SerializeObject(uploadSwapOrder)}");
UploadSwapOrderResp? sendUploadPowerChangeOrder = CloudClientMgr.CloudClient?.SendUploadPowerChangeOrder(
uploadSwapOrder,
global::System.TimeSpan.FromSeconds(TimeSpan));
Log.Info(
$" CloudApi UploadSwapOrder seq={seq} SendUploadPowerChangeOrder resp={JsonConvert.SerializeObject(sendUploadPowerChangeOrder)}");
if (sendUploadPowerChangeOrder == null)
{
return -1;
}
return sendUploadPowerChangeOrder.re;
}
/// <summary>
@ -125,7 +136,12 @@ public abstract class CloudApi
/// <returns></returns>
public static CarCanStart CarCanStart()
{
return CloudClientMgr.CloudClient.CarCanStart;
Log.Info(
$" CloudApi CarCanStart ");
var cloudClientCarCanStart = CloudClientMgr.CloudClient.CarCanStart;
Log.Info(
$" CloudApi CarCanStart resp={cloudClientCarCanStart}");
return cloudClientCarCanStart;
}
/// <summary>

@ -31,14 +31,14 @@ public class PlcApi
{
var isRemote = PlcMgr.IsRemote();
Log.Info($"plc IsRemove resp={isRemote}");
Log.Info($"PlcApi IsRemove resp={isRemote}");
return isRemote;
}
public static bool IsAuto()
{
var isAuto = PlcMgr.IsAuto();
Log.Info($"plc IsRemove resp={isAuto}");
Log.Info($"PlcApi IsRemove resp={isAuto}");
return isAuto;
}
@ -48,8 +48,9 @@ public class PlcApi
/// <returns></returns>
public static bool EntranceRadar()
{
return PlcMgr.EntranceRadar();
var entranceRadar = PlcMgr.EntranceRadar();
Log.Info($"PlcApi EntranceRadar resp={entranceRadar}");
return entranceRadar;
}
/// <summary>
@ -58,7 +59,9 @@ public class PlcApi
/// <returns></returns>
public static bool ExitRadar()
{
return PlcMgr.ExitRadar();
var exitRadar = PlcMgr.ExitRadar();
Log.Info($"PlcApi ExitRadar resp={exitRadar}");
return exitRadar;
}
/// <summary>
@ -70,7 +73,9 @@ public class PlcApi
/// <returns></returns>
public static bool WriteEntranceLamp(ushort data)
{
return PlcMgr.WriteEntranceLamp(data);
var writeEntranceLamp = PlcMgr.WriteEntranceLamp(data);
Log.Info($"PlcApi writeEntranceLamp resp={writeEntranceLamp}");
return writeEntranceLamp;
}
/// <summary>
@ -82,7 +87,9 @@ public class PlcApi
/// <returns></returns>
public static bool WriteExistLamp(ushort data)
{
return PlcMgr.WriteExistLamp(data);
var writeExistLamp = PlcMgr.WriteExistLamp(data);
Log.Info($"PlcApi WriteExistLamp resp={writeExistLamp}");
return writeExistLamp;
}
/// <summary>
@ -103,7 +110,12 @@ public class PlcApi
/// <returns></returns>
public static bool StartSwapping(string inBinNo, string outBinNo)
{
return PlcMgr.DistributeTask(ushort.Parse(inBinNo), ushort.Parse(outBinNo), 1);
Log.Info($"PlcApi StartSwapping param= inBinNo={inBinNo}, outBinNo={outBinNo}");
var distributeTask = PlcMgr.DistributeTask(ushort.Parse(inBinNo), ushort.Parse(outBinNo), 1);
Log.Info($"PlcApi StartSwapping resp={distributeTask}");
return distributeTask;
}
@ -113,7 +125,10 @@ public class PlcApi
/// <returns></returns>
public static bool ReadTaskStatus(ushort taskNo)
{
return PlcMgr.ReadTaskStatus(taskNo);
Log.Info($"PlcApi ReadTaskStatus param= taskNo={taskNo}");
var readTaskStatus = PlcMgr.ReadTaskStatus(taskNo);
Log.Info($"PlcApi ReadTaskStatus resp={readTaskStatus}");
return readTaskStatus;
}
/// <summary>
@ -122,7 +137,10 @@ public class PlcApi
/// <returns></returns>
public static bool HoldOn()
{
return PlcMgr.HoldOn();
var holdOn = PlcMgr.HoldOn();
Log.Info($"PlcApi HoldOn resp={holdOn}");
return holdOn;
}
/// <summary>
@ -133,7 +151,7 @@ public class PlcApi
{
PlcMgr.ResetPlc();
var channelStatus = PlcMgr.ChannelStatus();
Log.Info($"plc ChannelStatus = {channelStatus}");
Log.Info($"PlcApi ChannelStatus resp= {channelStatus}");
return channelStatus;
}
@ -144,6 +162,8 @@ public class PlcApi
/// <returns>6未连接</returns>
public static int ReadPlcTaskStatus()
{
return PlcMgr.ReadPlcTaskStatus();
var readPlcTaskStatus = PlcMgr.ReadPlcTaskStatus();
Log.Info($"PlcApi ReadPlcTaskStatus resp= {readPlcTaskStatus}");
return readPlcTaskStatus;
}
}

@ -6,9 +6,8 @@ namespace Service.Execute.Api;
public class RfidApi
{
private static readonly ILog Log = LogManager.GetLogger(typeof(RfidApi));
private static readonly ILog Log = LogManager.GetLogger("RfidApi");
//TODO::Rfid 服务地址
private static readonly string BASE_URL = "http://localhost:5037";
private static readonly HttpClient _httpClient = new HttpClient()
@ -23,11 +22,11 @@ public class RfidApi
var connect = await Connect();
if (!connect)
{
Log.Info("Rfid connect fail");
Log.Info("RfidApi connect fail");
return false;
}
Log.Info("BeginRead");
Log.Info("RfidApi BeginRead");
string url = BASE_URL + "/Api/BeginRead";
try
{
@ -44,7 +43,7 @@ public class RfidApi
public static async Task<bool> StopRead()
{
Log.Info("StopRead");
Log.Info("RfidApi StopRead");
string url = BASE_URL + "/Api/StopRead";
try
{
@ -63,7 +62,7 @@ public class RfidApi
public static async Task<bool> DisConnect()
{
Log.Info("DisConnect");
Log.Info("RfidApi DisConnect");
string url = BASE_URL + "/Api/Close";
try
{
@ -82,7 +81,7 @@ public class RfidApi
{
var disConnect = await DisConnect();
Log.Info("Connect");
Log.Info("RfidApi Connect");
string url = BASE_URL + "/Api/Open";
try
{
@ -101,7 +100,7 @@ public class RfidApi
{
Log.Info("ReadRifd");
Log.Info("RfidApi ReadRifd");
string readUrl = BASE_URL + "/Api/BeginRead";
string url = BASE_URL + "/Api/ReadRfidData";
try

@ -7,7 +7,7 @@ namespace Service.Execute.Api;
public class TBoxApi
{
private static readonly ILog Log = LogManager.GetLogger(typeof(TBoxApi));
private static readonly ILog Log = LogManager.GetLogger("TBoxApi");
private static readonly string BASE_URL = "http://localhost:5036";
@ -21,7 +21,7 @@ public class TBoxApi
public static async Task<TboxCarInfoModel> GetCarInfo(string carNo)
{
Log.Info("GetCarInfo");
Log.Info(" TBoxApi GetCarInfo");
string url = BASE_URL + "/getCarInfo/" + carNo;
try
{
@ -32,30 +32,30 @@ public class TBoxApi
tboxCarInfoModel = JsonConvert.DeserializeObject<TboxCarInfoModel>(s);
}
Log.Info($"GetCarInfo resp = {tboxCarInfoModel}");
Log.Info($"TBoxApi GetCarInfo resp = {tboxCarInfoModel}");
return tboxCarInfoModel;
}
catch (Exception e)
{
Log.Error($"GetCarInfo e = {e}");
Log.Error($" TBoxApi GetCarInfo e = {e}");
return null;
}
}
public static async Task<bool> Reset(string carNo)
{
Log.Info("Reset");
Log.Info(" TBoxApi Reset");
string url = BASE_URL + "/Clear/" + carNo;
try
{
string s = await _httpClient.GetStringAsync(url);
Log.Info($"Clear Tbox resp = {s}");
Log.Info($"TBoxApi Reset resp = {s}");
return bool.Parse(s);
}
catch (Exception e)
{
Log.Error($"Reset e = {e}");
Log.Error($"TBoxApi Reset e = {e}");
return false;
}
}
@ -86,6 +86,8 @@ public class TBoxApi
public static async Task<bool> UnLockCarManyTimes(string carNo)
{
Log.Info($" TBoxApi start UnLockCarManyTimes carNo={carNo} ");
List<bool> bools = new List<bool>();
for (int i = 0; i < _times; i++)
{
@ -96,12 +98,14 @@ public class TBoxApi
bools.Add(unLockCar);
}
}
Log.Info($" TBoxApi end UnLockCarManyTimes carNo={carNo} time={_times} resp={JsonConvert.SerializeObject(bools)}");
return bools.Select(i => i).Count() > _successTimes;
}
public static async Task<bool> LockCarManyTimes(string carNo)
{
Log.Info($" TBoxApi start LockCarManyTimes carNo={carNo} ");
List<bool> bools = new List<bool>();
for (int i = 0; i < _times; i++)
{
@ -112,6 +116,7 @@ public class TBoxApi
bools.Add(unLockCar);
}
}
Log.Info($" TBoxApi end LockCarManyTimes carNo={carNo} time={_times} resp={JsonConvert.SerializeObject(bools)}");
return bools.Select(i => i).Count() > _successTimes;
}
@ -141,7 +146,7 @@ public class TBoxApi
public static async Task<List<TboxCarInfoModel>> GetCarInfoList()
{
Log.Info("GetCarInfoList");
Log.Info(" TBoxApi GetCarInfoList start");
string url = BASE_URL + "/getCarInfoList" ;
try
{
@ -152,12 +157,12 @@ public class TBoxApi
tboxCarInfoModels = JsonConvert.DeserializeObject<List<TboxCarInfoModel>>(s);
}
Log.Info($"GetCarInfoList resp = {tboxCarInfoModels}");
Log.Info($"TBoxApi GetCarInfoList resp = {tboxCarInfoModels}");
return tboxCarInfoModels;
}
catch (Exception e)
{
Log.Error($"GetCarInfoList e = {e}");
Log.Error($"TBoxApi GetCarInfoList e = {e}");
return null;
}
}

@ -119,6 +119,61 @@ public class Invoker
Log.Info($" {name} done");
return InvokeStatus.Done;
}
public static InvokeStatus Invoke(string name, int duration, int times, Func<bool> cancel,Func<bool> succ, Func<bool> done,
Action doAction,
Action timeoutAction, bool isTimeOutExit, Action exceptionAction, int timeOutActionTime,
InvokeStatus timeOutException)
{
int count = 0;
while (!done())
{
Log.Info($"begin {name}");
Thread.Sleep(duration);
if (cancel())
{
Log.Info($" {name} canceled");
return InvokeStatus.Cancel;
}
if (succ())
{
Log.Info($" {name} ManualSucc");
return InvokeStatus.ManualSucc;
}
try
{
doAction();
}
catch (Exception e)
{
Log.Error($"{name}", e);
exceptionAction();
}
if (count++ > times)
{
if (count % timeOutActionTime == 0)
{
timeoutAction();
Log.Info($" {name} timeout");
if (isTimeOutExit)
{
return timeOutException;
}
}
}
}
Log.Info($" {name} done");
return InvokeStatus.Done;
}
public static InvokeStatus Invoke(string name, int duration, int times, Func<bool> done,
@ -230,5 +285,6 @@ public enum InvokeStatus
TimeOut,
Done,
Exception,
None
None,
ManualSucc,
}

@ -0,0 +1,25 @@
namespace Service.Execute.Model;
/// <summary>
///
/// </summary>
public class OperateModel
{
/// <summary>
/// 操作人员名称
/// </summary>
public string? Operator { get; set; }
/// <summary>
/// 操作原因
/// </summary>
public string? Reason { get; set; }
/// <summary>
/// 操作类型 1人工确认成功;2人工确认失败
/// </summary>
public int Type { get; set; }
}

@ -26,6 +26,13 @@ namespace Service.Execute
{
SwappingStateMachine.Cancel();
}
/// <summary>
/// 换电流程收栋操作
/// </summary>
public static void SwappingStateMachineManual()
{
SwappingStateMachine.Manual();
}
#endregion 换电流程启动
}

@ -1,18 +1,26 @@
using Autofac;
using Entity.Constant;
using Entity.DbModel.Station;
using HybirdFrameworkCore.Autofac;
using log4net;
using Repository.Station;
using Service.Mgr;
namespace Service.Execute.Step;
public class CancelState : IState
{
private readonly SwapOrderRepository _swapOrderRepository= AppInfo.Container.Resolve<SwapOrderRepository>();
private readonly SwapOrderRepository _swapOrderRepository = AppInfo.Container.Resolve<SwapOrderRepository>();
private readonly SwapAmtOrderRepository _swapAmtOrderRepository =
AppInfo.Container.Resolve<SwapAmtOrderRepository>();
private readonly SwapAmtOrderRepository _swapAmtOrderRepository = AppInfo.Container.Resolve<SwapAmtOrderRepository>();
private static readonly ILog _log = LogManager.GetLogger(typeof(CancelState));
private static readonly ManualOperationRecordRepository _manualOperationRecordRepository =
AppInfo.Container.Resolve<ManualOperationRecordRepository>();
public StateResult Handle(SwappingStateMachine machine)
{
_log.Info($"'goto cancel");
@ -29,6 +37,16 @@ public class CancelState : IState
_swapOrderRepository.Update(machine.SwapOrder);
}
_manualOperationRecordRepository.Insert(new ManualOperationRecord()
{
Type = 2,
CreatedBy = UserManager.Account,
UpdatedBy = UserManager.Account,
Operator = machine.OperateModel.Operator,
Reason = machine.OperateModel.Reason,
});
machine.Reset();
return new StateResult()
{

@ -342,6 +342,13 @@ public class DoSwappingState : IState
int count = 0;
while (!machine.ChannelStatusOkFlag)
{
if (machine.CancelFlag)
{
_log.Info($" CheckChannelStatus canceled");
return StateResult.Cancel;
}
_log.Info("begin plc CheckChannelStatus");
Thread.Sleep(2000);
var channelStatus = PlcApi.ChannelStatus();

@ -0,0 +1,55 @@
using Autofac;
using Entity.Constant;
using Entity.DbModel.Station;
using HybirdFrameworkCore.Autofac;
using log4net;
using Repository.Station;
using Service.Mgr;
namespace Service.Execute.Step;
/// <summary>
/// 手动确认成功状态
/// </summary>
public class ManualSuccState : IState
{
private readonly SwapOrderRepository _swapOrderRepository = AppInfo.Container.Resolve<SwapOrderRepository>();
private readonly SwapAmtOrderRepository _swapAmtOrderRepository =
AppInfo.Container.Resolve<SwapAmtOrderRepository>();
private static readonly ILog _log = LogManager.GetLogger(typeof(CancelState));
private static readonly ManualOperationRecordRepository _manualOperationRecordRepository =
AppInfo.Container.Resolve<ManualOperationRecordRepository>();
public StateResult Handle(SwappingStateMachine machine)
{
_log.Info($"'goto ManualSucc");
machine.ManualSwapSuccFlag = false;
if (machine.SwapOrderBatteryInfo.swapAmtOrder != null)
{
machine.SwapOrderBatteryInfo.swapAmtOrder.Status = (byte)InfoEnum.AmtOrderStatus.SwapFinish;
_swapAmtOrderRepository.Update(machine.SwapOrderBatteryInfo.swapAmtOrder);
}
if (machine.SwapOrder != null)
{
machine.SwapOrder.SwapResult = (byte)InfoEnum.SwapOrderResult.Success;
machine.SwapOrder.VehicleLeaveTime = DateTime.Now;
_swapOrderRepository.Update(machine.SwapOrder);
}
_manualOperationRecordRepository.Insert(new ManualOperationRecord()
{
Type = 2,
CreatedBy = UserManager.Account,
UpdatedBy = UserManager.Account,
Operator = machine.OperateModel.Operator,
Reason = machine.OperateModel.Reason,
});
machine.Reset();
return new StateResult()
{
SwappingState = SwappingState.StationReady
};
}
}

@ -33,6 +33,24 @@ public class SwapDoneState : IState
_CommonMgr.UpdateSwapOrder(machine);
//修改预约单
if (machine.SwapOrderBatteryInfo!.swapAmtOrder != null)
{
machine.SwapOrderBatteryInfo.swapAmtOrder.Status =
machine.SwapStatus == (int)InfoEnum.SwapOrderResult.Success
? (int)InfoEnum.AmtOrderStatus.SwapFinish
: (int)InfoEnum.AmtOrderStatus.SwapFail;
_CommonMgr.UpdateAmtOrder(machine);
}
//新增换电成功上报云平台数据
_CommonMgr.InsertCloudReportForSwapSuccess(machine);
//换电成功关于bininfo表的更新
_CommonMgr.UpdateBinInfoForSwapSuccess(machine);
//可人工确认换电成功标识
machine.PlcSwapFlag = true;
if (machine.SwapStatus == (int)InfoEnum.SwapOrderResult.Success)
{
//上传云平台换电状态
@ -56,10 +74,6 @@ public class SwapDoneState : IState
return SwappingStateMachine.ReturnWithInvokeErr(existRadar, ExceptionReason.None);
}
//新增换电成功上报云平台数据
_CommonMgr.InsertCloudReportForSwapSuccess(machine);
//换电成功关于bininfo表的更新
_CommonMgr.UpdateBinInfoForSwapSuccess(machine);
return new StateResult()
{
@ -73,10 +87,11 @@ public class SwapDoneState : IState
/// <returns></returns>
public InvokeStatus LockCar(SwappingStateMachine machine)
{
return Invoker.Invoke("LockCar", 500, 100, machine.IsCanceled,
return Invoker.Invoke("LockCar", 500, 100, machine.IsCanceled,machine.IsManualSwapSucc,
() => machine.VelLockFlag, () =>
{
Task<bool> result = TBoxApi.LockCarManyTimes(machine.RfidReadModel.VelVin);
bool unLock = result.Result;
if (unLock)
{
@ -113,13 +128,12 @@ public class SwapDoneState : IState
public InvokeStatus ExistRadar(SwappingStateMachine machine)
{
return Invoker.Invoke("wait exist radar", 1000, 5, machine.IsCanceled,
return Invoker.Invoke("wait exist radar", 1000, 5, machine.IsCanceled,machine.IsManualSwapSucc,
() => machine.RadarOutFlag, () =>
{
if (PlcApi.ExitRadar())
{
_log.Info("exist radar false");
}
else
{
@ -135,14 +149,6 @@ public class SwapDoneState : IState
InfoEnum.BusinessSwappingForCloudState.SwapDoneWithoutVel;
machine.SwapOrder!.VehicleLeaveTime = DateTime.Now;
_CommonMgr.UpdateSwapOrder(machine);
if (machine.SwapOrderBatteryInfo!.swapAmtOrder != null)
{
machine.SwapOrderBatteryInfo.swapAmtOrder.Status =
machine.SwapStatus == (int)InfoEnum.SwapOrderResult.Success
? (int)InfoEnum.AmtOrderStatus.SwapFinish
: (int)InfoEnum.AmtOrderStatus.SwapFail;
_CommonMgr.UpdateAmtOrder(machine);
}
machine.RadarOutFlag = true;
@ -158,6 +164,6 @@ public class SwapDoneState : IState
SoundTool.PlayOneSound(machine.SwapStatus == (int)InfoEnum.SwapOrderResult.Success
? (int)InfoEnum.SwapInfo.InfoCarLeave
: (int)InfoEnum.SwapInfo.ErrInfoCarLeave);
}, false,() => { },10,InvokeStatus.None);
}, false, () => { }, 10, InvokeStatus.None);
}
}

@ -27,6 +27,14 @@ public class SwappingStateMachine : IDisposable
public bool CancelFlag { get; set; } = false;
public bool StopFlag { get; set; } = false;
public bool PlcSwapFlag { get; set; } = false;
//手动确认换电成功
public bool ManualSwapSuccFlag { get; set; }=false;
public OperateModel OperateModel = null;
public readonly LedTool? LedTool = null;
private readonly Thread _executeThread;
private readonly Dictionary<SwappingState, IState> _dictionary = new Dictionary<SwappingState, IState>();
@ -148,6 +156,7 @@ public class SwappingStateMachine : IDisposable
_dictionary[SwappingState.SwapDone] = new SwapDoneState();
_dictionary[SwappingState.Exception] = new ExceptionState();
_dictionary[SwappingState.Canceled] = new CancelState();
_dictionary[SwappingState.ManualSucc] = new CancelState();
LedTool = new LedTool();
@ -171,6 +180,10 @@ public class SwappingStateMachine : IDisposable
{
return null;
}
else if (status == InvokeStatus.ManualSucc)
{
return new StateResult() { SwappingState = SwappingState.ManualSucc };
}
else
{
return StateResult.Exception(exceptionReason, null);
@ -214,6 +227,11 @@ public class SwappingStateMachine : IDisposable
{
return CancelFlag;
}
public bool IsManualSwapSucc()
{
return ManualSwapSuccFlag;
}
public bool Start()
{
@ -239,7 +257,7 @@ public class SwappingStateMachine : IDisposable
ResetData();
//重置云平台下发的指令
// CloudApi.ClearCarCanStartInfo();
// CloudApi.ClearCarCanStartInfo();
}
public bool Cancel()
@ -250,6 +268,14 @@ public class SwappingStateMachine : IDisposable
return true;
}
public bool Manual()
{
ManualSwapSuccFlag = true;
Thread.Sleep(5000);
Log.Info($"ManualSwapSuccFlag machine ok");
return true;
}
private void ResetData()
{
@ -269,6 +295,13 @@ public class SwappingStateMachine : IDisposable
SwapOrderBatteryInfo = null;
StepSort = 0;
StepModel = new List<StepModel>();
PlcSwapFlag = false;
ManualSwapSuccFlag = false;
OperateModel = null;
CancelFlag = false;
StopFlag = false;
}
private void ResetStep()
@ -394,5 +427,6 @@ public enum SwappingState
DoSwapping,
SwapDone,
Exception,
Canceled
Canceled,
ManualSucc,
}

@ -14,9 +14,8 @@ public class SwapOrderMgr
public SwapOrderBatteryRepository _swapOrderBatteryRepository { get; set; }
public BinInfoRepository _BinInfoRepository { get; set; }
public bool UploadCloud(List<SwapOrderReportCloud> list)
public bool UploadCloud(List<SwapOrderReportCloud> list ,int uploadType)
{
if (list.Count <= 0)
{
@ -35,7 +34,8 @@ public class SwapOrderMgr
List<string> swapOrderSn = swapOrders.Select(i => i.Sn).ToList();
List<SwapOrderBattery> batterys =
_swapOrderBatteryRepository.QueryListByClause(i => swapOrderSn.Contains(i.SwapOrderSn));
_swapOrderBatteryRepository.QueryListByClause(i =>
swapOrderSn.Contains(i.SwapOrderSn) && i.DownBatteryNo != null);
if (batterys.Count <= 0)
{
@ -44,15 +44,10 @@ public class SwapOrderMgr
IDictionary<string, SwapOrderBattery> dictionary = batterys.ToDictionary(i => i.SwapOrderSn);
List<string> downBatteryBinNos = batterys.Select(i => i.DownBatteryBinNo.ToString()).ToList();
Dictionary<string, BinInfo> binInfosMap = _BinInfoRepository
.QueryListByClause(i => downBatteryBinNos.Contains(i.No)).ToDictionary(i => i.No);
Dictionary<int, SwapOrderReportCloud> swapOrderReportClouds = list.ToDictionary(i => i.SwapOrderId);
List<SwapOrderBattery> updateDbBattery = new List<SwapOrderBattery>();
List<SwapOrder> updateDbOrder = new List<SwapOrder>();
List<SwapOrderReportCloud> updateDbCloudReport = new List<SwapOrderReportCloud>();
@ -66,22 +61,12 @@ public class SwapOrderMgr
if (null == swapOrderBattery.DownBatteryNo)
{
//更新换下电池包
binInfosMap.TryGetValue(swapOrderBattery.DownBatteryBinNo.ToString(), out BinInfo info);
if (info.BatteryNo == null || info.BatteryNo == "" || info.BatteryNo=="-1")
{
continue;
}
swapOrderBattery.DownBatteryNo = info.BatteryNo;
swapOrderBattery.DownBatterySoc = info.Soc;
swapOrderBattery.DownBatterySoe = info.Soe;
updateDbBattery.Add(swapOrderBattery);
continue;
}
var count = _swapOrderRepository.GetCount(i =>
i.SwapResult == 1 && i.SwapEndTime >= DateTime.Today && i.SwapEndTime < swapOrder.SwapEndTime);
var uploadSwapOrder = CloudApi.UploadSwapOrder(swapOrder, count++, swapOrderBattery, 1);
var uploadSwapOrder = CloudApi.UploadSwapOrder(swapOrder, count++, swapOrderBattery, uploadType);
if (uploadSwapOrder == 0)
{
swapOrder.CloudReportStatus = 1;
@ -92,11 +77,6 @@ public class SwapOrderMgr
}
}
if (updateDbBattery.Count > 0)
{
_swapOrderBatteryRepository.Update(updateDbBattery);
}
if (updateDbOrder.Count > 0)
{
_swapOrderRepository.Update(updateDbOrder);

@ -36,7 +36,7 @@ public class SwapOrderReportCloudTask : ITask
{
List<SwapOrderReportCloud> list = ReportCloudRepository.QueryListByClause(i => i.CloudReportStatus == 0);
SwapOrderMgr.UploadCloud(list);
SwapOrderMgr.UploadCloud(list,1);
}
catch (Exception e)
{

@ -0,0 +1,98 @@
using Entity.DbModel.Station;
using HybirdFrameworkCore.Autofac.Attribute;
using HybirdFrameworkCore.AutoTask;
using log4net;
using Newtonsoft.Json;
using Repository.Station;
using Service.Mgr;
namespace Service.MyTask;
/// <summary>
/// 充电结束上报云平台task
/// </summary>
[Scope]
public class UpdateDownBatteryInfoTask : ITask
{
private static readonly ILog Log = LogManager.GetLogger(typeof(UpdateDownBatteryInfoTask));
private volatile bool _stop;
public SwapOrderBatteryRepository _swapOrderBatteryRepository { get; set; }
public BinInfoRepository _BinInfoRepository { get; set; }
public string Name()
{
return "UpdateDownBatteryInfoTask";
}
public int Interval()
{
return 1000 * 2;
}
public void Handle()
{
try
{
List<SwapOrderBattery> batterys =
_swapOrderBatteryRepository.QueryListByClause(
i => i.DownBatteryNo == null && i.DownBatteryBinNo != null);
if (batterys.Count <= 0)
{
return;
}
List<string> downBatteryBinNos = batterys.Select(i => i.DownBatteryBinNo.ToString()).ToList();
Dictionary<string, BinInfo> binInfosMap = _BinInfoRepository
.QueryListByClause(i => downBatteryBinNos.Contains(i.No)).ToDictionary(i => i.No);
List<SwapOrderBattery> updateDbBattery = new List<SwapOrderBattery>();
foreach (var battery in batterys)
{
//更新换下电池包
binInfosMap.TryGetValue(battery.DownBatteryBinNo.ToString(), out BinInfo info);
if (info.BatteryNo == null || info.BatteryNo == "" || info.BatteryNo == "-1")
{
continue;
}
battery.DownBatteryNo = info.BatteryNo;
battery.DownBatterySoc = info.Soc;
battery.DownBatterySoe = info.Soe;
updateDbBattery.Add(battery);
}
if (updateDbBattery.Count > 0)
{
Log.Info(
$" UpdateDownBatteryInfoTask update DowmBatteryInfo db={JsonConvert.SerializeObject(updateDbBattery)}");
_swapOrderBatteryRepository.Update(updateDbBattery);
}
}
catch (Exception e)
{
Log.Error($" UpdateDownBatteryInfoTask err e={e}");
}
}
public bool Stoped()
{
return _stop;
}
public void Stop()
{
_stop = true;
}
public void ResetStop()
{
_stop = false;
}
}

@ -38,7 +38,7 @@ public class SwapOrderService : BaseServices<SwapOrder>
}
return SwapOrderMgr.UploadCloud(list) ? Result<bool>.Success() : Result<bool>.Fail();
return SwapOrderMgr.UploadCloud(list,2) ? Result<bool>.Success() : Result<bool>.Fail();
}

@ -1,3 +1,4 @@
using Entity.Api.Req;
using Entity.Api.Resp;
using Entity.Constant;
using HybirdFrameworkCore.Attribute;
@ -66,7 +67,7 @@ public class SwapMonitorController : ControllerBase
/// </summary>
/// <returns></returns>
[HttpPost("LockCar")]
public async Task<Result<bool>> LockCar( string carNo)
public async Task<Result<bool>> LockCar(string carNo)
{
var success = await TBoxApi.LockCarManyTimes(carNo);
return success ? Result<bool>.Success() : Result<bool>.Fail();
@ -77,7 +78,7 @@ public class SwapMonitorController : ControllerBase
/// </summary>
/// <returns></returns>
[HttpPost("UnLockCar")]
public async Task<Result<bool>> UnLockCar( string carNo)
public async Task<Result<bool>> UnLockCar(string carNo)
{
var success = await TBoxApi.UnLockCarManyTimes(carNo);
return success ? Result<bool>.Success() : Result<bool>.Fail();
@ -115,6 +116,48 @@ public class SwapMonitorController : ControllerBase
return Result<bool>.Success();
}
/// <summary>
/// 人工操作换电成功标识
/// </summary>
/// <returns></returns>
[HttpGet("SwapPlcSucc")]
public Result<bool> SwapPlcSucc()
{
return Result<bool>.Success(StationSoftMgr.SwappingStateMachine.PlcSwapFlag);
}
/// <summary>
/// 人工操作换电成功还是失败
/// </summary>
/// <returns></returns>
[HttpPost("ManualOperateSwap")]
public Result<bool> ManualOperateSwap([FromBody] OperateModelReq req)
{
StationSoftMgr.SwappingStateMachine.OperateModel = new OperateModel()
{
Type = req.Type,
Operator = req.Operator,
Reason = req.Reason
};
if (req.Type == 1)
{
if (!StationSoftMgr.SwappingStateMachine.PlcSwapFlag)
{
return Result<bool>.Fail("不满足确认换电成功条件");
}
StationSoftMgr.SwappingStateMachineManual();
}
else
{
StationSoftMgr.SwappingStateMachineCancel();
}
return Result<bool>.Success();
}
/// <summary>
/// 红绿灯操控
/// 0无颜色
@ -234,5 +277,4 @@ public class SwapMonitorController : ControllerBase
return Result<List<TboxCarInfoModel>>.Success(carInfoList);
}
}

@ -49,6 +49,102 @@
<param name="MaxSizeRollBackups" value="5" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="记录时间:%date 日志内容:%message%newline "/>
</layout>
</appender>
<logger name="CloudApi" additivity="false">
<level value="ALL" />
<appender-ref ref="Cloud" />
</logger>
<appender name="Cloud" type="log4net.Appender.RollingFileAppender">
<param name="File" value="logs\" />
<param name="AppendToFile" value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<Encoding value="UTF-8" />
<param name="StaticLogFileName" value="false" />
<param name="RollingStyle" value="Composite" />
<param name="DatePattern" value="yyyyMMdd/HH&quot;Cloud.log&quot;" />
<param name="maximumFileSize" value="200MB" />
<param name="MaxSizeRollBackups" value="5" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="记录时间:%date 日志内容:%message%newline "/>
</layout>
</appender>
<logger name="ChargeApi" additivity="false">
<level value="ALL" />
<appender-ref ref="Charge" />
</logger>
<appender name="Charge" type="log4net.Appender.RollingFileAppender">
<param name="File" value="logs\" />
<param name="AppendToFile" value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<Encoding value="UTF-8" />
<param name="StaticLogFileName" value="false" />
<param name="RollingStyle" value="Composite" />
<param name="DatePattern" value="yyyyMMdd/HH&quot;Charge.log&quot;" />
<param name="maximumFileSize" value="200MB" />
<param name="MaxSizeRollBackups" value="5" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="记录时间:%date 日志内容:%message%newline "/>
</layout>
</appender>
<logger name="RfidApi" additivity="false">
<level value="ALL" />
<appender-ref ref="Rfid" />
</logger>
<appender name="Rfid" type="log4net.Appender.RollingFileAppender">
<param name="File" value="logs\" />
<param name="AppendToFile" value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<Encoding value="UTF-8" />
<param name="StaticLogFileName" value="false" />
<param name="RollingStyle" value="Composite" />
<param name="DatePattern" value="yyyyMMdd/HH&quot;Rfid.log&quot;" />
<param name="maximumFileSize" value="200MB" />
<param name="MaxSizeRollBackups" value="5" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="记录时间:%date 日志内容:%message%newline "/>
</layout>
</appender>
<logger name="TboxApi" additivity="false">
<level value="ALL" />
<appender-ref ref="Tbox" />
</logger>
<appender name="Tbox" type="log4net.Appender.RollingFileAppender">
<param name="File" value="logs\" />
<param name="AppendToFile" value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<Encoding value="UTF-8" />
<param name="StaticLogFileName" value="false" />
<param name="RollingStyle" value="Composite" />
<param name="DatePattern" value="yyyyMMdd/HH&quot;Tbox.log&quot;" />
<param name="maximumFileSize" value="200MB" />
<param name="MaxSizeRollBackups" value="5" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="记录时间:%date 日志内容:%message%newline "/>

@ -49,6 +49,102 @@
<param name="MaxSizeRollBackups" value="5" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="记录时间:%date 日志内容:%message%newline "/>
</layout>
</appender>
<logger name="CloudApi" additivity="false">
<level value="ALL" />
<appender-ref ref="Cloud" />
</logger>
<appender name="Cloud" type="log4net.Appender.RollingFileAppender">
<param name="File" value="logs\" />
<param name="AppendToFile" value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<Encoding value="UTF-8" />
<param name="StaticLogFileName" value="false" />
<param name="RollingStyle" value="Composite" />
<param name="DatePattern" value="yyyyMMdd/HH&quot;Cloud.log&quot;" />
<param name="maximumFileSize" value="200MB" />
<param name="MaxSizeRollBackups" value="5" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="记录时间:%date 日志内容:%message%newline "/>
</layout>
</appender>
<logger name="ChargeApi" additivity="false">
<level value="ALL" />
<appender-ref ref="Charge" />
</logger>
<appender name="Charge" type="log4net.Appender.RollingFileAppender">
<param name="File" value="logs\" />
<param name="AppendToFile" value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<Encoding value="UTF-8" />
<param name="StaticLogFileName" value="false" />
<param name="RollingStyle" value="Composite" />
<param name="DatePattern" value="yyyyMMdd/HH&quot;Charge.log&quot;" />
<param name="maximumFileSize" value="200MB" />
<param name="MaxSizeRollBackups" value="5" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="记录时间:%date 日志内容:%message%newline "/>
</layout>
</appender>
<logger name="RfidApi" additivity="false">
<level value="ALL" />
<appender-ref ref="Rfid" />
</logger>
<appender name="Rfid" type="log4net.Appender.RollingFileAppender">
<param name="File" value="logs\" />
<param name="AppendToFile" value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<Encoding value="UTF-8" />
<param name="StaticLogFileName" value="false" />
<param name="RollingStyle" value="Composite" />
<param name="DatePattern" value="yyyyMMdd/HH&quot;Rfid.log&quot;" />
<param name="maximumFileSize" value="200MB" />
<param name="MaxSizeRollBackups" value="5" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="记录时间:%date 日志内容:%message%newline "/>
</layout>
</appender>
<logger name="TboxApi" additivity="false">
<level value="ALL" />
<appender-ref ref="Tbox" />
</logger>
<appender name="Tbox" type="log4net.Appender.RollingFileAppender">
<param name="File" value="logs\" />
<param name="AppendToFile" value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<Encoding value="UTF-8" />
<param name="StaticLogFileName" value="false" />
<param name="RollingStyle" value="Composite" />
<param name="DatePattern" value="yyyyMMdd/HH&quot;Tbox.log&quot;" />
<param name="maximumFileSize" value="200MB" />
<param name="MaxSizeRollBackups" value="5" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="记录时间:%date 日志内容:%message%newline "/>

Loading…
Cancel
Save