"""BACnet enumeration types per ASHRAE 135-2020."""

from __future__ import annotations

import logging
from enum import IntEnum

logger = logging.getLogger(__name__)


_OBJECT_TYPE_VENDOR_CACHE: dict[int, object] = {}


class ObjectType(IntEnum):
    """BACnet object types (Clause 12).

    Vendor-proprietary types (128-1023) are accepted as pseudo-members
    via ``_missing_`` so that devices with non-standard object types do
    not cause a ``ValueError`` during decoding.
    """

    @classmethod
    def _missing_(cls, value: object) -> ObjectType | None:
        if isinstance(value, int) and 0 <= value <= 1023:
            cached = _OBJECT_TYPE_VENDOR_CACHE.get(value)
            if cached is not None:
                return cached  # type: ignore[return-value]
            if len(_OBJECT_TYPE_VENDOR_CACHE) >= 4096:
                _OBJECT_TYPE_VENDOR_CACHE.clear()
            member = int.__new__(cls, value)
            member._name_ = f"VENDOR_{value}"
            member._value_ = value
            _OBJECT_TYPE_VENDOR_CACHE[value] = member
            return member
        return None

    ANALOG_INPUT = 0
    ANALOG_OUTPUT = 1
    ANALOG_VALUE = 2
    BINARY_INPUT = 3
    BINARY_OUTPUT = 4
    BINARY_VALUE = 5
    CALENDAR = 6
    COMMAND = 7
    DEVICE = 8
    EVENT_ENROLLMENT = 9
    FILE = 10
    GROUP = 11
    LOOP = 12
    MULTI_STATE_INPUT = 13
    MULTI_STATE_OUTPUT = 14
    NOTIFICATION_CLASS = 15
    PROGRAM = 16
    SCHEDULE = 17
    AVERAGING = 18
    MULTI_STATE_VALUE = 19
    TREND_LOG = 20
    LIFE_SAFETY_POINT = 21
    LIFE_SAFETY_ZONE = 22
    ACCUMULATOR = 23
    PULSE_CONVERTER = 24
    EVENT_LOG = 25
    GLOBAL_GROUP = 26
    TREND_LOG_MULTIPLE = 27
    LOAD_CONTROL = 28
    STRUCTURED_VIEW = 29
    ACCESS_DOOR = 30
    TIMER = 31
    ACCESS_CREDENTIAL = 32
    ACCESS_POINT = 33
    ACCESS_RIGHTS = 34
    ACCESS_USER = 35
    ACCESS_ZONE = 36
    CREDENTIAL_DATA_INPUT = 37
    NETWORK_SECURITY = 38  # Deprecated in 2020 (Clause 24 deleted)
    BITSTRING_VALUE = 39
    CHARACTERSTRING_VALUE = 40
    DATEPATTERN_VALUE = 41
    DATE_VALUE = 42
    DATETIMEPATTERN_VALUE = 43
    DATETIME_VALUE = 44
    INTEGER_VALUE = 45
    LARGE_ANALOG_VALUE = 46
    OCTETSTRING_VALUE = 47
    POSITIVE_INTEGER_VALUE = 48
    TIMEPATTERN_VALUE = 49
    TIME_VALUE = 50
    NOTIFICATION_FORWARDER = 51
    ALERT_ENROLLMENT = 52
    CHANNEL = 53
    LIGHTING_OUTPUT = 54
    BINARY_LIGHTING_OUTPUT = 55
    NETWORK_PORT = 56
    ELEVATOR_GROUP = 57
    ESCALATOR = 58
    LIFT = 59
    STAGING = 60  # New in 2020
    AUDIT_REPORTER = 61  # New in 2020
    AUDIT_LOG = 62  # New in 2020


_PROPERTY_ID_VENDOR_CACHE: dict[int, object] = {}


