Современные технологии автоматизации» («СТА») —  журнал для квалифицированных специалистов по промышленной автоматизации Форум СТА — современные технологии автоматизации Домашняя страница
Домашняя страница форума CTA Домашняя страница форума CTA > II. АСУТП и SCADA > Программное обеспечение
  Активные темы Активные темы
  FAQ FAQ  Искать в форуме   Зарегистрироваться Зарегистрироваться  Вход в систему Вход в систему

TrendWorX VBA (вычисление значений для точек графика)

 Ответить Ответить Страница  12>
Автор
Сообщение
DubAlex Смотреть выпадающим
Действительный член
Действительный член
Аватар

Присоединился: 28 Февраль 2007
Категория: Russian Federation
Online Status: Offline
Публикации: 212
Свойства публикации Свойства публикации   Ответить, цитируя автора - DubAlex Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Тема сообщения: TrendWorX VBA (вычисление значений для точек графика)
    Опубликовано: 13 Февраль 2008 18:00

Снова я со своими вопросами.

Задача: в зависимости от выбранной дискретности (30 мин., час и т.д.) вычислять потребляемую энергию (Вт/ч) за заданный дискрет.

Есть несколько однотипных скриптов вида:

Set obj = ThisDisplay.GetVisibleObjectFromName("TWXViewer1")

Set twx = obj.GetOLEObject

Set tset = twx.TimeSettings

rtime = twx.GetRightTime

seconds = DatePart("s", rtime)

rtime = DateAdd("s", seconds * -1, rtime)

twx.FreezeMode = True

twx.ChangeWinPeriod (120)

If Not twx.SetTrendRightTDate(rtime) Then

MsgBox "Error"

End If

twx.ExitAnimate

tset.DataUpdatePeriod = 1800000

twx.EnterAnimate

twx.FreezeMode = False

Суть их в возможности выбора дискретности отображения архивных данных и области построения графика. Результат выглядит примерно так:

выбор работает нормально, но для полного счастья нужно реализовать следующее:

в идеале нужно чтобы скрипт брал каждое значение из графика, т.е., предположим: в 14:30 - значение равно 39.78, в 15:00 - значение равно 40.34 и заносил их, допустим, в какие-то массивы. Затем в массиве скрипт умножает все значения на коэффициент. Потом умноженные значения переносит снова на график - получается новый график.

Коэффициент устанавливается в зависимости от значения в поле "Дискретность".

Вопросы:

1. Я не могу "вытаскивать" из графика значения в определенный момент времени. Предположим, я не могу занести в переменную значение 39.78 соответствующее моменту времени 14:30. Можно ли это сделать вообще?

2. Все это вроде бы решается, если напрямую читать из БД Access архивные данные, преобразовывать их и выводить на график с помощью TWXViewer1.SetPenValues(). Проблема в том, что формат архивации в БД Access не совсем обычный, т.к. хронология событий записывается не в один столбец, а в одну строку (сначала в строку, затем переходит на другую строку и снова в строку). Нет ли у кого-нибудь готового скрипта, выполняющего чтение из БД Access архивных данных (чтение именно из формата, которого придерживается TrendWorX Server)?

3. Есть ли другой способ реализации этой задачи?

Наверх
MuadDib Смотреть выпадающим
Действительный член
Действительный член
Аватар

Присоединился: 27 Июль 2006
Online Status: Offline
Публикации: 304
Свойства публикации Свойства публикации   Ответить, цитируя автора - MuadDib Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 14 Февраль 2008 05:49
Самым правильным решением здесь было бы, по-моему, следующее: выдирать данные из HDA сервера TrendWorx по интерфейсу OPC HDA, производить их мат обработку и строить по обработанным данным Custom Pen.

С обработкой и построением проблем быть не должно, а вот с получением данных...

Теоретически, можно использовать OPC HDA Wrapper под VBA. Но правильнее было бы применить что-то стандартное из Gen32. Так что, хотелось бы обратиться к уважаемым представителям ПроСофт: есть ли в Gen32 стандартный инструментарий для получения HDA-данных в VBA-скрипте? Мне самому этот вопрос весьма интересен.

Кстати, по вашему методу есть небольшое замечание: вычисляя энергию на "верху" путем интегрирования значения мощности, вы огребете существенную погрешность. Величина-то интегральная. Более правильный подход - использование прибора, который _измеряет_ энергию, снятие с него величины энергии по цифровому интерфейсу и вычисление потребления энергии на интервалах по разности показаний счетчика прибора. И еще, кстати, активная энергия измеряется в Вт*ч
Теория - это когда все знаешь, но ничего не работает.
Практика - это когда все работает, но никто не знает как.
Наверх
DubAlex Смотреть выпадающим
Действительный член
Действительный член
Аватар

