Пример #1
0
        // This method uses Opc.Hda.Server class to read data
        // If OutWriter is specified, it is applied to data that were read.
        // In this case OPCHDAItemValues is NOT returned, to save memory.
        public bool Read(string strStartTime,
                         string strEndTime,
                         string[] Tagnames,
                         int AggregateID,
                         int MaxValues,
                         int ResampleInterval,
                         bool IncludeBounds,
                         bool read_raw,
                         OutputWriter OutWriter,
                         out Opc.Hda.ItemValueCollection[] OPCHDAItemValues)
        {
            if ((Tagnames == null) || (Tagnames.Count() == 0))
            {
                _trace.TraceEvent(TraceEventType.Error, 0, "HDAClient.Read: no tagnames to read");
                OPCHDAItemValues = null;
                return(false);
            }

            if (!read_raw && !(SupportedAggregates.Any(a => a.ID == AggregateID)))
            {
                _trace.TraceEvent(TraceEventType.Error, 0, "HDAClient.Read: this aggregate is not supported");
                OPCHDAItemValues = null;
                return(false);
            }

            var ItemIds = new Opc.ItemIdentifier[Tagnames.Count()];

            for (int i = 0; i < Tagnames.Count(); i++)
            {
                ItemIds[i] = new Opc.ItemIdentifier(Tagnames[i]);
            }
            // When using Server.ReadProcessed instead of Trend.ReadProcessed, we have to manually Server.CreateItems before.
            // We also have to call ReleaseItems after use
            var ItemIDResults = _OPCServer.CreateItems(ItemIds);

            for (int i = 0; i < Tagnames.Count(); i++)
            {
                if (!ItemIDResults[i].ResultID.Succeeded())
                {
                    _trace.TraceEvent(TraceEventType.Error, 0, "Tag {0} from the read list is still not valid! Result_ID={1}", Tagnames[i], ItemIDResults[i].ResultID.ToString());
                }
            }

            DateTime dtStartTime, dtEndTime;

            Opc.Hda.Time hdaStartTime, hdaEndTime;
            ConvertStrDatetimeToHDADatetime(strStartTime, out dtStartTime, out hdaStartTime);
            ConvertStrDatetimeToHDADatetime(strEndTime, out dtEndTime, out hdaEndTime);

            // Specified dtStartTime may be > than dtEndTime, this means that data should be returned in reverse order (see spec)
            int order = 1;

            if (dtStartTime > dtEndTime)
            {
                order = -1;
            }

            Opc.Hda.ItemValueCollection[] tmpOPCHDAItemValues = null;
            OPCHDAItemValues = null;

            try {
                if (read_raw)
                {
                    if ((Status != null) && (MaxValues > Status.MaxReturnValues))
                    {
                        _trace.TraceEvent(TraceEventType.Verbose, 0, "MaxValue was set to {0} (server cannot return more).", Status.MaxReturnValues);
                        MaxValues = Status.MaxReturnValues;
                    }
                    tmpOPCHDAItemValues = _OPCServer.ReadRaw(hdaStartTime, hdaEndTime, MaxValues, IncludeBounds, ItemIDResults);
                    if (OutWriter != null)
                    {
                        OutWriter.WriteHeader(tmpOPCHDAItemValues);
                        OutWriter.Write(tmpOPCHDAItemValues);
                    }
                    else
                    {
                        OPCHDAItemValues = tmpOPCHDAItemValues;
                    }
                }
                else     // ReadProcessed
                {
                    var Items = new Opc.Hda.Item[Tagnames.Count()];
                    for (int i = 0; i < Tagnames.Count(); i++)
                    {
                        Items[i]             = new Opc.Hda.Item(ItemIDResults[i]);
                        Items[i].AggregateID = AggregateID;
                    }

                    // Server returns data including start datetime, excluding last datetime: [dtStartPortion, dtEndPortion)
                    DateTime dtStartPortion = dtStartTime;
                    DateTime dtEndPortion;

                    while (order * ((dtEndTime - dtStartPortion).TotalSeconds) > 0)
                    {
                        // is 32-bit int enough for Seconds? Yes, it's 68 years
                        int numvalues = (int)Math.Abs((dtEndTime - dtStartPortion).TotalSeconds / ResampleInterval);
                        if (numvalues > Status.MaxReturnValues)
                        {
                            dtEndPortion = dtStartPortion.AddSeconds(ResampleInterval * Status.MaxReturnValues * order);
                            numvalues    = Status.MaxReturnValues;
                        }
                        else
                        {
                            dtEndPortion = dtEndTime;
                        }

                        _trace.TraceEvent(TraceEventType.Verbose, 0, "Reading {0} values from {1} to {2}",
                                          numvalues, dtStartPortion.ToString(), dtEndPortion.ToString());

                        tmpOPCHDAItemValues = _OPCServer.ReadProcessed(new Opc.Hda.Time(dtStartPortion),
                                                                       new Opc.Hda.Time(dtEndPortion), ResampleInterval, Items);

                        if (dtStartPortion.Equals(dtStartTime))
                        {
                            // if it was a first call
                            if (OutWriter != null)
                            {
                                OutWriter.WriteHeader(tmpOPCHDAItemValues);
                                OutWriter.Write(tmpOPCHDAItemValues);
                            }
                            else
                            {
                                OPCHDAItemValues = tmpOPCHDAItemValues;
                            }
                        }
                        else
                        {
                            if (OutWriter != null)
                            {
                                OutWriter.Write(tmpOPCHDAItemValues);
                            }
                            else
                            {
                                for (int i = 0; i < tmpOPCHDAItemValues.Count(); i++)
                                {
                                    OPCHDAItemValues[i].AddRange(tmpOPCHDAItemValues[i]);
                                }
                            }
                        }
                        dtStartPortion = dtEndPortion;
                    }
                }
                if (OPCHDAItemValues != null)
                {
                    _trace.TraceEvent(TraceEventType.Verbose, 0, "Number of tags = OPCHDAItemValues.Count()={0}", OPCHDAItemValues.Count());
                    _trace.TraceEvent(TraceEventType.Verbose, 0, "Number of values for the first tag = OPCHDAItemValues[0].Count={0}",
                                      OPCHDAItemValues[0].Count);
                }
                return(true);
            } catch (Opc.ResultIDException e) {
                _trace.TraceEvent(TraceEventType.Error, 0, "Opc.ResultIDException:" + e.ToString());
                // anyway, let's try to examine data
                if (tmpOPCHDAItemValues == null)
                {
                    _trace.TraceEvent(TraceEventType.Error, 0, "tmpOPCHDAItemValues == null");
                }
                else
                {
                    foreach (Opc.Hda.ItemValueCollection item in tmpOPCHDAItemValues)
                    {
                        _trace.TraceEvent(TraceEventType.Error, 0, "For tag {0}  the ResultID is {1}", item.ItemName, item.ResultID.ToString());
                    }
                }
                return(false);
            } catch (Exception e) {
                _trace.TraceEvent(TraceEventType.Error, 0, e.Message);
                _trace.TraceEvent(TraceEventType.Error, 0, e.GetType().ToString());

                if (e.Data.Count > 0)
                {
                    _trace.TraceEvent(TraceEventType.Verbose, 0, "  Extra details:");
                    foreach (System.Collections.DictionaryEntry de in e.Data)
                    {
                        _trace.TraceEvent(TraceEventType.Verbose, 0, "    Key: {0,-20}      Value: {1}",
                                          "'" + de.Key.ToString() + "'", de.Value);
                    }
                }
                return(false);
            } finally {
                _trace.TraceEvent(TraceEventType.Verbose, 0, "Releasing items.");
                _OPCServer.ReleaseItems(ItemIds);
                for (int i = 0; i < Tagnames.Count(); i++)
                {
                    if (!ItemIDResults[i].ResultID.Succeeded())
                    {
                        _trace.TraceEvent(TraceEventType.Error, 0, "Tag {0} couldn't be released! Result_ID={1}", Tagnames[i], ItemIDResults[i].ResultID.ToString());
                    }
                }
                if (OutWriter != null)
                {
                    OutWriter.Close();
                }
            }
        }