class PropertyIdentifier(IntEnum):
    """BACnet property identifiers per ASHRAE 135-2020 Clause 21.

    Gaps (18, 51, 55, 95, 101, etc.) are properties deleted from the standard.

    Vendor-proprietary property IDs (512+) and any other values in the
    22-bit property namespace (0--4194303) are accepted as pseudo-members
    via ``_missing_`` so that devices with non-standard property IDs do
    not cause a ``ValueError`` during decoding.
    """

    @classmethod
    def _missing_(cls, value: object) -> PropertyIdentifier | None:
        if isinstance(value, int) and 0 <= value <= 4194303:
            cached = _PROPERTY_ID_VENDOR_CACHE.get(value)
            if cached is not None:
                return cached  # type: ignore[return-value]
            if len(_PROPERTY_ID_VENDOR_CACHE) >= 4096:
                _PROPERTY_ID_VENDOR_CACHE.clear()
            member = int.__new__(cls, value)
            member._name_ = f"VENDOR_{value}"
            member._value_ = value
            _PROPERTY_ID_VENDOR_CACHE[value] = member
            logger.debug("vendor-proprietary PropertyIdentifier(%s)", value)
            return member
        return None

    # 0-50
    ACKED_TRANSITIONS = 0
    ACK_REQUIRED = 1
    ACTION = 2
    ACTION_TEXT = 3
    ACTIVE_TEXT = 4
    ACTIVE_VT_SESSIONS = 5
    ALARM_VALUE = 6
    ALARM_VALUES = 7
    ALL = 8
    ALL_WRITES_SUCCESSFUL = 9
    APDU_SEGMENT_TIMEOUT = 10
    APDU_TIMEOUT = 11
    APPLICATION_SOFTWARE_VERSION = 12
    ARCHIVE = 13
    BIAS = 14
    CHANGE_OF_STATE_COUNT = 15
    CHANGE_OF_STATE_TIME = 16
    NOTIFICATION_CLASS = 17
    # 18: deleted
    CONTROLLED_VARIABLE_REFERENCE = 19
    CONTROLLED_VARIABLE_UNITS = 20
    CONTROLLED_VARIABLE_VALUE = 21
    COV_INCREMENT = 22
    DATE_LIST = 23
    DAYLIGHT_SAVINGS_STATUS = 24
    DEADBAND = 25
    DERIVATIVE_CONSTANT = 26
    DERIVATIVE_CONSTANT_UNITS = 27
    DESCRIPTION = 28
    DESCRIPTION_OF_HALT = 29
    DEVICE_ADDRESS_BINDING = 30
    DEVICE_TYPE = 31
    EFFECTIVE_PERIOD = 32
    ELAPSED_ACTIVE_TIME = 33
    ERROR_LIMIT = 34
    EVENT_ENABLE = 35
    EVENT_STATE = 36
    EVENT_TYPE = 37
    EXCEPTION_SCHEDULE = 38
    FAULT_VALUES = 39
    FEEDBACK_VALUE = 40
    FILE_ACCESS_METHOD = 41
    FILE_SIZE = 42
    FILE_TYPE = 43
    FIRMWARE_REVISION = 44
    HIGH_LIMIT = 45
    INACTIVE_TEXT = 46
    IN_PROCESS = 47
    INSTANCE_OF = 48
    INTEGRAL_CONSTANT = 49
    INTEGRAL_CONSTANT_UNITS = 50

    # 51-100
    ISSUE_CONFIRMED_NOTIFICATIONS = 51  # removed in rev 4, re-added in rev 20
    LIMIT_ENABLE = 52
    LIST_OF_GROUP_MEMBERS = 53
    LIST_OF_OBJECT_PROPERTY_REFERENCES = 54
    # 55: deleted (formerly list-of-session-keys)
    LOCAL_DATE = 56
    LOCAL_TIME = 57
    LOCATION = 58
    LOW_LIMIT = 59
    MANIPULATED_VARIABLE_REFERENCE = 60
    MAXIMUM_OUTPUT = 61
    MAX_APDU_LENGTH_ACCEPTED = 62
    MAX_INFO_FRAMES = 63
    MAX_MASTER = 64
    MAX_PRES_VALUE = 65
    MINIMUM_OFF_TIME = 66
    MINIMUM_ON_TIME = 67
    MINIMUM_OUTPUT = 68
    MIN_PRES_VALUE = 69
    MODEL_NAME = 70
    MODIFICATION_DATE = 71
    NOTIFY_TYPE = 72
    NUMBER_OF_APDU_RETRIES = 73
    NUMBER_OF_STATES = 74
    OBJECT_IDENTIFIER = 75
    OBJECT_LIST = 76
    OBJECT_NAME = 77
    OBJECT_PROPERTY_REFERENCE = 78
    OBJECT_TYPE = 79
    OPTIONAL = 80
    OUT_OF_SERVICE = 81
    OUTPUT_UNITS = 82
    EVENT_PARAMETERS = 83
    POLARITY = 84
    PRESENT_VALUE = 85
    PRIORITY = 86
    PRIORITY_ARRAY = 87
    PRIORITY_FOR_WRITING = 88
    PROCESS_IDENTIFIER = 89
    PROGRAM_CHANGE = 90
    PROGRAM_LOCATION = 91
    PROGRAM_STATE = 92
    PROPORTIONAL_CONSTANT = 93
    PROPORTIONAL_CONSTANT_UNITS = 94
    # 95: deleted (formerly protocol-conformance-class)
    PROTOCOL_OBJECT_TYPES_SUPPORTED = 96
    PROTOCOL_SERVICES_SUPPORTED = 97
    PROTOCOL_VERSION = 98
    READ_ONLY = 99
    REASON_FOR_HALT = 100

    # 101-200
    # 101: deleted (formerly recipient)
    RECIPIENT_LIST = 102
    RELIABILITY = 103
    RELINQUISH_DEFAULT = 104
    REQUIRED = 105
    RESOLUTION = 106
    SEGMENTATION_SUPPORTED = 107
    SETPOINT = 108
    SETPOINT_REFERENCE = 109
    STATE_TEXT = 110
    STATUS_FLAGS = 111
    SYSTEM_STATUS = 112
    TIME_DELAY = 113
    TIME_OF_ACTIVE_TIME_RESET = 114
    TIME_OF_STATE_COUNT_RESET = 115
    TIME_SYNCHRONIZATION_RECIPIENTS = 116
    UNITS = 117
    UPDATE_INTERVAL = 118
    UTC_OFFSET = 119
    VENDOR_IDENTIFIER = 120
    VENDOR_NAME = 121
    VT_CLASSES_SUPPORTED = 122
    WEEKLY_SCHEDULE = 123
    ATTEMPTED_SAMPLES = 124
    AVERAGE_VALUE = 125
    BUFFER_SIZE = 126
    CLIENT_COV_INCREMENT = 127
    COV_RESUBSCRIPTION_INTERVAL = 128
    # 129: deleted (formerly current-notify-time)
    EVENT_TIME_STAMPS = 130
    LOG_BUFFER = 131
    LOG_DEVICE_OBJECT_PROPERTY = 132
    LOG_ENABLE = 133  # renamed to "enable" in rev 5
    LOG_INTERVAL = 134
    MAXIMUM_VALUE = 135
    MINIMUM_VALUE = 136
    NOTIFICATION_THRESHOLD = 137
    # 138: deleted (formerly previous-notify-time)
    PROTOCOL_REVISION = 139
    RECORDS_SINCE_NOTIFICATION = 140
    RECORD_COUNT = 141
    START_TIME = 142
    STOP_TIME = 143
    STOP_WHEN_FULL = 144
    TOTAL_RECORD_COUNT = 145
    VALID_SAMPLES = 146
    WINDOW_INTERVAL = 147
    WINDOW_SAMPLES = 148
    MAXIMUM_VALUE_TIMESTAMP = 149
    MINIMUM_VALUE_TIMESTAMP = 150
    VARIANCE_VALUE = 151
    ACTIVE_COV_SUBSCRIPTIONS = 152
    BACKUP_FAILURE_TIMEOUT = 153
    CONFIGURATION_FILES = 154
    DATABASE_REVISION = 155
    DIRECT_READING = 156
    LAST_RESTORE_TIME = 157
    MAINTENANCE_REQUIRED = 158
    MEMBER_OF = 159
    MODE = 160
    OPERATION_EXPECTED = 161
    SETTING = 162
    SILENCED = 163
    TRACKING_VALUE = 164
    ZONE_MEMBERS = 165
    LIFE_SAFETY_ALARM_VALUES = 166
    MAX_SEGMENTS_ACCEPTED = 167
    PROFILE_NAME = 168
    AUTO_SLAVE_DISCOVERY = 169
    MANUAL_SLAVE_ADDRESS_BINDING = 170
    SLAVE_ADDRESS_BINDING = 171
    SLAVE_PROXY_ENABLE = 172
    LAST_NOTIFY_RECORD = 173
    SCHEDULE_DEFAULT = 174
    ACCEPTED_MODES = 175
    ADJUST_VALUE = 176
    COUNT = 177
    COUNT_BEFORE_CHANGE = 178
    COUNT_CHANGE_TIME = 179
    COV_PERIOD = 180
    INPUT_REFERENCE = 181
    LIMIT_MONITORING_INTERVAL = 182
    LOGGING_OBJECT = 183
    LOGGING_RECORD = 184
    PRESCALE = 185
    PULSE_RATE = 186
    SCALE = 187
    SCALE_FACTOR = 188
    UPDATE_TIME = 189
    VALUE_BEFORE_CHANGE = 190
    VALUE_SET = 191
    VALUE_CHANGE_TIME = 192
    ALIGN_INTERVALS = 193
    # 194: unassigned
    INTERVAL_OFFSET = 195
    LAST_RESTART_REASON = 196
    LOGGING_TYPE = 197
    # 198-201: unassigned

    # 202-235
    RESTART_NOTIFICATION_RECIPIENTS = 202
    TIME_OF_DEVICE_RESTART = 203
    TIME_SYNCHRONIZATION_INTERVAL = 204
    TRIGGER = 205
    UTC_TIME_SYNCHRONIZATION_RECIPIENTS = 206
    NODE_SUBTYPE = 207
    NODE_TYPE = 208
    STRUCTURED_OBJECT_LIST = 209
    SUBORDINATE_ANNOTATIONS = 210
    SUBORDINATE_LIST = 211
    ACTUAL_SHED_LEVEL = 212
    DUTY_WINDOW = 213
    EXPECTED_SHED_LEVEL = 214
    FULL_DUTY_BASELINE = 215
    # 216-217: unassigned
    REQUESTED_SHED_LEVEL = 218
    SHED_DURATION = 219
    SHED_LEVEL_DESCRIPTIONS = 220
    SHED_LEVELS = 221
    STATE_DESCRIPTION = 222
    # 223-225: unassigned
    DOOR_ALARM_STATE = 226
    DOOR_EXTENDED_PULSE_TIME = 227
    DOOR_MEMBERS = 228
    DOOR_OPEN_TOO_LONG_TIME = 229
    DOOR_PULSE_TIME = 230
    DOOR_STATUS = 231
    DOOR_UNLOCK_DELAY_TIME = 232
    LOCK_STATUS = 233
    MASKED_ALARM_VALUES = 234
    SECURED_STATUS = 235

    # 244-321 (access control)
    ABSENTEE_LIMIT = 244
    ACCESS_ALARM_EVENTS = 245
    ACCESS_DOORS = 246
    ACCESS_EVENT = 247
    ACCESS_EVENT_AUTHENTICATION_FACTOR = 248
    ACCESS_EVENT_CREDENTIAL = 249
    ACCESS_EVENT_TIME = 250
    ACCESS_TRANSACTION_EVENTS = 251
    ACCOMPANIMENT = 252
    ACCOMPANIMENT_TIME = 253
    ACTIVATION_TIME = 254
    ACTIVE_AUTHENTICATION_POLICY = 255
    ASSIGNED_ACCESS_RIGHTS = 256
    AUTHENTICATION_FACTORS = 257
    AUTHENTICATION_POLICY_LIST = 258
    AUTHENTICATION_POLICY_NAMES = 259
    AUTHENTICATION_STATUS = 260
    AUTHORIZATION_MODE = 261
    BELONGS_TO = 262
    CREDENTIAL_DISABLE = 263
    CREDENTIAL_STATUS = 264
    CREDENTIALS = 265
    CREDENTIALS_IN_ZONE = 266
    DAYS_REMAINING = 267
    ENTRY_POINTS = 268
    EXIT_POINTS = 269
    EXPIRATION_TIME = 270
    EXTENDED_TIME_ENABLE = 271
    FAILED_ATTEMPT_EVENTS = 272
    FAILED_ATTEMPTS = 273
    FAILED_ATTEMPTS_TIME = 274
    LAST_ACCESS_EVENT = 275
    LAST_ACCESS_POINT = 276
    LAST_CREDENTIAL_ADDED = 277
    LAST_CREDENTIAL_ADDED_TIME = 278
    LAST_CREDENTIAL_REMOVED = 279
    LAST_CREDENTIAL_REMOVED_TIME = 280
    LAST_USE_TIME = 281
    LOCKOUT = 282
    LOCKOUT_RELINQUISH_TIME = 283
    # 284: deleted (formerly master-exemption)
    MAX_FAILED_ATTEMPTS = 285
    MEMBERS = 286
    MUSTER_POINT = 287
    NEGATIVE_ACCESS_RULES = 288
    NUMBER_OF_AUTHENTICATION_POLICIES = 289
    OCCUPANCY_COUNT = 290
    OCCUPANCY_COUNT_ADJUST = 291
    OCCUPANCY_COUNT_ENABLE = 292
    # 293: deleted (formerly occupancy-exemption)
    OCCUPANCY_LOWER_LIMIT = 294
    OCCUPANCY_LOWER_LIMIT_ENFORCED = 295
    OCCUPANCY_STATE = 296
    OCCUPANCY_UPPER_LIMIT = 297
    OCCUPANCY_UPPER_LIMIT_ENFORCED = 298
    # 299: deleted (formerly passback-exemption)
    PASSBACK_MODE = 300
    PASSBACK_TIMEOUT = 301
    POSITIVE_ACCESS_RULES = 302
    REASON_FOR_DISABLE = 303
    SUPPORTED_FORMATS = 304
    SUPPORTED_FORMAT_CLASSES = 305
    THREAT_AUTHORITY = 306
    THREAT_LEVEL = 307
    TRACE_FLAG = 308
    TRANSACTION_NOTIFICATION_CLASS = 309
    USER_EXTERNAL_IDENTIFIER = 310
    USER_INFORMATION_REFERENCE = 311
    # 312-316: unassigned
    USER_NAME = 317
    USER_TYPE = 318
    USES_REMAINING = 319
    ZONE_FROM = 320
    ZONE_TO = 321
    ACCESS_EVENT_TAG = 322
    GLOBAL_IDENTIFIER = 323

    # 326-398
    VERIFICATION_TIME = 326
    # 327-337: removed (security properties, Clause 24 deleted in 2020)
    BASE_DEVICE_SECURITY_POLICY = 327  # Deprecated: removed with Clause 24 in 135-2020.
    DISTRIBUTION_KEY_REVISION = 328  # Deprecated: removed with Clause 24 in 135-2020.
    DO_NOT_HIDE = 329  # Deprecated: removed with Clause 24 in 135-2020.
    KEY_SETS = 330  # Deprecated: removed with Clause 24 in 135-2020.
    LAST_KEY_SERVER = 331  # Deprecated: removed with Clause 24 in 135-2020.
    NETWORK_ACCESS_SECURITY_POLICIES = 332  # Deprecated: removed with Clause 24 in 135-2020.
    PACKET_REORDER_TIME = 333  # Deprecated: removed with Clause 24 in 135-2020.
    SECURITY_PDU_TIMEOUT = 334  # Deprecated: removed with Clause 24 in 135-2020.
    SECURITY_TIME_WINDOW = 335  # Deprecated: removed with Clause 24 in 135-2020.
    SUPPORTED_SECURITY_ALGORITHMS = 336  # Deprecated: removed with Clause 24 in 135-2020.
    UPDATE_KEY_SET_TIMEOUT = 337  # Deprecated: removed with Clause 24 in 135-2020.
    BACKUP_AND_RESTORE_STATE = 338
    BACKUP_PREPARATION_TIME = 339
    RESTORE_COMPLETION_TIME = 340
    RESTORE_PREPARATION_TIME = 341
    BIT_MASK = 342
    BIT_TEXT = 343
    IS_UTC = 344
    GROUP_MEMBERS = 345
    GROUP_MEMBER_NAMES = 346
    MEMBER_STATUS_FLAGS = 347
    REQUESTED_UPDATE_INTERVAL = 348
    COVU_PERIOD = 349
    COVU_RECIPIENTS = 350
    EVENT_MESSAGE_TEXTS = 351
    EVENT_MESSAGE_TEXTS_CONFIG = 352
    EVENT_DETECTION_ENABLE = 353
    EVENT_ALGORITHM_INHIBIT = 354
    EVENT_ALGORITHM_INHIBIT_REF = 355
    TIME_DELAY_NORMAL = 356
    RELIABILITY_EVALUATION_INHIBIT = 357
    FAULT_PARAMETERS = 358
    FAULT_TYPE = 359
    LOCAL_FORWARDING_ONLY = 360
    PROCESS_IDENTIFIER_FILTER = 361
    SUBSCRIBED_RECIPIENTS = 362
    PORT_FILTER = 363
    AUTHORIZATION_EXEMPTIONS = 364
    ALLOW_GROUP_DELAY_INHIBIT = 365
    CHANNEL_NUMBER = 366
    CONTROL_GROUPS = 367
    EXECUTION_DELAY = 368
    LAST_PRIORITY = 369
    WRITE_STATUS = 370
    PROPERTY_LIST = 371
    SERIAL_NUMBER = 372
    BLINK_WARN_ENABLE = 373
    DEFAULT_FADE_TIME = 374
    DEFAULT_RAMP_RATE = 375
    DEFAULT_STEP_INCREMENT = 376
    EGRESS_TIME = 377
    IN_PROGRESS = 378
    INSTANTANEOUS_POWER = 379
    LIGHTING_COMMAND = 380
    LIGHTING_COMMAND_DEFAULT_PRIORITY = 381
    MAX_ACTUAL_VALUE = 382
    MIN_ACTUAL_VALUE = 383
    POWER = 384
    TRANSITION = 385
    EGRESS_ACTIVE = 386
    INTERFACE_VALUE = 387
    FAULT_HIGH_LIMIT = 388
    FAULT_LOW_LIMIT = 389
    LOW_DIFF_LIMIT = 390
    STRIKE_COUNT = 391
    TIME_OF_STRIKE_COUNT_RESET = 392
    DEFAULT_TIMEOUT = 393
    INITIAL_TIMEOUT = 394
    LAST_STATE_CHANGE = 395
    STATE_CHANGE_VALUES = 396
    TIMER_RUNNING = 397
    TIMER_STATE = 398

    # 399-429 (NetworkPort properties, Clause 12.56)
    APDU_LENGTH = 399
    IP_ADDRESS = 400
    IP_DEFAULT_GATEWAY = 401
    IP_DHCP_ENABLE = 402
    IP_DHCP_LEASE_TIME = 403
    IP_DHCP_LEASE_TIME_REMAINING = 404
    IP_DHCP_SERVER = 405
    IP_DNS_SERVER = 406
    BACNET_IP_GLOBAL_ADDRESS = 407
    BACNET_IP_MODE = 408
    BACNET_IP_MULTICAST_ADDRESS = 409
    BACNET_IP_NAT_TRAVERSAL = 410
    IP_SUBNET_MASK = 411
    BACNET_IP_UDP_PORT = 412
    BBMD_ACCEPT_FD_REGISTRATIONS = 413
    BBMD_BROADCAST_DISTRIBUTION_TABLE = 414
    BBMD_FOREIGN_DEVICE_TABLE = 415
    CHANGES_PENDING = 416
    COMMAND = 417
    FD_BBMD_ADDRESS = 418
    FD_SUBSCRIPTION_LIFETIME = 419
    LINK_SPEED = 420
    LINK_SPEEDS = 421
    LINK_SPEED_AUTONEGOTIATE = 422
    MAC_ADDRESS = 423
    NETWORK_INTERFACE_NAME = 424
    NETWORK_NUMBER = 425
    NETWORK_NUMBER_QUALITY = 426
    NETWORK_TYPE = 427
    ROUTING_TABLE = 428
    VIRTUAL_MAC_ADDRESS_TABLE = 429

    # 430-446 (commandable + IPv6)
    COMMAND_TIME_ARRAY = 430
    CURRENT_COMMAND_PRIORITY = 431
    LAST_COMMAND_TIME = 432
    VALUE_SOURCE = 433
    VALUE_SOURCE_ARRAY = 434
    BACNET_IPV6_MODE = 435
    IPV6_ADDRESS = 436
    IPV6_PREFIX_LENGTH = 437
    BACNET_IPV6_UDP_PORT = 438
    IPV6_DEFAULT_GATEWAY = 439
    BACNET_IPV6_MULTICAST_ADDRESS = 440
    IPV6_DNS_SERVER = 441
    IPV6_AUTO_ADDRESSING_ENABLE = 442
    IPV6_DHCP_LEASE_TIME = 443
    IPV6_DHCP_LEASE_TIME_REMAINING = 444
    IPV6_DHCP_SERVER = 445
    IPV6_ZONE_INDEX = 446

    # 447-480 (lift / escalator, Clause 12.58-12.60)
    ASSIGNED_LANDING_CALLS = 447
    CAR_ASSIGNED_DIRECTION = 448
    CAR_DOOR_COMMAND = 449
    CAR_DOOR_STATUS = 450
    CAR_DOOR_TEXT = 451
    CAR_DOOR_ZONE = 452
    CAR_DRIVE_STATUS = 453
    CAR_LOAD = 454
    CAR_LOAD_UNITS = 455
    CAR_MODE = 456
    CAR_MOVING_DIRECTION = 457
    CAR_POSITION = 458
    ELEVATOR_GROUP = 459
    ENERGY_METER = 460
    ENERGY_METER_REF = 461
    ESCALATOR_MODE = 462
    FAULT_SIGNALS = 463
    FLOOR_TEXT = 464
    GROUP_ID = 465
    # 466: unassigned
    GROUP_MODE = 467
    HIGHER_DECK = 468
    INSTALLATION_ID = 469
    LANDING_CALLS = 470
    LANDING_CALL_CONTROL = 471
    LANDING_DOOR_STATUS = 472
    LOWER_DECK = 473
    MACHINE_ROOM_ID = 474
    MAKING_CAR_CALL = 475
    NEXT_STOPPING_FLOOR = 476
    OPERATION_DIRECTION = 477
    PASSENGER_ALARM = 478
    POWER_MODE = 479
    REGISTERED_CAR_CALL = 480

    # 481-507 (misc + structured view + staging + audit)
    ACTIVE_COV_MULTIPLE_SUBSCRIPTIONS = 481
    PROTOCOL_LEVEL = 482
    REFERENCE_PORT = 483
    DEPLOYED_PROFILE_LOCATION = 484
    PROFILE_LOCATION = 485
    TAGS = 486
    SUBORDINATE_NODE_TYPES = 487
    SUBORDINATE_TAGS = 488
    SUBORDINATE_RELATIONSHIPS = 489
    DEFAULT_SUBORDINATE_RELATIONSHIP = 490
    REPRESENTS = 491
    DEFAULT_PRESENT_VALUE = 492
    PRESENT_STAGE = 493
    STAGES = 494
    STAGE_NAMES = 495
    TARGET_REFERENCES = 496
    AUDIT_SOURCE_REPORTER = 497
    AUDIT_LEVEL = 498
    AUDIT_NOTIFICATION_RECIPIENT = 499
    AUDIT_PRIORITY_FILTER = 500
    AUDITABLE_OPERATIONS = 501
    DELETE_ON_FORWARD = 502
    MAXIMUM_SEND_DELAY = 503
    MONITORED_OBJECTS = 504
    SEND_NOW = 505
    FLOOR_NUMBER = 506
    DEVICE_UUID = 507


