Skip to main content

Use of BACnet Client Function Blocks

In addition to BACnet objects, BACnet clients can also be inserted as "devices" below a BACnet server.

Like the objects and the server, each client device also brings with it a function block that is instantiated under the same name as the client device.

Unlike BACnet objects, a BACnet client does not require a complex (static) configuration. As a result, a client function block can be used even without creating a BACnet client as "device". In this case, however, it has to be "signed in" to its BACnet server by means of RegisterToServer() in IEC the code, and be activated in that way. This "activation" happens automatically when a BACnet client is inserted as "device".

The BACnet client function blocks implement the "Common Behaviour Model", and so they provide inputs and outputs for flow control.

  • Inputs xExecute and xAbort

  • Outputs xBusy, xDone, xError, and xAborted

  • Inputs and outputs for the client request parameters and results

Example 2. Example of IEC code for a client action

The following code uses the function block BACnetClientReadProperty from the BACnet library to send a client-read-property request to a specific BACnet client device in the BACnet network. The received response is read out into a local variable:

PROGRAM PLC_PRG
VAR
    initDone : BOOL := FALSE;
    readProp : BACnet.BACnetClientReadProperty;
    readPropCnt : INT := 0;
    readPropErrorCnt : INT := 0;
    readPropCancelCnt : INT := 0;
    readPropVal : REAL;
END_VAR

IF NOT initDone THEN
    readProp.RegisterToServer(BACnet_Server);
    readProp(
        dwTargetDeviceNumber:= 43,
        objType:= BACnet.CmpBACnet.IEC_BACNET_OBJECT_TYPE.OBJ_ANALOG_VALUE,
        objInst:= 1,
        propID:= BACnet.CmpBACnet.IEC_BACNET_PROPERTY_ID.PROP_PRESENT_VALUE,
        nIndex:= -1);
END_IF

IF readProp.xExecute AND readProp.xBusy AND readProp.iState = 3 THEN
    IF readPropCnt MOD 2 = 0 THEN // cancel every second request
        readProp.xAbort := TRUE;
        readPropCancelCnt := readPropCancelCnt + 1;
    END_IF
END_IF
IF NOT readProp.xExecute AND NOT readProp.xAborted AND NOT readProp.xDone THEN
    readProp.xExecute := TRUE;
    readPropCnt := readPropCnt + 1;
END_IF

IF readProp.xExecute THEN
    IF readProp.xDone THEN
        readProp.xExecute := FALSE;
    END_IF
    IF readProp.xError THEN
        readProp.xExecute := FALSE;
        readPropErrorCnt := readPropErrorCnt + 1;
    END_IF
    IF readProp.xAborted THEN
        readProp.xExecute := FALSE;
        readProp.xAbort := FALSE;
    END_IF
END_IF

readProp();

IF readProp.xDone OR readProp.xError THEN
    IF readProp.xError THEN
        // handle error
        ;
    ELSE
        readPropVal := BACnet.GetRealFromContents(readProp.result);
    END_IF
END_IF


As long as a client-request sends a response, the response contents are provided in the form of one or more output variables, as in the above example. However, this may vary depending on the client action. The example also uses the auxiliary function GetRealFromContents() to read the output variable readProp.result of type IEC_BACNET_PROPERTY_CONTENTS.