BACnet

Manual for BACnet/IP device and variable configuration in the configuration area.

Updated 15 min read
On this page (7 sections)
  1. Overview
  2. Device Settings
  3. Device Discovery
  4. Variable Settings
  5. Supported Object Types
  6. Variable Arrays
  7. Notes

BACnet is the standard communication protocol for building automation and control networks. EnvisionSCADA communicates with BACnet devices using BACnet/IP. Each BACnet device entry represents one BACnet/IP device on the network, identified by its IP Address and Device Instance. Variables map individual BACnet objects such as analog inputs, binary outputs, and multi-state values into the project variable space.

Configure the device first, then add variables to it. A variable is referenced at runtime by its full name. A name that starts with the {Device} replacer, for example {Device}.Supply_Temperature, resolves to the device name, so on device AHU1 the variable is AHU1.Supply_Temperature. A name without the replacer is used exactly as written.

The value of each variable is read from the present-value property of the configured BACnet object at the configured scan rate. Devices on the local network can be found automatically with the Discover function, and the object list of a device can be read directly with the Browse Objects function.

Device Settings

Each BACnet device defines a connection to one BACnet/IP device. Configure the connection endpoint, timing, and scanning options.

Create a new device with the Add button in the toolbar. The Add device dialog contains all device settings organized in the sections General, Connection, Scanning, and Diagnostics, with default values already filled in. Enter at least the Name, IP Address, and Device Instance and press Create.

The device row shows Enable, Name, IP Address, Port, Device Instance, ScanRate, Template, and Description directly and these values can be edited in place. Press the Settings icon on a device row to open the Edit device dialog, which contains the same sections and all settings of the device. Press Save to apply the changes.

15 rows
SettingDescriptionExampleUnits / Format
EnableEnables or disables communication with this BACnet device.trueBoolean
SimulationRuns the device in simulation mode. The device does not open its real connection; its variables stay available and become read and write in memory like Local variables, with a Good status and a Channel State of Simulation, so the project can be tested without hardware. Written values are held in memory only and reset when the application restarts.falseBoolean
NameUnique name for this BACnet device. Used as the device name prefix in runtime variable references.AHU1Text
TemplateOptional template device name. Variables created on the template device are also created on this device, and template variable changes are applied to this device.BacnetTemplateText
DescriptionFree text description for documentation purposes.Air handling unit roofText
IP AddressIP address of the BACnet/IP device.192.168.1.40IPv4
PortUDP port of the BACnet/IP device.47808Integer
Device InstanceBACnet device instance number of the remote device.1001Integer (0 to 4194302)
Timeout (ms)Timeout for a single request before it is retried or reported as failed.3000Milliseconds
RetriesNumber of retries for a request that received no answer within the timeout.2Integer (0 to 10)
ScanRatePolling interval. All enabled variables of the device are read once per scan cycle.2000Milliseconds
Objects per RequestNumber of objects read together in one ReadPropertyMultiple request.20Integer (1 to 100)
Write PriorityBACnet write priority used for writes on this device when the variable Write Priority is 0.8Integer (1 to 16)
Use ReadPropertyMultipleReads the present-values of multiple objects grouped in ReadPropertyMultiple requests. When disabled, each object is read with a single ReadProperty request.trueBoolean
VerboseLogging verbosity level. 0 logs connection details and errors, 1 also includes protocol details.0Integer

Device Discovery

Press the Discover button in the toolbar to search the network for BACnet devices. Discovery uses a local network broadcast (Who-Is). Devices on other subnets will not appear and must be added manually.

The Discover dialog lists each answering device with its Device Instance, IP Address, Port, Vendor, Object Name, and Model.

Press Use on a discovered device to open the Add device dialog prefilled with the Name, IP Address, Port, and Device Instance. The Name is the object name of the device with each character other than a letter, digit, or underscore replaced by an underscore, for example AHU-1 Main becomes AHU_1_Main. Complete the remaining settings and press Create.

Variable Settings

Variables are added per device. Each variable maps one BACnet object to the project variable space. The value is read from the present-value property of the object.

