The Multistate Value object is the in-memory (non-physical I/O) counterpart to Multistate Input and Multistate Output. It holds an integer state (1..N) that represents an operating mode, a stage, a position in a sequence, or any other enumerated control parameter that lives inside the device.
The semantics of the states are a local matter and may be described with the
optional state_text array. The object is frequently commandable via priority
array so that schedules, operators and control logic can change the mode.
Intrinsic reporting (CHANGE_OF_STATE + optional FAULT_STATE when
intrinsic_reporting: true) are supported exactly as for the input/output variants.
Object Description (ASHRAE 135)
The Multi-state Value object type defines a standardized object whose properties represent the externally visible characteristics of a multi-state value. A "multi-state value" is a control system parameter residing in the memory of the BACnet Device.
Multi-state Value objects that support intrinsic reporting shall apply the CHANGE_OF_STATE event algorithm.
Behaviour and Operation
Multistate Value objects are in-memory multi-state parameters (operating modes, stage selections, enumerated setpoints, etc.). When not commandable, the integer state can be written directly by the application or by BACnet clients.
When a priority array is present, the object is commandable: present_value is
derived from the priority mechanism and direct writes are not permitted.
Use set_priority/3 to command the mode.
The meaning of states is local (number_of_states + optional state_text).
Intrinsic CHANGE_OF_STATE + FAULT_STATE alarming is available when enabled at
creation.
Developer Implementation Notes (geared to device server / application authors)
The generated code handles storage + basic mechanics (validation, implicit_relationships,
readonly annotations as hints to your server, etc.). You must drive "special" live
properties and side effects yourself, analogous to maintaining present_value on
inputs via update_property/3 (never direct mutation). Read notes below + generated
tables for details.
Special / live properties and expected developer behaviour
present_value: The discrete value or mode. Dev must: Your application logic writes the current state (direct if not commandable; via set_priority/PA if commandable). Other logic reads it to act.priority_array,relinquish_default: Dev must: Optional Priority commanding; library derives PV.number_of_states,state_text(size must matchnumber_of_states): Human names for states 1..N. Dev must: Define states; keep text array in sync.feedback_value: Actual state from hardware. Dev must: Update from feedback sensor; used for command failure alarming.alarm_values: List of state numbers that are alarm. Dev must: For intrinsic, your event engine runs CHANGE_OF_STATE algorithm, updates event state/notifications.fault_values: States that indicate fault. Dev must: If PV in fault_values, set reliability appropriately.status_flags,out_of_service,reliability: Dev must:out_of_servicefor test direct writes. Reliability from actuator health.in_alarm/fault/out_of_servicebits ofstatus_flagsare auto-managed by the object (overriddenis local matter).
In-memory multistate "variable". Your code is the producer and consumer.
Intrinsic Reporting
When intrinsic_reporting: true is passed to create/4, the CHANGE_OF_STATE (and
optionally FAULT_STATE) algorithms become active.
Commandability and Priority Arrays
Value objects can have a priority_array (making them commandable). When a priority array
is present, the present value is protected and is only changed through the priority mechanism.
Examples
Creating a minimal Multistate Value:
iex> {:ok, mv} = BACnet.Protocol.ObjectTypes.MultistateValue.create(5, "ModeSel", %{present_value: 1}); mv.present_value
1With intrinsic reporting:
iex> {:ok, mv} = BACnet.Protocol.ObjectTypes.MultistateValue.create(6, "Flag", %{present_value: 1}, intrinsic_reporting: true); mv.object_name
"Flag"See Also
The following part has been automatically generated.
Click to expand
This module defines a BACnet object of the type `multi_state_value`. The following properties are defined: | Property | Revision | Required | Readonly | Protected | Intrinsic | |----------|----------|----------|----------|-----------|-----------| | acked_transitions | | | X | | X | | alarm_values | | | | | X | | description | | | | | | | device_type | | | | | | | event_algorithm_inhibit | | | | | X | | event_algorithm_inhibit_ref | | | | | X | | event_detection_enable | | | | | X | | event_enable | | | | | X | | event_message_texts | | | X | | X | | event_message_texts_config | | | | | X | | event_state | | X | | | | | event_timestamps | | | X | | X | | fault_values | | | | | | | limit_enable | | | | | X | | notification_class | | | | | X | | notify_type | | | | | X | | number_of_states | | X | X | | | | object_instance | | X | X | | | | object_name | | X | X | | | | out_of_service | | X | | | | | present_value | | X | | | | | priority_array | | | X | | | | profile_location | 19 | | | | | | profile_name | | | | | | | reliability | | | | | | | reliability_evaluation_inhibit | | | | | | | relinquish_default | | | | | | | state_text | | | | | | | status_flags | | X | X | | | | tags | 19 | | | | | | time_delay | | | | | X | | time_delay_normal | | | | | X | The following properties have additional semantics: | Property | Has Default | Has Init | Implicit Relationships | Validators | Annotations | |----------|-------------|----------|------------------------|------------|-------------| | alarm_values | X | | | | | | event_algorithm_inhibit_ref | | | event_algorithm_inhibit | | | | fault_values | X | | reliability | | | | number_of_states | X | | | Type | | | present_value | X | | | Fun/Type | `readonly_when: {:out_of_service, false}` | | profile_location | | | | Fun | `revision: 19` | | reliability | | | reliability_evaluation_inhibit | | | | relinquish_default | X | | | Fun/Type | | | state_text | | | | Fun | | | tags | | | | | `revision: 19` | The following table shows the default values and/or init functions: | Property | Default Value | Init Function | |----------|---------------|---------------| | alarm_values | `[]` | | | fault_values | `[]` | | | number_of_states | `1` | | | present_value | `1` | | | relinquish_default | `1` | |Summary
Types
Common object options for creation - all are optional.
Options accepted when creating or configuring a Multistate Value object.
Available property names for this object.
The structure for property errors.
Represents an Multistate Value object. All keys should be treated as read-only,
all updates should go only through update_property/3.
Functions
Adds an optional property to an object. Remote objects can not be mutated using this operation.
Creates a new object struct with the defined properties. Optional properties are not
created when not given, only required, given and dependency properties are created.
Properties with a value of nil are ignored.
Auto generated function to get the names of all properties this object supports.
Auto generated function to get the annotations for the given property name.
Auto generated function to get the list of annotations for each property.
Auto generated function to get the names of properties used for COV reporting.
Auto generated function to get the names of intrinsic properties.
Get the BACnet object identifier.
Auto generated function to get the names of optional properties.
Get the active priority value from the priority array, or nil.
Get the list of properties the object has.
Auto generated function to get a map of property name to type.
Get a property's value from an object.
Auto generated function to get the names of protected properties.
Auto generated function to get the names of readonly properties.
Auto generated function to get the names of required properties.
Checks whether the given object has a priority array.
Checks if the given object has the given property.
Checks if the given object has Intrinsic Reporting enabled.
Checks if the given property is writable.
Removes an optional property from an object. This function is idempotent. Remote objects can not be mutated using this operation.
Sets the given priority in the priority array of an object. This function also updates the present value.
Auto generated function to check whether the object type supports intrinsic reporting.
Updates a property of an object. To update the priority array, use set_priority/3 instead.
Types
@type common_object_opts() :: {:allow_numeric_constants, boolean()} | {:allow_unknown_properties, boolean()} | {:ignore_unknown_properties, boolean()} | {:revision, BACnet.Protocol.Constants.protocol_revision()} | {:skip_property_validation_remote_object, boolean() | :value}
Common object options for creation - all are optional.
allow_numeric_constants- Constants are atoms and thus unknown constants or vendor extensions are integers and thus are rejected. Enabling this option will allow integers (non_neg_integer()) for properties with aConstants.type()spec.allow_unknown_properties- Properties that are unknown to the object implementation are usually rejected. With this option, unknown properties (numeric identifiers usually means we dont know them) are accepted and put into a separate map. This does mean we can not validate or write them. Types of the values can be anything at this point. While you can read unknown properties with atom or integer as property identifier, you can only remove numeric unknown property identifiers from an object. Property identifiers of typeatomare only accepted, if it is a remote object (object implementation is only enforced if it is a local object). Numeric property identifiers are accepted regardless of remote object or not. For remote objects, this means you have to write "raw values" (usuallyEncodingstructs).ignore_unknown_properties- Properties that are unknown to the object implementation are usually rejected. With this option, unknown properties get ignored, as if they were not specified.revision- The BACnet protocol revision to check required properties against. Optional properties are regardless of revision available. SeeBACnet.Protocol.Constants.protocol_revision/0for the available revisions.skip_property_validation_remote_object- Skips property validation for remote objects. Sometimes it is possible that the value is invalid as per BACnet specification (i.e. value 0 for a multistate object), but you still want those to be represented. Valuetrueneither type nor value are validated. Value:valuemeans the type is still validated and only the value validator is not run (if present). The property'svalidator_funwill also be skipped.
@type object_opts() :: {:intrinsic_reporting, boolean()} | common_object_opts()
Options accepted when creating or configuring a Multistate Value object.
In addition to the common options, Multistate Value supports:
intrinsic_reporting- Enables CHANGE_OF_STATE (and FAULT_STATE) intrinsic reporting.
@type property_name() ::
:acked_transitions
| :alarm_values
| :description
| :device_type
| :event_algorithm_inhibit
| :event_algorithm_inhibit_ref
| :event_detection_enable
| :event_enable
| :event_message_texts
| :event_message_texts_config
| :event_state
| :event_timestamps
| :fault_values
| :limit_enable
| :notification_class
| :notify_type
| :number_of_states
| :object_instance
| :object_name
| :out_of_service
| :present_value
| :priority_array
| :profile_location
| :profile_name
| :reliability
| :reliability_evaluation_inhibit
| :relinquish_default
| :state_text
| :status_flags
| :tags
| :time_delay
| :time_delay_normal
Available property names for this object.
@type property_update_error() :: {:error, {error :: atom(), property :: BACnet.Protocol.Constants.property_identifier()}}
The structure for property errors.
@type t() :: %BACnet.Protocol.ObjectTypes.MultistateValue{ _metadata: internal_metadata(), _unknown_properties: %{ optional(atom() | non_neg_integer()) => term() | BACnet.Protocol.ApplicationTags.Encoding.t() | [BACnet.Protocol.ApplicationTags.Encoding.t()] }, acked_transitions: BACnet.Protocol.EventTransitionBits.t() | nil, alarm_values: [non_neg_integer()] | nil, description: String.t() | nil, device_type: String.t() | nil, event_algorithm_inhibit: boolean() | nil, event_algorithm_inhibit_ref: BACnet.Protocol.ObjectPropertyRef.t() | nil, event_detection_enable: boolean() | nil, event_enable: BACnet.Protocol.EventTransitionBits.t() | nil, event_message_texts: BACnet.Protocol.EventMessageTexts.t() | nil, event_message_texts_config: BACnet.Protocol.EventMessageTexts.t() | nil, event_state: BACnet.Protocol.Constants.event_state() | (reserved_or_vendor_extension :: non_neg_integer()), event_timestamps: BACnet.Protocol.EventTimestamps.t() | nil, fault_values: [non_neg_integer()] | nil, limit_enable: BACnet.Protocol.LimitEnable.t() | nil, notification_class: non_neg_integer() | nil, notify_type: BACnet.Protocol.Constants.notify_type() | (reserved_or_vendor_extension :: non_neg_integer()) | nil, number_of_states: pos_integer(), object_instance: non_neg_integer(), object_name: String.t(), out_of_service: boolean(), present_value: pos_integer(), priority_array: BACnet.Protocol.PriorityArray.t(pos_integer()) | nil, profile_location: String.t() | nil, profile_name: String.t() | nil, reliability: BACnet.Protocol.Constants.reliability() | (reserved_or_vendor_extension :: non_neg_integer()) | nil, reliability_evaluation_inhibit: boolean() | nil, relinquish_default: pos_integer() | nil, state_text: BACnet.Protocol.BACnetArray.t(String.t(), pos_integer()) | nil, status_flags: BACnet.Protocol.StatusFlags.t(), tags: BACnet.Protocol.BACnetArray.t(BACnet.Protocol.NameValue.t()) | nil, time_delay: non_neg_integer() | nil, time_delay_normal: non_neg_integer() | nil }
Represents an Multistate Value object. All keys should be treated as read-only,
all updates should go only through update_property/3.
Properties which are for Intrinsic Reporting are nil, if disabled. If Intrinsic Reporting is enabled on the object, then the properties can not be nil.
For commandable objects (objects with a priority array), the present value property is protected.
Functions
@spec add_property(t(), BACnet.Protocol.Constants.property_identifier(), term()) :: {:ok, t()} | property_update_error()
Adds an optional property to an object. Remote objects can not be mutated using this operation.
Please note that properties of services can not be dynamically added and instead
the object must be newly created using create/4.
@spec create( non_neg_integer(), String.t(), %{optional(property_name() | atom() | non_neg_integer()) => term()}, [object_opts() | internal_metadata()] ) :: {:ok, t()} | property_update_error()
Creates a new object struct with the defined properties. Optional properties are not
created when not given, only required, given and dependency properties are created.
Properties with a value of nil are ignored.
Only properties that are required for specific services (i.e. Intrinsic Reporting) are automatically created.
@spec get_all_properties() :: [BACnet.Protocol.Constants.property_identifier()]
Auto generated function to get the names of all properties this object supports.
@spec get_annotation(property_name()) :: [term()]
Auto generated function to get the annotations for the given property name.
@spec get_annotations() :: [{name :: property_name(), values :: [term()]}]
Auto generated function to get the list of annotations for each property.
@spec get_cov_properties() :: [BACnet.Protocol.Constants.property_identifier()]
Auto generated function to get the names of properties used for COV reporting.
@spec get_intrinsic_properties() :: [BACnet.Protocol.Constants.property_identifier()]
Auto generated function to get the names of intrinsic properties.
@spec get_object_identifier(t()) :: BACnet.Protocol.ObjectIdentifier.t()
Get the BACnet object identifier.
@spec get_optional_properties() :: [BACnet.Protocol.Constants.property_identifier()]
Auto generated function to get the names of optional properties.
@spec get_priority_value(t()) :: {priority :: 1..16, value :: pos_integer()} | nil
Get the active priority value from the priority array, or nil.
@spec get_properties(t()) :: [BACnet.Protocol.Constants.property_identifier()]
Get the list of properties the object has.
@spec get_properties_type_map() :: map()
Auto generated function to get a map of property name to type.
@spec get_property( t(), BACnet.Protocol.Constants.property_identifier() | non_neg_integer() ) :: {:ok, term()} | property_update_error()
Get a property's value from an object.
@spec get_protected_properties() :: [BACnet.Protocol.Constants.property_identifier()]
Auto generated function to get the names of protected properties.
Protected is an annotation and the object modules prevent writing to this property directly in code. The protected properties are either written on creation or updated automatically depending on other properties being written to. Some properties are only written once at creation and never updated.
@spec get_readonly_properties() :: [BACnet.Protocol.Constants.property_identifier()]
Auto generated function to get the names of readonly properties.
Readonly is only an annotation that the property should be write protected
on the BACnet side, there is no actual write protection in the object.
This is a hint to the device server. If you need actual write protection, see protected.
@spec get_required_properties() :: [BACnet.Protocol.Constants.property_identifier()]
Auto generated function to get the names of required properties.
Checks whether the given object has a priority array.
@spec has_property?(t(), BACnet.Protocol.Constants.property_identifier()) :: boolean()
Checks if the given object has the given property.
See BACnet.Protocol.ObjectsUtility.has_property?/2 for implementation details.
Checks if the given object has Intrinsic Reporting enabled.
@spec property_writable?(t(), BACnet.Protocol.Constants.property_identifier()) :: boolean()
Checks if the given property is writable.
Check BACnet.Protocol.ObjectsUtility.property_writable?/2 for a basic run-down.
@spec remove_property( t(), BACnet.Protocol.Constants.property_identifier() | non_neg_integer() ) :: {:ok, t()} | property_update_error()
Removes an optional property from an object. This function is idempotent. Remote objects can not be mutated using this operation.
Please note that properties of services can not be dynamically removed and instead
the object must be newly created using create/4. Required properties can not be removed.
@spec set_priority(t(), 1..16, pos_integer() | nil) :: {:ok, t()} | property_update_error()
Sets the given priority in the priority array of an object. This function also updates the present value.
@spec supports_intrinsic() :: boolean()
Auto generated function to check whether the object type supports intrinsic reporting.
@spec update_property(t(), BACnet.Protocol.Constants.property_identifier(), term()) :: {:ok, t()} | property_update_error()
Updates a property of an object. To update the priority array, use set_priority/3 instead.