This commit is contained in:
2024-12-18 15:50:21 +08:00
parent 684973e6b7
commit b2c54119ea
214 changed files with 65908 additions and 8461 deletions

View File

@@ -0,0 +1,27 @@
using CapMachine.Wpf.CanDrive;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CapMachine.Wpf.Services
{
/// <summary>
/// Can驱动服务
/// </summary>
public class CanDriveService:BindableBase
{
public CanDriveService()
{
ToomossCanDrive=new ToomossCanFD();
//ToomossCanDrive.StartCanDrive();
}
/// <summary>
/// ToomossCanDrive
/// </summary>
public ToomossCanFD ToomossCanDrive { get; set; }
}
}

View File

@@ -1,20 +1,84 @@
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CapMachine.Model;
using CapMachine.Wpf.Dtos;
using Prism.Mvvm;
namespace CapMachine.Wpf.Services
{
/// <summary>
/// 配置服务中心
/// 状态中心
/// </summary>
public class ConfigService:BindableBase
public class ConfigService : BindableBase
{
public ConfigService()
{
CurUserDto = new UserDto();
}
/// <summary>
/// Csv文件锁
/// 防止同时读取数据
/// </summary>
public static readonly object CsvFileLock = new object();
/// <summary>
/// 记录周期
/// </summary>
public short RecordCycle { get; set; } = 1000;
/// <summary>
/// 是否开始记录数据
/// </summary>
public bool IsRecord { get; set; } = false;
/// <summary>
/// SCV保存的根路径
/// </summary>
public string SaveCsvRootPath { get; set; } = "D:\\TestData";
/// <summary>
/// 实时曲线数据缓存的时间(秒)
/// </summary>
public int ChartRtDataCacheTimeSec { get; set; } = 3600_8;
private HistoryExp _CurExpInfo;
/// <summary>
/// 当前的试验信息
/// </summary>
public HistoryExp CurExpInfo
{
get { return _CurExpInfo; }
set
{
_CurExpInfo = value;
if (value != null)
{
IsExpInfoOk = true;
}
RaisePropertyChanged();
}
}
/// <summary>
/// 试验信息是否OK
/// </summary>
public bool IsExpInfoOk { get; set; }
///// <summary>
///// 当前的试验信息
///// </summary>
//public HistoryExp CurExpInfo { get; set; }
private UserDto _CurUserDto;
/// <summary>
/// 当前的用户信息
/// </summary>
public UserDto CurUserDto
{
get { return _CurUserDto; }
set { _CurUserDto = value; RaisePropertyChanged(); }
}
}
}

View File

