using MeterVision.Config; using MeterVision.FreeAi; using MeterVision.model; using MeterVision.RemoteApi; using MeterVision.Util; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MeterVision.db { public class TPatchDetail { public string PatchDetailId { get; set; } public string PatchId { get; set; } public string CreateTime { get; set; } public string StandDetailId { get; set; } public string StandValue { get; set; } public string SrcImage { get; set; } public string SampleTime { get; set; } //图片的采样时间 public int RunFlag { get; set; } public string RunTime { get; set; } public string DstImage { get; set; } public int ResultType { get; set; } public long RawValue { get; set; } public long FinalValue { get; set; } public long CompleteValue { get; set; } //识别后的完整结果 public int ValueChanged { get; set; } public int ResultMeter { get; set; } //识别后的水表类型 //0:还未运行比较 1:比较后相等 2:比较后不等 3:比较后识别无效 public int EqualFlag { get; set; } public string AiVer { get; set; } public string DebugInfo { get; set; } public string LogPath { get; set; } public string Memo { get; set; } //--20250313 add by djs public string StationKey { get; set; } //站点表-主键 public string StationId { get; set; } //站点ID public int MeterType { get; set; } public double BrightVal { get; set; } //配置参数-图片亮度 public int FlowRate { get; set; } //配置参数-每小时最大水流 public int DigitCount { get; set; } public int PointerCount { get; set; } public double LastUnit { get; set; } //20250430新增项(数据区域是否在s public int NumInUpper { get; set; } public string MeterRegion { get; set; } //配置参数-表盘区域 public string FeatureRegion { get; set; } //配置参数-特征区域 public int LastCompress { get; set; } //上一次压缩大小 public long LatestValue { get; set; } //上次正确结果值 public string LatestTime { get; set; } //上次正确值的时间 public long LatestComplete { get; set; } //上次完整结果值 public int JudgeLastnumFlag { get; set; } // 构造函数,初始化默认值 public TPatchDetail() { PatchDetailId = string.Empty; PatchId = string.Empty; CreateTime = string.Empty; StandDetailId = string.Empty; StandValue = string.Empty; SrcImage = string.Empty; RunFlag = 0; RunTime = string.Empty; DstImage = string.Empty; MeterType = -1; DigitCount = -1; PointerCount = -1; LastUnit = -1; NumInUpper = -1; ResultType = 0; RawValue = -1; FinalValue = -1; EqualFlag = 0; AiVer = string.Empty; DebugInfo = string.Empty; LogPath = string.Empty; Memo = string.Empty; StationKey = string.Empty; StationId = string.Empty; ResultMeter = -1; CompleteValue = -1; ValueChanged = -1; BrightVal = 1.2f; FlowRate = -1; MeterRegion = string.Empty; FeatureRegion = string.Empty; LastCompress = -1; LatestValue = -1; LatestTime = string.Empty; LatestComplete = -1; JudgeLastnumFlag = 1; } public TPatchDetail(PatchDetailItem patchDetail, ResultModel resultModel) { //PatchDetailId = patchDetail.PatchDetailId; //PatchId = patchDetail.PatchId; //CreateTime = patchDetail.CreateTime; //StandDetailId = patchDetail.StandDetailId; //StandValue = patchDetail.StandValue; //SrcImage = patchDetail.SrcImage; ObjectHelper.CopyMatchingFields(patchDetail, this); RunFlag = 1; RunTime = ThisApp.GetNowTime_yyyyMMddHHmmss(); DstImage = resultModel.DstImage; ResultMeter = resultModel.ResultMeter; ResultType = resultModel.ResultType; RawValue = (long)resultModel.RawValue; //resultModel.SRawValue; FinalValue = (long)resultModel.FinalValue; //resultModel.sFinalValue; CompleteValue = (long)resultModel.CompleteValue; //resultModel.sCompleteValue; AiVer = resultModel.AiVer; LogPath = resultModel.LogPath; // 使用 LINQ 进行转换和条件判断 //var formattedBytes = resultModel.DebugInfoBytes.Select(b => b == 88 ? "" : b.ToString()); DebugInfo = ThisApp.GetDebugInfos(resultModel.DebugInfoBytes); //string.Join(",", formattedBytes); //EqualFlag,这里需要判断,是否相等、约等、不等 //先简单判断 //20250317 delte by djs (无标准值的数据不会进入到这里 if (string.IsNullOrWhiteSpace(StandValue)) { //EqualFlag = 2; EqualFlag = 3; //无标准值可供比较(理论上不会出现这种情况) } else { if (double.TryParse(StandValue, out double dStandValue)) { //EqualFlag = CheckEquailityWithStandValue(dStandValue, FinalValue) ? 1 : 0; EqualFlag = GetEqualFlag(dStandValue, FinalValue); }//if } } public TPatchDetail(PatchDetailItem patchDetail,CallApiResult apiResult) { ObjectHelper.CopyMatchingFields(patchDetail, this); RunFlag = 1; RunTime = ThisApp.GetNowTime_yyyyMMddHHmmss(); ResultMeter = 4; //先随便给一个 ResultType = 1; //存储图像 if (apiResult.recognResult.data.image != null) { string dstImagPath = CfginiItem.GetConfigItem().DstImgPath; dstImagPath = Path.Combine(dstImagPath, ThisApp.GetNowTime_yyyyMMdd()); if (!Directory.Exists(dstImagPath)) { Directory.CreateDirectory(dstImagPath); } dstImagPath = Path.Combine(dstImagPath, Guid.NewGuid().ToString() + ".jpg"); //SaveBigJpg(api, dstImagPath); //bool blSave = RecogApi.SaveDstJpg(apiResult.recognResult.data.image, dstImagPath); bool blSaveImage = RecogApi.SaveBase64ToFile(apiResult.recognResult.data.image, dstImagPath); DstImage = blSaveImage ? dstImagPath : string.Empty; } else { DstImage = ""; } //存储日志 if (!string.IsNullOrEmpty(apiResult.recognResult.data.logs)) { string aiLogPath = CfginiItem.GetConfigItem().AiLogPath; aiLogPath = Path.Combine(aiLogPath, ThisApp.GetNowTime_yyyyMMdd()); if (!Directory.Exists(aiLogPath)) { Directory.CreateDirectory(aiLogPath); } aiLogPath = Path.Combine(aiLogPath, Guid.NewGuid().ToString() + ".txt"); bool blSaveLog = RecogApi.SaveBase64ToFile(apiResult.recognResult.data.logs, aiLogPath); LogPath = blSaveLog ? aiLogPath : string.Empty; } else { LogPath = ""; } if (apiResult.recognResult.data != null) { if(apiResult.recognResult.data.reading == null) { FinalValue = long.MaxValue; } else { FinalValue = (long)(apiResult.recognResult.data.reading * 10000); } //先借用配置的字段存放识别的数据 //空的时候保存最大值 if (apiResult.recognResult.data.meter_type == null) { MeterType = int.MaxValue; } else { MeterType = (int)apiResult.recognResult.data.meter_type; } if (apiResult.recognResult.data.reading_unit == null) { LastUnit = double.MaxValue; } else { LastUnit = (double)apiResult.recognResult.data.reading_unit; } if (string.IsNullOrWhiteSpace(StandValue)) { //EqualFlag = 2; EqualFlag = 2; //无标准值可供比较(理论上不会出现这种情况) } else if (MeterType == int.MaxValue || LastUnit == double.MaxValue || FinalValue == long.MaxValue) { EqualFlag = 2; } else { if (MeterType == 0 || MeterType == 88 || MeterType == 90) { EqualFlag = 2; } else { if (double.TryParse(StandValue, out double dStandValue)) { //EqualFlag = CheckEquailityWithStandValue(dStandValue, FinalValue) ? 1 : 0; //EqualFlag = GetEqualFlag(dStandValue, FinalValue); EqualFlag = GetEqualFlag_http(dStandValue, FinalValue); } } } //else //{ // if (double.TryParse(StandValue, out double dStandValue)) // { // //EqualFlag = CheckEquailityWithStandValue(dStandValue, FinalValue) ? 1 : 0; // //EqualFlag = GetEqualFlag(dStandValue, FinalValue); // EqualFlag = (long)(dStandValue * 10000) == FinalValue ? 1 : 0; // }//if //} } else { FinalValue = long.MaxValue; LastUnit = double.MaxValue; MeterType = int.MaxValue; EqualFlag = 2; } //等于0说明调用成功,但是AI服务未识别成功 if (apiResult.recognResult.result == 0) { Memo = apiResult.recognResult.message; } else { Memo = ""; } } //设置结果 public void SetResult(ResultModel resultModel) { RunFlag = 1; RunTime = ThisApp.GetNowTime_yyyyMMddHHmmss(); DstImage = resultModel.DstImage; //MeterType = resultModel.MeterType; ResultMeter = resultModel.ResultMeter; ResultType = resultModel.ResultType; RawValue = (long)resultModel.RawValue; FinalValue = (long)resultModel.FinalValue; CompleteValue = (long)resultModel.CompleteValue; AiVer = resultModel.AiVer; LogPath = resultModel.LogPath; // 使用 LINQ 进行转换和条件判断 //var formattedBytes = resultModel.DebugInfoBytes.Select(b => b == 88 ? "" : b.ToString()); DebugInfo = ThisApp.GetDebugInfos(resultModel.DebugInfoBytes); //string.Join(",", formattedBytes); //EqualFlag,这里需要判断,是否相等、约等、不等 //先简单判断 if (string.IsNullOrWhiteSpace(StandValue)) { EqualFlag = 3; } else { //if (int.TryParse(StandValue, out int iStandValue)) if(double.TryParse(StandValue,out double dStandValue)) { //EqualFlag = CheckEquailityWithStandValue(dStandValue, FinalValue) ? 1 : 0; EqualFlag = GetEqualFlag(dStandValue, FinalValue); } } } public void SetResult(CallApiResult apiResult) { RunFlag = 1; RunTime = ThisApp.GetNowTime_yyyyMMddHHmmss(); ResultMeter = 4; //先随便给一个 ResultType = 1; //存储图像 if (apiResult.recognResult.data.image != null) { string dstImagPath = CfginiItem.GetConfigItem().DstImgPath; dstImagPath = Path.Combine(dstImagPath, ThisApp.GetNowTime_yyyyMMdd()); if (!Directory.Exists(dstImagPath)) { Directory.CreateDirectory(dstImagPath); } dstImagPath = Path.Combine(dstImagPath, Guid.NewGuid().ToString() + ".jpg"); //SaveBigJpg(api, dstImagPath); //bool blSave = RecogApi.SaveDstJpg(apiResult.recognResult.data.image, dstImagPath); bool blSaveImage = RecogApi.SaveBase64ToFile(apiResult.recognResult.data.image, dstImagPath); DstImage = blSaveImage ? dstImagPath : string.Empty; } else { DstImage = ""; } //存储日志 if (!string.IsNullOrEmpty(apiResult.recognResult.data.logs)) { string aiLogPath = CfginiItem.GetConfigItem().AiLogPath; aiLogPath = Path.Combine(aiLogPath, ThisApp.GetNowTime_yyyyMMdd()); if (!Directory.Exists(aiLogPath)) { Directory.CreateDirectory(aiLogPath); } aiLogPath = Path.Combine(aiLogPath, Guid.NewGuid().ToString() + ".txt"); bool blSaveLog = RecogApi.SaveBase64ToFile(apiResult.recognResult.data.logs, aiLogPath); LogPath = blSaveLog ? aiLogPath : string.Empty; } else { LogPath = ""; } if (apiResult.recognResult.data.reading != null) { if (apiResult.recognResult.data.reading == null) { FinalValue = long.MaxValue; } else { FinalValue = (long)(apiResult.recognResult.data.reading * 10000); } //先借用配置的字段存放识别的数据 //空的时候保存最大值 if (apiResult.recognResult.data.meter_type == null) { MeterType = int.MaxValue; } else { MeterType = (int)apiResult.recognResult.data.meter_type; } if (apiResult.recognResult.data.reading_unit == null) { LastUnit = double.MaxValue; } else { LastUnit = (double)apiResult.recognResult.data.reading_unit; } if (string.IsNullOrWhiteSpace(StandValue)) { //EqualFlag = 2; EqualFlag = 2; //无标准值可供比较(理论上不会出现这种情况) } else if (MeterType == int.MaxValue || LastUnit == double.MaxValue || FinalValue == long.MaxValue) { EqualFlag = 2; } else { if (MeterType == 0 || MeterType == 88 || MeterType == 90) { EqualFlag = 2; } else { if (double.TryParse(StandValue, out double dStandValue)) { //EqualFlag = CheckEquailityWithStandValue(dStandValue, FinalValue) ? 1 : 0; //EqualFlag = GetEqualFlag(dStandValue, FinalValue); //EqualFlag = (long)(dStandValue * 10000) == FinalValue ? 1 : 0; EqualFlag = GetEqualFlag_http(dStandValue, FinalValue); }//if } } } else { FinalValue = long.MaxValue; LastUnit = double.MaxValue; MeterType = int.MaxValue; EqualFlag = 2; } //等于0说明调用成功,但是服务并未AI识别成功 if(apiResult.recognResult.result == 0) { Memo = apiResult.recognResult.message; } else { Memo = ""; } } public bool IsGoodResult() { bool isGood = false; if(MeterType == ResultMeter && (ResultType == 1 || ResultType == 2 || ResultType == 7 || ResultType == 8)) { isGood = true; } return isGood; } public bool CheckEquailityWithStandValue(double standValue, long finalValue) { bool isEqual = false; //比较结果值与标准值是否相等 if (MeterType == ResultMeter) { if (MeterType == 1) { //数字+指针(只比较数字部分) //获取真正数据部分的值 int standValue1 = (int)Math.Ceiling(standValue / LastUnit); int finalValue1 = (int)(finalValue / (FaConstant.CUBE_VALUE * LastUnit)); //isEqual = (standValue1 == finalValue1); //判断如何按最后一个单位差1,也认为正确(比如0.1单位,则差0.1是正确的,10单位的,差10也是正确的) //上面的值,也就规划为数字的整数 isEqual = (Math.Abs(standValue1 - finalValue1) <= 1); return isEqual; } else if (MeterType == 2) { //全指针 return (standValue * FaConstant.CUBE_VALUE) == finalValue; } else if (MeterType == 3) { //全数字 return (standValue * FaConstant.CUBE_VALUE) == finalValue; } } return isEqual; } public int GetEqualFlag2(string strStandValue,double standValue, long finalValue) { bool isEqual = false; //比较结果值与标准值是否相等 if (MeterType == ResultMeter) { if (MeterType == 1) { //数字+指针(只比较数字部分) //获取真正数据部分的值 int standValue1 = (int)Math.Ceiling(standValue / LastUnit); int finalValue1 = (int)(finalValue / (FaConstant.CUBE_VALUE * LastUnit)); //isEqual = (standValue1 == finalValue1); //判断如何按最后一个单位差1,也认为正确(比如0.1单位,则差0.1是正确的,10单位的,差10也是正确的) //上面的值,也就规划为数字的整数 //isEqual = (Math.Abs(standValue1 - finalValue1) <= 1); //位数长度相同,最后一个的数字字符串差1判定相等 int lastStandNum = standValue1 % 10; int lastFinalNum = finalValue1 % 10; int preStandNum = standValue1 / 10; int preFinalNum = finalValue1 / 10; //前面数字相同,最后一位差1或相同,即判断为相等 if(preFinalNum == preStandNum && Math.Abs(lastFinalNum - lastStandNum) <= 1) { isEqual = true; } return isEqual ? 1 : 0; } else if (MeterType == 2) { //全指针 //数字+指针(只比较数字部分) //获取真正数据部分的值 int standValue1; // = (int)Math.Ceiling(standValue / LastUnit); int finalValue1; // = (int)(finalValue / (FaConstant.CUBE_VALUE * LastUnit)); //isEqual = (standValue1 == finalValue1); //isEqual = (standValue * FaConstant.CUBE_VALUE) == finalValue; /*if(finalValue == 22066060) { Console.WriteLine("测试"); }*/ if (strStandValue.Contains(".")) { //标准值带有小数则全比较 standValue1 = (int)Math.Ceiling(standValue / LastUnit); finalValue1 = (int)(finalValue / (FaConstant.CUBE_VALUE * LastUnit)); isEqual = (Math.Abs(standValue1 - finalValue1) <= 1); } else { //标准值没有小数则只比较整数部分 standValue1 = (int)standValue; finalValue1 = (int)(finalValue / FaConstant.CUBE_VALUE); isEqual = (Math.Abs(standValue1 - finalValue1) <= 1); } return isEqual ? 1 : 0; } else if (MeterType == 3) { //全数字 //return (standValue * FaConstant.CUBE_VALUE) == finalValue; isEqual = (standValue * FaConstant.CUBE_VALUE) == finalValue; return isEqual ? 1 : 0; } else { return 2; } } else { return 2; } } public int GetEqualFlag(double standValue, long finalValue) { bool isEqual = false; //比较结果值与标准值是否相等 if (MeterType == ResultMeter) { if (MeterType == 1 || MeterType == 3) { //数字+指针(只比较数字部分) //获取真正数据部分的值 //int standValue1 = (int)(standValue / LastUnit); //int standValue1 = (int)((long)(standValue * 10000) / (long)(LastUnit * 10000)); int standValue1 = (int)Math.Round(standValue / LastUnit); //(int)Math.Ceiling(standValue / LastUnit); //int finalValue1 = (int)(finalValue / (FaConstant.CUBE_VALUE * LastUnit)); int finalValue1 = (int)Math.Round(finalValue / (FaConstant.CUBE_VALUE * LastUnit)); //isEqual = (standValue1 == finalValue1); //判断如果按最后一个单位差1,也认为正确(比如0.1单位,则差0.1是正确的,10单位的,差10也是正确的) isEqual = (Math.Abs(standValue1 - finalValue1) <= 1); if (isEqual == false && JudgeLastnumFlag == 0) { int standValue1_lastnum = standValue1 % 10; int finalValue1_lastnum = finalValue1 % 10; //上面的值,也就规划为数字的整数 int standValue2 = standValue1 - standValue1_lastnum; int finalValue2 = finalValue1 - finalValue1_lastnum; isEqual = standValue2 == finalValue2; } return isEqual ? 1 : 0; } else if (MeterType == 2) { int standValue1 = (int)standValue; int finalValue1 = (int)(finalValue / FaConstant.CUBE_VALUE); isEqual = (Math.Abs(standValue1 - finalValue1) <= 1); return isEqual ? 1 : 0; } } return 2; } public int GetEqualFlag_http(double standValue, long finalValue) { bool isEqual = false; //if (MeterType == 1 || MeterType == 3) //{ //数字+指针(只比较数字部分) //获取真正数据部分的值 //int standValue1 = (int)(standValue / LastUnit); //int standValue1 = (int)((long)(standValue * 10000) / (long)(LastUnit * 10000)); int standValue1 = (int)Math.Round(standValue / LastUnit); //(int)Math.Ceiling(standValue / LastUnit); //int finalValue1 = (int)(finalValue / (FaConstant.CUBE_VALUE * LastUnit)); int finalValue1 = (int)Math.Round(finalValue / (FaConstant.CUBE_VALUE * LastUnit)); //isEqual = (standValue1 == finalValue1); //判断如果按最后一个单位差1,也认为正确(比如0.1单位,则差0.1是正确的,10单位的,差10也是正确的) isEqual = (Math.Abs(standValue1 - finalValue1) <= 1); if (isEqual == false && JudgeLastnumFlag == 0) { int standValue1_lastnum = standValue1 % 10; int finalValue1_lastnum = finalValue1 % 10; //上面的值,也就规划为数字的整数 int standValue2 = standValue1 - standValue1_lastnum; int finalValue2 = finalValue1 - finalValue1_lastnum; isEqual = standValue2 == finalValue2; } return isEqual ? 1 : 0; //} //else if (MeterType == 2) //{ // int standValue1 = (int)standValue; // int finalValue1 = (int)(finalValue / FaConstant.CUBE_VALUE); // isEqual = (Math.Abs(standValue1 - finalValue1) <= 1); // return isEqual ? 1 : 0; //} //return 2; } //恢复运行时的默认值 public void ResetRunValue() { RunFlag = 0; RunTime = string.Empty; DstImage = string.Empty; ResultMeter = -1; ResultType = 0; RawValue = -1; FinalValue = -1; CompleteValue = -1; ValueChanged = -1; EqualFlag = -1; AiVer = string.Empty; DebugInfo = string.Empty; LogPath = string.Empty; Memo = string.Empty; //说明这条数据是在模板中被配置的数据 //latest_complete=-1,last_compress = 100 LatestComplete = -1; if (LatestTime.Equals(SampleTime)) { LastCompress = 100; } else { LastCompress = -1; LatestValue = -1; LatestTime = string.Empty; } } //---------------------------------------------- } //////////////////////////////////////////////////////////// }