/// <summary> /// <para> /// This method is used to read changed historical values for one or more data objects within a specific data /// journal list. Changed historical values are those that were entered into the journal and then changed /// (corrected) by an operator or other user. /// </para> /// </summary> /// <param name="serverListId"> /// The server identifier of the list that contains data objects whose historical values are to /// be read. /// </param> /// <param name="firstTimestamp"> /// The filter that specifies the inclusive earliest (oldest) timestamp for values to be /// returned. Valid operands include the Timestamp and OpcHdaTimestampStr constants defined by the FilterOperand class. /// </param> /// <param name="secondTimestamp"> /// The filter that specifies the inclusive newest (most recent) timestamp for values to be /// returned. Valid operands include the Timestamp and OpcHdaTimestampStr constants defined by the FilterOperand class. /// </param> /// <param name="serverAliases"> The list of server aliases for the data objects whose historical values are to be read. </param> /// <param name="numValuesPerAlias"> The maximum number of JournalDataChangedValues to be returned per alias. </param> /// <returns> /// The list of requested historical values, or the reason they could not be read. If, however, the number /// returned for any alias is equal to numValuesPerDataObject, then the client should issue a /// ReadJournalDataChangesNext() to retrieve any remaining values. /// </returns> public JournalDataChangedValues[]? ReadJournalDataChanges(uint serverListId, FilterCriterion firstTimestamp, FilterCriterion secondTimestamp, uint numValuesPerAlias, List <uint> serverAliases) { if (_disposed) { throw new ObjectDisposedException("Cannot access a disposed XiContext."); } if (_readEndpoint is null) { throw new Exception("No Read Endpoint"); } JournalDataChangedValues[]? listJDCV = null; if (XiEndpointRoot.CreateChannelIfNotCreated(_readEndpoint)) { try { listJDCV = _readEndpoint.Proxy.ReadJournalDataChanges(ContextId, serverListId, firstTimestamp, secondTimestamp, numValuesPerAlias, serverAliases); _readEndpoint.LastCallUtc = DateTime.UtcNow; } catch (Exception ex) { ProcessRemoteMethodCallException(ex); } } return(listJDCV); }
/// <summary> /// <para> /// This method is used to read the historical values at specific times for one or more data objects within a /// specific data journal list. If no item exists at the specified time in the data journal for an object, the /// server creates an interpolated value for that time and includes it in the response as though it actually /// existed in the journal. /// </para> /// </summary> /// <param name="serverListId"> /// The server identifier of the list that contains data objects whose historical values are to /// be read. /// </param> /// <param name="timestamps"> /// Identifies the timestamps of historical values to be returned for each of the requested data /// objects. /// </param> /// <param name="serverAliases"> The list of server aliases for the data objects whose historical values are to be read. </param> /// <returns> The list of requested historical values, or the reason they could not be read. </returns> public JournalDataValues[]? ReadJournalDataAtSpecificTimes(uint serverListId, List <DateTime> timestamps, List <uint> serverAliases) { if (_disposed) { throw new ObjectDisposedException("Cannot access a disposed XiContext."); } if (_readEndpoint is null) { throw new Exception("No Read Endpoint"); } JournalDataValues[]? listJDRV = null; if (XiEndpointRoot.CreateChannelIfNotCreated(_readEndpoint)) { try { listJDRV = _readEndpoint.Proxy.ReadJournalDataAtSpecificTimes(ContextId, serverListId, timestamps, serverAliases); _readEndpoint.LastCallUtc = DateTime.UtcNow; } catch (Exception ex) { ProcessRemoteMethodCallException(ex); } } return(listJDRV); }
/// <summary> /// Use this method to update this Xi List with a replacement Xi Endpoint. /// The method is used when an endpoint loses communication and is replaced /// by a new endpoint /// </summary> /// <param name="failedEndpoint"> The failed endpoint </param> /// <param name="replacementEndpoint"> The endpoint that replaces the failed endpoint </param> public void ReplaceEndpointInList(XiEndpointRoot failedEndpoint, XiEndpointRoot replacementEndpoint) { if (Disposed) { throw new ObjectDisposedException("Cannot access a disposed XiListRoot."); } if (_endpoints.Contains(failedEndpoint)) { _endpoints.Add(replacementEndpoint); _endpoints.Remove(failedEndpoint); } }
/// <summary> /// <para> Throws or returns new IXiEventListItems (not null, but possibly zero-lenghth). </para> /// <para> eventList is not null </para> /// <para> /// This method is used to poll the endpoint for changes to a specific event list. Event messages are sent when /// there has been a change to the specified event list. A new alarm or event that has been added to the list, a /// change to an alarm already in the list, or the deletion of an alarm from the list constitutes a change to the /// list. /// </para> /// <para> /// Once an event has been reported from the list, it is automatically deleted from the list. Alarms are only /// deleted from the list when they transition to inactive and acknowledged. /// </para> /// <para> /// This method return a list of event messages to the client application via the EventMessagesCallback callback /// method. The list consists of alarm/event messages for new alarms/events in the Event List, and alarm/event /// messages that represent state changes to alarms that are already in the list, including alarm/event messages /// that identify state changes that caused alarms to tbe deleted from the list. /// </para> /// <para> /// Null is returned as a keep-alive message when there have been no new alarm/event messages since the last /// poll. /// </para> /// <para> /// In addition, a special event message is included as the first item in the list to indicate to the client /// that one or more event message have been discarded due to queue size limitations. All fields of this message /// are set to null with the exception of the following: /// </para> /// <para> OccurrenceTime = current time of the response </para> /// <para> EventType = EventType.DiscardedMessage </para> /// <para> TextMessage = the number of event/alarm messages discarded since the last poll response was returned. </para> /// </summary> /// <param name="eventList"> The event list to poll (reported). </param> /// <param name="filterSet"> /// Optional set of filters to further refine the selection from the alarms and events in the /// list. The event list itself is created using a filter. /// </param> public IXiEventListItem[] PollEventChanges(XiEventList eventList, FilterSet?filterSet) { if (eventList is null) { throw new ArgumentNullException(@"eventList"); } if (_disposed) { throw new ObjectDisposedException("Cannot access a disposed XiContext."); } if (_pollEndpoint is null) { throw new Exception("No Poll Endpoint"); } if (_pollEndpoint.Disposed) { throw new Exception("Poll Endpoint is Disposed."); } EventMessage[]? eventMessages = null; if (XiEndpointRoot.CreateChannelIfNotCreated(_pollEndpoint)) { try { eventMessages = _pollEndpoint.Proxy.PollEventChanges(ContextId, eventList.ServerListId, filterSet); _pollEndpoint.LastCallUtc = DateTime.UtcNow; } catch (Exception ex) { ProcessRemoteMethodCallException(ex); } } IXiEventListItem[]? newEventListItems = EventMessagesCallbackInternal(eventList, eventMessages); if (newEventListItems is null) { throw new Exception("PollEventChanges() error."); } return(newEventListItems); }
/// <summary> /// <para> Throws or returns changed IXiDataListItems (not null, but possibly zero-lenghth). </para> /// <para> dataList is not null </para> /// <para> /// This method is used to poll the endpoint for changes to a specific data list. It is also used as a /// keep-alive for the poll endpoint by setting the listId parameter to 0. In this case, null is returned /// immediately. /// </para> /// <para> Changes consists of: </para> /// <para> 1) values for data objects that were added to the list, </para> /// <para> /// 2) values for data objects whose current values have changed since the last time they were reported to the /// client via this interface. If a deadband filter has been defined for the list, floating point values are not /// considered to have changed unless they have changed by the deadband amount. /// </para> /// <para> 3) historical values that meet the list filter criteria, including the deadband. </para> /// <para> /// This method returns the list of changed values to the client application using the ElementValuesCallback /// callback.. The list of changed values is null if this is a keep-alive. The following two standard data objects /// can also be returned. /// </para> /// <para> /// The first is identified by a ListId of 0 and a ClientId of 0. It contains a ServerStatus object value that /// indicates to the client that the server or one of its wrapped servers is shutting down. When present, this will /// always be the first value in the returned OBJECT value array. /// </para> /// <para> /// The second is identified by its ListId and a ClientId of 0. It contains a UInt32 value that indicates to the /// client how many data changes have been discarded for the specified list since the last poll response. If this /// condition persists, the client should increase its poll frequency. When present, this will always be the first /// value in the returned UINT value array. /// </para> /// </summary> /// <param name="dataList"> The data list to poll. </param> public IXiDataListItem[] PollDataChanges(XiDataList dataList) { if (dataList is null) { throw new ArgumentNullException(@"dataList"); } if (_disposed) { throw new ObjectDisposedException("Cannot access a disposed XiContext."); } if (_pollEndpoint is null) { throw new Exception("No Poll Endpoint."); } if (_pollEndpoint.Disposed) { throw new Exception("Poll Endpoint is Disposed."); } DataValueArraysWithAlias?readValueList = null; if (XiEndpointRoot.CreateChannelIfNotCreated(_pollEndpoint)) { try { readValueList = _pollEndpoint.Proxy.PollDataChanges(ContextId, dataList.ServerListId); _pollEndpoint.LastCallUtc = DateTime.UtcNow; } catch (Exception ex) { ProcessRemoteMethodCallException(ex); } } IXiDataListItem[]? changedListItems = ElementValuesCallbackInternal(dataList, readValueList); if (changedListItems is null) { throw new Exception("PollDataChanges() error."); } return(changedListItems); }
/// <summary> /// <para> /// This method is used to read the values of one or more data objects in a list. It is also used as a /// keep-alive for the read endpoint by setting the listId parameter to 0. In this case, null is returned /// immediately. /// </para> /// </summary> /// <param name="serverListId"> /// The server identifier of the list that contains data objects to be read. Null if this is a /// keep-alive. /// </param> /// <param name="serverAliases"> The server aliases of the data objects to read. </param> /// <returns> /// <para> /// The list of requested values. Each value in this list is identified by its client alias. If the server alias /// for a data object to read was not found, an ErrorInfo object will be returned that contains the server alias /// instead of a value, status, and timestamp. /// </para> /// <para> Returns null if this is a keep-alive. </para> /// </returns> public DataValueArraysWithAlias?ReadData(uint serverListId, List <uint> serverAliases) { if (_disposed) { throw new ObjectDisposedException("Cannot access a disposed XiContext."); } if (_readEndpoint is null) { throw new Exception("No Read Endpoint"); } if (_readEndpoint.Disposed) { return(null); } DataValueArraysWithAlias?readValueList = null; if (XiEndpointRoot.CreateChannelIfNotCreated(_readEndpoint)) { try { readValueList = _readEndpoint.Proxy.ReadData(ContextId, serverListId, serverAliases); _readEndpoint.LastCallUtc = DateTime.UtcNow; } catch (Exception ex) { ProcessRemoteMethodCallException(ex); } } return(readValueList); }
/// <summary> /// This method reads the properties associated with a historized data object. /// </summary> /// <param name="serverListId"> /// The server identifier of the list that contains data objects whose property values are to /// be read. /// </param> /// <param name="firstTimestamp"> /// The filter that specifies the inclusive earliest (oldest) timestamp for values to be /// returned. Valid operands include the Timestamp and OpcHdaTimestampStr constants defined by the FilterOperand class. /// </param> /// <param name="secondTimestamp"> /// The filter that specifies the inclusive newest (most recent) timestamp for values to be /// returned. Valid operands include the Timestamp and OpcHdaTimestampStr constants defined by the FilterOperand class. /// </param> /// <param name="serverAlias"> The server alias of the data object whose property values are to be read. </param> /// <param name="propertiesToRead"> /// The TypeIds of the properties to read. Each property is identified by its property /// type. /// </param> /// <returns> The array of requested property values. </returns> public JournalDataPropertyValue[]? ReadJournalDataProperties(uint serverListId, FilterCriterion firstTimestamp, FilterCriterion secondTimestamp, uint serverAlias, List <TypeId> propertiesToRead) { if (_disposed) { throw new ObjectDisposedException("Cannot access a disposed XiContext."); } if (_readEndpoint is null) { throw new Exception("No Read Endpoint"); } JournalDataPropertyValue[]? JDPVarray = null; if (XiEndpointRoot.CreateChannelIfNotCreated(_readEndpoint)) { try { JDPVarray = _readEndpoint.Proxy.ReadJournalDataProperties(ContextId, serverListId, firstTimestamp, secondTimestamp, serverAlias, propertiesToRead); _readEndpoint.LastCallUtc = DateTime.UtcNow; } catch (Exception ex) { ProcessRemoteMethodCallException(ex); } } return(JDPVarray); }