/*
         * /// <summary>
         * ///   <para> This method is used to read the historical values that fall between a start and end time for one or more data objects within a specific data journal list. </para>
         * /// </summary>
         * /// <param name="firstTimestamp"> The filter that specifies the first or beginning (of returned list) timestamp for values to be returned. Valid operands include the Timestamp (UTC) and OpcHdaTimestampStr constants defined by the FilterOperand class. The FilterOperand Operator is used to determine if the returned data should include data values the occur exactly at the first or second time stamp. If the equals operator is specified then values that occur at the first and second time stamp will be included in the sample set. Any other operator will not include first or second time stamped values. </param>
         * /// <param name="secondTimestamp"> The filter that specifies the second or ending (of returned list) timestamp for values to be returned. Valid operands include the Timestamp (UTC) and OpcHdaTimestampStr constants defined by the FilterOperand class. The FilterOperand Operator is not used. </param>
         * /// <param name="numValuesPerDataObject"> The maximum number of values to be returned for each data object. </param>
         * /// <param name="xiDataJournalListItem"> The list of data objects whose historical values are to be read. Each data object is represented by a value set that contains the values selected and returned by the server. </param>
         * public JournalDataValues ReadJournalDataForTimeInterval(FilterCriterion firstTimestamp, FilterCriterion secondTimestamp,
         *                                         uint numValuesPerDataObject,
         *                                         IXiDataJournalListItem xiDataJournalListItem)
         * {
         *  if (Disposed) throw new ObjectDisposedException("Cannot access a disposed XiDataJournalList.");
         *
         *  var serverAliases = new List<uint> {((XiDataJournalListItem) xiDataJournalListItem).ServerAlias};
         *
         *  JournalDataValues[] journalDataValuesArray = Context.ReadJournalDataForTimeInterval(ServerListId, firstTimestamp,
         *                                                                                secondTimestamp,
         *                                                                                numValuesPerDataObject,
         *                                                                                serverAliases);
         *
         *  return journalDataValuesArray.FirstOrDefault();
         * }*/

        /// <summary>
        ///     <para>
        ///         This method is used to read the historical values that fall between a start and end time for one or more
        ///         data objects within a specific data journal list.
        ///     </para>
        /// </summary>
        /// <param name="firstTimestamp">
        ///     The filter that specifies the first or beginning (of returned list) timestamp for values
        ///     to be returned. Valid operands include the Timestamp (UTC) and OpcHdaTimestampStr constants defined by the
        ///     FilterOperand class. The FilterOperand Operator is used to determine if the returned data should include data
        ///     values the occur exactly at the first or second time stamp. If the equals operator is specified then values that
        ///     occur at the first and second time stamp will be included in the sample set. Any other operator will not include
        ///     first or second time stamped values.
        /// </param>
        /// <param name="secondTimestamp">
        ///     The filter that specifies the second or ending (of returned list) timestamp for values
        ///     to be returned. Valid operands include the Timestamp (UTC) and OpcHdaTimestampStr constants defined by the
        ///     FilterOperand class. The FilterOperand Operator is not used.
        /// </param>
        /// <param name="numValuesPerDataObject"> The maximum number of values to be returned for each data object. </param>
        /// <param name="xiValueStatusTimestampSetCollection">
        ///     The list of data objects whose historical values are to be read. Each data
        ///     object is represented by a value set that contains the values selected and returned by the server.
        /// </param>
        public void ReadJournalDataForTimeInterval(FilterCriterion firstTimestamp, FilterCriterion secondTimestamp,
                                                   uint numValuesPerDataObject,
                                                   IEnumerable <IXiDataJournalValueStatusTimestampSet>?xiValueStatusTimestampSetCollection)
        {
            if (Disposed)
            {
                throw new ObjectDisposedException("Cannot access a disposed XiDataJournalList.");
            }

            var serverAliases = new HashSet <uint>();

            if (xiValueStatusTimestampSetCollection is null)
            {
                foreach (XiDataJournalListItem item in ListItemsManager)
                {
                    serverAliases.Add(item.ServerAlias);
                }
            }
            else
            {
                foreach (IXiDataJournalValueStatusTimestampSet xiValueStatusTimestampSet in xiValueStatusTimestampSetCollection)
                {
                    if (xiValueStatusTimestampSet.CalculationTypeId.LocalId ==
                        JournalDataSampleTypes.RawDataSamples.ToString(CultureInfo.InvariantCulture))
                    {
                        serverAliases.Add(
                            ((XiDataJournalValueStatusTimestampSet)xiValueStatusTimestampSet).OwningXiDataJournalListItem
                            .ServerAlias);
                    }
                }
            }

            if (serverAliases.Count == 0)
            {
                return;
            }

            JournalDataValues[]? journalDataValuesArray = Context.ReadJournalDataForTimeInterval(ServerListId,
                                                                                                 firstTimestamp,
                                                                                                 secondTimestamp,
                                                                                                 numValuesPerDataObject,
                                                                                                 serverAliases.ToList());

            if (journalDataValuesArray is not null)
            {
                foreach (JournalDataValues journalDataValues in journalDataValuesArray)
                {
                    XiDataJournalListItem?xiDataJournalListItem;
                    if (ListItemsManager.TryGetValue(journalDataValues.ClientAlias, out xiDataJournalListItem))
                    {
                        xiDataJournalListItem.Update(journalDataValues);
                    }
                }
            }
        }
