Skip to content

Standards

Catalog, under Systems: Standards (/standards, with standard:read, covered by every viewer’s *:read floor) is the directory of standards: the blueprints your systems are built against. A Huddle Room, a Classroom, an Auditorium are standards; the meeting room on the third floor is a system that conforms to one. Each row shows the name (the operator-facing name, for example huddle-room), the label, its parent standard if it is a variant, and its origin. A standard also carries an id, a uuid minted by the database, the internal address the handle resolves to (ADR-0062); the handle is what you type and read.

A standard is the system-side counterpart of a product. A product says what a component is and what it carries; a standard says what a system is built to be and what it carries. It was formerly a bare label registry that carried no contract, and its promotion into a first-class catalog entity is why it has its own page and its own standard:* permission rather than sitting under the shared type registry (ADR-0048).

A standard is not a system type. They are two axes and a system can carry either, both, or neither. The system type (Catalog, under Systems: Types) is the coarse genus of what kind of space a system is, a boardroom, a classroom, a video wall; the standard is the blueprint it is built to. One fleet holds ten signage standards and six classroom standards under a single coarse type, which is why the classifier is its own registry rather than a use of a standard’s own parent-variant chain (ADR-0096).

  • Conforming is optional. A system points at a standard through its Standard field, and leaving it empty is legitimate: a one-off system that matches no blueprint carries only its own values, exactly as a component with no product does.
  • Variants use parent standard. A specific blueprint that refines a broader one points at it with parent standard (a Large Classroom under Classroom). A standard with no parent is a base standard.
  • New standard (with standard:create, an admin permission) opens a create drawer: give it a name (unique tenant-wide, e.g. lecture-hall) and a label, and optionally pick a parent standard. An unknown parent is refused (422).
  • Pick a row to open its detail blade. The footer Edit pencil (with standard:update) edits the label and parent; the name is fixed, since a catalog row carries no rename. Delete (with standard:delete) removes the row, behind a confirm.
  • Delete is refused (409) while a system still conforms to it. Repoint or remove those systems first.

The same operations are omniglass standard list/get/create/update/delete from the CLI (see the CLI reference).

Omniglass ships a starter set, and unlike a seeded vendor or product those rows are not official and not read-only. They arrive as ordinary operator-owned rows: rename them, re-parent them, add to their contract, delete the ones you do not run. The shipped set, rendered from the seed itself:

StandardRoles it staffs
meeting-room (Meeting Room)video-bar (quorum 0, accepts video-bar) main-display (quorum 0, accepts display) touch-control (quorum 0, accepts touch-panel) scheduling-panel (quorum 0, accepts scheduling-panel)
mr55 (Meeting Room 55)video-bar (quorum 0, accepts video-bar) main-display (quorum 0, accepts display) touch-control (quorum 0, accepts touch-panel) scheduling-panel (quorum 0, accepts scheduling-panel)
mr65 (Meeting Room 65)video-bar (quorum 0, accepts video-bar) main-display (quorum 0, accepts display) touch-control (quorum 0, accepts touch-panel) scheduling-panel (quorum 0, accepts scheduling-panel)
mr75 (Meeting Room 75)video-bar (quorum 0, accepts video-bar) main-display (quorum 0, accepts display) touch-control (quorum 0, accepts touch-panel) scheduling-panel (quorum 0, accepts scheduling-panel)
mr86 (Meeting Room 86)video-bar (quorum 0, accepts video-bar) main-display (quorum 0, accepts display) touch-control (quorum 0, accepts touch-panel) scheduling-panel (quorum 0, accepts scheduling-panel)
mr98 (Meeting Room 98)video-bar (quorum 0, accepts video-bar) main-display (quorum 0, accepts display) touch-control (quorum 0, accepts touch-panel) scheduling-panel (quorum 0, accepts scheduling-panel)
divisible-conference (Divisible Conference)video-bar (quorum 0, accepts video-bar) main-display (quorum 2, accepts display) room-mic (quorum 2, accepts ceiling-mic) dsp (quorum 0, accepts dsp) amplifier (quorum 0, accepts amplifier) touch-control (quorum 0, accepts touch-panel) scheduling-panel (quorum 0, accepts scheduling-panel)
huddle-room (Huddle Room)main-display (quorum 0, accepts display) conf-bar (quorum 1, accepts video-bar) conf-codec (quorum 0, accepts codec) conf-camera (quorum 0, accepts camera) conf-dsp (quorum 0, accepts dsp) conf-amp (quorum 0, accepts amplifier) conf-mic (quorum 0, accepts mic)
classroom (Classroom)class-display (quorum 0, accepts display) instructor-mic (quorum 0, accepts wireless-mic) touch-control (quorum 0, accepts touch-panel)
training-room (Training Room)front-display (quorum 2, accepts display) ceiling-mic (quorum 2, accepts ceiling-mic) presenter-mic (quorum 0, accepts wireless-mic) podium-mic (quorum 0, accepts gooseneck-mic) dsp (quorum 0, accepts dsp) amplifier (quorum 0, accepts amplifier) speakers (quorum 4, accepts speaker) video-switcher (quorum 0, accepts presentation-switcher) display-endpoint (quorum 2, accepts av-extender) control-system (quorum 0, accepts control-processor) touch-control (quorum 0, accepts touch-panel) scheduling-panel (quorum 0, accepts scheduling-panel) people-counter (quorum 0, accepts occupancy-sensor) camera (quorum 2, accepts camera)
auditorium (Auditorium)projection (quorum 0, accepts projector) confidence-display (quorum 0, accepts display) stage-mic (quorum 2, accepts wireless-mic) podium-mic (quorum 0, accepts gooseneck-mic) dsp (quorum 0, accepts dsp) amplifier (quorum 2, accepts amplifier) speakers (quorum 4, accepts speaker) video-switcher (quorum 0, accepts presentation-switcher) control-system (quorum 0, accepts control-processor) touch-control (quorum 0, accepts touch-panel) camera (quorum 2, accepts camera)
digital-sign (Digital Sign)panel (quorum 0, accepts display) player (quorum 0, accepts media-player)
ds55 (Digital Sign 55)panel (quorum 0, accepts display) player (quorum 0, accepts media-player)
ds75 (Digital Sign 75)panel (quorum 0, accepts display) player (quorum 0, accepts media-player)

