Calendar and schedule functions
For the implementation of schedule functions the BACnet standard provides the schedule object. It allows the use of recurring weekly programs (Weekly_Schedule) as well as the definition of exceptions (Exception_Schedule). Exceptions can either be entered directly in the schedule object or these are determined on the basis of a Calendar object (which must be located in the same device). A single date, a date range or a combined type of day, week and month can be used to specify an exception.
The weekly schedule is noted using the array aWeek
.
Calendar-based exceptions are noted using the array aCalendar
.
Exceptions contained directly in the schedule are noted using the array aException
.
Help functions are available for specifying the dates, e.g. F_BA_DateVal
.
For dates, according to the BACnet standard, the year starts from 1900. The Month element can contain odd (13) and even (14) months in addition to the regular month information. The day of the month may include odd (33) and even (34) days of the month in addition to the regular day information, as well as the last day (32) of the month.
When specifying specific dates, it is important that the day of the week matches the specified date.
Functions are also available for defining the time/value pairs of the schedule, e.g. F_BACnet_SchedWeekly3xA
. Here, 3x indicates the number (3 entries). The indicator A stands for analog values (REAL), the indicator B for binary values (BOOL) and M for multistate states (integer).
If the schedule is to directly influence one or more properties from BACnet objects, these references can be specified in the aObjectPropertyReferences
element. If this specification is missing, an empty list is created in the property ListofObjectPropertyReferences and the schedule does not access external objects/properties. This can be used if the state of the schedule is to be monitored within the PLC, but no BACnet objects are to be directly influenced.
Variables
// 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;