Присоединился: 28 Февраль 2007
Категория: Russian Federation
Online Status: Offline
Публикации: 212
Свойства публикации Свойства публикации   Ответить, цитируя автора - DubAlex Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 14 Февраль 2008 08:45

Первоначально опубликовано MuadDib

Теоретически, можно использовать OPC HDA Wrapper под VBA.

А где можно почитать про него?

Первоначально опубликовано MuadDib


есть ли в Gen32 стандартный инструментарий для получения HDA-данных в VBA-скрипте?

Казалось бы, весьма стандартная задача. Нужно же иногда преобразовывать и архивные данные тоже? Но в документации я не смог ничего найти по этому вопросу.

Первоначально опубликовано MuadDib


Кстати, по вашему методу есть небольшое замечание: вычисляя энергию на "верху" путем интегрирования значения мощности, вы огребете существенную погрешность. Величина-то интегральная. Более правильный подход - использование прибора, который _измеряет_ энергию, снятие с него величины энергии по цифровому интерфейсу и вычисление потребления энергии на интервалах по разности показаний счетчика прибора. И еще, кстати, активная энергия измеряется в Вт*ч

Прибора, измеряющего энергию нет и не будет. Есть только ток и напряжение. Поэтому делаю под то, что есть.

По поводу Вт*ч Вы, конечно, правы (опечатка)

Наверх
MuadDib Смотреть выпадающим
Действительный член
Действительный член
Аватар

Присоединился: 27 Июль 2006
Online Status: Offline
Публикации: 304
Свойства публикации Свойства публикации   Ответить, цитируя автора - MuadDib Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 14 Февраль 2008 08:59
На счет wrapper. Напишите мне в личку свой e-mail, вечером я отправлю вам халявный враппер и документацию.

На счет измерения энергии. У вас постоянный ток? Если нет, то для вычисления активной энергии по току и напряжению потребуется коэффициент мощности. Его, по идее, тоже нужно измерять.
Теория - это когда все знаешь, но ничего не работает.
Практика - это когда все работает, но никто не знает как.
Наверх
MuadDib Смотреть выпадающим
Действительный член
Действительный член
Аватар

Присоединился: 27 Июль 2006
Online Status: Offline
Публикации: 304
Свойства публикации Свойства публикации   Ответить, цитируя автора - MuadDib Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 14 Февраль 2008 09:16
В догонку, по поводу стандартности задачи о работе с архивными данными. Да, действительно, задачка типовая. Но! ICONICS продает пакет BizViz, в состав которого входит мощные средства генерации отчетов по архивным данным. Стоимость данного пакета та еще. А что было бы, если бы в комплект Gen32, входил полноценный инструмент для работы с архивными данными из VBA? Тогда бы пресловутый ReportWorX никто бы не покупал. Отсюда вывод...

Мне бы очень хотелось ошибаться по данному вопросу. И надеюсь, представители ICONICS в России развеют мое заблуждение. Но на данный момент я тоже не вижу в Gen32 какого-бы то ни было средства обработки архивных данных. TWX Reporter не в счет.
Теория - это когда все знаешь, но ничего не работает.
Практика - это когда все работает, но никто не знает как.
Наверх
DubAlex Смотреть выпадающим
Действительный член
Действительный член
Аватар

Присоединился: 28 Февраль 2007
Категория: Russian Federation
Online Status: Offline
Публикации: 212
Свойства публикации Свойства публикации   Ответить, цитируя автора - DubAlex Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 14 Февраль 2008 11:27

Первоначально опубликовано MuadDib


Мне бы очень хотелось ошибаться по данному вопросу. И надеюсь, представители ICONICS в России развеют мое заблуждение. Но на данный момент я тоже не вижу в Gen32 какого-бы то ни было средства обработки архивных данных. TWX Reporter не в счет.

Получается, что остается только способ с общением с БД Access напрямую через запросы? Или тут тоже будет затруднительно сформировать запрос, учитывая формат архивирования данных? 

Наверх
MuadDib Смотреть выпадающим
Действительный член
Действительный член
Аватар

Присоединился: 27 Июль 2006
Online Status: Offline
Публикации: 304
Свойства публикации Свойства публикации   Ответить, цитируя автора - MuadDib Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 14 Февраль 2008 13:06
Если через OPC HDA wrapper удастся достучаться до Trendworx, то формат БД станет для вас несущественным - вы просто должны будете задать нужный тег и параметры выборки и получить набор значений напрямую от OPC HDA сервера. Другое дело, что все это еще нужно попробовать. Гарантию, что такая схема заработает, я дать не могу. У меня времени разобраться во всем этом и проверить не было. Может быть, у вас получится. Необходимый софт я вышлю сегодня вечером. Удачи!
Теория - это когда все знаешь, но ничего не работает.
Практика - это когда все работает, но никто не знает как.
Наверх
DubAlex Смотреть выпадающим
Действительный член
Действительный член
Аватар

