BACnet:读取和写入日历对象


FAQ BACnet 中的 BACnet 服务器:属性的循环读取 用作此处的服务器。

BACnet 服务器的要求

  • 如果您完全按照上面链接的常见问题解答中的步骤进行操作,那么

    • 将 BACnet 日历类型的 BACnet 对象添加到设备树中的 BACnet 服务器
    • 删除现有的 BACnet 模拟值
  • 调整“PLC_PRG”如下:


声明

VAR
    xAddCalendar        : BOOL;
    // API does not check dayOfweek!!! == >> DAY_OF_WEEK_UNSPECIFIED
    bacDate             : CmpBACnet.IEC_BACNET_DATE := (year := 2020, month := 2, dayOfMonth := 7, dayOfWeek := CmpBACnet.IEC_BACNET_DAY_OF_WEEK.DAY_OF_WEEK_FRIDAY);
    bacDate2            : CmpBACnet.IEC_BACNET_DATE := (year := 2020, month := 2, dayOfMonth := 14, dayOfWeek := CmpBACnet.IEC_BACNET_DAY_OF_WEEK.DAY_OF_WEEK_UNSPECIFIED);
    bacDateStartRange   : CmpBACnet.IEC_BACNET_DATE := (year := 2020, month := 2, dayOfMonth := 17, dayOfWeek := CmpBACnet.IEC_BACNET_DAY_OF_WEEK.DAY_OF_WEEK_UNSPECIFIED);
    bacDateEndRange     : CmpBACnet.IEC_BACNET_DATE := (year := 2020, month := 3, dayOfMonth := 25, dayOfWeek := CmpBACnet.IEC_BACNET_DAY_OF_WEEK.DAY_OF_WEEK_UNSPECIFIED);

    udiCnt              : UDINT;
    xMatchCurDay        : BOOL;
END_VAR

实现

BACnet_Calendar.GetEntryCount(count => udiCnt);
xMatchCurDay := BACnet_Calendar.PresentValue;
IF xAddCalendar THEN
    xAddCalendar := FALSE;
    BACnet_Calendar.AddBACnetDate(bacDat := bacDate);
    BACnet_Calendar.AddBACnetDate(bacDat := bacDate2);
    BACnet_Calendar.AddBACnetDateRange(bacStartDat := bacDateStartRange, bacEndDat := bacDateEndRange);
END_IF

  • 将项目下载到控制器并将 xAddCalendar 变量设置为 TRUE。 如果成功,BACnet 日历的条目数将增加三个。

图1

BACnet 客户端的要求

  • 创建“标准项目”并选择CODESYS Control Win V3 作为设备。
  • 通过网络扫描定义目标系统(参见 BACnet 服务器)。
  • 插入“BACnet Server”对象并将其重命名为“BACnet_Client”

图2

  • 打开 库管理器 并添加以下库 CmpBACnet

图3

  • 调整“PLC_PRG”如下:

声明

VAR CONSTANT
    c_udiMaxEntries     : UDINT := 10;
    c_sDelimeter        : String := '.';
END_VAR
VAR
    fbReadProperty      : BACnet.BACnetClientReadProperty;
    xReadExecute        : BOOL;

    xInitDone           : BOOL := FALSE;
    bacCalendarContents : CmpBACnet.IEC_BACNET_PROPERTY_CONTENTS;
    udiIndex            : UDINT;

    asEntries           : ARRAY [0..c_udiMaxEntries] OF STRING;

    pbyRawBuffer        : POINTER TO BYTE;
    pCalenderEntry      : POINTER TO CmpBACnet.IEC_BACNET_CALENDAR_ENTRY;
    dat                 : CmpBACnet.IEC_BACNET_DATE;
    // Value is used if type is set to "date range"
    dateRange           : CmpBACnet.IEC_BACNET_DATE_RANGE;
    // Value is used if type is set to "week-n-day"
    weekNDay            : CmpBACnet.IEC_BACNET_WEEK_AND_DAY;

    sHelp               : STRING;
END_VAR

实现