@@ -0,0 +1,771 @@
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="冷媒流量[L/min]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
new Columns(){ Name="润滑油流量[L/min]",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="通讯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="创建时间",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))
{
////第一次计时
//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();
var models = ConvertToCsvRecordModel(recordChannelData.Data);
//数据库保存
//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();
}
}
}
/// <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)kvp.Value.EngValue);
DataInfo.Add("创建时间", DateTime.Now);
var RecordData = new RecordChannelData()
{
CreateTime = DateTime.Now,
TableName = "",
Data = DataInfo
//new Dictionary<string, object>()
//{
// {"转速[rpm]",Random.Next(0,10)+10 +Add},
// {"排气压力[BarA]",Random.Next(0,10)+20 +Add},
// {"吸气压力[BarA]",Random.Next(0,10)+30 +Add},
// {"吸气温度[℃]",Random.Next(0,10)+40 +Add},
// {"COND1温度[℃]",Random.Next(0,10)+50 +Add},
// {"润滑油压力[BarA]",Random.Next(0,10)+60 +Add},
// {"COND2压力[BarA]",Random.Next(0,10)+70 +Add},
// {"OCR[%]",Random.Next(0,10)+80 +Add},
// {"HV[V]",Random.Next(0,10)+90 +Add},
// {"HV[A]",Random.Next(0,10)+5 +Add},
// {"HV[W]",Random.Next(0,10)+15 +Add},
// {"LV[V]",Random.Next(0,10)+25 +Add},
// {"LV[A]",Random.Next(0,10)+25 +Add},
// {"环境温度[℃]",Random.Next(0,10)+35 +Add},
// {"环境湿度[%]",Random.Next(0,10)+45 +Add},
// {"OS1温度[℃]",Random.Next(0,10)+55 +Add},
// {"OS2温度[℃]",Random.Next(0,10)+65 +Add},
// {"COND2温度[℃]",Random.Next(0,10)+75 +Add},
// {"EVAP出口温度[℃]",Random.Next(0,10) +85+Add},
// {"冷媒流量[L/min]",Random.Next(0,10) +10+Add},
// {"润滑油流量[L/min]",Random.Next(0,10)+1 +Add},
// {"排气温度[℃]",Random.Next(0,10)+13 +Add},
// {"膨胀阀前压力[BarA]",Random.Next(0,10)+23 +Add},
// {"膨胀阀前温度[℃]",Random.Next(0,10) +33+Add},
// {"EVAP出口压力[BarA]",Random.Next(0,10)+43 +Add},
// {"腔内压力[BarA]",Random.Next(0,10) +53+Add},
// {"压缩机表面温度[℃]",Random.Next(0,10)+63 +Add},
// {"PTC流量[L/min]",Random.Next(0,10)+73 +Add},
// {"PTC入水温度[℃]",Random.Next(0,10)+83 +Add},
// {"PTC出水温度[℃]",Random.Next(0,10)+7 +Add},
// {"通讯Cmp母线电流[A]",Random.Next(0,10)+17 +Add},
// {"通讯Cmp母线电压[V]",Random.Next(0,10)+27 +Add},
// {"通讯Cmp逆变器温度[℃]",Random.Next(0,10)+37 +Add},
// {"通讯Cmp相电流[A]",Random.Next(0,10)+47 +Add},
// {"通讯Cmp功率[W]",Random.Next(0,10)+57 +Add},
// {"通讯Cmp芯片温度[℃]",Random.Next(0,10) +67+Add},
// {"通讯PTC入水温度[℃]",Random.Next(0,10)+77 +Add},
// {"通讯PTC出水温度[℃]",Random.Next(0,10) +87+Add},
// {"通讯PTC峰值电流[A]",Random.Next(0,10)+1 +Add},
// {"通讯PTC母线电流[A]",Random.Next(0,10)+16 +Add},
// {"通讯PTC膜温[℃]",Random.Next(0,10)+26 +Add},
// {"通讯PTC模块温度[℃]",Random.Next(0,10)+39 +Add},
// {"创建时间",DateTime.Now},
//},
};
if (IsRecord)
{
//本体数据记录
RecoredChannelInfo.Writer.WriteAsync(RecordData);
}
//CycleTimer.Start(); //执行完毕后再开启器
}
catch (Exception ex)
{
//CycleTimer.Start(); //执行完毕后再开启器
LogService.Info($"时间:{DateTime.Now.ToString()}-【PwAnalyze-CycleAction】-{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
}
}

View File