Присоединился: 28 Февраль 2007
Категория: Russian Federation
Online Status: Offline
Публикации: 212
Свойства публикации Свойства публикации   Ответить, цитируя автора - DubAlex Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 16 Февраль 2008 20:43

Все же решил попробывать написать собственный скрипт.

Заметил такую деталь: TrendWorX Server пишет каждый параметр только в 36 колонок, а затем переходит на следующую строку и снова заполняет 36 колонок для каждого параметра. Т.е., формат примерно следующий:

  V1   T1   M1   Q1   V2  T2  M2   Q2 ... V36 T36 M36 Q36

V37 T37 M37 Q37 V38 T38 M38 Q38 ... V72 T72 M72 Q72

где Vi - значение тега, Ti - дата и время, Mi - миллисекунды, Qi - качество

Описал я приблизительно, там, конечно, еще куча информации, но в качестве примера сойдет.

Код следующий:

    Const kol_column_TWX = 36
    Const kol_element = 9000
    Dim adoConnection As ADODB.Connection   'имя подключения
    Dim rsInitData As ADODB.Recordset       'имя набора данных (здесь хранятся все значения из БД)
    Dim qryText As String                   'строка SQL-запроса
   
    Dim values(1 To kol_elements)           'массив значений измеряемого параметра
    Dim tDates(1 To kol_elements)           'массив дат
    Dim mSecs(1 To kol_elements)            'массив миллисекунд (не учитывается, поэтому все значения = 0)
    Dim qual(1 To kol_elements)             'массив качества значений (качество всегда хорошее)
    Dim kol_str                             'количество строк в БД (TrendWorX Server довольно специфично архивирует
                                            'данные: сначала он записывает 36 значений в одну строку, затем переходит на
                                            'следующую строку. Затем снова 36 значений в одной строке и снова на
                                            'следующую строку. Параметр kol_str содержит в себе количество таких строк и
                                            'используется при заполнении массивов значениями)
    Set adoConnection = New ADODB.Connection 'создаем подключение
    Set rsInitData = New ADODB.Recordset    'выделяем переменную для хранения архивных данных
   
    kol_str = 0                             'инициализация
    adoConnection.Provider = "Microsoft.Jet.OLEDB.4.0" 'устанавливаем параметры соединения
    'имя используемой БД
    adoConnection.ConnectionString = "DataSource=D:\work\genesis\databases\sme1_seria1_DBTwxData.mdb"
    adoConnection.Open "D:\work\genesis\databases\my_DBTwxData.mdb" 'открываем базу
    If Not (adoConnection.State = adStateOpen) Then 'обработка ошибок
        MsgBox "Извините, не могу подключиться, проверьте путь к БД", vbCritical, "Ошибка"
    End If
    'формируем SQL-запрос для получения данных из БД
    qryText = "SELECT Sample_TDate_1,Sample_TDate_2,Sample_TDate_3,Sample_TDate_4,Sample_TDate_5,Sample_TDate_6,Sample_TDate_7,"
    qryText = qryText & "Sample_TDate_8,Sample_TDate_9,Sample_TDate_10,Sample_TDate_11,Sample_TDate_12,Sample_TDate_13,Sample_TDate_14,"
    qryText = qryText & "Sample_TDate_15,Sample_TDate_16,Sample_TDate_17,Sample_TDate_18,Sample_TDate_19,Sample_TDate_20,Sample_TDate_21,"
    qryText = qryText & "Sample_TDate_22,Sample_TDate_23,Sample_TDate_24,Sample_TDate_25,Sample_TDate_26,Sample_TDate_27,Sample_TDate_28,"
    qryText = qryText & "Sample_TDate_29,Sample_TDate_30,Sample_TDate_31,Sample_TDate_32,Sample_TDate_33,Sample_TDate_34,Sample_TDate_35,"
    qryText = qryText & "Sample_TDate_36,Sample_Value_1,Sample_Value_2,Sample_Value_3,Sample_Value_4,Sample_Value_5,Sample_Value_6,"
    qryText = qryText & "Sample_Value_7,Sample_Value_8,Sample_Value_9,Sample_Value_10,Sample_Value_11,Sample_Value_12,Sample_Value_13,"
    qryText = qryText & "Sample_Value_14,Sample_Value_15,Sample_Value_16,Sample_Value_17,Sample_Value_18,Sample_Value_19,Sample_Value_20,"
    qryText = qryText & "Sample_Value_21,Sample_Value_22,Sample_Value_23,Sample_Value_24,Sample_Value_25,Sample_Value_26,Sample_Value_27,"
    qryText = qryText & "Sample_Value_28,Sample_Value_29,Sample_Value_30,Sample_Value_31,Sample_Value_32,Sample_Value_33,Sample_Value_34,"
    qryText = qryText & "Sample_Value_35,Sample_Value_36 "
    qryText = qryText & "FROM seria1 WHERE seria1.Signal_Index = 1 ORDER BY "
    qryText = qryText & "seria1.Sample_TDate_1 ASC,seria1.Sample_TDate_2 ASC,seria1.Sample_TDate_3 ASC,seria1.Sample_TDate_4 Asc"
    'выполняем запрос
    rsInitData.Open qryText, adoConnection, adOpenForwardOnly, adLockReadOnly, adCmdText
    If rsInitData.EOF And rsInitData.BOF Then
        MsgBox "Извините, не могу инициализировать объект", vbCritical, "Ошибка"
    End If
    rsInitData.MoveFirst                    'переходим к первой строке полученной таблицы с данными
    While (Not rsInitData.EOF)              'заполняем массивы полученными данными
        For i = 1 To kol_column_TWX
            arr_index = i + kol_str * kol_column_TWX 'формула для вычисления индекса массива
            values(arr_index) = rsInitData.Fields(i + (kol_column_TWX - 1)) 'формат хранения данных в переменной
                                        'rsInitData после выполнения SQl-запроса следующий:
                                        'в первых 36 столбцах хранятся даты значений                                                               '
                                        'в столбцах с 37 по 72 хранятся сами значения
                                        'индексация начинается не с 1, а с 0, поэтому и используется формула:
                                        'i + (kol_column_TWX - 1)
            tDates(arr_index) = rsInitData.Fields(i - 1) ' индексация с 0
            mSecs(arr_index) = 0            'не учитываем миллисекунды, поэтому равны 0
            qual(arr_index) = 192           'значение 192 соответствует хорошему качеству тега
        Next i
        rsInitData.MoveNext                 'переходим к следующей строке полученной таблицы с данными
        kol_str = kol_str + 1               'счетчик строк тоже увеличиваем
    Wend

