예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        /// <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);
            }
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
        /// <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);
        }
예제 #6
0
        /// <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);
        }
예제 #7
0
        /// <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);
        }