Пример #1
0
        /// <summary>Получить значения параметров источника данных за указанный час</summary>
        /// <param name="begin_time">Начало часового интервала</param>
        /// <param name="source">Описатель источника данных</param>
        /// <param name="table">Буфер в памяти для приёма значений параметров</param>
        private static bool ReadInterval(SourceConfiguration source, DateTime begin_time, out MemoryTable table)
        {
            // диагностическая переменная для определения успешных запросов к группам источников данных
            bool result = false;

            // инициализация таблицы в памяти для приёма сырых данных
            table = new MemoryTable();

            foreach (string _station in source.Stations)
            {
                // диагностическая переменная для определения успешных запросов к отдельным источникам данных
                bool _result_per_station = false;

                // чтение истории значений каждого параметра по отдельности
                foreach (KeyValuePair <ushort, ParameterConfiguration> __parameter in source.Parameters)
                {
                    // обращение к источникам данных по типу
                    switch (source.SourceType)
                    {
                    case SourceType.Kvint:
                        _result_per_station = kvint_stations[_station].get_hour_interval(begin_time, __parameter.Key, __parameter.Value.Name, ref table);
                        break;

                    case SourceType.Odbc:
                        _result_per_station = odbc_sources[_station].get_hour_interval(begin_time, __parameter.Key, __parameter.Value.sql_queries, ref table);
                        break;

                    default:
                        break;
                    }

                    if (!_result_per_station)
                    {
                        break;                       // при отсутствии данных по одному из параметров, дальнейший запрос источника прекращается
                    }
                }

                result = result || _result_per_station; // чтение интервала успешно, если успешен запрос хотя бы одного источника
            }

            return(result);
        }
Пример #2
0
        /// <summary>Извлекает свойства параметра</summary>
        /// <param name="source">Конфигурация источника данных</param>
        /// <param name="node_kvint_parameter">Узел дерева XML файла конфигурации, описывающий одиночный параметр</param>
        private void _get_parameter_properties(SourceConfiguration source, XmlNode node_kvint_parameter)
        {
            // чтобы получить номер параметра по его абстрактному имени, выполняем поиск ключа по значению перебором
            foreach (KeyValuePair <ushort, string> name in _abstract_parameter_names)
            {
                if (name.Value == node_kvint_parameter.Name)
                {
                    source.Parameters[name.Key] = new ParameterConfiguration();

                    // по умолчанию относим сигнал к шумоподобным, если его линейность явно не указана
                    if (node_kvint_parameter.Attributes.GetNamedItem("type") != null)
                    {
                        if (node_kvint_parameter.Attributes.GetNamedItem("type").Value == "linear")
                        {
                            source.Parameters[name.Key].Type = ParameterType.Linear;
                        }
                    }

                    // записываем локальное название параметра в источнике данных, кроме источника типа odbc, где для доступа к истории значений используется коллекция sql-запросов
                    if (source.SourceType == SourceType.Odbc)
                    {
                        // для источника данных odbc в качестве имени заносим абстрактное имя параметра
                        source.Parameters[name.Key].Name = name.Value;

                        // заполняем коллекцию sql запросов для получения значений параметров из базы данных
                        foreach (XmlNode query in node_kvint_parameter.SelectNodes("*"))
                        {
                            // при использовании свойства InnerText происходит конвертация экранированных значений xml вида "&lt;" в текстовое представление вида "<"
                            if (query.Name == "query")
                            {
                                source.Parameters[name.Key].sql_queries.Add(query.InnerText);
                            }
                        }
                    }
                    else
                    {
                        // записываем локальное название параметра в источнике данных, используемое для доступа к истории параметра
                        source.Parameters[name.Key].Name = node_kvint_parameter.InnerText;
                    }
                }
            }
        }
