PDA

Просмотр полной версии : Расписание включение/выключение установки для MasterSCADA 4d



Cinks
05.05.2020, 04:06
Добрый день.

Делаю расписание для включения/отключения установки, а также для задачи уставки на определенный период времени.
Проблемы с переходом времени в новые сутки, ну и с моей логикой. Я еще не программист, только начинаю изучать данное ремесло.
Призываю коллективный разум на помощь. Заранее благодарю всех за участие и помощь.
Дальше код и пояснение проблем с которыми столкнулся.
Код:

if (Расписание_ВКЛ_ВЫКЛ=TRUE) and (Индикатор сезона=1) THEN
if (ПН=TRUE) THEN
if ((Сейчас_время>=Время_вкл) and (Сейчас_время<Время_выкл) and (День_недели=1)) then
Выход:=10; Флаг:=true;
ELSE Выход:=5; Флаг:=false;
end_if;
end_if;

if (ВТ=TRUE) THEN
if ((Сейчас_время>=Время_вкл) and (Сейчас_время<Время_выкл) and (День_недели=2)) then
Выход:=10; Флаг:=true;
ELSE Выход:=5; Флаг:=false;
end_if;
end_if;

if (СР=TRUE) THEN
if ((Сейчас_время>=Время_вкл) and (Сейчас_время<Время_выкл) and (День_недели=3)) then
Выход:=10; Флаг:=true;
ELSE Выход:=5; Флаг:=false;
end_if;
end_if;

if (ЧТ=TRUE) THEN
if ((Сейчас_время>=Время_вкл) and (Сейчас_время<Время_выкл) and (День_недели=4)) then
Выход:=10; Флаг:=true;
ELSE Выход:=5; Флаг:=false;
end_if;
end_if;

if (ПТ=TRUE) THEN
if ((Сейчас_время>=Время_вкл) and (Сейчас_время<Время_выкл) and (День_недели=5)) then
Выход:=10; Флаг:=true;
ELSE Выход:=5; Флаг:=false;
end_if;
end_if;

if (СБ=TRUE) THEN
if ((Сейчас_время>=Время_вкл) and (Сейчас_время<Время_выкл) and (День_недели=6)) then
Выход:=10; Флаг:=true;
ELSE Выход:=5; Флаг:=false;
end_if;
end_if;

if (ВС=TRUE) THEN
if ((Сейчас_время>=Время_вкл) and (Сейчас_время<Время_выкл) and (День_недели=7)) then
Выход:=10; Флаг:=true;
ELSE Выход:=5; Флаг:=false;
end_if;
end_if;

end_if;

Проблемы:
1. 24 часа в сутках. При условии (Сейчас_время>=8:00) and (Сейчас_время<18:00), в промежутке между 8:00-18:00 код работает.
Но если задать условие (Сейчас_время>=8:00) and (Сейчас_время<00:01) тогда код оказывается неработоспособным, по причине невыполнения условия.
Задать точку включения днем и точку выключения ночью не получается, используя данную логику.

2. И еще не могу придумать, как привязаться к дню недели. К примеру точка включения днем в понедельник 8:00 и точка выключения 00:01(а это уже вторник). Если мне нужно использовать расписание только в понедельник, получается, что я не могу даже использовать "ИЛИ"(понедельник или вторник). Если мне нужно в понедельник использовать расписание, а точка выключения оказывается ночью во вторник, то не получается привязаться к условия "понедельник".

Логика подсказывает что многие решали подобную задачу.
Покажите свои решения подобной задачи. Расскажите, как вам удалось придти к решению?

Призываю коллективный разум на помощь. Заранее благодарю всех за участие и помощь.

b_aleks
05.05.2020, 11:49
1. 24 часа в сутках. При условии (Сейчас_время>=8:00) and (Сейчас_время<18:00), в промежутке между 8:00-18:00 код работает.
Но если задать условие (Сейчас_время>=8:00) and (Сейчас_время<00:01) тогда код оказывается неработоспособным, по причине невыполнения условия.
Задать точку включения днем и точку выключения ночью не получается, используя данную логику.
Это условие у вас и не выполнится, тут ничего удивительного. Подставьте любое время с 08:00 до 00:00 и сами увидите, что второе условие в скобках никогда не отработает. Чтобы задать работу установки в промежуток времени с 08:00 до 00:00, достаточно написать:


IF Текущее_время < Утро //константа 8 часов утра
THEN Работа_установки := FALSE
ELSE Работа_установки := TRUE
END_IF;


2. И еще не могу придумать, как привязаться к дню недели. К примеру точка включения днем в понедельник 8:00 и точка выключения 00:01(а это уже вторник). Если мне нужно использовать расписание только в понедельник, получается, что я не могу даже использовать "ИЛИ"(понедельник или вторник). Если мне нужно в понедельник использовать расписание, а точка выключения оказывается ночью во вторник, то не получается привязаться к условия "понедельник".


