Kalender und Zeitschaltfunktionen
Für die Umsetzung von Zeitschaltfunktionen stellt der BACnet Standard das Schedule-Objekt bereit. Es erlaubt die Verwendung wiederkehrender Wochenprogramme (Weekly_Schedule) als auch die Festlegung von Ausnahmen (Exception_Schedule). Ausnahmen können entweder direkt im Schedule-Objekt eingetragen werden oder diese werden auf Basis eines Calendar-Objekts (das sich im gleichen Gerät befinden muss) ermittelt. Für die Festlegung einer Ausnahme können ein einzelnes Datum, ein Datumsbereich oder ein kombinierter Typ aus Tag, Woche und Monat verwendet werden.
Der Wochenzeitplan wird über das Array aWeek
notiert.
Kalender-basierte Ausnahmen werden im Array aCalendar
notiert.
Im Zeitplan direkt enthaltene Ausnahmen werden über das Array aException
notiert.
Für die Festlegung der Datumsangaben stehen Hilfsfunktionen zur Verfügung, z. B. F_BA_DateVal
.
Bei Datumsangaben gilt gemäß BACnet-Standard, dass das Jahr ab 1900 beginnt. Das Element Monat kann zusätzlich zu den regulären Monatsangaben auch ungerade (13) und gerade (14) Monate enthalten. Der Tag des Monats kann zusätzlich zu den regulären Tagesangaben auch ungerade (33) und gerade (34) Tage des Monats sowie den letzten Tag (32) des Monats enthalten.
Wichtig ist bei der Angabe spezifischer Datumsangaben, dass der Wochentag zum angegebenen Datum passen muss.
Für die Festlegung der Zeit/Werte-Paare des Zeitschaltplans stehen ebenfalls Funktionen zur Verfügung, z. B. F_BACnet_SchedWeekly3xA
. Dabei bezeichnet die Angabe 3x die Anzahl (3 Einträge). Das Kennzeichen A steht für Analogwerte (REAL), das Kennzeichen B für Binärwerte (BOOL) und M für Multistate-Zustände (Integer).
Soll der Zeitschaltplan direkt ein oder mehrere Properties aus BACnet-Objekten beeinflussen, können diese Referenzen im Element aObjectPropertyReferences
angegeben werden. Fehlt diese Angabe, wird eine leere Liste im Property ListofObjectPropertyReferences erzeugt und der Zeitplan greift nicht auf externe Objekte/Properties ein. Dieses kann verwendet werden, wenn innerhalb der SPS der Zustand des Zeitplans überwacht werden soll, aber keine BACnet-Objekte direkt beeinflusst werden sollen.
Variablen
// Calendar object examples
fbCAL01 : FB_BACnet_Cal := (
sObjectName := 'Calendar 1',
sDescription := 'demonstrates a date-list for each choice',
aDateList := [
(
eType := E_BA_DateValChoice.eDate,
uDate := F_BA_DateVal(2021,E_BA_Month.eJanuary,19)
),
(
eType := E_BA_DateValChoice.eDateRange,
uDate := F_BA_DateRangeVal(nFromYear:=2021,E_BA_Month.eJanuary,19, nToYear:=2021,E_BA_Month.eJanuary,21)
),
(
eType := E_BA_DateValChoice.eWeekNDay,
uDate := F_BA_WeekNDayVal(E_BA_Weekday.eFriday, E_BA_Week.eWeek1, E_BA_Month.eFebruary)
)
]
);
fbCAL02 : FB_BACnet_Cal := (
sObjectName := 'Calendar 2'
);
fbCAL03 : FB_BACnet_Cal := (
sObjectName := 'Calendar 3'
);
// schedule object for analog scheduling
fbAnalogOutput : FB_BACnet_AO;
fbSchedA : FB_BACnet_SchedA := (
sObjectName := 'Schedule Analog',
aObjectPropertyReferences :=
[
(iObject := fbAnalogOutput, ePropertyId := PropPresentValue)
],
aWeek := F_BACnet_SchedWeekly3xA(E_BA_Weekday.eMonday, E_BA_Weekday.eFriday, T#0H, 0.0, T#6H, 5.0, T#20H, 0.0),
aCalendar := [(
iRefCalendar := fbCAL01,
aEntry := F_BACnet_SchedEntry1xA(T#0H, 2.0)
),
(
iRefCalendar := fbCAL02,
aEntry := F_BACnet_SchedEntry1xA(T#10H, 3.4)
),
(
iRefCalendar := fbCAL03,
aEntry := F_BACnet_SchedEntry3xA(T#0H, 5, T#6H, 7, T#20H, 8)
)],
aException := [
(
eType := E_BA_DateValChoice.eDate,
uDate := F_BA_DateVal(2020,E_BA_Month.eApril,10),
aEntry := F_BACnet_SchedEntry1xA(T#0H, 0.0)
),
(
eType := E_BA_DateValChoice.eDateRange,
uDate := F_BA_DateRangeVal(nFromYear:=2020,E_BA_Month.eApril,10, nToYear:=2021,E_BA_Month.eMay,11),
aEntry := F_BACnet_SchedEntry3xA(T#0H, 0.0, T#6H, 5.0, T#20H, 0.0)
),
(
eType := E_BA_DateValChoice.eWeekNDay,
uDate := F_BA_WeekNDayVal(E_BA_Weekday.eFriday, E_BA_Week.eWeek1, E_BA_Month.eFebruary),
aEntry := F_BACnet_SchedEntry3xA(T#0H, F_BA_NullA(), T#6H, 5.0, T#20H, F_BA_NullA())
),
(
eType := E_BA_DateValChoice.eDate,
uDate := F_BA_DateVal(2019,E_BA_Month.eJune,20),
aEntry := [
(
eState := E_BA_SchedEntryState.eValue,
stTime := F_BA_ToSTTime(T#10H),
uValue := F_BA_RVal(1.0)
),
(
eState := E_BA_SchedEntryState.eNull,
stTime := F_BA_ToSTTime(T#11H)
)
]
)]);
// schedule object for binary scheduling
bScheduledValue : BOOL;
fbSchedB : FB_BACnet_SchedB := (
sObjectName := 'Schedule Bool',
aWeek := F_BACnet_SchedWeekly3xB(E_BA_Weekday.eMonday, E_BA_Weekday.eFriday, T#0H, FALSE, T#6H, TRUE, T#20H, FALSE),
aCalendar := [
(
iRefCalendar := fbCAL01,
aEntry := F_BACnet_SchedEntry1xB(T#0H, FALSE)
),
(
iRefCalendar := fbCAL02,
aEntry := F_BACnet_SchedEntry1xB(T#10H, TRUE)
),
(
iRefCalendar := fbCAL03,
aEntry := F_BACnet_SchedEntry3xB(T#0H, F_BA_NullB(), T#6H, TRUE, T#20H, FALSE)
)]);
// schedule object for multistate scheduling
nMultistateValue : UDINT;
bSchedM_AssignCalReference : BOOL;
fbSchedM : FB_BACnet_SchedM :=
(
sObjectName := 'Schedule Multistate',
aWeek := F_BACnet_SchedWeekly3xM(E_BA_Weekday.eMonday, E_BA_Weekday.eFriday, T#0H, 1, T#6H, 2, T#20H, 1),
nScheduleDefault := 3
);
Code
fbCAL01();
fbCAL02();
fbCAL03();
fbAnalogOutput();
fbSchedA();
fbSchedB();
bScheduledValue := fbSchedB.bPresVal;
// example how to assign a calendar reference at runtime
IF( bSchedM_AssignCalReference ) THEN
bSchedM_AssignCalReference := FALSE;
fbSchedM.aCalendar[1].iRefCalendar := fbCAL01;
fbSchedM.aCalendar[1].aEntry := F_BACnet_SchedEntry1xM(T#11H, 2);
fbSchedM.bWriteException := TRUE;
END_IF
fbSchedM();
nMultistateValue := fbSchedM.nPresVal;