class ErrorClass(IntEnum):
    """BACnet error classes (Clause 18.1.1)."""

    DEVICE = 0
    OBJECT = 1
    PROPERTY = 2
    RESOURCES = 3
    SECURITY = 4
    SERVICES = 5
    VT = 6
    COMMUNICATION = 7


class ErrorCode(IntEnum):
    """BACnet error codes (Clause 18, Clause 21 numerical order)."""

    OTHER = 0
    AUTHENTICATION_FAILED = 1  # removed in rev 11, kept for compat
    CONFIGURATION_IN_PROGRESS = 2
    DEVICE_BUSY = 3
    DYNAMIC_CREATION_NOT_SUPPORTED = 4
    FILE_ACCESS_DENIED = 5
    INCOMPATIBLE_SECURITY_LEVELS = 6  # removed in rev 11, kept for compat
    INCONSISTENT_PARAMETERS = 7
    INCONSISTENT_SELECTION_CRITERION = 8
    INVALID_DATA_TYPE = 9
    INVALID_FILE_ACCESS_METHOD = 10
    INVALID_FILE_START_POSITION = 11
    INVALID_OPERATOR_NAME = 12  # removed in rev 11, kept for compat
    INVALID_PARAMETER_DATA_TYPE = 13
    INVALID_TIME_STAMP = 14
    KEY_GENERATION_ERROR = 15  # removed in rev 11, kept for compat
    MISSING_REQUIRED_PARAMETER = 16
    NO_OBJECTS_OF_SPECIFIED_TYPE = 17
    NO_SPACE_FOR_OBJECT = 18
    NO_SPACE_TO_ADD_LIST_ELEMENT = 19
    NO_SPACE_TO_WRITE_PROPERTY = 20
    NO_VT_SESSIONS_AVAILABLE = 21
    PROPERTY_IS_NOT_A_LIST = 22
    OBJECT_DELETION_NOT_PERMITTED = 23
    OBJECT_IDENTIFIER_ALREADY_EXISTS = 24
    OPERATIONAL_PROBLEM = 25
    PASSWORD_FAILURE = 26
    READ_ACCESS_DENIED = 27
    SECURITY_NOT_SUPPORTED = 28  # removed in rev 11, kept for compat
    SERVICE_REQUEST_DENIED = 29
    TIMEOUT = 30
    UNKNOWN_OBJECT = 31
    UNKNOWN_PROPERTY = 32
    # 33 removed
    UNKNOWN_VT_CLASS = 34
    UNKNOWN_VT_SESSION = 35
    UNSUPPORTED_OBJECT_TYPE = 36
    VALUE_OUT_OF_RANGE = 37
    VT_SESSION_ALREADY_CLOSED = 38
    VT_SESSION_TERMINATION_FAILURE = 39
    WRITE_ACCESS_DENIED = 40
    CHARACTER_SET_NOT_SUPPORTED = 41
    INVALID_ARRAY_INDEX = 42
    COV_SUBSCRIPTION_FAILED = 43
    NOT_COV_PROPERTY = 44
    OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED = 45
    INVALID_CONFIGURATION_DATA = 46
    DATATYPE_NOT_SUPPORTED = 47
    DUPLICATE_NAME = 48
    DUPLICATE_OBJECT_ID = 49
    PROPERTY_IS_NOT_AN_ARRAY = 50
    ABORT_BUFFER_OVERFLOW = 51
    ABORT_INVALID_APDU_IN_THIS_STATE = 52
    ABORT_PREEMPTED_BY_HIGHER_PRIORITY_TASK = 53
    ABORT_SEGMENTATION_NOT_SUPPORTED = 54
    ABORT_PROPRIETARY = 55
    ABORT_OTHER = 56
    INVALID_TAG = 57
    NETWORK_DOWN = 58
    REJECT_BUFFER_OVERFLOW = 59
    REJECT_INCONSISTENT_PARAMETERS = 60
    REJECT_INVALID_PARAMETER_DATA_TYPE = 61
    REJECT_INVALID_TAG = 62
    REJECT_MISSING_REQUIRED_PARAMETER = 63
    REJECT_PARAMETER_OUT_OF_RANGE = 64
    REJECT_TOO_MANY_ARGUMENTS = 65
    REJECT_UNDEFINED_ENUMERATION = 66
    REJECT_UNRECOGNIZED_SERVICE = 67
    REJECT_PROPRIETARY = 68
    REJECT_OTHER = 69
    UNKNOWN_DEVICE = 70
    UNKNOWN_ROUTE = 71
    VALUE_NOT_INITIALIZED = 72
    INVALID_EVENT_STATE = 73
    NO_ALARM_CONFIGURED = 74
    LOG_BUFFER_FULL = 75
    LOGGED_VALUE_PURGED = 76
    NO_PROPERTY_SPECIFIED = 77
    NOT_CONFIGURED_FOR_TRIGGERED_LOGGING = 78
    UNKNOWN_SUBSCRIPTION = 79
    PARAMETER_OUT_OF_RANGE = 80
    LIST_ELEMENT_NOT_FOUND = 81
    BUSY = 82
    COMMUNICATION_DISABLED = 83
    SUCCESS = 84
    ACCESS_DENIED = 85
    BAD_DESTINATION_ADDRESS = 86
    BAD_DESTINATION_DEVICE_ID = 87
    BAD_SIGNATURE = 88
    BAD_SOURCE_ADDRESS = 89
    # Values 90-109: removed in revision 22 (Clause 24 deleted in 135-2020).
    BAD_TIMESTAMP = 90
    CANNOT_USE_KEY = 91
    CANNOT_VERIFY_MESSAGE_ID = 92
    CORRECT_KEY_REVISION = 93
    DESTINATION_DEVICE_ID_REQUIRED = 94
    DUPLICATE_MESSAGE = 95
    ENCRYPTION_NOT_CONFIGURED = 96
    ENCRYPTION_REQUIRED = 97
    INCORRECT_KEY = 98
    INVALID_KEY_DATA = 99
    KEY_UPDATE_IN_PROGRESS = 100
    MALFORMED_MESSAGE = 101
    NOT_KEY_SERVER = 102
    SECURITY_NOT_CONFIGURED = 103
    SOURCE_SECURITY_REQUIRED = 104
    TOO_MANY_KEYS = 105
    UNKNOWN_AUTHENTICATION_TYPE = 106
    UNKNOWN_KEY = 107
    UNKNOWN_KEY_REVISION = 108
    UNKNOWN_SOURCE_MESSAGE = 109
    NOT_ROUTER_TO_DNET = 110
    ROUTER_BUSY = 111
    UNKNOWN_NETWORK_MESSAGE = 112
    MESSAGE_TOO_LONG = 113
    SECURITY_ERROR = 114
    ADDRESSING_ERROR = 115
    WRITE_BDT_FAILED = 116
    READ_BDT_FAILED = 117
    REGISTER_FOREIGN_DEVICE_FAILED = 118
    READ_FDT_FAILED = 119
    DELETE_FDT_ENTRY_FAILED = 120
    DISTRIBUTE_BROADCAST_FAILED = 121
    UNKNOWN_FILE_SIZE = 122
    ABORT_APDU_TOO_LONG = 123
    ABORT_APPLICATION_EXCEEDED_REPLY_TIME = 124
    ABORT_OUT_OF_RESOURCES = 125
    ABORT_TSM_TIMEOUT = 126
    ABORT_WINDOW_SIZE_OUT_OF_RANGE = 127
    FILE_FULL = 128
    INCONSISTENT_CONFIGURATION = 129
    INCONSISTENT_OBJECT_TYPE = 130
    INTERNAL_ERROR = 131
    NOT_CONFIGURED = 132
    OUT_OF_MEMORY = 133
    VALUE_TOO_LONG = 134
    ABORT_INSUFFICIENT_SECURITY = 135
    ABORT_SECURITY_ERROR = 136
    DUPLICATE_ENTRY = 137
    INVALID_VALUE_IN_THIS_STATE = 138