Для того чтобы привязаться ко дню недели, имеется специальная функция - DAY_OF_WEEK. Также при работе со временем в MS4D необходимо обязательно учитывать часовой пояс, т.к. в программе в режиме отладки может отображаться правильное время, но некоторые функции на самом деле будут считать не совсем корректно.

Да и вообще я бы сделал по-другому.
1. Сделать отдельный условный блок в программе, который определяет текущие временные параметры (текущее время дня, текущий день недели и прочее).
2. При помощи цикла


if {выражение1} then {последовательность предложений1}

elsif {выражение2} then {последовательность предложений2}

...

elsif {выражениеN} then {последовательность предложенийN}

else {последовательность предложений} end_if

реализовать требуемую логику включения и отключения оборудования.

Cinks
05.05.2020, 12:41
И снова я вас благодарю за помощь!
А есть мысли как привязаться к дню недели, если точка включения днем, а точка выключения ночью?
Значение дня недели я вычисляю правильно и корректно его могу использовать.
Если мне нужно включать установку только в понедельник 8:00, и выключить в 00:10(а это уже вторник). Ведь вторник это уже новый день, и соответственно значения дня изменится в 00:01. И если задать в коде условие работы включения "понедельник", а точка выключения оказывается во вторник - ничего работать не будет.
Вот используемый мною код для получения дня недели, текучего времени с учетом часового пояса и др.:

//Данный код работает.
Plus7:=t#7h;
UTC_TIME_DT:=GET_UTC_TIME();
UTC_TIME_TOD:=DT_TO_TOD(UTC_TIME_DT)
Сейчас_время:=ADD_TOD_TIME(UTC_TIME_TOD , Plus7);

Время_DT_UTC_TIME_Plus7:=ADD_DT_TIME(UTC_TIME_DT, Plus7);
Сейчас_дата_время:=date_and_time_to_string(Время_D T_UTC_TIME_Plus7);
год:=String_to_int(Left(Сейчас_дата_время,4));
Сейчас_дата_время_без_года:=DELETE(Сейчас_дата_вре мя,5,1);
месяц:=String_to_int(Left(Сейчас_дата_время_без_го да,2));
Сейчас_дата_время_без_года_и_месяца:=delete(Сейчас _дата_время_без_года,3,1);
день:=String_to_int(left(Сейчас_дата_время_без_год а_и_месяца,2));


a:=(14-месяц)/12;
y:=год-a;
m:=месяц+12*a-2;

промежуточный_параметр:=REAL_TO_INT(день+y+y/4-y/100+y/400+(31*m)/12);


День_недели_числом:=MOD(промежуточный_параметр,7);

CASE День_недели_числом of
0:День_недели:="Воскресенье";
1:День_недели:="Понедельник";
2:День_недели:="Вторник";
3:День_недели:="Среда";
4:День_недели:="Четверг";
5:День_недели:="Пятница";
6:День_недели:="Суббота";


end_case;

If ((День_недели_числом=0) OR (День_недели_числом=6)) then Выходной_день:=true;
else Выходной_день:=false;
end_if;


Здесь небольшая ошибка, вы указали знак (<) меньше, поэтому код будет работать наоборот, только с 00:00 по 8:00

IF Текущее_время < Утро //константа 8 часов утра
THEN Работа_установки := FALSE
ELSE Работа_установки := TRUE
END_IF;

b_aleks
05.05.2020, 13:14
А есть мысли как привязаться к дню недели, если точка включения днем, а точка выключения ночью?
Значение дня недели я вычисляю правильно и корректно его могу использовать.
Если мне нужно включать установку только в понедельник 8:00, и выключить в 00:10(а это уже вторник). Ведь вторник это уже новый день, и соответственно значения дня изменится в 00:01. И если задать в коде условие работы включения "понедельник", а точка выключения оказывается во вторник - ничего работать не будет.

Я же вам говорю, используйте функцию DAY_OF_WEEK и текущее значение времени. Тогда требуемое вам условие будет выглядеть следующим образом:

IF Текущее_время > Утро (*константа 8 утра*) AND День_недели = 1 OR Текущее_время < Ночь (*константа 00:10*) AND День_недели = 2
THEN Работа_установки := TRUE
ELSE Работа_установки := FALSE
END_IF;

Дальше у вас каша идет какая-то. Непонятно, зачем работать со строками, если можно работать с группой типов Дата-Время, мне кажется так намного проще, плюс меньше шансов словить ошибку.


Здесь небольшая ошибка, вы указали знак (<) меньше, поэтому код будет работать наоборот, только с 00:00 по 8:00

IF Текущее_время < Утро //константа 8 часов утра
THEN Работа_установки := FALSE
ELSE Работа_установки := TRUE
END_IF;
Нет, вы неправы. Установка будет работать как раз с 08:00 по 00:00, внимательно смотрите цикл, если не верите, можете в отладчике проверить.