Create a new variable with the Add button in the toolbar. The Add variable dialog organizes all variable settings in the tabs General, Scaling, Historian, BACnet Settings, and Gateway, with default values already filled in. Enter at least the Name, ObjectType, and Object Instance on the General tab and press Create. When the variable is created on a template device, it is also created on all instance devices that use the template. On a template device, start the Name with the {Device} replacer, so that each instance device gets its own variable. The Name must resolve to a different variable on each device; this is checked for every instance device before anything is saved, when a variable is created and when it is renamed.

Variables can also be created from the live object list of the device. Press the Browse Objects button in the toolbar to read the object list directly from the device. The Browse Objects dialog lists the objects with ObjectType, Object Instance, and Name. Select the objects to add and press Add Selected to create a variable for each selected object.

The variable name is the object name, with each character other than a letter, digit, or underscore replaced by an underscore. An object without a usable name is named after its object type and instance, for example analog_input_3.

With Start names with {Device}. selected, which is the default, the name starts with the {Device} replacer. An object named Supply Temperature becomes {Device}.Supply_Temperature, which resolves to AHU1.Supply_Temperature on device AHU1, so the same object added on several devices, or on a template device and its instance devices, gives each device its own variable. Clear Start names with {Device}. to use the plain name, for example Supply_Temperature. A plain name must be unique across the whole project, and a template device with instance devices requires the {Device} replacer.

Objects that already exist as a variable on the device, with or without the {Device}. prefix, are skipped. When one of the selected objects cannot be added, the dialog names that object and no variable is created.

The variable row shows Enable, Name, Asset, ObjectType, Object Instance, and Description directly and these values can be edited in place. Press the Settings icon on a variable row to open the Edit variable dialog, which contains the same tabs and all settings of the variable. Press Save to apply the changes. Changes made on a template device are also applied to the matching variable on all instance devices, while each instance keeps its own Modbus Address value. The Gateway tab settings Modbus Address, OPC UA, Writeable, MQTT Publisher, Kafka Device, Kafka Remap Device, and Kafka Remap Variable are also available as table columns, which are shown with Columns as described in the Configuration Tables article.