class Segmentation(IntEnum):
    """BACnet segmentation support options (Clause 20.1.2.4)."""

    BOTH = 0
    TRANSMIT = 1
    RECEIVE = 2
    NONE = 3


class AbortReason(IntEnum):
    """BACnet abort reasons (Clause 20.1.9)."""

    OTHER = 0
    BUFFER_OVERFLOW = 1
    INVALID_APDU_IN_THIS_STATE = 2
    PREEMPTED_BY_HIGHER_PRIORITY_TASK = 3
    SEGMENTATION_NOT_SUPPORTED = 4
    SECURITY_ERROR = 5
    INSUFFICIENT_SECURITY = 6
    WINDOW_SIZE_OUT_OF_RANGE = 7
    APPLICATION_EXCEEDED_REPLY_TIME = 8
    OUT_OF_RESOURCES = 9
    TSM_TIMEOUT = 10
    APDU_TOO_LONG = 11


class RejectReason(IntEnum):
    """BACnet reject reasons (Clause 20.1.8)."""

    OTHER = 0
    BUFFER_OVERFLOW = 1
    INCONSISTENT_PARAMETERS = 2
    INVALID_PARAMETER_DATA_TYPE = 3
    INVALID_TAG = 4
    MISSING_REQUIRED_PARAMETER = 5
    PARAMETER_OUT_OF_RANGE = 6
    TOO_MANY_ARGUMENTS = 7
    UNDEFINED_ENUMERATION = 8
    UNRECOGNIZED_SERVICE = 9


class PduType(IntEnum):
    """APDU PDU type identifiers (Clause 20.1)."""

    CONFIRMED_REQUEST = 0
    UNCONFIRMED_REQUEST = 1
    SIMPLE_ACK = 2
    COMPLEX_ACK = 3
    SEGMENT_ACK = 4
    ERROR = 5
    REJECT = 6
    ABORT = 7


class ConfirmedServiceChoice(IntEnum):
    """Confirmed service request types (Clause 21)."""

    ACKNOWLEDGE_ALARM = 0
    CONFIRMED_COV_NOTIFICATION = 1
    CONFIRMED_EVENT_NOTIFICATION = 2
    GET_ALARM_SUMMARY = 3
    GET_ENROLLMENT_SUMMARY = 4
    SUBSCRIBE_COV = 5
    ATOMIC_READ_FILE = 6
    ATOMIC_WRITE_FILE = 7
    ADD_LIST_ELEMENT = 8
    REMOVE_LIST_ELEMENT = 9
    CREATE_OBJECT = 10
    DELETE_OBJECT = 11
    READ_PROPERTY = 12
    READ_PROPERTY_MULTIPLE = 14
    WRITE_PROPERTY = 15
    WRITE_PROPERTY_MULTIPLE = 16
    DEVICE_COMMUNICATION_CONTROL = 17
    CONFIRMED_PRIVATE_TRANSFER = 18
    CONFIRMED_TEXT_MESSAGE = 19
    REINITIALIZE_DEVICE = 20
    VT_OPEN = 21
    VT_CLOSE = 22
    VT_DATA = 23
    READ_RANGE = 26
    LIFE_SAFETY_OPERATION = 27
    SUBSCRIBE_COV_PROPERTY = 28
    GET_EVENT_INFORMATION = 29
    SUBSCRIBE_COV_PROPERTY_MULTIPLE = 30
    CONFIRMED_COV_NOTIFICATION_MULTIPLE = 31
    CONFIRMED_AUDIT_NOTIFICATION = 32
    AUDIT_LOG_QUERY = 33


class UnconfirmedServiceChoice(IntEnum):
    """Unconfirmed service request types (Clause 21)."""

    I_AM = 0
    I_HAVE = 1
    UNCONFIRMED_COV_NOTIFICATION = 2
    UNCONFIRMED_EVENT_NOTIFICATION = 3
    UNCONFIRMED_PRIVATE_TRANSFER = 4
    UNCONFIRMED_TEXT_MESSAGE = 5
    TIME_SYNCHRONIZATION = 6
    WHO_HAS = 7
    WHO_IS = 8
    UTC_TIME_SYNCHRONIZATION = 9
    WRITE_GROUP = 10
    UNCONFIRMED_COV_NOTIFICATION_MULTIPLE = 11
    UNCONFIRMED_AUDIT_NOTIFICATION = 12
    WHO_AM_I = 13
    YOU_ARE = 14


class NetworkPriority(IntEnum):
    """NPDU network priority levels (Clause 6.2.2)."""

    NORMAL = 0
    URGENT = 1
    CRITICAL_EQUIPMENT = 2
    LIFE_SAFETY = 3