Exemple #2
0
        /// <summary>
        ///     <para>
        ///         This method is used to enable or disable updating of individual elements of a list. If the
        ///         dataObjectsToEnableOrDisable parameter is null, then all elements of the list are enabled/disabled. This call
        ///         does not change the enabled state of the list itself.
        ///     </para>
        ///     <para>
        ///         When an element of the list is disabled, the server excludes it from participating in callbacks and polls.
        ///         However, at the option of the server, the server may continue updating its cache for the element.
        ///     </para>
        /// </summary>
        /// <param name="enableUpdating">
        ///     Indicates, when TRUE, that updating of the list is to be enabled, and when FALSE, that
        ///     updating of the list is to be disabled.
        /// </param>
        /// <param name="dataObjectsToEnableOrDisable"> The list of data objects to be enabled or disabled. </param>
        public void EnableListElementUpdating(bool enableUpdating,
                                              IEnumerable <IXiDataListItem>?dataObjectsToEnableOrDisable)
        {
            if (Disposed)
            {
                throw new ObjectDisposedException("Cannot access a disposed XiDataList.");
            }

            List <uint>?serverAliases = null;

            if (null != dataObjectsToEnableOrDisable)
            {
                serverAliases = new List <uint>();
                foreach (XiDataListItem item in dataObjectsToEnableOrDisable)
                {
                    serverAliases.Add(item.ServerAlias);
                    item.Enabled    = enableUpdating;
                    item.ResultCode = XiFaultCodes.S_OK;
                }
            }
            else
            {
                foreach (XiDataListItem item in ListItemsManager)
                {
                    item.Enabled    = enableUpdating;
                    item.ResultCode = XiFaultCodes.S_OK;
                }
            }

            IEnumerable <AliasResult>?listAliasResult = Context.EnableListElementUpdating(ServerListId, enableUpdating,
                                                                                          serverAliases);

            if (listAliasResult is not null)
            {
                foreach (AliasResult ar in listAliasResult)
                {
                    // Each result in the list identifies a Data Object that failed.
                    // Data objects that succeeded are not in the list
                    XiDataListItem?item;
                    ListItemsManager.TryGetValue(ar.ClientAlias, out item);
                    if (item is not null)
                    {
                        item.Enabled    = false;
                        item.ResultCode = ar.Result;
                    }
                }
            }
        }
