Exemple #1
0
        /// <summary>
        /// Прочитать тренд из бинарника
        /// </summary>
        /// <param name="channel">Канал, для которого грузится тренд</param>
        public ReadChannelTrendResult ReadChannelTrendFromBinaryFile(/*string filePath,*/ RpdChannel channel)
        {
            var result = new ReadChannelTrendResult {
                Result = ((RpdMeter)channel.OwnerMeter).CloneAndLinkWithFault(null)
            };

            // Запишем в результат измеритель (родитель для channel)
            result.Result.Channels.Clear();                                           //каналы тоже склонировались!!1
            result.Result.Channels.Add(channel.CloneAndLinkWithMeter(result.Result)); //добавим результирующему измерителю канал
            try {
                result.Result.Channels[0].Trend.Clear();                              //очистим тренд канала, вдруг там что-то есть!
                //using (AdvancedBinaryReader reader = new AdvancedBinaryReader(new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read), false))
                using (var reader = new AdvancedBinaryReader(new FileStream(BinFilePath.FullName, FileMode.Open, FileAccess.Read), false))
                {
                    // запомним количество страниц в файле
                    long pagesCount = reader.BaseStream.Length / 2048;

                    // постраничное перемещение i
                    int timePosition = 0;

                    for (long i = 0; i < pagesCount; ++i)
                    {
                        try {
                            var pageRaw = new byte[2048];                             //ряд байтов, представляющих собой страницу
                            reader.Read(pageRaw, 0, 2048);                            //считываем страницу
                            // тут не надо проверять псн! // && pageRaw[0] != 0x80) //если это не заголовок аварии и не данные по ПСН (по идее заголовок - это >= 0x55) fixed
                            if (pageRaw[0] < 0x55)
                            {
                                int meterAddrFromPage = pageRaw[0];                                    //номер/адрес измерителя хранится в первом байте страницы
                                if (meterAddrFromPage == result.Result.Channels[0].OwnerMeter.Address) //если страница принадлежит нужному измерителю, то:
                                {
                                    var currentPage = new FaultArchivePage(pageRaw, this);             //сформируем страницу как объект
                                    var neededMeter = (RpdMeter)result.Result.Channels[0].OwnerMeter;

                                    //если настройки не считаны - считываем:
                                    if (!neededMeter.SettingsReaded)
                                    {
                                        neededMeter.ReadSettings(currentPage);                                         // Настройки измерителя хранятся в первой послезаголовочной странице ( TODO: а если это измеритель № 10 и его настройки не влезли в первую послезаголовочную страницу?)
                                    }

                                    // В любом случае удаляем информационные строки с настройками по измерителю
                                    RemoveMeterSettingLines(currentPage);
                                    // Зачем пытаться удалять то, чего возможно и нет? (не лучше ли будет перенести под условие if (!neededMeter.SettingsReaded)
                                    // Не лучше, т.к. нужно в люом случае проверять строки на нулевой номер (вдруг в системе куча измерителей? и т.п.)
                                    // Можно не удалять, а работать только со строками, номер которых больше нуля (нулевые - это строки настроек измерителей)


                                    // Теперь необходимо прочесать строки и найти строки для нашего канала
                                    foreach (VariableLengthPageLine currentLine in currentPage.Lines)
                                    {
                                        if (currentLine.ChannelNumber + 1 == result.Result.Channels[0].Number)                                         //ввбираем строки для нужного канала
                                        {
                                            foreach (int val in currentLine.Values)
                                            {
                                                ChannelCalibration chT = neededMeter.Settings.Calibrations.Channels[result.Result.Channels[0].Number - 1];
                                                //формула вычисления значения с учетом настроек измерителя: (см. ТЗ)
                                                var point = new DataPointSimple((val - chT.Zero) * chT.Kkor * chT.Kper * 1.0, AccuredAt.AddTicks((long)(timePosition * (10000000.0 / neededMeter.Settings.Time) - neededMeter.TrendsTimeOffset * 10)), true, 0, null); // TODO
                                                result.Result.Channels[0].Trend.Add(point);                                                                                                                                                                            // *10 is microseconds in ticks//timePosition * 25 - neededMeter.TrendsTimeOffset));
                                                timePosition++;
                                            }
                                            //else пропускаем, такого канала в системе нету :(
                                        }
                                    }
                                }
                            }
                        }
                        catch {
                            // TODO: remove empty catch
                        }
                    }
                    //sw.Close();//DEBUG
                    reader.Close();                     //ридер нужно закрыть
                }
            }
            catch             // (Exception ex)
            {
                result = null;
            }

            return(result);
        }
Exemple #2
0
 /// <summary>
 /// Создаёт новый экземпляр класса
 /// </summary>
 /// <param name="channel">Ассоциируемый канал</param>
 /// <param name="data">Данные канала</param>
 public RpdChannelCurrentData(RpdChannel channel, double data)
 {
     _channel = channel;
     Data     = data;
 }