Страница 1 из 1
Добавлено: 13 май 2009, 15:30
Blaze
1) В RAD Studio -2007, когда я помещаю на форму компонент TdepSvgPanel, то не могу перемещать его по форме. Выделяется он лишь правой кнопкой мыши (но выделение какое-то странное, будто кружки выделения находятся под объектом).
2) После запуска модели я не могу выделить на форме на компоненте TdepSvgPanel (на svg рисунке) ни одного элемента. Приходится закрывать форму и открывать заново. Так и должно быть?
3) Допустим я создал и запустил модель. Далее запускаю ДЭП ОРС проводник. В нем я могу изменять значения дискретов - все нормально. Но если я пытаюсь изменять значение аналогов (для того же примера с насосами), то у меня вместо нуля (заданного по умолчанию) быстро проскакивает первая цифра введенного мной нового значения аналога и опять появляется ноль.
4) В том же примере про насосы, кнопка "квитировать" мигает у меня только тогда, когда я в проводнике ставлю галочку во внимание у SignalAlarm. Если не выходить из рамок примера, то должна ли кнопка мигать еще в каком-нибудь случае? Например, когда мигает лампочка "пожар" или когда мигает треугольник у насоса?
Добавлено: 13 май 2009, 16:50
Dino
Blaze писал(а):1) В RAD Studio -2007, когда я помещаю на форму компонент TdepSvgPanel, то не могу перемещать его по форме. Выделяется он лишь правой кнопкой мыши (но выделение какое-то странное, будто кружки выделения находятся под объектом).
Описанная Вами проблема в данном случае имеет место. В будущем предполагается сделать два режима взаимодействия с панелью(как обычный компонент TPanel(без возможности выделения SVG-элементов) и как поведение как сейчас). TdepSvgPanel можно также выбрать нажав Shift+Alt+F11, вызвав структуру формы.
Blaze писал(а):2) После запуска модели я не могу выделить на форме на компоненте TdepSvgPanel (на svg рисунке) ни одного элемента. Приходится закрывать форму и открывать заново. Так и должно быть?
Описанная Вами проблема у нас не наблюдается. Скачайте последнюю версию компонентов со страницы
http://www.dep.ru/page/updating_software/. Если проблема все еще осталась вышлите свой проект и модель на
kl_alex@dep.ru, описав последовательность действий, приводящих к ошибке.
На следующие вопросы будет дан ответ 14.05.09.
Добавлено: 14 май 2009, 10:01
galina
Добрый день!
3)Во-первых, различают 2 вида сигналов: входные (wdAIn, wdCIn, wdDIn) и выходные (wdAOut, wdCOut, wdDOut, wdDOutImp).
Во входные сигналы вы НЕ можете писать из модели. В выходные можете, если в модели нет типа tUsers. Если есть тип tusers, то необходимо войти в систему.
OPC проводник отображает дерево WD и дерево модели.
Дерево WD - те дискреты, аналоги и счетчики, которые находятся в запущенном WD. Эти дискреты, аналоги, счетчики, например, могут приходить с модулей. Поэтому когда вы их меняете, то естественно модуль перезаписывает значение.
Добавлено: 14 май 2009, 10:15
galina
4) SignalAlarm имеет тип alState. В справке написано: "alState - контролируемый элемент в аварийном состоянии, если его значение достоверно и удовлетворяет условиям CheckedState". В CheckedState у вас стоит 1. Значит, как только у вас элементы, имеющие тип FVSignal будут иметь 1, то возведется авария. Тип FVSignal имеют элементы Fire и Voltage.
Добавлено: 15 май 2009, 18:14
Blaze
к 4), когда я меняю в opc проводнике значения так, то у меня возникает пожар или отсутствие напряжения, то кнопка "квитировать" не загорается. К тому же, в моем проекте SignalAlarm не имеет тип alState (по кр мере в примере указано поставить другой тип). А что такое тип FVSignal , я вообще не знаю.
5) Где можно найти любой пример или информацию о том, как связать модель, созданную в конструкторе и алгоритм, созданный в разработчике. Хотя бы, чтобы при, скажем, нажатии на кнопку в модели производился расчет чисел и результат выводился на форме. Или чтобы делалось хоть что-нибудь.
6) Есть ли возможность включить в модель редактор ввода чисел (напрямую из работающей формы, запущенной в CodeGear)?
Добавлено: 17 май 2009, 21:49
galina
4)значит, я посмотела старую справку. Напишите тип того элемента, к которому вы привязываете кнопку "Квитировать", далее я вам подскажу.
5)И в "Разработчике" и в модели можно производить вычисления. Модель выполняется на компьютере. Компонент "Разработчика" выполняется в контроллере. Для того, чтобы выполнять вычисления в модели необходимо добавить функцию в необходимый тип и написать код на С. Также можно часть вычислений производить в модели, часть в "Разработчике".
Как связать вычисления Разработчика и модели? Например, писать моделью дискрет, а читать его "Разработчиком" и проанализировав его выполнять необходимые операции.
Добавлено: 18 май 2009, 08:34
Blaze
Как указано в справке, кнопку "Квитировать" привязываем к элементу AllUndef.
Сигнал имеет параметры:
- тип alAlarm
- поле Root - тип CTP
- TypeName - SignalUndef
- AutoReset - False
- AlarmControl - True
SignalUndef имеет тип alToBad.
Добавлено: 18 май 2009, 11:36
Dino
Blaze писал(а):6) Есть ли возможность включить в модель редактор ввода чисел (напрямую из работающей формы, запущенной в CodeGear)?
Вопрос не совсем понятен. Опишите более подробно что Вы хотите сделать.
Добавлено: 18 май 2009, 16:54
galina
Читаем Help: "alToBad - тревожное состояние - это недостоверное значение контролируемого элемента. " Значит, авария будет взведена, если элементы, имеющие тип SignalUndef и являющиеся подэлментами типа CTP, будут иметь флаг неопределенности.
Добавлено: 18 май 2009, 18:38
Blaze
к 6) В Codegear есть компонент TEdit. Он нужен для ввода информации. Так вот при запущенной программе мне хотелось бы, например, в TEdit ввести число, потом нажать кнопку TButton, а это число отобразится на модели на компоненте TdepSvgPanel в качестве wdAOut - т.е. на экране в его сразу будет видно. Понимаете?
7) Т.к. модель реализуется через Codegear, то можно ли взаимодействовать с злементами модели напрямую через компоненты Codegear?
а) например, при нажатии на кнопку TButton (компонент Codegear) чтобы подавалась команда на элемент модели - скажем лампочка загоралась или значение value подавалось бы на элемент-приемник.
б) если вышеуазанное возможно, то в том же блоке операции, написанной средствами си или delphi можно было бы производить вычисления, в заваисмости от результата которых взаимодействовать с элементами модели.
Если вышесказанное покажется непонятным, то могу спросить проще - можно ли обратиться к элементу модели минуя opc design form? Скажем, чтобы при нажатии кнопки TButton свойству caption метки label (codegear) присваивалось значение value любого элемента модели (например из примера с насосами State элемента Pump).
8_) Не понимаю про создание пользовательских функций. В них можно производить дествия только с элементами opc или еще что-то?
Допустим, в примере с насосами я хочу создать пользовательскую функцию, которая будет передавать значение 1 в элемент Voltage.
Я создаю новую привязку к произвольному компоненту по "нажатию кнопки мыши".
Далее ставлю галочку пользовательской функции.
Имя - f1
Тип параметра - константа
Значение - 1
Что мне делать дальше? Если нажать кнопку редактирования тела функции, то я не знаю что там писать. Если не нажимать, а запускать программу на выполнение, то вообще ничего не происходит.
И еще, пожалуйста, опишите любой пример пользовательской функции с типом параметра - opc тег. Конкретно - что писать в описании пользовательской функции и в теле самой функции.
Добавлено: 19 май 2009, 08:11
Blaze
galina писал(а):Читаем Help: "alToBad - тревожное состояние - это недостоверное значение контролируемого элемента. " Значит, авария будет взведена, если элементы, имеющие тип SignalUndef и являющиеся подэлментами типа CTP, будут иметь флаг неопределенности.
Хорошо, Галина, скажите - что мне сделать, чтобы кнопка "квитировать" все-таки загоралась при мигании лампочек "пожар" или "напряжение"?
Добавлено: 19 май 2009, 10:37
galina
Чтобы кнопка "Квитировать" замигала, необходимо, чтобы поле State любого насоса изменило значение с определенного на неопределенное.
Почему так? Pump имеет поле State типа DIn. Также Pump имеет SignalAlarm типа SignalUndef (унаследованного от alToBad). Контролируемыми элементами SiganlAlarm являются элементы, имеющие тип DIn. Значит, как только поле State будет иметь переход с определенности к неопреденоости, то в каждом Pump взведется авария SignalAlarm.
А в типе CTP существует элемент AllUndef, который по аварии SignalAlarm любого насоса взведет тревогу.
P.S. Проверьте еще раз правильность модели, если тревога не взвелась!
Добавлено: 19 май 2009, 10:39
galina
По Напряжению и пожару в примере не сделана тревога. Вы сами можете попробовать ее добавить и проверить.
Добавлено: 19 май 2009, 11:09
galina
6) Если в TEdit нужно смотреть текущее значение аналога, то к полю Text добавляете ОРС - привязку, где выбираете необходимый аналог и пишете %f.
Если по кнопке хотите писать значение из TEdit в аналог, то
1) надо добавить привязку к кнопке на левое нажатие клавиши мыши
2) поставить галочку "Пользовательская функция"
3) Ввести название функции и проследовать в С-код где будет прототип данной функции и где можно написать ее тело.
4) в aWriteValue написать значение из TEdit.
5) В привязке в элементе-приемнике написать необходимый аналог, куда будет писаться значение.
Добавлено: 19 май 2009, 11:11
galina
8. В модели есть возможно добавлять функции к типу. Меню "Тип"->"Новая функция"
Добавлено: 19 май 2009, 12:27
Blaze
В модели и пробовал задать функцию, но получил ошибку
Error E2376 C:\DEPt\temp1\CTPF.cpp 8: If statement missing ( in function TCTP::val1()
Warning W8070 C:\DEPt\temp1\CTPF.cpp 9: Function should return a value in function TCTP::val1()
Я записал это:
//--!-- TCTP::val1() ;public
TCTP::val1()
{
if CmdOn = 1 then State == 1;
}
___
И все же, есть ли возможность в CodeGear (например в теле пользовательской функции) обратиться напрямую к элементу модели, находящемуся на TdepSvgPanel?
Если да, то как пишется полный путь к нему? Может что-то типа этого (то что написано - чисто образно) depOpcModel.CTP.GroupPump.Pump1.State или depOpcModel.SVGLayer1.rect3411.
Или так обращаться нельзя?
Добавлено: 19 май 2009, 13:13
Dino
Blaze писал(а):7) Т.к. модель реализуется через Codegear, то можно ли взаимодействовать с злементами модели напрямую через компоненты Codegear?
а) например, при нажатии на кнопку TButton (компонент Codegear) чтобы подавалась команда на элемент модели - скажем лампочка загоралась или значение value подавалось бы на элемент-приемник.
б) если вышеуазанное возможно, то в том же блоке операции, написанной средствами си или delphi можно было бы производить вычисления, в заваисмости от результата которых взаимодействовать с элементами модели.
Если вышесказанное покажется непонятным, то могу спросить проще - можно ли обратиться к элементу модели минуя opc design form? Скажем, чтобы при нажатии кнопки TButton свойству caption метки label (codegear) присваивалось значение value любого элемента модели (например из примера с насосами State элемента Pump).
Да, это можно сделать, без использования редактора динамизации, создавая пользовательские привязки или читая синхронно из элементов модели(см. в справке раздел "Программный доступ для расширенных возможностей"-> "Синхронное чтение и запись значений в тэги(элементы) OPC сервера" и "Асинхронное чтение и запись значений в тэги(элементы) OPC сервера(пользовательские привязки)"
).
Blaze писал(а):8_) Не понимаю про создание пользовательских функций. В них можно производить дествия только с элементами opc или еще что-то?
Допустим, в примере с насосами я хочу создать пользовательскую функцию, которая будет передавать значение 1 в элемент Voltage.
Я создаю новую привязку к произвольному компоненту по "нажатию кнопки мыши".
Далее ставлю галочку пользовательской функции.
Имя - f1
Тип параметра - константа
Значение - 1
Что мне делать дальше? Если нажать кнопку редактирования тела функции, то я не знаю что там писать. Если не нажимать, а запускать программу на выполнение, то вообще ничего не происходит.
Пользовательская функция служит для пересчета значения(ий) элементов OPC сервера перед производимыми действиями(установка свойств компонента, запись в OPC элемент) и выполнения дополнительных действий(например, при записи в OPC элемент можно вызвать диалог с подтверждением выполняемых действий, т.е. выполнить запись или отменить ее)
О пользовательских фунциях также написано в файле справки. Если Вы все же читали справку, но вопросы остались, задайте их повторно.
Добавлено: 19 май 2009, 13:24
galina
Blaze писал(а):В модели и пробовал задать функцию, но получил ошибку
Error E2376 C:\DEPt\temp1\CTPF.cpp 8: If statement missing ( in function TCTP::val1()
Warning W8070 C:\DEPt\temp1\CTPF.cpp 9: Function should return a value in function TCTP::val1()
Я записал это:
//--!-- TCTP::val1() ;public
TCTP::val1()
{
if CmdOn = 1 then State == 1;
}
___
Нужно писать на С. К элементам нельзя так обращаться. Они не представляют собой простые типы. Откройте в BDS модель и посмотрите какого они типа. Также смотрите "Справку".
Добавлено: 19 май 2009, 13:44
Blaze
galina писал(а):Чтобы кнопка "Квитировать" замигала, необходимо, чтобы поле State любого насоса изменило значение с определенного на неопределенное.
Почему так? Pump имеет поле State типа DIn. Также Pump имеет SignalAlarm типа SignalUndef (унаследованного от alToBad). Контролируемыми элементами SiganlAlarm являются элементы, имеющие тип DIn. Значит, как только поле State будет иметь переход с определенности к неопреденоости, то в каждом Pump взведется авария SignalAlarm.
А в типе CTP существует элемент AllUndef, который по аварии SignalAlarm любого насоса взведет тревогу.
P.S. Проверьте еще раз правильность модели, если тревога не взвелась!
Единственный способ увидеть мигание кнопки квитирования пока в opc проводнике установить галочку в поле "внимание" SignalUndef любого насоса. Но мне хотелось бы попробовать вызвать это явление программно.
Добавляю кнопку на форму и выбираю пользовательскую функцию, передающую значение в сигнал state. Хочу передать состояние "неопределенность". Правильно будет, если я запишу в теле функции такую строку:
aWriteQuality := 'BAD';
Ибо, когда я запускаю на выполнение, то codegear ругается на 'BAD'. Может aWriteQuality записывется как-то иначе? В справке по этому поводу ничего не нашел.
galina писал(а):Blaze писал(а):В модели и пробовал задать функцию, но получил ошибку
Error E2376 C:\DEPt\temp1\CTPF.cpp 8: If statement missing ( in function TCTP::val1()
Warning W8070 C:\DEPt\temp1\CTPF.cpp 9: Function should return a value in function TCTP::val1()
Я записал это:
//--!-- TCTP::val1() ;public
TCTP::val1()
{
if CmdOn = 1 then State == 1;
}
___
Нужно писать на С. К элементам нельзя так обращаться. Они не представляют собой простые типы. Откройте в BDS модель и посмотрите какого они типа. Также смотрите "Справку".
Можете мне 1 раз исправить строчку, которую я написал в теле функции на правильный или приблизительно правильный вариант. Ибо я не совсем понимаю о чем идет речь.
Добавлено: 19 май 2009, 13:53
galina
В "Помощь" есть пункт "Программный доступ для расширенных возможностей". Там описана функция, как сделать quality плохим.
Можно самим имитировать: в WD в дискрете состояния поставить 1, а потом стереть (то есть неопределенность).
Добавлено: 19 май 2009, 15:10
Blaze
galina писал(а):В "Помощь" есть пункт "Программный доступ для расширенных возможностей". Там описана функция, как сделать quality плохим.
Если вы имеете в виду
procedure QualitySetBad(var aQuality: TdepOpcQuality);
то когда я пишу в тело пользовательской функции по нажатию мыши (значение передается в state)
QualitySetBad(aWriteQuality);
то ничего не происходит
Добавлено: 20 май 2009, 10:28
Blaze
Функции:
function TdepOpcServer.ReadFromTag(const aFullOpcName: string; var aValue: Variant; var aQuality: TdepOpcQuality; var aTimeStamp: TDateTime): HResult;
function TdepOpcServer.WriteToTag(const aFullOpcName: string; const aValue: Variant; const aQualitySpecified: Boolean = False; const aQuality: TdepOpcQuality = 0): HResult;
Можно ли получить по каждой из них пример того, как они будут звучать, если вместо параметров подставить то, что должно там стоять? Например в теле пользовательской функции. Для любого примера, хоть для того же примера с насосами.
Добавлено: 20 май 2009, 10:59
galina
Blaze писал(а):Можете мне 1 раз исправить строчку, которую я написал в теле функции на правильный или приблизительно правильный вариант. Ибо я не совсем понимаю о чем идет речь.
Надо писать так:
TCTP::val()
{
//с помощью value() получаем текущее значение
if( GroupOtopl.Pump1.State.value() == 1 )
//с помощью assign пишем
GroupOtopl.Pump1.CmdOn.assign(1);
else
GroupOtopl.Pump1.CmdOn.assign(0);
}
Еще раз. Создавайте проект для C++ Builder и смотрите какие там структуры данных, какие у них методы.
Эта функция нигде не будет вызываться. Они ни от чего не унаследована. Следовательно, вам нужно самим ее вызывать. Например, создаете еще одну функцию, унаследованной от тактовой и пишете ее вызов:
void TMainType::tact()
{
inherited::tact();
CTP.val();
}
P.S. Можно было сразу писать в тактовой функции!
Добавлено: 20 май 2009, 11:14
galina
Blaze писал(а):Функции:
function TdepOpcServer.ReadFromTag(const aFullOpcName: string; var aValue: Variant; var aQuality: TdepOpcQuality; var aTimeStamp: TDateTime): HResult;
function TdepOpcServer.WriteToTag(const aFullOpcName: string; const aValue: Variant; const aQualitySpecified: Boolean = False; const aQuality: TdepOpcQuality = 0): HResult;
Можно ли получить по каждой из них пример того, как они будут звучать, если вместо параметров подставить то, что должно там стоять? Например в теле пользовательской функции. Для любого примера, хоть для того же примера с насосами.
Variant V; unsigned short Q; TDateTime t;
if( SUCCEEDED( gOpcApplication->DefaultAlias->ReadFromTag("CTP\\GroupOtopl\\Pump1\\State", V, Q, t) ) )
;
gOpcApplication->DefaultAlias->WriteToTag("CTP\\GroupOtopl\\Pump1\\CmdOn", 1, false, 0);
Добавлено: 20 май 2009, 11:25
Dino
Blaze писал(а):Если вы имеете в виду
procedure QualitySetBad(var aQuality: TdepOpcQuality);
то когда я пишу в тело пользовательской функции по нажатию мыши (значение передается в state)
QualitySetBad(aWriteQuality);
то ничего не происходит
В пользовательской функции записи также требуется явно указать в возвращаемом параметре aQualitySpecified, что требуется записать Quality (aQualitySpecified = true).
Добавлено: 20 май 2009, 13:01
Blaze
galina писал(а):gOpcApplication->DefaultAlias->WriteToTag("CTP\\GroupOtopl\\Pump1\\CmdOn", 1, false, 0);
В Delphi это звучит так?
gOpcApplication.DefaultAlias.WriteToTag('CTP\\GroupOtopl\\Pump1\\CmdOn', 1, false, 0)
Ибо, когда я вешаю эту функцию на кнопку, то ничего не происходит.
(пробовал заменять \\ на \ и на .)
Вот еще что...
У меня такая версия CodeGear, которая позволяет создавать проекты только на Delphi.
Вы рекомендуете поискать другой CodeGear?
Или может делать все не в opc-конструкторе и CodeGear, а целиком в C++Builder?
Добавлено: 20 май 2009, 13:17
galina
Blaze писал(а):galina писал(а):gOpcApplication->DefaultAlias->WriteToTag("CTP\\GroupOtopl\\Pump1\\CmdOn", 1, false, 0);
В Delphi это звучит так?
gOpcApplication.DefaultAlias.WriteToTag('CTP\\GroupOtopl\\Pump1\\CmdOn', 1, false, 0)
Ибо, когда я вешаю эту функцию на кнопку, то ничего не происходит.
(пробовал заменять \\ на \ и на .)
Вот еще что...
У меня такая версия CodeGear, которая позволяет создавать проекты только на Delphi.
Вы рекомендуете поискать другой CodeGear?
Или может делать все не в opc-конструкторе и CodeGear, а целиком в C++Builder?
CodeGear необходимо использовать для использования ОРС - динамизации 3.0.
А модель можно писать и отлаживать в C++Builder 6.0. Рекомендую отлаживать в C++Builder 6.0.
\\ используется в С++.
\ мспользуетя в Delphi.
Добавлено: 21 май 2009, 01:25
Faster
ГАЛИНА, а писатьдля зилока проще в q4 так что надо цать компиляторов держать на одном компе , и не важно что будут проблемы так как RAD студио не переносит Builder 6.0 так как юзают одни ключив реестре...
хотя конечно можно и так поступить, но я всегда повтаряю что осмотр гланд через анус не очень эффективноезанятие.
Про конструктор можели я уже писал не однакратно , да и любой кодер вам скажит что если чтото за вас пишет код это страшно !