IF NOT xInitDone THEN
    fbReadProperty.RegisterToServer(BACnet_Client);
    fbReadProperty(dwTargetDeviceNumber := 718,
                    objType := BACnet.CmpBACnet.IEC_BACNET_OBJECT_TYPE.OBJ_CALENDAR, objInst := 1,
                    propID := BACnet.CmpBACnet.IEC_BACNET_PROPERTY_ID.PROP_DATELIST,
                    udiTimeOut := 5000000);
    xInitDone := TRUE;
ELSE
    fbReadProperty(xExecute := xReadExecute);
    IF fbReadProperty.xDone THEN
        xReadExecute := FALSE;
        bacCalendarContents := fbReadProperty.result;

        IF bacCalendarContents.tag = CmpBACnet.IEC_BACNET_DATA_TYPE.DATA_TYPE_CALENDAR_ENTRY THEN  
            pCalenderEntry := bacCalendarContents.buffer.pBuffer;
            FOR udiIndex := 0 TO bacCalendarContents.nElements -1 DO
                CASE pCalenderEntry[udiIndex].tag OF
                    CmpBACnet.IEC_BACNET_CALENDAR_ENTRY_TYPE.CALENDAR_ENTRY_DATE:
                        sHelp := CONCAT(BYTE_TO_STRING(pCalenderEntry[udiIndex].entry.dat.dayOfMonth), '.');
                        sHelp := CONCAT(sHelp, TO_STRING(pCalenderEntry[udiIndex].entry.dat.month));
                        sHelp := CONCAT(sHelp, '.');
                        sHelp := CONCAT(sHelp, WORD_TO_STRING(pCalenderEntry[udiIndex].entry.dat.year));
                        asEntries[udiIndex] := sHelp;
                        CmpBACnet.IEC_BACNET_CALENDAR_ENTRY_TYPE.CALENDAR_ENTRY_DATE_RANGE:
                        sHelp := CONCAT(BYTE_TO_STRING(pCalenderEntry[udiIndex].entry.dateRange.startDate.dayOfMonth), '.');
                        sHelp := CONCAT(sHelp, TO_STRING(pCalenderEntry[udiIndex].entry.dateRange.startDate.month));
                        sHelp := CONCAT(sHelp, '.');
                        sHelp := CONCAT(sHelp, WORD_TO_STRING(pCalenderEntry[udiIndex].entry.dateRange.startDate.year));
                        sHelp := CONCAT(sHelp, ' ... ');
                        sHelp := CONCAT(sHelp, BYTE_TO_STRING(pCalenderEntry[udiIndex].entry.dateRange.endDate.dayOfMonth));
                        sHelp := CONCAT(sHelp, '.');
                        sHelp := CONCAT(sHelp, TO_STRING(pCalenderEntry[udiIndex].entry.dateRange.endDate.month));
                        sHelp := CONCAT(sHelp, '.');
                        sHelp := CONCAT(sHelp, WORD_TO_STRING(pCalenderEntry[udiIndex].entry.dateRange.endDate.year));
                        asEntries[udiIndex] := sHelp;  
                    CmpBACnet.IEC_BACNET_CALENDAR_ENTRY_TYPE.CALENDAR_ENTRY_WEEK_AND_DAY:
                        // Do Something
                    ELSE
                        // Should never used == >> Implement ErrorHandling
                END_CASE
                IF pCalenderEntry[udiIndex].tag = CmpBACnet.IEC_BACNET_CALENDAR_ENTRY_TYPE.CALENDAR_ENTRY_DATE THEN
                    dat := pCalenderEntry[udiIndex].entry.dat;
                END_IF
                IF pCalenderEntry[udiIndex].tag = CmpBACnet.IEC_BACNET_CALENDAR_ENTRY_TYPE.CALENDAR_ENTRY_DATE_RANGE THEN
                    dateRange := pCalenderEntry[udiIndex].entry.dateRange;
                END_IF
            END_FOR
        END_IF
    END_IF
END_IF

  • 将项目下载到控制器并将 xReadExecute auf den Wert 设置为TRUE。 如果成功,值将从服务器传输到客户端。

图4