@@ -13,7 +13,7 @@ namespace CapMachine.Wpf.Services
/// </summary>
public class LogService : ILogService
{
private static Logger logger = LogManager.GetCurrentClassLogger(); //初始化日志类
private static Logger Logger = LogManager.GetCurrentClassLogger(); //初始化日志类
/// <summary>
/// 调试日志
@@ -21,7 +21,7 @@ namespace CapMachine.Wpf.Services
/// <param name="msg">日志内容</param>
public void Debug(string msg)
{
logger.Debug(msg);
Logger.Debug(msg);
}
/// <summary>
@@ -34,7 +34,7 @@ namespace CapMachine.Wpf.Services
/// </remarks>
public void Info(string msg)
{
logger.Info(msg);
Logger.Info(msg);
}
/// <summary>
@@ -47,7 +47,7 @@ namespace CapMachine.Wpf.Services
/// </remarks>
public void Error(string msg)
{
logger.Error(msg);
Logger.Error(msg);
}
/// <summary>
@@ -60,7 +60,7 @@ namespace CapMachine.Wpf.Services
/// </remarks>
public void Fatal(string msg)
{
logger.Fatal(msg);
Logger.Fatal(msg);
}
/// <summary>
@@ -75,7 +75,7 @@ namespace CapMachine.Wpf.Services
{
try
{
logger.Warn(msg);
Logger.Warn(msg);
}
catch { }
}

File diff suppressed because it is too large Load Diff

View File

@@ -44,6 +44,11 @@ namespace CapMachine.Wpf.Services
{
new NavigationItem("Circle","转速PID",""),
}),
new NavigationItem("", "通信配置","",new ObservableCollection<NavigationItem>()
{
new NavigationItem("Circle","CAN配置","CANConfigView"),
new NavigationItem("Circle","LIN配置",""),
}),
new NavigationItem("","版本信息","",new ObservableCollection<NavigationItem>()
{
new NavigationItem("FormatColorText", "操作手册",""),
@@ -51,10 +56,27 @@ namespace CapMachine.Wpf.Services
}),
}));
//MenuItems.Add(new NavigationItem("", "通信配置", "", new ObservableCollection<NavigationItem>()
//{
// new NavigationItem("","CAN通信","",new ObservableCollection<NavigationItem>()
// {
// new NavigationItem("","CAN配置","CANConfigView"),
// new NavigationItem("","快速工况","QuickMeterStepView"),
// new NavigationItem("Clouds", "高速记录",""),
// new NavigationItem("ShapeOvalPlus","系统配置",""),
// }),
// new NavigationItem("", "LIN通信","",new ObservableCollection<NavigationItem>()
// {
// new NavigationItem("","LIN配置",""),
// new NavigationItem("Palette","过冷度",""),
// }),
//}));
MenuItems.Add(new NavigationItem("", "工艺过程", "MonitorView"));
MenuItems.Add(new NavigationItem("", "CAN配置", "CANConfigView"));
MenuItems.Add(new NavigationItem("", "工艺参数", "ProConfigView"));
MenuItems.Add(new NavigationItem("", "工艺曲线", "RealTimeChartView"));
MenuItems.Add(new NavigationItem("", "动作日志", "ActionLogView"));
MenuItems.Add(new NavigationItem("", "历史数据", "HistoryDataView"));
MenuItems.Add(new NavigationItem("", "用户管理", "UserManageView"));
MenuItems.Add(new NavigationItem("", "快速工况", "QuickMeterStepView"));
}

View File

@@ -1,4 +1,6 @@
using Prism.Mvvm;
using CapMachine.Wpf.Models;
using Prism.Events;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -8,11 +10,11 @@ using System.Threading.Tasks;
namespace CapMachine.Wpf.Services
{
/// <summary>
/// 系统资源
/// 系统
/// </summary>
public class SysService : BindableBase
public class SysRunService : BindableBase
{
public SysService()
public SysRunService(IEventAggregator eventAggregator,ConfigService configService)
{
// 创建一个定时器设置间隔时间为2000毫秒即2秒
CurTimer = new System.Timers.Timer(5000);
@@ -22,11 +24,22 @@ namespace CapMachine.Wpf.Services
// 启动定时器
CurTimer.Start();
EventAggregator = eventAggregator;
ConfigService = configService;
MachineRunState1 = new MachineRunState("M1", EventAggregator, ConfigService);
}
/// <summary>
/// 设备运行状态
/// </summary>
public MachineRunState MachineRunState1 { get; set; }
private void CurTimer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
{
CurDateTime=DateTime.Now;
CurDateTime = DateTime.Now;
}
@@ -45,5 +58,10 @@ namespace CapMachine.Wpf.Services
set { _CurDateTime = value; RaisePropertyChanged(); }
}
/// <summary>
/// 时间发布器
/// </summary>
public IEventAggregator EventAggregator { get; }
public ConfigService ConfigService { get; }
}
}