using System; using System.Collections.ObjectModel; using System.Linq; using 常用工具集.Base; using System.Threading; using OpcUaHelper; using Org.BouncyCastle.Crypto.Tls; using System.Threading.Tasks; using Opc.Ua.Client; using Opc.Ua; using Ursa.Controls; namespace 常用工具集.ViewModel._01PLC通信调试 { public class OPCUA调试ViewModel : ViewModelBase { private bool stop = false; private OpcUaClient client; private object _lock = new object(); private Thread thread; public bool Enabled1 { get; set; } = true; public bool Enabled2 { get; set; } = false; public string OpcServer { get; set; } = "opc.tcp://10.10.0.40"; public string Node { get; set; } = "ns=4;s=|var|Inovance-ARM-Linux.Application.StorageDatas.gStorageDatas[10].MaterialInfo.Width"; public string Result { get; set; } = ""; public string WriteValue { get; set; } = ""; public string SelecedValue { get; set; } = ""; public int SelectedIndex { get; set; } = -1; public ObservableCollection NodeList { get; set; } = new ObservableCollection(); public DelegateCommand ConnectCmd { get; set; } public DelegateCommand DisconnectCmd { get; set; } public DelegateCommand SubscribeCmd { get; set; } public DelegateCommand ReadValueCmd { get; set; } public DelegateCommand WriteValueCmd { get; set; } public DelegateCommand CancelSubscribeCmd { get; set; } public DelegateCommand OpenBrowerCmd { get; set; } public OPCUA调试ViewModel() { ConnectCmd = new DelegateCommand(ConnectCmdFunc); DisconnectCmd = new DelegateCommand(DisconnectCmdFunc); SubscribeCmd = new DelegateCommand(SubscribeCmdFunc); ReadValueCmd = new DelegateCommand(ReadValueCmdFunc); WriteValueCmd = new DelegateCommand(WriteValueCmdFunc); CancelSubscribeCmd = new DelegateCommand(CancelSubscribeCmdFunc); OpenBrowerCmd = new DelegateCommand(OpenBrowerCmdFunc); } private void OpenBrowerCmdFunc(object obj) { //new OpcUaHelper.Forms.FormBrowseServer().Show(); } /// /// 建立连接 /// /// private void ConnectCmdFunc(object obj) { try { client = new OpcUaClient(); DateTime start = DateTime.Now; bool connected = false; Task task = client.ConnectServer(OpcServer); while (true) { if (client.Connected) { connected = true; break; } if ((DateTime.Now - start).TotalMilliseconds > 1000) { break; } } if (!connected) { GlobalValues.Error($"连接失败"); client = null; return; } Enabled1 = false; Enabled2 = true; stop = false; thread = new Thread(() => { while (true) { try { if (stop) { break; } Loop(); Thread.Sleep(1000); } catch (ThreadInterruptedException ex) { break; } catch (Exception e) { } } }); thread.Start(); } catch (Exception ex) { GlobalValues.Error($"连接失败:{ex.Message}"); } } /// /// 断开连接 /// /// private void DisconnectCmdFunc(object obj) { foreach (MyNode node in NodeList) { client.RemoveSubscription(node.NodeName); } NodeList.Clear(); client.Disconnect(); client = null; Enabled1 = true; Enabled2 = false; stop = true; thread.Interrupt(); thread = null; } private void SubscribeCmdFunc(object obj) { string node = Node; if (NodeList.Any(x => x.NodeName == node)) return; lock (_lock) { NodeList.Add(new MyNode { NodeName = node, Value = null }); } client.AddSubscription(node, node, CallBack); } private void CallBack(string key, MonitoredItem item, MonitoredItemNotificationEventArgs itemNotify) { MonitoredItemNotification notification = itemNotify.NotificationValue as MonitoredItemNotification; DataValue dataValue = notification.Value; bool isGood = StatusCode.IsGood(dataValue.StatusCode); if (isGood) { lock (_lock) { MyNode node = NodeList.Where(it => it.NodeName == key).FirstOrDefault(); node.Value = dataValue.Value; } } else { lock (_lock) { MyNode node = NodeList.Where(it => it.NodeName == key).FirstOrDefault(); node.Value = null; } } } private void ReadValueCmdFunc(object obj) { try { DataValue dataValue = client.ReadNode(new NodeId(Node)); if (!StatusCode.IsGood(dataValue.StatusCode)) { Result = ""; GlobalValues.Error("读取失败"); return; } Result = dataValue.Value.ToString(); GlobalValues.Success($"读取成功"); } catch (Exception ex) { Result = ""; GlobalValues.Error($"读取失败:{ex.Message}"); } } private void WriteValueCmdFunc(object obj) { try { string cmd = obj.ToString(); if (cmd == "bool") { bool value; bool flag = bool.TryParse(WriteValue, out value); if (!flag) { GlobalValues.Error("数据转换失败,请输入正确的数据"); return; } flag = client.WriteNode(Node, value); if (!flag) { GlobalValues.Error("写入失败"); return; } GlobalValues.Success("写入成功"); } else if (cmd == "uint16") { ushort value; bool flag = ushort.TryParse(WriteValue, out value); if (!flag) { GlobalValues.Error("数据转换失败,请输入正确的数据"); return; } flag = client.WriteNode(Node, value); if (!flag) { GlobalValues.Error("写入失败"); return; } GlobalValues.Success("写入成功"); } else if (cmd == "int16") { short value; bool flag = short.TryParse(WriteValue, out value); if (!flag) { GlobalValues.Error("数据转换失败,请输入正确的数据"); return; } flag = client.WriteNode(Node, value); if (!flag) { GlobalValues.Error("写入失败"); return; } GlobalValues.Success("写入成功"); } else if (cmd == "int32") { int value; bool flag = int.TryParse(WriteValue, out value); if (!flag) { GlobalValues.Error("数据转换失败,请输入正确的数据"); return; } flag = client.WriteNode(Node, value); if (!flag) { GlobalValues.Error("写入失败"); return; } GlobalValues.Success("写入成功"); } else if (cmd == "int64") { long value; bool flag = long.TryParse(WriteValue, out value); if (!flag) { GlobalValues.Error("数据转换失败,请输入正确的数据"); return; } flag = client.WriteNode(Node, value); if (!flag) { GlobalValues.Error("写入失败"); return; } GlobalValues.Success("写入成功"); } else if (cmd == "float") { float value; bool flag = float.TryParse(WriteValue, out value); if (!flag) { GlobalValues.Error("数据转换失败,请输入正确的数据"); return; } flag = client.WriteNode(Node, value); if (!flag) { GlobalValues.Error("写入失败"); return; } GlobalValues.Success("写入成功"); } else if (cmd == "double") { double value; bool flag = double.TryParse(WriteValue, out value); if (!flag) { GlobalValues.Error("数据转换失败,请输入正确的数据"); return; } flag = client.WriteNode(Node, value); if (!flag) { GlobalValues.Error("写入失败"); return; } GlobalValues.Success("写入成功"); } } catch (Exception ex) { MessageBox.ShowAsync(ex.Message); } } /// /// 取消订阅 /// /// private void CancelSubscribeCmdFunc(object obj) { try { if (SelectedIndex < 0) { return; } lock (_lock) { MyNode selectKey = NodeList[SelectedIndex]; client.RemoveSubscription(selectKey.NodeName); NodeList.RemoveAt(SelectedIndex); } } catch (Exception ex) { } } private void Loop() { if (SelectedIndex < 0) { return; } lock (_lock) { MyNode selectKey = NodeList[SelectedIndex]; object value = selectKey.Value; if (value == null) { SelecedValue = ""; } else { SelecedValue = value.ToString(); } } } } public class MyNode : ViewModelBase { public string NodeName { get; set; } public object Value { get; set; } } }