diff --git a/src/GBNewEnergy.Protocol.Test/DownStream/NEControlDownStreamTest.cs b/src/GBNewEnergy.Protocol.Test/DownStream/NEControlDownStreamTest.cs new file mode 100644 index 0000000..0f696bd --- /dev/null +++ b/src/GBNewEnergy.Protocol.Test/DownStream/NEControlDownStreamTest.cs @@ -0,0 +1,125 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; +using GBNewEnergy.Protocol.Extensions; +using GBNewEnergy.Protocol.NEProperties; +using GBNewEnergy.Protocol.DownStream; +using GBNewEnergy.Protocol.Enums; + +namespace GBNewEnergy.Protocol.Test.DownStream +{ + public class NEControlDownStreamTest : NEPackageBase + { + #region NEControlCmd.unused + [Fact] + public void NEControlDownStreamConstructor4_1() + { + NEControlProperty nEControlProperty = new NEControlProperty + { + VIN = "LGHC4V1D3HE202652", + CmdID=NEControlCmd.unused, + UpgradeParameter=new NEControlUpgradeParameter { + DialPassword = "123", + DialPointName = "xyz", + DialUserName = "11" + } + }; + NEControlDownStream nEControlDownStream = new NEControlDownStream(nEControlProperty, NEGlobalConfigs); + INEProperties nEPackageProperty = new NEPackageProperty + { + Bodies = nEControlDownStream, + MsgId = Enums.NEMsgId.control, + AskId = Enums.NEAskId.cmd, + VIN = "LGHC4V1D3HE202652" + }; + NEPackage nEPackage = new NEPackage(nEPackageProperty, NEGlobalConfigs); + string headerHex = nEPackage.Header.ToHexString(); + string bodiesHex = nEPackage.Bodies.Buffer.ToHexString(); + string packageHex = nEPackage.Buffer.ToHexString(); + } + + [Fact] + public void NEControlDownStreamConstructor4_2() + { + byte[] packageBytes = "23 23 82 FE 4C 47 48 43 34 56 31 44 33 48 45 32 30 32 36 35 32 01 00 07 12 06 0E 0A 0E 1B 00 57".ToHexBytes(); + NEPackage nEPackage = new NEPackage(packageBytes, NEGlobalConfigs); + string headerHex = nEPackage.Header.ToHexString(); + string bodiesHex = nEPackage.Bodies.Buffer.ToHexString(); + string packageHex = nEPackage.Buffer.ToHexString(); + } + #endregion + + #region NEControlCmd.remoteupdate + [Fact] + public void NEControlDownStreamConstructor4_3() + { + NEControlProperty nEControlProperty = new NEControlProperty + { + VIN = "LGHC4V1D3HE202652", + CmdID = NEControlCmd.remoteupdate, + UpgradeParameter=new NEControlUpgradeParameter { + DialPassword = "123", + DialPointName = "xyz", + DialUserName = "11" + } + }; + NEControlDownStream nEControlDownStream = new NEControlDownStream(nEControlProperty, NEGlobalConfigs); + INEProperties nEPackageProperty = new NEPackageProperty + { + Bodies = nEControlDownStream, + MsgId = Enums.NEMsgId.control, + AskId = Enums.NEAskId.cmd, + VIN = "LGHC4V1D3HE202652" + }; + NEPackage nEPackage = new NEPackage(nEPackageProperty, NEGlobalConfigs); + string headerHex = nEPackage.Header.ToHexString(); + string bodiesHex = nEPackage.Bodies.Buffer.ToHexString(); + string packageHex = nEPackage.Buffer.ToHexString(); + } + [Fact] + public void NEControlDownStreamConstructor4_4() + { + byte[] packageBytes = "23 23 82 FE 4C 47 48 43 34 56 31 44 33 48 45 32 30 32 36 35 32 01 00 18 12 06 0E 0A 22 0B 01 3B 78 79 7A 3B 31 31 3B 31 32 33 3B 3B 3B 3B 3B 3B 05".ToHexBytes(); + NEPackage nEPackage = new NEPackage(packageBytes, NEGlobalConfigs); + string headerHex = nEPackage.Header.ToHexString(); + string bodiesHex = nEPackage.Bodies.Buffer.ToHexString(); + string packageHex = nEPackage.Buffer.ToHexString(); + } + #endregion + + #region NEControlCmd.warning + [Fact] + public void NEControlDownStreamConstructor4_5() + { + NEControlProperty nEControlProperty = new NEControlProperty + { + VIN = "LGHC4V1D3HE202652", + CmdID = NEControlCmd.warning, + AlarmParameter= new NEControlAlarmParameter { nEAlarmLevel= NEAlarmLevel.一级报警 } + }; + NEControlDownStream nEControlDownStream = new NEControlDownStream(nEControlProperty, NEGlobalConfigs); + INEProperties nEPackageProperty = new NEPackageProperty + { + Bodies = nEControlDownStream, + MsgId = Enums.NEMsgId.control, + AskId = Enums.NEAskId.cmd, + VIN = "LGHC4V1D3HE202652" + }; + NEPackage nEPackage = new NEPackage(nEPackageProperty, NEGlobalConfigs); + string headerHex = nEPackage.Header.ToHexString(); + string bodiesHex = nEPackage.Bodies.Buffer.ToHexString(); + string packageHex = nEPackage.Buffer.ToHexString(); + } + [Fact] + public void NEControlDownStreamConstructor4_6() + { + byte[] packageBytes = "23 23 82 FE 4C 47 48 43 34 56 31 44 33 48 45 32 30 32 36 35 32 01 00 08 12 06 0E 0B 2C 0B 06 01 6C".ToHexBytes(); + NEPackage nEPackage = new NEPackage(packageBytes, NEGlobalConfigs); + string headerHex = nEPackage.Header.ToHexString(); + string bodiesHex = nEPackage.Bodies.Buffer.ToHexString(); + string packageHex = nEPackage.Buffer.ToHexString(); + } + #endregion + } +} diff --git a/src/GBNewEnergy.Protocol/DownStream/NEControlDownStream.cs b/src/GBNewEnergy.Protocol/DownStream/NEControlDownStream.cs index c876c26..2702f58 100644 --- a/src/GBNewEnergy.Protocol/DownStream/NEControlDownStream.cs +++ b/src/GBNewEnergy.Protocol/DownStream/NEControlDownStream.cs @@ -1,4 +1,5 @@ -using GBNewEnergy.Protocol.Extensions; +using GBNewEnergy.Protocol.Enums; +using GBNewEnergy.Protocol.Extensions; using GBNewEnergy.Protocol.NEProperties; using System; using System.Collections.Generic; @@ -17,33 +18,75 @@ namespace GBNewEnergy.Protocol.DownStream public NEControlDownStream(INEProperties nEProperties, NEGlobalConfigs nEConfigs) : base(nEProperties, nEConfigs) { - } - + } /// /// 命令ID 只能发送一个 - /// - public byte CmdId { get; set; } - - /// - /// 命令参数 - /// [{id,value},{id,value}], 没有内容则内容为空 - /// - public List> Vauels { get; set; } - + /// + public NEControlCmd CmdID { get; set; } + /// + /// 命令参数 没有内容则内容为空 + /// + public string CmdParameter { get; set; } protected override void InitializeProperties(INEProperties nEProperties) - { - + { + NEControlProperty nEControlProperty = (NEControlProperty)nEProperties; + CmdID = nEControlProperty.CmdID; + if (CmdID == NEControlCmd.remoteupdate) + { + CmdParameter = nEControlProperty.UpgradeParameter.ToString(); + } + else if(CmdID == NEControlCmd.warning) + { + CmdParameter = nEControlProperty.AlarmParameter.nEAlarmLevel.ToString(); + } } protected override void InitializePropertiesFromBuffer() { CurrentDateTime = Buffer.ReadDateTimeLittle(0, 6); + CmdID = (NEControlCmd)Buffer[6]; + switch (CmdID) + { + case NEControlCmd.remoteupdate: + CmdParameter = Buffer.ReadStringLittle(7, Buffer.Length - 8);//最后一位为校验码,不在参数列 + break; + case NEControlCmd.warning: + CmdParameter = ((NEAlarmLevel)Buffer[7]).ToString(); + break; + case NEControlCmd.unused: + case NEControlCmd.shutdown: + case NEControlCmd.reset: + case NEControlCmd.restorefactorysettings: + case NEControlCmd.interruptrequest: + case NEControlCmd.OpenMonitoring: + default: + break; + } } + protected override void ToBuffer() { - Buffer = new byte[6]; - Buffer.WriteLittle(CurrentDateTime, 0, 6); + if (CmdID == NEControlCmd.remoteupdate) + { + var contentLength = NEConfigs.NEEncoding.GetBytes(CmdParameter).Length; + Buffer = new byte[6 + 1 + contentLength]; + Buffer.WriteLittle(CurrentDateTime, 0, 6); + Buffer.WriteLittle(CmdID.ToByteValue(), 6); + Buffer.WriteLittle(CmdParameter, 7); + } + else if (CmdID == NEControlCmd.warning) { + Buffer = new byte[6 + 1 + 1]; + Buffer.WriteLittle(CurrentDateTime, 0, 6); + Buffer.WriteLittle(CmdID.ToByteValue(), 6); + Buffer.WriteLittle(CmdParameter.ToEnum().ToByteValue(), 7); + } + else + { + Buffer = new byte[6 + 1]; + Buffer.WriteLittle(CurrentDateTime, 0, 6); + Buffer.WriteLittle(CmdID.ToByteValue(), 6); + } } } } diff --git a/src/GBNewEnergy.Protocol/Enums/NEAlarmLevel.cs b/src/GBNewEnergy.Protocol/Enums/NEAlarmLevel.cs new file mode 100644 index 0000000..37c9ee6 --- /dev/null +++ b/src/GBNewEnergy.Protocol/Enums/NEAlarmLevel.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace GBNewEnergy.Protocol.Enums +{ + /// + /// 报警等级 + /// + public enum NEAlarmLevel:byte + { + 无报警 = 0x00, + 一级报警 = 0x01, + 二级报警 = 0x02, + 三级报警 = 0x03, + 无效数据 = 0xFF + } +} diff --git a/src/GBNewEnergy.Protocol/Enums/NEControlCmd.cs b/src/GBNewEnergy.Protocol/Enums/NEControlCmd.cs index 08437b1..8dfdcb1 100644 --- a/src/GBNewEnergy.Protocol/Enums/NEControlCmd.cs +++ b/src/GBNewEnergy.Protocol/Enums/NEControlCmd.cs @@ -16,9 +16,9 @@ namespace GBNewEnergy.Protocol.Enums /// unused= 0x00, /// - /// 远程升级 + /// 远程升级 见表B.16 /// - remoteupdate=0x01, + remoteupdate = 0x01, /// /// 车载终端关机 /// diff --git a/src/GBNewEnergy.Protocol/Extensions/EnumExtensions.cs b/src/GBNewEnergy.Protocol/Extensions/EnumExtensions.cs new file mode 100644 index 0000000..9ab863f --- /dev/null +++ b/src/GBNewEnergy.Protocol/Extensions/EnumExtensions.cs @@ -0,0 +1,135 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Reflection; + +namespace GBNewEnergy.Protocol.Extensions +{ + /// + /// 枚举扩展 + /// + internal static class EnumExtensions + { + /// + /// 转为整型 + /// + /// + /// + /// + public static int ToValue(this T t) where T : struct + { + return Convert.ToInt32(t); + } + /// + /// 转为Byte + /// + /// + /// + /// + public static byte ToByteValue(this T t) where T : struct + { + return Convert.ToByte(t); + } + + /// + /// 字符转枚举 + /// + /// + /// + /// + public static T ToEnum(this string value) where T : struct + { + return (T)Enum.Parse(typeof(T), value); + } + + /// + /// 获取枚举字符串 + /// + /// + public static string GetName(this Enum valueEnum) + { + return valueEnum.ToString(); + } + + /// + /// 获取DescriptionAttribute特性枚举值的描述 + /// + /// + /// + public static string GetDescription(this Enum value) + { + var attribute = value.GetAttribute(); + return attribute == null ? value.ToString() : attribute.Description; + } + + /// + /// 验证是否是枚举类型 + /// + /// + /// + /// + public static bool IsEnumValid(this int enumValue) + { + return Enum.IsDefined(typeof(TEnum), enumValue); + } + + /// + /// 获取DescriptionAttribute特性枚举及描述 + /// + /// + /// + public static Dictionary GetDescriptionAttributeDictionary(this Enum value) + { + Dictionary dictionary = new Dictionary(); + var fields = value.GetType().GetFields(BindingFlags.Static | BindingFlags.Public); + foreach (var fi in fields) + { + DescriptionAttribute attr = Attribute.GetCustomAttribute(fi, typeof(DescriptionAttribute), false) as DescriptionAttribute; + dictionary.Add(fi.Name, attr != null ? attr.Description : ""); + } + return dictionary; + } + + /// + /// 获取DisplayNameAttribute特性枚举值的描述 + /// + /// 枚举值 + /// + public static string GetDisplayName(this Enum value) + { + var attribute = value.GetAttribute(); + return attribute == null ? value.ToString() : attribute.DisplayName; + } + + /// + /// 获取DisplayNameAttribute特性枚举及描述 + /// + /// + /// + public static Dictionary GetDisplayNameAttributeDictionary(this Enum value) + { + Dictionary dictionary = new Dictionary(); + var fields = value.GetType().GetFields(BindingFlags.Static | BindingFlags.Public); + foreach (var fi in fields) + { + DisplayNameAttribute attr = Attribute.GetCustomAttribute(fi, typeof(DisplayNameAttribute), false) as DisplayNameAttribute; + dictionary.Add(fi.Name, attr != null ? attr.DisplayName : ""); + } + return dictionary; + } + + /// + /// 获取枚举对应特性 + /// + /// + /// + /// + public static T GetAttribute(this Enum value) where T : Attribute + { + var type = value.GetType(); + var memberInfo = type.GetMember(value.ToString()); + var attributes = memberInfo[0].GetCustomAttributes(typeof(T), false); + return (T)attributes[0]; + } + } +} diff --git a/src/GBNewEnergy.Protocol/NEBodiesFactory.cs b/src/GBNewEnergy.Protocol/NEBodiesFactory.cs index 032f90a..e9d0787 100644 --- a/src/GBNewEnergy.Protocol/NEBodiesFactory.cs +++ b/src/GBNewEnergy.Protocol/NEBodiesFactory.cs @@ -27,7 +27,8 @@ namespace GBNewEnergy.Protocol return new NEPlatformLoginUpStream(buf, nEConfigs); case NEMsgId.platformlogout: return new NEPlatformLogoutUpStream(buf, nEConfigs); - case NEMsgId.control: + case NEMsgId.control: + return new NEControlDownStream(buf, nEConfigs); case NEMsgId.settings: case NEMsgId.heartbeat: case NEMsgId.checktime: diff --git a/src/GBNewEnergy.Protocol/NEGlobalConfigs.cs b/src/GBNewEnergy.Protocol/NEGlobalConfigs.cs index c2f4f2e..e736e0d 100644 --- a/src/GBNewEnergy.Protocol/NEGlobalConfigs.cs +++ b/src/GBNewEnergy.Protocol/NEGlobalConfigs.cs @@ -8,7 +8,11 @@ namespace GBNewEnergy.Protocol /// /// 加密编码 /// - public Encoding NEEncryptEncoding { get; set; } = Encoding.UTF8; + public Encoding NEEncryptEncoding { get; set; } = Encoding.UTF8; + /// + /// 字符串编码 + /// + public Encoding NEEncoding { get; set; } = Encoding.UTF8; /// /// 数据单元加密方式 /// 0x01:数据不加密;0x02:数据经过 RSA 算法加密;0x03:数据经过 AES128 位算法加密;“0xFE”表示异常,“0xFF”表示无效 diff --git a/src/GBNewEnergy.Protocol/NEProperties/NEControlAlarmParameter.cs b/src/GBNewEnergy.Protocol/NEProperties/NEControlAlarmParameter.cs new file mode 100644 index 0000000..6f51269 --- /dev/null +++ b/src/GBNewEnergy.Protocol/NEProperties/NEControlAlarmParameter.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; +using GBNewEnergy.Protocol.Enums; + +namespace GBNewEnergy.Protocol.NEProperties +{ + /// + /// 控制命令 报警、预警 + /// + public class NEControlAlarmParameter + { + /// + /// 报警等级 + /// + public NEAlarmLevel nEAlarmLevel { get; set; } + } +} diff --git a/src/GBNewEnergy.Protocol/NEProperties/NEControlProperty.cs b/src/GBNewEnergy.Protocol/NEProperties/NEControlProperty.cs new file mode 100644 index 0000000..7ebd502 --- /dev/null +++ b/src/GBNewEnergy.Protocol/NEProperties/NEControlProperty.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Text; +using GBNewEnergy.Protocol.Enums; + +namespace GBNewEnergy.Protocol.NEProperties +{ + /// + /// 控制命令属性 + /// + public class NEControlProperty : INEProperties + { + public string VIN { get; set ; } + /// + /// 命令ID 只能发送一个 + /// + public NEControlCmd CmdID { get; set; } + /// + /// 升级参数 + /// + public NEControlUpgradeParameter UpgradeParameter { get; set; } + /// + /// 报警,预警参数 + /// + public NEControlAlarmParameter AlarmParameter { get; set; } + } +} diff --git a/src/GBNewEnergy.Protocol/NEProperties/NEControlUpgradeParameter.cs b/src/GBNewEnergy.Protocol/NEProperties/NEControlUpgradeParameter.cs new file mode 100644 index 0000000..e3be834 --- /dev/null +++ b/src/GBNewEnergy.Protocol/NEProperties/NEControlUpgradeParameter.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace GBNewEnergy.Protocol.NEProperties +{ + /// + /// 控制命令,升级 + /// + public class NEControlUpgradeParameter + { + /// + /// URL地址 + /// + public string Url { get; set; } + /// + /// 拨号点名称 + /// + public string DialPointName { get; set; } + /// + /// 拨号用户名 + /// + public string DialUserName { get; set; } + /// + /// 拨号密码 + /// + public string DialPassword { get; set; } + /// + /// 服务器地址 + /// + public string ServerUrl { get; set; } + /// + /// 服务器端口 + /// + public string ServerPort { get; set; } + /// + /// 生产厂商代码 + /// + public string ProviderCode { get; set; } + /// + /// 硬件版本 + /// + public string HardwareVersion { get; set; } + /// + /// 固件版本 + /// + public string FirmwareVersion { get; set; } + /// + /// 升级服务器时限 + /// + public string UpLimitTime { get; set; } + public override string ToString() + { + return $"{Url};{DialPointName};{DialUserName};{DialPassword};{ServerUrl};{ServerPort};{ProviderCode};{HardwareVersion};{FirmwareVersion};{UpLimitTime}"; + } + } +}