Можете пользоваться, если кому-то пригодится. Правда там могут всплыть проблемы с подключением библиотек (ADODB, к примеру) и т.д., но это уже другой вопрос.

Но вот если формат в 36 колонок не является постоянным, то этот кусок кода оказывается абсолютно бесполезным.

Вопрос: действительно ли TrendWorX Server придерживается этого формата (36 колонок) или через пару месяцев их станет 72, затем 144 и т.д. (у меня база накопила пока данных чуть больше чем за неделю)?

Если формат все же изменяется, то есть ли функцая которая вычисляет количество колонок в таблице, чтобы можно было отслеживать это в программе?

Наверх
MuadDib Смотреть выпадающим
Действительный член
Действительный член
Аватар

Присоединился: 27 Июль 2006
Online Status: Offline
Публикации: 304
Свойства публикации Свойства публикации   Ответить, цитируя автора - MuadDib Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 18 Февраль 2008 05:36
Не думаю, что формат таблицы меняется. Но, как правило, при конфигурировании TWX задается формирование нескольких таблиц с данными. Поэтому в скрипте необходимо предварительно читать одну из служебных таблиц и формировать запрос, в общем случае, по нескольким смежным по времени таблицам.
Теория - это когда все знаешь, но ничего не работает.
Практика - это когда все работает, но никто не знает как.
Наверх
DubAlex Смотреть выпадающим
Действительный член
Действительный член
Аватар

Присоединился: 28 Февраль 2007
Категория: Russian Federation
Online Status: Offline
Публикации: 212
Свойства публикации Свойства публикации   Ответить, цитируя автора - DubAlex Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 18 Февраль 2008 08:14

Первоначально опубликовано MuadDib

Не думаю, что формат таблицы меняется. Но, как правило, при конфигурировании TWX задается формирование нескольких таблиц с данными. Поэтому в скрипте необходимо предварительно читать одну из служебных таблиц и формировать запрос, в общем случае, по нескольким смежным по времени таблицам.

У меня сконфигурировано так, что таблица одна

Наверх
 Ответить Ответить Страница  12>

Переход на форум Права доступа на форуме Смотреть выпадающим

Bulletin Board Software by Web Wiz Forums® version 9.64
Powered by Web Wiz Forums Free Express Edition
Copyright ©2001-2009 Web Wiz