diff --git a/Entity/Api/Req/QueryChargeOrderReq.cs b/Entity/Api/Req/QueryChargeOrderReq.cs
index 87128f0..9e06379 100644
--- a/Entity/Api/Req/QueryChargeOrderReq.cs
+++ b/Entity/Api/Req/QueryChargeOrderReq.cs
@@ -12,11 +12,9 @@ namespace Entity.Api.Req
- ///
- /// Desc:订单编号
- /// Default:
- /// Nullable:True
- ///
+ ///
+ /// 订单编号
+ ///
public string? Sn {get;set;}
///
diff --git a/Entity/Api/Resp/ChargeOrderResp.cs b/Entity/Api/Resp/ChargeOrderResp.cs
index 473d33c..21ea145 100644
--- a/Entity/Api/Resp/ChargeOrderResp.cs
+++ b/Entity/Api/Resp/ChargeOrderResp.cs
@@ -203,6 +203,13 @@ namespace Entity.Api.Resp
/// Nullable:True
///
public DateTime? UpdatedTime {get;set;}
+
+
+ ///
+ /// 云平台订单号
+ ///
+
+ public string? CloudSn { get; set; }
}
}
diff --git a/Entity/Constant/BaseEnumExtensions.cs b/Entity/Constant/BaseEnumExtensions.cs
new file mode 100644
index 0000000..119004f
--- /dev/null
+++ b/Entity/Constant/BaseEnumExtensions.cs
@@ -0,0 +1,30 @@
+using System.ComponentModel;
+using System.Reflection;
+
+namespace Entity.Constant;
+
+public class BaseEnumExtensions
+{
+ //根据枚举获取注释
+ public static string GetDescription(Enum value)
+ {
+ FieldInfo field = value.GetType().GetField(value.ToString());
+
+ DescriptionAttribute attribute =
+ Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
+
+ return attribute == null ? value.ToString() : attribute.Description;
+ }
+
+ //根据code获取枚举
+ public static T GetEnumByCode(int code) where T : Enum
+ {
+ return (T)Enum.ToObject(typeof(T), code);
+ }
+
+ //根据code获取值
+ public static string GetEnumDescriptionByCode(int code) where T : Enum
+ {
+ return GetDescription((T)Enum.ToObject(typeof(T), code));
+ }
+}
\ No newline at end of file
diff --git a/Entity/Constant/StationConstant.cs b/Entity/Constant/StationConstant.cs
index 9443856..fa1ea4e 100644
--- a/Entity/Constant/StationConstant.cs
+++ b/Entity/Constant/StationConstant.cs
@@ -47,17 +47,7 @@ public class StationConstant
}
- public static class EnumExtensions
- {
- public static string GetDescription( Enum value)
- {
- FieldInfo field = value.GetType().GetField(value.ToString());
-
- DescriptionAttribute attribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
-
- return attribute == null ? value.ToString() : attribute.Description;
- }
- }
+
}
\ No newline at end of file
diff --git a/Entity/DbModel/Station/BinInfo.cs b/Entity/DbModel/Station/BinInfo.cs
index 73e1c19..ecae8a8 100644
--- a/Entity/DbModel/Station/BinInfo.cs
+++ b/Entity/DbModel/Station/BinInfo.cs
@@ -191,5 +191,18 @@ namespace Entity.DbModel.Station
[SugarColumn(ColumnName="updated_time")]
public DateTime? UpdatedTime {get;set;}
+ ///
+ /// 电池是否在为
+ /// 0:不在位 1:在位 2:无效
+ ///
+
+ [SugarColumn(ColumnName="exists")]
+ public int? Exists { get; set; }
+ ///
+ /// 最后结束充电的时间
+ ///
+ [SugarColumn(ColumnName="last_charge_finish_time")]
+ public DateTime? LastChargeFinishTime { get; set; }
+
}
}
diff --git a/Entity/DbModel/Station/SwapAmtOrder.cs b/Entity/DbModel/Station/SwapAmtOrder.cs
index 6654330..f89c06e 100644
--- a/Entity/DbModel/Station/SwapAmtOrder.cs
+++ b/Entity/DbModel/Station/SwapAmtOrder.cs
@@ -150,6 +150,11 @@ namespace Entity.DbModel.Station
///
[SugarColumn(ColumnName="updated_time")]
public DateTime? UpdatedTime {get;set;}
+
+ ///
+ /// 车牌
+ ///
+ public string VehicleNo { get; set; }
}
}
diff --git a/Entity/DbModel/Station/SwapOrder.cs b/Entity/DbModel/Station/SwapOrder.cs
index 291f77a..2810476 100644
--- a/Entity/DbModel/Station/SwapOrder.cs
+++ b/Entity/DbModel/Station/SwapOrder.cs
@@ -11,137 +11,141 @@ namespace Entity.DbModel.Station
[SugarTable("swap_order")]
public partial class SwapOrder
{
- public SwapOrder(){
-
-
- }
- ///
- /// Desc:id
- /// Default:
- /// Nullable:False
- ///
- [SugarColumn(IsPrimaryKey=true,IsIdentity=true,ColumnName="id")]
- public int Id {get;set;}
-
- ///
- /// Desc:订单编号
- /// Default:
- /// Nullable:True
- ///
- [SugarColumn(ColumnName="sn")]
- public string Sn {get;set;}
-
- ///
- /// Desc:车牌号
- /// Default:
- /// Nullable:True
- ///
- [SugarColumn(ColumnName="vehicle_no")]
- public string VehicleNo {get;set;}
-
- ///
- /// Desc:车辆mac
- /// Default:
- /// Nullable:True
- ///
- [SugarColumn(ColumnName="vehicle_mac")]
- public string VehicleMac {get;set;}
-
- ///
- /// Desc:车辆vin码
- /// Default:
- /// Nullable:True
- ///
- [SugarColumn(ColumnName="vehicle_vin")]
- public string VehicleVin {get;set;}
-
- ///
- /// Desc:车辆进场时间
- /// Default:
- /// Nullable:True
- ///
- [SugarColumn(ColumnName="vehicle_enter_time")]
- public DateTime? VehicleEnterTime {get;set;}
-
- ///
- /// Desc:车辆离场时间
- /// Default:
- /// Nullable:True
- ///
- [SugarColumn(ColumnName="vehicle_leave_time")]
- public DateTime? VehicleLeaveTime {get;set;}
-
- ///
- /// Desc:换电开始时间
- /// Default:
- /// Nullable:True
- ///
- [SugarColumn(ColumnName="swap_begin_time")]
- public DateTime? SwapBeginTime {get;set;}
-
- ///
- /// Desc:换电结束时间
- /// Default:
- /// Nullable:True
- ///
- [SugarColumn(ColumnName="swap_end_time")]
- public DateTime? SwapEndTime {get;set;}
-
- ///
- /// Desc:换电结果;0-未知;1-成功;2-失败
- /// Default:0
- /// Nullable:True
- ///
- [SugarColumn(ColumnName="swap_result")]
- public int? SwapResult {get;set;}
-
- ///
- /// Desc:失败原因
- /// Default:
- /// Nullable:True
- ///
- [SugarColumn(ColumnName="fail_reason")]
- public string FailReason {get;set;}
-
- ///
- /// Desc:上传云平台状态;0-未上传;1-已上传
- /// Default:0
- /// Nullable:True
- ///
- [SugarColumn(ColumnName="cloud_report_status")]
- public int? CloudReportStatus {get;set;}
-
- ///
- /// Desc:创建人
- /// Default:
- /// Nullable:True
- ///
- [SugarColumn(ColumnName="created_by")]
- public string CreatedBy {get;set;}
-
- ///
- /// Desc:创建时间
- /// Default:CURRENT_TIMESTAMP
- /// Nullable:True
- ///
- [SugarColumn(ColumnName="created_time")]
- public DateTime? CreatedTime {get;set;}
-
- ///
- /// Desc:更新人
- /// Default:
- /// Nullable:True
- ///
- [SugarColumn(ColumnName="updated_by")]
- public string UpdatedBy {get;set;}
-
- ///
- /// Desc:更新时间
- /// Default:CURRENT_TIMESTAMP
- /// Nullable:True
- ///
- [SugarColumn(ColumnName="updated_time")]
- public DateTime? UpdatedTime {get;set;}
-
+ public SwapOrder()
+ {
+ }
+
+ ///
+ /// Desc:id
+ /// Default:
+ /// Nullable:False
+ ///
+ [SugarColumn(IsPrimaryKey = true, IsIdentity = true, ColumnName = "id")]
+ public int Id { get; set; }
+
+ ///
+ /// Desc:订单编号
+ /// Default:
+ /// Nullable:True
+ ///
+ [SugarColumn(ColumnName = "sn")]
+ public string Sn { get; set; }
+
+ ///
+ /// Desc:车牌号
+ /// Default:
+ /// Nullable:True
+ ///
+ [SugarColumn(ColumnName = "vehicle_no")]
+ public string VehicleNo { get; set; }
+
+ ///
+ /// Desc:车辆mac
+ /// Default:
+ /// Nullable:True
+ ///
+ [SugarColumn(ColumnName = "vehicle_mac")]
+ public string VehicleMac { get; set; }
+
+ ///
+ /// Desc:车辆vin码
+ /// Default:
+ /// Nullable:True
+ ///
+ [SugarColumn(ColumnName = "vehicle_vin")]
+ public string VehicleVin { get; set; }
+
+ ///
+ /// Desc:车辆进场时间
+ /// Default:
+ /// Nullable:True
+ ///
+ [SugarColumn(ColumnName = "vehicle_enter_time")]
+ public DateTime? VehicleEnterTime { get; set; }
+
+ ///
+ /// Desc:车辆离场时间
+ /// Default:
+ /// Nullable:True
+ ///
+ [SugarColumn(ColumnName = "vehicle_leave_time")]
+ public DateTime? VehicleLeaveTime { get; set; }
+
+ ///
+ /// Desc:换电开始时间
+ /// Default:
+ /// Nullable:True
+ ///
+ [SugarColumn(ColumnName = "swap_begin_time")]
+ public DateTime? SwapBeginTime { get; set; }
+
+ ///
+ /// Desc:换电结束时间
+ /// Default:
+ /// Nullable:True
+ ///
+ [SugarColumn(ColumnName = "swap_end_time")]
+ public DateTime? SwapEndTime { get; set; }
+
+ ///
+ /// Desc:换电结果;0-未知;1-成功;2-失败
+ /// Default:0
+ /// Nullable:True
+ ///
+ [SugarColumn(ColumnName = "swap_result")]
+ public int? SwapResult { get; set; }
+
+ ///
+ /// Desc:失败原因
+ /// Default:
+ /// Nullable:True
+ ///
+ [SugarColumn(ColumnName = "fail_reason")]
+ public string FailReason { get; set; }
+
+ ///
+ /// Desc:上传云平台状态;0-未上传;1-已上传
+ /// Default:0
+ /// Nullable:True
+ ///
+ [SugarColumn(ColumnName = "cloud_report_status")]
+ public int? CloudReportStatus { get; set; }
+
+ ///
+ /// Desc:创建人
+ /// Default:
+ /// Nullable:True
+ ///
+ [SugarColumn(ColumnName = "created_by")]
+ public string CreatedBy { get; set; }
+
+ ///
+ /// Desc:创建时间
+ /// Default:CURRENT_TIMESTAMP
+ /// Nullable:True
+ ///
+ [SugarColumn(ColumnName = "created_time")]
+ public DateTime? CreatedTime { get; set; }
+
+ ///
+ /// Desc:更新人
+ /// Default:
+ /// Nullable:True
+ ///
+ [SugarColumn(ColumnName = "updated_by")]
+ public string UpdatedBy { get; set; }
+
+ ///
+ /// Desc:更新时间
+ /// Default:CURRENT_TIMESTAMP
+ /// Nullable:True
+ ///
+ [SugarColumn(ColumnName = "updated_time")]
+ public DateTime? UpdatedTime { get; set; }
+ ///
+ /// 云平台订单号
+ ///
+ [SugarColumn(ColumnName = "cloud_sn")]
+ public string? CloudSn { get; set; }
}
-}
+}
\ No newline at end of file
diff --git a/Entity/Entity.csproj b/Entity/Entity.csproj
index e52d8c8..6f549b2 100644
--- a/Entity/Entity.csproj
+++ b/Entity/Entity.csproj
@@ -27,10 +27,6 @@
-
-
-
-
diff --git a/HybirdFrameworkCore/HybirdFrameworkCore.csproj b/HybirdFrameworkCore/HybirdFrameworkCore.csproj
index c2fb8b7..ec6efa6 100644
--- a/HybirdFrameworkCore/HybirdFrameworkCore.csproj
+++ b/HybirdFrameworkCore/HybirdFrameworkCore.csproj
@@ -26,6 +26,8 @@
+
+
diff --git a/HybirdFrameworkCore/bin/Debug/net6.0/HybirdFrameworkCore.deps.json b/HybirdFrameworkCore/bin/Debug/net6.0/HybirdFrameworkCore.deps.json
index 7e4eb2e..a230c49 100644
--- a/HybirdFrameworkCore/bin/Debug/net6.0/HybirdFrameworkCore.deps.json
+++ b/HybirdFrameworkCore/bin/Debug/net6.0/HybirdFrameworkCore.deps.json
@@ -18,6 +18,8 @@
"Swashbuckle.AspNetCore.Swagger": "6.5.0",
"Swashbuckle.AspNetCore.SwaggerGen": "6.5.0",
"Swashbuckle.AspNetCore.SwaggerUI": "6.5.0",
+ "Vse.Web.Serialization.ControlledSerializationJsonConverter": "1.0.3",
+ "WebApiContrib.Formatting.JavaScriptSerializer": "0.9.2",
"log4net": "2.0.15"
},
"runtime": {
@@ -57,6 +59,18 @@
}
}
},
+ "Microsoft.AspNet.WebApi.Client/4.0.20710": {
+ "dependencies": {
+ "Microsoft.Net.Http": "2.0.20710",
+ "Newtonsoft.Json": "13.0.3"
+ },
+ "runtime": {
+ "lib/net40/System.Net.Http.Formatting.dll": {
+ "assemblyVersion": "4.0.0.0",
+ "fileVersion": "4.0.20710.0"
+ }
+ }
+ },
"Microsoft.CSharp/4.7.0": {},
"Microsoft.Extensions.ApiDescription.Server/6.0.5": {},
"Microsoft.Extensions.Configuration/7.0.0": {
@@ -156,6 +170,7 @@
}
}
},
+ "Microsoft.Net.Http/2.0.20710": {},
"Microsoft.NETCore.Platforms/2.0.0": {},
"Microsoft.OpenApi/1.2.3": {
"runtime": {
@@ -317,6 +332,25 @@
"fileVersion": "7.0.22.51805"
}
}
+ },
+ "Vse.Web.Serialization.ControlledSerializationJsonConverter/1.0.3": {
+ "runtime": {
+ "lib/net45/Vse.Web.Serialization.dll": {
+ "assemblyVersion": "1.0.3.0",
+ "fileVersion": "1.0.3.0"
+ }
+ }
+ },
+ "WebApiContrib.Formatting.JavaScriptSerializer/0.9.2": {
+ "dependencies": {
+ "Microsoft.AspNet.WebApi.Client": "4.0.20710"
+ },
+ "runtime": {
+ "lib/net40/WebApiContrib.Formatting.JavaScriptSerializer.dll": {
+ "assemblyVersion": "0.0.0.0",
+ "fileVersion": "0.0.0.0"
+ }
+ }
}
}
},
@@ -347,6 +381,13 @@
"path": "log4net/2.0.15",
"hashPath": "log4net.2.0.15.nupkg.sha512"
},
+ "Microsoft.AspNet.WebApi.Client/4.0.20710": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-BwFtW0cGr8tg02XalvF8MmznOpYrhquD2eXWI0oF3LLSqLMFoFkb8Pmke/7SnqkiNc+YfsaUqdXEKbjhv1Ctrw==",
+ "path": "microsoft.aspnet.webapi.client/4.0.20710",
+ "hashPath": "microsoft.aspnet.webapi.client.4.0.20710.nupkg.sha512"
+ },
"Microsoft.CSharp/4.7.0": {
"type": "package",
"serviceable": true,
@@ -424,6 +465,13 @@
"path": "microsoft.extensions.primitives/7.0.0",
"hashPath": "microsoft.extensions.primitives.7.0.0.nupkg.sha512"
},
+ "Microsoft.Net.Http/2.0.20710": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-OsB/5QO9tYJRLYIgBOhRl4Tssh3pw7+UAO9tMGMBg63f98GfjsniVIwLWRC0vcRr/F6HLP/NvRlHyGBhtD7Bmw==",
+ "path": "microsoft.net.http/2.0.20710",
+ "hashPath": "microsoft.net.http.2.0.20710.nupkg.sha512"
+ },
"Microsoft.NETCore.Platforms/2.0.0": {
"type": "package",
"serviceable": true,
@@ -556,6 +604,20 @@
"sha512": "sha512-DaGSsVqKsn/ia6RG8frjwmJonfos0srquhw09TlT8KRw5I43E+4gs+/bZj4K0vShJ5H9imCuXupb4RmS+dBy3w==",
"path": "system.text.json/7.0.0",
"hashPath": "system.text.json.7.0.0.nupkg.sha512"
+ },
+ "Vse.Web.Serialization.ControlledSerializationJsonConverter/1.0.3": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-eG8d1pOgu/espdIFfi9iAEE890oT9k5h/61RY9hpfu4+s1cozrZAkuwpHif6UadgKfexa5/BEVBZ8DNH1eA10w==",
+ "path": "vse.web.serialization.controlledserializationjsonconverter/1.0.3",
+ "hashPath": "vse.web.serialization.controlledserializationjsonconverter.1.0.3.nupkg.sha512"
+ },
+ "WebApiContrib.Formatting.JavaScriptSerializer/0.9.2": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-OHJxwvqZhrpIw5fz7058vEiGHozBE/GGfnWMWrd/DnZC4fXwCZPKKqiyvzqq5KWQw/xf1jZ+e0ip/m6M2ZiEpw==",
+ "path": "webapicontrib.formatting.javascriptserializer/0.9.2",
+ "hashPath": "webapicontrib.formatting.javascriptserializer.0.9.2.nupkg.sha512"
}
}
}
\ No newline at end of file
diff --git a/Repository/Station/BinInfoRepository.cs b/Repository/Station/BinInfoRepository.cs
new file mode 100644
index 0000000..71580e6
--- /dev/null
+++ b/Repository/Station/BinInfoRepository.cs
@@ -0,0 +1,14 @@
+using Entity.DbModel.Station;
+using HybirdFrameworkCore.Autofac.Attribute;
+using SqlSugar;
+
+namespace Repository.Station;
+
+[Scope("SingleInstance")]
+public class BinInfoRepository:BaseRepository
+{
+
+ public BinInfoRepository(ISqlSugarClient sqlSugar) : base(sqlSugar)
+ {
+ }
+}
\ No newline at end of file
diff --git a/Repository/Station/SwapAmtOrderRepository.cs b/Repository/Station/SwapAmtOrderRepository.cs
new file mode 100644
index 0000000..6f8b939
--- /dev/null
+++ b/Repository/Station/SwapAmtOrderRepository.cs
@@ -0,0 +1,14 @@
+using Entity.DbModel.Station;
+using HybirdFrameworkCore.Autofac.Attribute;
+using SqlSugar;
+
+namespace Repository.Station;
+
+[Scope("SingleInstance")]
+public class SwapAmtOrderRepository:BaseRepository
+{
+
+ public SwapAmtOrderRepository(ISqlSugarClient sqlSugar) : base(sqlSugar)
+ {
+ }
+}
\ No newline at end of file
diff --git a/Service/Execute/Api/CloudApi.cs b/Service/Execute/Api/CloudApi.cs
index 8745576..8b5f749 100644
--- a/Service/Execute/Api/CloudApi.cs
+++ b/Service/Execute/Api/CloudApi.cs
@@ -1,6 +1,38 @@
+using Entity.DbModel.Station;
+using log4net;
+using Service.Execute.Enum;
+using Service.Execute.Model;
+
namespace Service.Execute.Api;
public class CloudApi
{
+ ///
+ /// 云平台车辆认证
+ ///
+ ///
+ ///
+ public static bool VehicleCheck(RfidReadModel rfidReadModel)
+ {
+ return true;
+ }
+
+ ///
+ /// 上报换电步序到云端
+ ///
+ ///
+ ///
+ public static void SendStateLog(SwapOrder swapOrder, InfoEnum.BusinessSwappingForCloudState state)
+ {
+ return;
+ }
+ ///
+ /// 上报tbox数据
+ ///
+
+ public static void UploadTBoxCarInfo(SwapOrder swapOrder, TboxCarInfoModel model)
+ {
+ return ;
+ }
}
\ No newline at end of file
diff --git a/Service/Execute/Api/PlcApi.cs b/Service/Execute/Api/PlcApi.cs
index 3f5b381..9350067 100644
--- a/Service/Execute/Api/PlcApi.cs
+++ b/Service/Execute/Api/PlcApi.cs
@@ -33,4 +33,16 @@ public class PlcApi
//TODO::
return true;
}
+
+ ///
+ /// 写入口灯
+ /// 红灯:1020
+ /// 绿灯:1000
+ ///
+ ///
+ ///
+ public static bool WriteEntranceLamp(int data)
+ {
+ return true;
+ }
}
\ No newline at end of file
diff --git a/Service/Execute/Api/RfidApi.cs b/Service/Execute/Api/RfidApi.cs
index 26f0802..992d961 100644
--- a/Service/Execute/Api/RfidApi.cs
+++ b/Service/Execute/Api/RfidApi.cs
@@ -1,6 +1,6 @@
using log4net;
using Newtonsoft.Json;
-using Swapping.Business.Rfid;
+using Service.Execute.Model;
namespace Service.Execute.Api;
diff --git a/Service/Execute/Api/TboxApi.cs b/Service/Execute/Api/TboxApi.cs
index b0817c4..ad18ddb 100644
--- a/Service/Execute/Api/TboxApi.cs
+++ b/Service/Execute/Api/TboxApi.cs
@@ -1,6 +1,65 @@
+using log4net;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using Service.Execute.Model;
+
namespace Service.Execute.Api;
public class TBoxApi
{
+ private static readonly ILog Log = LogManager.GetLogger(typeof(TBoxApi));
+
+ //TODO::TBox 服务地址
+ private static readonly string BASE_URL = "http://localhost:7243";
+
+ private static readonly HttpClient _httpClient = new HttpClient()
+ {
+ Timeout = TimeSpan.FromSeconds(60)
+ };
+
+ public static async Task GetCarInfo()
+ {
+ Log.Info("GetCarInfo");
+ string url = BASE_URL + "/CarControl/getCarInfo";
+ try
+ {
+ string s = await _httpClient.GetStringAsync(url);
+ TboxCarInfoModel? tboxCarInfoModel = null;
+ if (!String.IsNullOrWhiteSpace(s))
+ {
+ tboxCarInfoModel = JsonConvert.DeserializeObject(s);
+ }
+
+ Log.Info($"GetCarInfo resp = {tboxCarInfoModel}");
+ return tboxCarInfoModel;
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ return null;
+ }
+ }
+ public static async Task IsConnected()
+ {
+ Log.Info("IsConnected");
+ string url = BASE_URL + "/CarControl/getCarInfo";
+ try
+ {
+ string s = await _httpClient.GetStringAsync(url);
+ TboxCarInfoModel? tboxCarInfoModel = null;
+ if (!String.IsNullOrWhiteSpace(s))
+ {
+ tboxCarInfoModel = JsonConvert.DeserializeObject(s);
+ }
+
+ Log.Info($"GetCarInfo resp = {tboxCarInfoModel}");
+ return tboxCarInfoModel.Connected;
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ return false;
+ }
+ }
}
\ No newline at end of file
diff --git a/Service/Execute/Enum/InfoEnum.cs b/Service/Execute/Enum/InfoEnum.cs
index c93d07c..851daa6 100644
--- a/Service/Execute/Enum/InfoEnum.cs
+++ b/Service/Execute/Enum/InfoEnum.cs
@@ -45,7 +45,6 @@ public class InfoEnum
[Remark("符合soc限制数量不足")] LessOfSoc,
[Remark("结束充电大于3分钟的数量不足")] LessOf3Minute,
[Remark("各种差数量不足")] LessOfMean,
- [Remark("未被预约数量不足")] LessOfUnAmt,
[Remark("预约电池异常")] AmtError,
[Remark("电池捆绑选包失败")] GroupError,
[Remark("无可用捆绑")] NoGroupError
@@ -62,23 +61,22 @@ public class InfoEnum
[Remark("换电中")] Swapping = 6,
[Remark("预约失败")] Expire = 7,
}
-
- public enum BusinessSwappingState : byte
+
+ public enum BusinessSwappingForCloudState : byte
{
[Remark("未知")] UnKnown,
[Remark("空闲")] Idle,
- [Remark("RFID扫描完成")] ScanRfid,
- [Remark("云平台验证完成")] CloudCheck,
- [Remark("车辆到位")] CarInPosition,
- [Remark("车辆准备完成(N档、手刹)")] CarPrepare,
- [Remark("云平台启动换电完成")] CloudBeginSwap,
- [Remark("车辆调整完成(下高压、下低压)")] CarAdjust,
+ [Remark("占位")] TakeUp,
+ [Remark("换电准备")] SwapReady,
[Remark("开始换电")] BeginSwap,
- [Remark("拆卸亏电包")] UnPack,
- [Remark("安装满电包")] Pack,
- [Remark("包安装完成")] PackFinish,
- [Remark("车辆自检")] CarSelfCheck,
- [Remark("换电完成(车辆驶离)")] SwapDone
+ [Remark("换电中")] Swapping,
+ [Remark("换电完成")] SwapFinish,
+ [Remark("换电中故障,等待修复")] SwappingErrWait,
+ [Remark("换电中故障,修复完成")] SwappingErrDone,
+ [Remark("换电暂停")] SwapPause,
+ [Remark("换电继续")] SwapContinue,
+ [Remark("换电完成(车辆未驶离)")] SwapDoneWithVel,
+ [Remark("换电完成(车辆驶离)")] SwapDoneWithoutVel
}
public enum AmtBatLockStatus : byte
diff --git a/Service/Execute/Invoker.cs b/Service/Execute/Invoker.cs
index c371974..9fbdf3b 100644
--- a/Service/Execute/Invoker.cs
+++ b/Service/Execute/Invoker.cs
@@ -45,11 +45,12 @@ public class Invoker
return InvokeStatus.Done;
}
+
public static InvokeStatus Invoke(string name, int duration, int times, Func cancel, Func done,
Action doAction,
- Action timeoutAction, bool isTimeOutExit, Action exceptionAction)
+ Action exceptionAction)
{
- int hvPwrOffTimes = 0;
+ int count = 0;
while (!done())
{
Log.Info($"begin {name}");
@@ -70,22 +71,12 @@ public class Invoker
exceptionAction();
}
- if (hvPwrOffTimes++ > times)
- {
- timeoutAction();
- Log.Info($" {name} timeout");
- if (isTimeOutExit)
- {
- return InvokeStatus.TimeOut;
- }
- }
}
Log.Info($" {name} done");
return InvokeStatus.Done;
}
-
public static InvokeStatus Invoke(string name, int duration, int times, Func cancel, Func done,
Action doAction,
Action timeoutAction, bool isTimeOutExit, Action exceptionAction, int timeOutActionTime,InvokeStatus timeOutException)
@@ -163,5 +154,6 @@ public enum InvokeStatus
Cancel,
TimeOut,
Done,
- Exception
+ Exception,
+ None
}
\ No newline at end of file
diff --git a/Service/Execute/Model/RfidReadModel.cs b/Service/Execute/Model/RfidReadModel.cs
index e4115f1..8788032 100644
--- a/Service/Execute/Model/RfidReadModel.cs
+++ b/Service/Execute/Model/RfidReadModel.cs
@@ -1,4 +1,4 @@
-namespace Swapping.Business.Rfid;
+namespace Service.Execute.Model;
public class RfidReadModel
{
diff --git a/Service/Execute/Model/SwapOrderBatteryInfo.cs b/Service/Execute/Model/SwapOrderBatteryInfo.cs
new file mode 100644
index 0000000..1fc3337
--- /dev/null
+++ b/Service/Execute/Model/SwapOrderBatteryInfo.cs
@@ -0,0 +1,17 @@
+using Entity.DbModel.Station;
+using NewLife.Common;
+using Service.Execute.Enum;
+
+namespace Service.Execute.Model;
+
+public class SwapOrderBatteryInfo
+{
+ public bool isAmt;
+ public SwapAmtOrder swapAmtOrder;
+ public SwapOrderBattery SwapOrderBattery;
+
+ public InfoEnum.SelectBinStatusInfo CanSwap;
+
+ public BinInfo UpBinInfo;
+ public BinInfo InBinInfo;
+}
\ No newline at end of file
diff --git a/Service/Execute/Model/TboxCarInfoModel.cs b/Service/Execute/Model/TboxCarInfoModel.cs
new file mode 100644
index 0000000..0c45e60
--- /dev/null
+++ b/Service/Execute/Model/TboxCarInfoModel.cs
@@ -0,0 +1,27 @@
+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/Model/TboxElecMsg.cs b/Service/Execute/Model/TboxElecMsg.cs
new file mode 100644
index 0000000..42dbd10
--- /dev/null
+++ b/Service/Execute/Model/TboxElecMsg.cs
@@ -0,0 +1,84 @@
+using HybirdFrameworkCore.Autofac.Attribute;
+
+namespace Service.Execute.Model;
+
+public class TboxElecMsg
+{
+ ///
+ /// 车辆累计放电量
+ ///
+ [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/TboxHeartBeatMsg.cs b/Service/Execute/Model/TboxHeartBeatMsg.cs
new file mode 100644
index 0000000..035a248
--- /dev/null
+++ b/Service/Execute/Model/TboxHeartBeatMsg.cs
@@ -0,0 +1,22 @@
+using HybirdFrameworkCore.Autofac.Attribute;
+
+namespace Service.Execute.Model;
+
+public class TboxHeartBeatMsg
+{
+ ///
+ /// 锁止状态 1 解锁状态 2 上锁状态
+ ///
+ [Property(248, 8)]
+ public byte LockStatus { get; set; }
+ ///
+ /// 钥匙状态 0: OFF 1: ACC 2: ON 0xFF: 不支持
+ ///
+ [Property(256, 8)]
+ public byte KeyStatus { get; set; }
+ ///
+ /// 电磁阀驱动状态 0:驱动关闭 1:驱动打开
+ ///
+ [Property(264, 8)]
+ public byte SolenoidValveStatus { get; set; }
+}
\ No newline at end of file
diff --git a/Service/Execute/Step/CarPrepareState.cs b/Service/Execute/Step/CarPrepareState.cs
index 4db0463..0fb106a 100644
--- a/Service/Execute/Step/CarPrepareState.cs
+++ b/Service/Execute/Step/CarPrepareState.cs
@@ -1,14 +1,446 @@
-namespace Service.Execute.Step;
+using AutoMapper;
+using Entity.Constant;
+using Entity.DbModel.Station;
+using log4net;
+using Repository.Station;
+using Service.Execute.Api;
+using Service.Execute.Enum;
+using Service.Execute.Model;
+using Service.Execute.StaticTools;
+using Service.Execute.SwapException;
+using Service.Init;
+using Swapping.Business.Tech;
-public class CarPrepareState: IState
+namespace Service.Execute.Step;
+
+public class CarPrepareState : IState
{
+ private readonly ILog _log = LogManager.GetLogger(typeof(CarPrepareState));
+
+
+ private BinInfoRepository BinInfoRepository { get; set; }
+
+ private SwapAmtOrderRepository AmtOrderRepository { get; set; }
+
+ private SwapOrderBatteryRepository SwapOrderBatteryRepository { get; set; }
+
public StateResult Handle(SwappingStateMachine machine)
{
-
+ Thread.Sleep(500);
+ RfidReadModel? rfidReadModel = machine.RfidReadModel;
+ if (rfidReadModel == null)
+ {
+ _log.Error("rfid is null");
+ return new StateResult()
+ {
+ SwappingState = SwappingState.StationReady
+ };
+ }
+
+ //云平台车辆认证
+ var cloudCheckVel = CloudCheckVel(machine);
+ if (cloudCheckVel != InvokeStatus.Done)
+ {
+ return SwappingStateMachine.ReturnWithInvokeErr(cloudCheckVel, ExceptionReason.None);
+ }
+
+ //检查tbox链接状态
+ InvokeStatus checkTBoxConnect = CheckTBoxConnectFlag(machine);
+ if (checkTBoxConnect != InvokeStatus.Done)
+ {
+ return SwappingStateMachine.ReturnWithInvokeErr(checkTBoxConnect, ExceptionReason.None);
+ }
+
+ //车辆本地验证
+ InvokeStatus checkTBoxVelLocal = CheckTBoxVelLocalFlag(machine);
+ if (checkTBoxVelLocal != InvokeStatus.Done)
+ {
+ return SwappingStateMachine.ReturnWithInvokeErr(checkTBoxVelLocal, ExceptionReason.None);
+ }
+
+
+ //云端数据上报
+ InvokeStatus cloudTBox = CloudTBoxFlag(machine);
+ if (cloudTBox != InvokeStatus.Done)
+ {
+ return SwappingStateMachine.ReturnWithInvokeErr(cloudTBox, ExceptionReason.None);
+ }
+
+ SwappingStateMachine.ExceptionReason = ExceptionReason.None;
+
+ //选包
+ InvokeStatus selectPack = SelectPack(machine);
+ if (selectPack != InvokeStatus.Done)
+ {
+ return SwappingStateMachine.ReturnWithInvokeErr(selectPack, ExceptionReason.None);
+ }
+
+ //车辆到位
+ InvokeStatus carInPosition = CarInPosition(machine);
+ if (carInPosition != InvokeStatus.Done)
+ {
+ return SwappingStateMachine.ReturnWithInvokeErr(carInPosition, ExceptionReason.None);
+ }
+
return new StateResult()
{
-
- SwappingState = SwappingState.StationReady
+ SwappingState = SwappingState.SelectPack
+ };
+ }
+
+
+ ///
+ /// 车辆到位
+ ///
+ ///
+ public InvokeStatus CarInPosition(SwappingStateMachine machine)
+ {
+ return Invoker.Invoke("check CarInPosition", 500, 50, machine.IsCanceled,
+ () => SwappingStateMachine.VehiclesInPlaceFlag, () =>
+ {
+ var result = TBoxApi.GetCarInfo();
+ TboxCarInfoModel tboxCarInfoModel = result.Result;
+
+ if (tboxCarInfoModel.HeartBeatMsg.KeyStatus == 0)
+ {
+ SwappingStateMachine.VehiclesInPlaceFlag = true;
+ //写入口等 :红灯
+ if (PlcApi.WriteEntranceLamp(1020))
+ {
+ machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.InfoCarInPosition.GetLed());
+ SoundTool.PlayOneSound((int)InfoEnum.SwapInfo.InfoCarInPosition);
+ SwappingStateMachine.VehiclesInPlaceFlag = true;
+ }
+ }
+ }, () =>
+ {
+ SwappingStateMachine.ExceptionReason = ExceptionReason.CarInPositionError;
+ machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrorCarInPositionTimeout.GetLed());
+ SoundTool.PlayOneSound((int)InfoEnum.SwapInfo.ErrorCarInPositionTimeout);
+ }, false, () => { }
+ , 20, InvokeStatus.None);
+ }
+
+ ///
+ /// 云平台车辆认证
+ ///
+ ///
+ public InvokeStatus CloudCheckVel(SwappingStateMachine machine)
+ {
+ return Invoker.Invoke("cloud check vehicle", 500, 20, machine.IsCanceled,
+ () => SwappingStateMachine.CloudVelCheckFlag, () =>
+ {
+ if (BaseEnumExtensions.GetEnumByCode(
+ int.Parse(StaticStationInfo.StationModel)) == StationConstant.StationModel.Remote)
+ {
+ bool flag = CloudApi.VehicleCheck(machine.RfidReadModel);
+
+ if (!flag)
+ {
+ _log.Info("cloud check vehicle error");
+ }
+ else
+ {
+ //置为换电准备中 ,上报换电准备中
+ SwappingStateMachine.BusinessSwappingForCloudState =
+ InfoEnum.BusinessSwappingForCloudState.SwapReady;
+ SwappingStateMachine.ExceptionReason = ExceptionReason.None;
+ _log.Info("cloud check vehicle done");
+ SwappingStateMachine.CloudVelCheckFlag = true;
+ machine.LedTool.WriteProgramContent("换电准备中:云平台车辆验证完成");
+ CloudApi.SendStateLog(machine.SwapOrder, SwappingStateMachine.BusinessSwappingForCloudState);
+ SwappingStateMachine.CloudVelCheckFlag = true;
+ }
+ }
+ else
+ {
+ SwappingStateMachine.CloudVelCheckFlag = true;
+ }
+ }, () =>
+ {
+ machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrorCloudCheck.GetLed());
+ SoundTool.PlayOneSound((int)InfoEnum.SwapInfo.ErrorCloudCheck);
+ }, false, () => { SwappingStateMachine.ExceptionReason = ExceptionReason.CloudCheckError; }
+ , 20, InvokeStatus.None);
+ }
+
+
+ ///
+ /// 检查tbox连接状态
+ ///
+ ///
+ public InvokeStatus CheckTBoxConnectFlag(SwappingStateMachine machine)
+ {
+ return Invoker.Invoke("check TBox connect", 1000, 20, machine.IsCanceled,
+ () => SwappingStateMachine.TBoxConnectFlag, () =>
+ {
+ Task result = TBoxApi.IsConnected();
+ bool isConnect = result.Result;
+ if (isConnect)
+ {
+ SwappingStateMachine.TBoxConnectFlag = true;
+ }
+ }, () => { SwappingStateMachine.ExceptionReason = ExceptionReason.ConnTBoxError; }, false, () =>
+ {
+ SwappingStateMachine.ExceptionReason = ExceptionReason.ConnTBoxError;
+ }
+ , 10, InvokeStatus.None);
+ }
+
+
+ ///
+ /// 车辆本地验证:车牌校验
+ ///
+ ///
+ public InvokeStatus CheckTBoxVelLocalFlag(SwappingStateMachine machine)
+ {
+ return Invoker.Invoke("check TBox VelLocal", 1000, 20, machine.IsCanceled,
+ () => SwappingStateMachine.TBoxLocalCheckFlag, () =>
+ {
+ Task carInfo = TBoxApi.GetCarInfo();
+ var tBoxCarInfoModel = carInfo.Result;
+ //TODO::不知道Tbox给的CardNo是什么
+ if (tBoxCarInfoModel.CarNo.Trim().Equals(machine.RfidReadModel.VelNo.Trim()))
+ {
+ SwappingStateMachine.TBoxLocalCheckFlag = true;
+ }
+ }, () => { SwappingStateMachine.ExceptionReason = ExceptionReason.LocalCheckVarError; }, true, () =>
+ {
+ SwappingStateMachine.ExceptionReason = ExceptionReason.LocalCheckVarError;
+ }
+ , 3, InvokeStatus.TimeOut);
+ }
+
+
+ ///
+ /// 蓝牙数据云平台上报
+ ///
+ ///
+ public InvokeStatus CloudTBoxFlag(SwappingStateMachine machine)
+ {
+ return Invoker.Invoke("cloud TBox upload", 500, 20, machine.IsCanceled,
+ () => SwappingStateMachine.CloudTBoxFlag, () =>
+ {
+ Task result = TBoxApi.GetCarInfo();
+ TboxCarInfoModel tBoxCarInfoModel = result.Result;
+ machine.TBoxCarInfoModel = tBoxCarInfoModel;
+ if (tBoxCarInfoModel != null)
+ {
+ if (tBoxCarInfoModel.Connected)
+ {
+ //将数据上报云平台
+ CloudApi.UploadTBoxCarInfo(machine.SwapOrder, machine.TBoxCarInfoModel);
+ }
+ }
+ }, () => { machine.LedTool?.WriteProgramContent("车机蓝牙车辆数据上报异常,请联系站务人员"); }, false, () =>
+ {
+ SwappingStateMachine.ExceptionReason = ExceptionReason.CloudCarDataUploadError;
+ }
+ , 20, InvokeStatus.None);
+ }
+
+ ///
+ /// 选包:
+ /// 有预约单: 获取预约单的电池
+ /// 无预约单:
+ /// 1.仓位状态:启动
+ /// 2.电池在位
+ /// 3.充电状态:不在充电中
+ /// 4.未锁定
+ /// 5.最后一次结束充电时间> ()
+ /// 6.soc >()
+ ///
+ ///
+ public InvokeStatus SelectPack(SwappingStateMachine machine)
+ {
+ SwapAmtOrder? swapAmtOrder =
+ AmtOrderRepository.QueryByClause(i => i.Status == 1 && i.VehicleNo.Equals(machine.TBoxCarInfoModel.CarNo));
+
+
+ return Invoker.Invoke("selectPack", 500, 20, machine.IsCanceled,
+ () => SwappingStateMachine.SelectPackFlag, () =>
+
+ {
+ SwapOrderBatteryInfo orderBatteryInfo = null;
+ if (swapAmtOrder != null)
+ {
+ orderBatteryInfo = SelectPackArm(swapAmtOrder);
+ }
+ else
+ {
+ orderBatteryInfo = SelectPackNotArm();
+ }
+
+ if (orderBatteryInfo.CanSwap != InfoEnum.SelectBinStatusInfo.Success)
+ {
+ machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrorSelectPack.GetLed());
+ SoundTool.PlayOneSound((int)InfoEnum.SwapInfo.ErrorSelectPack);
+ Thread.Sleep(1000 * 3);
+ _log.Info($"SelectPack error CanSwap={machine.SwapOrderBatteryInfo.CanSwap}");
+ }
+ else
+ {
+ //选包成功
+ LockBinAndUpdateAmt(orderBatteryInfo);
+ machine.SwapOrderBatteryInfo = orderBatteryInfo;
+ SaveSwapBattery(machine);
+ SwappingStateMachine.SelectPackFlag = true;
+ }
+ }, () => { SwappingStateMachine.ExceptionReason = ExceptionReason.SelectPackError; });
+ }
+
+ private void SaveSwapBattery(SwappingStateMachine machine)
+ {
+ 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),
};
+ SwapOrderBatteryRepository.Insert(swapOrderBattery);
+ }
+
+ ///
+ /// 1.锁仓
+ /// 2.更改预约单
+ ///
+ private void LockBinAndUpdateAmt(SwapOrderBatteryInfo orderBatteryInfo)
+ {
+ var configBinInfo =
+ new MapperConfiguration(cfg => cfg.CreateMap().ReverseMap());
+ IMapper mapperBinInfo = configBinInfo.CreateMapper();
+ BinInfo dbBinInfo = mapperBinInfo.Map(orderBatteryInfo.UpBinInfo);
+
+ dbBinInfo.AmtLock = "1";
+ BinInfoRepository.Update(dbBinInfo);
+ if (!orderBatteryInfo.isAmt)
+ {
+ return;
+ }
+
+ var configAmt =
+ new MapperConfiguration(cfg => cfg.CreateMap().ReverseMap());
+ IMapper mapperAmt = configAmt.CreateMapper();
+ SwapAmtOrder swapAmtOrder = mapperAmt.Map(orderBatteryInfo.swapAmtOrder);
+ swapAmtOrder.Status = 6;
+ AmtOrderRepository.Update(swapAmtOrder);
+ }
+
+ /// 1.仓位状态:启动
+ /// 2.电池在位
+ /// 3.充电状态:不在充电中
+ /// 4.未锁定
+ /// 5.最后一次结束充电时间> ()
+ /// 6.soc >()
+ /**
+ * && i.ChargeStatus == 2
+ && i.AmtLock == "0"
+ && new TimeSpan(DateTime.Now.Ticks -
+ i.LastChargeFinishTime.ToDateTime().Ticks)
+ .TotalMinutes > StaticStationInfo.SwapFinishChargeTime
+ && i.Soc > StaticStationInfo.Soc
+ */
+ private SwapOrderBatteryInfo SelectPackNotArm()
+ {
+ SwapOrderBatteryInfo orderBatteryInfo = new SwapOrderBatteryInfo();
+ UpBin(orderBatteryInfo);
+ if (orderBatteryInfo.CanSwap != InfoEnum.SelectBinStatusInfo.Success)
+ {
+ return orderBatteryInfo;
+ }
+
+ InBin(orderBatteryInfo);
+
+ return orderBatteryInfo;
+ }
+
+ private SwapOrderBatteryInfo SelectPackArm(SwapAmtOrder swapAmtOrder)
+ {
+ SwapOrderBatteryInfo orderBatteryInfo = new SwapOrderBatteryInfo();
+ orderBatteryInfo.swapAmtOrder = swapAmtOrder;
+ orderBatteryInfo.isAmt = true;
+ BinInfo UpBin = BinInfoRepository.QueryByClause(i => i.No.Equals(swapAmtOrder.AmtBinNoList));
+ bool CanSwap = UpBin.Exists == 1 && UpBin.Status == 1 && UpBin.ChargeStatus == 2
+ && UpBin.AmtLock == "1" && new TimeSpan(DateTime.Now.Ticks -
+ UpBin.LastChargeFinishTime.ToDateTime()
+ .Ticks)
+ .TotalMinutes > int.Parse(StaticStationInfo.SwapFinishChargeTime) &&
+ UpBin.Soc > int.Parse(StaticStationInfo.SwapSoc);
+ if (!CanSwap)
+ {
+ orderBatteryInfo.CanSwap = InfoEnum.SelectBinStatusInfo.AmtError;
+
+ return orderBatteryInfo;
+ }
+
+ orderBatteryInfo.UpBinInfo = UpBin;
+ InBin(orderBatteryInfo);
+ return orderBatteryInfo;
+ }
+
+ ///
+ /// 取电池判断
+ ///
+ ///
+ private void UpBin(SwapOrderBatteryInfo orderBatteryInfo)
+ {
+ List list =
+ BinInfoRepository.QueryListByClause(i => i.Exists == 1 && i.Status == 1 && i.AmtLock == "0");
+ if (list.Count <= 0)
+ {
+ orderBatteryInfo.CanSwap = InfoEnum.SelectBinStatusInfo.NoBattery;
+ return;
+ }
+
+ list = list.Where(i => i.ChargeStatus == 2).ToList();
+ if (list.Count <= 0)
+ {
+ orderBatteryInfo.CanSwap = InfoEnum.SelectBinStatusInfo.LessOfFinishCharging;
+ return;
+ }
+
+
+ list = list.Where(i => i.Soc > int.Parse(StaticStationInfo.SwapSoc)).ToList();
+ if (list.Count <= 0)
+ {
+ orderBatteryInfo.CanSwap = InfoEnum.SelectBinStatusInfo.LessOfSoc;
+ return;
+ }
+
+ list = list.Where(i => new TimeSpan(DateTime.Now.Ticks -
+ i.LastChargeFinishTime.ToDateTime().Ticks)
+ .TotalMinutes > int.Parse(StaticStationInfo.SwapFinishChargeTime)).ToList();
+ if (list.Count <= 0)
+ {
+ orderBatteryInfo.CanSwap = InfoEnum.SelectBinStatusInfo.LessOf3Minute;
+ return;
+ }
+
+ orderBatteryInfo.UpBinInfo = list[0];
+ orderBatteryInfo.CanSwap = InfoEnum.SelectBinStatusInfo.Success;
+ }
+
+ ///
+ /// 放电池判断
+ ///
+ ///
+ private void InBin(SwapOrderBatteryInfo orderBatteryInfo)
+ {
+ List list =
+ BinInfoRepository.QueryListByClause(i => i.Exists == 1 && i.Status == 1 && i.AmtLock == "0"
+ && i.Exists == 0);
+ if (list.Count <= 0)
+ {
+ orderBatteryInfo.CanSwap = InfoEnum.SelectBinStatusInfo.LessOfEmptyBin;
+ return;
+ }
+
+ orderBatteryInfo.InBinInfo = list[0];
+ orderBatteryInfo.CanSwap = InfoEnum.SelectBinStatusInfo.Success;
}
}
\ No newline at end of file
diff --git a/Service/Execute/Step/CloudSendOutSwapState.cs b/Service/Execute/Step/CloudSendOutSwapState.cs
new file mode 100644
index 0000000..b09e25f
--- /dev/null
+++ b/Service/Execute/Step/CloudSendOutSwapState.cs
@@ -0,0 +1,52 @@
+using Entity.Constant;
+
+namespace Service.Execute.Step;
+
+///
+/// 云平台下发换电
+///
+public class CloudSendOutSwapState: IState
+{
+ public StateResult Handle(SwappingStateMachine machine)
+ {
+
+ return new StateResult()
+ {
+
+ SwappingState = SwappingState.StationReady
+ };
+ }
+
+
+ ///
+ /// 等待云平台下发换电
+ ///
+ ///
+ /*public InvokeStatus CloudSendOutSwap(SwappingStateMachine machine)
+ {
+ return Invoker.Invoke("check CarInPosition", 500, 50, machine.IsCanceled,
+ () => SwappingStateMachine.VehiclesInPlaceFlag, () =>
+ {
+ var result = TBoxApi.GetCarInfo();
+ TboxCarInfoModel tboxCarInfoModel = result.Result;
+
+ if (tboxCarInfoModel.HeartBeatMsg.KeyStatus == 0)
+ {
+ SwappingStateMachine.VehiclesInPlaceFlag = true;
+ //写入口等 :红灯
+ if (PlcApi.WriteEntranceLamp(1020))
+ {
+ machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.InfoCarInPosition.GetLed());
+ SoundTool.PlayOneSound((int)InfoEnum.SwapInfo.InfoCarInPosition);
+ SwappingStateMachine.VehiclesInPlaceFlag = true;
+ }
+ }
+ }, () =>
+ {
+ SwappingStateMachine.ExceptionReason = ExceptionReason.CarInPositionError;
+ machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrorCarInPositionTimeout.GetLed());
+ SoundTool.PlayOneSound((int)InfoEnum.SwapInfo.ErrorCarInPositionTimeout);
+ }, false, () => { }
+ , 20, InvokeStatus.None);
+ }*/
+}
\ No newline at end of file
diff --git a/Service/Execute/Step/SelectPackState.cs b/Service/Execute/Step/SelectPackState.cs
deleted file mode 100644
index 6469a08..0000000
--- a/Service/Execute/Step/SelectPackState.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-namespace Service.Execute.Step;
-
-public class SelectPackState: IState
-{
- public StateResult Handle(SwappingStateMachine machine)
- {
-
- return new StateResult()
- {
-
- SwappingState = SwappingState.StationReady
- };
- }
-}
\ No newline at end of file
diff --git a/Service/Execute/Step/StationReadyState.cs b/Service/Execute/Step/StationReadyState.cs
index 6832ae6..edc70bb 100644
--- a/Service/Execute/Step/StationReadyState.cs
+++ b/Service/Execute/Step/StationReadyState.cs
@@ -2,16 +2,17 @@
using Entity.Constant;
using Entity.DbModel.Station;
using log4net;
+using Microsoft.OpenApi.Extensions;
using Microsoft.VisualBasic;
using Newtonsoft.Json;
using Repository.Station;
using Service.Execute.Api;
using Service.Execute.Enum;
+using Service.Execute.Model;
using Service.Execute.StaticTools;
using Service.Execute.SwapException;
using Service.Init;
using Swapping.Business.Common;
-using Swapping.Business.Rfid;
using Swapping.Business.Tech;
namespace Service.Execute.Step;
@@ -28,7 +29,7 @@ public class StationReadyState : IState
_log.Info($"'goto stationReady");
machine.Reset();
- SwappingStateMachine.BusinessSwappingState = InfoEnum.BusinessSwappingState.Idle;
+ SwappingStateMachine.BusinessSwappingForCloudState = InfoEnum.BusinessSwappingForCloudState.Idle;
SwappingStateMachine.BusinessSwappingStateUpdateTime = DateTime.Now;
//判断换电站是否具备换电条件
@@ -78,20 +79,29 @@ public class StationReadyState : IState
public InvokeStatus PlcIsRemote(SwappingStateMachine machine)
{
- return Invoker.Invoke("check plc remote", 1000, 5, machine.IsCanceled, PlcApi.IsRemote,
+ bool isRemote = false;
+ return Invoker.Invoke("check plc remote", 1000, 5, machine.IsCanceled, () => isRemote,
() =>
{
- //LED显示-欢迎光临_换电站点_正在营业(三行展示)
- string welcomeContent = "欢迎光临" + StaticStationInfo.StationName + "正在营业";
-
- machine.LedTool?.WriteContent(welcomeContent);
+ if (PlcApi.IsRemote())
+ {
+ //写入口灯绿灯
+ if (PlcApi.WriteEntranceLamp(1000))
+ {
+ //LED显示-欢迎光临_换电站点_正在营业
+ string welcomeContent = "欢迎光临" + StaticStationInfo.StationName + "正在营业";
+
+ machine.LedTool?.WriteContent(welcomeContent);
+ isRemote = true;
+ }
+ }
},
- () => { }, false);
+ () => { }, true);
}
public InvokeStatus EntranceRadar(SwappingStateMachine machine)
{
- return Invoker.Invoke("wait entrance radar", 1000, 1, machine.IsCanceled,
+ return Invoker.Invoke("wait entrance radar", 1000, 5, machine.IsCanceled,
() => SwappingStateMachine.RadarInFlag, () =>
{
if (!PlcApi.EntranceRadar())
@@ -128,7 +138,8 @@ public class StationReadyState : IState
{
machine.LedTool.WriteProgramContent(InfoEnum.SwapInfo.ErrorReadRfid.GetLed());
SoundTool.PlayOneSound((int)InfoEnum.SwapInfo.ErrorReadRfid);
- }, false, () => { SwappingStateMachine.ExceptionReason = ExceptionReason.ReadRfidError; });
+ }, false, () => { SwappingStateMachine.ExceptionReason = ExceptionReason.ReadRfidError; }
+ , 1, InvokeStatus.TimeOut);
}
///
@@ -139,13 +150,19 @@ public class StationReadyState : IState
///
private bool IsAutoSwapping()
{
- var statusDes = StationConstant.EnumExtensions.GetDescription(StaticStationInfo.StationStatus);
+ var statusDes =
+ BaseEnumExtensions.GetEnumDescriptionByCode(
+ int.Parse(StaticStationInfo.StationStatus));
_log.Info($"换电站处于{statusDes}状态");
- var wayDes = StationConstant.EnumExtensions.GetDescription(StaticStationInfo.StationWay);
+ var wayDes =
+ BaseEnumExtensions.GetEnumDescriptionByCode(
+ int.Parse(StaticStationInfo.StationWay));
_log.Info($"换电站处于{wayDes}模式");
- if (StationConstant.StationStatus.Run == StaticStationInfo.StationStatus
- && StationConstant.StationWay.Auto == StaticStationInfo.StationWay)
+ if (StationConstant.StationStatus.Run ==
+ BaseEnumExtensions.GetEnumByCode(int.Parse(StaticStationInfo.StationStatus))
+ && StationConstant.StationWay.Auto ==
+ BaseEnumExtensions.GetEnumByCode(int.Parse(StaticStationInfo.StationWay)))
{
return true;
}
@@ -177,9 +194,8 @@ public class StationReadyState : IState
_log.Info($"read rfid={JsonConvert.SerializeObject(machine.RfidReadModel)}");
SwappingStateMachine.ExceptionReason = ExceptionReason.None;
- SwappingStateMachine.BusinessSwappingState = InfoEnum.BusinessSwappingState.ScanRfid;
SwappingStateMachine.BusinessSwappingStateUpdateTime = DateTime.Now;
- _log.Info($"BusinessSwappingState={SwappingStateMachine.BusinessSwappingState}");
+ _log.Info($"BusinessSwappingForCloudState={SwappingStateMachine.BusinessSwappingForCloudState}");
machine.SwapOrder = SaveOrder(BuildOrder(machine.RfidReadModel));
diff --git a/Service/Execute/SwapException/ExceptionReason.cs b/Service/Execute/SwapException/ExceptionReason.cs
index 26d8aa2..7dea255 100644
--- a/Service/Execute/SwapException/ExceptionReason.cs
+++ b/Service/Execute/SwapException/ExceptionReason.cs
@@ -8,11 +8,11 @@ namespace Service.Execute.SwapException;
{
None,
ReadRfidError,
- OpenBarrierError,
- ConnVbleError,
+ ConnTBoxError,
CarStateCheckError,
CloudCheckError,
- CloudVbleDataError,
+ LocalCheckVarError,
+ CloudCarDataUploadError,
CarInPositionError,
CloudSendSwapError,
SelectPackError,
diff --git a/Service/Execute/SwappingStateMachine.cs b/Service/Execute/SwappingStateMachine.cs
index 66d365e..3028612 100644
--- a/Service/Execute/SwappingStateMachine.cs
+++ b/Service/Execute/SwappingStateMachine.cs
@@ -2,11 +2,11 @@
using log4net;
using Newtonsoft.Json;
using Service.Execute.Enum;
+using Service.Execute.Model;
using Service.Execute.StaticTools;
using Service.Execute.Step;
using Service.Execute.SwapException;
using Service.Execute.Tech;
-using Swapping.Business.Rfid;
namespace Service.Execute;
@@ -22,16 +22,21 @@ public class SwappingStateMachine : IDisposable
private Dictionary Dictionary = new Dictionary();
private StateResult _result = new StateResult() { SwappingState = SwappingState.Begin };
- public static InfoEnum.BusinessSwappingState BusinessSwappingState = InfoEnum.BusinessSwappingState.UnKnown;
+ //给云平台的实时状态
+ public static InfoEnum.BusinessSwappingForCloudState BusinessSwappingForCloudState =
+ InfoEnum.BusinessSwappingForCloudState.UnKnown;
public static DateTime BusinessSwappingStateUpdateTime = DateTime.Now;
public static ExceptionReason ExceptionReason = ExceptionReason.None;
public RfidReadModel? RfidReadModel=null;
+ public TboxCarInfoModel? TBoxCarInfoModel = null;
public SwapOrder? SwapOrder=null;
+ public SwapOrderBatteryInfo SwapOrderBatteryInfo = null;
+
#region 小步状态
@@ -46,7 +51,13 @@ public class SwappingStateMachine : IDisposable
public static bool CloudVelCheckFlag = false;
//Tbox连接
- public static bool TBoxConnectionFlag = false;
+ public static bool TBoxConnectFlag = false;
+
+ //Tbox本地校验
+ public static bool TBoxLocalCheckFlag = false;
+
+ //Tbox数据上传
+ public static bool CloudTBoxFlag = false;
//选包
public static bool SelectPackFlag = false;
@@ -102,7 +113,7 @@ public class SwappingStateMachine : IDisposable
Dictionary[SwappingState.Begin] = new BeginState();
Dictionary[SwappingState.StationReady] = new StationReadyState();
Dictionary[SwappingState.CarPrepare] = new CarPrepareState();
- Dictionary[SwappingState.SelectPack] = new SelectPackState();
+ Dictionary[SwappingState.SelectPack] = new CloudSendOutSwapState();
Dictionary[SwappingState.CarCtrl] = new CarCtrlState();
Dictionary[SwappingState.DoSwapping] = new DoSwappingState();
Dictionary[SwappingState.SwapDone] = new SwapDoneState();
diff --git a/Service/Init/StaticStationInfo.cs b/Service/Init/StaticStationInfo.cs
index bb18b56..d06fec7 100644
--- a/Service/Init/StaticStationInfo.cs
+++ b/Service/Init/StaticStationInfo.cs
@@ -11,23 +11,49 @@ namespace Service.Init;
///
public class StaticStationInfo
{
- public static StationConstant.StationStatus StationStatus;
- public static StationConstant.StationWay StationWay;
-
- public static StationConstant.StationModel StationModel;
+ public static string StationStatus
+ {
+ get => Resolve(StationParamConst.StationStatus);
+ set => Set(StationParamConst.StationStatus, value);
+ }
+ public static string StationWay
+ {
+ get => Resolve(StationParamConst.StationWay);
+ set => Set(StationParamConst.StationWay, value);
+ }
+ public static string StationModel
+ {
+ get => Resolve(StationParamConst.StationModel);
+ set => Set(StationParamConst.StationModel, value);
+ }
+
public static string StationName
{
get => Resolve(StationParamConst.StationName);
set => Set(StationParamConst.StationName, value);
}
+
+
public static string StationNo
{
get => Resolve(StationParamConst.StationNo);
set => Set(StationParamConst.StationNo, value);
}
+
+ public static string SwapFinishChargeTime
+ {
+ get => Resolve(StationParamConst.SwapFinishChargeTime);
+ set => Set(StationParamConst.SwapFinishChargeTime, value);
+ }
+
+ public static string SwapSoc
+ {
+ get => Resolve(StationParamConst.SwapSoc);
+ set => Set(StationParamConst.SwapSoc, value);
+ }
#region cloud
diff --git a/Service/Station/StationParamConst.cs b/Service/Station/StationParamConst.cs
index 822e1a3..6e0b84c 100644
--- a/Service/Station/StationParamConst.cs
+++ b/Service/Station/StationParamConst.cs
@@ -5,6 +5,15 @@ public class StationParamConst
public static readonly string StationNo = "Station.StationNo";
public static readonly string StationName = "Station.StationName";
+ //选包策略中最后结束充电时间需要>此值
+ public static readonly string SwapFinishChargeTime = "Station.SwapFinishChargeTime";
+ //选包策略换电Soc
+ public static readonly string SwapSoc = "Station.SwapSoc";
+
+
+ public static readonly string StationStatus = "Station.StationStatus";
+ public static readonly string StationWay = "Station.StationWay";
+ public static readonly string StationModel = "Station.StationModel";
#region cloud param
public static readonly string CloudServerIp = "Cloud.CloudServerIp";
diff --git a/WebStarter/Controllers/Test/GenController.cs b/WebStarter/Controllers/Test/GenController.cs
index cee0a5d..628777a 100644
--- a/WebStarter/Controllers/Test/GenController.cs
+++ b/WebStarter/Controllers/Test/GenController.cs
@@ -1,3 +1,4 @@
+using Entity.DbModel.Station;
using Microsoft.AspNetCore.Mvc;
using Repository.Station;
using SqlSugar;
@@ -30,17 +31,17 @@ public class GenController : ControllerBase
.FormatFileName(it => ToPascalCase(it)) //格式化文件名(文件名和表名不一样情况)
.FormatClassName(it => ToPascalCase(it)) //格式化类名 (类名和表名不一样的情况)
.FormatPropertyName(it => ToPascalCase(it)) //格式化属性名 (属性名和字段名不一样情况)
- .CreateClassFile("D:\\lxw\\work\\pro\\c#\\hn_back_main\\Entity\\DbModel\\Station",
+ .CreateClassFile("D:\\lxw\\work\\pro\\c#\\hn_back_main\\Entity\\DbModel\\Station\\Temp",
"Entity.DbModel.Station");
Console.WriteLine("生成完毕");
}
- /*[HttpGet("test115")]
+ [HttpGet("test115")]
public void Test115()
{
- _batteryGroupRepository.Insert(new List()
+ /*_batteryGroupRepository.Insert(new List()
{
new BatteryGroup()
{
@@ -52,17 +53,25 @@ public class GenController : ControllerBase
BatteryNo = "2",
Group = 2,
},
- });
- List batteryGroups = _batteryGroupRepository.Query();
- BatteryGroup batteryGroup = batteryGroups[0];
+ });*/
+ BatteryGroup batteryGroups = _batteryGroupRepository.QueryByClause(i=>i.Group==1);
+ /*BatteryGroup batteryGroup = batteryGroups[0];
_batteryGroupRepository.Delete(batteryGroup);
BatteryGroup batteryGroup1 = batteryGroups[1];
batteryGroup1.Group = 3;
- _batteryGroupRepository.Update(batteryGroup1);
+ _batteryGroupRepository.Update(batteryGroup1);*/
+ if (batteryGroups == null)
+ {
+ Console.WriteLine();
+ }
+ else
+ {
+ Console.WriteLine();
+ }
Console.WriteLine("测试完毕");
- }*/
+ }
static string ToPascalCase(string input)