A BACnet Object Identifier (application tag 12) is the universal handle by which every object in every BACnet device is named and addressed. It is a 32-bit packed value defined as:
Bit 31 ...................... 22 21 ............................. 0
+-------------------------------+----------------------------------+
| 10-bit Object Type | 22-bit Instance Number |
+-------------------------------+----------------------------------+The 10-bit type field identifies the object class (:analog_input, :device,
:schedule, vendor-proprietary types, …). The 22-bit instance number must be
unique for that type inside the device (0 … 4_194_302). The combination
(type, instance) is the primary key for every object in the protocol.
Object identifiers appear in almost every service, in subscription lists, in
trend-log records, in alarm & event notifications, and as the value of the
mandatory Object_Identifier property on every object.
BACnet Specification References
- Encoding (Clause 20.2.14): Primitive, four contents octets. The 10-bit type occupies the high bits; the 22-bit instance the low bits. The encoding is big-endian within the 32-bit word.
- ASN.1 (Clause 21):
BACnetObjectIdentifier ::= [APPLICATION 12] BIT STRING { ... }(the production also references theBACnetObjectTypeenumeration). - Constraints: Instance numbers 0 and 4_194_302 are reserved in some
contexts; the library accepts the full 0 …
max_instance_and_property_idrange. - Uniqueness: The (type, instance) pair shall be unique within a device (Clause 12 introduction and many object-type clauses).
This module provides the canonical from_number/1 / to_number/1 round-trips
plus the usual encode/parse/valid? helpers used by BACnet.Protocol.ApplicationTags.
Examples
Creating and using an Object Identifier
iex> device = %ObjectIdentifier{type: :device, instance: 1234}
iex> ObjectIdentifier.to_number(device)
33555666
iex> ObjectIdentifier.from_number(33555666)
{:ok, %ObjectIdentifier{type: :device, instance: 1234}}Validation
iex> ObjectIdentifier.valid?(%ObjectIdentifier{type: :device, instance: 4_194_304})
falseEdge cases
Instance numbers are limited to 22 bits:
iex> max = %ObjectIdentifier{type: :device, instance: 0x3FFFFF}
iex> ObjectIdentifier.valid?(max)
true
iex> too_big = %ObjectIdentifier{type: :device, instance: 0x400000}
iex> ObjectIdentifier.valid?(too_big)
falseUnknown object types (as integers) are allowed for forward compatibility but are not very useful:
iex> unknown = %ObjectIdentifier{type: 999, instance: 1}
iex> ObjectIdentifier.valid?(unknown)
trueSee Also
Summary
Functions
Encodes an object identifier into application tags encoding.
Parses the number and retrieves the object identifier from an object identifier number.
Parses an object identifier from application tags encoding.
Converts the struct into an object identifier number.
Validates whether the given object identifier is in form valid.
Types
@type t() :: %BACnet.Protocol.ObjectIdentifier{ instance: non_neg_integer(), type: BACnet.Protocol.Constants.object_type() | non_neg_integer() }
Uniquely identifies a BACnet object within a device.
type- aConstants.object_type()atom (or vendor extension integer)instance- 0 … 4_194_301 (22 bits)
The 32-bit wire representation is produced by to_number/1 and parsed by
from_number/1 (see Clause 20.2.14 for the exact bit packing).
Functions
@spec encode(t(), Keyword.t()) :: {:ok, BACnet.Protocol.ApplicationTags.encoding_list()} | {:error, term()}
Encodes an object identifier into application tags encoding.
@spec from_number(non_neg_integer()) :: {:ok, t()} | {:error, term()}
Parses the number and retrieves the object identifier from an object identifier number.
The object identifier number is a 32bit non-negative integer which consists of a 10bit object type number and 22bit instance number.
@spec parse(BACnet.Protocol.ApplicationTags.encoding_list()) :: {:ok, {t(), rest :: BACnet.Protocol.ApplicationTags.encoding_list()}} | {:error, term()}
Parses an object identifier from application tags encoding.
There's actually nothing special that needs to be done here, it just unwraps
and gets the {:object_identifier, t()} tuple from the head of the tags list.
The conversion is already handled by BACnet.Protocol.ApplicationTags.
@spec to_number(t()) :: non_neg_integer()
Converts the struct into an object identifier number.
The object identifier number is a 32bit non-negative integer which consists of a 10bit object type number and 22bit instance number.
Validates whether the given object identifier is in form valid.
It only validates the struct is valid as per type specification.