This is deliberate. A standard is forked from a template that lives in the code, once, with no inheritance: nothing in your fleet points back at that template afterwards. So Omniglass can improve its templates in any release without ever touching your rows, and your edits are never reverted by a restart, because the boot seed installs a standard only if it is absent. The thing the vendor updates and the thing you own are two different objects, which is the whole point.

The exception is the canonical vocabulary: the property catalog (and later commands and event types) is the shared namespace a driver maps onto, so it must read the same on every install. Those entries stay official and read-only, and a release can correct them. See the seed model for the full reasoning.

Declared properties: the standard’s contract

Section titled “Declared properties: the standard’s contract”

A standard’s blade carries a Declared properties panel, its contract: which properties every system conforming to it exposes, and what each one defaults to. It is the same editor as a product’s contract, on the system side.

  • Declare a property (with standard:update) picks a name from the property catalog, optionally types a default, and optionally marks it required. The property must already exist in the catalog, since the contract only names it: mint it under Catalog, under Telemetry: Properties first. Declaring is idempotent, so declaring a property already on the contract revises that line in place.
  • The default is typed by the catalog, not here. Type and validation live on the property, so a standard cannot redefine what room-capacity means, only what a system conforming to it starts with.
  • Conformance is live, not a copy. A system does not fork its standard. Change a contract default and every conforming system that has not overridden that property picks up the new value immediately. Only a system’s own override survives the change.
  • Required means a conforming system must resolve the property to a value; the system’s Properties panel blocks Save while a required property is empty.
  • Withdraw (with standard:delete, from the blade’s edit mode, so the pencil’s standard:update is also in the path; behind a confirm) removes a line. Conforming systems keep any value they set for it; it simply reads as off contract from then on.

From the CLI the contract is omniglass standard property list <id>, omniglass standard property update <id> <property>, and omniglass standard property delete <id> <property>.

Roles: what a conforming system needs filled

Section titled “Roles: what a conforming system needs filled”

A contract says what a system carries. A role says what it needs filled: a room microphone, a main display, a confidence monitor. Declare a role on a standard and every conforming system inherits it, the same live inheritance the contract has, so a standard is not only a shape but a checklist that says which rooms are short a component.

A role in this sense is a slot in a room, and it has nothing to do with the roles under Admin that grant people access. Different word, different namespace, no overlap.

