/// <summary> /// Returns the localized text for the specified result code. /// </summary> /// <param name="locale">The locale name in the format "[languagecode]-[country/regioncode]".</param> /// <param name="resultId">The result code identifier.</param> /// <returns>A message localized for the best match for the requested locale.</returns> public override string GetErrorText(string locale, OpcResult resultId) { lock (this) { if (m_server == null) { throw new NotConnectedException(); } string methodName = "IOPCServer.GetErrorString"; // invoke COM method. try { string errorText = null; IOPCServer server = BeginComCall <IOPCServer>(methodName, true); ((IOPCServer)m_server).GetErrorString( resultId.Code, Technosoftware.DaAeHdaClient.Com.Interop.GetLocale(locale), out errorText); return(errorText); } catch (Exception e) { ComCallError(methodName, e); throw Technosoftware.DaAeHdaClient.Com.Interop.CreateException("IOPCServer.GetErrorString", e); } finally { EndComCall(methodName); } } }
/// <summary> /// 写入数据 /// </summary> /// <param name="sender"></param> /// <param name="e"></param>; private void btnWriteDataItem_Click(object sender, RoutedEventArgs e) { string message = null; if (!opcClienthelper.IsConnected) { message = DateTime.Now.ToString(dateString) + "请先连接服务器" + System.Environment.NewLine; asyncUpMessage(message); return; } OpcDataItem opcDataItem = null; OpcResult opcResult = OpcResult.Unknow; if (Equals(null, opcClienthelper.OpcDataItems) || opcClienthelper.OpcDataItems.Count < 1) { message = DateTime.Now.ToString(dateString) + "没有数据点" + System.Environment.NewLine; } else { opcDataItem = opcClienthelper.OpcDataItems.FirstOrDefault().Clone() as OpcDataItem; //bool newValue = (DateTime.Now.Millisecond % 2) == 0 ? true : false; //bool newValue = !tmpValue; //tmpValue = newValue; //System.Diagnostics.Debug.Print(tmpValue.ToString()); opcResult = opcClienthelper.Write(opcDataItem, 1); message = DateTime.Now.ToString(dateString) + "写入完成 " + opcResult + " " + (opcDataItem == null ? " " : opcDataItem.ToString()) + System.Environment.NewLine; } asyncUpMessage(message); }
/// <summary> /// Lookups the error text for the specified error id. /// </summary> private string GetErrorText(object subscriptionHandle, OpcResult resultID) { if (ShowErrorTextMI.Checked) { // display nothing for ok results. if (resultID == OpcResult.S_OK) { return(""); } // fetch the error text from the server. string errorText = null; try { TsCDaSubscription subscription = (TsCDaSubscription)m_subscriptions[subscriptionHandle]; string locale = (subscription != null)?subscription.Locale:CultureInfo.CurrentCulture.Name; errorText = m_server.GetErrorText(locale, resultID); } catch { errorText = null; } // return the result; return((errorText != null)?errorText:""); } // return the result id as a string. return(resultID.ToString()); }
/// <summary> /// Returns the localized text for the specified result code. /// </summary> /// <param name="locale">The locale name in the format "[languagecode]-[country/regioncode]".</param> /// <param name="resultId">The result code identifier.</param> /// <returns>A message localized for the best match for the requested locale.</returns> public virtual string GetErrorText(string locale, OpcResult resultId) { lock (lock_) { if (server_ == null) { throw new NotConnectedException(); } try { string currentLocale = GetLocale(); if (currentLocale != locale) { SetLocale(locale); } ((IOPCCommon)server_).GetErrorString(resultId.Code, out var errorText); if (currentLocale != locale) { SetLocale(currentLocale); } return(errorText); } catch (Exception e) { throw Utilities.Interop.CreateException("IOPCServer.GetErrorString", e); } } }
/// <summary> /// Lookups the error text for the specified error id. /// </summary> private string GetErrorText(OpcResult resultID) { if (ShowErrorTextMI.Checked) { // display nothing for ok results. if (resultID == OpcResult.S_OK) { return(""); } // check if text has already been fetched. string errorText = (string)m_errors[resultID]; // fetch the error text from the server. if (errorText == null) { try { errorText = m_server.GetErrorText(m_locale, resultID); m_errors[resultID] = errorText; } catch { errorText = null; } } // return the result; return((errorText != null)?errorText:""); } // return the result id as a string. return(resultID.ToString()); }
/// <summary> /// Lookups the error text for the specified error id. /// </summary> private string GetErrorText(OpcResult resultId) { if (showErrorTextMi_.Checked) { // display nothing for ok results. if (resultId == OpcResult.S_OK) { return(""); } // check if text has already been fetched. string errorText = (string)MErrors[resultId]; // fetch the error text from the server. if (errorText == null) { try { errorText = MServer.GetErrorText(MLocale, resultId); MErrors[resultId] = errorText; } catch { errorText = null; } } // return the result; return((errorText != null)?errorText:""); } // return the result id as a string. return(resultId.ToString()); }
/// <summary> /// 写数据 /// </summary> /// <param name="opcDataItem"></param> /// <param name="value"></param> /// <returns></returns> public OpcResult Write(OpcDataItem opcDataItem, object value) { OpcResult opcResult = OpcResult.Unknow; //如果未连接那么返回 if (!this.IsConnected) { if (!Equals(null, OnErrorHappened)) { OnErrorHappened(this, new OpcErrorEventArgs(OpcResult.E_FAIL, "Opc服务器未连接,请先连接再写数据项", null)); } return(opcResult); } try { if (Equals(null, opcDataItem)) { throw new ArgumentNullException("opcDataItem参数不能为空。"); } Opc.Da.Subscription tmpSubscription = this.opcServer.Subscriptions.Cast <Opc.Da.Subscription>().FirstOrDefault(a => a.State.UpdateRate == opcDataItem.UpdateRate); var itemValue = new ItemValue((ItemIdentifier)tmpSubscription.Items.FirstOrDefault(a => a.ItemName == opcDataItem.Name)); //itemValue.Value = opcDataItem.NewValue; itemValue.Value = value; var results = tmpSubscription.Write(new ItemValue[] { itemValue }); //写多次 //for (int i = 0; i < 20; i++) //{ results = tmpSubscription.Write(new ItemValue[] { itemValue }); //} if (results.Count() < 1 && !Equals(null, OnErrorHappened)) { opcResult = OpcResult.E_UNKNOWN_ITEM_NAME; OnErrorHappened(this, new OpcErrorEventArgs(opcResult, "写入数据项时发生错误,未找到数据项:" + opcDataItem.Name, null)); opcDataItem.Quality = OpcResult.Unknow; return(opcResult); } foreach (var v in results) { Enum.TryParse <OpcResult>(v.ResultID.ToString(), out opcResult); if (v.ResultID != Opc.ResultID.S_OK && !Equals(null, OnErrorHappened)) { Enum.TryParse <OpcResult>(v.ResultID.ToString(), out opcResult); OnErrorHappened(this, new OpcErrorEventArgs(opcResult, "写入数据项时发生错误:" + v.ResultID.Name, null)); } }//end foreach return(opcResult); } catch (Exception ex) { if (!Equals(null, OnErrorHappened)) { OnErrorHappened(this, new OpcHelper.OpcErrorEventArgs(OpcResult.E_FAIL, "写入数据时错误。", ex)); } return(opcResult); } }
/// <summary> /// 连接服务器 /// </summary> /// <param name="serverName"></param> /// <param name="host"></param> public OpcResult Connect(string serverName, string host = "127.0.0.1") { OpcResult opcResult = OpcResult.ServerNoConnect; try { this.OpcServerName = serverName; this.Host = host; if (string.IsNullOrWhiteSpace(serverName) || string.IsNullOrWhiteSpace(host)) { if (!Equals(null, OnLogHappened)) { OnLogHappened(this, new OpcLogEventArgs("未指定服务器或主机名称")); } opcResult = OpcResult.E_FAIL; return(opcResult); } if (IsConnected) { if (!Equals(null, OnLogHappened)) { OnLogHappened(this, new OpcLogEventArgs("Opc服务器已经连接,host=" + host + ",serverName=" + serverName)); } opcResult = OpcResult.S_OK; return(opcResult); } var servers = OpcClientHelper.getOpcServers(host); if (!Equals(null, servers) && servers.Any(a => a.Name == serverName)) { opcServer = (Opc.Da.Server)servers.FirstOrDefault(a => a.Name == serverName); opcServer.Connect(); //服务器断开事件 opcServer.ServerShutdown += opcServer_ServerShutdown; IsConnected = true; if (!Equals(null, OnLogHappened)) { OnLogHappened(this, new OpcLogEventArgs("连接Opc服务器成功,host=" + host + ",serverName=" + serverName)); } //连接成功后开启守护进程 daemonTimer.Enabled = true; daemonTimer.Start(); opcResult = OpcResult.S_OK; } return(opcResult); } catch (Exception ex) { IsConnected = false; if (!Equals(null, OnErrorHappened)) { OnErrorHappened(this, new OpcErrorEventArgs(OpcResult.E_FAIL, "连接Opc服务器时出错:" + ex.Message, ex)); } opcResult = OpcResult.E_FAIL; return(opcResult); } }
/// <summary> /// Initializes the object with the specified item identifier and result. /// </summary> public TsCDaItemPropertyCollection(OpcItem itemId, OpcResult result) { if (itemId != null) { ItemName = itemId.ItemName; ItemPath = itemId.ItemPath; } result_ = result; }
/// <summary> /// 数据改变事件函数 /// </summary> /// <param name="subscriptionHandle"></param> /// <param name="requestHandle"></param> /// <param name="values"></param> private void ThisSubscription_DataChanged(object subscriptionHandle, object requestHandle, Opc.Da.ItemValueResult[] values) { if (!Equals(null, OnDataChanged) && IsConnected && !Equals(null, OpcDataItems)) { //异步方式 //System.Threading.Tasks.Parallel.ForEach<ItemValueResult>(values, (v) => //{ // OpcDataItem item = OpcDataItems.FirstOrDefault(a => a.Name == v.ItemName); // if (Equals(null, item)) // { // return; // } // OpcResult opcResult = OpcResult.Unknow; // Enum.TryParse<OpcResult>(v.ResultID.ToString(), out opcResult); // item.Name = v.ItemName; // item.Quality = opcResult; // item.OldValue = item.NewValue; // item.NewValue = v.Value.ToString(); // OnDataChanged(this, new OpcDataEventArgs(opcResult, item)); //}); //同步方式 foreach (var v in values) { OpcDataItem item = OpcDataItems.FirstOrDefault(a => a.Name == v.ItemName); if (Equals(null, item)) { //OnDataChanged(this, new OpcDataEventArgs(OpcResult.E_FAIL, item)); continue; } OpcResult opcResult = OpcResult.Unknow; Enum.TryParse <OpcResult>(v.ResultID.ToString(), out opcResult); item.Name = v.ItemName; item.Quality = opcResult; item.OldValue = item.NewValue; item.NewValue = v.Value?.ToString(); OnDataChanged(this, new OpcDataEventArgs(opcResult, item)); } } }
/// <summary> /// Returns the localized text for the specified result code. /// </summary> /// <param name="locale">The locale name in the format "[languagecode]-[country/regioncode]".</param> /// <param name="resultId">The result code identifier.</param> /// <returns>A message localized for the best match for the requested locale.</returns> public override string GetErrorText(string locale, OpcResult resultId) { lock (this) { if (server_ == null) { throw new NotConnectedException(); } string methodName = "IOPCServer.GetErrorString"; // invoke COM method. try { IOPCServer server = BeginComCall <IOPCServer>(methodName, true); (server).GetErrorString( resultId.Code, Technosoftware.DaAeHdaClient.Com.Interop.GetLocale(locale), out var errorText); if (DCOMCallWatchdog.IsCancelled) { throw new Exception($"{methodName} call was cancelled due to response timeout"); } return(errorText); } catch (Exception e) { ComCallError(methodName, e); throw Technosoftware.DaAeHdaClient.Com.Interop.CreateException("IOPCServer.GetErrorString", e); } finally { EndComCall(methodName); } } }
/// <summary> /// 注册Opc数据项集合 /// </summary> /// <param name="opcDataItems"></param> private void registerOpcDataItems(IList <OpcDataItem> opcDataItems) { this.OpcDataItems = opcDataItems; daemonTimer.Enabled = false; daemonTimer.Stop(); //如果未连接那么返回 if (!this.IsConnected) { if (!Equals(null, OnErrorHappened)) { OnErrorHappened(this, new OpcErrorEventArgs(OpcResult.E_FAIL, "Opc服务器未连接,请先连接在订阅数据项", null)); } return; } #region 没有数据项那么清空所有订阅 //如果订阅的DataItem没有,那么清空现在所有订阅 if (Equals(null, opcDataItems) || opcDataItems.Count() < 1) { if (!Equals(this.opcServer.Subscriptions, null) && this.opcServer.Subscriptions.Count > 0) { foreach (Opc.Da.Subscription thisSubscription in this.opcServer.Subscriptions) { thisSubscription.RemoveItems(thisSubscription.Items); thisSubscription.DataChanged -= ThisSubscription_DataChanged; this.opcServer.CancelSubscription(thisSubscription); thisSubscription.Dispose(); } this.opcServer.Subscriptions.Clear(); //订阅项取消后通知外部程序 if (!Equals(null, OnLogHappened)) { OnLogHappened(this, new OpcHelper.OpcLogEventArgs("已经取消所有订阅")); } return; } } #endregion 数据项需要更新或者删除 //根据要订阅的新数据项,增加或者移除现在的订阅 if (!IsConnected) { if (!Equals(null, OnLogHappened)) { OnLogHappened(this, new OpcLogEventArgs("Opc服务器已断开")); } return; } //根据更新频率分组 var dataItemGroups = from a in opcDataItems group a by a.UpdateRate into g select new { UpdateRate = g.Key, DataItems = g }; //循环每组订阅对象,查询是否实际订阅,有则更新,没有则新建 foreach (var dataItemGroup in dataItemGroups) { Opc.Da.Subscription thisSubscription = this.opcServer.Subscriptions.Cast <Opc.Da.Subscription>().FirstOrDefault(a => a.State.UpdateRate == dataItemGroup.UpdateRate); //未找到已经订阅的组,那么新建组并添加订阅项 if (Equals(null, thisSubscription)) { if (!IsConnected) { if (!Equals(null, OnLogHappened)) { OnLogHappened(this, new OpcLogEventArgs("Opc服务器已断开")); } return; } #region 增加订阅 //创建订阅组。订阅组状态的名称是更新频率 Opc.Da.Subscription newSubscription = this.opcServer.CreateSubscription (CreateSubscriptionState(dataItemGroup.UpdateRate.ToString(), dataItemGroup.UpdateRate)) as Opc.Da.Subscription;//创建组 //创建opc订阅项 var opcItems = ConvertItems(dataItemGroup.DataItems); //添加订阅项 var results = newSubscription.AddItems(opcItems.ToArray()); newSubscription.DataChanged += ThisSubscription_DataChanged; //订阅的结果通过事件通知给外部调用程序 foreach (var v in results) { if (!IsConnected) { if (!Equals(null, OnLogHappened)) { OnLogHappened(this, new OpcLogEventArgs("Opc服务器已断开")); } return; } //订阅成功更新状态 if (v.ResultID == Opc.ResultID.S_OK) { OpcResult opcResult = OpcResult.Unknow; Enum.TryParse <OpcResult>(v.ResultID.ToString(), out opcResult); OpcDataItems.FirstOrDefault(a => a.Name == v.ItemName).Quality = opcResult; } //未订阅成功,异常事件通知 else if (v.ResultID == Opc.ResultID.S_OK && !Equals(null, OnDataChanged)) { OnDataChanged(this, new OpcDataEventArgs(OpcResult.DataItemRegistered, dataItemGroup.DataItems.FirstOrDefault(a => a.Name == v.ItemName))); } else if (v.ResultID != Opc.ResultID.S_OK && !Equals(null, OnErrorHappened)) { OpcResult opcResult = OpcResult.Unknow; Enum.TryParse <OpcResult>(v.ResultID.ToString(), out opcResult); this.OpcDataItems.FirstOrDefault(a => a.Name == v.ItemName).Quality = opcResult; OnErrorHappened(this, new OpcErrorEventArgs(opcResult, "订阅数据项时发生错误" + v.ResultID.Name, null)); } }//end foreach #endregion } else//已经有订阅组,那么更新订阅项 { if (!IsConnected) { if (!Equals(null, OnLogHappened)) { OnLogHappened(this, new OpcLogEventArgs("Opc服务器已断开")); } return; } #region 已经有订阅组,那么更新订阅项 //查询要新增加的点, IList <OpcDataItem> newItems = new List <OpcDataItem>(); foreach (var v in dataItemGroup.DataItems) { if (!thisSubscription.Items.Any(a => a.ItemName == v.Name)) { newItems.Add(v); } } var opcItems = ConvertItems(newItems); //添加订阅项 var addResults = thisSubscription.AddItems(opcItems.ToArray()); //订阅的结果通过事件通知给外部调用程序 foreach (var v in addResults) { if (!IsConnected) { if (!Equals(null, OnLogHappened)) { OnLogHappened(this, new OpcLogEventArgs("Opc服务器已断开")); } return; } //订阅成功更新状态 if (v.ResultID == Opc.ResultID.S_OK) { OpcResult opcResult = OpcResult.Unknow; Enum.TryParse <OpcResult>(v.ResultID.ToString(), out opcResult); OpcDataItems.FirstOrDefault(a => a.Name == v.ItemName).Quality = opcResult; } //未订阅成功,异常事件通知 else if (v.ResultID == Opc.ResultID.S_OK && !Equals(null, OnDataChanged)) { OnDataChanged(this, new OpcDataEventArgs(OpcResult.DataItemRegistered, dataItemGroup.DataItems.FirstOrDefault(a => a.Name == v.ItemName))); } else if (v.ResultID != Opc.ResultID.S_OK && !Equals(null, OnErrorHappened)) { OpcResult opcResult = OpcResult.Unknow; Enum.TryParse <OpcResult>(v.ResultID.ToString(), out opcResult); this.OpcDataItems.FirstOrDefault(a => a.Name == v.ItemName).Quality = opcResult; OnErrorHappened(this, new OpcErrorEventArgs(opcResult, "订阅数据项时发生错误:" + v.ItemName + " 无效,OpcResult=" + v.ResultID.Name, null)); } }//end foreach //查询要删除的点, IList <Opc.Da.Item> deleteItems = new List <Opc.Da.Item>(); foreach (var v in thisSubscription.Items) { if (!dataItemGroup.DataItems.Any(a => a.Name == v.ItemName)) { deleteItems.Add(v); } } //删除已经订阅点 var deleteResults = thisSubscription.RemoveItems(deleteItems.ToArray()); //订阅的结果通过事件通知给外部调用程序 foreach (var v in deleteResults) { if (!IsConnected) { if (!Equals(null, OnLogHappened)) { OnLogHappened(this, new OpcLogEventArgs("Opc服务器已断开")); } return; } //未订阅成功,异常事件通知 if (v.ResultID == Opc.ResultID.S_OK && !Equals(null, OnDataChanged)) { OpcDataItem tmp2 = new OpcDataItem(v.ItemName, thisSubscription.State.UpdateRate, "", "", OpcResult.DataItemUnregistered); OnDataChanged(this, new OpcDataEventArgs(OpcResult.DataItemUnregistered, tmp2)); } else if (v.ResultID != Opc.ResultID.S_OK && !Equals(null, OnErrorHappened)) { OnErrorHappened(this, new OpcErrorEventArgs(OpcResult.E_FAIL, "取消订阅数据项时发生错误" + v.ResultID.Name, null)); } }//end foreach //删除订阅项后没有item了,那么删除thisSubscription if (thisSubscription.Items.Count() < 1) { thisSubscription.DataChanged -= ThisSubscription_DataChanged; string name = thisSubscription.Name; //this.opcServer.Subscriptions.Remove(thisSubscription); this.opcServer.CancelSubscription(thisSubscription); thisSubscription.Dispose();// if (!Equals(null, OnLogHappened)) { OnLogHappened(this, new OpcLogEventArgs("Subscription " + name + " 已经从订阅组中移除")); } name = null; } #endregion } }//end foreach (var dataItemGroup in dataItemGroups) //删除订阅项后没有item了,那么删除subscription foreach (var subscription in this.opcServer.Subscriptions.Cast <Opc.Da.Subscription>()) { var isHave = dataItemGroups.Any(a => a.UpdateRate == subscription.State.UpdateRate); if (!isHave) { subscription.DataChanged -= ThisSubscription_DataChanged; string name = subscription.Name; //his.opcServer.Subscriptions.Remove(thisSubscription); this.opcServer.CancelSubscription(subscription); subscription.Dispose();// if (!Equals(null, OnLogHappened)) { OnLogHappened(this, new OpcLogEventArgs("Subscription " + name + " 已经从订阅组中移除")); } name = null; } } if (!Equals(null, OnLogHappened)) { OnLogHappened(this, new OpcLogEventArgs("OPC Subscriptions Count:" + this.opcServer.Subscriptions.Count + ".")); } daemonTimer.Enabled = true; daemonTimer.Start(); }
/// <summary> /// Initializes the object with an ItemIdentifier object and Result. /// </summary> public TsCDaItemResult(OpcItem item, OpcResult resultID) : base(item) { Result = resultID; }
public OpcDataItem(string name, int updateRate, string oldValue, string newValue, OpcResult quality) { this.Name = name; this.UpdateRate = updateRate; this.OldValue = oldValue; this.NewValue = newValue; this.Quality = quality; }
/// <summary> /// Initializes the object with the specified item name, result code and diagnostic info. /// </summary> public TsCDaItemValueResult(string itemName, OpcResult resultId, string diagnosticInfo) : base(itemName) { Result = resultId; DiagnosticInfo = diagnosticInfo; }
/// <summary> /// Initialize object with the specified ItemIdentifier and result code. /// </summary> public TsCDaItemValueResult(OpcItem item, OpcResult resultId) : base(item) { Result = resultId; }
/// <summary> /// Initializes the object with the specified ItemIdentifier, result code and diagnostic info. /// </summary> public TsCDaItemValueResult(OpcItem item, OpcResult resultId, string diagnosticInfo) : base(item) { Result = resultId; DiagnosticInfo = diagnosticInfo; }
/// <summary> /// Initializes the object with the specified item name and result code. /// </summary> public TsCDaItemValueResult(string itemName, OpcResult resultId) : base(itemName) { Result = resultId; }
/// <summary> /// Initializes the object with the specified result id. /// </summary> public TsCHdaResult(OpcResult resultId) { Result = resultId; DiagnosticInfo = null; }
public OpcErrorEventArgs(OpcResult opcResult, string message, Exception exception) { this.OpcResult = opcResult; this.Message = message; this.Exception = exception; }
public OpcDataEventArgs(OpcResult opcResult, OpcDataItem opcDataItem) { this.OpcResult = opcResult; this.OpcDataItem = opcDataItem; }
/// <summary> /// Initializes the object with an qualified name and Result. /// </summary> public TsCAeEnabledStateResult(string qualifiedName, OpcResult result) { qualifiedName_ = qualifiedName; Result = result; }
/// <summary> /// Initializes the object with an Item object and Result. /// </summary> public TsCDaItemResult(TsCDaItem item, OpcResult resultId) : base(item) { Result = resultId; }