Добрый день. Создаете скрипт "Прошла секунда", получаете из текущей даты и времени (NOW) часы минуты и секунды, сравниваете с заданными, если равно - записать значение переменной.
var
DT_now : TDateTime;
samebit : Boolean;
begin
DT_now := Now();
if (HourOf(DT_now) = 12) and (MinuteOf(DT_now)=30) and (SecondOf(DT_now) = 0) then samebit := True;
end.
В 12:30:00 каждый день установится бит
Здравствуйте.
1. Если требуется включать/отключать бит по расписанию, то нужно использовать отдельную Boolean переменную вместо бита и применять компонент "Расписание (https://simple-scada.com/help/manual/schedule.html)".
2. Если нужно выполнять какие-либо действия из скрипта через заданный интервал времени(по таймеру), то пример такого скрипта см. по ссылке (https://simple-scada.com/help/script/second-passed.html).
3. Если нужно выполнять скрипт в начале заданного часа, то можно использовать скрипт с типом события "Прошел час (https://simple-scada.com/help/script/hour-passed.html)".
4. Если требуется выполнять скрипт в какое-то заданное время(например в 12-30), то можно использовать скрипт с типом события "Прошла секунда (https://simple-scada.com/help/script/event-types.html)", в котором сравнивать текущее время с заданным:
begin
// если сейчас 12:30
if (HourOf(Now) = 12) and (MinuteOf(Now) = 30) and (SecondOf(Now) = 0) then
// , то выполнить какое-то действие
end.
Методы для работы с датой/временем можно найти в руководстве по ссылке (https://simple-scada.com/help/script/datetime.html). Если требуется изменить нужный бит переменной, то используйте функцию SetBit (https://simple-scada.com/help/script/setbit.html).
Как вариант архивировать переменную по-изменению, потом по истечению таймера использовать функцию работы с архивом
var
aDate: TDateTime;
aTimer : Integer;
begin
aTimer := aTimer * -1;
aDate:= IncMinute(Now, aTimer); // текущие дата и время минус количество минут в таймере
{ извлечь из архива значение переменной "MyVariable" в отметке времени
"aDate" и записать результат в переменную "MyVariableRes" }
ArchiveValueByTime(MyVariable, MyVariableRes, aDate);
end.
Доброго всем времени суток
Вообще глобально стоит задача подсчитывать количество и длительность простоя механизма, длительностью от 3 до 5 минут.
Алгоритм сейчас такой: по сигналу Var2 остановки механизма запускается таймер отсчёта простоя Timer, в переменную Vremya записывается время начала простоя
Если таймер простоя находится в интервале от 180 до 300 секунд и механизм продолжает стоять, то в переменную Var1 нужно записать true во время начала простоя
Если таймер простоя перешагнул отметку 300 секунд, в переменную Var1 нужно записать false во время начала простоя, т.е. этот простой не учитывать
Код (скрипт выполняется каждую секунду):
Var
Vremya, Timer:TDateTime;
Var1, Var2, AlwTrue, AlwFalse: Boolean;
K:integer;
Begin
AlwTrue.Value:=true;
AlwFalse.Value:=false;
K:=TimerGetState(Timer);
if ((Var2.value=false) and (K=-1)) then
begin
TimerStart(Timer,0);
Vremya:=Now;
end;
if ((Var2.value=true) and (K=1)) then
begin
TimerReset(Timer);
Var1.Value:=false;
end;
if ((Var2.value=false) and ((SecondsBetween(0, Timer.AsDateTime)>180) and (SecondsBetween(0, Timer.AsDateTime)<300))) then ArchiveValueByTime(Alwtrue,Var1, Vremya);
if ((Var2.value=false) and (SecondsBetween(0, Timer.AsDateTime)>300)) then ArchiveValueByTime(Alwfalse,Var1, Vremya);
end.
Здравствуйте.
Rolich, прочтите что Вы спрашивали в первом сообщении данной темы и в итоговом описании задачи в этом сообщении (https://simple-scada.com/forum/index.php?topic=1626.msg11823#msg11823). До момента полного описания задачи, в данной теме шла абсолютно бесполезная переписка. Если Вы хотите получить подробный ответ, то в вопросе сразу максимально подробно описывайте задачу целиком(а не ее отдельные фрагменты), при необходимости прилагайте дополнительную информацию(скрипты, скриншоты и т.д.). Тогда можно будет сразу дать подробный и точный ответ. Это значительно сэкономит Ваше и наше время.
Для решения задачи необходимо использовать способ описанный Timothy Clement с некоторыми изменениями. В БД нужно создать свою таблицу и использовать ее в качестве источника данных в отчетах(подробнее см. по ссылке (https://simple-scada.com/help/report/rep-user-data.html)). По сигналу Var2 записывайте время начала остановки в отдельную переменную. Если механизм простаивает нужное время (от 180 до 300 секунд), то в свою таблицу БД можно добавить новую строку с временем начала простоя(из переменной сформированной ранее), время окончания простоя и длительность простоя. По полученной таблице можно будет строить отчеты и при необходимости вывести ее в скаду (https://simple-scada.com/help/script/trunsql.html).
Возможно более простым способом будет использовать штатную систему сообщений (https://simple-scada.com/help/manual/edit-message.html), т.к. при архивации сообщений доступна информация о времени возникновения сообщения, времени завершении сообщения и его продолжительности, чего достаточно для решения описанной задачи. Для этого нужно создать отдельную группу сообщений, к примеру с именем "Простои" и создать в ней сообщения по переменным, для которых требуется отслеживать остановку механизмов. При необходимости эту группу можно скрыть от пользователей через настройку видимости групп сообщений (https://simple-scada.com/help/manual/editor-users.html). Затем в редакторе отчетов нужно создать новый отчет с типом "Сообщения", как это описано в руководстве по ссылке (https://simple-scada.com/help/report/messrep.html). При создании источника в поле "Группа сообщений" необходимо выбрать нашу группу "Простои". Далее в отчете нужно оставить требуемые колонки, например Текст сообщения, Время, Завершено и Длительность. В итоге получится таблица с простоями оборудования.
Для того, чтобы в отчет попадали только простои "в интервале от 180 до 300 секунд" нужно дважды кликнуть по бэнду данных, перейти на вкладку "Фильтры" и создать Фильтр -> Выражение:
(int)Сообщения.Длительность.TotalSeconds > 180 && (int)Сообщения.Длительность.TotalSeconds < 300
, где "Сообщения" - имя источника данных.
Для подсчета общего количества простоев нужно создать бэнд "Итог данных", разместить в нем компонент "Текст", дважды кликнуть по нему и написать выражение:
, где "DataСообщения" - имя бэнда данных, в который выводятся сообщения.
Доброго всем времени суток
Решил проблему чуть более элегантно, без костылей с созданием таблиц и сообщениями.
Суть идеи - в "отложенной" записи значений переменной остановки.
Это вполне решает задачу подсчёта количества остановок от 3 до 5 минут и их длительности штатными средствами Simple Scada
Привожу код, может кому-то будет полезно для решения аналогичной задачи:
K := TimerGetState(Timer_prostoya); // проверяем статус работы таймера простоя
// если переменная механизма в false и таймер простоя не запущен - запускаем его
if ((Var1.value = false) and (K = -1)) then
TimerStart(Timer_prostoya, 0);
// если механизм включился и таймер простоя в диапазоне 180-300 секунд
if ((Var1.value = true) and ((SecondsBetween(0, Timer_prostoya.AsDateTime) > 180) and
(SecondsBetween(0, Timer_prostoya.AsDateTime) < 300))) then
begin
Var2.value := true; // взводим переменную простоя 3-5 минут
Dlitelnost_prostoya.value := SecondsBetween(0, Timer_prostoya); // фиксируем длительность произошедшего простоя
TimerStart(Timer_3_5, 0); // стартуем таймер простоя 3-5 минут
end;
// если таймер 3-5 минут достиг значения фактического простоя
if SecondsBetween(0, Timer_3_5.AsDateTime) = Dlitelnost_prostoya.value then
begin
Dlitelnost_prostoya.value := 0; // обнулили переменную длительности
TimerReset(Timer_3_5); // остановили таймер простоя 3-5 минут
Var2.value := false; // сбросили переменную простоя 3-5 минут
end;
if ((Var1.value = true) and (K = 1)) then
TimerReset(Timer_prostoya); // реальный простой окончен, сбрасываем таймер
Спасибо всем за участие в дискуссии, было познавательно !