UPS数据接收

zw
CZ 3 months ago
parent 691932d28c
commit c3de3c80cf

@ -0,0 +1,49 @@
using HybirdFrameworkCore.Autofac.Attribute;
using HybirdFrameworkDriver.Session;
using HybirdFrameworkDriver.TcpClient;
using log4net;
using Service.Ups.Codec;
using Service.Ups.Common;
namespace Service.Ups.Client;
[Scope]
public class UpsClient: TcpClient<IBaseHandler, Decoder, Encoder>
{
/// <summary>
/// 设备编号
/// </summary>
public string Sn { get; set; }
private ILog Log()
{
var name = "Fire";
ILog logger = LogManager.GetLogger(name);
Console.WriteLine(name + "-" + logger.GetHashCode());
return logger;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public bool Connect()
{
base.BaseConnect();
Log().Info("ups connect succeed");
return Connected;
}
/// <summary>
///UPS
/// </summary>
/// <param name="sn"></param>
/// <param name="destAddr"></param>
public void SessionAttr(string sn)
{
ChannelUtils.AddAttr(Channel, UpsConst.UpsSn, sn);
ChannelUtils.AddAttr(Channel, UpsConst.EqmTypeNo, sn);
ChannelUtils.AddAttr(Channel, UpsConst.EqmCode, sn);
}
}

@ -0,0 +1,76 @@
using System.Collections.Concurrent;
using Autofac;
using DotNetty.Transport.Channels;
using HybirdFrameworkCore.Autofac;
using HybirdFrameworkDriver.Session;
using log4net;
using Service.Ups.Common;
namespace Service.Ups.Client;
public class UpsMgr
{
private static readonly ILog Log = LogManager.GetLogger(typeof(UpsMgr));
public static readonly ConcurrentDictionary<string, UpsClient> Dictionary = new();
public static void ConnClient()
{
Log.Info($"begin to connect ups");
UpsClient client = AppInfo.Container.Resolve<UpsClient>();
client.AutoReconnect = true;
client.Sn = UpsConst.Sn;
client.LogName = "ups" + UpsConst.EqmCode;
client.ConnectedEventHandler += (sender, b) =>
{
client.SessionAttr(UpsConst.Sn);
};
client.InitBootstrap(UpsConst.Ip, UpsConst.Port);
Task.Run(() =>
{
client.Connect();
client.SessionAttr(UpsConst.Sn);
Log.Info($"succeed to connect loading...");
});
AddBySn(UpsConst.Sn, client);
Log.Info($"begin to connect UpsClient");
}
public static void AddBySn(string sn, UpsClient client)
{
Dictionary[sn] = client;
}
/// <summary>
/// 通过channel获取client
/// </summary>
/// <param name="channel"></param>
/// <param name="sn"></param>
/// <param name="client">获取不到client则为空</param>
/// <returns></returns>
public static bool TryGetClient(IChannel channel, out string sn, out UpsClient? client)
{
string? snt = ChannelUtils.GetAttr(channel, UpsConst.EqmCode);
if (!string.IsNullOrWhiteSpace(snt))
{
var chargerClient = GetBySn(snt);
if (chargerClient != null)
{
sn = snt;
client = chargerClient;
return true;
}
}
sn = string.Empty;
client = null;
return false;
}
public static UpsClient? GetBySn(string sn)
{
Dictionary.TryGetValue(sn, out var o);
return o;
}
}

@ -0,0 +1,179 @@
using System.Text;
using DotNetty.Buffers;
using DotNetty.Codecs;
using DotNetty.Transport.Channels;
using HybirdFrameworkCore.Utils;
using HybirdFrameworkDriver.Session;
using log4net;
using Newtonsoft.Json;
using Service.Ups.Common;
using Service.Ups.Msg;
namespace Service.Ups.Codec;
public class Decoder: ByteToMessageDecoder
{
private readonly IByteBuffer[] _delimitersStart = { Unpooled.CopiedBuffer(UpsConst.StartChar) };
private readonly IByteBuffer[] _delimitersEnd = { Unpooled.CopiedBuffer(UpsConst.EndChar) };
private ILog Log(string? chargerSn)
{
if (ObjUtils.IsNotNullOrWhiteSpace(chargerSn))
{
return LogManager.GetLogger("Charger" + chargerSn);
}
return LogManager.GetLogger(typeof(Decoder));
}
protected override void Decode(IChannelHandlerContext context, IByteBuffer buffer, List<object> output)
{
string? chargerSn = ChannelUtils.GetAttr(context.Channel, UpsConst.UpsSn);
IByteBuffer? delimiterStart = FindDelimiterStart(buffer);
IByteBuffer? delimiterEnd = FindDelimiterEnd(buffer);
if (delimiterStart != null&&delimiterEnd!=null)
{
//分隔符索引
int delimiterIndex = IndexOf(buffer, delimiterStart);
int delimiterFinish = IndexOf(buffer, delimiterEnd);
//计算帧长
int frameLengthIndex = delimiterFinish - delimiterIndex + 1;
if (delimiterIndex > 0)
{
buffer.SkipBytes(delimiterIndex);
return;
}
//没有帧长
/*if (buffer.ReadableBytes < frameLengthIndex + 2)
{
// 数据不足,等待更多数据
return;
}*/
// 读取长度字段
/*byte frameLength = buffer.GetByte(buffer.ReaderIndex + frameLengthIndex);
//总帧长
int totalFrameLength = delimiterIndex + delimiter.Capacity + 2 + 2 + frameLength;*/
// 最小总帧长过滤
/*if (totalFrameLength < 5)
{
return;
}*/
/*if (buffer.ReadableBytes < totalFrameLength)
{
// 数据不足,等待更多数据
return;
}*/
byte[]? data = null;
try
{
ASDU asdu = Parse(buffer, frameLengthIndex, delimiterStart, out data);
Log(chargerSn)
.Info(
$"receive {BitUtls.BytesToHexStr(data)}:{JsonConvert.SerializeObject(asdu)} from {chargerSn}");
output.Add(asdu);
}
catch (Exception e)
{
Log(chargerSn).Error($"decode fail msg={BitUtls.BytesToHexStr(data)}");
}
}
}
private IByteBuffer? FindDelimiterStart(IByteBuffer buffer)
{
foreach (IByteBuffer delimiter in _delimitersStart)
{
int delimiterIndex = IndexOf(buffer, delimiter);
if (delimiterIndex >= 0)
{
return delimiter;
}
}
return null;
}
private IByteBuffer? FindDelimiterEnd(IByteBuffer buffer)
{
foreach (IByteBuffer delimiter in _delimitersEnd)
{
int delimiterIndex = IndexOf(buffer, delimiter);
if (delimiterIndex >= 0)
{
return delimiter;
}
}
return null;
}
#region 查找帧头
private static int IndexOf(IByteBuffer haystack, IByteBuffer needle)
{
for (int i = haystack.ReaderIndex; i < haystack.WriterIndex; i++)
{
int num = i;
int j;
for (j = 0; j < needle.Capacity && haystack.GetByte(num) == needle.GetByte(j); j++)
{
num++;
if (num == haystack.WriterIndex && j != needle.Capacity - 1)
{
return -1;
}
}
if (j == needle.Capacity)
{
return i - haystack.ReaderIndex;
}
}
return -1;
}
#endregion
#region 查找帧尾
#endregion
public ASDU Parse(IByteBuffer byteBuffer, int totalFrameLength, IByteBuffer delimiter, out byte[] data)
{
//这里转成ascll码
data = new byte[totalFrameLength];
byteBuffer.ReadBytes(data);
//data就是数据
string stRAsicll= Encoding.ASCII.GetString(data ).ToUpper();
string[] strLst = stRAsicll.Split(" ");
int removeIndex = delimiter.Capacity;
//TODO::后续处理
ushort cmd = data[2 + removeIndex];
byte[] bytes = new byte[data[2]];
Array.Copy(data, 2 + removeIndex, bytes, 0, bytes.Length);
byte length = data[2];
ASDU asdu = cmd switch
{
_ => new ASDU(),
};
ASDU.ParseHeader(data, asdu);
return asdu;
}
}

@ -0,0 +1,41 @@
using DotNetty.Buffers;
using DotNetty.Codecs;
using DotNetty.Transport.Channels;
using HybirdFrameworkCore.Utils;
using HybirdFrameworkDriver.Session;
using log4net;
using Newtonsoft.Json;
using Service.Fire.Common;
using Service.Fire.Msg;
namespace Service.Ups.Codec;
public class Encoder: MessageToByteEncoder<APCI>
{
private ILog? Log(string? chargerSn)
{
if (ObjUtils.IsNotNullOrWhiteSpace(chargerSn))
{
return LogManager.GetLogger("fire" + chargerSn);
}
return LogManager.GetLogger(typeof(Fire.Codec.Encoder));
}
/// <summary>
///
/// </summary>
/// <param name="context"></param>
/// <param name="obj"></param>
/// <param name="output"></param>
protected override void Encode(IChannelHandlerContext context, APCI obj, IByteBuffer output)
{
string? sn = ChannelUtils.GetAttr(context.Channel, FireConst.FireSn);
byte[] bytes = obj.ToBytes();
Log(sn)?.Info(
$"send {BitUtls.BytesToHexStr(bytes)}:{JsonConvert.SerializeObject(obj)} to {ChannelUtils.GetAttr(context.Channel, FireConst.FireSn)}");
context.WriteAndFlushAsync(bytes);
}
}

@ -0,0 +1,19 @@
using DotNetty.Common.Utilities;
namespace Service.Ups.Common;
public class UpsConst
{
public static readonly AttributeKey<string> UpsSn = AttributeKey<string>.ValueOf("ups_sn");//fire
public static readonly AttributeKey<string> EqmTypeNo = AttributeKey<string>.ValueOf("eqm_type_no");//5
public static readonly AttributeKey<string> EqmCode = AttributeKey<string>.ValueOf("eqm_code");//fire
//public static readonly AttributeKey<string> DestAddr = AttributeKey<string>.ValueOf("dest_addr");//
public static readonly byte[] StartChar = { 0x28 /* ,0xEE*/ };
public static readonly byte[] EndChar = { 0x3E /* ,0xEE*/ };
public static string Ip = "127.0.0.1";
public static int Port = 505;
public static string Sn = "fire";
public static string No = "1";
public static string Code = "5";
}

@ -0,0 +1,7 @@
namespace Service.Ups;
using DotNetty.Transport.Channels;
public interface IBaseHandler : IChannelHandler
{
}

@ -0,0 +1,15 @@
using HybirdFrameworkDriver.Common;
namespace Service.Ups.Msg;
public abstract class APCI: IToBytes
{
public byte[] ToBytes()
{
var bodyBytes = GetBytes();
var list = new List<byte>();
return list.ToArray();
}
public abstract byte[] GetBytes();
}

@ -0,0 +1,32 @@
using DotNetty.Buffers;
using HybirdFrameworkCore.Utils;
using Service.Fire.Common;
namespace Service.Ups.Msg;
public class ASDU:APCI
{
public override byte[] GetBytes()
{
var list = new List<byte>();
list.AddRange(ModelConvert.Encode(this));
return list.ToArray();
}
public static void ParseHeader(byte[] data, ASDU asdu)
{
IByteBuffer byteBuffer = Unpooled.WrappedBuffer(data);
try
{
}
catch (Exception e)
{
throw e;
}
finally
{
byteBuffer.Release();
}
}
}

@ -19,6 +19,7 @@ using Service.Fire.Common;
using Service.FireControl.Client;
using Service.Plc.Client;
using Service.RealTime;
using Service.Ups.Client;
using SqlSugar;
using SqlSugar.IOC;
using WebStarter.MyFilter;
@ -194,6 +195,12 @@ if (AppSettingsHelper.GetBool("fireZw", "enable"))
FireMgr.ConnClient();
}
//中卫Ups
if (AppSettingsHelper.GetBool("ups", "enable"))
{
UpsMgr.ConnClient();
}
TaskInit.Init();
QuartzSchedulerFactory.Init();

Loading…
Cancel
Save