refactored RTU response event to offload message processing to a single function
This commit is contained in:
35
Datasheet.cs
35
Datasheet.cs
@@ -25,12 +25,12 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
Device device = App.device;
|
Device device = App.device;
|
||||||
List<Entry> entries;
|
List<Entry> entries;
|
||||||
int activeEntryIndex; // entry index for modbus responses
|
int activeEntryIndex; // entry index for modbus responses
|
||||||
SerialPort port = App.port;
|
SerialPort port = Modbus.port;
|
||||||
|
|
||||||
bool closed = false;
|
bool closed = false;
|
||||||
public Datasheet(byte slaveID)
|
public Datasheet(byte slaveID)
|
||||||
{
|
{
|
||||||
App.port.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(PublishResponse);
|
Modbus.ResponseReceived += PublishResponse;
|
||||||
this.slaveID = slaveID;
|
this.slaveID = slaveID;
|
||||||
entries = device.entries;
|
entries = device.entries;
|
||||||
|
|
||||||
@@ -105,33 +105,22 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
await delay;
|
await delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PublishResponse(object sender, EventArgs e)
|
void PublishResponse(object sender, ModbusResponseEventArgs e)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Received data on port.");
|
|
||||||
if (isAwaitingResponse)
|
if (isAwaitingResponse)
|
||||||
{
|
{
|
||||||
isAwaitingResponse = false;
|
isAwaitingResponse = false;
|
||||||
|
|
||||||
if (!isProcessingResponse)
|
|
||||||
{
|
|
||||||
isProcessingResponse = true;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
message = new byte[255];
|
|
||||||
port.Read(message, 0, 3);
|
byte length = e.message[2];
|
||||||
int length = (int)message[2];
|
Console.WriteLine("Data length is:" + length);
|
||||||
for (int i = 0; i < length + 2; i++)
|
|
||||||
{
|
|
||||||
port.Read(message, i + 3, 1);
|
|
||||||
}
|
|
||||||
byte[] data = new byte[length];
|
byte[] data = new byte[length];
|
||||||
for (int i = 0; i < length; i++)
|
for (int i = 0; i < length; i++)
|
||||||
{
|
data[i] = e.message[i + 3];
|
||||||
data[i] = message[i+3];
|
|
||||||
}
|
Console.WriteLine("Data after processing in Datasheet.cs: " + Modbus.ByteArrayToString(data));
|
||||||
Console.WriteLine("Received message: " + Modbus.ByteArrayToString(message));
|
|
||||||
Console.WriteLine("Data trimmed: " + Modbus.ByteArrayToString(data));
|
|
||||||
string dataCleaned = Modbus.ByteArrayToString(message);
|
|
||||||
|
|
||||||
switch (entries[activeEntryIndex].dataType)
|
switch (entries[activeEntryIndex].dataType)
|
||||||
{
|
{
|
||||||
@@ -159,14 +148,12 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
|
|
||||||
//MessageBox.Show("Получен ответ от устройства: " + dataCleaned, "Успех", MessageBoxButtons.OK);
|
//MessageBox.Show("Получен ответ от устройства: " + dataCleaned, "Успех", MessageBoxButtons.OK);
|
||||||
port.DiscardInBuffer();
|
port.DiscardInBuffer();
|
||||||
isProcessingResponse = false;
|
|
||||||
}
|
}
|
||||||
catch (Exception err)
|
catch (Exception err)
|
||||||
{
|
{
|
||||||
MessageBox.Show(err.Message, "Event Error");
|
//MessageBox.Show(err.Message, "Event Error");
|
||||||
isProcessingResponse = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
21
Json.cs
21
Json.cs
@@ -13,11 +13,12 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
public string name;
|
public string name;
|
||||||
public string description;
|
public string description;
|
||||||
public List<Entry> entries;
|
public List<Entry> entries;
|
||||||
|
public CheckEntry checkEntry;
|
||||||
public Device(string name, string description, List<Entry> entries)
|
public Device(string name, string description, CheckEntry checkEntry, List<Entry> entries)
|
||||||
{
|
{
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
|
this.checkEntry = checkEntry;
|
||||||
this.entries = entries;
|
this.entries = entries;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,5 +41,21 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
this.readOnce = readOnce;
|
this.readOnce = readOnce;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public struct CheckEntry
|
||||||
|
{
|
||||||
|
public RegisterType registerType;
|
||||||
|
public ushort address;
|
||||||
|
public ushort length;
|
||||||
|
public string dataType;
|
||||||
|
public string expectedValue;
|
||||||
|
public CheckEntry(RegisterType registerType, ushort address, ushort length, string dataType, string expectedValue)
|
||||||
|
{
|
||||||
|
this.registerType = registerType;
|
||||||
|
this.address = address;
|
||||||
|
this.length = length;
|
||||||
|
this.dataType = dataType;
|
||||||
|
this.expectedValue = expectedValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
public enum RegisterType { Coil = 1, Discrete = 2, Holding = 3, Input = 4}
|
public enum RegisterType { Coil = 1, Discrete = 2, Holding = 3, Input = 4}
|
||||||
}
|
}
|
||||||
|
|||||||
94
Main.Designer.cs
generated
94
Main.Designer.cs
generated
@@ -80,9 +80,11 @@
|
|||||||
this.groupBox4 = new System.Windows.Forms.GroupBox();
|
this.groupBox4 = new System.Windows.Forms.GroupBox();
|
||||||
this.Radio_Ethernet = new System.Windows.Forms.RadioButton();
|
this.Radio_Ethernet = new System.Windows.Forms.RadioButton();
|
||||||
this.Radio_SerialPort = new System.Windows.Forms.RadioButton();
|
this.Radio_SerialPort = new System.Windows.Forms.RadioButton();
|
||||||
|
this.Label_ConfigTip = new System.Windows.Forms.Label();
|
||||||
this.Button_LoadConfig = new System.Windows.Forms.Button();
|
this.Button_LoadConfig = new System.Windows.Forms.Button();
|
||||||
this.label12 = new System.Windows.Forms.Label();
|
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||||
this.Label_Config = new System.Windows.Forms.Label();
|
this.Label_ConfPath = new System.Windows.Forms.Label();
|
||||||
|
this.button1 = new System.Windows.Forms.Button();
|
||||||
this.GBox_Serial.SuspendLayout();
|
this.GBox_Serial.SuspendLayout();
|
||||||
this.panel11.SuspendLayout();
|
this.panel11.SuspendLayout();
|
||||||
this.panel10.SuspendLayout();
|
this.panel10.SuspendLayout();
|
||||||
@@ -105,6 +107,7 @@
|
|||||||
this.panel17.SuspendLayout();
|
this.panel17.SuspendLayout();
|
||||||
this.panel18.SuspendLayout();
|
this.panel18.SuspendLayout();
|
||||||
this.groupBox4.SuspendLayout();
|
this.groupBox4.SuspendLayout();
|
||||||
|
this.groupBox1.SuspendLayout();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
// GBox_Serial
|
// GBox_Serial
|
||||||
@@ -115,7 +118,7 @@
|
|||||||
this.GBox_Serial.Controls.Add(this.panel7);
|
this.GBox_Serial.Controls.Add(this.panel7);
|
||||||
this.GBox_Serial.Controls.Add(this.panel2);
|
this.GBox_Serial.Controls.Add(this.panel2);
|
||||||
this.GBox_Serial.Controls.Add(this.panel1);
|
this.GBox_Serial.Controls.Add(this.panel1);
|
||||||
this.GBox_Serial.Location = new System.Drawing.Point(12, 12);
|
this.GBox_Serial.Location = new System.Drawing.Point(12, 92);
|
||||||
this.GBox_Serial.Name = "GBox_Serial";
|
this.GBox_Serial.Name = "GBox_Serial";
|
||||||
this.GBox_Serial.Size = new System.Drawing.Size(490, 65);
|
this.GBox_Serial.Size = new System.Drawing.Size(490, 65);
|
||||||
this.GBox_Serial.TabIndex = 0;
|
this.GBox_Serial.TabIndex = 0;
|
||||||
@@ -315,7 +318,7 @@
|
|||||||
//
|
//
|
||||||
this.Button_Connect.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
this.Button_Connect.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||||
| System.Windows.Forms.AnchorStyles.Right)));
|
| System.Windows.Forms.AnchorStyles.Right)));
|
||||||
this.Button_Connect.Location = new System.Drawing.Point(402, 155);
|
this.Button_Connect.Location = new System.Drawing.Point(402, 235);
|
||||||
this.Button_Connect.Name = "Button_Connect";
|
this.Button_Connect.Name = "Button_Connect";
|
||||||
this.Button_Connect.Size = new System.Drawing.Size(100, 25);
|
this.Button_Connect.Size = new System.Drawing.Size(100, 25);
|
||||||
this.Button_Connect.TabIndex = 4;
|
this.Button_Connect.TabIndex = 4;
|
||||||
@@ -325,7 +328,7 @@
|
|||||||
//
|
//
|
||||||
// TextBox_Log
|
// TextBox_Log
|
||||||
//
|
//
|
||||||
this.TextBox_Log.Location = new System.Drawing.Point(12, 192);
|
this.TextBox_Log.Location = new System.Drawing.Point(12, 269);
|
||||||
this.TextBox_Log.Multiline = true;
|
this.TextBox_Log.Multiline = true;
|
||||||
this.TextBox_Log.Name = "TextBox_Log";
|
this.TextBox_Log.Name = "TextBox_Log";
|
||||||
this.TextBox_Log.ReadOnly = true;
|
this.TextBox_Log.ReadOnly = true;
|
||||||
@@ -340,7 +343,7 @@
|
|||||||
this.groupBox2.Controls.Add(this.Button_SendCommand);
|
this.groupBox2.Controls.Add(this.Button_SendCommand);
|
||||||
this.groupBox2.Controls.Add(this.panel3);
|
this.groupBox2.Controls.Add(this.panel3);
|
||||||
this.groupBox2.Controls.Add(this.panel4);
|
this.groupBox2.Controls.Add(this.panel4);
|
||||||
this.groupBox2.Location = new System.Drawing.Point(12, 316);
|
this.groupBox2.Location = new System.Drawing.Point(12, 393);
|
||||||
this.groupBox2.Name = "groupBox2";
|
this.groupBox2.Name = "groupBox2";
|
||||||
this.groupBox2.Size = new System.Drawing.Size(490, 63);
|
this.groupBox2.Size = new System.Drawing.Size(490, 63);
|
||||||
this.groupBox2.TabIndex = 5;
|
this.groupBox2.TabIndex = 5;
|
||||||
@@ -465,7 +468,7 @@
|
|||||||
this.GBox_Ethernet.Controls.Add(this.panel16);
|
this.GBox_Ethernet.Controls.Add(this.panel16);
|
||||||
this.GBox_Ethernet.Controls.Add(this.panel17);
|
this.GBox_Ethernet.Controls.Add(this.panel17);
|
||||||
this.GBox_Ethernet.Controls.Add(this.panel18);
|
this.GBox_Ethernet.Controls.Add(this.panel18);
|
||||||
this.GBox_Ethernet.Location = new System.Drawing.Point(12, 82);
|
this.GBox_Ethernet.Location = new System.Drawing.Point(12, 162);
|
||||||
this.GBox_Ethernet.Name = "GBox_Ethernet";
|
this.GBox_Ethernet.Name = "GBox_Ethernet";
|
||||||
this.GBox_Ethernet.Size = new System.Drawing.Size(334, 65);
|
this.GBox_Ethernet.Size = new System.Drawing.Size(334, 65);
|
||||||
this.GBox_Ethernet.TabIndex = 6;
|
this.GBox_Ethernet.TabIndex = 6;
|
||||||
@@ -551,7 +554,7 @@
|
|||||||
//
|
//
|
||||||
this.groupBox4.Controls.Add(this.Radio_Ethernet);
|
this.groupBox4.Controls.Add(this.Radio_Ethernet);
|
||||||
this.groupBox4.Controls.Add(this.Radio_SerialPort);
|
this.groupBox4.Controls.Add(this.Radio_SerialPort);
|
||||||
this.groupBox4.Location = new System.Drawing.Point(348, 82);
|
this.groupBox4.Location = new System.Drawing.Point(348, 162);
|
||||||
this.groupBox4.Name = "groupBox4";
|
this.groupBox4.Name = "groupBox4";
|
||||||
this.groupBox4.Size = new System.Drawing.Size(154, 65);
|
this.groupBox4.Size = new System.Drawing.Size(154, 65);
|
||||||
this.groupBox4.TabIndex = 7;
|
this.groupBox4.TabIndex = 7;
|
||||||
@@ -582,44 +585,67 @@
|
|||||||
this.Radio_SerialPort.UseVisualStyleBackColor = true;
|
this.Radio_SerialPort.UseVisualStyleBackColor = true;
|
||||||
this.Radio_SerialPort.CheckedChanged += new System.EventHandler(this.Radio_SerialPort_CheckedChanged);
|
this.Radio_SerialPort.CheckedChanged += new System.EventHandler(this.Radio_SerialPort_CheckedChanged);
|
||||||
//
|
//
|
||||||
|
// Label_ConfigTip
|
||||||
|
//
|
||||||
|
this.Label_ConfigTip.AutoSize = true;
|
||||||
|
this.Label_ConfigTip.Location = new System.Drawing.Point(8, 16);
|
||||||
|
this.Label_ConfigTip.Name = "Label_ConfigTip";
|
||||||
|
this.Label_ConfigTip.Size = new System.Drawing.Size(94, 13);
|
||||||
|
this.Label_ConfigTip.TabIndex = 10;
|
||||||
|
this.Label_ConfigTip.Text = "Выбранный путь:";
|
||||||
|
//
|
||||||
// Button_LoadConfig
|
// Button_LoadConfig
|
||||||
//
|
//
|
||||||
this.Button_LoadConfig.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
this.Button_LoadConfig.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||||
| System.Windows.Forms.AnchorStyles.Right)));
|
| System.Windows.Forms.AnchorStyles.Right)));
|
||||||
this.Button_LoadConfig.Location = new System.Drawing.Point(292, 155);
|
this.Button_LoadConfig.Location = new System.Drawing.Point(415, 43);
|
||||||
this.Button_LoadConfig.Name = "Button_LoadConfig";
|
this.Button_LoadConfig.Name = "Button_LoadConfig";
|
||||||
this.Button_LoadConfig.Size = new System.Drawing.Size(100, 25);
|
this.Button_LoadConfig.Size = new System.Drawing.Size(69, 25);
|
||||||
this.Button_LoadConfig.TabIndex = 8;
|
this.Button_LoadConfig.TabIndex = 11;
|
||||||
this.Button_LoadConfig.Text = "Выбрать";
|
this.Button_LoadConfig.Text = "Файл";
|
||||||
this.Button_LoadConfig.UseVisualStyleBackColor = true;
|
this.Button_LoadConfig.UseVisualStyleBackColor = true;
|
||||||
this.Button_LoadConfig.Click += new System.EventHandler(this.LoadConfig);
|
this.Button_LoadConfig.Click += new System.EventHandler(this.LoadConfig);
|
||||||
//
|
//
|
||||||
// label12
|
// groupBox1
|
||||||
//
|
//
|
||||||
this.label12.AutoSize = true;
|
this.groupBox1.Controls.Add(this.Label_ConfPath);
|
||||||
this.label12.Location = new System.Drawing.Point(9, 161);
|
this.groupBox1.Controls.Add(this.button1);
|
||||||
this.label12.Name = "label12";
|
this.groupBox1.Controls.Add(this.Button_LoadConfig);
|
||||||
this.label12.Size = new System.Drawing.Size(83, 13);
|
this.groupBox1.Controls.Add(this.Label_ConfigTip);
|
||||||
this.label12.TabIndex = 9;
|
this.groupBox1.Location = new System.Drawing.Point(12, 12);
|
||||||
this.label12.Text = "Конфигурация:";
|
this.groupBox1.Name = "groupBox1";
|
||||||
|
this.groupBox1.Size = new System.Drawing.Size(490, 74);
|
||||||
|
this.groupBox1.TabIndex = 13;
|
||||||
|
this.groupBox1.TabStop = false;
|
||||||
|
this.groupBox1.Text = "Конфигурация";
|
||||||
//
|
//
|
||||||
// Label_Config
|
// Label_ConfPath
|
||||||
//
|
//
|
||||||
this.Label_Config.AutoSize = true;
|
this.Label_ConfPath.Location = new System.Drawing.Point(9, 29);
|
||||||
this.Label_Config.Location = new System.Drawing.Point(90, 161);
|
this.Label_ConfPath.Name = "Label_ConfPath";
|
||||||
this.Label_Config.Name = "Label_Config";
|
this.Label_ConfPath.Size = new System.Drawing.Size(400, 39);
|
||||||
this.Label_Config.Size = new System.Drawing.Size(66, 13);
|
this.Label_ConfPath.TabIndex = 14;
|
||||||
this.Label_Config.TabIndex = 1;
|
this.Label_ConfPath.Text = "Файл не выбран.";
|
||||||
this.Label_Config.Text = "не выбрана";
|
this.Label_ConfPath.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||||
|
//
|
||||||
|
// button1
|
||||||
|
//
|
||||||
|
this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||||
|
| System.Windows.Forms.AnchorStyles.Right)));
|
||||||
|
this.button1.Location = new System.Drawing.Point(415, 12);
|
||||||
|
this.button1.Name = "button1";
|
||||||
|
this.button1.Size = new System.Drawing.Size(69, 25);
|
||||||
|
this.button1.TabIndex = 13;
|
||||||
|
this.button1.Text = "Папка";
|
||||||
|
this.button1.UseVisualStyleBackColor = true;
|
||||||
|
this.button1.Click += new System.EventHandler(this.LoadFolder);
|
||||||
//
|
//
|
||||||
// App
|
// App
|
||||||
//
|
//
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
this.ClientSize = new System.Drawing.Size(514, 391);
|
this.ClientSize = new System.Drawing.Size(514, 467);
|
||||||
this.Controls.Add(this.Label_Config);
|
this.Controls.Add(this.groupBox1);
|
||||||
this.Controls.Add(this.label12);
|
|
||||||
this.Controls.Add(this.Button_LoadConfig);
|
|
||||||
this.Controls.Add(this.groupBox4);
|
this.Controls.Add(this.groupBox4);
|
||||||
this.Controls.Add(this.GBox_Ethernet);
|
this.Controls.Add(this.GBox_Ethernet);
|
||||||
this.Controls.Add(this.groupBox2);
|
this.Controls.Add(this.groupBox2);
|
||||||
@@ -669,6 +695,8 @@
|
|||||||
this.panel18.PerformLayout();
|
this.panel18.PerformLayout();
|
||||||
this.groupBox4.ResumeLayout(false);
|
this.groupBox4.ResumeLayout(false);
|
||||||
this.groupBox4.PerformLayout();
|
this.groupBox4.PerformLayout();
|
||||||
|
this.groupBox1.ResumeLayout(false);
|
||||||
|
this.groupBox1.PerformLayout();
|
||||||
this.ResumeLayout(false);
|
this.ResumeLayout(false);
|
||||||
this.PerformLayout();
|
this.PerformLayout();
|
||||||
|
|
||||||
@@ -727,9 +755,11 @@
|
|||||||
private System.Windows.Forms.GroupBox groupBox4;
|
private System.Windows.Forms.GroupBox groupBox4;
|
||||||
private System.Windows.Forms.RadioButton Radio_Ethernet;
|
private System.Windows.Forms.RadioButton Radio_Ethernet;
|
||||||
private System.Windows.Forms.RadioButton Radio_SerialPort;
|
private System.Windows.Forms.RadioButton Radio_SerialPort;
|
||||||
|
private System.Windows.Forms.Label Label_ConfigTip;
|
||||||
private System.Windows.Forms.Button Button_LoadConfig;
|
private System.Windows.Forms.Button Button_LoadConfig;
|
||||||
private System.Windows.Forms.Label label12;
|
private System.Windows.Forms.GroupBox groupBox1;
|
||||||
private System.Windows.Forms.Label Label_Config;
|
private System.Windows.Forms.Button button1;
|
||||||
|
private System.Windows.Forms.Label Label_ConfPath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
226
Main.cs
226
Main.cs
@@ -8,17 +8,12 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using System.IO.Ports;
|
using System.IO.Ports;
|
||||||
using System.Drawing.Drawing2D;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Runtime;
|
|
||||||
using System.Web;
|
|
||||||
using System.Windows.Forms.Automation;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
|
||||||
namespace Gidrolock_Modbus_Scanner
|
namespace Gidrolock_Modbus_Scanner
|
||||||
{
|
{
|
||||||
public partial class App : Form
|
public partial class App : Form
|
||||||
@@ -32,18 +27,33 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
|
|
||||||
byte[] message = new byte[255];
|
byte[] message = new byte[255];
|
||||||
public bool isAwaitingResponse = false;
|
public bool isAwaitingResponse = false;
|
||||||
public bool isProcessingResponse = false;
|
|
||||||
public short[] res = new short[12];
|
public short[] res = new short[12];
|
||||||
public static SerialPort port = new SerialPort();
|
SerialPort port = Modbus.port;
|
||||||
public int expectedLength = 0;
|
public int expectedLength = 0;
|
||||||
Datasheet datasheet;
|
Datasheet datasheet;
|
||||||
|
public SelectedPath selectedPath = SelectedPath.Folder;
|
||||||
|
|
||||||
public static Device device;
|
public static Device device; // Deserialized .json object
|
||||||
|
string path = String.Empty; // Path to selected file/folder
|
||||||
|
string defaultPath = Application.StartupPath + "\\Configs"; // Default folder path
|
||||||
|
OpenFileDialog ofd = new OpenFileDialog();
|
||||||
|
FolderBrowserDialog fbd = new FolderBrowserDialog();
|
||||||
|
|
||||||
|
Dictionary<CheckEntry, List<Device>> juju = new Dictionary<CheckEntry, List<Device>>(); // dictionary for device identification
|
||||||
|
string[] configs;
|
||||||
|
|
||||||
|
public byte[] latestMessage;
|
||||||
#region Initialization
|
#region Initialization
|
||||||
public App()
|
public App()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
port.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(PortDataReceived);
|
Modbus.Init();
|
||||||
|
Modbus.ResponseReceived += OnResponseReceived;
|
||||||
|
ofd.InitialDirectory = Application.StartupPath;
|
||||||
|
ofd.Filter = "JSON files (*.json)|*.json";
|
||||||
|
ofd.FilterIndex = 2;
|
||||||
|
ofd.RestoreDirectory = true;
|
||||||
|
|
||||||
this.UpDown_ModbusID.Value = 30;
|
this.UpDown_ModbusID.Value = 30;
|
||||||
TextBox_Log.Text = "Приложение готово к работе.";
|
TextBox_Log.Text = "Приложение готово к работе.";
|
||||||
|
|
||||||
@@ -102,6 +112,22 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
TBox_IP.Text = "192.168.3.7";
|
TBox_IP.Text = "192.168.3.7";
|
||||||
TBox_Port.Text = "8887";
|
TBox_Port.Text = "8887";
|
||||||
TBox_Timeout.Text = "3";
|
TBox_Timeout.Text = "3";
|
||||||
|
if (Directory.GetDirectories(Application.StartupPath).Contains(Application.StartupPath + "\\Configs") == false)
|
||||||
|
{
|
||||||
|
Task.Delay(1500).ContinueWith(t =>
|
||||||
|
{
|
||||||
|
MessageBox.Show("Приложение не нашло стандартную папку для конфигураций. Была создана папка 'Configs' в папке с приложением.");
|
||||||
|
Directory.CreateDirectory(Application.StartupPath + "\\Configs");
|
||||||
|
Console.WriteLine("New initial directory for OpenFile: " + ofd.InitialDirectory);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
ofd.InitialDirectory = Application.StartupPath + "\\Configs";
|
||||||
|
path = defaultPath;
|
||||||
|
UpdatePathLabel();
|
||||||
|
}
|
||||||
|
void UpdatePathLabel()
|
||||||
|
{
|
||||||
|
Label_ConfPath.Text = path;
|
||||||
}
|
}
|
||||||
void App_FormClosed(object sender, FormClosedEventArgs e)
|
void App_FormClosed(object sender, FormClosedEventArgs e)
|
||||||
{
|
{
|
||||||
@@ -205,10 +231,18 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
|
|
||||||
private async void ButtonConnect_Click(object sender, EventArgs e)
|
private async void ButtonConnect_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (device is null)
|
if (path == String.Empty)
|
||||||
MessageBox.Show("Выберите конфигурацию для подключения и опроса устройства.");
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
MessageBox.Show("Выберите конфигурацию для подключения и опроса устройства.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (CBox_Ports.SelectedItem.ToString() == "COM1")
|
||||||
|
{
|
||||||
|
DialogResult res = MessageBox.Show("Выбран серийный порт COM1, который обычно является портом PS/2 или RS-232, не подключенным к Modbus устройству. Продолжить?", "Внимание", MessageBoxButtons.OKCancel);
|
||||||
|
if (res == DialogResult.Cancel)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* - Port Setup - */
|
/* - Port Setup - */
|
||||||
if (port.IsOpen)
|
if (port.IsOpen)
|
||||||
port.Close();
|
port.Close();
|
||||||
@@ -227,6 +261,81 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
message = new byte[255];
|
message = new byte[255];
|
||||||
port.Open();
|
port.Open();
|
||||||
|
|
||||||
|
/* - Checking - */
|
||||||
|
if (selectedPath == SelectedPath.File)
|
||||||
|
{
|
||||||
|
var fileContent = string.Empty;
|
||||||
|
var filePath = string.Empty;
|
||||||
|
//Read the contents of the file into a stream
|
||||||
|
var fileStream = ofd.OpenFile();
|
||||||
|
|
||||||
|
using (StreamReader reader = new StreamReader(fileStream))
|
||||||
|
{
|
||||||
|
fileContent = reader.ReadToEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
device = JsonConvert.DeserializeObject<Device>(fileContent);
|
||||||
|
Label_ConfigTip.Text = device.name;
|
||||||
|
}
|
||||||
|
catch (Exception err)
|
||||||
|
{
|
||||||
|
MessageBox.Show(err.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string[] _configs = Directory.GetFiles(path, "*.json");
|
||||||
|
if (configs != _configs)
|
||||||
|
{
|
||||||
|
// something changed in the config folder, or we haven't gone through configs,
|
||||||
|
// remake the dictionary
|
||||||
|
configs = _configs;
|
||||||
|
juju = new Dictionary<CheckEntry, List<Device>>();
|
||||||
|
|
||||||
|
var fileContent = string.Empty;
|
||||||
|
FileStream fileStream;
|
||||||
|
Device _device;
|
||||||
|
|
||||||
|
foreach (string path in configs)
|
||||||
|
{
|
||||||
|
fileStream = File.OpenRead(path);
|
||||||
|
using (StreamReader reader = new StreamReader(fileStream))
|
||||||
|
fileContent = reader.ReadToEnd();
|
||||||
|
// get device object from .json
|
||||||
|
_device = JsonConvert.DeserializeObject<Device>(fileContent);
|
||||||
|
|
||||||
|
// compare device object to key of each dictionary;
|
||||||
|
// add to that dictionary if device's check entry registers match the key
|
||||||
|
foreach (CheckEntry ce in juju.Keys)
|
||||||
|
{
|
||||||
|
if (_device.checkEntry.address == ce.address && _device.checkEntry.length == ce.length && _device.checkEntry.dataType == ce.dataType)
|
||||||
|
{
|
||||||
|
juju[ce].Add(_device);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
// all configs are sorted out, we can poll for each checkEntry
|
||||||
|
|
||||||
|
foreach (CheckEntry ce in juju.Keys)
|
||||||
|
{
|
||||||
|
byte[] response;
|
||||||
|
// send read request to device,
|
||||||
|
// check for error codes or timeouts
|
||||||
|
// if we get normal response, go through
|
||||||
|
}
|
||||||
|
|
||||||
|
// with dictionaries arranged, go through every key, discarding those that return error
|
||||||
|
// if device returns a coherent reply, go through expected values associated with the key
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AddLog("Попытка подключиться к устройству " + device.name);
|
AddLog("Попытка подключиться к устройству " + device.name);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -242,7 +351,7 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
await SendMessageAsync(FunctionCode.InputRegister, 200, 6);
|
await SendMessageAsync(FunctionCode.InputRegister, 200, 6);
|
||||||
//else EthernetParse();
|
//else EthernetParse();
|
||||||
*/
|
*/
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async void EthernetParse()
|
async void EthernetParse()
|
||||||
@@ -267,7 +376,6 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
|
|
||||||
// set up an event listener to receive the response
|
// set up an event listener to receive the response
|
||||||
await SocketDataTransfer(data);
|
await SocketDataTransfer(data);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -278,50 +386,11 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
CBox_Ports.Items.AddRange(SerialPort.GetPortNames());
|
CBox_Ports.Items.AddRange(SerialPort.GetPortNames());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PortDataReceived(object sender, EventArgs e)
|
void OnResponseReceived(object sender, ModbusResponseEventArgs e)
|
||||||
{
|
{
|
||||||
if (datasheet is null)
|
|
||||||
return;
|
|
||||||
if (datasheet.Enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Console.WriteLine("Data receieved on Serial Port");
|
|
||||||
isAwaitingResponse = false;
|
isAwaitingResponse = false;
|
||||||
|
TextBox_Log.Invoke((MethodInvoker)delegate { AddLog("Получен ответ: " + Modbus.ByteArrayToString(e.message)); });
|
||||||
if (!isProcessingResponse)
|
TextBox_Log.Invoke((MethodInvoker)delegate { AddLog("UTF8: " + Encoding.UTF8.GetString(e.message)); });
|
||||||
{
|
|
||||||
isProcessingResponse = true;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
port.Read(message, 0, 3);
|
|
||||||
int length = (int)message[2];
|
|
||||||
for (int i = 0; i < length + 2; i++)
|
|
||||||
{
|
|
||||||
port.Read(message, i + 3, 1);
|
|
||||||
}
|
|
||||||
byte[] data = new byte[length];
|
|
||||||
for (int i = 0; i < length; i++)
|
|
||||||
{
|
|
||||||
data[i] = message[i + 3];
|
|
||||||
}
|
|
||||||
|
|
||||||
string dataCleaned = Modbus.ByteArrayToString(message);
|
|
||||||
TextBox_Log.Invoke((MethodInvoker)delegate { AddLog("Получен ответ: " + dataCleaned); });
|
|
||||||
TextBox_Log.Invoke((MethodInvoker)delegate { AddLog("ASCII: " + "wip"); });
|
|
||||||
|
|
||||||
port.DiscardInBuffer();
|
|
||||||
isProcessingResponse = false;
|
|
||||||
}
|
|
||||||
catch (Exception err)
|
|
||||||
{
|
|
||||||
MessageBox.Show(err.Message);
|
|
||||||
isProcessingResponse = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else Console.WriteLine("Already processing incoming message!");
|
|
||||||
|
|
||||||
//port.Close();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddLog(string message)
|
void AddLog(string message)
|
||||||
@@ -391,42 +460,31 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
|
|
||||||
private void LoadConfig(object sender, EventArgs e)
|
private void LoadConfig(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var fileContent = string.Empty;
|
if (ofd.ShowDialog() == DialogResult.OK)
|
||||||
var filePath = string.Empty;
|
|
||||||
|
|
||||||
using (OpenFileDialog openFileDialog = new OpenFileDialog())
|
|
||||||
{
|
|
||||||
openFileDialog.InitialDirectory = Application.StartupPath;
|
|
||||||
openFileDialog.Filter = "JSON files (*.json)|*.json";
|
|
||||||
openFileDialog.FilterIndex = 2;
|
|
||||||
openFileDialog.RestoreDirectory = true;
|
|
||||||
|
|
||||||
if (openFileDialog.ShowDialog() == DialogResult.OK)
|
|
||||||
{
|
{
|
||||||
//Get the path of specified file
|
//Get the path of specified file
|
||||||
filePath = openFileDialog.FileName;
|
path = ofd.FileName;
|
||||||
|
Label_ConfPath.Text = ofd.FileName;
|
||||||
|
|
||||||
//Read the contents of the file into a stream
|
selectedPath = SelectedPath.File;
|
||||||
var fileStream = openFileDialog.OpenFile();
|
}
|
||||||
|
UpdatePathLabel();
|
||||||
using (StreamReader reader = new StreamReader(fileStream))
|
|
||||||
{
|
|
||||||
fileContent = reader.ReadToEnd();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
private void LoadFolder(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
device = JsonConvert.DeserializeObject<Device>(fileContent);
|
|
||||||
Label_Config.Text = device.name;
|
fbd.RootFolder = Environment.SpecialFolder.MyComputer;
|
||||||
}
|
if (fbd.ShowDialog() == DialogResult.OK)
|
||||||
catch (Exception err)
|
|
||||||
{
|
{
|
||||||
MessageBox.Show(err.Message);
|
path = fbd.SelectedPath;
|
||||||
}
|
Label_ConfPath.Text = fbd.SelectedPath;
|
||||||
}
|
selectedPath = SelectedPath.Folder;
|
||||||
}
|
}
|
||||||
|
UpdatePathLabel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum FunctionCode { ReadCoil = 1, ReadDiscrete = 2, ReadHolding = 3, ReadInput = 4, WriteCoil = 5, WriteRegister = 6, WriteMultCoils = 15, WriteMultRegisters = 16};
|
public enum FunctionCode { ReadCoil = 1, ReadDiscrete = 2, ReadHolding = 3, ReadInput = 4, WriteCoil = 5, WriteRegister = 6, WriteMultCoils = 15, WriteMultRegisters = 16 };
|
||||||
|
public enum SelectedPath { File, Folder };
|
||||||
|
|||||||
92
Modbus.cs
92
Modbus.cs
@@ -1,17 +1,23 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO.Ports;
|
using System.IO.Ports;
|
||||||
using System.Runtime;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace Gidrolock_Modbus_Scanner
|
namespace Gidrolock_Modbus_Scanner
|
||||||
{
|
{
|
||||||
public static class Modbus
|
public static class Modbus
|
||||||
{
|
{
|
||||||
|
public static SerialPort port = new SerialPort();
|
||||||
|
|
||||||
|
|
||||||
|
public static event EventHandler<ModbusResponseEventArgs> ResponseReceived = delegate { };
|
||||||
|
|
||||||
|
public static void Init()
|
||||||
|
{
|
||||||
|
port.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(PortDataReceived);
|
||||||
|
}
|
||||||
|
|
||||||
#region Build Message
|
#region Build Message
|
||||||
public static byte[] BuildMessage(byte modbusID, byte functionCode, ushort address, ushort length, ref byte[] message)
|
public static byte[] BuildMessage(byte modbusID, byte functionCode, ushort address, ushort length, ref byte[] message)
|
||||||
{
|
{
|
||||||
@@ -116,20 +122,7 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
|
|
||||||
public static string ByteArrayToString(byte[] bytes)
|
public static string ByteArrayToString(byte[] bytes)
|
||||||
{
|
{
|
||||||
int length = bytes.Length - 1;
|
byte[] res = CleanByteArray(bytes);
|
||||||
// snip off the empty bytes at the end
|
|
||||||
for (int i = length; i >= 0; i--)
|
|
||||||
{
|
|
||||||
if (bytes[i] != 0)
|
|
||||||
{
|
|
||||||
length = i + 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] res = new byte[length];
|
|
||||||
for (int i = 0; i < length; i++)
|
|
||||||
res[i] = bytes[i];
|
|
||||||
|
|
||||||
string dataString = BitConverter.ToString(res);
|
string dataString = BitConverter.ToString(res);
|
||||||
string result = "";
|
string result = "";
|
||||||
@@ -142,6 +135,25 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
public static byte[] CleanByteArray(byte[] bytes)
|
||||||
|
{
|
||||||
|
int length = bytes.Length - 1;
|
||||||
|
// snip off the empty bytes at the end
|
||||||
|
for (int i = length; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (bytes[i] != 0)
|
||||||
|
{
|
||||||
|
length = i + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] res = new byte[length];
|
||||||
|
for (int i = 0; i < length; i++) { res[i] = bytes[i]; }
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#region CRC Computation
|
#region CRC Computation
|
||||||
static void GetCRC(byte[] message, ref byte[] CRC)
|
static void GetCRC(byte[] message, ref byte[] CRC)
|
||||||
@@ -170,5 +182,49 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
CRC[0] = CRCLow = (byte)(CRCFull & 0xFF);
|
CRC[0] = CRCLow = (byte)(CRCFull & 0xFF);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
static void PortDataReceived(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Data receieved on Serial Port");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] message = new byte[port.BytesToRead];
|
||||||
|
port.Read(message, 0, 3);
|
||||||
|
int length = (int)message[2];
|
||||||
|
for (int i = 0; i < length + 2; i++)
|
||||||
|
{
|
||||||
|
port.Read(message, i + 3, 1);
|
||||||
}
|
}
|
||||||
|
Console.WriteLine("Raw data from port: " + BitConverter.ToString(message));
|
||||||
|
byte[] data = new byte[length];
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
data[i] = message[i + 3];
|
||||||
|
}
|
||||||
|
string dataCleaned = ByteArrayToString(message);
|
||||||
|
Console.WriteLine("Received response: " + dataCleaned);
|
||||||
|
Console.WriteLine("UTF8: " + Encoding.UTF8.GetString(data));
|
||||||
|
|
||||||
|
port.DiscardInBuffer();
|
||||||
|
|
||||||
|
ResponseReceived.Invoke(null, new ModbusResponseEventArgs(message));
|
||||||
|
}
|
||||||
|
catch (Exception err)
|
||||||
|
{
|
||||||
|
MessageBox.Show(err.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ModbusResponseEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public byte[] message { get; set; }
|
||||||
|
public ModbusResponseEventArgs(byte[] message)
|
||||||
|
{
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user