Exemple #3
0
        public IEnumerable <IXiDataListItem>?CommitTouchDataListItems()
        {
            if (Disposed)
            {
                throw new ObjectDisposedException("Cannot access a disposed XiDataList.");
            }

            List <IXiDataListItem>?result = null;
            var serverAliases             = new List <uint>();

            foreach (XiDataListItem dataListItem in ListItemsManager)
            {
                if (dataListItem.PreparedForTouch)
                {
                    serverAliases.Add(dataListItem.ServerAlias);
                    dataListItem.HasTouched();
                }
            }

            IEnumerable <AliasResult>?results = Context.TouchDataObjects(ServerListId, serverAliases);

            if (results is not null)
            {
                result = new List <IXiDataListItem>();
                foreach (AliasResult aliasResult in results)
                {
                    XiDataListItem?item;
                    ListItemsManager.TryGetValue(aliasResult.ClientAlias, out item);
                    if (item is not null)
                    {
                        result.Add(item);
                    }
                }
            }

            return(result);
        }
Exemple #4
0
        /// <summary>
        ///     If returnChangedListItems == true, result is not null. Otherwise result is null.
        ///     This method processes the data value arrays received from the server by locating the data objects in the
        ///     data list for which values have been received and updating their values. If the notificationData parameter
        ///     is present (not null), then this method adds the received values to this notification data.
        /// </summary>
        /// <param name="readValueArrays"> The new values. </param>
        /// <param name="returnChangedListItems"> </param>
        private List <IXiDataListItem>?UpdateData(DataValueArraysWithAlias?readValueArrays, bool returnChangedListItems)
        {
            List <IXiDataListItem>?changedListItems;

            if (returnChangedListItems)
            {
                changedListItems = new List <IXiDataListItem>();
            }
            else
            {
                changedListItems = null;
            }

            if (readValueArrays is not null)
            {
                if (readValueArrays.DoubleAlias is not null)
                {
                    for (int idx = 0; idx < readValueArrays.DoubleAlias.Length; idx++)
                    {
                        XiDataListItem?item;
                        ListItemsManager.TryGetValue(readValueArrays.DoubleAlias[idx], out item);
                        if (item is not null && readValueArrays.DoubleValues is not null &&
                            readValueArrays.DoubleStatusCodes is not null &&
                            readValueArrays.DoubleTimeStamps is not null)
                        {
                            item.UpdateValue(readValueArrays.DoubleValues[idx],
                                             readValueArrays.DoubleStatusCodes[idx],
                                             readValueArrays.DoubleTimeStamps[idx]
                                             );
                            if (changedListItems is not null)
                            {
                                changedListItems.Add(item);
                            }
                        }
                    }
                }
                if (readValueArrays.UintAlias is not null)
                {
                    // TODO: Verify

                    /*
                     * int idx = 0;
                     * if (readValueArrays.UintAlias[idx] == 0) // is this a discard message?
                     * {
                     *  Context.ContextNotify(StandardListType,
                     *                        new XiContextNotificationData(XiContextNotificationType.Discards,
                     *                                                      readValueArrays.UintValues[idx]));
                     * }
                     */
                    for (int idx = 0; idx < readValueArrays.UintAlias.Length; idx++)
                    {
                        XiDataListItem?item;
                        ListItemsManager.TryGetValue(readValueArrays.UintAlias[idx], out item);
                        if (item is not null && readValueArrays.UintValues is not null &&
                            readValueArrays.UintStatusCodes is not null &&
                            readValueArrays.UintTimeStamps is not null)
                        {
                            item.UpdateValue(readValueArrays.UintValues[idx], readValueArrays.UintStatusCodes[idx],
                                             readValueArrays.UintTimeStamps[idx]);
                            if (changedListItems is not null)
                            {
                                changedListItems.Add(item);
                            }
                        }
                    }
                }
                if (readValueArrays.ObjectAlias is not null)
                {
                    for (int idx = 0; idx < readValueArrays.ObjectAlias.Length; idx++)
                    {
                        XiDataListItem?item;
                        ListItemsManager.TryGetValue(readValueArrays.ObjectAlias[idx], out item);
                        if (item is not null && readValueArrays.ObjectValues is not null &&
                            readValueArrays.ObjectStatusCodes is not null &&
                            readValueArrays.ObjectTimeStamps is not null)
                        {
                            item.UpdateValue(readValueArrays.ObjectValues[idx], readValueArrays.ObjectStatusCodes[idx],
                                             readValueArrays.ObjectTimeStamps[idx]
                                             );
                            if (changedListItems is not null)
                            {
                                changedListItems.Add(item);
                            }
                        }
                    }
                }
            }

            return(changedListItems);
        }
