Что-то никто не предложил набивать таблицу прямо в КДС, в визуализации.
Для упрощения ввода данных пришлось расписание в таблице с Time Of Day заменить на пользовательский тип данных
Код:
TYPE Schedule :
STRUCT
HourOff: INT;
MinuteOff: INT;
HourOn: INT;
MinuteOn: INT;
END_STRUCT
END_TYPE
Код:
PROGRAM PLC_PRG
VAR RETAIN PERSISTENT
Table:ARRAY [1..366] OF Schedule; (* Расписание: *)
END_VAR
VAR CONSTANT
dpm: ARRAY [1..12] OF INT := 31, 28, 31,30, 31, 30, 31, 31, 30, 31, 30, 31; (*Чисол дней в месяце*)
nulldt: SystemTimeDate; (*нужна для обнуления параметров*)
END_VAR
VAR
CurTimeExInst: CurTimeEx;
CurSystemTimeDate: SystemTimeDate;
CurSysTime64: SysTime64;
year: INT;
second: INT;
day: INT;
hour: INT;
minute: INT;
month: INT;
LEAP_YEAR: BOOL; (*Флаг високосного года*)
Curr_DAY: INT; (*Номер дня в году*)
i: INT;
Now: TOD; (*Текущее время*)
Stop: TOD; (*Время выключения*)
Start: TOD; (*Время включения*)
Light: BOOL; (*Освещение вкл.*)
selX:INT :=1; (*Используется в визуализации (в таблице)*)
selY:INT :=1; (*Используется в визуализации (в таблице)*)
END_VAR
CurSystemTimeDate:=nulldt;
CurTimeExInst(TimeDate := CurSystemTimeDate, SystemTime := CurSysTime64);
year :=CurSystemTimeDate.Year;
month :=CurSystemTimeDate.Month;
day :=CurSystemTimeDate.Day;
hour :=CurSystemTimeDate.Hour;
minute :=CurSystemTimeDate.Minute;
second :=CurSystemTimeDate.Second;
(*------------------------------------------------------------------------*)
LEAP_YEAR := SHL(year,14) = 0; (*Проверить високосный год*)
(*номер дня в году*)
Curr_DAY:=day + BOOL_TO_INT(month > 2 AND LEAP_YEAR);
FOR i:=1 TO 12 DO
IF i < month THEN Curr_DAY:=Curr_DAY + dpm[i] ; END_IF
END_FOR
(*------------------------------------------------------------------------*)
Now := DWORD_TO_TOD( INT_TO_DWORD(SECOND)*1000+ INT_TO_DWORD(MINUTE) * 60000 + INT_TO_DWORD(HOUR) * 3600000);
Stop:= DWORD_TO_TOD(INT_TO_DWORD(Table[Curr_DAY].HourOff) * 3600000 + INT_TO_DWORD(Table[Curr_DAY].MinuteOff) * 60000);
Start:=DWORD_TO_TOD(INT_TO_DWORD(Table[Curr_DAY].HourOn) * 3600000 + INT_TO_DWORD(Table[Curr_DAY].MinuteOn) * 60000);
IF stop < start THEN
Light := start <= Now OR Now < stop;
ELSE
Light := start <= Now AND Now < stop;
END_IF;