The standard’s blade carries a Roles panel beside its contract. Each role has:

  • a name (its address within the standard, e.g. room-mic) and a label;
  • a quorum, how many components should fill it. Two ceiling mics is one role with quorum 2, not two roles. The minimum is one, since a role no component need fill is not a role;
  • accepted types, the component types a filling component’s product may be classified under (self or a descendant); empty accepts any type. Optionally pinned products, narrowing further to specific products within an accepted type; empty accepts any product of an accepted type. This is the typed-slot guard: a role wanting video-bar accepts the shipped Cisco Room Bar and any other product classified under it, but not a display;
  • an impact, what the room loses when this slot is not being filled properly.

Impact is the health knob, and it belongs to the slot. The same broken box matters differently depending on the job it was doing, so the judgement lives on the role rather than on the device:

| impact | means | reach for it when | |---|---|---| | outage | the room is not working | the room cannot run without this slot | | degraded (the default) | the room works, worse | losing it costs quality, not the meeting | | none | nothing | you want the slot tracked, not depended on |

A dead confidence monitor is not a dead main display, and this is where you say so. Set the main display to outage and the confidence monitor to none, and a failed confidence monitor stops paging anybody about a room that is running fine. What that impact does downstream is the health rollup: a role short of its quorum contributes its impact, and the system takes the worst one.

Quorum is your redundancy setting, and it pairs with impact. A role wanting one mic with two assigned survives losing either of them, because one working mic still meets the quorum. A role wanting two with two assigned is impaired the moment either one fails. Redundancy is not a separate switch, it is the gap between what you staffed and what you need.

Declaring is idempotent, so saving a role that already exists revises it in place, and the accepted types and pinned products each replace the previous set wholesale (drop one by leaving it out). Withdrawing a role (with standard:delete, from edit mode like every contract control) also removes every assignment conforming systems made to it, so withdraw only when the slot itself is gone, not when one room’s component changed. Changing a quorum or an impact re-evaluates every conforming system immediately, so a retune shows up in the fleet’s health without waiting for anything to poll.

Two shipped roles come with Meeting Room, and they are the worked example: Room Microphone (accepts video-bar, quorum 2) and Main Display (accepts display). Like the standards themselves they are seeded only if absent, so retuning quorum to what your rooms actually run survives the next restart.

From the CLI: omniglass standard role list <id>, omniglass standard role update <id> <role> --label <label> --quorum <n> --accepted-types <types> --pinned-products <ids> --impact <outage|degraded|none>, and omniglass standard role delete <id> <role>.

Declaring the role is half of it; the other half happens on the system. Open a system from Systems and its detail carries a Roles panel showing every role it needs filled: the ones inherited from its standard and any declared on the system itself, each marked with where it came from.

  1. Conform the system to the standard. A system’s Standard field is what makes it inherit; a one-off system that conforms to nothing sees only roles declared directly on it.
  2. Assign a component to the role. Each role lists the components filling it and lets you add another. The picker is scoped to what you can see, and assignment is idempotent.
  3. Read the understaffed count. A role wanting two components with one assigned reads as short by one, immediately, without any monitoring running: staffing is a fact about what you have entered. The room’s health asks the second question, of the components that are assigned, how many can currently do the job, and routes the answer up through the role’s impact.
  4. Unassign when a component moves out. The role goes back to understaffed until something else fills it. A component that is currently staffing a role cannot be deleted; unassign it first, so the system never silently loses a slot.

A component that cannot fill the role is refused, and told why. Assigning a display to a role that accepts video-bar fails with a message naming both parties:

component "panel-1" is a display; role "Table microphone" wants a video-bar

Pinning products narrows further: a right-type, wrong-product component is refused by name too:

component "panel-3" is product "other-display"; role "Main Display" wants product samsung-qm55

That is the whole point of the typed-slot guard. Your next move is in the message: either you picked the wrong component, or the role’s accepted types (or pinned products) need widening.

Roles declared directly on a system work identically and are edited from the same panel; use them for what one room needs and the blueprint does not. A role inherited from the standard is withdrawn on the standard, not on the system that inherits it.

From the CLI: omniglass system role list <name>, omniglass system role update <name> <role>, omniglass system role delete <name> <role>, omniglass system role assignment update <name> <role> <component>, and omniglass system role assignment delete <name> <role> <component>.

Once the roles are declared and staffed, the whole loop (raise an alarm, watch the room go degraded, find the cause, clear it, read the history) is on Work with an entity.