35 rows
SettingDescriptionExampleUnits / Format
EnableEnables or disables polling of this variable.trueBoolean
NameFull variable name. The {Device}. replacer prefix is optional: {Device} resolves to the device name when the device loads, so the variable follows a device rename automatically, while a literal name is used exactly as written and keeps working across device renames. The resolved name must be unique across the whole project.{Device}.Supply_TemperatureText
AssetAsset tag used to group and filter this variable.Building1/AHU1Text
ObjectTypeBACnet object type of the object to read. See the Supported Object Types section for the available values.analog-inputEnum
Object InstanceInstance number of the BACnet object.1Integer (0 to 4194302)
DescriptionFree text description for documentation purposes.Supply air temperatureText
UserGroupsComma-separated list of user groups that have access to this variable at runtime.Operators,EngineersText
Signature RequiredRequires an electronic signature for each write to this variable from a page object, the Live Manager, the Runtime API or MCP while Part 11 compliance mode is enabled and Write variables marked Signature Required is selected under Signature Required Actions on the Parameters page. The write rights of the user and the value range are checked first, so a refused write does not open the Electronic Signature dialog. A variable created while Part 11 compliance mode is enabled starts with Signature Required selected. Writes by alarm, event and schedule actions, Python scripts and the gateways run without a signature. See the Electronic Signatures article.trueBoolean
Recipe TargetsRecipe type name (target) this variable belongs to. Supports the {Device} placeholder, which resolves to the owning device name so one naming rule can spread a set of variables across several devices.Line1Text
Recipe Parameter NameExplicit name of the parameter this variable represents inside a recipe. Variables that fill the same role across different targets share the same Recipe Parameter Name, which is how values are matched on Apply and Snapshot. A variable takes part in recipes only when both Recipe Targets and Recipe Parameter Name are set.SetpointText
Trend GroupsComma-separated list of trend group names this variable participates in.Text
UnitsEngineering unit label displayed alongside the value.degCText
FormatDisplay format of the value on screens and in the Trend Analyst: the value of a Label or Input (unless the object uses its own Floating Point and Decimals), the value text of a Knob and a Slider, the Trend tooltip, a Data Grid Variable column, the right-click menu, Quick Trend, the current value in the Recipe Manager, variable tokens in alarm and event messages, and the Trend Analyst tooltip, summary and pen Format. An Input shows the plain value while it is being edited. 0 shows no decimals, 0.00 always shows two decimals, 0.0## shows one to three decimals and #,##0.00 adds a thousands separator, with up to 15 decimals. Values are rounded half away from zero for display only; alarms and expressions keep the full value, and so does the historian unless Round to Format is on. ReadVariable in the runtime API and MCP returns the Format beside the full value. Leave empty to show the value as received.0.00Text
ConverterName of a Converter defined in the Converters configuration to apply a custom read/write expression.Text
MinRawMinimum raw value from the device, used for scaling.0Number
MaxRawMaximum raw value from the device, used for scaling.100Number
MinMinimum scaled engineering value corresponding to MinRaw.0Number
MaxMaximum scaled engineering value corresponding to MaxRaw.100Number
HistorianEnables logging of this variable's values to the historian database.trueBoolean
Round to FormatStores the historian samples of this variable rounded to the decimals of its Format, as a plain number: with Format 0.00 the value 34.30487 is stored as 34.3. The deadband compares the rounded values, so with Deadband 0 a sample is written only when the rounded value changes. On a variable without scaling the Raw value is stored empty, since it equals the value. The live value, alarms, expressions and all interfaces keep the full value. Applies to new samples only; samples already stored keep their values. Requires a Format.falseBoolean
DeadbandMinimum change in value required before a new historian record is written.0.5Number
MinimumTime (seconds)Minimum time in seconds between historian records for this variable.0Seconds
SampleGroupName of the Sample Group that controls the historian sampling rate for this variable.Text
History SourceWhere the trends read the history of this variable: Project default (the History Source with Project default enabled on the History Sources page, or the EnvisionSCADA Historian when no source has it), EnvisionSCADA Historian (the samples recorded while Historian is on) or a History Source of the History Sources page (a query on a Database Connection or the fetch() function of a Python Module script). In the table, an empty History Source is Project default and Historian is the EnvisionSCADA Historian. Live values always come from the variable itself. Test reads the last 24 hours with the settings in the dialog. See the History Sources article.Project defaultEnum
History ReferenceWhat the History Source reads for this variable: the reference passed to fetch(), or @Variable of the History Query. When empty, the History Reference of the source is used, by default the full name of the variable; the field shows it in italics. {Name} is replaced by the full name of the variable. Browse lists the references that a Script source offers.CDT158Text
History ParametersShown for a Script source: optional key=value pairs separated by ;, added to the History Parameters of the source. A key set here replaces the same key of the source. The field shows the History Parameters of the source in italics.scale=0.1Text
PropertyBACnet property that is read and written. present-value is the available property.present-valueEnum
Write PriorityBACnet write priority used for writes to this variable. 0 uses the Write Priority of the device.0Integer (0 to 16)
Modbus AddressOptional address on the built-in Modbus TCP and Modbus RTU servers where this variable is exposed. The servers are enabled in the Gateways section of the Parameters page. Each instance device keeps its own value.%MW0See Modbus TCP Addressing
OPC UAExposes this variable as an OPC UA node. When Historize is also ticked, the Historian data of the variable is readable through OPC UA Historical Access.trueBoolean
WriteableAllows external systems to write this variable through the gateways: the OPC UA Server, the Modbus TCP and Modbus RTU servers, the MQTT publisher when Subscribe is enabled on the publisher, and Kafka when Consumer is enabled on the Kafka device. Writes from pages, actions, scripts and the API are independent of this setting.falseBoolean
MQTT PublisherName of the MQTT publisher that publishes this variable, typed or chosen with the ... button. A variable is published by one publisher, and the name must match a publisher on the MQTT Publishers page. Leave empty to keep the variable unpublished. Writes from the broker need Subscribe on the publisher and Writeable on the variable. See the MQTT Publishers article.CloudIoTText
Kafka DeviceName of the Kafka device this variable is linked to, typed or chosen with the ... button. Every value change of a linked variable is produced to the Producer Topic of the Kafka device while the device is enabled. Writes from the Consumer Topic need Consumer on the Kafka device and Writeable on the variable. Leave empty to keep the variable unlinked. See the Kafka Devices article.KafkaBroker1Text
Kafka Remap DeviceDevice name used for this variable in Kafka messages instead of the name of the device that owns the variable. Inbound messages from the Consumer Topic are matched on this name as well. Leave empty to use the device name.RemoteAHU1Text
Kafka Remap VariableVariable name used for this variable in Kafka messages instead of its own name. Inbound messages from the Consumer Topic are matched on this name as well. Leave empty to use the variable name without the device name, for example Supply_Temperature for AHU1.Supply_Temperature on device AHU1.SupplyTempText

