LZ Broadcast Intercom docs/device-library.md

Device library (devices.zumpelars.de)

The shared device library of the AV Planner Suite keeps one entry per device: a core every planner shares (manufacturer, model, category, datasheet) and one facet per planner in that planner's own format. This page describes the intercom facet and how this system reads and writes it.

Code: apps/web/src/lib/deviceLibrary/. The client deviceLibraryClient.ts is an unchanged copy of clients/deviceLibraryClient.ts from larszu/av-device-library; changes go there first.

Account

Reading the library needs an account. Accounts are created on the website (Create account in the settings opens it), not in this app.

Setup → Settings & Logs → Device library

Every error code of the client has its own message. Two need action on the website: guidelines outdated (the community guidelines changed — the message links to <server>/guidelines to accept them again) and already in the library (HTTP 409 — confirm or correct the existing entry there instead of submitting a second one).

The token is kept per operator UI, never in a show config and never sent to the intercom core:

Where the UI runs Where the token lives
Desktop app encrypted with Electron safeStorage (Keychain / DPAPI) in the user-data folder. Without OS encryption nothing is written; the sign-in lasts until the app closes.
Browser localStorage of the core's address

Device types

Setup → Device types lists two sources side by side:

Entries the library delivers but this planner's check refuses are counted and listed under Delivered but not usable here, with the reason — never used, never silently dropped.

Uploading

The library keeps one device per manufacturer + model. Uploading a type the library already has adds this planner's view as the device's next version instead of a duplicate. Uploads are moderated unless the account is an admin.

This repo ships no built-in device models (no fixed beltpack or antenna catalogue), so there is no catalogue to publish from CI; everything in the library comes from own types.

Add device (Setup → Devices & Users) offers both sources as Device type: picking one sets the role (beltpack or station), limits the transports to the type's, and fills the label with the model.

The intercom facet

The facet is this planner's device type. Uploading writes it with toFacet, syncing reads it with readDeviceType — the same function checks both directions (intercomDeviceType.ts).

{
  "format": "intercom-device-type",
  "version": 1,
  "kind": "beltpack",
  "transports": ["dect", "ethernet"],
  "keys": { "pages": 2, "perPage": 4 },
  "power": ["battery", "usb-c"],
  "audio": { "headset": 1, "speaker": false },
  "protocols": ["aes67"]
}
Field Required Meaning
format yes always intercom-device-type
version yes 1. A newer version is refused, not guessed.
kind yes beltpack, deskstation, antenna, interface
transports yes, ≥ 1 how the device reaches the core: ethernet, dect, wifi (the core's TransportType)
keys beltpack, deskstation key grid: pages (1–32) × perPage (1–64) — the same page/button grid as PlanKey in avplan-intercom v2
dectCapacity — antennas: beltpacks one antenna carries at once (1–1000)
power — poe, battery, usb-c, mains
audio — headset, lineIn, lineOut (0–64), speaker (true/false)
protocols — aes67, dante, sip, gpio, 2-wire, 4-wire

An antenna must list dect. Unknown values are refused; unknown fields are dropped.

No project data. Label, device ID, IP address, user, channel assignment, antenna link, audio levels — all of that belongs to a device in a show config (BeltpackDevice), not to its type. The facet is built field by field from the table above, so none of it can pass through; npm run library:check proves it.

Relation to avplan-intercom. The vendor-neutral plan file (plan-import.md) describes a show: conferences, stations, memberships, keys. The facet describes the hardware a station runs on and reuses the plan's vocabulary for it (transports, the key grid). A plan station does not reference a device type; that link stays with the device in this system.

Where it is checked

npm run library:check (in CI): release default, address rules, facet round trip, project fields kept out, version/kind/transport refused by meaning, incremental sync with removed and refused entries, one cache per server (switching keeps the other, legacy copy migrates), reset on a lower latestSeq, empty server and sign-out keep the cache, request timeout, the proposal and the batched upload on the wire, change detection and retry rules, auto-upload wiring, the device manager's translations, the library's error codes (each with a text in both languages), no logging of the token, safeStorage in the desktop app.