class NetworkMessageType(IntEnum):
    """Network layer message types (Clause 6.2.4)."""

    WHO_IS_ROUTER_TO_NETWORK = 0x00
    I_AM_ROUTER_TO_NETWORK = 0x01
    I_COULD_BE_ROUTER_TO_NETWORK = 0x02
    REJECT_MESSAGE_TO_NETWORK = 0x03
    ROUTER_BUSY_TO_NETWORK = 0x04
    ROUTER_AVAILABLE_TO_NETWORK = 0x05
    INITIALIZE_ROUTING_TABLE = 0x06
    INITIALIZE_ROUTING_TABLE_ACK = 0x07
    ESTABLISH_CONNECTION_TO_NETWORK = 0x08
    DISCONNECT_CONNECTION_TO_NETWORK = 0x09
    CHALLENGE_REQUEST = 0x0A
    SECURITY_PAYLOAD = 0x0B
    SECURITY_RESPONSE = 0x0C
    REQUEST_KEY_UPDATE = 0x0D
    UPDATE_KEY_SET = 0x0E
    UPDATE_DISTRIBUTION_KEY = 0x0F
    REQUEST_MASTER_KEY = 0x10
    SET_MASTER_KEY = 0x11
    WHAT_IS_NETWORK_NUMBER = 0x12
    NETWORK_NUMBER_IS = 0x13


class BvlcFunction(IntEnum):
    """BVLC function codes (Annex J)."""

    BVLC_RESULT = 0x00
    WRITE_BROADCAST_DISTRIBUTION_TABLE = 0x01
    READ_BROADCAST_DISTRIBUTION_TABLE = 0x02
    READ_BROADCAST_DISTRIBUTION_TABLE_ACK = 0x03
    FORWARDED_NPDU = 0x04
    REGISTER_FOREIGN_DEVICE = 0x05
    READ_FOREIGN_DEVICE_TABLE = 0x06
    READ_FOREIGN_DEVICE_TABLE_ACK = 0x07
    DELETE_FOREIGN_DEVICE_TABLE_ENTRY = 0x08
    DISTRIBUTE_BROADCAST_TO_NETWORK = 0x09
    ORIGINAL_UNICAST_NPDU = 0x0A
    ORIGINAL_BROADCAST_NPDU = 0x0B
    SECURE_BVLL = 0x0C


class BvlcResultCode(IntEnum):
    """BVLC-Result codes (Annex J.2)."""

    SUCCESSFUL_COMPLETION = 0x0000
    WRITE_BROADCAST_DISTRIBUTION_TABLE_NAK = 0x0010
    READ_BROADCAST_DISTRIBUTION_TABLE_NAK = 0x0020
    REGISTER_FOREIGN_DEVICE_NAK = 0x0030
    READ_FOREIGN_DEVICE_TABLE_NAK = 0x0040
    DELETE_FOREIGN_DEVICE_TABLE_ENTRY_NAK = 0x0050
    DISTRIBUTE_BROADCAST_TO_NETWORK_NAK = 0x0060


class Bvlc6Function(IntEnum):
    """BACnet/IPv6 BVLC function codes (Annex U)."""

    BVLC_RESULT = 0x00
    ORIGINAL_UNICAST_NPDU = 0x01
    ORIGINAL_BROADCAST_NPDU = 0x02
    ADDRESS_RESOLUTION = 0x03
    FORWARDED_ADDRESS_RESOLUTION = 0x04
    ADDRESS_RESOLUTION_ACK = 0x05
    VIRTUAL_ADDRESS_RESOLUTION = 0x06
    VIRTUAL_ADDRESS_RESOLUTION_ACK = 0x07
    FORWARDED_NPDU = 0x08
    REGISTER_FOREIGN_DEVICE = 0x09
    DELETE_FOREIGN_DEVICE_TABLE_ENTRY = 0x0A
    SECURE_BVLL = 0x0B
    DISTRIBUTE_BROADCAST_NPDU = 0x0C


class Bvlc6ResultCode(IntEnum):
    """BACnet/IPv6 BVLC-Result codes (Annex U)."""

    SUCCESSFUL_COMPLETION = 0x0000
    ADDRESS_RESOLUTION_NAK = 0x0030
    VIRTUAL_ADDRESS_RESOLUTION_NAK = 0x0040
    REGISTER_FOREIGN_DEVICE_NAK = 0x0050
    DELETE_FOREIGN_DEVICE_TABLE_ENTRY_NAK = 0x0060
    DISTRIBUTE_BROADCAST_TO_NETWORK_NAK = 0x0070


class EventState(IntEnum):
    """BACnet event state enumeration (Clause 12)."""

    NORMAL = 0
    FAULT = 1
    OFFNORMAL = 2
    HIGH_LIMIT = 3
    LOW_LIMIT = 4
    LIFE_SAFETY_ALARM = 5


class BinaryPV(IntEnum):
    """BACnet binary present value enumeration (Clause 21)."""

    INACTIVE = 0
    ACTIVE = 1


class Polarity(IntEnum):
    """BACnet polarity enumeration (Clause 12)."""

    NORMAL = 0
    REVERSE = 1


class Reliability(IntEnum):
    """BACnet reliability enumeration (Clause 12).

    Value 11 is intentionally omitted — it was removed from the
    standard and is not assigned to any reliability condition.
    """

    NO_FAULT_DETECTED = 0
    NO_SENSOR = 1
    OVER_RANGE = 2
    UNDER_RANGE = 3
    OPEN_LOOP = 4
    SHORTED_LOOP = 5
    NO_OUTPUT = 6
    UNRELIABLE_OTHER = 7
    PROCESS_ERROR = 8
    MULTI_STATE_FAULT = 9
    CONFIGURATION_ERROR = 10
    COMMUNICATION_FAILURE = 12
    MEMBER_FAULT = 13
    MONITORED_OBJECT_FAULT = 14
    TRIPPED = 15
    LAMP_FAILURE = 16
    ACTIVATION_FAILURE = 17
    RENEW_DHCP_FAILURE = 18
    RENEW_FD_REGISTRATION_FAILURE = 19
    RESTART_AUTO_NEGOTIATION_FAILURE = 20
    RESTART_FAILURE = 21
    PROPRIETARY_COMMAND_FAILURE = 22
    FAULTS_LISTED = 23
    REFERENCED_OBJECT_FAULT = 24