Exemple #5
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public IEnumerable <ClientElementValueListItem> CommitWriteElementValueListItems()
        {
            if (Disposed)
            {
                throw new ObjectDisposedException("Cannot access a disposed ClientElementValueList.");
            }

            var fullElementValuesCollection = new ElementValuesCollection();

            using (var memoryStream = new MemoryStream(1024))
            {
                using (var writer = new SerializationWriter(memoryStream))
                {
                    foreach (ClientElementValueListItem item in ListItemsManager)
                    {
                        if (item.PendingWriteValueStatusTimestamp is null)
                        {
                            continue;
                        }

                        uint alias = item.ServerAlias;
                        ValueStatusTimestamp valueStatusTimestamp = item.PendingWriteValueStatusTimestamp.Value;

                        switch (valueStatusTimestamp.Value.ValueStorageType)
                        {
                        case Ssz.Utils.Any.StorageType.Double:
                            fullElementValuesCollection.DoubleAliases.Add(alias);
                            fullElementValuesCollection.DoubleValueStatusCodes.Add(valueStatusTimestamp.ValueStatusCode);
                            fullElementValuesCollection.DoubleTimestamps.Add(DateTimeHelper.ConvertToTimestamp(valueStatusTimestamp.TimestampUtc));
                            fullElementValuesCollection.DoubleValues.Add(valueStatusTimestamp.Value.StorageDouble);
                            break;

                        case Ssz.Utils.Any.StorageType.UInt32:
                            fullElementValuesCollection.UintAliases.Add(alias);
                            fullElementValuesCollection.UintValueStatusCodes.Add(valueStatusTimestamp.ValueStatusCode);
                            fullElementValuesCollection.UintTimestamps.Add(DateTimeHelper.ConvertToTimestamp(valueStatusTimestamp.TimestampUtc));
                            fullElementValuesCollection.UintValues.Add(valueStatusTimestamp.Value.StorageUInt32);
                            break;

                        case Ssz.Utils.Any.StorageType.Object:
                            fullElementValuesCollection.ObjectAliases.Add(alias);
                            fullElementValuesCollection.ObjectValueStatusCodes.Add(valueStatusTimestamp.ValueStatusCode);
                            fullElementValuesCollection.ObjectTimestamps.Add(DateTimeHelper.ConvertToTimestamp(valueStatusTimestamp.TimestampUtc));
                            writer.WriteObject(valueStatusTimestamp.Value.StorageObject);
                            break;
                        }
                        item.HasWritten(StatusCode.OK);
                    }
                }
                memoryStream.Position = 0;
                fullElementValuesCollection.ObjectValues = Google.Protobuf.ByteString.FromStream(memoryStream);
            }

            var result = new List <ClientElementValueListItem>();

            foreach (ElementValuesCollection elementValuesCollection in fullElementValuesCollection.SplitForCorrectGrpcMessageSize())
            {
                AliasResult[] listAliasesResult = Context.WriteElementValues(ListServerAlias, elementValuesCollection);
                foreach (AliasResult aliasResult in listAliasesResult)
                {
                    ClientElementValueListItem?item = null;
                    if (ListItemsManager.TryGetValue(aliasResult.ClientAlias, out item))
                    {
                        item.HasWritten((StatusCode)aliasResult.StatusCode);
                        result.Add(item);
                    }
                }
            }
            return(result);
        }