Пример #3
0
        /// <summary>Преобразование сырых данных в набор строк по шаблону</summary>
        /// <param name="config">Конфигурация</param>
        /// <param name="begin_time">Начало часового интервала</param>
        /// <param name="table">Таблица в памяти для принятых данных</param>
        /// <param name="buffer">Буфер в памяти для обработанных данных</param>
        private static long ProcessInterval(Configuration config, SourceConfiguration source, DateTime begin_time, ref MemoryTable table, out MemoryStream buffer)
        {
            long quality = 0;                                              // результирующее качество выборки по числу строк с хорошим качеством

            buffer = new MemoryStream();                                   // создаёт поток в памяти для записи выборки из текущего источника
            StreamWriter writer = new StreamWriter(buffer, Encoding.UTF8); // создаёт писатель текстовых данных в бинарный поток

            for (uint row = 0; row < 3600; row++)
            {
                int    row_quality = 0; // результирующее качество строки данных
                string result      = config.pattern;

                // запрос строки: названия параметров заменяются ближайшими по времени значениями
                foreach (string _str in Regex.Split(config.pattern, @"[;:]+"))
                {
                    result = result.Replace("_row_", row.ToString()); // вставка номера строки (секунды)

                    if (Regex.IsMatch(_str, @"^[$][A-z]+[$]$"))
                    {
                        // чтобы получить номер параметра по его абстрактному имени, выполняем поиск ключа по значению перебором
                        foreach (KeyValuePair <ushort, string> __abstract_name in config.abstract_parameter_names)
                        {
                            if (__abstract_name.Value == _str.Trim('$'))
                            {
                                // объявления переменных для запроса значения параметра
                                bool     column_quality;
                                double   column_value;
                                DateTime column_timestamp;

                                // запрос значения параметра, ближайшего по запрашиваемому времени
                                if (table.read_sample(__abstract_name.Key, begin_time.AddSeconds(row), out column_timestamp, out column_value, out column_quality))
                                {
                                    // для шумоподобных параметров анализируется отставание метки времени последнего полученного значения от времени запроса
                                    // если отставание превышает maximum_latency секунд, строке присваивается плохое качество
                                    if (source.Parameters[__abstract_name.Key].Type == ParameterType.Noisy &&
                                        (begin_time.AddSeconds(row) - column_timestamp).CompareTo(new TimeSpan(0, 0, config.maximum_latency)) > 0)
                                    {
                                        column_quality = false;
                                    }

                                    // замещение названий параметров значениями
                                    result = result.Replace(_str, String.Format(nfi, "{0:F" + config.precision + "}", column_value));

                                    // подсчёт количества значений с хорошим качеством для последующей оценки качества строки
                                    row_quality = row_quality + (column_quality ? 1 : 0);
                                }
                            }
                        }
                    }
                }

                // вставка интегрального качества выборки, вычисляется сравнением количества значений с хорошим качеством, с общим количеством зарегистрированных параметров
                result = result.Replace("_quality_", row_quality == config.abstract_parameter_names.Count ? "1" : "0");

                // запись строки с результатом в поток с результатом для текущего источника
                writer.WriteLine("{0}", result);

                // подсчёт строк с хорошим качеством
                if (row_quality > 0)
                {
                    quality++;
                }
            }

            writer.Flush();                   // сброс буфера текстового писателя потока
            buffer.Seek(0, SeekOrigin.Begin); // перемещение файлового указателя потока в начальную позицию
            return(quality);                  // возврат интегрального качества выборки
        }