class EngineeringUnits(IntEnum):
    """BACnet engineering units enumeration (Clause 21).

    Complete per ASHRAE 135-2020. Values 0-255 and 47808-49999 are reserved
    for ASHRAE; 256-47807 and 50000-65535 may be used by vendors (Clause 23).
    """

    # Acceleration
    METERS_PER_SECOND_PER_SECOND = 166

    # Area
    SQUARE_METERS = 0
    SQUARE_CENTIMETERS = 116
    SQUARE_FEET = 1
    SQUARE_INCHES = 115

    # Currency
    CURRENCY1 = 105
    CURRENCY2 = 106
    CURRENCY3 = 107
    CURRENCY4 = 108
    CURRENCY5 = 109
    CURRENCY6 = 110
    CURRENCY7 = 111
    CURRENCY8 = 112
    CURRENCY9 = 113
    CURRENCY10 = 114

    # Electrical
    MILLIAMPERES = 2
    AMPERES = 3
    AMPERES_PER_METER = 167
    AMPERES_PER_SQUARE_METER = 168
    AMPERE_SQUARE_METERS = 169
    DECIBELS = 199
    DECIBELS_MILLIVOLT = 200
    DECIBELS_VOLT = 201
    FARADS = 170
    HENRYS = 171
    OHMS = 4
    OHM_METER_SQUARED_PER_METER = 237
    OHM_METERS = 172
    MILLIOHMS = 145
    KILOHMS = 122
    MEGOHMS = 123
    MICROSIEMENS = 190
    MILLISIEMENS = 202
    SIEMENS = 173
    SIEMENS_PER_METER = 174
    TESLAS = 175
    VOLTS = 5
    MILLIVOLTS = 124
    KILOVOLTS = 6
    MEGAVOLTS = 7
    VOLT_AMPERES = 8
    KILOVOLT_AMPERES = 9
    MEGAVOLT_AMPERES = 10
    VOLT_AMPERES_REACTIVE = 11
    KILOVOLT_AMPERES_REACTIVE = 12
    MEGAVOLT_AMPERES_REACTIVE = 13
    VOLTS_PER_DEGREE_KELVIN = 176
    VOLTS_PER_METER = 177
    DEGREES_PHASE = 14
    POWER_FACTOR = 15
    WEBERS = 178

    # Energy
    AMPERE_SECONDS = 238
    VOLT_AMPERE_HOURS = 239
    KILOVOLT_AMPERE_HOURS = 240
    MEGAVOLT_AMPERE_HOURS = 241
    VOLT_AMPERE_HOURS_REACTIVE = 242
    KILOVOLT_AMPERE_HOURS_REACTIVE = 243
    MEGAVOLT_AMPERE_HOURS_REACTIVE = 244
    VOLT_SQUARE_HOURS = 245
    AMPERE_SQUARE_HOURS = 246
    JOULES = 16
    KILOJOULES = 17
    KILOJOULES_PER_KILOGRAM = 125
    MEGAJOULES = 126
    WATT_HOURS = 18
    KILOWATT_HOURS = 19
    MEGAWATT_HOURS = 146
    WATT_HOURS_REACTIVE = 203
    KILOWATT_HOURS_REACTIVE = 204
    MEGAWATT_HOURS_REACTIVE = 205
    BTUS = 20
    KILO_BTUS = 147
    MEGA_BTUS = 148
    THERMS = 21
    TON_HOURS = 22

    # Enthalpy
    JOULES_PER_KILOGRAM_DRY_AIR = 23
    KILOJOULES_PER_KILOGRAM_DRY_AIR = 149
    MEGAJOULES_PER_KILOGRAM_DRY_AIR = 150
    BTUS_PER_POUND_DRY_AIR = 24
    BTUS_PER_POUND = 117

    # Entropy
    JOULES_PER_DEGREE_KELVIN = 127
    KILOJOULES_PER_DEGREE_KELVIN = 151
    MEGAJOULES_PER_DEGREE_KELVIN = 152
    JOULES_PER_KILOGRAM_DEGREE_KELVIN = 128

    # Force
    NEWTON = 153

    # Frequency
    CYCLES_PER_HOUR = 25
    CYCLES_PER_MINUTE = 26
    HERTZ = 27
    KILOHERTZ = 129
    MEGAHERTZ = 130
    PER_HOUR = 131

    # Humidity
    GRAMS_OF_WATER_PER_KILOGRAM_DRY_AIR = 28
    PERCENT_RELATIVE_HUMIDITY = 29

    # Length
    MICROMETERS = 194
    MILLIMETERS = 30
    CENTIMETERS = 118
    KILOMETERS = 193
    METERS = 31
    INCHES = 32
    FEET = 33

    # Light
    CANDELAS = 179
    CANDELAS_PER_SQUARE_METER = 180
    WATTS_PER_SQUARE_FOOT = 34
    WATTS_PER_SQUARE_METER = 35
    LUMENS = 36
    LUXES = 37
    FOOT_CANDLES = 38

    # Mass
    MILLIGRAMS = 196
    GRAMS = 195
    KILOGRAMS = 39
    POUNDS_MASS = 40
    TONS = 41

    # Mass flow
    GRAMS_PER_SECOND = 154
    GRAMS_PER_MINUTE = 155
    KILOGRAMS_PER_SECOND = 42
    KILOGRAMS_PER_MINUTE = 43
    KILOGRAMS_PER_HOUR = 44
    POUNDS_MASS_PER_SECOND = 119
    POUNDS_MASS_PER_MINUTE = 45
    POUNDS_MASS_PER_HOUR = 46
    TONS_PER_HOUR = 156

    # Power
    MILLIWATTS = 132
    WATTS = 47
    KILOWATTS = 48
    MEGAWATTS = 49
    BTUS_PER_HOUR = 50
    KILO_BTUS_PER_HOUR = 157
    JOULE_PER_HOURS = 247
    HORSEPOWER = 51
    TONS_REFRIGERATION = 52

    # Pressure
    PASCALS = 53
    HECTOPASCALS = 133
    KILOPASCALS = 54
    MILLIBARS = 134
    BARS = 55
    POUNDS_FORCE_PER_SQUARE_INCH = 56
    MILLIMETERS_OF_WATER = 206
    CENTIMETERS_OF_WATER = 57
    INCHES_OF_WATER = 58
    MILLIMETERS_OF_MERCURY = 59
    CENTIMETERS_OF_MERCURY = 60
    INCHES_OF_MERCURY = 61

    # Temperature
    DEGREES_CELSIUS = 62
    DEGREES_KELVIN = 63
    DEGREES_KELVIN_PER_HOUR = 181
    DEGREES_KELVIN_PER_MINUTE = 182
    DEGREES_FAHRENHEIT = 64
    DEGREE_DAYS_CELSIUS = 65
    DEGREE_DAYS_FAHRENHEIT = 66
    DELTA_DEGREES_FAHRENHEIT = 120
    DELTA_DEGREES_KELVIN = 121

    # Time
    YEARS = 67
    MONTHS = 68
    WEEKS = 69
    DAYS = 70
    HOURS = 71
    MINUTES = 72
    SECONDS = 73
    HUNDREDTHS_SECONDS = 158
    MILLISECONDS = 159

    # Torque
    NEWTON_METERS = 160

    # Velocity
    MILLIMETERS_PER_SECOND = 161
    MILLIMETERS_PER_MINUTE = 162
    METERS_PER_SECOND = 74
    METERS_PER_MINUTE = 163
    METERS_PER_HOUR = 164
    KILOMETERS_PER_HOUR = 75
    FEET_PER_SECOND = 76
    FEET_PER_MINUTE = 77
    MILES_PER_HOUR = 78

    # Volume
    CUBIC_FEET = 79
    CUBIC_METERS = 80
    IMPERIAL_GALLONS = 81
    MILLILITERS = 197
    LITERS = 82
    US_GALLONS = 83

    # Volumetric flow
    CUBIC_FEET_PER_SECOND = 142
    CUBIC_FEET_PER_MINUTE = 84
    MILLION_STANDARD_CUBIC_FEET_PER_MINUTE = 254
    CUBIC_FEET_PER_HOUR = 191
    CUBIC_FEET_PER_DAY = 248
    STANDARD_CUBIC_FEET_PER_DAY = 47808
    MILLION_STANDARD_CUBIC_FEET_PER_DAY = 47809
    THOUSAND_CUBIC_FEET_PER_DAY = 47810
    THOUSAND_STANDARD_CUBIC_FEET_PER_DAY = 47811
    POUNDS_MASS_PER_DAY = 47812
    CUBIC_METERS_PER_SECOND = 85
    CUBIC_METERS_PER_MINUTE = 165
    CUBIC_METERS_PER_HOUR = 135
    CUBIC_METERS_PER_DAY = 249
    IMPERIAL_GALLONS_PER_MINUTE = 86
    MILLILITERS_PER_SECOND = 198
    LITERS_PER_SECOND = 87
    LITERS_PER_MINUTE = 88
    LITERS_PER_HOUR = 136
    US_GALLONS_PER_MINUTE = 89
    US_GALLONS_PER_HOUR = 192

    # Other
    DEGREES_ANGULAR = 90
    DEGREES_CELSIUS_PER_HOUR = 91
    DEGREES_CELSIUS_PER_MINUTE = 92
    DEGREES_FAHRENHEIT_PER_HOUR = 93
    DEGREES_FAHRENHEIT_PER_MINUTE = 94
    JOULE_SECONDS = 183
    KILOGRAMS_PER_CUBIC_METER = 186
    KILOWATT_HOURS_PER_SQUARE_METER = 137
    KILOWATT_HOURS_PER_SQUARE_FOOT = 138
    WATT_HOURS_PER_CUBIC_METER = 250
    JOULES_PER_CUBIC_METER = 251
    MEGAJOULES_PER_SQUARE_METER = 139
    MEGAJOULES_PER_SQUARE_FOOT = 140
    MOLE_PERCENT = 252
    NO_UNITS = 95
    NEWTON_SECONDS = 187
    NEWTONS_PER_METER = 188
    PARTS_PER_MILLION = 96
    PARTS_PER_BILLION = 97
    PASCAL_SECONDS = 253
    PERCENT = 98
    PERCENT_OBSCURATION_PER_FOOT = 143
    PERCENT_OBSCURATION_PER_METER = 144
    PERCENT_PER_SECOND = 99
    PER_MINUTE = 100
    PER_SECOND = 101
    PSI_PER_DEGREE_FAHRENHEIT = 102
    RADIANS = 103
    RADIANS_PER_SECOND = 184
    REVOLUTIONS_PER_MINUTE = 104
    SQUARE_METERS_PER_NEWTON = 185
    WATTS_PER_METER_PER_DEGREE_KELVIN = 189
    WATTS_PER_SQUARE_METER_DEGREE_KELVIN = 141
    PER_MILLE = 207
    GRAMS_PER_GRAM = 208
    KILOGRAMS_PER_KILOGRAM = 209
    GRAMS_PER_KILOGRAM = 210
    MILLIGRAMS_PER_GRAM = 211
    MILLIGRAMS_PER_KILOGRAM = 212
    GRAMS_PER_MILLILITER = 213
    GRAMS_PER_LITER = 214
    MILLIGRAMS_PER_LITER = 215
    MICROGRAMS_PER_LITER = 216
    GRAMS_PER_CUBIC_METER = 217
    MILLIGRAMS_PER_CUBIC_METER = 218
    MICROGRAMS_PER_CUBIC_METER = 219
    NANOGRAMS_PER_CUBIC_METER = 220
    GRAMS_PER_CUBIC_CENTIMETER = 221
    BECQUERELS = 222
    KILOBECQUERELS = 223
    MEGABECQUERELS = 224
    GRAY = 225
    MILLIGRAY = 226
    MICROGRAY = 227
    SIEVERTS = 228
    MILLISIEVERTS = 229
    MICROSIEVERTS = 230
    MICROSIEVERTS_PER_HOUR = 231
    MILLIREMS = 47814
    MILLIREMS_PER_HOUR = 47815
    DECIBELS_A = 232
    NEPHELOMETRIC_TURBIDITY_UNIT = 233
    PH = 234
    GRAMS_PER_SQUARE_METER = 235
    MINUTES_PER_DEGREE_KELVIN = 236
    DEGREES_LOVIBOND = 47816
    ALCOHOL_BY_VOLUME = 47817
    INTERNATIONAL_BITTERING_UNITS = 47818
    EUROPEAN_BITTERNESS_UNITS = 47819
    DEGREES_PLATO = 47820
    SPECIFIC_GRAVITY = 47821
    EUROPEAN_BREWING_CONVENTION = 47822


class EnableDisable(IntEnum):
    """BACnetEnableDisable values (Clause 16.4)."""

    ENABLE = 0
    DISABLE = 1  # Deprecated in revision 20; use DISABLE_INITIATION instead.
    DISABLE_INITIATION = 2


class ReinitializedState(IntEnum):
    """BACnetReinitializedStateOfDevice values (Clause 16.5)."""

    COLDSTART = 0
    WARMSTART = 1
    START_BACKUP = 2
    END_BACKUP = 3
    START_RESTORE = 4
    END_RESTORE = 5
    ABORT_RESTORE = 6
    ACTIVATE_CHANGES = 7


class FileAccessMethod(IntEnum):
    """BACnetFileAccessMethod values (Clause 12.12)."""

    STREAM_ACCESS = 0
    RECORD_ACCESS = 1


class ProgramState(IntEnum):
    """BACnetProgramState values (Clause 12.22)."""

    IDLE = 0
    LOADING = 1
    RUNNING = 2
    WAITING = 3
    HALTED = 4
    UNLOADING = 5


class ProgramChange(IntEnum):
    """BACnetProgramRequest values (Clause 12.22)."""

    READY = 0
    LOAD = 1
    RUN = 2
    HALT = 3
    RESTART = 4
    UNLOAD = 5


class Action(IntEnum):
    """BACnetAction values (Clause 12.17)."""

    DIRECT = 0
    REVERSE = 1


class DeviceStatus(IntEnum):
    """BACnetDeviceStatus values (Clause 12.11.9)."""

    OPERATIONAL = 0
    OPERATIONAL_READ_ONLY = 1
    DOWNLOAD_REQUIRED = 2
    DOWNLOAD_IN_PROGRESS = 3
    NON_OPERATIONAL = 4
    BACKUP_IN_PROGRESS = 5


class BackupAndRestoreState(IntEnum):
    """BACnetBackupAndRestoreState values (Clause 19.1)."""

    IDLE = 0
    PREPARING_FOR_BACKUP = 1
    PREPARING_FOR_RESTORE = 2
    PERFORMING_A_BACKUP = 3
    PERFORMING_A_RESTORE = 4


