轮胎外观检测添加思谋语义分割模型检测工具
C3204
6 小时以前 dc18021539bdf4ee176ec9d9b88eb7d9ad581600
LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorS7Form.cs
@@ -1,11 +1,17 @@
using LB_VisionProcesses.Communicators;
using LB_SmartVisionCommon;
using LB_VisionProcesses.Communicators;
using LB_VisionProcesses.Communicators.SiemensS7;
using LB_VisionProcesses.Communicators.Tcom;
using Microsoft.VisualBasic;
using OpenVinoSharp.Extensions.model;
using ReaLTaiizor.Forms;
using RJCP.IO.Ports;
using S7.Net;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Windows.Forms;
using YamlDotNet.Core.Tokens;
namespace LB_SmartVision.Forms.Pages.CommunicatorPage
{
@@ -15,6 +21,11 @@
        BaseCommunicator communicator { get; set; }
        public event CommunicatorS7Change CommunicatorChanged;
        private PlcConfig config;
        private DataTable signalTable;
        private BindingSource bindingSource;
        private string Name;
        private void communicatorChanged(BaseCommunicator communicator)
        {
@@ -44,60 +55,14 @@
            cmbIP.Enabled = false;
            txtIP.Enabled = false;
            txtPort.Enabled = false;
            cmbDataType.Enabled = false;
            lblType.Visible = false;
            lblAddress.Visible = false;
            cmbType.Visible = false;
            txtAddress.Visible = false;
            lblDataType.Visible = false;
            cmbDataType.Visible = false;
            Name = name;
            this.Text = name;
            if (communicator is UARTPort)
            {
                //统计可用端口
                SerialPortStream temp = new SerialPortStream();
                string[] ArryPort = temp.GetPortNames();
                for (int i = 0; i < ArryPort.Length; i++)
                {
                    cmbIP.Items.Add(ArryPort[i]);
                }
                cmbIP.Text = communicator.CommunicatorConnections["地址"]?.ToString();
                txtPort.Text = communicator.CommunicatorConnections["端口"]?.ToString();
                txtIP.Visible = false;
                cmbIP.Visible = true;
                this.btnRuleSend.Visible = true;
                lblType.Visible = false;
                lblAddress.Visible = false;
                cmbType.Visible = false;
                txtAddress.Visible = false;
                lblDataType.Visible = false;
                cmbDataType.Visible = false;
                lblIP.Text = "COM口";
                lblPort.Text = "波特率";
            }
            else if (communicator is TCPClient || communicator is TCPServer)
            {
                txtIP.Text = communicator.CommunicatorConnections["地址"]?.ToString();
                txtPort.Text = communicator.CommunicatorConnections["端口"]?.ToString();
                txtIP.Visible = true;
                cmbIP.Visible = false;
                this.btnRuleSend.Visible = false;
                lblType.Visible = false;
                lblAddress.Visible = false;
                cmbType.Visible = false;
                txtAddress.Visible = false;
                lblDataType.Visible = false;
                cmbDataType.Visible = false;
                lblIP.Text = "地址";
                lblPort.Text = "端口";
            }
            else if (communicator is SiemensLBS7)
            if (communicator is SiemensLBS7)
            {
                txtIP.Text = communicator.CommunicatorConnections["地址"]?.ToString();
                txtPort.Text = communicator.CommunicatorConnections["端口"]?.ToString();
@@ -107,33 +72,10 @@
                    cmbType.Items.Add(communicator.CommunicatorConnections["型号"]?.ToString());
                    cmbType.Text = communicator.CommunicatorConnections["型号"]?.ToString();
                }
                if (!string.IsNullOrEmpty(communicator.CommunicatorConnections["变量地址"]?.ToString()))
                {
                    txtAddress.Text = communicator.CommunicatorConnections["变量地址"]?.ToString();
                }
                // 初始化数据类型
                cmbDataType.Items.Clear();
                cmbDataType.Items.AddRange(new string[] { "String", "Bool", "Byte", "Int", "DInt", "Real", "Double", "Word", "DWord" });
                if (communicator.CommunicatorConnections.Contains("数据类型"))
                {
                    cmbDataType.Text = communicator.CommunicatorConnections["数据类型"].ToString();
                }
                else
                {
                    cmbDataType.Text = "String";
                }
                txtIP.Visible = true;
                cmbIP.Visible = false;
                this.btnRuleSend.Visible = false;
                lblType.Visible = true;
                lblAddress.Visible = true;
                cmbType.Visible = true;
                txtAddress.Visible = true;
                lblDataType.Visible = true;
                cmbDataType.Visible = true;
                cmbDataType.Enabled = true; // 启用数据类型选择
                lblIP.Text = "IP";
                lblPort.Text = "槽";
@@ -142,15 +84,7 @@
            this.communicator = communicator;
            //加载回调函数
            Subscribe();
        }
        private void cmbDataType_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (communicator != null)
            {
                communicator.CommunicatorConnections.Add("数据类型", cmbDataType.Text);
                communicatorChanged(communicator);
            }
            LoadConfigAndSetupGrid();
        }
        private void CommunicatorForm_FormClosing(object sender, FormClosingEventArgs e) => Unsubscribe();