Пример #4
0
        /// <summary>Загрузка конфигурации из файла</summary>
        public void Load(string file)
        {
            XmlDocument xml = new XmlDocument(); // создаёт заготовку XML-документа

            try
            {
                xml.Load(String.Format(@"{0}\{1}", Program.base_path, file)); // загрузка файла конфигурации в память

                #region Загрузка настроек
                foreach (XmlNode __node in xml.SelectNodes("/settings/options/*"))
                {
                    try
                    {
                        if (__node.Name == "path")
                        {
                            _path = __node.InnerText;
                        }
                        if (__node.Name == "pattern")
                        {
                            _pattern = __node.InnerText;
                        }
                        if (__node.Name == "precision")
                        {
                            _precision = int.Parse(__node.InnerText);
                        }
                        if (__node.Name == "deph")
                        {
                            _deph = int.Parse(__node.InnerText);
                        }
                        if (__node.Name == "maximum_latency")
                        {
                            _maximum_latency = int.Parse(__node.InnerText);
                        }
                        if (__node.Name == "debug_level_console")
                        {
                            _debug_level_console = int.Parse(__node.InnerText);
                        }
                        if (__node.Name == "debug_level_file")
                        {
                            _debug_level_file = int.Parse(__node.InnerText);
                        }
                        if (__node.Name == "debug_level_eventlog")
                        {
                            _debug_level_eventlog = int.Parse(__node.InnerText);
                        }
                    }
                    catch (Exception ex) { }
                }

                _parse_pattern(_pattern);
                #endregion

                #region Загрузка конфигурации энергоблоков
                foreach (XmlNode block in xml.SelectNodes("/settings/blocks/*"))
                {
                    if (block.Attributes.GetNamedItem("prefix") != null)
                    {
                        _blocks[block.Name]        = new Block();
                        _blocks[block.Name].prefix = block.Attributes.GetNamedItem("prefix").Value;
                    }
                    else
                    {
                        break;
                    }

                    #region Загрузка конфигурации источников
                    foreach (XmlNode node in xml.SelectNodes("/settings/blocks/" + block.Name + "/sources/*"))
                    {
                        try
                        {
                            SourceConfiguration source = new SourceConfiguration();

                            source.Name = node.Name;

                            if (node.Attributes.GetNamedItem("type") != null)
                            {
                                if (node.Attributes.GetNamedItem("type").Value.ToLower() == "kvint")
                                {
                                    source.SourceType = SourceType.Kvint;
                                }
                                if (node.Attributes.GetNamedItem("type").Value.ToLower() == "odbc")
                                {
                                    source.SourceType = SourceType.Odbc;
                                }
                                if (node.Attributes.GetNamedItem("type").Value.ToLower() == "opc_ua")
                                {
                                    source.SourceType = SourceType.OpcUa;
                                }
                            }

                            #region Архивные станции Квинта
                            if (source.SourceType == SourceType.Kvint)
                            {
                                foreach (XmlNode node_kvint in xml.SelectNodes("/settings/blocks/" + block.Name + "/sources/" + source.Name + "/*"))
                                {
                                    if (node_kvint.Name == "station")
                                    {
                                        source.Stations.Add(node_kvint.InnerText);
                                    }
                                    if (node_kvint.Name == "parameters")
                                    {
                                        foreach (XmlNode node_kvint_parameters in xml.SelectNodes("/settings/blocks/" + block.Name + "/sources/" + source.Name + "/parameters/*"))
                                        {
                                            _get_parameter_properties(source, node_kvint_parameters);
                                        }
                                    }
                                }
                            }
                            #endregion

                            #region Источники данных ODBC
                            if (source.SourceType == SourceType.Odbc)
                            {
                                foreach (XmlNode node_odbc in xml.SelectNodes("/settings/blocks/" + block.Name + "/sources/" + source.Name + "/*"))
                                {
                                    if (node_odbc.Name == "station")
                                    {
                                        source.Stations.Add(node_odbc.InnerText);
                                    }
                                    if (node_odbc.Name == "parameters")
                                    {
                                        foreach (XmlNode node_kvint_parameter in xml.SelectNodes("/settings/blocks/" + block.Name + "/sources/" + source.Name + "/parameters/*"))
                                        {
                                            _get_parameter_properties(source, node_kvint_parameter);
                                        }
                                    }
                                }
                            }
                            #endregion

                            #region Серверы архивных данных стандарта OPC UA Historical Access (не поддерживается)
                            #endregion

                            _blocks[block.Name].sources.Add(source); // добавление конфигурации источника в общий список
                        }
                        catch (Exception ex) { }
                    }
                    #endregion
                }
                #endregion
            }
            catch (Exception ex) { Console.WriteLine("ERROR: ошибка загрузки конфигурации: {0}", ex.Message); }
        }