class EventType(IntEnum):
    """BACnetEventType values (Clause 12.12.6)."""

    CHANGE_OF_BITSTRING = 0
    CHANGE_OF_STATE = 1
    CHANGE_OF_VALUE = 2
    COMMAND_FAILURE = 3
    FLOATING_LIMIT = 4
    OUT_OF_RANGE = 5
    CHANGE_OF_LIFE_SAFETY = 8
    EXTENDED = 9
    BUFFER_READY = 10
    UNSIGNED_RANGE = 11
    ACCESS_EVENT = 13
    DOUBLE_OUT_OF_RANGE = 14
    SIGNED_OUT_OF_RANGE = 15
    UNSIGNED_OUT_OF_RANGE = 16
    CHANGE_OF_CHARACTERSTRING = 17
    CHANGE_OF_STATUS_FLAGS = 18
    CHANGE_OF_RELIABILITY = 19
    NONE = 20
    CHANGE_OF_DISCRETE_VALUE = 21
    CHANGE_OF_TIMER = 22


class LoggingType(IntEnum):
    """BACnetLoggingType values (Clause 12.25.14)."""

    POLLED = 0
    COV = 1
    TRIGGERED = 2


class NotifyType(IntEnum):
    """BACnetNotifyType values (Clause 12.21)."""

    ALARM = 0
    EVENT = 1
    ACK_NOTIFICATION = 2


class RejectMessageReason(IntEnum):
    """Reject-Message-To-Network reason codes (Clause 6.4.4)."""

    OTHER = 0
    NOT_DIRECTLY_CONNECTED = 1
    ROUTER_BUSY = 2
    UNKNOWN_MESSAGE_TYPE = 3
    MESSAGE_TOO_LONG = 4
    SECURITY_ERROR = 5
    ADDRESSING_ERROR = 6


class NetworkReachability(IntEnum):
    """Reachability status for a routing table entry (Clause 6.6.1)."""

    REACHABLE = 0
    BUSY = 1
    UNREACHABLE = 2


class NetworkType(IntEnum):
    """BACnet data link/network layer type (Clause 12.56.44)."""

    ETHERNET = 0
    ARCNET = 1
    MSTP = 2
    PTP = 3
    LONTALK = 4
    IPV4 = 5
    ZIGBEE = 6
    VIRTUAL = 7
    NON_BACNET = 8  # removed in protocol revision 16
    IPV6 = 9
    SERIAL = 10


class IPMode(IntEnum):
    """IP addressing mode for a NetworkPort (Clause 12.56)."""

    NORMAL = 0
    FOREIGN = 1
    BBMD = 2


class NetworkPortCommand(IntEnum):
    """Commands for a NetworkPort object (Clause 12.56.40)."""

    IDLE = 0
    DISCARD_CHANGES = 1
    RENEW_FD_REGISTRATION = 2
    RESTART_SLAVE_DISCOVERY = 3
    RENEW_DHCP = 4
    RESTART_AUTONEG = 5
    DISCONNECT = 6
    RESTART_PORT = 7


class NetworkNumberQuality(IntEnum):
    """Quality of a NetworkPort's network number (Clause 12.56.42)."""

    UNKNOWN = 0
    LEARNED = 1
    LEARNED_CONFIGURED = 2
    CONFIGURED = 3


class ProtocolLevel(IntEnum):
    """Protocol level of a NetworkPort (Clause 12.56)."""

    PHYSICAL = 0
    PROTOCOL = 1
    BACNET_APPLICATION = 2
    NON_BACNET_APPLICATION = 3


class WriteStatus(IntEnum):
    """Status of the last Channel write operation (Clause 12.53)."""

    IDLE = 0
    IN_PROGRESS = 1
    SUCCESSFUL = 2
    FAILED = 3


class LifeSafetyState(IntEnum):
    """Life safety point/zone sensor state (Clause 12.15/12.16)."""

    QUIET = 0
    PRE_ALARM = 1
    ALARM = 2
    FAULT = 3
    FAULT_PRE_ALARM = 4
    FAULT_ALARM = 5
    NOT_READY = 6
    ACTIVE = 7
    TAMPER = 8
    TEST_ALARM = 9
    TEST_ACTIVE = 10
    TEST_FAULT = 11
    TEST_FAULT_ALARM = 12
    HOLDUP = 13
    DURESS = 14
    TAMPER_ALARM = 15
    ABNORMAL = 16
    EMERGENCY_POWER = 17
    DELAYED = 18
    BLOCKED = 19
    LOCAL_ALARM = 20
    GENERAL_ALARM = 21
    SUPERVISORY = 22
    TEST_SUPERVISORY = 23


class LifeSafetyMode(IntEnum):
    """Life safety operating mode (Clause 12.15.12)."""

    OFF = 0
    ON = 1
    TEST = 2
    MANNED = 3
    UNMANNED = 4
    ARMED = 5
    DISARMED = 6
    PRE_ARMED = 7
    SLOW = 8
    FAST = 9
    DISCONNECTED = 10
    ENABLED = 11
    DISABLED = 12
    AUTOMATIC_RELEASE_DISABLED = 13
    DEFAULT = 14


class LifeSafetyOperation(IntEnum):
    """Life safety commanded operation (Clause 12.15.13)."""

    NONE = 0
    SILENCE = 1
    SILENCE_AUDIBLE = 2
    SILENCE_VISUAL = 3
    SILENCE_ALL = 4
    UNSILENCE = 5
    UNSILENCE_AUDIBLE = 6
    UNSILENCE_VISUAL = 7
    UNSILENCE_ALL = 8
    RESET = 9
    RESET_ALARM = 10
    RESET_FAULT = 11


class SilencedState(IntEnum):
    """Silenced state for a life safety point/zone (Clause 12.15.14)."""

    UNSILENCED = 0
    AUDIBLE_SILENCED = 1
    VISIBLE_SILENCED = 2
    ALL_SILENCED = 3


class AcknowledgmentFilter(IntEnum):
    """BACnet acknowledgment filter for GetEnrollmentSummary (Clause 13.7.1)."""

    ALL = 0
    ACKED = 1
    NOT_ACKED = 2


class EventTransitionBits(IntEnum):
    """Positional constants for the 3-element event transition bitstring.

    Used to index into ``event_enable`` and ``acked_transitions``
    bitstrings (Clause 12.11).
    """

    TO_OFFNORMAL = 0
    TO_FAULT = 1
    TO_NORMAL = 2


class TimerState(IntEnum):
    """BACnet timer state enumeration (Clause 12.31, new in 2020)."""

    IDLE = 0
    RUNNING = 1
    EXPIRED = 2


class TimerTransition(IntEnum):
    """BACnet timer state transition enumeration (Clause 12.31, new in 2020)."""

    NONE = 0
    IDLE_TO_RUNNING = 1
    RUNNING_TO_IDLE = 2
    RUNNING_TO_RUNNING = 3
    RUNNING_TO_EXPIRED = 4
    FORCED_TO_EXPIRED = 5
    EXPIRED_TO_IDLE = 6
    EXPIRED_TO_RUNNING = 7


class MessagePriority(IntEnum):
    """BACnet message priority for TextMessage services (Clause 16.5)."""

    NORMAL = 0
    URGENT = 1


class VTClass(IntEnum):
    """BACnet virtual terminal class (Clause 17.1)."""

    DEFAULT_TERMINAL = 0
    ANSI_X3_64 = 1
    DEC_VT52 = 2
    DEC_VT100 = 3
    DEC_VT220 = 4
    HP_700_94 = 5
    IBM_3130 = 6


class NodeType(IntEnum):
    """BACnet node type for Structured View (Clause 12.29)."""

    UNKNOWN = 0
    SYSTEM = 1
    NETWORK = 2
    DEVICE = 3
    ORGANIZATIONAL = 4
    AREA = 5
    EQUIPMENT = 6
    POINT = 7
    COLLECTION = 8
    PROPERTY = 9
    FUNCTIONAL = 10
    OTHER = 11
    SUBSYSTEM = 12
    BUILDING = 13
    FLOOR = 14
    SECTION = 15
    MODULE = 16
    TREE = 17
    MEMBER = 18
    PROTOCOL = 19
    ROOM = 20
    ZONE = 21


class ShedState(IntEnum):
    """BACnet shed state for Load Control (Clause 12.28)."""

    SHED_INACTIVE = 0
    SHED_REQUEST_PENDING = 1
    SHED_COMPLIANT = 2
    SHED_NON_COMPLIANT = 3


class DoorAlarmState(IntEnum):
    """BACnet door alarm state (Clause 12.26)."""

    NORMAL = 0
    ALARM = 1
    DOOR_OPEN_TOO_LONG = 2
    FORCED_OPEN = 3
    TAMPER = 4
    DOOR_FAULT = 5
    LOCK_FAULT = 6
    FREE_ACCESS = 7
    EGRESS_OPEN = 8


class DoorStatus(IntEnum):
    """BACnet door status (Clause 12.26)."""

    CLOSED = 0
    OPENED = 1
    UNKNOWN = 2


class LockStatus(IntEnum):
    """BACnet lock status (Clause 12.26)."""

    LOCKED = 0
    UNLOCKED = 1
    LOCK_FAULT = 2
    UNUSED = 3
    UNKNOWN = 4


class DoorSecuredStatus(IntEnum):
    """BACnet secured status for Access Door (Clause 12.26)."""

    SECURED = 0
    UNSECURED = 1
    UNKNOWN = 2


class LightingOperation(IntEnum):
    """BACnet lighting operation (Clause 12.54)."""

    NONE = 0
    FADE_TO = 1
    RAMP_TO = 2
    STEP_UP = 3
    STEP_DOWN = 4
    STEP_ON = 5
    STEP_OFF = 6
    WARN = 7
    WARN_OFF = 8
    WARN_RELINQUISH = 9
    STOP = 10


class LightingInProgress(IntEnum):
    """BACnet lighting in-progress state (Clause 12.54)."""

    IDLE = 0
    FADE_ACTIVE = 1
    RAMP_ACTIVE = 2
    NOT_CONTROLLED = 3
    OTHER = 4


