启动充电

master
smartwyy 5 months ago
parent 7169abb8df
commit 5fc0ef3e16

@ -3,7 +3,7 @@ using Common.Enum;
using Entity.Base;
using SqlSugar;
namespace Entity.DbModel.System.SysBaseObject
namespace Entity.DbModel.System
{
/// <summary>
/// 系统参数配置表

@ -1,4 +1,4 @@
using Entity.DbModel.System.SysBaseObject;
using Entity.DbModel.System;
namespace Entity.Dto.Req
{

@ -83,7 +83,7 @@ public class RedisHelper : IDisposable
/// </summary>
/// <param name="key">键</param>
/// <returns>对应的值如果键不存在则返回null</returns>
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
/// </summary>
/// <param name="key">键</param>
/// <returns>一个表示异步操作的任务任务的结果是对应的值如果键不存在则返回null</returns>
public async Task<string> GetAsync(string key)
public async Task<string?> GetAsync(string key)
{
var db = GetConnect().GetDatabase(_defaultDB);
return await db.StringGetAsync(key);
@ -105,11 +105,12 @@ public class RedisHelper : IDisposable
/// </summary>
/// <param name="key">键</param>
/// <param name="value">值</param>
/// <param name="expiry">值</param>
/// <returns>操作是否成功</returns>
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);
}
/// <summary>

@ -8,6 +8,12 @@ public static class ModbusDecoder
{
private static readonly ILog Log = LogManager.GetLogger(typeof(ModbusDecoder));
public static T Decode<T>(byte[] bytes) where T : class, new()
{
T t = new T();
return Decode<T>(bytes, t);
}
public static T Decode<T>(byte[] bytes, T t) where T : class, new()
{
var fields = t.GetType().GetProperties()

@ -1,3 +1,4 @@
using System.Net;
using System.Reflection;
using Autofac;
using Autofac.Core;
@ -138,7 +139,7 @@ public class TcpClient<TH, TD, TE> : IDisposable where TH : IChannelHandler
{
try
{
Task<IChannel> task = _bootstrap!.ConnectAsync(Host, Port);
Task<IChannel> task = _bootstrap!.ConnectAsync(new IPEndPoint(IPAddress.Parse(Host), Port));
Channel = task.Result;
Connected = Channel.Open;
}

@ -1,4 +1,4 @@
using Entity.DbModel.System.SysBaseObject;
using Entity.DbModel.System;
using HybirdFrameworkCore.Autofac.Attribute;
using SqlSugar;

@ -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<IBaseHandler, Decoder, Encoder>
/// </summary>
public string? BatterSn { get; set; }
/// <summary>
/// 电池仓编号
/// </summary>
public int? BinNo { get; set; }
/// <summary>
/// 远程升级-监控网关上送升级完成确认帧
/// </summary>
public UplinkUpgrade UplinkUpgrade { get; set; }
@ -134,6 +145,17 @@ public class ChargerClient : TcpClient<IBaseHandler, Decoder, Encoder>
public string? CurrentMsg { get; set; }
#endregion
#region db
private ChargeOrderRepository _chargeOrderRepository;
#endregion
public ChargerClient(ChargeOrderRepository chargeOrderRepository)
{
_chargeOrderRepository = chargeOrderRepository;
}
/// <summary>
///
@ -319,6 +341,52 @@ public class ChargerClient : TcpClient<IBaseHandler, Decoder, Encoder>
}
#endregion
#region 启动充电
/// <summary>
///
/// </summary>
public Result<bool> StartCharge()
{
if (!Connected)
{
return Result<bool>.Fail($"充电机{BinNo}未连接");
}
if (string.IsNullOrWhiteSpace(BatterSn))
{
return Result<bool>.Fail($"充电仓{BinNo}电池不存在");
}
RedisHelper redisHelper = AppInfo.Container.Resolve<RedisHelper>();
string? lockKey = redisHelper.GetStrValue($"chargeNo{BinNo}Start");
if (!string.IsNullOrWhiteSpace(lockKey))
{
return Result<bool>.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<bool>.Success(true);
}
#endregion
/// <summary>
///

@ -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();
}

@ -0,0 +1,149 @@
using Autofac;
using HybirdFrameworkCore.Autofac;
using Service.Station;
using Service.System;
namespace Service.Init;
/// <summary>
/// 换电站基本信息静态数据
/// </summary>
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<SysConfigService>();
}
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>();
}
_sysConfigService.Set(key, value);
}
#endregion
}

@ -29,4 +29,8 @@
<ProjectReference Include="..\Repository\Repository.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Mgr\" />
</ItemGroup>
</Project>

@ -1,6 +0,0 @@
namespace Service.Station.Common;
public class StationConstant
{
public static string StationCode = "";
}

@ -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
}

@ -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<SysConfig>
{
private static readonly ConcurrentDictionary<string, string> Dictionary =
new ConcurrentDictionary<string, string>();
private readonly SysConfigRepository _sysConfigRep;
public SysConfigService(SysConfigRepository sysConfigRep)
{
_sysConfigRep = sysConfigRep;
}
RedisHelper redisHelper = AppInfo.Container.Resolve<RedisHelper>();
/// <summary>
/// 获取参数配置分页列表 🔖
/// </summary>
@ -77,7 +82,6 @@ namespace Service.System
if (insertSesult > 0)
result = "增加参数配置成功";
return result;
}
/// <summary>
@ -85,21 +89,23 @@ namespace Service.System
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
// [ApiDescriptionSettings(Name = "Update"), HttpPost]
// [ApiDescriptionSettings(Name = "Update"), HttpPost]
[DisplayName("更新参数配置")]
public async Task<string> 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<SysConfig>();
int updateResult = await _sysConfigRep.UpdateAsync(config,true);
int updateResult = await _sysConfigRep.UpdateAsync(config, true);
if (updateResult > 0)
result = "更新参数配置成功";
redisHelper.Remove(config.Code);
return result;
}
/// <summary>
/// 删除参数配置 🔖
/// </summary>
@ -125,7 +131,7 @@ namespace Service.System
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
// [ApiDescriptionSettings(Name = "BatchDelete"), HttpPost]
// [ApiDescriptionSettings(Name = "BatchDelete"), HttpPost]
[DisplayName("批量删除参数配置")]
public async Task BatchDeleteConfig(List<long> 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
}
/// <summary>
///
/// </summary>
/// <param name="key">GroupCode.code</param>
/// <returns></returns>
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;
}
/// <summary>
///
/// </summary>
/// <param name="key">GroupCode.code</param>
/// <param name="value"></param>
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);
}
}
}
}
}

@ -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;

@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

@ -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}

Loading…
Cancel
Save