Пример #2
0
        private void CreateSignalDict(Opc.Hda.Server Hda, List <string> tagsLst, string[] propID = null, string dtBegin = null, string dtEnd = null, bool restrict = false)
        {
            Dictionary = new Dictionary <string, Signal>();
            DateTime dt1    = new DateTime();
            DateTime dt2    = new DateTime();
            var      memRec = new OpcRecord();

            if (dtBegin != null)
            {
                if (serverHda == null)
                {
                    serverHda = Hda;
                }
            }



            for (int i = 0; i < tagsLst.Count; i++)
            {
                var signal = new Signal(serverDa, tagsLst[i], propID);

                if (dtBegin != null)
                {
                    try
                    {
                        signal.ValueCollection = new List <OpcRecord>();
                        dt1 = System.Convert.ToDateTime(dtBegin);
                        dt2 = DateTime.Today;
                        DateTime lastdt = dt1;

                        if (dtEnd == null)
                        {
                            dtEnd = dt2.AddDays(1).ToString();
                        }
                        dt2 = System.Convert.ToDateTime(dtEnd);

                        signal.DtBegin = dt1;
                        signal.DtEnd   = dt2;

                        var identifiers = new ItemIdentifier[1];
                        identifiers[0] = new Opc.ItemIdentifier(tagsLst[i]);

                        Opc.IdentifiedResult[] items = serverHda.CreateItems(identifiers);
                        OpcRecord rec  = null;
                        bool      exit = false;
                        Opc.Hda.ItemValueCollection[] vForPrev = serverHda.ReadRaw(new Opc.Hda.Time(dt1),
                                                                                   new Opc.Hda.Time(dt1.AddSeconds(1)), 0, true, items);
                        signal.PrevValue = new OpcRecord();
                        if (vForPrev.Length > 0)
                        {
                            if (vForPrev[0].Count > 0)
                            {
                                signal.PrevValue.Value     = vForPrev[0][0].Value;
                                signal.PrevValue.Quality   = vForPrev[0][0].Quality.GetCode();
                                signal.PrevValue.Timestamp = vForPrev[0][0].Timestamp.ToString();
                            }
                        }
                        Opc.Hda.ItemValueCollection[] vForNext =
                            serverHda.ReadRaw(new Opc.Hda.Time(dt2.AddMilliseconds(-1)), new Opc.Hda.Time(dt2), 0, true,
                                              items);
                        signal.NextValue = new OpcRecord();
                        if (vForNext.Length > 0)
                        {
                            if (vForNext[0].Count > 0)
                            {
                                signal.NextValue.Value     = vForNext[0][vForNext[0].Count - 1].Value;
                                signal.NextValue.Quality   = vForNext[0][vForNext[0].Count - 1].Quality.GetCode();
                                signal.NextValue.Timestamp = vForNext[0][vForNext[0].Count - 1].Timestamp.ToString();
                            }
                        }

                        while (!exit)
                        {
                            Opc.Hda.ItemValueCollection[] values = serverHda.ReadRaw(new Opc.Hda.Time(lastdt),
                                                                                     new Opc.Hda.Time(dt2), 0, false, items);

                            for (int j = 0; j < values.Length; j++)
                            {
                                if (values[j].Count <= 1)
                                {
                                    exit = true;
                                }
                                for (int k = 0; k < values[j].Count; k++)
                                {
                                    rec = new OpcRecord();
                                    if (signal.ValueType == "long")
                                    {
                                        if (values[j][k].Value != null)
                                        {
                                            rec.Value = System.Convert.ToInt64(values[j][k].Value.ToString());
                                        }
                                        else
                                        {
                                            rec.Value = 0;
                                        }
                                    }
                                    if (signal.ValueType == "double")
                                    {
                                        if (values[j][k].Value != null)
                                        {
                                            rec.Value = System.Convert.ToDouble(values[j][k].Value.ToString());
                                        }
                                        else
                                        {
                                            rec.Value = 0.0;
                                        }
                                    }
                                    if (signal.ValueType == "string")
                                    {
                                        if (values[j][k].Value != null)
                                        {
                                            rec.Value = values[j][k].Value.ToString();
                                        }
                                        else
                                        {
                                            rec.Value = "";
                                        }
                                    }
                                    if (signal.ValueType == "bool")
                                    {
                                        if (values[j][k].Value != null)
                                        {
                                            rec.Value = values[j][k].Value.ToString().ToLower().Trim() == "true";
                                        }
                                        else
                                        {
                                            rec.Value = false;
                                        }
                                    }

                                    rec.Quality   = values[j][k].Quality.GetCode();
                                    rec.Timestamp = values[j][k].Timestamp.ToString();
                                    rec.Value     = values[j][k].Value;
                                    lastdt        = values[j][k].Timestamp;
                                    if (values[j].Count > 1)
                                    {
                                        if (k == values[j].Count - 1 &&
                                            values[j][k].Timestamp == values[j][k - 1].Timestamp)
                                        {
                                            lastdt = lastdt.AddMilliseconds(1);
                                        }
                                    }
                                    if (k != values[j].Count - 1)
                                    {
                                        if (restrict & signal.ValueCollection.Count > 0)
                                        {
                                            if (
                                                System.Convert.ToDateTime(
                                                    signal.ValueCollection[signal.ValueCollection.Count - 1].Timestamp)
                                                .ToString() ==
                                                System.Convert.ToDateTime(rec.Timestamp).ToString() &&
                                                rec.Quality >= 192)
                                            {
                                                signal.ValueCollection[signal.ValueCollection.Count - 1] = rec;
                                            }
                                            else
                                            {
                                                signal.ValueCollection.Add(rec);
                                            }
                                        }
                                        else
                                        {
                                            signal.ValueCollection.Add(rec);
                                        }
                                    }
                                }
                            }
                        }

                        if (restrict & signal.ValueCollection.Count > 0)
                        {
                            if (
                                System.Convert.ToDateTime(
                                    signal.ValueCollection[signal.ValueCollection.Count - 1].Timestamp).ToString() ==
                                System.Convert.ToDateTime(rec.Timestamp).ToString() && rec.Quality >= 192)
                            {
                                signal.ValueCollection[signal.ValueCollection.Count - 1] = rec;
                            }
                            else
                            {
                                signal.ValueCollection.Add(rec);
                            }
                        }
                        else
                        {
                            signal.ValueCollection.Add(rec);
                        }
                    }

                    catch (Exception)
                    {
                        MessageBox.Show(@"Отсутствует лицензия или проверьте подключения к серверу C:\Tag.ini", @"Ошибка подключения сервера", MessageBoxButton.OK, MessageBoxImage.Error);

                        Environment.Exit(0);
                    }
                }

                if (restrict)
                {
                    if (signal.ValueCollection.Count > 0)
                    {
                        if (signal.ValueCollection[0] == null)
                        {
                            signal.ValueCollection.Remove(signal.ValueCollection[0]);
                        }
                    }

                    var restrictLeft = new OpcRecord();
                    restrictLeft.Value     = signal.PrevValue.Value;
                    restrictLeft.Quality   = signal.PrevValue.Quality;
                    restrictLeft.Timestamp = dt1.ToString();
                    signal.ValueCollection.Insert(0, restrictLeft);

                    var restrictRight = new OpcRecord();
                    restrictRight.Value     = signal.ValueCollection[signal.ValueCollection.Count - 1].Value;
                    restrictRight.Quality   = signal.ValueCollection[signal.ValueCollection.Count - 1].Quality;
                    restrictRight.Timestamp = dt2.ToString();
                    signal.ValueCollection.Add(restrictRight);
                }
                Dictionary.Add(tagsLst[i], signal);
            }
        }