class AccessEvent(IntEnum):
    """BACnet access event (Clause 12.33).

    Values 0-127 are granted events; 128-511 are denied events.
    Values 0-511 reserved for ASHRAE; 512-65535 for vendor use (Clause 23).
    """

    NONE = 0
    GRANTED = 1
    MUSTER = 2
    PASSBACK_DETECTED = 3
    DURESS = 4
    TRACE = 5
    LOCKOUT_MAX_ATTEMPTS = 6
    LOCKOUT_OTHER = 7
    LOCKOUT_RELINQUISHED = 8
    LOCKED_BY_HIGHER_PRIORITY = 9
    OUT_OF_SERVICE = 10
    OUT_OF_SERVICE_RELINQUISHED = 11
    ACCOMPANIMENT_BY = 12
    AUTHENTICATION_FACTOR_READ = 13
    AUTHORIZATION_DELAYED = 14
    VERIFICATION_REQUIRED = 15
    NO_ENTRY_AFTER_GRANTED = 16
    # Denied events (128+)
    DENIED_DENY_ALL = 128
    DENIED_UNKNOWN_CREDENTIAL = 129
    DENIED_AUTHENTICATION_UNAVAILABLE = 130
    DENIED_AUTHENTICATION_FACTOR_TIMEOUT = 131
    DENIED_INCORRECT_AUTHENTICATION_FACTOR = 132
    DENIED_ZONE_NO_ACCESS_RIGHTS = 133
    DENIED_POINT_NO_ACCESS_RIGHTS = 134
    DENIED_NO_ACCESS_RIGHTS = 135
    DENIED_OUT_OF_TIME_RANGE = 136
    DENIED_THREAT_LEVEL = 137
    DENIED_PASSBACK = 138
    DENIED_UNEXPECTED_LOCATION_USAGE = 139
    DENIED_MAX_ATTEMPTS = 140
    DENIED_LOWER_OCCUPANCY_LIMIT = 141
    DENIED_UPPER_OCCUPANCY_LIMIT = 142
    DENIED_AUTHENTICATION_FACTOR_LOST = 143
    DENIED_AUTHENTICATION_FACTOR_STOLEN = 144
    DENIED_AUTHENTICATION_FACTOR_DAMAGED = 145
    DENIED_AUTHENTICATION_FACTOR_DESTROYED = 146
    DENIED_AUTHENTICATION_FACTOR_DISABLED = 147
    DENIED_AUTHENTICATION_FACTOR_ERROR = 148
    DENIED_CREDENTIAL_UNASSIGNED = 149
    DENIED_CREDENTIAL_NOT_PROVISIONED = 150
    DENIED_CREDENTIAL_NOT_YET_ACTIVE = 151
    DENIED_CREDENTIAL_EXPIRED = 152
    DENIED_CREDENTIAL_MANUAL_DISABLE = 153
    DENIED_CREDENTIAL_LOCKOUT = 154
    DENIED_CREDENTIAL_MAX_DAYS = 155
    DENIED_CREDENTIAL_MAX_USES = 156
    DENIED_CREDENTIAL_INACTIVITY = 157
    DENIED_CREDENTIAL_DISABLED = 158
    DENIED_NO_ACCOMPANIMENT = 159
    DENIED_INCORRECT_ACCOMPANIMENT = 160
    DENIED_LOCKOUT = 161
    DENIED_VERIFICATION_FAILED = 162
    DENIED_VERIFICATION_TIMEOUT = 163
    DENIED_OTHER = 164


class AccessCredentialDisable(IntEnum):
    """BACnet access credential disable (Clause 21).

    Values 0-63 reserved for ASHRAE; 64-65535 for vendor use (Clause 23).
    """

    NONE = 0
    DISABLE = 1
    DISABLE_MANUAL = 2
    DISABLE_LOCKOUT = 3


class AccessCredentialDisableReason(IntEnum):
    """BACnet access credential disable reason (Clause 21).

    Values 0-63 reserved for ASHRAE; 64-65535 for vendor use (Clause 23).
    """

    DISABLED = 0
    DISABLED_NEEDS_PROVISIONING = 1
    DISABLED_UNASSIGNED = 2
    DISABLED_NOT_YET_ACTIVE = 3
    DISABLED_EXPIRED = 4
    DISABLED_LOCKOUT = 5
    DISABLED_MAX_DAYS = 6
    DISABLED_MAX_USES = 7
    DISABLED_INACTIVITY = 8
    DISABLED_MANUAL = 9


class AccessUserType(IntEnum):
    """BACnet access user type (Clause 12.35)."""

    ASSET = 0
    GROUP = 1
    PERSON = 2


class AuthorizationMode(IntEnum):
    """BACnet authorization mode (Clause 12.31)."""

    AUTHORIZE = 0
    GRANT_ACTIVE = 1
    DENY_ALL = 2
    VERIFICATION_REQUIRED = 3
    AUTHORIZATION_DELAYED = 4
    NONE = 5


class AccessPassbackMode(IntEnum):
    """BACnet access passback mode (Clause 12.32)."""

    PASSBACK_OFF = 0
    HARD_PASSBACK = 1
    SOFT_PASSBACK = 2


class EscalatorMode(IntEnum):
    """BACnet escalator operating mode (Clause 12.60)."""

    UNKNOWN = 0
    STOP = 1
    UP = 2
    DOWN = 3
    INSPECTION = 4
    OUT_OF_SERVICE = 5


class EscalatorFault(IntEnum):
    """BACnet escalator fault signals (Clause 12.60)."""

    CONTROLLER_FAULT = 0
    DRIVE_AND_MOTOR_FAULT = 1
    MECHANICAL_COMPONENT_FAULT = 2
    OVERSPEED_FAULT = 3
    POWER_SUPPLY_FAULT = 4
    SAFETY_DEVICE_FAULT = 5
    CONTROLLER_SUPPLY_FAULT = 6
    DRIVE_TEMPERATURE_EXCEEDED = 7
    COMB_PLATE_FAULT = 8


class LiftCarDirection(IntEnum):
    """BACnet lift car travel direction (Clause 12.59)."""

    UNKNOWN = 0
    NONE = 1
    STOPPED = 2
    UP = 3
    DOWN = 4
    UP_AND_DOWN = 5


class LiftGroupMode(IntEnum):
    """BACnet lift group operating mode (Clause 12.58)."""

    UNKNOWN = 0
    NORMAL = 1
    DOWN_PEAK = 2
    TWO_WAY = 3
    FOUR_WAY = 4
    EMERGENCY = 5
    UP_PEAK = 6


class LiftCarDoorStatus(IntEnum):
    """BACnet lift car door status (Clause 12.59)."""

    UNKNOWN = 0
    NONE = 1
    CLOSING = 2
    CLOSED = 3
    OPENING = 4
    OPENED = 5
    SAFETY_LOCKED = 6
    LIMITED_OPENED = 7


class LiftCarDoorCommand(IntEnum):
    """BACnet lift car door command (Clause 21)."""

    NONE = 0
    OPEN = 1
    CLOSE = 2


class LiftCarDriveStatus(IntEnum):
    """BACnet lift car drive status (Clause 21)."""

    UNKNOWN = 0
    STATIONARY = 1
    BRAKING = 2
    ACCELERATE = 3
    DECELERATE = 4
    RATED_SPEED = 5
    SINGLE_FLOOR_JUMP = 6
    TWO_FLOOR_JUMP = 7
    THREE_FLOOR_JUMP = 8
    MULTI_FLOOR_JUMP = 9


class LiftCarMode(IntEnum):
    """BACnet lift car operating mode (Clause 21).

    Values 0-1023 reserved for ASHRAE; 1024-65535 for vendor use (Clause 23).
    """

    UNKNOWN = 0
    NORMAL = 1
    VIP = 2
    HOMING = 3
    PARKING = 4
    ATTENDANT_CONTROL = 5
    FIREFIGHTER_CONTROL = 6
    EMERGENCY_POWER = 7
    INSPECTION = 8
    CABINET_RECALL = 9
    EARTHQUAKE_OPERATION = 10
    FIRE_OPERATION = 11
    OUT_OF_SERVICE = 12
    OCCUPANT_EVACUATION = 13


class LiftFault(IntEnum):
    """BACnet lift fault signals (Clause 21).

    Values 0-1023 reserved for ASHRAE; 1024-65535 for vendor use (Clause 23).
    """

    CONTROLLER_FAULT = 0
    DRIVE_AND_MOTOR_FAULT = 1
    GOVERNOR_AND_SAFETY_GEAR_FAULT = 2
    LIFT_SHAFT_DEVICE_FAULT = 3
    POWER_SUPPLY_FAULT = 4
    SAFETY_INTERLOCK_FAULT = 5
    DOOR_CLOSING_FAULT = 6
    DOOR_OPENING_FAULT = 7
    CAR_STOPPED_OUTSIDE_LANDING_ZONE = 8
    CALL_BUTTON_STUCK = 9
    START_FAILURE = 10
    CONTROLLER_SUPPLY_FAULT = 11
    SELF_TEST_FAILURE = 12
    RUNTIME_LIMIT_EXCEEDED = 13
    POSITION_LOST = 14
    DRIVE_TEMPERATURE_EXCEEDED = 15
    LOAD_MEASUREMENT_FAULT = 16


class StagingState(IntEnum):
    """BACnet staging state (Clause 12.62, new in 2020)."""

    NOT_STAGED = 0
    STAGING = 1
    STAGED = 2
    COMMITTING = 3
    COMMITTED = 4
    ABANDONING = 5
    ABANDONED = 6


class AuditLevel(IntEnum):
    """BACnet audit level (Clause 19.6, new in 2020)."""

    NONE = 0
    AUDIT_ALL = 1
    AUDIT_CONFIG = 2
    DEFAULT = 3


class AuditOperation(IntEnum):
    """BACnet audit operation (Clause 19.6, new in 2020)."""

    READ = 0
    WRITE = 1
    CREATE = 2
    DELETE = 3
    LIFE_SAFETY = 4
    ACKNOWLEDGE_ALARM = 5
    DEVICE_DISABLE_COMM = 6
    DEVICE_ENABLE_COMM = 7
    DEVICE_RESET = 8
    DEVICE_BACKUP = 9
    DEVICE_RESTORE = 10
    SUBSCRIPTION = 11
    NOTIFICATION = 12
    AUDITING_FAILURE = 13
    NETWORK_CHANGES = 14
    GENERAL = 15


class BACnetSuccessFilter(IntEnum):
    """BACnet success filter for audit log queries (Clause 13.19, new in 2020)."""

    ALL = 0
    SUCCESSES_ONLY = 1
    FAILURES_ONLY = 2
