From 5fc0ef3e163ec7af728f30056c0e6c0d3028b319 Mon Sep 17 00:00:00 2001 From: smartwyy <645583145@qq.com> Date: Thu, 23 May 2024 14:42:03 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=AF=E5=8A=A8=E5=85=85=E7=94=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Entity/DbModel/System/SysConfig.cs | 2 +- Entity/Dto/Req/ConfigReq.cs | 2 +- HybirdFrameworkCore/Redis/RedisHelper.cs | 9 +- .../ModbusTcpMaster/ModbusDecoder.cs | 6 + HybirdFrameworkDriver/TcpClient/TcpClient.cs | 3 +- Repository/System/SysConfigRepository.cs | 2 +- Service/Charger/Client/ChargerClient.cs | 70 +++++++- Service/Charger/Common/ChargerUtils.cs | 4 +- Service/Init/StaticStationInfo.cs | 149 ++++++++++++++++++ Service/Service.csproj | 4 + Service/Station/Common/StationConstant.cs | 6 - Service/Station/StationParamConst.cs | 33 ++++ Service/System/SysConfigService.cs | 87 ++++++++-- .../Controllers/System/SysConfigController.cs | 2 +- WinFormStarter/Form2.resx | 60 +++++++ hnBackCharger.sln | 7 + 16 files changed, 419 insertions(+), 27 deletions(-) create mode 100644 Service/Init/StaticStationInfo.cs delete mode 100644 Service/Station/Common/StationConstant.cs create mode 100644 Service/Station/StationParamConst.cs create mode 100644 WinFormStarter/Form2.resx diff --git a/Entity/DbModel/System/SysConfig.cs b/Entity/DbModel/System/SysConfig.cs index c5f8d6f..c7596c9 100644 --- a/Entity/DbModel/System/SysConfig.cs +++ b/Entity/DbModel/System/SysConfig.cs @@ -3,7 +3,7 @@ using Common.Enum; using Entity.Base; using SqlSugar; -namespace Entity.DbModel.System.SysBaseObject +namespace Entity.DbModel.System { /// /// 系统参数配置表 diff --git a/Entity/Dto/Req/ConfigReq.cs b/Entity/Dto/Req/ConfigReq.cs index 62e1bbb..d870864 100644 --- a/Entity/Dto/Req/ConfigReq.cs +++ b/Entity/Dto/Req/ConfigReq.cs @@ -1,4 +1,4 @@ -using Entity.DbModel.System.SysBaseObject; +using Entity.DbModel.System; namespace Entity.Dto.Req { diff --git a/HybirdFrameworkCore/Redis/RedisHelper.cs b/HybirdFrameworkCore/Redis/RedisHelper.cs index d9dfbfe..0f93318 100644 --- a/HybirdFrameworkCore/Redis/RedisHelper.cs +++ b/HybirdFrameworkCore/Redis/RedisHelper.cs @@ -83,7 +83,7 @@ public class RedisHelper : IDisposable /// /// 键 /// 对应的值,如果键不存在则返回null - public string GetStrValue(string key) + public string? GetStrValue(string key) { var db = GetConnect().GetDatabase(_defaultDB); return db.StringGet(key); @@ -94,7 +94,7 @@ public class RedisHelper : IDisposable /// /// 键 /// 一个表示异步操作的任务,任务的结果是对应的值,如果键不存在则返回null - public async Task GetAsync(string key) + public async Task GetAsync(string key) { var db = GetConnect().GetDatabase(_defaultDB); return await db.StringGetAsync(key); @@ -105,11 +105,12 @@ public class RedisHelper : IDisposable /// /// 键 /// 值 + /// 值 /// 操作是否成功 - public bool SetKeyValueStr(string key, string value) + public bool SetKeyValueStr(string key, string value, TimeSpan? expiry = default(TimeSpan?)) { var db = GetConnect().GetDatabase(_defaultDB); - return db.StringSet(key, value); + return db.StringSet(key, value, expiry); } /// diff --git a/HybirdFrameworkDriver/ModbusTcpMaster/ModbusDecoder.cs b/HybirdFrameworkDriver/ModbusTcpMaster/ModbusDecoder.cs index 2e4e8dd..fee6009 100644 --- a/HybirdFrameworkDriver/ModbusTcpMaster/ModbusDecoder.cs +++ b/HybirdFrameworkDriver/ModbusTcpMaster/ModbusDecoder.cs @@ -8,6 +8,12 @@ public static class ModbusDecoder { private static readonly ILog Log = LogManager.GetLogger(typeof(ModbusDecoder)); + public static T Decode(byte[] bytes) where T : class, new() + { + T t = new T(); + return Decode(bytes, t); + } + public static T Decode(byte[] bytes, T t) where T : class, new() { var fields = t.GetType().GetProperties() diff --git a/HybirdFrameworkDriver/TcpClient/TcpClient.cs b/HybirdFrameworkDriver/TcpClient/TcpClient.cs index ae3bc11..199889c 100644 --- a/HybirdFrameworkDriver/TcpClient/TcpClient.cs +++ b/HybirdFrameworkDriver/TcpClient/TcpClient.cs @@ -1,3 +1,4 @@ +using System.Net; using System.Reflection; using Autofac; using Autofac.Core; @@ -138,7 +139,7 @@ public class TcpClient : IDisposable where TH : IChannelHandler { try { - Task task = _bootstrap!.ConnectAsync(Host, Port); + Task task = _bootstrap!.ConnectAsync(new IPEndPoint(IPAddress.Parse(Host), Port)); Channel = task.Result; Connected = Channel.Open; } diff --git a/Repository/System/SysConfigRepository.cs b/Repository/System/SysConfigRepository.cs index 065d821..603a424 100644 --- a/Repository/System/SysConfigRepository.cs +++ b/Repository/System/SysConfigRepository.cs @@ -1,4 +1,4 @@ -using Entity.DbModel.System.SysBaseObject; +using Entity.DbModel.System; using HybirdFrameworkCore.Autofac.Attribute; using SqlSugar; diff --git a/Service/Charger/Client/ChargerClient.cs b/Service/Charger/Client/ChargerClient.cs index c4207ef..59ff050 100644 --- a/Service/Charger/Client/ChargerClient.cs +++ b/Service/Charger/Client/ChargerClient.cs @@ -1,8 +1,14 @@ -using HybirdFrameworkCore.Autofac.Attribute; +using Autofac; +using Entity.DbModel.Station; +using HybirdFrameworkCore.Autofac; +using HybirdFrameworkCore.Autofac.Attribute; +using HybirdFrameworkCore.Entity; +using HybirdFrameworkCore.Redis; using HybirdFrameworkCore.Utils; using HybirdFrameworkDriver.Session; using HybirdFrameworkDriver.TcpClient; using Newtonsoft.Json; +using Repository.Station; using Service.Charger.Codec; using Service.Charger.Common; using Service.Charger.Handler; @@ -11,6 +17,7 @@ using Service.Charger.Msg.Charger.Req; using Service.Charger.Msg.Charger.Resp; using Service.Charger.Msg.Host.Req; using Service.Charger.Msg.Host.Req.Bms; +using Service.Init; namespace Service.Charger.Client; @@ -117,6 +124,10 @@ public class ChargerClient : TcpClient /// public string? BatterSn { get; set; } /// + /// 电池仓编号 + /// + public int? BinNo { get; set; } + /// /// 远程升级-监控网关上送升级完成确认帧 /// public UplinkUpgrade UplinkUpgrade { get; set; } @@ -134,6 +145,17 @@ public class ChargerClient : TcpClient public string? CurrentMsg { get; set; } #endregion + + #region db + + private ChargeOrderRepository _chargeOrderRepository; + + #endregion + + public ChargerClient(ChargeOrderRepository chargeOrderRepository) + { + _chargeOrderRepository = chargeOrderRepository; + } /// /// @@ -319,6 +341,52 @@ public class ChargerClient : TcpClient } #endregion + + + #region 启动充电 + + /// + /// + /// + public Result StartCharge() + { + if (!Connected) + { + return Result.Fail($"充电机{BinNo}未连接"); + } + + if (string.IsNullOrWhiteSpace(BatterSn)) + { + return Result.Fail($"充电仓{BinNo}电池不存在"); + } + + RedisHelper redisHelper = AppInfo.Container.Resolve(); + + string? lockKey = redisHelper.GetStrValue($"chargeNo{BinNo}Start"); + if (!string.IsNullOrWhiteSpace(lockKey)) + { + return Result.Fail($"充电仓{BinNo}正在启动中"); + } + + redisHelper.SetKeyValueStr($"chargeNo{BinNo}Start", DateTime.Now.ToString("f"), TimeSpan.FromMinutes(1)); + + byte chargeSoc = StaticStationInfo.ChargeSoc; + string chargeOrderNo = SendRemoteStartCharging(chargeSoc); + + _chargeOrderRepository.Insert(new ChargeOrder() + { + Sn = chargeOrderNo, + BatteryNo = BatterSn, + CmdStatus = 0, + ChargerNo = (BinNo??-1).ToString(), + ChargeMode = 1, + StartMode = 1 + }); + + return Result.Success(true); + } + + #endregion /// /// diff --git a/Service/Charger/Common/ChargerUtils.cs b/Service/Charger/Common/ChargerUtils.cs index 69eb6bf..d18e2e3 100644 --- a/Service/Charger/Common/ChargerUtils.cs +++ b/Service/Charger/Common/ChargerUtils.cs @@ -1,5 +1,5 @@ using System.Text; -using Service.Station.Common; +using Service.Station; namespace Service.Charger.Common; @@ -55,7 +55,7 @@ public static class ChargerUtils public static string GenChargeOrderSn() { - return StationConstant.StationCode + DateTime.Now.ToString(ChargerConst.DateFormat) + + return StationParamConst.StationNo + DateTime.Now.ToString(ChargerConst.DateFormat) + GetRandomNumLimit99(); } diff --git a/Service/Init/StaticStationInfo.cs b/Service/Init/StaticStationInfo.cs new file mode 100644 index 0000000..7b5187a --- /dev/null +++ b/Service/Init/StaticStationInfo.cs @@ -0,0 +1,149 @@ +using Autofac; +using HybirdFrameworkCore.Autofac; +using Service.Station; +using Service.System; + +namespace Service.Init; + +/// +/// 换电站基本信息静态数据 +/// +public class StaticStationInfo +{ + 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); + } + + public static byte ChargeSoc + { + get => byte.Parse(Resolve(StationParamConst.ChargeSoc)); + set => Set(StationParamConst.ChargeSoc, value); + } + + + #region cloud + + public static string CloudServerIp + { + get => Resolve(StationParamConst.CloudServerIp); + set => Set(StationParamConst.CloudServerIp, value); + } + + public static int CloudServerPort + { + get + { + string port = Resolve(StationParamConst.CloudServerPort); + if (string.IsNullOrWhiteSpace(port)) + { + return 33000; + } + + return int.Parse(port); + } + set => Set(StationParamConst.CloudServerPort, value); + } + + public static string CloudClientId + { + get => Resolve(StationParamConst.CloudClientId); + set => Set(StationParamConst.CloudClientId, value); + } + + public static string CloudUsername + { + get => Resolve(StationParamConst.CloudUsername); + set => Set(StationParamConst.CloudUsername, value); + } + + public static string CloudPassword + { + get => Resolve(StationParamConst.CloudPassword); + set => Set(StationParamConst.CloudPassword, value); + } + + public static string CloudSubTopic + { + get => Resolve(StationParamConst.CloudSubTopic); + set => Set(StationParamConst.CloudSubTopic, value); + } + + public static string CloudPubTopic + { + get => Resolve(StationParamConst.CloudPubTopic); + set => Set(StationParamConst.CloudPubTopic, value); + } + + #endregion + + #region db method + + private static SysConfigService _sysConfigService; + + private static string Resolve(string key) + { + if (_sysConfigService == null) + { + _sysConfigService = AppInfo.Container.Resolve(); + } + + string? s = _sysConfigService.Get(key); + if (s != null) + { + return s; + } + + return ""; + } + + private static void Set(string key, object value) + { + if (_sysConfigService == null) + { + _sysConfigService = AppInfo.Container.Resolve(); + } + + _sysConfigService.Set(key, value); + } + + #endregion +} \ No newline at end of file diff --git a/Service/Service.csproj b/Service/Service.csproj index cb2f6cb..4ef4ff9 100644 --- a/Service/Service.csproj +++ b/Service/Service.csproj @@ -29,4 +29,8 @@ + + + + diff --git a/Service/Station/Common/StationConstant.cs b/Service/Station/Common/StationConstant.cs deleted file mode 100644 index da04a2b..0000000 --- a/Service/Station/Common/StationConstant.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Service.Station.Common; - -public class StationConstant -{ - public static string StationCode = ""; -} \ No newline at end of file diff --git a/Service/Station/StationParamConst.cs b/Service/Station/StationParamConst.cs new file mode 100644 index 0000000..825a7cf --- /dev/null +++ b/Service/Station/StationParamConst.cs @@ -0,0 +1,33 @@ +namespace Service.Station; + +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"; + + //充电soc + public static readonly string ChargeSoc = "Station.ChargeSoc"; + + + 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"; + public static readonly string CloudServerPort = "Cloud.CloudServerPort"; + public static readonly string CloudClientId = "Cloud.CloudClientId"; + public static readonly string CloudUsername = "Cloud.CloudUsername"; + public static readonly string CloudPassword = "Cloud.CloudPassword"; + public static readonly string CloudSubTopic = "Cloud.CloudSubTopic"; + public static readonly string CloudPubTopic = "Cloud.CloudPubTopic"; + + #endregion +} \ No newline at end of file diff --git a/Service/System/SysConfigService.cs b/Service/System/SysConfigService.cs index 0d4faac..82c73b6 100644 --- a/Service/System/SysConfigService.cs +++ b/Service/System/SysConfigService.cs @@ -1,8 +1,9 @@ -using System.ComponentModel; +using System.Collections.Concurrent; +using System.ComponentModel; using Autofac; using Common.Enum; using Entity.Base; -using Entity.DbModel.System.SysBaseObject; +using Entity.DbModel.System; using Entity.Dto.Req; using HybirdFrameworkCore.Autofac; using HybirdFrameworkCore.Autofac.Attribute; @@ -12,19 +13,23 @@ using Microsoft.AspNetCore.Mvc; using Repository.System; using SqlSugar; - namespace Service.System { [Scope("SingleInstance")] public class SysConfigService : BaseServices { + private static readonly ConcurrentDictionary Dictionary = + new ConcurrentDictionary(); + private readonly SysConfigRepository _sysConfigRep; public SysConfigService(SysConfigRepository sysConfigRep) { _sysConfigRep = sysConfigRep; } + RedisHelper redisHelper = AppInfo.Container.Resolve(); + /// /// 获取参数配置分页列表 🔖 /// @@ -77,7 +82,6 @@ namespace Service.System if (insertSesult > 0) result = "增加参数配置成功"; return result; - } /// @@ -85,21 +89,23 @@ namespace Service.System /// /// /// - // [ApiDescriptionSettings(Name = "Update"), HttpPost] + // [ApiDescriptionSettings(Name = "Update"), HttpPost] [DisplayName("更新参数配置")] public async Task UpdateConfig(UpdateConfigReq input) { string result = ""; - var isExist = await _sysConfigRep.QueryByClauseAsync(u => (u.Name == input.Name || u.Code == input.Code) && u.Id != input.Id); + var isExist = await _sysConfigRep.QueryByClauseAsync(u => + (u.Name == input.Name || u.Code == input.Code) && u.Id != input.Id); if (isExist != null) result = "已存在同名或同编码参数配置"; var config = input.Adapt(); - int updateResult = await _sysConfigRep.UpdateAsync(config,true); + int updateResult = await _sysConfigRep.UpdateAsync(config, true); if (updateResult > 0) result = "更新参数配置成功"; redisHelper.Remove(config.Code); return result; } + /// /// 删除参数配置 🔖 /// @@ -125,7 +131,7 @@ namespace Service.System /// /// /// - // [ApiDescriptionSettings(Name = "BatchDelete"), HttpPost] + // [ApiDescriptionSettings(Name = "BatchDelete"), HttpPost] [DisplayName("批量删除参数配置")] public async Task BatchDeleteConfig(List ids) { @@ -134,6 +140,7 @@ namespace Service.System var config = await _sysConfigRep.QueryByClauseAsync(u => u.Id == id); if (config.SysFlag == YesNoEnum.Y) // 禁止删除系统参数 continue; + await _sysConfigRep.DeleteAsync(config); redisHelper.Remove(config.Code); } @@ -151,5 +158,67 @@ namespace Service.System } + /// + /// + /// + /// GroupCode.code + /// + public string? Get(string key) + { + string[] keys = key.Split('.'); + if (keys.Length != 2) + { + throw new ArgumentException("配置数据key格式错误"); + } + + if (Dictionary.TryGetValue(key, out string? value)) + { + return value; + } + + SysConfig sysConfig = _sysConfigRep.QueryByClause(i => i.GroupCode == keys[0] && i.Code == keys[1]); + if (sysConfig == null) + { + return null; + } + + return sysConfig.Value; + } + + /// + /// + /// + /// GroupCode.code + /// + public void Set(string key, object value) + { + string[] keys = key.Split('.'); + if (keys.Length != 2) + { + throw new ArgumentException("配置数据key格式错误"); + } + + string newValue = Convert.ToString(value); + + Dictionary.AddOrUpdate(key, newValue, (s, s1) => newValue); + + SysConfig sysConfig = _sysConfigRep.QueryByClause(i => i.GroupCode == keys[0] && i.Code == keys[1]); + if (sysConfig == null) + { + _sysConfigRep.Insert(new SysConfig() + { + GroupCode = keys[0], + Code = keys[1], + Value = newValue, + SysFlag = YesNoEnum.N, + Name = key + }); + } + else + { + sysConfig.Value = newValue; + _sysConfigRep.Update(sysConfig); + } + } } -} +} \ No newline at end of file diff --git a/WebStarter/Controllers/System/SysConfigController.cs b/WebStarter/Controllers/System/SysConfigController.cs index f59279c..81d9432 100644 --- a/WebStarter/Controllers/System/SysConfigController.cs +++ b/WebStarter/Controllers/System/SysConfigController.cs @@ -1,6 +1,6 @@  using Entity.Base; -using Entity.DbModel.System.SysBaseObject; +using Entity.DbModel.System; using Entity.Dto.Req; using Microsoft.AspNetCore.Mvc; using Service.System; diff --git a/WinFormStarter/Form2.resx b/WinFormStarter/Form2.resx new file mode 100644 index 0000000..f298a7b --- /dev/null +++ b/WinFormStarter/Form2.resx @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/hnBackCharger.sln b/hnBackCharger.sln index a044641..d9365b3 100644 --- a/hnBackCharger.sln +++ b/hnBackCharger.sln @@ -27,6 +27,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Framework", "Framework", "{ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Business", "Business", "{C9515084-B676-4C33-9FE7-E0B860493A4F}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common", "Common\Common.csproj", "{F96FA24C-1615-452C-94FE-A1A3389E1F42}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -69,6 +71,10 @@ Global {17044C11-3794-4938-BA80-C061BD871AE0}.Debug|Any CPU.Build.0 = Debug|Any CPU {17044C11-3794-4938-BA80-C061BD871AE0}.Release|Any CPU.ActiveCfg = Release|Any CPU {17044C11-3794-4938-BA80-C061BD871AE0}.Release|Any CPU.Build.0 = Release|Any CPU + {F96FA24C-1615-452C-94FE-A1A3389E1F42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F96FA24C-1615-452C-94FE-A1A3389E1F42}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F96FA24C-1615-452C-94FE-A1A3389E1F42}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F96FA24C-1615-452C-94FE-A1A3389E1F42}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -83,6 +89,7 @@ Global {C2380814-15D4-491D-ADF2-ADC68617C3FA} = {C9515084-B676-4C33-9FE7-E0B860493A4F} {01D2CC15-F1FD-4E22-845A-2D2473662860} = {C9515084-B676-4C33-9FE7-E0B860493A4F} {A6C2AA7F-B2A2-4AE0-AE84-49BE36B990EC} = {C9515084-B676-4C33-9FE7-E0B860493A4F} + {F96FA24C-1615-452C-94FE-A1A3389E1F42} = {C9515084-B676-4C33-9FE7-E0B860493A4F} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3E10BF3D-9914-44B1-A6AA-FCF013C3F155}