diff --git a/DyeingComputer.csproj b/DyeingComputer.csproj index 595e462..1f67d9e 100644 --- a/DyeingComputer.csproj +++ b/DyeingComputer.csproj @@ -129,6 +129,7 @@ + @@ -143,6 +144,7 @@ + @@ -347,6 +349,9 @@ 8.2.2 + + 2.0.0-rc3.3 + 8.0.0 @@ -406,11 +411,11 @@ - + %(ReferenceCopyLocalPaths.DestinationSubDirectory)%(ReferenceCopyLocalPaths.Filename)%(ReferenceCopyLocalPaths.Extension) - + \ No newline at end of file diff --git a/MainWindow.xaml b/MainWindow.xaml index 4a16346..c73a6da 100644 --- a/MainWindow.xaml +++ b/MainWindow.xaml @@ -4,7 +4,8 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:lang="clr-namespace:DyeingComputer.Properties" - xmlns:local="clr-namespace:DyeingComputer" xmlns:viewmodel="clr-namespace:DyeingComputer.ViewModel" + xmlns:local="clr-namespace:DyeingComputer" + xmlns:viewmodel="clr-namespace:DyeingComputer.ViewModel" d:DataContext="{d:DesignInstance Type=viewmodel:MainWindowViewModel}" mc:Ignorable="d" KeyDown="W_KeyDown" Title="SUNLIGHT 838 b0.0.1 (2024/08/10)" diff --git a/UserClass/CSV.cs b/UserClass/CSV.cs new file mode 100644 index 0000000..afd0abd --- /dev/null +++ b/UserClass/CSV.cs @@ -0,0 +1,216 @@ +using Microsoft.Win32; +using System; +using System.Collections.Generic; +using System.Data; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Markup; + +namespace DyeingComputer.UserClass +{ + internal class CSV + { + /// + /// 将DataTable中数据写入到CSV文件中 + /// + /// 提供保存数据的DataTable + /// CSV的文件路径 + public static void SaveCSV(DataTable dt,string strFormat) + { + FileInfo fi = new FileInfo(strFormat); + if (!fi.Directory.Exists) + { + fi.Directory.Create(); + } + FileStream fs = new FileStream(strFormat, System.IO.FileMode.Create, System.IO.FileAccess.Write); + //StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.Default); + StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8); + string data = ""; + //写出列名称 + for (int i = 0; i < dt.Columns.Count; i++) + { + data += dt.Columns[i].ColumnName.ToString(); + if (i < dt.Columns.Count - 1) + { + data += ","; + } + } + sw.WriteLine(data); + //写出各行数据 + for (int i = 0; i < dt.Rows.Count; i++) + { + data = ""; + for (int j = 0; j < dt.Columns.Count; j++) + { + string str = dt.Rows[i][j].ToString(); + str = str.Replace("\"", "\"\"");//替换英文冒号 英文冒号需要换成两个冒号 + if (str.Contains(',') || str.Contains('"') + || str.Contains('\r') || str.Contains('\n')) //含逗号 冒号 换行符的需要放到引号中 + { + str = string.Format("\"{0}\"", str); + } + + data += str; + if (j < dt.Columns.Count - 1) + { + data += ","; + } + } + sw.WriteLine(data); + } + sw.Close(); fs.Close(); + } + + #region CSV文件读取 + /// + /// 将CSV文件的数据读取到DataTable中 + /// + /// CSV文件路径 + /// 返回读取了CSV数据的DataTable + public static DataTable OpenCSV(string filePath)//从csv读取数据返回table + { + System.Text.Encoding encoding = GetType(filePath); //Encoding.ASCII;// + DataTable dt = new DataTable(); + System.IO.FileStream fs = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read); + System.IO.StreamReader sr = new System.IO.StreamReader(fs, encoding); + + //记录每次读取的一行记录 + string strLine = ""; + //记录每行记录中的各字段内容 + string[] aryLine = null; + string[] tableHead = null; + //标示列数 + int columnCount = 0; + //标示是否是读取的第一行 + bool IsFirst = true; + //逐行读取CSV中的数据 + int readCol = 0; + while ((strLine = sr.ReadLine()) != null) + { + if (readCol > 0) + { + if (IsFirst == true) + { + tableHead = strLine.Split(','); + IsFirst = false; + columnCount = tableHead.Length; + //创建列 + for (int i = 0; i < columnCount; i++) + { + DataColumn dc = new DataColumn(tableHead[i]); + dt.Columns.Add(dc); + } + } + else + { + aryLine = strLine.Split(','); + DataRow dr = dt.NewRow(); + for (int j = 0; j < columnCount; j++) + { + dr[j] = aryLine[j]; + } + dt.Rows.Add(dr); + } + } + readCol++; + } + if (aryLine != null && aryLine.Length > 0) + { + dt.DefaultView.Sort = tableHead[0] + " " + "asc"; + } + + sr.Close(); + fs.Close(); + return dt; + } + /// 给定文件的路径,读取文件的二进制数据,判断文件的编码类型 + /// 文件路径 + /// 文件的编码类型 + + public static System.Text.Encoding GetType(string FILE_NAME) + { + System.IO.FileStream fs = new System.IO.FileStream(FILE_NAME, System.IO.FileMode.Open, + System.IO.FileAccess.Read); + System.Text.Encoding r = GetType(fs); + fs.Close(); + return r; + } + + /// 通过给定的文件流,判断文件的编码类型 + /// 文件流 + /// 文件的编码类型 + public static System.Text.Encoding GetType(System.IO.FileStream fs) + { + byte[] Unicode = new byte[] { 0xFF, 0xFE, 0x41 }; + byte[] UnicodeBIG = new byte[] { 0xFE, 0xFF, 0x00 }; + byte[] UTF8 = new byte[] { 0xEF, 0xBB, 0xBF }; //带BOM + System.Text.Encoding reVal = System.Text.Encoding.Default; + + System.IO.BinaryReader r = new System.IO.BinaryReader(fs, System.Text.Encoding.Default); + int i; + int.TryParse(fs.Length.ToString(), out i); + byte[] ss = r.ReadBytes(i); + if (IsUTF8Bytes(ss) || (ss[0] == 0xEF && ss[1] == 0xBB && ss[2] == 0xBF)) + { + reVal = System.Text.Encoding.UTF8; + } + else if (ss[0] == 0xFE && ss[1] == 0xFF && ss[2] == 0x00) + { + reVal = System.Text.Encoding.BigEndianUnicode; + } + else if (ss[0] == 0xFF && ss[1] == 0xFE && ss[2] == 0x41) + { + reVal = System.Text.Encoding.Unicode; + } + r.Close(); + return reVal; + } + + /// 判断是否是不带 BOM 的 UTF8 格式 + /// + /// + private static bool IsUTF8Bytes(byte[] data) + { + int charByteCounter = 1; //计算当前正分析的字符应还有的字节数 + byte curByte; //当前分析的字节. + for (int i = 0; i < data.Length; i++) + { + curByte = data[i]; + if (charByteCounter == 1) + { + if (curByte >= 0x80) + { + //判断当前 + while (((curByte <<= 1) & 0x80) != 0) + { + charByteCounter++; + } + //标记位首位若为非0 则至少以2个1开始 如:110XXXXX...........1111110X  + if (charByteCounter == 1 || charByteCounter > 6) + { + return false; + } + } + } + else + { + //若是UTF-8 此时第一位必须为1 + if ((curByte & 0xC0) != 0x80) + { + return false; + } + charByteCounter--; + } + } + if (charByteCounter > 1) + { + throw new Exception("非预期的byte格式"); + } + return true; + } + #endregion + + } +} diff --git a/View/CurveDiagramView.xaml b/View/CurveDiagramView.xaml index e0ed3af..88530e7 100644 --- a/View/CurveDiagramView.xaml +++ b/View/CurveDiagramView.xaml @@ -2,11 +2,15 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - xmlns:local="clr-namespace:DyeingComputer.View" - mc:Ignorable="d" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:lvc="clr-namespace:LiveChartsCore.SkiaSharpView.WPF;assembly=LiveChartsCore.SkiaSharpView.WPF" + xmlns:viewmodel="clr-namespace:DyeingComputer.ViewModel" + d:DataContext="{d:DesignInstance Type=viewmodel:CurveDiagramViewModel}" + mc:Ignorable="d" Loaded="UserControl_Loaded" d:DesignHeight="630" d:DesignWidth="1280" VerticalAlignment="Top"> - + + + diff --git a/View/CurveDiagramView.xaml.cs b/View/CurveDiagramView.xaml.cs index ee8f162..b447587 100644 --- a/View/CurveDiagramView.xaml.cs +++ b/View/CurveDiagramView.xaml.cs @@ -1,5 +1,9 @@ -using System; +using DyeingComputer.ViewModel; +using LiveChartsCore.SkiaSharpView; +using LiveChartsCore; +using System; using System.Collections.Generic; +using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -12,6 +16,12 @@ using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; +using static DyeingComputer.UserClass.SqliteHelper; +using DyeingComputer.UserClass; +using LiveChartsCore.Kernel.Sketches; +using LiveChartsCore.Measure; +using ScottPlot.Plottables; +using System.Runtime.InteropServices; namespace DyeingComputer.View { @@ -20,9 +30,41 @@ namespace DyeingComputer.View /// public partial class CurveDiagramView : UserControl { + private SQLiteHelper SQLiteHelpers = null; //定义数据库 + private readonly string ChartAdress = Environment.CurrentDirectory + "\\DataBase\\Chart.db"; //数据库路径 + DataTable CDB = new DataTable(); + public CurveDiagramView() { InitializeComponent(); + DataContext = new CurveDiagramViewModel(); } + + private void UserControl_Loaded(object sender, RoutedEventArgs e) + { + if (MainWindowViewModel.WorkNumder.ToString() != "----------") + { + SQLiteHelpers = new SQLiteHelper(ChartAdress); //数据库连接路径 + SQLiteHelpers.Open(); //打开数据库 + CDB = SQLiteHelpers.ExecuteDataSet("select * from Chart where DYELOT = '" + MainWindowViewModel.WorkNumder + "'", null).Tables[0]; + SQLiteHelpers.Close(); + + + + + + + + } + + + OscChart.Series = new ISeries[] { new LineSeries + { + Values = new double[] { 2, 1, 3, 5, 3, 4, 6 }, + Fill = null + } }; + + } + } } diff --git a/ViewModel/CurveDiagramViewModel.cs b/ViewModel/CurveDiagramViewModel.cs new file mode 100644 index 0000000..01b67d9 --- /dev/null +++ b/ViewModel/CurveDiagramViewModel.cs @@ -0,0 +1,31 @@ +using LiveChartsCore.SkiaSharpView; +using LiveChartsCore; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static DyeingComputer.UserClass.SqliteHelper; +using CommunityToolkit.Mvvm.ComponentModel; + +namespace DyeingComputer.ViewModel +{ + public class CurveDiagramViewModel : ObservableObject + { + + public ISeries[] Series { get; set; } = new ISeries[] + { + new LineSeries + { + Values = new double[] { 2, 1, 3, 5, 3, 4, 6 }, + Fill = null + } + }; + + public CurveDiagramViewModel() + { + + } + } +} diff --git a/ViewModel/MainWindowViewModel.cs b/ViewModel/MainWindowViewModel.cs index db84631..17b5a3f 100644 --- a/ViewModel/MainWindowViewModel.cs +++ b/ViewModel/MainWindowViewModel.cs @@ -56,6 +56,7 @@ namespace DyeingComputer.ViewModel { private SQLiteHelper SQLiteHelpers = null; //定义数据库 private readonly string DBAddress = Environment.CurrentDirectory + "\\DataBase\\800COMPUTER.db"; //数据库路径 + private readonly string ChartAdress = Environment.CurrentDirectory + "\\DataBase\\Chart.db"; //数据库路径 private IniFile.IniFiles Configini = new IniFile.IniFiles(Convert.ToString(System.AppDomain.CurrentDomain.BaseDirectory) + "DyeingComputer.ini"); private PID pid = new PID(); public static DataTable RUN_DATATABLE = new DataTable();//缓存工作表 @@ -82,7 +83,6 @@ namespace DyeingComputer.ViewModel private int MT40;//低水位 private int MT41;//安全水位 private static int MT90;//呼叫操作员 - private int S16;//机型 private int SM01;//副缸 private int SM02;//副缸 @@ -121,6 +121,7 @@ namespace DyeingComputer.ViewModel SM03 = Convert.ToInt16(Selet_sys("SM03"));//FG } DataTable dt_con = new DataTable(); + DataTable dt_sys = new DataTable(); public string Selet_con(string key)//配置缓存 { try @@ -135,8 +136,6 @@ namespace DyeingComputer.ViewModel return "0"; } } - - DataTable dt_sys = new DataTable(); public string Selet_sys(string key)//配置缓存 { try @@ -151,6 +150,7 @@ namespace DyeingComputer.ViewModel return "0"; } } + public string work_Temp; //显示温度 public string Work_Temp //通知UI控件参数改变 { @@ -226,15 +226,16 @@ namespace DyeingComputer.ViewModel if (!SETP_runtime) DIDETime++; - STEP_RUN(); + STEP_RUN(); LOG_view(); IO_view(); if (!string.IsNullOrEmpty(Name_err.ToString())) Status_Str = Name_err.ToString(); } void Tick_Event_5S(object sender, EventArgs e)//Tick_Event周期执行事件5S - { + { if (!LINK_OK) Modbus_link(); + Chart();//写入记录 if (string.IsNullOrEmpty(Name_err.ToString()) && ((Selet_dtm("1010") < 10) || (Selet_dtm("1010") > 160))) { Name_err = Resources.Temperature + Resources.Sensor + Resources.Malfunction; } //温度故障提示 @@ -256,6 +257,28 @@ namespace DyeingComputer.ViewModel } } + void Chart() + { + Dictionary Chart_new = new Dictionary();//缓存函数 + Chart_new.Add("DYELOT", work_Numder); + Chart_new.Add("Time", sys_Time); + Chart_new.Add("MST", string.Format(" {0:###.#}", TEMP_co)); + Chart_new.Add("MTT", Selet_dtm("1010")); + Chart_new.Add("MTL", Selet_dtm("1015")); + Chart_new.Add("MTH", Selet_dtm("1009")); + Chart_new.Add("STTA", Selet_dtm("1012")); + Chart_new.Add("STLA", Selet_dtm("1017")); + Chart_new.Add("STTB", Selet_dtm("1013")); + Chart_new.Add("STLB", Selet_dtm("1018")); + Chart_new.Add("STTC", Selet_dtm("1014")); + Chart_new.Add("STLC", Selet_dtm("1019")); + + SQLiteHelpers = new SQLiteHelper(ChartAdress); //数据库连接路径 + SQLiteHelpers.Open(); //打开数据库 + SQLiteHelpers.InsertData("Chart", Chart_new);// 执行插入 + SQLiteHelpers.Close(); + }//历史记录 + public static int WORK_RUN = 0; //运行状态0停止1暂停2运行 private static string STEP_ID = "0"; private static double STEP_P1 = 0; @@ -268,7 +291,7 @@ namespace DyeingComputer.ViewModel private static int STEP_TIME = 0; //步骤计时S private static int THL_mode = 0; //温控模式 0保温 1加热 2降 private static double TEMP_co = 0; //计算温度 - private static double TEMP_tar = 16.5; //目标温度 + private static double TEMP_tar = 0.5; //目标温度 private bool Alert_yellow = false; //警报黄灯 private bool Alert_red = false; //警报红灯 private bool Alert_bell = false; //警报铃声 @@ -990,7 +1013,6 @@ namespace DyeingComputer.ViewModel Name_err = "800_SerialPort_Not"; } } - private bool LINK_OK = false; private int LINK_RUN = 0; private int LINK_ERR = 0; diff --git a/ViewModel/ViewModelLocator.cs b/ViewModel/ViewModelLocator.cs index a820b33..2880829 100644 --- a/ViewModel/ViewModelLocator.cs +++ b/ViewModel/ViewModelLocator.cs @@ -26,6 +26,12 @@ namespace DyeingComputer.ViewModel return ServiceLocator.Current.GetInstance(); } } - + public CurveDiagramViewModel Curve + { + get + { + return ServiceLocator.Current.GetInstance(); + } + } } }