Files
CapMachine/CapMachine.Wpf/Services/DataRecordService.cs

761 lines
38 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 CapMachine.Core;
using CapMachine.Model;
using CapMachine.Model.ModelMapConfig;
using CapMachine.Wpf.ChannelModel;
using CapMachine.Wpf.Models;
using CapMachine.Wpf.PrismEvent;
using CsvHelper;
using CsvHelper.Configuration;
using CsvHelper.Configuration.Attributes;
using FreeSql.Extensions.ZeroEntity;
using Masuit.Tools;
using Newtonsoft.Json;
using NPOI.Util;
using Prism.Events;
using Prism.Mvvm;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Channels;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
namespace CapMachine.Wpf.Services
{
/// <summary>
/// 数据记录服务功能
/// </summary>
public class DataRecordService : BindableBase
{
/// <summary>
/// 实例化函数
/// </summary>
public DataRecordService(MachineRtDataService machineRtDataService, IEventAggregator eventAggregator, ConfigService configService, ILogService logService, IFreeSql FreeSql)
{
MachineRtDataService = machineRtDataService;
ConfigService = configService;
LogService = logService;
this.FreeSql = FreeSql;
//事件服务
_EventAggregator = eventAggregator;
ListRecordModelMap = new List<ModelMap>()
{
////测试用TestTable
//new ModelMap(){
// Name="TestTable",
// Comment="测试Table",
// Columns=new List<Columns>(){
// new Columns(){ Name="Id",MapType="System.Int32",IsIdentity=true,IsPrimary=true},
// new Columns(){ Name="Name",MapType="System.String",IsIdentity=false,IsPrimary=false,StringLength=20},
// new Columns(){ Name="Value",MapType=typeof(decimal).ToString(),IsIdentity=false,IsPrimary=false,Precision=8,Scale=2},
// new Columns(){ Name="IntValue",MapType=typeof(Int16).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="FloatValue",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="Content",MapType="System.String",IsIdentity=false,IsPrimary=false,StringLength=20},
// new Columns(){ Name="CreateTime",MapType="System.DateTime",IsIdentity=false,IsPrimary=false},
// }
//},
//new ModelMap(){
// Name="Record",
// Comment="工况数据记录",
// Columns=new List<Columns>(){
// new Columns(){ Name="Id",MapType="System.Int32",IsIdentity=true,IsPrimary=true},
// new Columns(){ Name="WorkCondName",MapType="System.String",IsIdentity=false,IsPrimary=false,StringLength=20},
// new Columns(){ Name="Speed",MapType=typeof(Int16).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="Cond1Temp",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="Cond2Temp",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="Cond2Press",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="EVAPExpTemp",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="ExPress",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="HVVol",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="InhPress",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="InhTemp",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="LubePress",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="LVVol",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="OCR",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="OS1Temp",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="OS2Temp",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="PTCEntTemp",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="PTCFlow",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="PTCPw",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="EnvRH",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="EnvTemp",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="OutLock",MapType=typeof(bool).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="ParNo",MapType=typeof(Int16).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="Ev",MapType=typeof(Int16).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="CapEnable",MapType=typeof(bool).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="InhExhValve",MapType=typeof(Int16).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="PTCEnable",MapType=typeof(bool).ToString(),IsIdentity=false,IsPrimary=false},
// new Columns(){ Name="CreateTime",MapType="System.DateTime",IsIdentity=false,IsPrimary=false},
// }
//}
new ModelMap(){
Name="Record",
Comment="工况数据记录",
Columns=new List<Columns>(){
new Columns(){ Name="Id",MapType="System.Int64",IsIdentity=true,IsPrimary=true},
new Columns(){ Name="工况",MapType="System.String",IsIdentity=false,IsPrimary=false,StringLength=100},
new Columns(){ Name="转速[rpm]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="排气压力[BarA]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="吸气压力[BarA]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="吸气温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="COND1温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="润滑油压力[BarA]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="COND2压力[BarA]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="OCR[%]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="HV[V]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="HV[A]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="HV[W]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="LV[V]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="LV[A]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="环境温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="环境湿度[%]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="OS1温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="OS2温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="COND2温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="EVAP出口温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="冷媒流量[kg/h]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="润滑油流量[kg/h]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="排气温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="膨胀阀前压力[BarA]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="膨胀阀前温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="EVAP出口压力[BarA]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="腔内压力[BarA]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="压缩机表面温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="PTC流量[L/min]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="PTC入水温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="PTC出水温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="AT04_01[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="AT04_02[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="通讯Cmp母线电流[A]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="通讯Cmp母线电压[V]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="通讯Cmp逆变器温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="通讯Cmp相电流[A]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="通讯Cmp功率[W]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="通讯Cmp芯片温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="通讯PTC入水温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="通讯PTC出水温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="通讯PTC峰值电流[A]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="通讯PTC母线电流[A]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="通讯PTC膜温[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="通讯PTC模块温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="液冷媒流量[kg/h]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="干度流量[kg/h]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="H5吸气混合器温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="COND循环水温[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="SUBCOOL出口温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="吸气混合器出口温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="H1出口温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="S.C循环水温[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="EVAP循环水温[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="吸气混合器出口压力[BarA]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="气路阀前压力[BarA]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="气路阀前温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="干度[%]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="过冷度[K]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="过热度[K]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="制热量Qh[W]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="压缩机性能系数(制热)",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="等熵效率ns[%]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="制冷量Qc[W]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="压缩机性能系数(制冷)",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="容积效率nv[%]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="创建时间",MapType="System.DateTime",IsIdentity=false,IsPrimary=false},
}
}
};
ListRecordKeyValue = new List<RecordKeyValue>()
{
new RecordKeyValue(){
TableName="TestTable",
KeyValuePairs=new Dictionary<string, object>(){
{ "Name", "testName" },
{ "Content", "user1deContentss" },
{ "Value", 3.4 },
{ "IntValue", 23 },
{ "FloatValue", 3.569 },
{ "CreateTime", DateTime.Now.ToString() },
}
},
};
var JsonModelMap = JsonConvert.SerializeObject(ListRecordModelMap);
//秒触发一次
CycleTimer = new System.Timers.Timer(ConfigService.RecordCycle);
CycleTimer.Elapsed += RecoredCycleAction;
CycleTimer.AutoReset = true;
CycleTimer.Enabled = true;
//var json = "[\r\n {\r\n \"Name\":\"User\",\r\n \"Comment\":\"用户表\",\r\n \"Columns\": [\r\n {\"Name\":\"Id\",\"IsPrimary\":true,\"IsIdentity\":true,\"MapType\":\"System.Int32\"},\r\n {\"Name\":\"Name\",\"MapType\":\"System.String\"}\r\n ],\r\n \"Navigates\":[\r\n {\"Name\":\"Ext\",\"Type\":\"OneToOne\",\"RelTable\":\"UserExt\"},\r\n {\"Name\":\"Claims\",\"Type\":\"OneToMany\",\"RelTable\":\"UserClaim\",\"Bind\":\"UserId\"},\r\n {\"Name\":\"Roles\",\"Type\":\"ManyToMany\",\"RelTable\":\"Role\",\"ManyToMany\":\"UserRole\"}\r\n ],\r\n \"Indexes\":[]\r\n },\r\n {\r\n \"Name\":\"UserExt\",\r\n \"Comment\":\"用户扩展信息表\",\r\n \"Columns\":[\r\n {\"Name\":\"UserId\",\"IsPrimary\":true,\"MapType\":\"System.Int32\"},\r\n ],\r\n \"Navigates\":[\r\n {\"Name\":\"Remarks\",\"Type\":\"OneToMany\",\"RelTable\":\"UserExtRemarks\",\"Bind\":\"UserId\"},\r\n ],\r\n },\r\n {\r\n \"Name\":\"UserExtRemarks\",\r\n \"Comment\":\"用户扩展信息表-子表\",\r\n \"Columns\":[\r\n {\"Name\":\"RemarkId\",\"IsPrimary\":true,\"MapType\":\"System.Guid\"},\r\n {\"Name\":\"UserId\",\"MapType\":\"System.Int32\"},\r\n {\"Name\":\"Remark\",\"MapType\":\"System.String\"},\r\n ],\r\n },\r\n {\r\n \"Name\":\"UserClaim\",\r\n \"Comment\":\"一对多测试表\",\r\n \"Columns\":[\r\n {\"Name\":\"Id\",\"IsPrimary\":true,\"IsIdentity\":true,\"MapType\":\"System.Int32\"},\r\n {\"Name\":\"UserId\",\"MapType\":\"System.Int32\"},\r\n {\"Name\":\"ClaimName\",\"MapType\":\"System.String\"},\r\n ],\r\n },\r\n {\r\n \"Name\":\"Role\",\r\n \"Comment\":\"权限表\",\r\n \"Columns\":[\r\n {\"Name\":\"Id\",\"IsPrimary\":true,\"IsIdentity\":true,\"MapType\":\"System.Int32\"},\r\n {\"Name\":\"Name\",\"MapType\":\"System.String\"}\r\n ],\r\n \"Navigates\":[\r\n {\"Name\":\"Users\",\"Type\":\"ManyToMany\",\"RelTable\":\"User\",\"ManyToMany\":\"UserRole\"}\r\n ],\r\n \"Indexes\":[]\r\n },\r\n {\r\n \"Name\":\"UserRole\",\r\n \"Comment\":\"多对多中间表\",\r\n \"Columns\":[\r\n {\"Name\":\"UserId\",\"IsPrimary\":true,\"MapType\":\"System.Int32\"},\r\n {\"Name\":\"RoleId\",\"IsPrimary\":true,\"MapType\":\"System.Int32\"}\r\n ],\r\n \"Navigates\":[\r\n {\"Name\":\"User\",\"Type\":\"ManyToOne\",\"RelTable\":\"User\",\"Bind\":\"UserId\"},\r\n {\"Name\":\"Role\",\"Type\":\"ManyToOne\",\"RelTable\":\"Role\",\"Bind\":\"RoleId\"}\r\n ]\r\n }\r\n]\r\n";
//zeroDbContext = new ZeroDbContext(this.FreeSql, JsonConvert.DeserializeObject<TableDescriptor[]>(JsonModelMap)); //在文档后面
//var item = JsonConvert.DeserializeObject<Dictionary<string, object>>(@"
// {
// //""Id"":1,
// ""Name"":""user1"",
// ""Content"":""user1deContent"",
// ""Value"":3.4,
// ""IntValue"":23,
// ""FloatValue"":3.569,
// ""CreateTime"":""2024-09-30 11:47"",
// }");
//插入数据
//zeroDbContext.Insert(ListRecordKeyValue.Find(a => a.TableName == "TestTable")!.KeyValuePairs);
//var dd = FreeSql.InsertDict(new Dictionary<string, object>()
//{
// { "Name", "PC" },
// { "Mark", "dds" },
// { "Price", 1000 },
// { "CreateTime", DateTime.Now },
//}).AsTable("RecordData").ExecuteAffrows();
//实时数据记录管道数据监听
Task.Run(() => ListenRecoredChannelAction());
}
/// <summary>
/// 事件聚合器
/// </summary>
private IEventAggregator _EventAggregator { get; set; }
/// <summary>
/// DbContext信息
/// </summary>
private ZeroDbContext zeroDbContext { get; set; }
/// <summary>
/// 数据记录字段模型
/// 定义表名称
/// 定义表字段的信息
/// 定义主外键的表的关系
/// </summary>
public List<ModelMap> ListRecordModelMap { get; set; }
/// <summary>
/// 要记录的每个表格的键值对数据
/// </summary>
public List<RecordKeyValue> ListRecordKeyValue { get; set; }
/// <summary>
/// 周期定时器
/// </summary>
private System.Timers.Timer CycleTimer { get; set; }
private bool _IsRecord;
/// <summary>
/// 是否记录
/// </summary>
public bool IsRecord
{
get { return _IsRecord; }
set { _IsRecord = value; RaisePropertyChanged(); }
}
/// <summary>
/// 设备实时数据功能服务
/// </summary>
public MachineRtDataService MachineRtDataService { get; }
/// <summary>
/// 配置功能服务
/// </summary>
public ConfigService ConfigService { get; }
public ILogService LogService { get; }
public IFreeSql FreeSql { get; }
#region
/// <summary>
/// 队列通道
/// 当前队列消费周期触发的数据记录
/// </summary>
public Channel<RecordChannelData> RecoredChannelInfo = Channel.CreateUnbounded<RecordChannelData>(new UnboundedChannelOptions()
{
SingleWriter = false,//允许一次写入多条数据
SingleReader = true //一次只能读取一条消息
});
/// <summary>
/// 缓存的集合数据
/// </summary>
public List<RecordChannelData> CacheRecordData { get; set; } = new List<RecordChannelData>();
/// <summary>
/// 当前缓存的队列信息
/// 高效的队列数据
/// </summary>
public ConcurrentQueue<RecordChannelData> ConcurrentQueueData { get; set; } = new ConcurrentQueue<RecordChannelData>();
/// <summary>
/// 最大的缓存单元数据
/// 存储超过规定60个缓存数据后进行判断后删除
/// </summary>
private int MaxCacheCellCount { get; set; } = 0;
/// <summary>
/// 数据记录管道监听方法
/// </summary>
/// <exception cref="NotImplementedException"></exception>
private async void ListenRecoredChannelAction()
{
while (await RecoredChannelInfo.Reader.WaitToReadAsync())
{
if (RecoredChannelInfo.Reader.TryRead(out var recordChannelData))
{
try
{
////第一次计时
//stopwatch.Start(); //启动Stopwatch
//新增数据
CacheRecordData.Add(recordChannelData);
MaxCacheCellCount++;
//先判断缓存的单元大小,防止每次都检查删除,数据达到时间范围外的话,则删除,即是600次后进行一次判断删除
if (MaxCacheCellCount >= 600)
{
//不在缓存的时间范围内的话,则删除数据
if (CacheRecordData.Where(a => a.CreateTime <= DateTime.Now.AddSeconds(-ConfigService.ChartRtDataCacheTimeSec)).Any())
{
CacheRecordData.RemoveAll(a => a.CreateTime <= DateTime.Now.AddSeconds(-ConfigService.ChartRtDataCacheTimeSec));
}
MaxCacheCellCount = 0;
}
//ConcurrentQueueData.
//Prism发布数据
_EventAggregator.GetEvent<RecordDataEvent>().Publish(recordChannelData.DeepClone());
//判断集合的数据是否达到要求
//if (CacheRecordData.Count >= MaxCacheCount)
//{
//CacheRecordData可能存在多个表格数据依据表名进行分类
//考虑多个表结构
//var GroupTableData = CacheRecordData.GroupBy(a => a.TableName).ToList();
//foreach (var ItemData in GroupTableData)
//{
//表名称
//var TableName = ItemData.Key;
//当前表格的数据
//var Datas = ItemData.Select(item => item.Data).ToList();
//var Datas = recordChannelData.Select(item => item.Data).ToList();
//List<CsvRecordModel> models = Datas.Select(dict => ConvertToCsvRecordModel(dict)).ToList();
//转换到CSV的数据
var models = ConvertToCsvRecordModel(recordChannelData.Data);
//填充工况名称
models.WorkCond = ConfigService.CurExpInfo.Name;
//数据库保存
//zeroDbContext.Insert(Datas);
//CSV文件保存
SaveToCsv(new List<CsvRecordModel>() { models });
//}
//CacheRecordData.Clear();
//Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss:fff")}-{LineName}-保存成功!");
//}
//stopwatch.Stop(); //停止Stopwatch
//Console.WriteLine("保存数据耗时::{0}", stopwatch.Elapsed.TotalSeconds.ToString());
//stopwatch.Reset();
}
catch (Exception ex)
{
LogService.Error(ex.Message);
}
}
}
}
/// <summary>
/// 转换到CsvRecordModel
/// </summary>
/// <param name="dict"></param>
/// <returns></returns>
public static CsvRecordModel ConvertToCsvRecordModel(Dictionary<string, object> dict)
{
CsvRecordModel model = new CsvRecordModel();
foreach (var kvp in dict)
{
//var property = typeof(CsvRecordModel).GetProperty(kvp.Key);
var property = GetPropertyByName(kvp.Key);
if (property != null && kvp.Value != null)
{
property.SetValue(model, Convert.ChangeType(kvp.Value, property.PropertyType));
}
}
//增加日期和时间两个列
model.WorkDay = model.CreateTime.ToString("yyyy-MM-dd");
model.Time = model.CreateTime.ToString("HH:mm:ss");
return model;
}
/// <summary>
/// 获取属性的名称
/// [Name("通讯PTC出水温度")] 获取其名称
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
private static PropertyInfo GetPropertyByName(string name)
{
var properties = typeof(CsvRecordModel).GetProperties();
foreach (var property in properties)
{
var attr = property.GetCustomAttribute<Models.NameAttribute>();
if (attr != null && attr.Name == name)
{
return property;
}
}
return null;
}
#endregion
private Random Random = new Random();
private int Add = 1;
Stopwatch stopwatch = new Stopwatch();
/// <summary>
/// 记录周期内容
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <exception cref="NotImplementedException"></exception>
private void RecoredCycleAction(object? sender, ElapsedEventArgs e)
{
try
{
//如果Execute执行的是一个很耗时的方法会导致方法未执行完毕定时器又启动了一个线程来执行Execute方法
//CycleTimer.Stop(); //先关闭定时器
var DataInfo = MachineRtDataService.TagManger.DicTags
//.ToDictionary(kvp => kvp.Key, kvp => (object)MachineRtDataService.TagManger.TryGetRecordPVValue(kvp.Value.Name));
.ToDictionary(kvp => kvp.Key, kvp => (object)MachineRtDataService.TagManger.TryGetRecordPVValue(kvp.Key));
DataInfo.Add("创建时间", DateTime.Now);
var RecordData = new RecordChannelData()
{
CreateTime = DateTime.Now,
TableName = "",
Data = DataInfo
};
if (IsRecord)
{
//本体数据记录
RecoredChannelInfo.Writer.WriteAsync(RecordData);
}
//CycleTimer.Start(); //执行完毕后再开启器
}
catch (Exception ex)
{
//CycleTimer.Start(); //执行完毕后再开启器
LogService.Error($"时间:{DateTime.Now.ToString()}-【RecoredCycleAction】-{ex.Message}");
}
}
#region
/// <summary>
/// 创建 ModelMappTable
/// </summary>
/// <param name="TableName"></param>
/// <returns></returns>
private ModelMap CreateModelMappTable(string TableName)
{
var NewTable = new ModelMap()
{
Name = TableName,
Comment = TableName,
Columns = new List<Columns>(),
};
//新增到数据库中
var NewModelMap = FreeSql.Insert<ModelMap>(NewTable).ExecuteInserted();
return NewModelMap.FirstOrDefault()!;
}
/// <summary>
/// 增加字符串列
/// </summary>
/// <param name="Name"></param>
/// <param name="MapType"></param>
/// <param name="IsPrimary"></param>
/// <param name="IsIdentity"></param>
/// <returns></returns>
private Columns CreateStringColumn(string Name, string MapType, short StringLength, bool IsPrimary, bool IsIdentity)
{
return new Columns()
{
Name = Name,
MapType = MapType,
IsIdentity = IsIdentity,
StringLength = StringLength,
IsPrimary = IsPrimary,
};
}
/// <summary>
/// 增加IntFloatBool列
/// </summary>
/// <param name="Name"></param>
/// <param name="MapType"></param>
/// <param name="IsPrimary"></param>
/// <param name="IsIdentity"></param>
/// <returns></returns>
private Columns CreateIntFloatBoolColumn(string Name, string MapType, bool IsPrimary, bool IsIdentity)
{
return new Columns()
{
Name = Name,
MapType = MapType,
IsIdentity = IsIdentity,
IsPrimary = IsPrimary,
};
}
/// <summary>
/// 增加DateTime列
/// </summary>
/// <param name="Name"></param>
/// <param name="MapType"></param>
/// <param name="IsPrimary"></param>
/// <param name="IsIdentity"></param>
/// <returns></returns>
private Columns CreateDateTimeColumn(string Name, string MapType, bool IsPrimary, bool IsIdentity)
{
return new Columns()
{
Name = Name,
MapType = MapType,
IsIdentity = IsIdentity,
IsPrimary = IsPrimary,
};
}
/// <summary>
/// 增加Decimal列
/// </summary>
/// <param name="Name"></param>
/// <param name="MapType"></param>
/// <param name="IsPrimary"></param>
/// <param name="IsIdentity"></param>
/// <returns></returns>
private Columns CreateDecimalColumn(string Name, string MapType, short Precision, short Scale, bool IsPrimary, bool IsIdentity)
{
return new Columns()
{
Name = Name,
MapType = MapType,
IsIdentity = IsIdentity,
IsPrimary = IsPrimary,
Precision = Precision,
Scale = Scale,
};
}
#endregion
/// <summary>
/// 开始运行或者开始记录
/// </summary>
public void StartRecord()
{
//首先清除清除本地试验工况缓存的数据
CacheRecordData.Clear();
if (ConfigService.CurExpInfo != null)
{
//判断是否已经有了当前的试验工况信息
var ExisData = FreeSql.Select<HistoryExp>().Where(a => a.Name == ConfigService.CurExpInfo.Name).IncludeMany(a => a.HistoryWorkCondFiles);
if (ExisData.Count() > 0)
{
ConfigService.CurExpInfo = ExisData.First()!;
}
IsRecord = true;
//var RecordHistoryExp = FreeSql.Insert<HistoryExp>(new HistoryExp()
//{
// Name = "试验测试工况",
// WorkCond = "测试工况",
//}).ExecuteInserted();
//if (RecordHistoryExp != null)
//{
// ConfigService.CurExpInfo = RecordHistoryExp.FirstOrDefault()!;
//}
}
else
{
IsRecord = false;
MessageBox.Show("当前试验信息未填写,无法开始记录数据", "提示", MessageBoxButton.OK, MessageBoxImage.Hand);
}
}
/// <summary>
/// 结束记录数据
/// </summary>
public void EndRecord()
{
IsRecord = false;
//不可以清除清除本地试验工况缓存的数据,因为可能实时数据会分析使用 //CacheRecordData.Clear();
if (ConfigService.CurExpInfo != null)
{
var ListUpdate = FreeSql.Update<HistoryExp>()
.Set(a => a.IsComplete, true)
.Where(a => a.Id == ConfigService.CurExpInfo.Id)
.ExecuteUpdated();
ConfigService.CurExpInfo = ListUpdate.FirstOrDefault()!;
}
}
/// <summary>
/// 更新当前的试验信息
/// </summary>
private void CreateUpdateCurHistoryExp(string Name, string FileFullInfo)
{
var RecordHistoryExp = FreeSql.Insert<HistoryWorkCondFile>(new HistoryWorkCondFile()
{
WorkDay = DateTime.Now.ToString("yyyy-MM-dd"),
FilePath = FileFullInfo,
HistoryExpId = ConfigService.CurExpInfo.Id,
}).ExecuteInserted();
//更新数据
ConfigService.CurExpInfo = FreeSql.Select<HistoryExp>().Where(a => a.Name == Name).IncludeMany(a => a.HistoryWorkCondFiles).First();
}
#region CSV Helper CSV
/// <summary>
/// CSV文件保存根路径
/// </summary>
private string SaveCsvRootPath { get; set; }
/// <summary>
/// Append to the file.
/// </summary>
CsvConfiguration CSVconfig { get; set; } = new CsvConfiguration(CultureInfo.CurrentCulture)
{
// Don't write the header again.
HasHeaderRecord = false,
};
/// <summary>
/// 保存到CSV文件
/// </summary>
private void SaveToCsv(List<CsvRecordModel> csvRecordModels)
{
//年份的文件是否存在
var FilePath = FileHelper.GetExpFilePath(ConfigService.SaveCsvRootPath, ConfigService.CurExpInfo.Name);
if (!Directory.Exists(FilePath))
{
Directory.CreateDirectory(FilePath);
}
//文件全部路径信息
var FileFullInfo = FileHelper.GetCSVPath(FilePath);
if (!File.Exists(FileFullInfo))//是否存在文件
{
lock (ConfigService.CsvFileLock)
{
//新增的文件
using (var writer = new StreamWriter(FileFullInfo, false, Encoding.UTF8))
using (var csv = new CsvWriter(writer, CultureInfo.CurrentCulture))
{
var Result = csv.Context.RegisterClassMap<CsvRecordModelMap>();
csv.WriteRecords(csvRecordModels);
}
}
//创建和更新当前试验信息
CreateUpdateCurHistoryExp(ConfigService.CurExpInfo.Name, FileFullInfo);
}
else//存在文件的话则新增数据
{
lock (ConfigService.CsvFileLock)
{
//往已有的文件增加数据
using (var stream = File.Open(FileFullInfo, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
//using (var stream = new FileStream(FileFullInfo, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
using (var writer = new StreamWriter(stream))
using (var csv = new CsvWriter(writer, CSVconfig))
{
csv.Context.RegisterClassMap<CsvRecordModelMap>();
csv.WriteRecords(csvRecordModels);
}
}
}
}
#endregion
}
}