Exemple #6
0
        /// <summary>
        ///     Returns changed ClientElementValueListItems or null, if waiting next message.
        /// </summary>
        /// <param name="elementValuesCollection"></param>
        /// <returns></returns>
        public ClientElementValueListItem[]? OnElementValuesCallback(ElementValuesCollection elementValuesCollection)
        {
            if (Disposed)
            {
                throw new ObjectDisposedException("Cannot access a disposed ClientElementValueList.");
            }

            if (elementValuesCollection.Guid != @"" && _incompleteElementValuesCollection.Count > 0)
            {
                var beginElementValuesCollection = _incompleteElementValuesCollection.TryGetValue(elementValuesCollection.Guid);
                if (beginElementValuesCollection is not null)
                {
                    _incompleteElementValuesCollection.Remove(elementValuesCollection.Guid);
                    beginElementValuesCollection.CombineWith(elementValuesCollection);
                    elementValuesCollection = beginElementValuesCollection;
                }
            }

            if (elementValuesCollection.NextCollectionGuid != @"")
            {
                _incompleteElementValuesCollection[elementValuesCollection.NextCollectionGuid] = elementValuesCollection;

                return(null);
            }
            else
            {
                var changedListItems = new List <ClientElementValueListItem>();

                for (int index = 0; index < elementValuesCollection.DoubleAliases.Count; index++)
                {
                    ClientElementValueListItem?item;
                    ListItemsManager.TryGetValue(elementValuesCollection.DoubleAliases[index], out item);
                    if (item is not null)
                    {
                        item.UpdateValue(elementValuesCollection.DoubleValues[index],
                                         elementValuesCollection.DoubleValueStatusCodes[index],
                                         elementValuesCollection.DoubleTimestamps[index].ToDateTime()
                                         );
                        changedListItems.Add(item);
                    }
                }
                for (int index = 0; index < elementValuesCollection.UintAliases.Count; index++)
                {
                    ClientElementValueListItem?item;
                    ListItemsManager.TryGetValue(elementValuesCollection.UintAliases[index], out item);
                    if (item is not null)
                    {
                        item.UpdateValue(elementValuesCollection.UintValues[index],
                                         elementValuesCollection.UintValueStatusCodes[index],
                                         elementValuesCollection.UintTimestamps[index].ToDateTime()
                                         );
                        changedListItems.Add(item);
                    }
                }
                if (elementValuesCollection.ObjectAliases.Count > 0)
                {
                    using (var memoryStream = new MemoryStream(elementValuesCollection.ObjectValues.ToByteArray()))
                        using (var reader = new SerializationReader(memoryStream))
                        {
                            for (int index = 0; index < elementValuesCollection.ObjectAliases.Count; index++)
                            {
                                object?objectValue = reader.ReadObject();
                                ClientElementValueListItem?item;
                                ListItemsManager.TryGetValue(elementValuesCollection.ObjectAliases[index], out item);
                                if (item is not null)
                                {
                                    item.UpdateValue(objectValue,
                                                     elementValuesCollection.ObjectValueStatusCodes[index],
                                                     elementValuesCollection.ObjectTimestamps[index].ToDateTime()
                                                     );
                                    changedListItems.Add(item);
                                }
                            }
                        }
                }

                return(changedListItems.ToArray());
            }
        }
