Стартовая страница › Форумы › Понять, как работает ПО › Использование формул › Формулы в V6 Beta
Помечено: Формулы Версия 6
- В этой теме 81 ответ, 4 участника, последнее обновление 1 год, 8 месяцев назад сделано
a80808.
-
АвторСообщения
-
26.03.2022 в 15:43 #22665
a80808
УчастникИтак:
1. Вот по поводу возвращаемого значения. Была написана формула
public CnlData TankEmu65010()
{
SetVal(65012, Val()+10);
}В канале вызов как вы и советовали «без лишних скобок»
EveryMin(TankEmu65010)В логах сообщение
2022-03-26 15:14:34 [DELL6230][DELL6230$][ERR] Ошибка при компиляции исходного кода скриптов и формул:
(353,16): error CS0161: ‘Scripts.TankEmu65010()’: not all code paths return a value
Проверьте исходный код в файле Z:\SCADA\ScadaServer\Log\CalcEngine.cs
2022-03-26 15:14:34 [DELL6230][DELL6230$][ERR] Нормальная работа невозможна2. Ставим формулу «с возвратом»
public CnlData TankEmu65010()
{
return NewData(Val()+10,1);
}
В канале EveryMin(TankEmu65010)Все работает.
Вопрос как передавать параметры…26.03.2022 в 15:57 #22666a80808
УчастникПо событиям — почему то события генерируются непрерывно, причем постоянно меняется состояние каналов — «недостоверный» — «определен». Непонятно почему, потому как состояние канала не меняется…
26.03.2022 в 16:01 #22667a80808
УчастникМаска событий (унаследованная от 5 версии) 5
26.03.2022 в 16:31 #22668a80808
УчастникP.S. Все это работает на Win 7. Оказывается если нет Симулятора, производительность в норме. Видимо он прилично подгружает…
26.03.2022 в 17:47 #22669a80808
УчастникИ еще — у меня создалось ощущение, что функция SetVal() не работает.
Вот простейшая формула в скриптах:
public CnlData TankEmu65010()
{
double capacity = Val(65010);
capacity += 27;
if (capacity > 930)
{
if (Val(65012) == 0)
{
SetVal(65012,1);
}
else
{
SetVal(65012,0);
}
capacity = 0;
}
return NewData(capacity,1);}
Т.е она добавляет значение 27 к содержимому канала 65010, и при достижении значения 930 канал обнуляется. В момент обнуления канал 65012 должен изменить свое значение на противоположное (0 или 1). Так вот, канал 65012 никогда не меняется! Пробовал и в «чистом» виде и под EveryMin()…26.03.2022 в 18:02 #22670manjey73
УчастникПоставьте на канал триггер, вполне возможно значение все таки меняется..
26.03.2022 в 20:30 #22671a80808
УчастникНет, я его вывел на схему, изменений нет. Можно конечно событие навесить…
26.03.2022 в 21:29 #22672a80808
УчастникИзменяется. Тоько на очень короткое время.
В результате понял, что нельзя делать SetVal() в расчетный канал, только во входной! Иначе значение сразу зануляется.
Изменил тип канала на входной — все заработало. Похоже это эффект работы через формулы. Раньше расчет канала запускался раз в минуту, а теперь расчет в цикле походу…28.03.2022 в 17:04 #22681Mikhail
МодераторПередача параметра:
Допустим метод имеет вид public CnlData TankEmu65010(double x) …
Тогда вызов раз в минуту будет EveryMin(() => TankEmu65010(12.3))Т.к. в объявлении метода стоит возвращаемый тип CnlData, то return должен возвращать объект этого типа.
Канал типа Входной и/или Выходной предназначен для получения или отправки данных контроллеру. Если канал рассчитывается по формулам на основе других каналов или его данные устанавливаются из других каналов, он должен быть Вычислимым.
Если что-то не работает, давайте разбираться детально.28.03.2022 в 17:26 #22688a80808
УчастникВ том то и дело. Если я делаю канал расчетным (не тот, в котором формула (65010, он расчетный по определению), а тот, в который пишется значение через SetVal() (65012)) то значение в нем изменяется на очень короткое время, затем становится равным . Удалось «поймать» только «навесив» на канал событие. А вот если он входной то все работает как надо. В пятой версии это работало с каналом типа расчетный нормально.
28.03.2022 в 20:59 #22689a80808
УчастникТеперь про параметры. Вот абсолютно реальная смоделированная ситуация.
Задача — эмулция заполнения баков с целью показать как это может быть отображено. По существу генератор «треугольника». Канал 65010 — это значение содержимого бака в куб.м. Канал 65012 — направление счета. Если 1 — бак сливается, 0 — наполняется (т.е. счет идет в плюс или минус) с каждой минутой к содержимому канала добавляется/вычитается определенная константа (27). 930 — верхний порог, 500 — нижний порог.
если я в канале пишу формулу ежеминутного вызова функции расчета без перердачи параметра все работает.
Вызов в канале 65010:
EveryMin(TankEmu65010)Скрипт:
public CnlData TankEmu65010()
{
double capacity = Val(65010);if (capacity > 930)
{
SetVal(65012,1);
}
if (capacity < 500)
{
SetVal(65012,0);
}
if (Val(65012)==1)
{
capacity -= 27;
}
else
{
capacity += 27;
}return NewData(capacity,1);
}
Пытаюсь передать номер канала направления расчета как параметр функции.
Канал 65010:
EveryMin(TankEmu65010(6512))Скрипт:
public CnlData TankEmu65010(int direct)
{
double capacity = Val(65010);if (capacity > 930)
{
SetVal(direct,1);
}
if (capacity < 500)
{
SetVal(direct,0);
}
if (Val(direct)==1)
{
capacity -= 27;
}
else
{
capacity += 27;
}return NewData(capacity,1);
}
Получаю следующее сообщение об ошибке:
2022-03-28 20:28:09 [DELL6230][DELL6230$][ERR] Ошибка при компиляции исходного кода скриптов и формул:
(619,63): error CS1503: Argument 1: cannot convert from ‘Scada.Data.Models.CnlData’ to ‘System.Func<Scada.Data.Models.CnlData>’
Проверьте исходный код в файле Z:\SCADA\ScadaServer\Log\CalcEngine.csСтрока 619 из CalcEngine.cs:
public CnlData CalcCnlData65010() { return ToCnlData(EveryMin(TankEmu65010(65012))); }
^Убираю из канала параметр в вызове, но в скрипте определяю его какк внутреннюю переменную int:
public CnlData TankEmu65010()
{
double capacity = Val(65010);
int direct = 65012;if (capacity > 930)
{
SetVal(direct,1);
}
if (capacity < 500)
{
SetVal(direct,0);
}
if (Val(direct)==1)
{
capacity -= 27;
}
else
{
capacity += 27;
}return NewData(capacity,1);
}
И все работает:
для справки — в пятой версии вызов функции выглядел так:
TankEmu(65010, 65012, 27, 500, 930)
Соответственно формула:
double TankEmu(int cnl_emu, int cnl_dir, int step, int dn_lim, int up_lim)
{
double capacity = Val(cnl_emu);if (capacity < dn_lim)
{
SetVal(cnl_dir, 1);
}
if (capacity > up_lim)
{
SetVal(cnl_dir, 0);
}
if (Val(cnl_dir) == 1)
{
capacity += step;
}
else
{
capacity -= step;
}
return capacity;
}Т.е. практически все параметры передавались через вызов. Все работало.
28.03.2022 в 21:04 #22690a80808
УчастникВ ВЕБ это выглядело так (сорри за каракули, сам рисовал 🙂 — не мое это рисование :))
Баки29.03.2022 в 11:37 #22695a80808
УчастникПочему тут нужны параметры — на станции баков великое множество и с разными параметрами. В случае расчета по косвенным данным (далеко не везде стоят расходомеры, рассчитывают по времени работы насоса) не писать же под каждый бак свою формулу…
29.03.2022 в 12:29 #22698Mikhail
МодераторПытаюсь передать номер канала направления расчета как параметр функции.
Синтаксис передачи параметра для вызова раз в минуту писал выше в сообщении #22681.
По поводу некорректной работы формулы: приложите скриншоты задействованных каналов и формул.29.03.2022 в 13:04 #22704a80808
Участник> Синтаксис передачи параметра для вызова раз в минуту писал выше в сообщении #22681.
Михаил, я понимаю, что у вас нет времени вникать в мои формулы, написанные выше. С возвратом значения все нормально. Проблема в том, что если я в канале пишу формулу вызова без параметров — все работает, если я пытаюсь передать номер канала, в который надо писать через SetVal() — причем без разницы как я его потом объявляю в формуле — идет ошибка компиляции.
Про входные/расчетные каналы понятно, но вот только если в канал (расчетный) записать что то функцией SetVal() — он мгновенно обнуляется. В пятой версии такого не было…
-
АвторСообщения
- Вы должны авторизироваться для ответа в этой теме.