Skip to content

Access-Control Assembly (Doors, Readers, Relays, Contacts, REX)

Guidance for modelling how access-control elements relate. This is not a rigid prescription — it is a set of questions to investigate and recommendations for how to approach the answer. Pick the shape that fits what the protocol actually exposes, and document the choice.

The one firm premise

Access is granted to doors. A "door" is the logical assembly of: one or more readers, a lock/relay (strike), an optional door contact (position sensor / DPS), and an optional REX (request-to-exit). There must be a door construct to assign access to — even when the protocol has no "door" object at all and the door is a purely logical grouping wired together in adapter code/config.

Everything else below is about how to express that assembly.

Two relationship mechanisms

PQ expresses the links between these elements with exactly two concepts. Use whichever fits:

Mechanism What it is Use when
parent-child tree nesting via a Thing's parents there is natural containment/addressing (controller → module → reader) and the element belongs to exactly one owner
deviceRef a property whose type is a device type (SomeType or SomeType[]), resolved at tree construction linking peers across the tree, many-to-many, or assembling a door from elements that live elsewhere (or are shared)

A door assembly is commonly expressed with deviceRef: a Door Thing carries reference properties to the elements it wires together, e.g.

- type_id: AccessDoor
  category: door
  access_point: true
  functions: { Door: }
  properties:
    entry_reader:  { type: ReaderThing }       # deviceRef → reader (entry side)
    exit_reader:   { type: ReaderThing }        # deviceRef → reader (exit side, optional)
    strike:        { type: OutputThing }        # deviceRef → lock relay
    door_contact:  { type: InputThing }         # deviceRef → position sensor (optional)
    rex:           { type: InputThing }         # deviceRef → request-to-exit (optional)

Equally valid is parent-child (readers/inputs/outputs nested under the door) when the protocol addresses them that way. And the integrated variant: the Door function has built-in has_position_sensor / has_rex_sensor flags when contact/REX are not separate addressable elements.

Questions to investigate

Before modelling an access-control device, answer these from the vendor documentation (cite; "not documented" is a valid answer → gap):

  1. Does the protocol have a first-class door object, or only terminals (reader, relay, inputs)? If only terminals, the door is a logical construct — say so.
  2. Which elements are fixed/implicit (a single-purpose terminal that cannot be used for anything else, often unaddressed) versus configurable/addressable? Implicit elements may not need their own Thing — they can be the Door function's built-in sensors or a documented logical wiring.
  3. How does a reader relate to the relay and contact it controls? Is the binding fixed by hardware, or configured?
  4. Is there an entry/exit pair (two readers per door)? In/out is expressed as the direction parameter on the reader's access events, not as access-control logic.
  5. Is REX its own input, an integrated door capability, or absent?
  6. Can one physical element be shared by multiple doors (favours deviceRef over parent-child)?

Recommendations

  • Choose parent-child for genuine containment/addressing hierarchy; choose deviceRef for the door-assembly wiring and any shared/cross-tree link. Both are first-class — don't force one.
  • A reader must be resolvably linked to its door (a deviceRef property, or parent-child, or the framework IThingRelationResolver relation). Without the link the door cannot grant on read.
  • When elements have no protocol address (purely logical), express the wiring in adapter code/config and record it as a note/gap — do not invent protocol addresses for them.
  • Keep the door as the access_point (access_point: true) so authorization targets it. This document is door-scoped, but access_point is not door-only: on panels that authorize users per area/partition/floor, that unit is also an access point — see MODEL-002 (precedent: intrusion panels that authorize per partition).
  • Document the chosen shape and why (which protocol facts drove it) in the adapter's notes.

A shipping door-controller adapter demonstrates the deviceRef wiring pattern (a door Thing with entry_reader / exit_reader / strike / door_contact / rex reference properties to separate reader/output/input Things) — study one before modelling a new one.

See also

  • reference/functions/door.md — Door function (strike, contact, REX, timers, states)
  • reference/functions/reader.md — Reader function (access events, direction, door relation)
  • concepts/things.md — parent-child and device-reference properties