Exemple #7
0
        /*
         * public void Func()
         * {
         *  if (Disposed) throw new ObjectDisposedException("Cannot access a disposed XiDataListBase.");
         * }*/

        #region protected functions

        /// <summary>
        ///     This method requests the server to add elements to the list that have been added to the local ClientBase copy
        ///     of the list. For example, after using the AddNewDataObjectToList() method add a set of data objects to the local
        ///     ClientBase copy of the list, this method is called to add them to the server's copy of the list in a single call.
        /// </summary>
        /// <returns> The list of elements that were not added to the server or null is call to server failed.</returns>
        protected IEnumerable <TXiDataAndDataJournalListItemBase>?CommitAddItemsInternal()
        {
            var listInstanceIdsCollection = new List <ListInstanceId>();

            foreach (TXiDataAndDataJournalListItemBase listItem in ListItemsManager)
            {
                if (!listItem.IsInServerList && listItem.PreparedForAdd)
                {
                    var listInstanceId = new ListInstanceId
                    {
                        ObjectElementId = listItem.InstanceId,
                        ClientAlias     = listItem.ClientAlias,
                    };
                    listInstanceIdsCollection.Add(listInstanceId);
                }
                listItem.PreparedForAdd = false;
            }

            var resultItems = new List <TXiDataAndDataJournalListItemBase>();

            if (listInstanceIdsCollection.Count > 0)
            {
                try
                {
                    List <AddDataObjectResult>?result = Context.AddDataObjectsToList(ServerListId,
                                                                                     listInstanceIdsCollection);

                    if (result is not null)
                    {
                        foreach (AddDataObjectResult r in result)
                        {
                            TXiDataAndDataJournalListItemBase?listItem = null;
                            if (ListItemsManager.TryGetValue(r.ClientAlias, out listItem))
                            {
                                listItem.ServerAlias = r.ServerAlias;
                                listItem.ResultCode  = r.Result;
                                listItem.ValueTypeId = r.DataTypeId;

                                listItem.IsReadable = true;
                                listItem.IsWritable = true;

                                if (listItem.ResultCode == XiFaultCodes.S_OK || listItem.ResultCode == XiFaultCodes.S_FALSE)
                                {
                                    listItem.IsInServerList = true;
                                    listItem.Enabled        = false;
                                }
                                else
                                {
                                    ListItemsManager.Remove(listItem.ClientAlias);
                                    // remove values that the server failed to add
                                    listItem.ClientAlias = 0; //IsInClientList = false;
                                    resultItems.Add(listItem);
                                }
                            }
                        }
                    }
                }
                catch (Exception)
                {
                    foreach (ListInstanceId ar in listInstanceIdsCollection)
                    {
                        ListItemsManager.Remove(ar.ClientAlias); // remove values that the server failed to add
                        ar.ClientAlias = 0;                      //IsInClientList = false;
                    }
                    return(null);
                }

                GetListAttributes();
            }

            return(resultItems);
        }
Exemple #8
0
        /// <summary>
        ///     This method requests the server to add elements to the list that have been added to the local ClientBase copy
        ///     of the list. For example, after using the AddNewDataObjectToList() method add a set of data objects to the local
        ///     ClientBase copy of the list, this method is called to add them to the server's copy of the list in a single call.
        /// </summary>
        /// <returns> The list of elements that were not added to the server or null is call to server failed.</returns>
        protected IEnumerable <TClientElementListItemBase>?CommitAddItemsInternal()
        {
            var listInstanceIdsCollection = new List <ListItemInfo>();

            foreach (TClientElementListItemBase listItem in ListItemsManager)
            {
                if (!listItem.IsInServerList && listItem.PreparedForAdd)
                {
                    var listInstanceId = new ListItemInfo
                    {
                        ElementId   = listItem.ElementId,
                        ClientAlias = listItem.ClientAlias,
                    };
                    listInstanceIdsCollection.Add(listInstanceId);
                }
                listItem.PreparedForAdd = false;
            }

            var resultItems = new List <TClientElementListItemBase>();

            if (listInstanceIdsCollection.Count > 0)
            {
                try
                {
                    List <AddItemToListResult> result = Context.AddItemsToList(ListServerAlias,
                                                                               listInstanceIdsCollection);

                    foreach (AddItemToListResult r in result)
                    {
                        TClientElementListItemBase?listItem = null;
                        if (ListItemsManager.TryGetValue(r.AliasResult.ClientAlias, out listItem))
                        {
                            listItem.ServerAlias = r.AliasResult.ServerAlias;
                            listItem.StatusCode  = (StatusCode)r.AliasResult.StatusCode;
                            listItem.ValueTypeId = r.DataTypeId;
                            listItem.IsReadable  = r.IsReadable;
                            listItem.IsWritable  = r.IsWritable;

                            if (listItem.StatusCode == StatusCode.OK)
                            {
                                listItem.IsInServerList = true;
                            }
                            else
                            {
                                ListItemsManager.Remove(listItem.ClientAlias);
                                // remove values that the server failed to add
                                listItem.ClientAlias    = 0;
                                listItem.IsInClientList = false;
                                resultItems.Add(listItem);
                            }
                        }
                    }
                }
                catch (Exception)
                {
                    foreach (ListItemInfo ar in listInstanceIdsCollection)
                    {
                        ListItemsManager.Remove(ar.ClientAlias); // remove values that the server failed to add
                    }
                    return(null);
                }
            }

            return(resultItems);
        }