@@ -274,59 +208,233 @@
            }
        }
        private void btnSend_Click(object sender, EventArgs e)
        // 批量读取所有信号
        private void btnReadAll_Click(object sender, EventArgs e)
        {
            if (communicator == null)
            if (communicator == null || !communicator.bConnected)
            {
                MessageBox.Show("请先连接 PLC", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            if (communicator.SendMessage(txtSendMsg.Text))
            try
            {
                ShowSendMsg(txtSendMsg.Text);
                for (int i = 0; i < config.Signals.Count; i++)
                {
                    var signal = config.Signals[i];
                    object value = ((SiemensLBS7)communicator).ReadSignal(signal);
                    config.Signals[i].Value= value?.ToString() ?? "";
                    signalTable.Rows[i]["Value"] = config.Signals[i].Value;
                    ShowLogMsg(signalTable.Rows[i]["Value"] + ":" + value?.ToString() ?? "");
                }
            }
            else
            catch (Exception ex)
            {
                ShowLogMsg(communicator.Msg);
                MessageBox.Show($"批量读取失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private void btnRuleSend_Click(object sender, EventArgs e)
        // 批量写入:将表格中修改过的值写入 PLC
        private void btnWriteAll_Click(object sender, EventArgs e)
        {
            if (communicator == null)
            if (communicator == null || !communicator.bConnected)
            {
                MessageBox.Show("请先连接 PLC", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            string SendMsg = txtSendMsg.Text;
            //byte[] HexByte = BaseCommunicator.strToHexByte(SendMsg);
            byte[] HexByte = SendMsg.Split(' ', StringSplitOptions.RemoveEmptyEntries)
                                        .Select(hex => Convert.ToByte(hex, 16))
                                        .ToArray();
            ushort crcHexByte = BaseCommunicator.CRC16Calculate(HexByte, HexByte.Length);
            string crcString = crcHexByte.ToString("X4");
            crcString = crcString.Insert(2, " ");
            HexByte = BaseCommunicator.strToHexByte(SendMsg + " " + crcString);
            if (communicator.SendMessage(HexByte))
            try
            {
                ShowSendMsg(SendMsg + " " + crcString);
                int successCount = 0;
                for (int i = 0; i < config.Signals.Count; i++)
                {
                    var signal = config.Signals[i];
                    string newValueStr = signalTable.Rows[i]["Value"]?.ToString();
                    if (!string.IsNullOrEmpty(newValueStr))
                    {
                        object convertedValue = ConvertValue(signal.DataType, newValueStr);
                        ((SiemensLBS7)communicator).WriteSignal(signal, convertedValue);
                        successCount++;
                    }
                    ShowSendMsg(signalTable.Rows[i]["Value"] + ":" + newValueStr?.ToString() ?? "");
                }
                MessageBox.Show($"批量写入完成,成功写入 {successCount} 个信号。", "写入结果", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            catch (Exception ex)
            {
                ShowLogMsg(communicator.Msg);
                MessageBox.Show($"批量写入失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private void txtAddress_TextChanged(object sender, EventArgs e)
        private void btnConfig_Click(object sender, EventArgs e)
        {
            if (communicator != null)
            using (var configForm = new ConfigForm(config, GlobalVar.allPlcSettingPath + "\\" + this.Name + ".json"))
            {
                communicator.CommunicatorConnections.Add("变量地址", txtAddress.Text);
                communicatorChanged(communicator);
                if (configForm.ShowDialog() == DialogResult.OK)
                {
                    config = S7ConfigService.LoadConfig(GlobalVar.allPlcSettingPath);
                    LoadConfigAndSetupGrid();
                    UpdateConnectionStatus();
                }
            }
        }
        // 数据类型转换辅助方法
        private object ConvertValue(string dataType, string valueStr)
        {
            switch (dataType)
            {
                case "Bool":
                    {
                        if (bool.TryParse(valueStr, out bool b)) return b;
                        if (valueStr == "1") return true;
                        if (valueStr == "0") return false;
                        throw new Exception("无效的布尔值");
                    }
                case "Byte":
                    {
                        return byte.Parse(valueStr);
                    }
                case "Int":
                    {
                        return short.Parse(valueStr);
                    }
                case "DInt":
                    {
                        return int.Parse(valueStr);
                    }
                case "Real":
                    {
                        return float.Parse(valueStr);
                    }
                case "String":
                    {
                        return valueStr;
                    }
                default:
                    {
                        throw new NotSupportedException($"不支持的类型: {dataType}");
                    }
            }
        }
        private void LoadConfigAndSetupGrid()
        {
            config = S7ConfigService.LoadConfig(GlobalVar.allPlcSettingPath + "\\" + this.Name + ".json");
            if (GlobalVar.allPlcSettings.Keys.Contains(Name))
            {
                GlobalVar.allPlcSettings[Name] = config;
            }
            else
            {
                GlobalVar.allPlcSettings.TryAdd(Name, config);
            }
            ConfigManager<Dictionary<string, PlcConfig>>.SaveConfig<Dictionary<string, PlcConfig>>(GlobalVar.allPlcSettings, GlobalVar.allPlcSettingsPath);
            // 构建 DataTable 用于展示信号(支持编辑值列)
            signalTable = new DataTable();
            signalTable.Columns.Add("SignalName", typeof(string));
            signalTable.Columns.Add("Address", typeof(string));
            signalTable.Columns.Add("Value", typeof(string));
            foreach (var signal in config.Signals)
            {
                string address = $"{signal.Area}";
                if (signal.Area == "DB")
                    address += $"{signal.DbNumber}.DB";
                address += $"{signal.ByteOffset}.{signal.BitOffset}";
                signalTable.Rows.Add(signal.SignalName, address, "");
            }
            bindingSource = new BindingSource();
            bindingSource.DataSource = signalTable;
            dgvSignals.DataSource = bindingSource;
            dgvSignals.Columns["SignalName"].HeaderText = "信号名称";
            dgvSignals.Columns["SignalName"].ReadOnly = true;
            dgvSignals.Columns["Address"].HeaderText = "PLC 地址";
            dgvSignals.Columns["Address"].ReadOnly = true;
            dgvSignals.Columns["Value"].HeaderText = "当前值";
            dgvSignals.Columns["Value"].ReadOnly = false;  // 允许用户编辑
            UpdateConnectionStatus();
            dgvSignals.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
        }
        private void UpdateConnectionStatus()
        {
            if (communicator != null && communicator.bConnected)
            {
                lblStatus.Text = $"已连接: {config.PlcIpAddress}";
                lblStatus.ForeColor = Color.Green;
            }
            else
            {
                lblStatus.Text = "未连接";
                lblStatus.ForeColor = Color.Red;
            }
        }
        // ========== 右键菜单:单信号操作 ==========
        private SignalConfig GetSelectedSignal()
        {
            if (dgvSignals.CurrentRow == null) return null;
            int index = dgvSignals.CurrentRow.Index;
            if (index >= 0 && index < config.Signals.Count)
                return config.Signals[index];
            return null;
        }
        private void menuReadSignal_Click(object sender, EventArgs e)
        {
            var signal = GetSelectedSignal();
            if (signal == null) return;
            if (communicator != null && !communicator.bConnected)
            {
                MessageBox.Show("请先连接 PLC");
                return;
            }
            try
            {
                object value = ((SiemensLBS7)communicator).ReadSignal(signal);
                MessageBox.Show($"信号 [{signal.SignalName}] 当前值: {value}", "读取结果");
                signalTable.Rows[dgvSignals.CurrentRow.Index]["Value"] = value?.ToString();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"读取失败: {ex.Message}");
            }
        }
        private void menuWriteSignal_Click(object sender, EventArgs e)
        {
            var signal = GetSelectedSignal();
            if (signal == null) return;
            if (communicator != null && !communicator.bConnected)
            {
                MessageBox.Show("请先连接 PLC");
                return;
            }
            string input = Interaction.InputBox(
                $"请输入要写入 {signal.SignalName} 的值 ({signal.DataType})",
                "写入信号", "");
            if (string.IsNullOrEmpty(input)) return;
            try
            {
                object value = ConvertValue(signal.DataType, input);
                ((SiemensLBS7)communicator).WriteSignal(signal, value);
                MessageBox.Show("写入成功");
            }
            catch (Exception ex)
            {
                MessageBox.Show($"写入失败: {ex.Message}");
            }
        }
    }