using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto; using NUglify.JavaScript.Syntax; using System.Text.RegularExpressions; using YamlDotNet.Core.Tokens; namespace JiShe.CollectBus.Protocol.T37612012 { public static class Protocol3761Extensions { /// /// 3761协议数据字节校验 /// /// /// public static bool Check3761Byte(this string value) { if (!value.ToUpper().Equals("FF") && !value.ToUpper().Equals("EE")) return true; return false; } /// /// 字符串中是否包含字母 /// /// /// public static bool IsLetterExists(this string value) { return Regex.Matches(value, "[a-zA-Z]").Count > 0; } /// /// 判断错误代码 /// public static Tuple? CheckErrorCode(this List data) { var value = string.Join("", data); if (value.IsLetterExists()) { var code = ErrorCodes().Where(f => value.Contains(f.Key)).FirstOrDefault(); if (code.Key != null) return Tuple.Create(code.Key,code.Value); else return Tuple.Create("EE", "未知数据错误"); } return null; } /// /// 判断错误代码 /// public static Tuple? CheckErrorCode(this string value) { if (value.IsLetterExists()) { var code = ErrorCodes().Where(f => value.Contains(f.Key)).FirstOrDefault(); if (code.Key != null) return Tuple.Create(code.Key, code.Value); else return Tuple.Create("EE", "未知数据错误"); } return null; } /// /// 错误信息 /// /// public static Dictionary ErrorCodes() { return new Dictionary() { { "FF", "电表无此数据项" }, { "EE", "未知数据错误" }, { "E1", "数据点缺少(停电)" }, { "E2", "通讯异常" }, { "E3", "集中器未配置数据项" }, { "E4", "电表档案无效" }, { "E5", "电表无此数据项" }, { "E6", "电表时间异常" }, { "E7","暂停抄表" } }; } /// /// 费率数 /// /// /// /// public static int GetRatingCount(this List hexMessageList ,int index, int len) { var list = hexMessageList.GetRange(index, len); return list.Count > 0 ? list[0].HexToDec() : 0; } /// /// 抄表时间 /// /// /// /// public static string GetReadTime(this List hexMessageList, int index, int len) { var list = hexMessageList.GetRange(index, len); return list.GetReadTime(); } /// /// 抄表时间 /// /// /// public static string GetReadTime(this List data) { data.Reverse(); data.Insert(0, DateTime.Now.ToString("yyyy").Substring(0, 2)); return string.Join("", data); } /// /// 判断当前时间所在时标(15分钟) /// /// /// public static DateTime CheckTimePoint(this DateTime curTime) { var curMinute = Convert.ToInt32(curTime.ToString("mm")); string dataTime; if (curMinute >= 0 && curMinute < 15) dataTime = curTime.ToString("yyyy-MM-dd HH:00:00"); else if (curMinute >= 15 && curMinute < 30) dataTime = curTime.ToString("yyyy-MM-dd HH:15:00"); else if (curMinute >= 30 && curMinute < 45) dataTime = curTime.ToString("yyyy-MM-dd HH:30:00"); else dataTime = curTime.ToString("yyyy-MM-dd HH:45:00"); return DateTime.Parse(dataTime); } /// /// 判断当前时间所在时标(5分钟) /// /// /// public static DateTime CheckTimeFivePoint(this DateTime curTime) { string dataTime; var curMinute = Convert.ToInt32(curTime.ToString("mm")); if (curMinute >= 0 && curMinute < 5) dataTime = curTime.ToString("yyyy-MM-dd HH:00:00"); else if (curMinute >= 5 && curMinute < 10) dataTime = curTime.ToString("yyyy-MM-dd HH:5:00"); else if (curMinute >= 10 && curMinute < 15) dataTime = curTime.ToString("yyyy-MM-dd HH:10:00"); else if (curMinute >= 15 && curMinute < 20) dataTime = curTime.ToString("yyyy-MM-dd HH:15:00"); else if (curMinute >= 20 && curMinute < 25) dataTime = curTime.ToString("yyyy-MM-dd HH:20:00"); else if (curMinute >= 25 && curMinute < 30) dataTime = curTime.ToString("yyyy-MM-dd HH:25:00"); else if (curMinute >= 30 && curMinute < 35) dataTime = curTime.ToString("yyyy-MM-dd HH:30:00"); else if (curMinute >= 35 && curMinute < 40) dataTime = curTime.ToString("yyyy-MM-dd HH:35:00"); else if (curMinute >= 40 && curMinute < 45) dataTime = curTime.ToString("yyyy-MM-dd HH:40:00"); else if (curMinute >= 45 && curMinute < 50) dataTime = curTime.ToString("yyyy-MM-dd HH:45:00"); else if (curMinute >= 50 && curMinute < 55) dataTime = curTime.ToString("yyyy-MM-dd HH:50:00"); else dataTime = curTime.ToString("yyyy-MM-dd HH:55:00"); return DateTime.Parse(dataTime); } /// /// 格式化时间 /// /// /// /// /// public static DateTime GetFormatTime(this DateTime dateTime, DensityUnit densityUnit, int timeDensity) { switch (densityUnit) { case DensityUnit.Minute: if (timeDensity == 1 || timeDensity == 30) return DateTime.Parse(dateTime.ToString("yyyy-MM-dd HH:mm:00")); if (timeDensity == 5) return dateTime.CheckTimeFivePoint(); if (timeDensity == 15) return dateTime.CheckTimePoint(); if (timeDensity == 60) return DateTime.Parse(dateTime.ToString("yyyy-MM-dd HH:00:00")); break; case DensityUnit.Day: return DateTime.Parse(dateTime.ToString("yyyy-MM-dd 00:00:00")); case DensityUnit.Month: return DateTime.Parse(dateTime.ToString("yyyy-MM-01 00:00:00")); } return dateTime; } /// /// 数据时标(曲线类型) /// /// /// /// /// /// public static List GetReadTimeTd_c(this List hexMessageList, int index, int len) { if (len != 7) throw new ArgumentException("数据时标 Td_c参数为不标准长度"); var list = hexMessageList.GetRange(index, len); List values = new List { GetReadTime(list.GetRange(0, 5)), list[5].HexToDec().ToString(),//密度 list[6].HexToDec().ToString()//数据点数 }; return values; } /// /// 数据时标型(曲线类型) /// /// /// public static List> GenerateFinalResultTd_c(this List data, int index,int density,string dataType, string filedDesc = "") { List> list = new List>(); for (int i = index; i < data.Count; i++) { AnalysisBaseDto meter = new AnalysisBaseDto { DeviceType = MeterTypeEnum.Ammeter }; var errorCode = data[i].CheckErrorCode(); if (errorCode != null) { meter.ValidData = false; meter.ErrorCodeMsg = errorCode.Item2; } else { if(decimal.TryParse(data[i], out decimal value)) { meter.DataValue = value; } } meter.ItemType = dataType; meter.FiledDesc = filedDesc; meter.FiledName = meter.ItemType.GetDataFieldByGatherDataType() ?? string.Empty; if (DateTime.TryParse(CalculateTimeSpan(i - 3, data[0], density), out DateTime readingDate)) meter.TimeSpan = readingDate; list.Add(meter); } return list; } /// /// 月冻结(曲线类型) /// /// /// /// /// /// /// public static List> GenerateFinalResultTd_m(this List data, int index,string dataType,string timeSpan, string filedDesc = "") { List> list = new List>(); for (int i = index; i < data.Count; i++) { AnalysisBaseDto meter = new AnalysisBaseDto(); meter.DeviceType = MeterTypeEnum.Ammeter; var errorCode = data[i].CheckErrorCode(); if (errorCode != null) { meter.ValidData = false; meter.ErrorCodeMsg = errorCode.Item2; } else { if(decimal.TryParse(data[i], out decimal value)) { meter.DataValue = value; } } if (DateTime.TryParse(timeSpan, out DateTime readingDate)) { meter.TimeSpan = readingDate; } meter.ItemType = i - index == 0 ? dataType : $"{dataType}_{i - index}"; meter.FiledDesc = filedDesc; meter.FiledName = meter.ItemType.GetDataFieldByGatherDataType() ?? string.Empty; list.Add(meter); } return list; } /// /// 日冻结(曲线类型) /// /// /// /// /// public static List> GenerateFinalResultTd_d(this List data, int index,string dataType, string timeSpan, string filedDesc = "") { List> list = new List>(); int typeIndex = 0; for (int i = index; i < data.Count; i++) { AnalysisBaseDto meter = new AnalysisBaseDto { DeviceType = MeterTypeEnum.Ammeter }; decimal value = 0; var errorCode = data[i].CheckErrorCode(); if (errorCode != null) { meter.ValidData = false; meter.ErrorCodeMsg = errorCode.Item2; } else { if(decimal.TryParse(data[i], out value)) { meter.DataValue = value; } } if (DateTime.TryParse(timeSpan, out DateTime readingDate)) { meter.TimeSpan = readingDate; } meter.ItemType = i - index == 0 ? dataType : $"{dataType}_{i - index}"; meter.FiledDesc = filedDesc; meter.FiledName = meter.ItemType.GetDataFieldByGatherDataType() ?? string.Empty; list.Add(meter); typeIndex++; } return list; } /// /// 计算时标 /// /// /// /// /// private static string CalculateTimeSpan(int index, string time, int intervalTime) { var startTime = Convert.ToDateTime($"{time.Substring(0, 4)}-{time.Substring(4, 2)}-{time.Substring(6, 2)} {time.Substring(8, 2)}:{time.Substring(10, 2)}"); return startTime.AddMinutes(index * intervalTime).ToString("yyyy-MM-dd HH:mm:ss"); } /// /// 校验数据值精度 /// /// /// /// public static List> IsValidData(this List> meterDatas, List mark) { bool isUpload = false; var jfpgSum = 0M; foreach (var item in meterDatas) { if (item.ValidData && item.DataValue.HasValue) jfpgSum += item.DataValue.Value; } var totalItem = meterDatas.FirstOrDefault(f => f.ItemType.Equals(mark[0]));//meterDatas.Find(f => f.DataType.Equals(mark[0])); if (totalItem != null) { var floatingNum = (jfpgSum * 5 / 100);//上下浮动数据 var minjfpgSum = jfpgSum - floatingNum;//100-(100*5/100); var maxjfpgSum = jfpgSum + floatingNum; if ((totalItem.DataValue <= maxjfpgSum || totalItem.DataValue >= minjfpgSum))//总值,在JFPG之和的浮动范围内 isUpload = true; else isUpload = false; } if (!isUpload) { meterDatas.ForEach(f => { f.ValidData = false; }); } return meterDatas; } } }