From 86412fff024663fdf3b17df78c14bfdc2232bd3a Mon Sep 17 00:00:00 2001 From: nikzori Date: Mon, 23 Dec 2024 16:30:35 +0300 Subject: [PATCH] added multi-entry supportfor bool and uint16; `poll once` option now works --- Datasheet.cs | 177 ++++++++++++++++++++++++++++++++----- Json.cs | 10 ++- Main.Designer.cs | 20 ++--- Main.cs | 9 +- Properties/AssemblyInfo.cs | 6 +- 5 files changed, 185 insertions(+), 37 deletions(-) diff --git a/Datasheet.cs b/Datasheet.cs index 5bbe1ff..c35eb89 100644 --- a/Datasheet.cs +++ b/Datasheet.cs @@ -25,6 +25,7 @@ namespace Gidrolock_Modbus_Scanner Device device = App.device; List entries; int activeEntryIndex; // entry index for modbus responses + int activeDGVIndex; // index for DGV rows SerialPort port = Modbus.port; bool closed = false; @@ -56,14 +57,49 @@ namespace Gidrolock_Modbus_Scanner DGV_Device.Columns[4].Name = "Опрос"; DGV_Device.Columns[4].FillWeight = 20; DGV_Device.Columns[4].ValueType = typeof(bool); - + + int rowCount = 0; + + foreach (Entry e in entries) + { + if (e.length > 1) + { + // multi-register entry check + if ((e.length == 2 && e.dataType == "uint32") || e.dataType == "string") + { + DGV_Device.Rows.Add(rowCount, e.name, "", e.address); + rowCount++; + } + else + { + for (int i = 0; i < e.length; i++) + { + if (i < e.labels.Count) + DGV_Device.Rows.Add(rowCount, e.name + ": " + e.labels[i], "", e.address + i); + else DGV_Device.Rows.Add(rowCount, e.address + i, "", e.address + i); + rowCount++; + } + } + + } + else + { + DGV_Device.Rows.Add(rowCount, e.name, "", e.address); + rowCount++; + } + } + foreach (DataGridViewRow row in DGV_Device.Rows) + { + row.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; + } + /* for (int i = 0; i < entries.Count; i++) { DGV_Device.Rows.Add(i.ToString(), entries[i].name, "", entries[i].address); DGV_Device.Rows[i].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; } - - foreach (DataGridViewColumn column in DGV_Device.Columns) + */ + foreach (DataGridViewColumn column in DGV_Device.Columns) column.SortMode = DataGridViewColumnSortMode.NotSortable; // disabling sorting for now FormClosing += (s, e) => { closed = true; }; @@ -81,33 +117,51 @@ namespace Gidrolock_Modbus_Scanner { if (isPolling) { - for (int i = 0; i < entries.Count; i++) + // holy fuck DGV is awful + DataGridViewCheckBoxCell chbox = DGV_Device.Rows[activeDGVIndex].Cells[4] as DataGridViewCheckBoxCell; + if (Convert.ToBoolean(chbox.Value)) { - // holy fuck DGV is awful - DataGridViewCheckBoxCell chbox = DGV_Device.Rows[i].Cells[4] as DataGridViewCheckBoxCell; - if (Convert.ToBoolean(chbox.Value)) + Console.WriteLine("Polling for " + device.entries[activeEntryIndex].name); + await PollForEntry(entries[activeEntryIndex]); + await Task.Delay(150); + } + else //need to skip multiple dgv entries without accidentaly skipping entries + { + if (device.entries[activeEntryIndex].labels is null || device.entries[activeEntryIndex].labels.Count == 0) + activeDGVIndex++; + else { - Console.WriteLine("Polling for " + device.entries[i].name); - activeEntryIndex = i; - await PollForEntry(entries[i]); + for (int i = 0; i < device.entries[activeEntryIndex].labels.Count; i++) + { + activeDGVIndex++; + } } } + + activeEntryIndex++; + if (activeEntryIndex >= device.entries.Count) + activeEntryIndex = 0; + if (activeDGVIndex >= DGV_Device.RowCount) + activeDGVIndex = 0; + + Console.WriteLine("entry index: " + activeEntryIndex + "; dgv index: " + activeDGVIndex); } } } catch (Exception err) { - MessageBox.Show(err.Message); + MessageBox.Show(err.Message, "AutoPollAsync"); } + } public async Task PollForEntry(Entry entry) { - byte[] message = new byte[9]; + byte[] message = new byte[8]; var send = await Modbus.ReadRegAsync(port, slaveID, (FunctionCode)entry.registerType, entry.address, entry.length); isAwaitingResponse = true; - Task delay = Task.Delay(timeout).ContinueWith((t) => + Task delay = Task.WhenAny(Task.Delay(timeout), Task.Run( () => { while (isAwaitingResponse) { } return; })).ContinueWith((t) => { if (isAwaitingResponse) { @@ -124,23 +178,94 @@ namespace Gidrolock_Modbus_Scanner { if (isAwaitingResponse) { - isAwaitingResponse = false; try { + if (entries[activeEntryIndex].readOnce) + { + DataGridViewCheckBoxCell chbox = DGV_Device.Rows[activeDGVIndex].Cells[4] as DataGridViewCheckBoxCell; + chbox.Value = false; + } + int dbc = e.Message[2]; // data byte count switch (entries[activeEntryIndex].dataType) { case ("bool"): - DGV_Device.Rows[activeEntryIndex].Cells[2].Value = e.Data[0] > 0x00 ? "true" : "false"; + if (entries[activeEntryIndex].labels is null || entries[activeEntryIndex].labels.Count == 0) // assume that no labels = 1 entry + { + if (entries[activeEntryIndex].valueParse is null || entries[activeEntryIndex].valueParse.Keys.Count == 0) + DGV_Device.Rows[activeEntryIndex].Cells[2].Value = e.Data[0] > 0x00 ? "true" : "false"; + else + { + try { DGV_Device.Rows[activeEntryIndex].Cells[2].Value = e.Data[0] > 0x00 ? entries[activeEntryIndex].valueParse["true"] : entries[activeEntryIndex].valueParse["false"]; } + catch + { + Console.WriteLine("Value parsing error for bool entry: " + entries[activeEntryIndex].name); + DGV_Device.Rows[activeEntryIndex].Cells[2].Value = e.Data[0] > 0x00 ? "true" : "false"; + } + } + activeDGVIndex++; + } + else + { + List values = new List(); + for (int i = 0; i < dbc; i++) + { + for (int j = 0; j < 8; j++) + { + bool res = (((e.Data[i] >> j) & 0x01) >= 1) ? true : false; + values.Add(res); + } + } + for (int i = 0; i < entries[activeEntryIndex].labels.Count; i++) + { + DGV_Device.Rows[activeDGVIndex].Cells[2].Value = values[i]; + activeDGVIndex++; + } + } break; case ("uint16"): - //Array.Reverse(e.Data); // BitConverter.ToUInt is is little endian, so we need to flip the array - ushort test = BitConverter.ToUInt16(e.Data, 0); - Console.WriteLine("ushort parsed value: " + test); - DGV_Device.Rows[activeEntryIndex].Cells[2].Value = test; + ushort value = BitConverter.ToUInt16(e.Data, 0); + if (entries[activeEntryIndex].labels is null || entries[activeEntryIndex].labels.Count == 0) // single value + { + if (entries[activeEntryIndex].valueParse is null || entries[activeEntryIndex].valueParse.Keys.Count == 0) + { + //Array.Reverse(e.Data); // this was necessary, but something changed, idk + + Console.WriteLine("ushort parsed value: " + value); + DGV_Device.Rows[activeDGVIndex].Cells[2].Value = value; + } + else + { + try + { + DGV_Device.Rows[activeDGVIndex].Cells[2].Value = entries[activeEntryIndex].valueParse[value.ToString()]; + } + catch { DGV_Device.Rows[activeDGVIndex].Cells[2].Value = value; Console.WriteLine("Error parsing uint value at address: " + entries[activeEntryIndex].address); } + } + + activeDGVIndex++; + } + else // value group + { + List values = new List(); + for (int i = 0; i < dbc; i += 2) + { + ushort s = BitConverter.ToUInt16(e.Data, i); + values.Add(s); + } + for (int i = 0; i < entries[activeEntryIndex].labels.Count; i++) + { + DGV_Device.Rows[activeDGVIndex].Cells[2].Value = values[i]; + activeDGVIndex++; + } + } + break; case ("uint32"): Array.Reverse(e.Data); - DGV_Device.Rows[activeEntryIndex].Cells[2].Value = BitConverter.ToUInt32(e.Data, 0); + DGV_Device.Rows[activeDGVIndex].Cells[2].Value = BitConverter.ToUInt32(e.Data, 0); + + activeDGVIndex++; + break; case ("string"): List bytes = new List(); @@ -150,13 +275,18 @@ namespace Gidrolock_Modbus_Scanner bytes.Add(e.Data[i]); } bytes.Reverse(); - DGV_Device.Rows[activeEntryIndex].Cells[2].Value = System.Text.Encoding.UTF8.GetString(bytes.ToArray()); + DGV_Device.Rows[activeDGVIndex].Cells[2].Value = System.Text.Encoding.UTF8.GetString(bytes.ToArray()); + + activeDGVIndex++; + break; default: MessageBox.Show("Wrong data type set for entry " + entries[activeEntryIndex].name); + activeDGVIndex++; break; } - + if (activeDGVIndex >= DGV_Device.RowCount) + activeDGVIndex = 0; //MessageBox.Show("Получен ответ от устройства: " + dataCleaned, "Успех", MessageBoxButtons.OK); port.DiscardInBuffer(); @@ -164,6 +294,9 @@ namespace Gidrolock_Modbus_Scanner catch { return; } } + if (activeDGVIndex >= DGV_Device.Rows.Count) + activeDGVIndex = 0; + isAwaitingResponse = false; } private void Button_StartStop_Click(object sender, EventArgs e) diff --git a/Json.cs b/Json.cs index 4dd8378..0457999 100644 --- a/Json.cs +++ b/Json.cs @@ -14,6 +14,7 @@ namespace Gidrolock_Modbus_Scanner public string description; public List entries; public CheckEntry checkEntry; + public Device(string name, string description, CheckEntry checkEntry, List entries) { this.name = name; @@ -29,16 +30,23 @@ namespace Gidrolock_Modbus_Scanner public ushort address; public ushort length; public string dataType; + public List labels; + public Dictionary valueParse; public bool readOnce; + public bool isModbusID; - public Entry(string name, RegisterType registerType, ushort address, ushort length = 1, string dataType = "uint16", bool readOnce = false) + public Entry(string name, RegisterType registerType, ushort address, ushort length = 1, string dataType = "uint16", List labels = null, Dictionary valueParse = null, bool readOnce = false, bool isModbusID = false) { this.name = name; this.registerType = registerType; this.address = address; this.length = length; this.dataType = dataType; + this.labels = labels; + this.valueParse = valueParse; + this.readOnce = readOnce; + this.isModbusID = isModbusID; } } public struct CheckEntry diff --git a/Main.Designer.cs b/Main.Designer.cs index 67431e8..62a1b5c 100644 --- a/Main.Designer.cs +++ b/Main.Designer.cs @@ -49,8 +49,8 @@ this.Button_LoadConfig = new System.Windows.Forms.Button(); this.groupBox1 = new System.Windows.Forms.GroupBox(); this.Label_ConfPath = new System.Windows.Forms.Label(); - this.button1 = new System.Windows.Forms.Button(); this.progressBar1 = new System.Windows.Forms.ProgressBar(); + this.button1 = new System.Windows.Forms.Button(); this.GBox_Serial = new System.Windows.Forms.GroupBox(); this.panel11 = new System.Windows.Forms.Panel(); this.CBox_Parity = new System.Windows.Forms.ComboBox(); @@ -105,12 +105,12 @@ // // TextBox_Log // - this.TextBox_Log.Location = new System.Drawing.Point(12, 192); + this.TextBox_Log.Location = new System.Drawing.Point(12, 177); this.TextBox_Log.Multiline = true; this.TextBox_Log.Name = "TextBox_Log"; this.TextBox_Log.ReadOnly = true; this.TextBox_Log.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.TextBox_Log.Size = new System.Drawing.Size(498, 118); + this.TextBox_Log.Size = new System.Drawing.Size(498, 133); this.TextBox_Log.TabIndex = 1; // // groupBox2 @@ -285,6 +285,13 @@ this.Label_ConfPath.Text = "Файл не выбран."; this.Label_ConfPath.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // + // progressBar1 + // + this.progressBar1.Location = new System.Drawing.Point(172, 54); + this.progressBar1.Name = "progressBar1"; + this.progressBar1.Size = new System.Drawing.Size(210, 25); + this.progressBar1.TabIndex = 14; + // // button1 // this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) @@ -297,13 +304,6 @@ this.button1.UseVisualStyleBackColor = true; this.button1.Click += new System.EventHandler(this.LoadFolder); // - // progressBar1 - // - this.progressBar1.Location = new System.Drawing.Point(172, 54); - this.progressBar1.Name = "progressBar1"; - this.progressBar1.Size = new System.Drawing.Size(210, 25); - this.progressBar1.TabIndex = 14; - // // GBox_Serial // this.GBox_Serial.Controls.Add(this.panel11); diff --git a/Main.cs b/Main.cs index ab2aafd..5b7575f 100644 --- a/Main.cs +++ b/Main.cs @@ -124,7 +124,14 @@ namespace Gidrolock_Modbus_Scanner ofd.InitialDirectory = Application.StartupPath + "\\Configs"; path = defaultPath; UpdatePathLabel(); + + /* - Version Check - */ + System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly(); + System.Diagnostics.FileVersionInfo fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(assembly.Location); + string version = fvi.FileVersion; + Console.WriteLine("Version: " + version); } + void UpdatePathLabel() { Label_ConfPath.Text = path; @@ -531,7 +538,7 @@ namespace Gidrolock_Modbus_Scanner void AddLog(string message) { dateTime = DateTime.Now; - TextBox_Log.Invoke((MethodInvoker)delegate { TextBox_Log.AppendText(Environment.NewLine + "[" + dateTime.Hour + ":" + dateTime.Minute + ":" + dateTime.Second + "] " + message); }); + TextBox_Log.Invoke((MethodInvoker)delegate { TextBox_Log.AppendText(Environment.NewLine + "[" + dateTime.Hour.ToString().PadLeft(2, '0') + ":" + dateTime.Minute.ToString().PadLeft(2, '0') + ":" + dateTime.Second.ToString().PadLeft(2, '0') + "] " + message); }); } private async void Button_SendCommand_Click(object sender, EventArgs e) diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index 86186e9..9fb9ef1 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -9,7 +9,7 @@ using System.Runtime.InteropServices; [assembly: AssemblyTitle("Gidrolock Modbus Scanner")] [assembly: AssemblyDescription("A collection of Modbus tools.")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Gidroresurs LLC")] +[assembly: AssemblyCompany("nikzori")] [assembly: AssemblyProduct("Gidrolock Modbus Scanner")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] @@ -30,6 +30,6 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.0.0.8")] -[assembly: AssemblyFileVersion("0.0.0.8")] +[assembly: AssemblyVersion("0.9.0.0")] +[assembly: AssemblyFileVersion("0.9.0.0")] [assembly: NeutralResourcesLanguage("en")]