diff --git a/Service/WaterCool/Codec/Decoder.cs b/Service/WaterCool/Codec/Decoder.cs new file mode 100644 index 0000000..c7514f3 --- /dev/null +++ b/Service/WaterCool/Codec/Decoder.cs @@ -0,0 +1,40 @@ +using DotNetty.Buffers; +using DotNetty.Codecs; +using DotNetty.Transport.Channels; +using HybirdFrameworkCore.Utils; +using log4net; +using Newtonsoft.Json; +using Service.WaterCool.Msg; +using Service.WaterCool.Msg.WaterCool; + +namespace Service.WaterCool.Codec; + +public class Decoder : ByteToMessageDecoder +{ + private static readonly ILog Log = LogManager.GetLogger(typeof(Decoder)); + + private readonly int _fixedLength = 13; + + protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List output) + { + if (_fixedLength <= input.ReadableBytes) + { + byte[] bytes = new byte[_fixedLength - 1]; + input.SkipBytes(1); + input.ReadBytes(bytes); + + Log.Info($"receive {BitUtls.BytesToHexStr(bytes)}"); + + int id = BitConverter.ToInt32(new byte[] { bytes[3], bytes[2], bytes[1], bytes[0] }, 0); + + BaseMsg baseMsg = id switch + { + 0x18FFC13A => ModelConvert.Decode(bytes), + _ => ModelConvert.Decode(bytes), + }; + + Log.Info($"receive={BitUtls.BytesToHexStr(bytes)}, msg={JsonConvert.SerializeObject(baseMsg)}"); + output.Add(baseMsg); + } + } +} \ No newline at end of file diff --git a/Service/WaterCool/Codec/Encoder.cs b/Service/WaterCool/Codec/Encoder.cs new file mode 100644 index 0000000..b52c211 --- /dev/null +++ b/Service/WaterCool/Codec/Encoder.cs @@ -0,0 +1,25 @@ +using DotNetty.Buffers; +using DotNetty.Codecs; +using DotNetty.Transport.Channels; +using HybirdFrameworkCore.Utils; +using log4net; +using Service.WaterCool.Msg; + +namespace Service.WaterCool.Codec; +/// +/// +/// +public class Encoder : MessageToByteEncoder +{ + private static readonly ILog Log = LogManager.GetLogger(typeof(Encoder)); + + + protected override void Encode(IChannelHandlerContext context, BaseMsg obj, IByteBuffer output) + { + byte[] bytes = obj.ToBytes(); + byte[] result = + { 0x88, bytes[3], bytes[2], bytes[1], bytes[0], bytes[4], bytes[5], bytes[6], bytes[7], bytes[8], bytes[9], bytes[10], bytes[11] }; + + Log.Info($"send={BitUtls.BytesToHexStr(result)}"); + output.WriteBytes(result); } +} \ No newline at end of file diff --git a/Service/WaterCool/Handler/WaterCoolStatusHandler.cs b/Service/WaterCool/Handler/WaterCoolStatusHandler.cs new file mode 100644 index 0000000..0ca60a9 --- /dev/null +++ b/Service/WaterCool/Handler/WaterCoolStatusHandler.cs @@ -0,0 +1,23 @@ +using DotNetty.Transport.Channels; +using HybirdFrameworkCore.Autofac.Attribute; +using log4net; +using Service.Charger.Handler; +using Service.WaterCool.Msg.WaterCool; +using Service.WaterCool.Server; + +namespace Service.WaterCool.Handler; + +[Order(8)] +[Scope("InstancePerDependency")] +public class WaterCoolStatusHandler : SimpleChannelInboundHandler, IBaseHandler +{ + private static readonly ILog Log = LogManager.GetLogger(typeof(WaterCoolStatusHandler)); + + + protected override void ChannelRead0(IChannelHandlerContext ctx, WaterCoolStatus msg) + { + Log.Info($"receive OtherMsg={msg}"); + var server = WaterCoolServerMgr.Server; + if (server != null) server.WaterCoolStatus = msg; + } +} \ No newline at end of file diff --git a/Service/WaterCool/Msg/BaseMsg.cs b/Service/WaterCool/Msg/BaseMsg.cs new file mode 100644 index 0000000..ac7bba5 --- /dev/null +++ b/Service/WaterCool/Msg/BaseMsg.cs @@ -0,0 +1,15 @@ +using HybirdFrameworkCore.Autofac.Attribute; +using HybirdFrameworkCore.Utils; +using HybirdFrameworkDriver.Common; + +namespace Service.WaterCool.Msg; + +public class BaseMsg: IToBytes +{ + [Property(0, 32)] public UInt32 Id { get; set; } + + public byte[] ToBytes() + { + return ModelConvert.Encode(this); + } +} \ No newline at end of file diff --git a/Service/WaterCool/Msg/Host/ModeMsg.cs b/Service/WaterCool/Msg/Host/ModeMsg.cs new file mode 100644 index 0000000..3cfb1ff --- /dev/null +++ b/Service/WaterCool/Msg/Host/ModeMsg.cs @@ -0,0 +1,97 @@ +using HybirdFrameworkCore.Autofac.Attribute; + +namespace Service.WaterCool.Msg.Host; + +/// +/// 站控向水冷发送模式设定指令 +/// 消息id 18FF45A7 +/// +public class ModeMsg : BaseMsg +{ + /// + /// BMS 请求设定模式 + /// 0关机模式,1制冷模式,2制热模式,3自循环模式 + /// + [Property(32, 2)] + public byte Mode { get; set; } + + /// + /// 高压请求 + /// 0 上高压请求,1 下高压请求,2~3 无效 + /// + [Property(34, 2)] + public byte HighTension { get; set; } + + /// + /// 充电状态 + /// 0 非充电模式,1 充电模式,2~3 无效 + /// + [Property(36, 2)] + public byte ChargState { get; set; } + + /// + /// BMS 高压继电器状态 + /// 0 断开状态,1 闭合状态,2~3 无效 + /// + [Property(38, 2)] + public byte BMSState { get; set; } + + /// + /// BMS 当前电压高字节 + /// 分辨率:1V /bit 偏移量:0 范围:0V~1000V 类型:测量 65535:无效 + /// + [Property(40, 8)] + public byte BMSHighByte { get; set; } + + /// + /// BMS 当前电压低字节 + /// 分辨率:1V /bit 偏移量:0 范围:0V~1000V 类型:测量 65535:无效 + /// + [Property(48, 8)] + public byte BMSLowByte { get; set; } + + /// + /// 保留 + /// + [Property(56, 8)] + public byte ReserveOne { get; set; } + + /// + /// 设定温度 + /// 分辨率:1℃\bit 偏移量:-40℃ 单位:℃ + /// + [Property(64, 8, PropertyReadConstant.Bit, 1, 0, 40)] + public sbyte SetTemperature { get; set; } + + /// + /// 保留 + /// + [Property(72, 8)] + public byte ReserveTwo { get; set; } + + /// + /// 生命帧 + /// + [Property(80, 8)] + public byte HP { get; set; } + + /// + /// CRC 效验值 + /// + [Property(88, 8)] + public byte CrcCheckValue { get; set; } + + + public ModeMsg(byte mode,byte highTension,byte chargState,byte bmsState,sbyte setTemperature,byte hp,byte crcCheckValue) + { + Id = 0x18FF45A7; + Mode = mode; + HighTension = highTension; + ChargState= chargState; + BMSState= bmsState; + SetTemperature = setTemperature; + HP = hp; + CrcCheckValue = crcCheckValue; + } + +} \ No newline at end of file diff --git a/Service/WaterCool/Msg/WaterCool/WaterCoolStatus.cs b/Service/WaterCool/Msg/WaterCool/WaterCoolStatus.cs new file mode 100644 index 0000000..9ae036c --- /dev/null +++ b/Service/WaterCool/Msg/WaterCool/WaterCoolStatus.cs @@ -0,0 +1,78 @@ +using HybirdFrameworkCore.Autofac.Attribute; + +namespace Service.WaterCool.Msg.WaterCool; + +/// +/// 水冷机数据主动上报 +/// +public class WaterCoolStatus : BaseMsg +{ + /// + /// TMS 工作状态 + /// 0关机模式,1制冷模式,2制热模式,3自循环模式 + /// + [Property(32, 2)] + public byte TmsStatus { get; set; } + + /// + /// TMS 高压继电器状态 + /// 0 断开状态,1 闭合状态,2~3 无效 + /// + [Property(34, 2)] + public byte TmsHighStatus { get; set; } + + /// + /// 出水温度(机组到电池) + /// 分辨率:1 ℃/bit 偏移量:-40℃范围:-40℃~210℃ 类型:测量255:无效 + /// + [Property(40, 8, PropertyReadConstant.Bit, 1, 0, 40)] + + public sbyte GetOutTemperature { get; set; } + + /// + /// 回水温度(电池到机组) + /// 分辨率:1 ℃/bit 偏移量:-40℃范围:-40℃~210℃ 类型:测量255:无效 + /// + [Property(48, 8, PropertyReadConstant.Bit, 1, 0, 40)] + + public sbyte ComeBackTemperature { get; set; } + + /// + /// 供应商编号 + /// + [Property(56, 8)] + public byte SupplierNumber { get; set; } + + /// + /// 软件版本 + /// + [Property(64, 8)] + public byte SoftwareVersion { get; set; } + + /// + /// TMS 需求功率高字节 + /// 分辨率:0.1 Kw/bit 偏移量:0范围:0Kw~100.0Kw 类型:测量65535:无效(按照实时发送) + /// + [Property(72, 8)] + public byte TmsHighPower { get; set; } + + /// + /// TMS 需求功率低字节 + /// 分辨率:0.1 Kw/bit 偏移量:0范围:0Kw~100.0Kw 类型:测量65535:无效(按照实时发送) + /// + [Property(80, 8)] + public byte TmsLowPower { get; set; } + + /// + /// TMS 故障码 + /// 0:无故障; 出现 1 种以上循环发送 + /// + [Property(88, 6)] + public byte TmsTroubleCode { get; set; } + + /// + /// crc校验帧 + /// + [Property(94, 2)] + public byte CrcCheckValue { get; set; } +} \ No newline at end of file diff --git a/Service/WaterCool/Server/WaterCoolServer.cs b/Service/WaterCool/Server/WaterCoolServer.cs new file mode 100644 index 0000000..b827605 --- /dev/null +++ b/Service/WaterCool/Server/WaterCoolServer.cs @@ -0,0 +1,18 @@ +using HybirdFrameworkCore.Autofac.Attribute; +using HybirdFrameworkDriver.TcpServer; +using log4net; +using Service.Charger.Handler; +using Service.WaterCool.Codec; +using Service.WaterCool.Msg.WaterCool; + +namespace Service.WaterCool.Server; + +[Scope] +public class WaterCoolServer: TcpServer +{ + private static readonly ILog Log = LogManager.GetLogger(typeof(WaterCoolServer)); + + public WaterCoolStatus? WaterCoolStatus { get; set; } + + +} \ No newline at end of file diff --git a/Service/WaterCool/Server/WaterCoolServerMgr.cs b/Service/WaterCool/Server/WaterCoolServerMgr.cs new file mode 100644 index 0000000..3df340c --- /dev/null +++ b/Service/WaterCool/Server/WaterCoolServerMgr.cs @@ -0,0 +1,18 @@ +using Autofac; +using HybirdFrameworkCore.Autofac; + +namespace Service.WaterCool.Server; + +public class WaterCoolServerMgr +{ + public static WaterCoolServer? Server { get; private set; } + + public static void InitWaterCoolServer(int port) + { + if (Server == null) + { + Server = AppInfo.Container.Resolve(); + Server.Start(port); + } + } +} \ No newline at end of file