Files
HTCoreServiceApp/HTCoreServiceApp/DataHandle/DataExtractMB.cs

234 lines
9.2 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 System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HTCoreServiceApp.Common;
using HTCoreServiceApp.Models;
using HTCoreServiceApp.Communicate.ModbusTcp;
using System.Collections;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Reflection;
using HTCoreServiceApp.WebApi;
namespace HTCoreServiceApp.DataHandle
{
public class DataExtractMB
{
public static async void DataExtractCAsync(List<MetaTag> metaTags, string systenName, string groupName, string driverName, int[] bytes, AddressArg addressArg)
{
string res = await DataExtractConsecutive(metaTags, systenName, groupName, driverName, bytes, addressArg);
}
public static async void DataExtractCAsync(List<MetaTag> metaTags, string systenName, string groupName, string driverName, int[] bytes, AddressArg addressArg, ScanTagsPara scanTagsPara)
{
string res = await DataExtractConsecutive(metaTags, systenName, groupName, driverName, bytes, addressArg, scanTagsPara);
}
public static Task<string> DataExtractConsecutive(List<MetaTag> metaTags, string systenName, string groupName, string driverName, int[] bytes, AddressArg addressArg)
{
return DataExtractConsecutive(metaTags, systenName, groupName, driverName, bytes, addressArg, null);
}
public static Task<string> DataExtractConsecutive(List<MetaTag> metaTags, string systenName, string groupName, string driverName, int[] bytes, AddressArg addressArg, ScanTagsPara scanTagsPara)
{
return Task.Run(() =>
{
long hdatetime = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds();
List<MetaTagValue> listMetaTagValue = new List<MetaTagValue>();
try
{
//CodingTools.StartTime = DateTime.Now.Millisecond;//de
foreach (MetaTag metaTag in metaTags)
{
short datatype = metaTag.DataType;
MetaTagValue metaTagValue = PCAutoCopy(metaTag);
switch (datatype)
{
case (short)DataType.FLOAT:
metaTagValue.TagValue = GetVlaue(datatype, metaTag.Address, bytes, addressArg);
break;
case (short)DataType.BOOL:
metaTagValue.TagValue = GetVlaue(datatype, metaTag.Address, bytes, addressArg);
break;
case (short)DataType.INT:
metaTagValue.TagValue = GetVlaue(datatype, metaTag.Address, bytes, addressArg);
break;
case (short)DataType.WORD:
metaTagValue.TagValue = GetVlaue(datatype, metaTag.Address, bytes, addressArg);
break;
}
listMetaTagValue.Add(metaTagValue);
}
//CodingTools.EndTime = DateTime.Now.Millisecond;//de
//var timess = (CodingTools.EndTime - CodingTools.StartTime).ToString();
//Console.WriteLine($"转换耗时:{timess}");
//Console.WriteLine(string.Join(",", (Array)listMetaTagValue.ToArray()) + "字节数据转换完成" + ",数据量:" + listMetaTagValue.Count.ToString());
//异步缓存 - 始终执行,用于实时数据更新
Task.Run(()=>
DataLiving.DataLive2CaChe(listMetaTagValue, driverName, groupName)
);
//异步储存 - 根据存储周期控制是否执行
bool shouldStore = true;
if (scanTagsPara != null)
{
shouldStore = CheckStorageTiming(scanTagsPara, hdatetime);
}
if (shouldStore)
{
Task.Run(() =>
DataStorage.DataSave2DB(listMetaTagValue, systenName, driverName, groupName, hdatetime)
);
Console.WriteLine($"{driverName}_{groupName}执行数据存储");
}
else
{
Console.WriteLine($"{driverName}_{groupName}跳过数据存储(未到存储周期)");
}
return "0";
}
catch (Exception ex)
{
return "1";
}
});
}
/// <summary>
/// 检查是否到达存储周期
/// 每一秒unix时间戳的每一秒内必须触发一次存储
/// </summary>
/// <param name="scanTagsPara">扫描参数</param>
/// <param name="currentTime">当前时间戳</param>
/// <returns>是否应该执行存储</returns>
private static bool CheckStorageTiming(ScanTagsPara scanTagsPara, long currentTime)
{
// 获取当前时间戳的秒数(去掉毫秒部分)
long currentSecond = currentTime / 1000;
// 如果是第一次执行,直接存储
if (scanTagsPara.LastStorageTime == 0)
{
scanTagsPara.LastStorageTime = currentTime;
return true;
}
// 获取上次存储时间的秒数(去掉毫秒部分)
long lastStorageSecond = scanTagsPara.LastStorageTime / 1000;
// 如果当前秒数大于上次存储的秒数,说明已经进入新的一秒,需要执行存储
if (currentSecond > lastStorageSecond)
{
scanTagsPara.LastStorageTime = currentTime;
return true;
}
return false;
}
/// <summary>
/// 父类的value赋值给子类
/// </summary>
/// <param name="parent"></param>
/// <returns></returns>
private static MetaTagValue PCAutoCopy(MetaTag parent)
{
MetaTagValue child = new MetaTagValue();
var ParentType = typeof(MetaTag);
var Properties = ParentType.GetProperties();
foreach (var Propertie in Properties)
{
if (Propertie.CanRead && Propertie.CanWrite)
{
Propertie.SetValue(child, Propertie.GetValue(parent, null), null);
}
}
return child;
//listMetaTagValue.Add(new MetaTagValue()
//{
// TagId = metaTag.TagId,
// TagName = metaTag.TagName,
// DataType = metaTag.DataType,
// DataSize = metaTag.DataSize,
// Address = metaTag.Address,
// GroupId = metaTag.GroupId,
// IsActive = metaTag.IsActive,
// Archive = metaTag.Archive,
// DefaultValue = metaTag.DefaultValue,
// Description = metaTag.Description,
// Maximum = metaTag.Maximum,
// Minimum = metaTag.Minimum,
// Cycle = metaTag.Cycle,
//});
}
private static string GetVlaue(short dataType, string address, int[] bytes, AddressArg addressArg)
{
string val = "";
string startaddress = Regex.Replace(address, "[a-z]", "", RegexOptions.IgnoreCase);
int address_dem = 0;
int address_int = 0;
if (startaddress.Contains(".") && startaddress.Length > 2)
{
try
{
string[] address_arr = startaddress.Split('.');
address_int = int.Parse(address_arr[0]) - addressArg.AddressOffset;
address_dem = int.Parse(address_arr[1]);
}
catch (Exception exp)
{
//logger
}
}
else
{
address_int = int.Parse(startaddress) - addressArg.AddressOffset;
}
switch (dataType)
{
case (short)DataType.FLOAT:
return ModbusClient.ConvertRegistersToFloat(new int[] { bytes[address_int] , bytes[address_int + 1] }).ToString("0.########");
case (short)DataType.BOOL:
int[] Mask = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200,0x400,0x800,0x1000,0x2000,0x4000,0x8000};
if (address_dem < 0) address_dem = 0;
if (address_dem > 15) address_dem = 15;
return ((bytes[address_int] & Mask[address_dem]) != 0).ToString();
case (short)DataType.INT:
return ModbusClient.ConvertRegistersToInt(new int[] { bytes[address_int]}).ToString();
//case (short)DataType.WORD:
// return ModbusClient.ConvertRegistersToInt(bytes, address_int).ToString();
}
return val;
}
}
}