diff --git a/Entity/Api/Resp/SwapVehicleResp.cs b/Entity/Api/Resp/SwapVehicleResp.cs index 8c187b9..b6ee309 100644 --- a/Entity/Api/Resp/SwapVehicleResp.cs +++ b/Entity/Api/Resp/SwapVehicleResp.cs @@ -40,4 +40,15 @@ public class SwapVehicleResp /// 钥匙状态 0: OFF 1: ACC 2: ON 0xFF: 不支持 /// public byte? KeyStatus { get; set; } + + + /// + /// 车辆档位 最小值:-1,最大值 14 ,0x0F表示无效,-1 代表倒档 R;0 代表空挡 N;大于 0 代表前进档 D; + /// + public byte? Gear { get; set; } + + /// + /// 刹车状态 "0:未拉手刹1:已拉手刹 其它值无效" + /// + public byte? Break { get; set; } } \ No newline at end of file diff --git a/Entity/Constant/InfoEnum.cs b/Entity/Constant/InfoEnum.cs index 5621a4b..166dc2e 100644 --- a/Entity/Constant/InfoEnum.cs +++ b/Entity/Constant/InfoEnum.cs @@ -15,7 +15,8 @@ public class InfoEnum [Info("车辆连接失败", "车辆连接失败,请联系站务人员")] ErrorTBoxConn , [Info("云端校验失败", "云端校验失败,请联系站务人员")] ErrorCloudCheck , [Info("车辆已到位", "车辆已到位")] InfoCarInPosition , - [Info("车辆到位超时", "车辆到位超时")] ErrorCarInPositionTimeout, + //TODO:: 录音内容已改 + [Info("请熄火挂空挡拉手刹", "请熄火挂空挡拉手刹")] ErrorCarInPositionTimeout, [Info("云平台下发换电失败", "云平台下发换电超时")] CloudSendSwapError , diff --git a/Entity/Constant/StationParamConst.cs b/Entity/Constant/StationParamConst.cs index 342f75f..500c9ac 100644 --- a/Entity/Constant/StationParamConst.cs +++ b/Entity/Constant/StationParamConst.cs @@ -65,7 +65,6 @@ public class StationParamConst public static readonly string Sevstatus = "Station.Sevstatus"; - /// /// 投放时间 /// @@ -179,13 +178,11 @@ public class StationParamConst #endregion 换电站基础信息 #region 系统管理-基础设置 + //提交灯光日间时间 public static readonly string SetLightDayStartTime = "Station.LightDayStartTime"; public static readonly string SetLightDayEndTime = "Station.LightDayEndTime"; - - - #endregion 系统管理-基础设置 //选包策略中最后结束充电时间需要>此值 @@ -198,9 +195,12 @@ public class StationParamConst public static readonly string ChargeSoc = "Station.ChargeSoc"; public static readonly string ChargePower = "Station.ChargePower"; public static readonly string AutoChargeEnabled = "Station.AutoChargeEnabled"; + public static readonly string Eid = "Station.Eid"; + //运营模型 public static readonly string Oid = "Station.Oid"; + //电价模型 public static readonly string Ceid = "Station.Ceid"; @@ -208,6 +208,45 @@ public class StationParamConst public static readonly string StationWay = "Station.StationWay"; public static readonly string StationModel = "Station.StationModel"; + #region Tbox + + //Tbox是否需要连接 + public static readonly string TboxStateConnect = "Tbox.StateConnect"; + + //Tbox是否需要检测熄火 + public static readonly string TboxStateFlameout = "Tbox.StateFlameout"; + //Tbox是否需要检测N挡 + public static readonly string TboxStateN = "Tbox.StateTboxStateN"; + //Tbox是否需要检测手刹 + public static readonly string TboxStateBreak = "Tbox.StateHandbrake"; + //Tbox是否需要断连 + public static readonly string TboxStateDisConnect = "Tbox.StateDisConnect"; + public static readonly string TboxStateCarList = "Tbox.TboxStateCarList"; + //Tbox是否需要连接 + public static readonly string TboxUrlConnect = "Tbox.UrlConnect"; + + + + //Tbox 断连url + public static readonly string TboxUrlDisConnect = "Tbox.UrlDisConnect"; + + //Tbox解锁url + public static readonly string TboxUrlUnLock = "Tbox.UrlUnLock"; + + //Tbox上锁url + public static readonly string TboxUrlLock = "Tbox.UrlLock"; + + //Tbox获取车辆信息url + public static readonly string TboxUrlCarInfo = "Tbox.UrlCarInfo"; + + //Tbox 清除url + public static readonly string TboxUrlClear = "Tbox.UrlClear"; + + //Tbox 获取所有车辆url + public static readonly string TboxUrlCarInfoList = "Tbox.UrlCarInfoList"; + + #endregion + #region cloud param public static readonly string CloudServerMqttVersion = "Cloud.CloudServerMqttVersion"; @@ -220,4 +259,4 @@ public class StationParamConst public static readonly string CloudPubTopic = "Cloud.CloudPubTopic"; #endregion -} +} \ No newline at end of file diff --git a/Service/Cloud/Msg/Host/Req/UploadSwapOrder.cs b/Service/Cloud/Msg/Host/Req/UploadSwapOrder.cs index 776f6e5..8eec39a 100644 --- a/Service/Cloud/Msg/Host/Req/UploadSwapOrder.cs +++ b/Service/Cloud/Msg/Host/Req/UploadSwapOrder.cs @@ -145,7 +145,7 @@ namespace Service.Cloud.Msg.Host.Req /// 车朝总里程 /// 单位:kWh, 保留两位小数 /// - public float vtm { get; set; } + public float? vtm { get; set; } /// /// 车制累计换电次数 /// diff --git a/Service/Execute/Api/CloudApi.cs b/Service/Execute/Api/CloudApi.cs index b95194a..3719a1d 100644 --- a/Service/Execute/Api/CloudApi.cs +++ b/Service/Execute/Api/CloudApi.cs @@ -7,6 +7,7 @@ using Service.Cloud.Msg.Cloud.Req; using Service.Cloud.Msg.Cloud.Resp; using Service.Cloud.Msg.Host.Req; using Service.Execute.Model; +using Service.Execute.Model.Tbox; using Service.Init; namespace Service.Execute.Api; @@ -56,7 +57,8 @@ public abstract class CloudApi /// /// /// - public static int UploadSwapOrder(SwapOrder swapOrder, int seq, SwapOrderBattery swapOrderBattery, int uploadType) + public static int UploadSwapOrder(SwapOrder swapOrder, int seq, SwapOrderBattery swapOrderBattery, int uploadType + ,SwapOrderReportCloud orderReportCloud) { UploadSwapOrder uploadSwapOrder = new() @@ -71,7 +73,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, @@ -85,6 +87,7 @@ public abstract class CloudApi vin = swapOrder.VehicleVin, wt = new TimeSpan((swapOrder.SwapEndTime.ToDateTime().Ticks - swapOrder.SwapBeginTime.ToDateTime().Ticks)) .TotalSeconds.ToInt(), + vtm=orderReportCloud.Vtm, }; Log.Info( $" CloudApi UploadSwapOrder seq={seq} SendUploadPowerChangeOrder param={JsonConvert.SerializeObject(uploadSwapOrder)}"); diff --git a/Service/Execute/Api/TboxApi.cs b/Service/Execute/Api/TboxApi.cs index 05148b2..9c6f8fe 100644 --- a/Service/Execute/Api/TboxApi.cs +++ b/Service/Execute/Api/TboxApi.cs @@ -2,6 +2,9 @@ using log4net; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Service.Execute.Model; +using Service.Execute.Model.Tbox; +using Service.Init; +using TboxCarInfoModel = Service.Execute.Model.Tbox.TboxCarInfoModel; namespace Service.Execute.Api; @@ -9,7 +12,7 @@ public class TBoxApi { private static readonly ILog Log = LogManager.GetLogger("TboxApi"); - private static readonly string BASE_URL = "http://localhost:5036/Car"; + private static readonly string BASE_URL = "http://localhost:5036"; private static int _times = 5; private static int _successTimes = 3; @@ -19,20 +22,27 @@ public class TBoxApi Timeout = TimeSpan.FromSeconds(60) }; + /// + /// /Car/getCarInfo/ + /// + /// + /// public static async Task GetCarInfo(string carNo) { Log.Info($" TBoxApi GetCarInfo carNo={carNo}"); - string url = BASE_URL + "/getCarInfo/" + carNo; + string url = BASE_URL + StaticStationInfo.TboxUrlCarInfo + carNo; try { string s = await _httpClient.GetStringAsync(url); - TboxCarInfoModel? tboxCarInfoModel = null; + Log.Info($"TBoxApi GetCarInfo resp = {s}"); + + TboxCarInfoModel tboxCarInfoModel = null; + if (!String.IsNullOrWhiteSpace(s)) { tboxCarInfoModel = JsonConvert.DeserializeObject(s); } - Log.Info($"TBoxApi GetCarInfo resp = {JsonConvert.SerializeObject(tboxCarInfoModel)}"); return tboxCarInfoModel; } catch (Exception e) @@ -42,10 +52,15 @@ public class TBoxApi } } + /// + /// /Car/Clear + /// + /// + /// public static async Task Reset(string carNo) { Log.Info(" TBoxApi Reset"); - string url = BASE_URL + "/Clear/" + carNo; + string url = BASE_URL + StaticStationInfo.TboxUrlClear + carNo; try { string s = await _httpClient.GetStringAsync(url); @@ -63,25 +78,10 @@ public class TBoxApi public static async Task IsConnected(string carNo) { Log.Info($"IsConnected carNo={carNo}"); - string url = BASE_URL + "/getCarInfo/"+carNo; - try - { - string s = await _httpClient.GetStringAsync(url); - TboxCarInfoModel? tboxCarInfoModel = null; - if (!String.IsNullOrWhiteSpace(s)) - { - tboxCarInfoModel = JsonConvert.DeserializeObject(s); - Log.Info($"IsConnected resp={JsonConvert.SerializeObject(tboxCarInfoModel)}"); - } + TboxCarInfoModel tboxCarInfoModel = await GetCarInfo(carNo); + Log.Info($"IsConnected resp={JsonConvert.SerializeObject(tboxCarInfoModel)}"); - Log.Info($"GetCarInfo resp = {JsonConvert.SerializeObject(tboxCarInfoModel)}"); - return tboxCarInfoModel.Connected; - } - catch (Exception e) - { - Log.Error($"IsConnected e = {e}"); - return false; - } + return tboxCarInfoModel == null ? false : tboxCarInfoModel.Connected; } @@ -99,7 +99,9 @@ public class TBoxApi bools.Add(unLockCar); } } - Log.Info($" TBoxApi end UnLockCarManyTimes carNo={carNo} times={_times} resp={JsonConvert.SerializeObject(bools)}"); + + Log.Info( + $" TBoxApi end UnLockCarManyTimes carNo={carNo} times={_times} resp={JsonConvert.SerializeObject(bools)}"); return bools.Select(i => i).Count() > _successTimes; } @@ -117,19 +119,22 @@ public class TBoxApi bools.Add(unLockCar); } } - Log.Info($" TBoxApi end LockCarManyTimes carNo={carNo} times={_times} resp={JsonConvert.SerializeObject(bools)}"); + + Log.Info( + $" TBoxApi end LockCarManyTimes carNo={carNo} times={_times} resp={JsonConvert.SerializeObject(bools)}"); return bools.Select(i => i).Count() > _successTimes; } /// /// 车辆解锁 + /// /Car/unLock/ /// /// public static async Task UnLockCar(string carNo) { Log.Info("UnLockCar"); - string url = BASE_URL + "/unLock/" + carNo; + string url = BASE_URL + StaticStationInfo.TboxUrlUnLock + carNo; try { string s = await _httpClient.GetStringAsync(url); @@ -144,11 +149,62 @@ public class TBoxApi return false; } } + + /// + /// Tbox连接 + /// /Car/unLock/ + /// + /// + public static async Task Connect(string carNo) + { + Log.Info("TboxConnect"); + string url = BASE_URL + StaticStationInfo.TboxUrlConnect + carNo; + try + { + string s = await _httpClient.GetStringAsync(url); + + Log.Info($"TboxConnect resp = {s}"); + return bool.Parse(s); + } + catch (Exception e) + { + Log.Error($"TboxConnect e = {e}"); + return false; + } + } + + /// + /// Tbox断连 + /// /Car/unLock/ + /// + /// + public static async Task DisConnect(string carNo) + { + Log.Info("TboxDisConnect"); + string url = BASE_URL + StaticStationInfo.TboxUrlDisConnect + carNo; + try + { + string s = await _httpClient.GetStringAsync(url); + + + Log.Info($"TboxDisConnect resp = {s}"); + return bool.Parse(s); + } + catch (Exception e) + { + Log.Error($"TboxDisConnect e = {e}"); + return false; + } + } + /// + /// /Car/getCarInfoList + /// + /// public static async Task> GetCarInfoList() { Log.Info(" TBoxApi GetCarInfoList start "); - string url = BASE_URL + "/getCarInfoList" ; + string url = BASE_URL + StaticStationInfo.TboxUrlCarInfoList; try { string s = await _httpClient.GetStringAsync(url); @@ -175,7 +231,7 @@ public class TBoxApi public static async Task LockCar(string carNo) { Log.Info("LockCar"); - string url = BASE_URL + "/lock/" + carNo; + string url = BASE_URL +StaticStationInfo.TboxUrlLock + carNo; try { string s = await _httpClient.GetStringAsync(url); @@ -190,4 +246,4 @@ public class TBoxApi return false; } } -} +} \ No newline at end of file diff --git a/Service/Execute/Mgr/CommonMgr.cs b/Service/Execute/Mgr/CommonMgr.cs index 5c1e9b7..d5cbf12 100644 --- a/Service/Execute/Mgr/CommonMgr.cs +++ b/Service/Execute/Mgr/CommonMgr.cs @@ -58,18 +58,22 @@ public class CommonMgr public void SaveSwapBattery(SwappingStateMachine machine) { - BinInfo UpBin = machine.SwapOrderBatteryInfo.UpBinInfo; - BinInfo InBin = machine.SwapOrderBatteryInfo.InBinInfo; + BinInfo upBin = machine.SwapOrderBatteryInfo.UpBinInfo; + BinInfo inBin = machine.SwapOrderBatteryInfo.InBinInfo; SwapOrderBattery swapOrderBattery = new SwapOrderBattery() { SwapOrderSn = machine.SwapOrder.Sn, - UpBatterySoc = UpBin.Soc, - UpBatteryNo = UpBin.BatteryNo, - UpBatterySoe = UpBin.Soe, - UpBatteryBinNo = int.Parse(UpBin.No), - DownBatteryBinNo = int.Parse(InBin.No), + UpBatterySoc = upBin.Soc, + UpBatteryNo = upBin.BatteryNo, + UpBatterySoe = upBin.Soe, + UpBatteryBinNo = int.Parse(upBin.No), + DownBatteryBinNo = int.Parse(inBin.No), + DownBatteryNo = inBin.BatteryNo, + DownBatterySoc = inBin.Soc, + DownBatterySoe = inBin.Soe, }; - swapOrderBattery = _swapOrderBatteryRepository.Insert(swapOrderBattery); + + _swapOrderBatteryRepository.Insert(swapOrderBattery); } /// @@ -112,7 +116,7 @@ public class CommonMgr .TotalMinutes > StaticStationInfo.SwapFinishChargeTime && i.Soc > StaticStationInfo.Soc */ - public SwapOrderBatteryInfo SelectPackNotArm() + public SwapOrderBatteryInfo SelectPackNotArm(SwappingStateMachine machine) { SwapOrderBatteryInfo orderBatteryInfo = new SwapOrderBatteryInfo(); UpBin(orderBatteryInfo); @@ -121,12 +125,12 @@ public class CommonMgr return orderBatteryInfo; } - InBin(orderBatteryInfo); + InBin(orderBatteryInfo, machine); return orderBatteryInfo; } - public SwapOrderBatteryInfo SelectPackArm(SwapAmtOrder swapAmtOrder) + public SwapOrderBatteryInfo SelectPackArm(SwapAmtOrder swapAmtOrder, SwappingStateMachine machine) { SwapOrderBatteryInfo orderBatteryInfo = new SwapOrderBatteryInfo(); orderBatteryInfo.swapAmtOrder = swapAmtOrder; @@ -146,7 +150,7 @@ public class CommonMgr } orderBatteryInfo.UpBinInfo = UpBin; - InBin(orderBatteryInfo); + InBin(orderBatteryInfo, machine); return orderBatteryInfo; } @@ -167,7 +171,7 @@ public class CommonMgr /// 放电池判断:取出来的电池仓位能不能放 /// /// - public void InBin(SwapOrderBatteryInfo orderBatteryInfo) + public void InBin(SwapOrderBatteryInfo orderBatteryInfo, SwappingStateMachine machine) { List list = _binInfoRepository.QueryListByClause(i => @@ -182,6 +186,19 @@ public class CommonMgr } orderBatteryInfo.InBinInfo = list[0]; + orderBatteryInfo.InBinInfo.BatteryNo = "-1"; + orderBatteryInfo.InBinInfo.Soc = -1; + orderBatteryInfo.InBinInfo.Soe = -1; + orderBatteryInfo.InBinInfo.Soh = -1; + var carInfoBatteryInfos = machine.BoxCarInfoModel?.CarInfo?.BatteryInfos; + if (carInfoBatteryInfos != null && carInfoBatteryInfos.Count > 0) + { + orderBatteryInfo.InBinInfo.BatteryNo = carInfoBatteryInfos[0].BatteryNo; + // orderBatteryInfo.InBinInfo.Soc = carInfoBatteryInfos[0].Soc; + orderBatteryInfo.InBinInfo.Soe = carInfoBatteryInfos[0].Soe; + orderBatteryInfo.InBinInfo.Soh = carInfoBatteryInfos[0].Soh; + } + orderBatteryInfo.CanSwap = InfoEnum.SelectBinStatusInfo.Success; } @@ -228,17 +245,12 @@ public class CommonMgr if (machineSwapOrderBatteryInfo != null) { var inBinInfo = machineSwapOrderBatteryInfo.InBinInfo; - inBinInfo.Soc = -1; - inBinInfo.Soe = -1; - inBinInfo.BatteryNo = "-1"; //修改入仓顺序 BinInfo binInfo = _binInfoRepository .QueryListByClause(i => i.BatteryEnterSeq != null, "battery_enter_seq desc").First(); inBinInfo.BatteryEnterSeq = binInfo.BatteryEnterSeq + 1; inBinInfo.InTime = DateTime.Now; _binInfoRepository.Update(inBinInfo); - - var upBinInfo = machineSwapOrderBatteryInfo.UpBinInfo; upBinInfo.Soc = -1; upBinInfo.Soe = -1; @@ -255,12 +267,14 @@ public class CommonMgr public void InsertCloudReportForSwapSuccess(SwappingStateMachine machine) { SwapOrder? machineSwapOrder = machine.SwapOrder; + _swapOrderReportCloudRepository.Insert(new SwapOrderReportCloud() { SwapOrderSn = machineSwapOrder.Sn, SwapOrderId = machineSwapOrder.Id, CloudReportStatus = 0, - Vin = machineSwapOrder.VehicleVin + Vin = machineSwapOrder.VehicleVin, + Vtm = Convert.ToSingle(machine.BoxCarInfoModel?.ElecMsg?.TotalMile), }); } } \ No newline at end of file diff --git a/Service/Execute/Model/Tbox/BatteryInfo.cs b/Service/Execute/Model/Tbox/BatteryInfo.cs new file mode 100644 index 0000000..eb89db9 --- /dev/null +++ b/Service/Execute/Model/Tbox/BatteryInfo.cs @@ -0,0 +1,23 @@ +namespace Service.Execute.Model.Tbox +{ + public class BatteryInfo + { + public string? BatteryNo { get; set; } + + /// + /// 电池类型 + /// + public int? BatteryType { get; set; } + + /// + /// 电池包型号 + /// + public int? BatteryPackageModel { get; set; } + + public decimal? Soe { get; set; } + + public decimal? Soc { get; set; } + + public decimal? Soh { get; set; } + } +} \ No newline at end of file diff --git a/Service/Execute/Model/Tbox/CarInfo.cs b/Service/Execute/Model/Tbox/CarInfo.cs new file mode 100644 index 0000000..f827311 --- /dev/null +++ b/Service/Execute/Model/Tbox/CarInfo.cs @@ -0,0 +1,26 @@ +namespace Service.Execute.Model.Tbox; + +public class CarInfo +{ + public string CarNo { get; set; } + + + public string CarVin { get; set; } + + + /// + /// 车型数据 "0:无效值1:牵引车 2:搅拌车 3:自卸车" + /// + public byte? CarType { get; set; } + + /// + /// 电池数 + /// + public int BatteryNum { get; set; } + + + /// + /// 车辆电池数据 + /// + public List? BatteryInfos { get; set; } +} \ No newline at end of file diff --git a/Service/Execute/Model/Tbox/CarStatus.cs b/Service/Execute/Model/Tbox/CarStatus.cs new file mode 100644 index 0000000..23d9977 --- /dev/null +++ b/Service/Execute/Model/Tbox/CarStatus.cs @@ -0,0 +1,28 @@ +namespace Service.Execute.Model.Tbox; + +public class CarStatus +{ + /// + /// 车辆档位 最小值:-1,最大值 14 ,0x0F表示无效,-1 代表倒档 R;0 代表空挡 N;大于 0 代表前进档 D; + /// + public byte? Gear { get; set; } + + /// + /// 刹车状态 "0:未拉手刹1:已拉手刹 其它值无效" + /// + public byte? Break { get; set; } + + /// + /// 钥匙状态 "0:OFF1:ACC ON 2:IG ON 其它值无效" + /// + public byte? Keys { get; set; } + + + /// + /// 0:未解锁未上锁 + /// 1:解锁成功 + /// 2:上锁成功 + /// 3:无效数据 + /// + public byte? LockStatus { get; set; } +} \ No newline at end of file diff --git a/Service/Execute/Model/TboxElecMsg.cs b/Service/Execute/Model/Tbox/ElecMsg.cs similarity index 69% rename from Service/Execute/Model/TboxElecMsg.cs rename to Service/Execute/Model/Tbox/ElecMsg.cs index 42dbd10..69ec785 100644 --- a/Service/Execute/Model/TboxElecMsg.cs +++ b/Service/Execute/Model/Tbox/ElecMsg.cs @@ -1,84 +1,79 @@ -using HybirdFrameworkCore.Autofac.Attribute; +namespace Service.Execute.Model.Tbox; -namespace Service.Execute.Model; - -public class TboxElecMsg +public class ElecMsg { + /// + /// 小计里程 0~16777215 + /// + public double? SubMile { get; set; } + + /// + /// 车辆总里程 0~16777215 + /// + public double? TotalMile { get; set; } + /// /// 车辆累计放电量 /// - [Property(248, 24, scale: 0.01, round: 2)] public double AccDischargeCount { get; set; } /// /// 车辆累计回馈电量 /// - [Property(272, 24, scale: 0.01, round: 2)] public double AccFallbackCount { get; set; } /// /// 车辆累计插枪充电量 /// - [Property(296, 24, scale: 0.01, round: 2)] public double AccChargeCount { get; set; } /// /// 5 车辆累计综合能耗 /// - [Property(320, 24, scale: 0.01, round: 2)] public double AccKgce { get; set; } /// /// 6 本次实时放电量 /// - [Property(344, 24, scale: 0.01, round: 2)] public double ThisTimeRealDischarge { get; set; } /// /// 7 上一次结算放电量 /// - [Property(368, 24, scale: 0.01, round: 2)] public double LastTimeBalanceDischarge { get; set; } /// /// 8 本次实时回馈电量 /// - [Property(392, 24, scale: 0.01, round: 2)] public double ThisTimeRealFeedbackPower { get; set; } /// /// 9 上一次结算回馈电量 /// - [Property(416, 24, scale: 0.01, round: 2)] public double LastTimeBalanceFeedbackPower { get; set; } /// /// 10 本次实时插枪充电量 /// - [Property(440, 24, scale: 0.01, round: 2)] public double ThisTimeRealChargeCount { get; set; } /// /// 11 上一次结算插枪充电量 /// - [Property(464, 24, scale: 0.01, round: 2)] public double LastTimeBalanceChargeCount { get; set; } /// /// 12 本次实时综合能耗 /// - [Property(488, 24, scale: 0.01, round: 2)] public double ThisTimeRealKgce { get; set; } /// /// 13 上一次结算综合能耗 /// - [Property(512, 24, scale: 0.01, round: 2)] public double LastTimeBalanceKgce { get; set; } /// /// 14 待结算电费电量 /// - [Property(536, 24, scale: 0.01, round: 2)] public double ElectricityToBeSettled { get; set; } } \ No newline at end of file diff --git a/Service/Execute/Model/Tbox/TboxCarInfoModel.cs b/Service/Execute/Model/Tbox/TboxCarInfoModel.cs new file mode 100644 index 0000000..01d9e60 --- /dev/null +++ b/Service/Execute/Model/Tbox/TboxCarInfoModel.cs @@ -0,0 +1,27 @@ +namespace Service.Execute.Model.Tbox; + +/// +/// 车辆返回 +/// +public class TboxCarInfoModel +{ + public bool Connected { get; set; } + + public string CarNo { get; set; } + + /// + /// 度电数据 + /// + /// + public ElecMsg? ElecMsg { get; set; } + + /// + /// 车辆信息 + /// + public CarInfo? CarInfo { get; set; } + + /// + /// 车辆状态信息 + /// + public CarStatus? CarStatus { get; set; } +} \ No newline at end of file diff --git a/Service/Execute/Model/TboxCarInfoModel.cs b/Service/Execute/Model/TboxCarInfoModel.cs deleted file mode 100644 index 0c45e60..0000000 --- a/Service/Execute/Model/TboxCarInfoModel.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace Service.Execute.Model; - -/// -/// 车辆数据 -/// -public class TboxCarInfoModel -{ - /// - /// 连接状态 - /// - public bool Connected { get; set; } - - /// - /// 车牌号 - /// - public string? CarNo { get; set; } - - /// - /// 度电数据 - /// - public TboxElecMsg? ElecMsg { get; set; } - - /// - /// 状态数据 - /// - public TboxHeartBeatMsg? HeartBeatMsg { get; set; } -} \ No newline at end of file diff --git a/Service/Execute/Step/CarCtrlState.cs b/Service/Execute/Step/CarCtrlState.cs index 780971b..02f4424 100644 --- a/Service/Execute/Step/CarCtrlState.cs +++ b/Service/Execute/Step/CarCtrlState.cs @@ -5,6 +5,7 @@ using HybirdFrameworkCore.Autofac; using log4net; using Service.Execute.Api; using Service.Execute.Model; +using Service.Execute.Model.Tbox; using Service.Execute.StaticTools; using Service.Execute.SwapException; using Service.Execute.Utils; @@ -19,6 +20,8 @@ public class CarCtrlState : IState public StateResult Handle(SwappingStateMachine machine) { + + //解锁车辆 InvokeStatus unLockCar = UnLockCar(machine); if (unLockCar != InvokeStatus.Done) @@ -57,9 +60,10 @@ public class CarCtrlState : IState { //查询车辆锁止状态 Task carInfo = TBoxApi.GetCarInfo(machine.RfidReadModel.VelVin); - var resultHeartBeatMsg = carInfo.Result.HeartBeatMsg; - if (resultHeartBeatMsg.LockStatus == 1 || resultHeartBeatMsg.LockStatus==0) + var resultHeartBeatMsg = carInfo.Result.CarStatus; + if (resultHeartBeatMsg?.LockStatus == 1) { + machine.BoxCarInfoModel = carInfo.Result; machine.VelUnlockFlag = true; _CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.VelUnlockFlag, machine); diff --git a/Service/Execute/Step/CarPrepareState.cs b/Service/Execute/Step/CarPrepareState.cs index 1e95169..379ee8d 100644 --- a/Service/Execute/Step/CarPrepareState.cs +++ b/Service/Execute/Step/CarPrepareState.cs @@ -10,6 +10,7 @@ using Repository.Station; using Service.Cloud.Msg.Cloud.Resp; using Service.Execute.Api; using Service.Execute.Model; +using Service.Execute.Model.Tbox; using Service.Execute.StaticTools; using Service.Execute.SwapException; using Service.Execute.Utils; @@ -47,6 +48,16 @@ public class CarPrepareState : IState return SwappingStateMachine.ReturnWithInvokeErr(cloudCheckVel, ExceptionReason.None); } + //TBox连接 + if (StaticStationInfo.TboxStateConnect) + { + InvokeStatus tboxConnect = TboxConnect(machine); + if (tboxConnect != InvokeStatus.Done) + { + return SwappingStateMachine.ReturnWithInvokeErr(tboxConnect, ExceptionReason.None); + } + } + //检查tbox链接状态 InvokeStatus checkTBoxConnect = CheckTBoxConnectFlag(machine); if (checkTBoxConnect != InvokeStatus.Done) @@ -78,6 +89,7 @@ public class CarPrepareState : IState return SwappingStateMachine.ReturnWithInvokeErr(selectPack, ExceptionReason.None); } + //车辆到位 InvokeStatus carInPosition = CarInPosition(machine); if (carInPosition != InvokeStatus.Done) @@ -98,13 +110,46 @@ public class CarPrepareState : IState /// public InvokeStatus CarInPosition(SwappingStateMachine machine) { - return Invoker.Invoke("check CarInPosition", 500, 50, machine.IsCanceled, + return Invoker.Invoke("check CarInPosition", 500, 5, machine.IsCanceled, () => machine.VehiclesInPlaceFlag, () => { var result = TBoxApi.GetCarInfo(machine.RfidReadModel.VelVin); + int succCount = 0; + List succL = new List() + { + StaticStationInfo.TboxStateFlameout, StaticStationInfo.TboxStateBreak, StaticStationInfo.TboxStateN + }; + var successCount = succL.Where(i => i).Count(); TboxCarInfoModel tboxCarInfoModel = result.Result; - if (tboxCarInfoModel.HeartBeatMsg.KeyStatus == 0) + var status = tboxCarInfoModel?.CarStatus; + + if (StaticStationInfo.TboxStateFlameout) + { + if (status?.Keys == 0) + { + succCount++; + } + } + + if (StaticStationInfo.TboxStateBreak) + { + if (status?.Break == 1) + { + succCount++; + } + } + + if (StaticStationInfo.TboxStateN) + { + if (status?.Gear == 0) + { + succCount++; + } + } + + + if (succCount == successCount) { machine.VehiclesInPlaceFlag = true; //写入口等 :红灯 @@ -123,6 +168,7 @@ public class CarPrepareState : IState _CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.CarInPositionFlag, machine); + machine.BoxCarInfoModel = tboxCarInfoModel; } } }, () => @@ -131,7 +177,7 @@ public class CarPrepareState : IState // machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrorCarInPositionTimeout.GetLed()); SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.ErrorCarInPositionTimeout); }, false, () => { } - , 20, InvokeStatus.None); + , 10, InvokeStatus.None); } @@ -148,9 +194,10 @@ public class CarPrepareState : IState BaseEnumExtensions.GetEnumByCode( StaticStationInfo.StationModel)) { - VehicleCertificationResp? vehicleCertificationResp = CloudApi.VehicleCheck(machine.RfidReadModel, machine.SwapOrder); + VehicleCertificationResp? vehicleCertificationResp = + CloudApi.VehicleCheck(machine.RfidReadModel, machine.SwapOrder); - if (vehicleCertificationResp==null || vehicleCertificationResp.re!=0) + if (vehicleCertificationResp == null || vehicleCertificationResp.re != 0) { _log.Info("cloud check vehicle error"); // machine.LedTool?.WriteProgramContent("换电准备中:云平台车辆验证完成"); @@ -208,6 +255,44 @@ public class CarPrepareState : IState } + /// + /// 连接TBox + /// + public InvokeStatus TboxConnect(SwappingStateMachine machine) + { + return Invoker.Invoke("TBox connect", 1000, 10, machine.IsCanceled, + () => machine.BoxConnectFlag, () => + { + Task result = TBoxApi.Connect(machine.RfidReadModel.VelVin); + bool isConnect = result.Result; + if (isConnect) + { + //读取车辆carNo=carVin + Task carInfoResult = TBoxApi.GetCarInfo(machine.RfidReadModel.VelVin); + var tboxCarInfoModel = carInfoResult.Result; + var carInfo = tboxCarInfoModel?.CarInfo; + if (carInfo != null) + { + if (carInfo.CarNo.Equals(carInfo.CarVin)) + { + machine.BoxConnectFlag = true; + } + } + } + }, () => + { + machine.ExceptionReason = ExceptionReason.ConnTBoxError; + SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.ErrorTBoxConn); + }, false, () => + { + machine.ExceptionReason = ExceptionReason.ConnTBoxError; + // machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrorTBoxConn.GetLed()); + } + , 20, InvokeStatus.None); + } + + /// /// 车辆本地验证:车牌校验 /// @@ -285,11 +370,11 @@ public class CarPrepareState : IState SwapOrderBatteryInfo orderBatteryInfo = null; if (swapAmtOrder != null) { - orderBatteryInfo = _CommonMgr.SelectPackArm(swapAmtOrder); + orderBatteryInfo = _CommonMgr.SelectPackArm(swapAmtOrder, machine); } else { - orderBatteryInfo = _CommonMgr.SelectPackNotArm(); + orderBatteryInfo = _CommonMgr.SelectPackNotArm(machine); } if (orderBatteryInfo.CanSwap != InfoEnum.SelectBinStatusInfo.Success) diff --git a/Service/Execute/Step/DoSwappingState.cs b/Service/Execute/Step/DoSwappingState.cs index 82bbde8..a41c948 100644 --- a/Service/Execute/Step/DoSwappingState.cs +++ b/Service/Execute/Step/DoSwappingState.cs @@ -6,9 +6,11 @@ using log4net; using Repository.Station; using Service.Execute.Api; using Service.Execute.Model; +using Service.Execute.Model.Tbox; using Service.Execute.StaticTools; using Service.Execute.SwapException; using Service.Execute.Utils; +using Service.Init; using Service.Station; namespace Service.Execute.Step; @@ -414,7 +416,40 @@ public class DoSwappingState : IState var result = TBoxApi.GetCarInfo(machine.RfidReadModel.VelVin); TboxCarInfoModel tboxCarInfoModel = result.Result; - if (tboxCarInfoModel.HeartBeatMsg.KeyStatus == 0) + int succCount = 0; + List succL = new List() + { + StaticStationInfo.TboxStateFlameout, StaticStationInfo.TboxStateBreak, StaticStationInfo.TboxStateN + }; + var successCount = succL.Where(i => i).Count(); + + var status = tboxCarInfoModel?.CarStatus; + + if (StaticStationInfo.TboxStateFlameout) + { + if (status?.Keys == 0) + { + succCount++; + } + } + + if (StaticStationInfo.TboxStateBreak) + { + if (status?.Break == 1) + { + succCount++; + } + } + + if (StaticStationInfo.TboxStateN) + { + if (status?.Gear == 0) + { + succCount++; + } + } + + if (succCount==successCount) { machine.VehiclesInPlace2Flag = true; } diff --git a/Service/Execute/Step/SwapDoneState.cs b/Service/Execute/Step/SwapDoneState.cs index 4ce8bb4..d6081f1 100644 --- a/Service/Execute/Step/SwapDoneState.cs +++ b/Service/Execute/Step/SwapDoneState.cs @@ -6,9 +6,11 @@ using log4net; using Repository.Station; using Service.Execute.Api; using Service.Execute.Model; +using Service.Execute.Model.Tbox; using Service.Execute.StaticTools; using Service.Execute.SwapException; using Service.Execute.Utils; +using Service.Init; using Service.Station; namespace Service.Execute.Step; @@ -101,8 +103,9 @@ public class SwapDoneState : IState { //查询车辆锁止状态 Task carInfo = TBoxApi.GetCarInfo(machine.RfidReadModel.VelVin); - if (carInfo.Result.HeartBeatMsg!.LockStatus == 2) + if (carInfo.Result?.CarStatus?.LockStatus == 2) { + machine.BoxCarInfoModel = carInfo.Result; //设置出口的是绿灯 if (PlcApi.WriteExistLamp(1000)) { @@ -114,7 +117,11 @@ public class SwapDoneState : IState ? (int)InfoEnum.SwapInfo.InfoCarLeave : (int)InfoEnum.SwapInfo.ErrInfoCarLeave); machine.VelLockFlag = true; - + //断连Tbox + if (StaticStationInfo.TboxStateDisConnect) + { + TBoxApi.DisConnect(machine.BoxCarInfoModel.CarNo); + } _CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.VelLockFlag, machine); diff --git a/Service/Execute/SwappingStateMachine.cs b/Service/Execute/SwappingStateMachine.cs index 49d0ded..f5bf753 100644 --- a/Service/Execute/SwappingStateMachine.cs +++ b/Service/Execute/SwappingStateMachine.cs @@ -8,6 +8,7 @@ using Newtonsoft.Json; using Repository.Station; using Service.Execute.Api; using Service.Execute.Model; +using Service.Execute.Model.Tbox; using Service.Execute.StaticTools; using Service.Execute.Step; using Service.Execute.SwapException; @@ -28,9 +29,9 @@ public class SwappingStateMachine : IDisposable public bool StopFlag { get; set; } = false; public bool PlcSwapFlag { get; set; } = false; - + //手动确认换电成功 - public bool ManualSwapSuccFlag { get; set; }=false; + public bool ManualSwapSuccFlag { get; set; } = false; public OperateModel OperateModel = null; @@ -156,7 +157,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(); + _dictionary[SwappingState.ManualSucc] = new ManualSuccState(); LedTool = new LedTool(); @@ -227,7 +228,7 @@ public class SwappingStateMachine : IDisposable { return CancelFlag; } - + public bool IsManualSwapSucc() { return ManualSwapSuccFlag; @@ -245,7 +246,7 @@ public class SwappingStateMachine : IDisposable { Log.Info("reset data"); ResetOrderAmtStatus(); - if (RfidReadModel != null && RfidReadModel.VelNo != null) + if (RfidReadModel != null) { //wifi数据重置 TBoxApi.Reset(RfidReadModel.VelVin); diff --git a/Service/Init/StaticStationInfo.cs b/Service/Init/StaticStationInfo.cs index 3642b80..152d66c 100644 --- a/Service/Init/StaticStationInfo.cs +++ b/Service/Init/StaticStationInfo.cs @@ -72,6 +72,90 @@ public class StaticStationInfo set => Set(StationParamConst.SwapSoc, value); } + #region Tbox + + public static bool TboxStateConnect + { + get => bool.Parse(Resolve(StationParamConst.TboxStateConnect)); + set => Set(StationParamConst.TboxStateConnect, value); + } + + public static bool TboxStateFlameout + { + get => bool.Parse(Resolve(StationParamConst.TboxStateFlameout)); + set => Set(StationParamConst.TboxStateFlameout, value); + } + public static bool TboxStateN + { + get => bool.Parse(Resolve(StationParamConst.TboxStateN)); + set => Set(StationParamConst.TboxStateN, value); + } + + public static bool TboxStateCarList + { + get => bool.Parse(Resolve(StationParamConst.TboxStateCarList)); + set => Set(StationParamConst.TboxStateCarList, value); + } + + public static bool TboxStateBreak + { + get => bool.Parse(Resolve(StationParamConst.TboxStateBreak)); + set => Set(StationParamConst.TboxStateBreak, value); + } + + + public static bool TboxStateDisConnect + { + get => bool.Parse(Resolve(StationParamConst.TboxStateDisConnect)); + set => Set(StationParamConst.TboxStateDisConnect, value); + } + + public static string TboxUrlDisConnect + { + get => Resolve(StationParamConst.TboxUrlDisConnect); + set => Set(StationParamConst.TboxUrlDisConnect, value); + } + + + + public static string TboxUrlConnect + { + get => Resolve(StationParamConst.TboxUrlConnect); + set => Set(StationParamConst.TboxUrlConnect, value); + } + + public static string TboxUrlLock + { + get => Resolve(StationParamConst.TboxUrlLock); + set => Set(StationParamConst.TboxUrlLock, value); + } + + public static string TboxUrlUnLock + { + get => Resolve(StationParamConst.TboxUrlUnLock); + set => Set(StationParamConst.TboxUrlUnLock, value); + } + + public static string TboxUrlCarInfoList + { + get => Resolve(StationParamConst.TboxUrlCarInfoList); + set => Set(StationParamConst.TboxUrlCarInfoList, value); + } + + public static string TboxUrlCarInfo + { + get => Resolve(StationParamConst.TboxUrlCarInfo); + set => Set(StationParamConst.TboxUrlUnLock, value); + } + + public static string TboxUrlClear + { + get => Resolve(StationParamConst.TboxUrlClear); + set => Set(StationParamConst.TboxUrlClear, value); + } + + #endregion + #region 充电相关 public static int Eid @@ -145,6 +229,7 @@ public class StaticStationInfo get => Resolve(StationParamConst.CloudServerMqttVersion, "4.0.0"); set => Set(StationParamConst.CloudServerMqttVersion, value); } + public static string CloudClientId { get => Resolve(StationParamConst.CloudClientId); @@ -208,4 +293,4 @@ public class StaticStationInfo } #endregion -} +} \ No newline at end of file diff --git a/Service/Mgr/SwapOrderMgr.cs b/Service/Mgr/SwapOrderMgr.cs index 460774d..0950b01 100644 --- a/Service/Mgr/SwapOrderMgr.cs +++ b/Service/Mgr/SwapOrderMgr.cs @@ -35,7 +35,8 @@ public class SwapOrderMgr List batterys = _swapOrderBatteryRepository.QueryListByClause(i => - swapOrderSn.Contains(i.SwapOrderSn) && i.DownBatteryNo != null); + swapOrderSn.Contains(i.SwapOrderSn) && i.DownBatteryNo != null && i.DownBatteryNo!="-1" + && i.DownBatterySoc!=-1 && i.DownBatterySoc!=null); if (batterys.Count <= 0) { @@ -59,7 +60,12 @@ public class SwapOrderMgr continue; } - if (null == swapOrderBattery.DownBatteryNo) + + if (null == swapOrderBattery.DownBatteryNo || "-1".Equals(swapOrderBattery.DownBatteryNo)) + { + continue; + } + if (null == swapOrderBattery.DownBatterySoc || -1==swapOrderBattery.DownBatterySoc) { continue; } @@ -71,9 +77,9 @@ public class SwapOrderMgr var count = _swapOrderRepository.GetCount(i => i.SwapResult == 1 && i.SwapEndTime >= DateTime.Today && i.SwapEndTime < swapOrder.SwapEndTime); - - var uploadSwapOrder = CloudApi.UploadSwapOrder(swapOrder, count++, swapOrderBattery, uploadType); swapOrderReportClouds.TryGetValue(swapOrder.Id, out SwapOrderReportCloud value); + var uploadSwapOrder = CloudApi.UploadSwapOrder(swapOrder, count++, swapOrderBattery, uploadType,value); + if (uploadSwapOrder == 0) { swapOrder.CloudReportStatus = 1; diff --git a/Service/MyTask/UpdateDownBatteryInfoTask.cs b/Service/MyTask/UpdateDownBatteryInfoTask.cs index 9afff4f..6067bef 100644 --- a/Service/MyTask/UpdateDownBatteryInfoTask.cs +++ b/Service/MyTask/UpdateDownBatteryInfoTask.cs @@ -39,7 +39,7 @@ public class UpdateDownBatteryInfoTask : ITask { List batterys = _swapOrderBatteryRepository.QueryListByClause( - i => i.DownBatteryNo == null && i.DownBatteryBinNo != null); + i => (i.DownBatteryNo == null || i.DownBatterySoc<0) && i.DownBatteryBinNo != null); if (batterys.Count <= 0) diff --git a/Service/Plc/Client/PlcMgr.cs b/Service/Plc/Client/PlcMgr.cs index 98183a8..abd8919 100644 --- a/Service/Plc/Client/PlcMgr.cs +++ b/Service/Plc/Client/PlcMgr.cs @@ -183,6 +183,7 @@ public class PlcMgr { if (PlcClient != null) { + ResetPlc(); return PlcToHostData.TaskType.Value == taskNo; } diff --git a/Service/Station/MonitorService.cs b/Service/Station/MonitorService.cs index 818fff7..fad9778 100644 --- a/Service/Station/MonitorService.cs +++ b/Service/Station/MonitorService.cs @@ -56,14 +56,17 @@ public class MonitorService VelMac = StationSoftMgr.SwappingStateMachine.RfidReadModel != null ? StationSoftMgr.SwappingStateMachine.RfidReadModel.VelMac : null, - LockStatus = tboxCarInfoModel != null ? tboxCarInfoModel.HeartBeatMsg.LockStatus : null, - KeyStatus = tboxCarInfoModel != null ? tboxCarInfoModel.HeartBeatMsg.KeyStatus : null, + LockStatus = tboxCarInfoModel != null ? tboxCarInfoModel.CarStatus.LockStatus : null, + KeyStatus = tboxCarInfoModel != null ? tboxCarInfoModel.CarStatus.Keys : null, VelNo = StationSoftMgr.SwappingStateMachine.RfidReadModel != null ? StationSoftMgr.SwappingStateMachine.RfidReadModel.VelNo : null, VelVin = StationSoftMgr.SwappingStateMachine.RfidReadModel != null ? StationSoftMgr.SwappingStateMachine.RfidReadModel.VelVin : null, + Break = StationSoftMgr.SwappingStateMachine.BoxCarInfoModel?.CarStatus?.Break, + Gear = StationSoftMgr.SwappingStateMachine.BoxCarInfoModel?.CarStatus?.Gear, + }, BatteryInfo = new() { diff --git a/WebStarter/Controllers/SwapMonitorController.cs b/WebStarter/Controllers/SwapMonitorController.cs index 0771f9b..2ebe0b4 100644 --- a/WebStarter/Controllers/SwapMonitorController.cs +++ b/WebStarter/Controllers/SwapMonitorController.cs @@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Mvc; using Service.Execute; using Service.Execute.Api; using Service.Execute.Model; +using Service.Execute.Model.Tbox; using Service.Init; using Service.Plc.Client; using Service.Station; @@ -269,6 +270,20 @@ public class SwapMonitorController : ControllerBase [HttpGet("GetCarList")] public async Task>> GetCarList() { + //兼容不能查车辆列表的,就获取当前换电车辆 + if (!StaticStationInfo.TboxStateCarList) + { + if (StationSoftMgr.SwappingStateMachine.BoxCarInfoModel == null) + { + return Result>.Success(new List()); + } + + return Result>.Success(new() + { + StationSoftMgr.SwappingStateMachine.BoxCarInfoModel + }); + } + var carInfoList = await TBoxApi.GetCarInfoList(); if (carInfoList == null || carInfoList.Count <= 0) {