2025-06-03 23:01:46 +08:00

183 lines
8.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using JiShe.CollectBus.Common.Enums;
using JiShe.CollectBus.Protocol.Contracts.Protocol.Dto;
using JiShe.CollectBus.Protocol.Contracts;
using JiShe.CollectBus.Protocol.Dto;
using JiShe.CollectBus.Protocol.Interfaces;
using JiShe.CollectBus.Protocol3761;
using Microsoft.Extensions.Logging;
using JiShe.CollectBus.Protocol.T37612012.Appendix;
using JiShe.CollectBus.Common.Extensions;
using AutoMapper.Internal.Mappers;
using JiShe.CollectBus.IotSystems.Ammeters;
using JiShe.CollectBus.Common.Helpers;
using JiShe.CollectBus.Common.Consts;
using JiShe.CollectBus.IotSystems.Devices;
using System.Collections.Generic;
namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_0DH
{
/// <summary>
/// 5.13.2.4.4 F4日冻结反向有/无功最大需量及发生时间(总、费率 1M1≤M≤12
/// </summary>
public class AFN13_F4_Analysis : IAnalysisStrategy<TB3761>
{
private readonly ILogger<AFN13_F4_Analysis> _logger;
private readonly AnalysisStrategyContext _analysisStrategyContext;
private readonly DataStorage _dataStorage;
public AFN13_F4_Analysis(ILogger<AFN13_F4_Analysis> logger, AnalysisStrategyContext analysisStrategyContext, DataStorage dataStorage)
{
_logger = logger;
_analysisStrategyContext = analysisStrategyContext;
_dataStorage = dataStorage;
}
public async Task<bool> ExecuteAsync(TB3761 input, Action<dynamic>? result = null)
{
try
{
ArgumentNullException.ThrowIfNull(input);
ArgumentNullException.ThrowIfNull(input.A.Code);
ArgumentNullException.ThrowIfNull(input.UnitData?.HexMessageList);
List<string> datas = await AnalysisDataUnitAsync(input.UnitData.HexMessageList);
string dataType = $"{input.AFN_FC.AFN.HexToDecStr().PadLeft(2, '0')}_{input.DT.Fn}";
//冻结数据时标
var time = $"{datas[0].Substring(0, 4)}-{datas[0].Substring(4, 2)}-{datas[0].Substring(6, 2)} 00:00:00";
List<AnalysisBaseDto<decimal?>> list = GenerateFinalResult(datas, dataType, "日冻结反向有/无功最大需量及发生时间");
if (list.Count > 0)
{
// 查询设备信息
DeviceCacheInfo? deviceInfo = await _dataStorage.GetDeviceInfoAsync(input.A.Code, input.DA.Pn);
if (deviceInfo != null)
{
list.ForEach(item =>
{
item.ProjectId = deviceInfo.ProjectId;
item.DeviceId = deviceInfo.MeterId;
item.DatabaseBusiID = deviceInfo.DatabaseBusiID;
item.DeviceAddress = deviceInfo.MeterAddress;
item.FocusId = deviceInfo.FocusId;
});
}
}
UnitDataAnalysis<List<AnalysisBaseDto<decimal?>>> unitDataAnalysis = new UnitDataAnalysis<List<AnalysisBaseDto<decimal?>>>
{
Code = input.A.Code!,
AFN = input.AFN_FC.AFN,
Fn = input.DT.Fn,
Pn = input.DA.Pn,
MSA = input.A.A3!.D1_D7!,
PSEQ = input.SEQ.PSEQ,
Data = list,
ReceivedHexMessage = input.BaseHexMessage.HexMessageString,
MessageId = input.MessageId,
TimeDensity = 1,//密度-间隔,
DensityUnit = DensityUnit.Day,
ReceivedTime = input.ReceivedTime,
DataType = IOTDBDataTypeConst.Data,
};
await _dataStorage.SaveMultipleDataToIotDbAsync<decimal?>(unitDataAnalysis);
result?.Invoke(unitDataAnalysis);
return await Task.FromResult(true);
}
catch (Exception ex)
{
_logger.LogError(ex, $"0D_4解析失败:{input.A.Code}-{input.DT.Fn}-{input.BaseHexMessage.HexMessageString},{ex.Message}");
return await Task.FromResult(false);
}
}
private async Task<List<string>> AnalysisDataUnitAsync(List<string> hexMessageList)
{
List<string> values = new List<string>
{
hexMessageList.GetReadTime(4, 3),//日冻结类数据时标 Td_d
hexMessageList.GetReadTime(7, 5)//终端抄表时间
};
int ratingCount = hexMessageList.GetRatingCount(12, 1);//费率数 M1≤M≤12
values.Add(ratingCount.ToString());
int handlerNum = 13;
values.AddRange(await GetDataAsync(hexMessageList.GetRange(handlerNum, 3 * (ratingCount + 1)), ratingCount, 3, nameof(Appendix_A23)));//正向有功总最大需量
handlerNum += 3 * (ratingCount + 1);//12
values.AddRange(await GetDataAsync(hexMessageList.GetRange(handlerNum, 4 * (ratingCount + 1)), ratingCount, 4, nameof(Appendix_A17)));//正向有功总最大需量发生时间
handlerNum += 4 * (ratingCount + 1);//28
values.AddRange(await GetDataAsync(hexMessageList.GetRange(handlerNum, 3 * (ratingCount + 1)), ratingCount, 3, nameof(Appendix_A23)));//正向无功总最大需量
handlerNum += 3 * (ratingCount + 1);//48
values.AddRange(await GetDataAsync(hexMessageList.GetRange(handlerNum, 4 * (ratingCount + 1)), ratingCount, 4, nameof(Appendix_A17)));//正向无功总最大需量发生时间
handlerNum += 4 * (ratingCount + 1);
return values;
}
private async Task<List<string>> GetDataAsync(List<string> data, int ratingCount, int len, string appendixName)
{
List<string> values = new List<string>();
for (int i = 0; i < ratingCount + 1; i++)
{
var arr = data.GetRange(0 + (i * len), len);
var errorCode = arr.CheckErrorCode();
if (errorCode != null)
values.Add(errorCode.Item1);
else
{
await _analysisStrategyContext.ExecuteAsync<List<string>>(appendixName, arr, (value) =>
{
values.Add(value.ToString());
});
}
}
return values;
}
public List<AnalysisBaseDto<decimal?>> GenerateFinalResult(List<string> data,string dataType, string filedDesc = "")
{
List<AnalysisBaseDto<decimal?>> list = new List<AnalysisBaseDto<decimal?>>();
int fCount = Convert.ToInt32(data[2]) + 1;
for (int i = 1; i <= 2; i++)
{
AnalysisBaseDto<decimal?> meter = new AnalysisBaseDto<decimal?>
{
DeviceType = MeterTypeEnum.Ammeter
};
int startIndex = i == 1 ? 3 : (3 + i * fCount);
var errorCode = data[startIndex].CheckErrorCode();
if (errorCode != null)
{
meter.ValidData = false;
meter.ErrorCodeMsg = errorCode.Item2;
}
if(decimal.TryParse(data[startIndex], out decimal value))
meter.DataValue = value;
//TODO:日冻结类数据时标Td
var dataTime = string.Empty;
errorCode = data[0].CheckErrorCode();
if (data[0].Length == 8 && errorCode is null)
dataTime = $"{data[0].Substring(0, 4)}-{data[0].Substring(4, 2)}-{data[0].Substring(6, 2)} 00:00:00";
if (!DateTime.TryParse(dataTime, out DateTime readingDate))
meter.ValidData = false;
else
meter.TimeSpan = readingDate;
//TODO:最大需量发生时间
errorCode = data[startIndex + fCount].CheckErrorCode();
if (errorCode != null && data[startIndex + fCount].Length != 8)
meter.ValidData = false;
else
{
string timeSpan = $"{data[0].Substring(0, 4)}-{data[startIndex + fCount].Substring(0, 2)}-{data[startIndex + fCount].Substring(2, 2)} {data[startIndex + fCount].Substring(4, 2)}:{data[startIndex + fCount].Substring(6, 2)}:00";
if (!DateTime.TryParse(timeSpan, out DateTime tsField))
meter.ValidData = false;
else
meter.TimeSpan = tsField;
}
meter.ItemType = i == 1 ? dataType : $"{dataType}_{ i - 1}";
filedDesc = i == 1 ? filedDesc : filedDesc.Replace("有功", "无功");
meter.FiledDesc = filedDesc;
meter.FiledName = meter.ItemType.GetDataFieldByGatherDataType() ?? string.Empty;
list.Add(meter);
}
return list;
}
}
}