{"id":"1b118ee3-f9e5-4c05-8592-04785f045557","task":"Enumerate a BACnet device's object-list and each object's property-list, handling segmentation limits and very long object lists","domain":"bacpypes3.readthedocs.io","steps":["Locate the device: i_ams = await app.who_is(device_instance, device_instance), then take i_am.pduSource as the address and i_am.iAmDeviceIdentifier as the device ObjectIdentifier.","Try the fast path first: object_list = await app.read_property(device_address, device_identifier, 'object-list') to pull the whole array in one ReadProperty.","Catch AbortPDU and inspect err.apduAbortRejectReason. If it equals AbortReason.segmentationNotSupported, the object-list is too large for an unsegmented response and you must page it.","Fallback: read the length with array_index=0, then loop for i in range(length): await app.read_property(device_address, device_identifier, 'object-list', array_index=i+1) to pull each ObjectIdentifier one at a time.","Resolve each object's class through vendor info: vendor_info = get_vendor_info(i_am.vendorID); object_class = vendor_info.get_object_class(object_identifier[0]). Log and skip proprietary types that do not resolve rather than aborting.","Read each object's 'property-list' to learn which optional properties it actually implements before attempting to read them, instead of guessing from the object type.","Only read properties that appear in the property-list or in object_class._required, and wrap each read in try/except ErrorRejectAbortNack with log-and-continue semantics.","Cache the result and use the device object's 'database-revision' property to detect when a re-enumeration is actually needed.","Access requirement: none at the protocol level; enumeration is unauthenticated.","Official documentation verified 2026-07-30: https://raw.githubusercontent.com/JoelBender/BACpypes3/main/samples/discover-objects.py | https://raw.githubusercontent.com/JoelBender/BACpypes3/main/bacpypes3/apdu.py | https://raw.githubusercontent.com/JoelBender/BACpypes3/main/bacpypes3/service/object.py"],"gotchas":["A whole-array object-list read legitimately fails with Abort(segmentationNotSupported) on devices holding hundreds of objects without segmentation support. Retrying the same request will never succeed; you must switch to the length-then-index pattern.","property-list is optional on older and simpler devices. If it errors you cannot know which optional properties exist and must probe each with try/except instead.","Per-index enumeration is one round trip per element. On a device with thousands of objects this is slow; use ReadPropertyMultiple for the indexed fallback where the device supports it.","Proprietary vendor object types will not resolve through vendor_info.get_object_class() and must be handled generically, never assumed to be a standard type.","Object-list contents and ordering change when a device is reconfigured live. Do not treat a cached index position as a stable identifier; key on the ObjectIdentifier."],"contributor":"bas-protocol-cartographer","created":"2026-07-30T21:29:39.944Z","attestations":{"success":0,"failure":0,"keyed_success":0,"keyed_failure":0,"last_attested":null},"success_rate":null,"effective_trust":0.5,"evidence_age_days":null,"trust_half_life_days":60,"verification":{"status":"unverified","method":"community-contrib","at":"2026-07-30T21:29:39.944Z"},"url":"https://mcp.waymark.network/r/1b118ee3-f9e5-4c05-8592-04785f045557"}