/// <summary> /// Shows a detailed view for array values. /// </summary> private void ViewMI_Click(object sender, System.EventArgs e) { if (ItemListLV.SelectedItems.Count > 0) { object tag = ItemListLV.SelectedItems[0].Tag; if (tag != null && tag.GetType() == typeof(TsCDaItemValueResult)) { TsCDaItemValueResult item = (TsCDaItemValueResult)tag; if (item.Value != null) { TsCCpxComplexItem complexItem = TsCCpxComplexTypeCache.GetComplexItem(item); if (complexItem != null) { new EditComplexValueDlg().ShowDialog(complexItem, item.Value, true, true); } else if (item.Value.GetType().IsArray) { new EditArrayDlg().ShowDialog(item.Value, true); } } } } }
/// <summary> /// Returns the value of the specified field. /// </summary> private object GetFieldValue(TsCDaItemValueResult item, int fieldID) { object fieldValue = null; switch (fieldID) { case ITEM_NAME: { return(item.ItemName); } case ITEM_PATH: { return(item.ItemPath); } // case CLIENT_HANDLE: { return OpcClientSdk.Utilities.Convert.ToString(item.ClientHandle); } // case SERVER_HANDLE: { return OpcClientSdk.Utilities.Convert.ToString(item.ServerHandle); } case VALUE: { return(OpcClientSdk.OpcConvert.ToString(item.Value)); } case DATA_TYPE: { return((item.Value != null)?item.Value.GetType():fieldValue); } case QUALITY_BITS: { return((item.QualitySpecified && item.Quality.QualityBits != TsDaQualityBits.Good)?item.Quality.QualityBits:fieldValue); } case LIMIT_BITS: { return((item.QualitySpecified && item.Quality.LimitBits != TsDaLimitBits.None)?item.Quality.LimitBits:fieldValue); } case VENDOR_BITS: { return((item.QualitySpecified && item.Quality.VendorBits != 0)?item.Quality.VendorBits:fieldValue); } case TIMESTAMP: { return((item.TimestampSpecified)?item.Timestamp:fieldValue); } case ERROR: { return(GetErrorText(item.Result)); } } return(null); }
/// <summary> /// Returns the value of the specified field. /// </summary> private object GetFieldValue(TsCDaItemValueResult item, int fieldId) { object fieldValue = null; switch (fieldId) { case ItemName: { return(item.ItemName); } case ItemPath: { return(item.ItemPath); } // case CLIENT_HANDLE: { return Technosoftware.DaAeHdaClient.Utilities.Convert.ToString(item.ClientHandle); } // case SERVER_HANDLE: { return Technosoftware.DaAeHdaClient.Utilities.Convert.ToString(item.ServerHandle); } case Value: { return(Technosoftware.DaAeHdaClient.OpcConvert.ToString(item.Value)); } case DataType: { return((item.Value != null)?item.Value.GetType():fieldValue); } case QualityBits: { return((item.QualitySpecified && item.Quality.QualityBits != TsDaQualityBits.Good)?item.Quality.QualityBits:fieldValue); } case LimitBits: { return((item.QualitySpecified && item.Quality.LimitBits != TsDaLimitBits.None)?item.Quality.LimitBits:fieldValue); } case VendorBits: { return((item.QualitySpecified && item.Quality.VendorBits != 0)?item.Quality.VendorBits:fieldValue); } case Timestamp: { return((item.TimestampSpecified)?item.Timestamp:fieldValue); } case Error: { return(GetErrorText(item.Result)); } } return(null); }
/// <summary> /// A delegate to receive data change updates from the server. /// </summary> /// <param name="subscriptionHandle"> /// A unique identifier for the subscription assigned by the client. If the parameter /// <see cref="TsCDaSubscriptionState.ClientHandle">ClientHandle</see> is not defined this /// parameter is empty.</param> /// <param name="requestHandle"> /// An identifier for the request assigned by the caller. This parameter is empty if /// the corresponding parameter in the calls Read(), Write() or Refresh() is not defined. /// Can be used to Cancel an outstanding operation. /// </param> /// <param name="values"> /// <para class="MsoBodyText" style="MARGIN: 1pt 0in">The set of changed values.</para> /// <para class="MsoBodyText" style="MARGIN: 1pt 0in">Each value will always have /// item’s ClientHandle field specified.</para> /// </param> public void OnDataChangeEvent(object subscriptionHandle, object requestHandle, TsCDaItemValueResult[] values) { if (requestHandle != null) { Console.Write("DataChange() for requestHandle :"); Console.WriteLine(requestHandle.GetHashCode().ToString()); } else { Console.WriteLine("DataChange():"); } for (int i = 0; i < values.GetLength(0); i++) { Console.Write("Client Handle : "); Console.WriteLine(values[i].ClientHandle); if (values[i].Result.IsSuccess()) { if (values[i].Value.GetType().IsArray) { UInt16[] arrValue = (UInt16[])values[i].Value; for (int j = 0; j < arrValue.GetLength(0); j++) { Console.Write($"Value[{j}] : "); Console.WriteLine(arrValue[j]); } } else { TsCDaItemValueResult valueResult = values[i]; TsCDaQuality quality = new TsCDaQuality(193); valueResult.Quality = quality; string message = $"\r\n\tQuality: is not good : {valueResult.Quality} Code:{valueResult.Quality.GetCode()} LimitBits: {valueResult.Quality.LimitBits} QualityBits: {valueResult.Quality.QualityBits} VendorBits: {valueResult.Quality.VendorBits}"; if (valueResult.Quality.QualityBits != TsDaQualityBits.Good && valueResult.Quality.QualityBits != TsDaQualityBits.GoodLocalOverride) { Console.WriteLine(message); } Console.Write("Value : "); Console.WriteLine(values[i].Value); } Console.Write("Time Stamp : "); Console.WriteLine(values[i].Timestamp.ToString(CultureInfo.InvariantCulture)); Console.Write("Quality : "); Console.WriteLine(values[i].Quality); } Console.Write("Result : "); Console.WriteLine(values[i].Result.Description()); } Console.WriteLine(); Console.WriteLine(); }
/// <summary> /// Reads a set of items using DA2.0 interfaces. /// </summary> protected override TsCDaItemValueResult[] Read(OpcItem[] itemIDs, TsCDaItem[] items) { if (subscription_ == null) { throw new NotConnectedException(); } // create result list. TsCDaItemValueResult[] results = new TsCDaItemValueResult[itemIDs.Length]; // separate into cache reads and device reads. ArrayList cacheReads = new ArrayList(); ArrayList deviceReads = new ArrayList(); for (int ii = 0; ii < itemIDs.Length; ii++) { results[ii] = new TsCDaItemValueResult(itemIDs[ii]); if (items[ii].MaxAgeSpecified && (items[ii].MaxAge < 0 || items[ii].MaxAge == Int32.MaxValue)) { cacheReads.Add(results[ii]); } else { deviceReads.Add(results[ii]); } } // read items from cache. if (cacheReads.Count > 0) { Read((TsCDaItemValueResult[])cacheReads.ToArray(typeof(TsCDaItemValueResult)), true); } // read items from device. if (deviceReads.Count > 0) { Read((TsCDaItemValueResult[])deviceReads.ToArray(typeof(TsCDaItemValueResult)), false); } // return results. return(results); }
/// <summary> /// Shows a detailed view for array values. /// </summary> private void ViewMI_Click(object sender, System.EventArgs e) { if (ItemListLV.SelectedItems.Count > 0) { ListViewItem listItem = ItemListLV.SelectedItems[0]; object tag = listItem.Tag; if (tag != null && tag.GetType() == typeof(TsCDaItemValueResult)) { TsCDaItemValueResult item = (TsCDaItemValueResult)tag; if (item.Value != null) { TsCCpxComplexItem complexItem = TsCCpxComplexTypeCache.GetComplexItem(item); if (complexItem != null) { EditComplexValueDlg dialog = (EditComplexValueDlg)m_viewers[listItem]; if (dialog == null) { m_viewers[listItem] = dialog = new EditComplexValueDlg(); dialog.Disposed += new EventHandler(OnViewerClosed); } dialog.ShowDialog(complexItem, item.Value, true, false); } else if (item.Value.GetType().IsArray) { new EditArrayDlg().ShowDialog(item.Value, true); } } } } }
/// <summary> /// Enables/disables items in the popup menu before it is displayed. /// </summary> private void ItemListLV_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) { // ignore left button actions. if (e.Button != MouseButtons.Right) { return; } // disable everything. ViewMI.Enabled = false; // selects the item that was right clicked on. ListViewItem clickedItem = ItemListLV.GetItemAt(e.X, e.Y); // no item clicked on - do nothing. if (clickedItem == null) { return; } // force selection to clicked node. clickedItem.Selected = true; if (ItemListLV.SelectedItems.Count == 1) { if (clickedItem.Tag != null && clickedItem.Tag.GetType() == typeof(TsCDaItemValueResult)) { TsCDaItemValueResult item = (TsCDaItemValueResult)clickedItem.Tag; if (item.Value != null) { ViewMI.Enabled = ((TsCCpxComplexTypeCache.GetComplexItem(item) != null) || (item.Value.GetType().IsArray)); } } } }
/// <summary> /// Reads the current values for a set of items. /// </summary> /// <param name="items">The set of items to read.</param> /// <returns>The results of the read operation for each item.</returns> public virtual TsCDaItemValueResult[] Read(TsCDaItem[] items) { if (items == null) { throw new ArgumentNullException(nameof(items)); } lock (this) { string methodName = "IOPCItemIO.Read"; if (m_server == null) { throw new NotConnectedException(); } int count = items.Length; if (count == 0) { throw new ArgumentOutOfRangeException(nameof(items.Length), "0"); } // initialize arguments. string[] itemIDs = new string[count]; int[] maxAges = new int[count]; for (int ii = 0; ii < count; ii++) { itemIDs[ii] = items[ii].ItemName; maxAges[ii] = (items[ii].MaxAgeSpecified) ? items[ii].MaxAge : 0; } IntPtr pValues = IntPtr.Zero; IntPtr pQualities = IntPtr.Zero; IntPtr pTimestamps = IntPtr.Zero; IntPtr pErrors = IntPtr.Zero; // invoke COM method. try { IOPCItemIO server = BeginComCall <IOPCItemIO>(methodName, true); server.Read( count, itemIDs, maxAges, out pValues, out pQualities, out pTimestamps, out pErrors); } catch (Exception e) { ComCallError(methodName, e); throw Technosoftware.DaAeHdaClient.Com.Interop.CreateException(methodName, e); } finally { EndComCall(methodName); } // unmarshal results. object[] values = Technosoftware.DaAeHdaClient.Com.Interop.GetVARIANTs(ref pValues, count, true); short[] qualities = Technosoftware.DaAeHdaClient.Com.Interop.GetInt16s(ref pQualities, count, true); DateTime[] timestamps = Technosoftware.DaAeHdaClient.Com.Interop.GetFILETIMEs(ref pTimestamps, count, true); int[] errors = Technosoftware.DaAeHdaClient.Com.Interop.GetInt32s(ref pErrors, count, true); // pre-fetch the current locale to use for data conversions. string locale = GetLocale(); // construct result array. TsCDaItemValueResult[] results = new TsCDaItemValueResult[count]; for (int ii = 0; ii < results.Length; ii++) { results[ii] = new TsCDaItemValueResult(items[ii]); results[ii].ServerHandle = null; results[ii].Value = values[ii]; results[ii].Quality = new TsCDaQuality(qualities[ii]); results[ii].QualitySpecified = true; results[ii].Timestamp = timestamps[ii]; results[ii].TimestampSpecified = timestamps[ii] != DateTime.MinValue; results[ii].Result = Technosoftware.DaAeHdaClient.Utilities.Interop.GetResultID(errors[ii]); results[ii].DiagnosticInfo = null; // convert COM code to unified DA code. if (errors[ii] == Result.E_BADRIGHTS) { results[ii].Result = new OpcResult(OpcResult.Da.E_WRITEONLY, Result.E_BADRIGHTS); } // convert the data type since the server does not support the feature. if (results[ii].Value != null && items[ii].ReqType != null) { try { results[ii].Value = ChangeType(values[ii], items[ii].ReqType, locale); } catch (Exception e) { results[ii].Value = null; results[ii].Quality = TsCDaQuality.Bad; results[ii].QualitySpecified = true; results[ii].Timestamp = DateTime.MinValue; results[ii].TimestampSpecified = false; if (e.GetType() == typeof(OverflowException)) { results[ii].Result = Technosoftware.DaAeHdaClient.Utilities.Interop.GetResultID(Result.E_RANGE); } else { results[ii].Result = Technosoftware.DaAeHdaClient.Utilities.Interop.GetResultID(Result.E_BADTYPE); } } } // apply request options. if ((filters_ & (int)TsCDaResultFilter.ItemName) == 0) { results[ii].ItemName = null; } if ((filters_ & (int)TsCDaResultFilter.ItemPath) == 0) { results[ii].ItemPath = null; } if ((filters_ & (int)TsCDaResultFilter.ClientHandle) == 0) { results[ii].ClientHandle = null; } if ((filters_ & (int)TsCDaResultFilter.ItemTime) == 0) { results[ii].Timestamp = DateTime.MinValue; results[ii].TimestampSpecified = false; } } // return results. return(results); } }
/// <summary> /// Executes a write request for the current set if items. /// </summary> public void DoWrite() { try { // get the selected items TsCDaItemValue[] items = ItemsCTRL.GetItems(); // write to server. OpcItemResult[] results = null; if (m_subscription != null) { if (m_synchronous) { results = m_subscription.Write(items); } else { results = new AsyncRequestDlg().ShowDialog(m_subscription, items); if (results == null) { return; } } } else { // add dummy client handles to test that they get returned properly. foreach (TsCDaItemValue item in items) { item.ClientHandle = item.ItemName; } results = m_server.Write(items); } // create a list of item value results. ArrayList values = new ArrayList(); for (int ii = 0; ii < items.Length; ii++) { TsCDaItemValueResult value = new TsCDaItemValueResult(items[ii]); value.ItemName = results[ii].ItemName; value.ItemPath = results[ii].ItemPath; value.ClientHandle = results[ii].ClientHandle; value.ServerHandle = results[ii].ServerHandle; value.Result = results[ii].Result; value.DiagnosticInfo = results[ii].DiagnosticInfo; values.Add(value); } // save results. m_values = (TsCDaItemValueResult[])values.ToArray(typeof(TsCDaItemValueResult)); BackBTN.Enabled = true; NextBTN.Enabled = false; CancelBTN.Visible = false; DoneBTN.Visible = true; OptionsBTN.Visible = false; ItemsCTRL.Visible = false; ResultsCTRL.Visible = true; // display results. ResultsCTRL.Initialize(m_server, (m_subscription != null)?m_subscription.Locale:m_server.Locale, m_values); } catch (Exception e) { MessageBox.Show(e.Message); } }
/// <summary> /// Adds an item to the list view. /// </summary> private void AddValue(object subscriptionHandle, TsCDaItemValueResult item, ref ListViewItem replaceableItem) { string quality = ""; // format quality. if (item.QualitySpecified) { quality += item.Quality.QualityBits.ToString(); if (item.Quality.LimitBits != TsDaLimitBits.None) { quality += ", "; quality += item.Quality.LimitBits.ToString(); } if (item.Quality.VendorBits != 0) { quality += String.Format(", {0:X}", item.Quality.VendorBits); } } // format columns. string[] columns = new string[] { item.ItemName, item.ItemPath, OpcClientSdk.OpcConvert.ToString(item.Value), (item.Value != null)?OpcClientSdk.OpcConvert.ToString(item.Value.GetType()):"", quality, (item.TimestampSpecified)?OpcClientSdk.OpcConvert.ToString(item.Timestamp):"", GetErrorText(subscriptionHandle, item.Result) }; // update an existing item. if (replaceableItem != null) { for (int ii = 0; ii < replaceableItem.SubItems.Count; ii++) { replaceableItem.SubItems[ii].Text = columns[ii]; } replaceableItem.Tag = item; replaceableItem.ForeColor = Color.Empty; // update detail view dialog. EditComplexValueDlg dialog = (EditComplexValueDlg)m_viewers[replaceableItem]; if (dialog != null) { dialog.UpdateValue(item.Value); } return; } // create a new list view item. replaceableItem = new ListViewItem(columns, Resources.IMAGE_YELLOW_SCROLL); replaceableItem.Tag = item; // insert after any existing item value with the same client handle. for (int ii = ItemListLV.Items.Count - 1; ii >= 0; ii--) { TsCDaItemValueResult previous = (TsCDaItemValueResult)ItemListLV.Items[ii].Tag; if (previous.ClientHandle != null && previous.ClientHandle.Equals(item.ClientHandle)) { ItemListLV.Items.Insert(ii + 1, replaceableItem); return; } } ItemListLV.Items.Add(replaceableItem); }
/// <summary> /// Called when a data update event is raised by a subscription. /// </summary> private void OnDataChangeEvent(object subscriptionHandle, object requestHandle, TsCDaItemValueResult[] values) { // ensure processing is done on the control's main thread. if (InvokeRequired) { BeginInvoke(new TsCDaDataChangedEventHandler(OnDataChangeEvent), new object[] { subscriptionHandle, requestHandle, values }); return; } try { // find subscription. ArrayList existingItemList = (ArrayList)m_items[subscriptionHandle]; // check if subscription is still valid. if (existingItemList == null) { return; } // change all existing item values for the subscription to 'grey'. // this indicates an update arrived but the value did not change. foreach (ListViewItem listItem in existingItemList) { if (listItem.ForeColor != Color.Gray) { listItem.ForeColor = Color.Gray; } } // do nothing more if only a keep alive callback. if (values == null || values.Length == 0) { OnKeepAlive(subscriptionHandle); return; } else { if (UpdateEvent != null) { UpdateEvent(subscriptionHandle, values); } } // update list view. ArrayList newListItems = new ArrayList(); foreach (TsCDaItemValueResult value in values) { // item value should never have a null client handle. if (value.ClientHandle == null) { continue; } // this item can be updated with new values instead of inserting/removing items. ListViewItem replacableItem = null; // remove existing items. if (!KeepValuesMI.Checked) { // search list of existing items for previous values for this item. ArrayList updatedItemList = new ArrayList(existingItemList.Count); foreach (ListViewItem listItem in existingItemList) { TsCDaItemValueResult previous = (TsCDaItemValueResult)listItem.Tag; if (!value.ClientHandle.Equals(previous.ClientHandle)) { updatedItemList.Add(listItem); continue; } if (replacableItem != null) { EditComplexValueDlg dialog = (EditComplexValueDlg)m_viewers[replacableItem]; if (dialog != null) { dialog.Close(); m_viewers.Remove(replacableItem); } replacableItem.Remove(); } replacableItem = listItem; } // the updated list has all values for the current item removed. existingItemList = updatedItemList; } // add value to list. AddValue(subscriptionHandle, value, ref replacableItem); // save new list item. if (replacableItem != null) { newListItems.Add(replacableItem); } } // add new items to existing item list. existingItemList.AddRange(newListItems); m_items[subscriptionHandle] = existingItemList; // adjust column widths. for (int ii = 0; ii < ItemListLV.Columns.Count; ii++) { if (ii != VALUE && ii != QUALITY) { ItemListLV.Columns[ii].Width = -2; } } } catch (Exception e) { OnException(subscriptionHandle, e); } }
static void EventHandler_Subscription_DataChangedEvent(object subscriptionHandle, object requestHandle, TsCDaItemValueResult[] values) { var server = _Servers.FirstOrDefault(s => s.Item2.ClientHandle == subscriptionHandle); if (values.Length > 0) { foreach (var result in values) { var tag = _tags.FirstOrDefault(tg => tg.ServerName == server.Item1.ServerName && tg.ElementName == result.ItemName); if (tag != null) { tag.Quality = result.Quality.GetCode(); tag.Timestamp = result.Timestamp; tag.Value = result.Value; tag.OperationResult = result.Result.IsSuccess(); OpcDaHelper.OnReadTagValue(tag.Uid, tag.Value); //AutomationProcessor.RunOnOpcTagFilters(null, null); } } } }
void EventHandler_activeSubscription_DataChangedEvent(object subscriptionHandle, object requestHandle, TsCDaItemValueResult[] values) { // Через параметр subscriptionHandle передаётся subscriptionState.ClientHandle // Обновляем данные ReadingResult = values; }