Supported Object Types

The ObjectType field selects the BACnet object type of the variable. The value is read from and written to the present-value property of the selected object.

Object TypeDescriptionValue
analog-inputAnalog input object.Numeric
analog-outputAnalog output object.Numeric
analog-valueAnalog value object.Numeric
binary-inputBinary input object.Two-state (0 or 1)
binary-outputBinary output object.Two-state (0 or 1)
binary-valueBinary value object.Two-state (0 or 1)
multi-state-inputMulti-state input object.State number
multi-state-outputMulti-state output object.State number
multi-state-valueMulti-state value object.State number

Variable Arrays

A variable can expand into an array by setting the Array size field to a value between 2 and 512. The variable itself is the first element and its Name must end in the first index, for example Temps[0]. The remaining elements are created automatically as Temps[1], Temps[2] and so on. Each element advances the Object Instance by one, so the elements map onto consecutive objects of the same type.

The element rows are managed by the first element: they follow its settings, appear locked in the variable list, and are edited by editing the first element. Changing the Array size adds or removes elements at the end. Renaming the first element or changing its address renames and re-addresses all elements. Setting Array size back to 0 while elements exist removes the elements.

To turn the elements into ordinary independent variables, use the Ungroup array action on the first element's row in the variable list, or the Configuration API (POST /API/Config/VariableArrays/Ungroup). All rows are kept and only the grouping is removed. This is one-way. The element count badge next to the first element's name folds and unfolds the element rows in the list.

Notes

With Use ReadPropertyMultiple enabled, the present-values of the enabled variables are read grouped in ReadPropertyMultiple requests of up to Objects per Request objects each. Lower the Objects per Request value when a device only supports small ReadPropertyMultiple requests. When a device rejects ReadPropertyMultiple entirely, this is logged and the device falls back to single ReadProperty requests. A request that receives no answer at all does not trigger this fallback.

Writes use the BACnet priority array. A variable Write Priority of 1 to 16 is used for that variable. A variable Write Priority of 0 uses the Write Priority of the device as the default. Priority 6 is reserved by BACnet for the minimum on and off time of an output, and devices normally refuse writes at that priority.

A write is sent only while the device is enabled. A value that does not match the object type (a number for analog objects, a state number for multi-state objects, true, false, or a number for binary objects) is not sent. A value the device refuses, for example a write to an input object that is not out of service, is not applied. In both cases the System Log records the attempt and the variable shows the FormatError status until its next successful read.

Template devices share their variable list with instance devices. Creating, changing, or deleting a variable on the template device applies the same change to the matching variable on all instance devices. Each instance device keeps its own Modbus Address value per variable.

Enable Verbose only during commissioning or diagnostics. Level 0 logs connection details and errors, level 1 also includes protocol details and increases log volume.

A device that does not answer is reported offline: its Channel State changes to Offline and its variables show the ConnectionLost status. A scan cycle in which the first request receives no answer within the Timeout and Retries ends there, so with the default Timeout and Retries a device is reported offline about 6 to 7 seconds after it stops answering. An offline device keeps being polled at the ScanRate and returns to Connected with the first answered request.

All BACnet devices share one BACnet/IP port (UDP 47808) on the server and send their requests one at a time. While a device does not answer, each of its requests holds the port for up to Timeout and Retries, which slows the polling of the other BACnet devices. Keep Timeout and Retries low on networks where devices are switched off.

On a server with several EnvisionSCADA instances, configure BACnet devices in one instance only: the instances would share this port, and the answers of a device reach one instance. See Multiple Instances.

Something missing or wrong in this article? Contact us