# Raumsystem-Steuerung

Source: https://www.veeting.com/de/developer-documentation/room-system-control

## Übersicht

Mit der Raumsystem-Steuerung bedient ein Panel im physischen Meetingraum ein laufendes Meeting. Das Panel kann ein Wandpanel, ein [Q-SYS](https://www.qsys.com/)- oder [Crestron](https://www.crestron.com/)-Prozessor sein oder jedes andere Gerät, das HTTPS-Anfragen senden kann. Über HTTPS-Anfragen steuert das Panel, was auf den Bildschirmen im Raum zu sehen ist und wie und wann das Meeting beendet wird. Es sind dieselben Aktionen, die ein Moderator in der Browserapplikation auch manuell ausführen kann. Mit den folgenden Kommandos bedienen Sie einen Raum über ein Panel statt über den Browser.

**Basis-URL:** `https://<DOMAIN-NAME>/api/v6`

`<DOMAIN-NAME>` ist Ihre eigene Web-Meeting-Domain. Verwenden Sie die Domain, unter der Ihre Instanz läuft.

**Content-Type:** `application/json` bei jedem POST.

Die Raumsystem-API besteht aus einem Endpunkt für Kommandos und einem für den Zustand. Sie senden ein Kommando und jede Antwort enthält den Zustand des Meetings nach dem Kommando. Mit den Zustands-APIs können Sie jederzeit den aktuellen Stand abrufen und so zum Beispiel die Tasten auf dem Panel beleuchten.

Mit den Raumsystem-Kommandos können Sie kein Meeting starten. Nutzen Sie dafür die normalen [REST-APIs](/de/developer-documentation/api-usage).

## Funktion aktivieren

Die Raumsystem-Steuerung ist standardmässig ausgeschaltet. Ein White-Label-Administrator schaltet sie in den Systemeinstellungen unter «Raumsystemfunktionen aktivieren» ein. Solange die Einstellung aus ist, antworten die nachfolgenden Endpunkte mit 402.

## Authentifizierung

Sie haben drei Möglichkeiten, sich zu authentifizieren. Die Methoden unterscheiden sich darin, welche Meetings sie erreichen.

| Methode                  | Header              | Erreicht                                                            |
| ------------------------ | ------------------- | ------------------------------------------------------------------- |
| API-Key auf Kontoebene   | `X-API-KEY`         | jedes laufende Meeting des zugehörigen Kontos                       |
| API-Key auf Instanzebene | `X-API-KEY`         | jedes laufende Meeting der White-Label-Instanz                      |
| Moderatoren-Token        | `X-MODERATOR-TOKEN` | ein bestimmtes laufendes Meeting, nur über die `/moderator/`-Routen |

**Für ein Raumsystem ist ein API-Key der Normalfall.** Einen Key auf Kontoebene erstellen Sie in den «Kontoeinstellungen». Er ist auf die Meeting-Endpunkte beschränkt und lässt sich darum bedenkenlos in einem Raum hinterlegen. Ein Key auf Instanzebene erreicht jedes Konto und gehört nie in Kundenhand. Wie Keys ausgestellt werden und wie sie im Namen eines Users handeln, steht unter [API-Nutzung](/de/developer-documentation/api-usage).

**Ein Moderatoren-Token** wird für jedes einzelne Meeting neu erstellt und ist nur für dieses spezifische Meeting gültig. Mit einem Moderatoren-Token muss das Raumsystem über die `/moderator/`-Varianten der beiden Routen angesprochen werden. Schicken Sie ihn als Header statt in der URL, damit er nicht in Proxy- und Browser-Logs landet.

## Endpunkte

| Methode | Pfad                                                        | Zweck                                         |
| ------- | ----------------------------------------------------------- | --------------------------------------------- |
| POST    | `/meeting-room/<MEETING-ID>/room-system/commands`           | ein Kommando ausführen                        |
| GET     | `/meeting-room/<MEETING-ID>/room-system/state`              | den Zustand lesen                             |
| POST    | `/meeting-room/<MEETING-ID>/room-system/moderator/commands` | ein Kommando ausführen, mit Moderatoren-Token |
| GET     | `/meeting-room/<MEETING-ID>/room-system/moderator/state`    | den Zustand lesen, mit Moderatoren-Token      |

`<MEETING-ID>` ist die 24 Zeichen lange `id` des Meetings, also der Wert, den die Meeting-API beim Anlegen zurückgibt, zum Beispiel _6a9e7e89813a920f5679188f_. Es ist **nicht** die `meetingId` mit den Bindestrichen aus dem Meeting-Link.

Der Request-Body eines Kommandos ist in beiden Varianten (API-Key und Moderatoren-Token) derselbe:

```json
{
  "command": "tool.activate",
  "parameters": {
    "toolId": "vr-whiteboard"
  }
}
```

Lassen Sie `parameters` weg, wenn ein Kommando keine braucht. Alle vier Routen liefern das Zustandsobjekt, das weiter unten beschrieben ist.

## Kommandos

| Kommando                     | Erforderlich    | Optional     | Wirkung                                                                                                                                                         |
| ---------------------------- | --------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `tool.activate`              | `toolId`        |              | Legt ein Tool auf den Bildschirm aller Teilnehmer. Das entspricht der Taste `take` im Meetingraum: Sie zieht alle mit, ob «Folge mir» nun aktiv ist oder nicht. |
| `presentation.goToSlide`     | `page`          | `documentId` | Blättert die offene Präsentation auf eine absolute Seitenzahl, gezählt ab 1.                                                                                    |
| `presentation.nextSlide`     |                 | `documentId` | Blättert auf die Seite nach der aktuellen.                                                                                                                      |
| `presentation.previousSlide` |                 | `documentId` | Blättert auf die Seite vor der aktuellen. Bei Seite 1 ist Schluss.                                                                                              |
| `screen.assignTool`          | `toolId`        | `tvChannel`  | Weist ein Tool einem TV-Kanal zu. Lassen Sie `tvChannel` weg, um die Zuweisung aufzuheben.                                                                      |
| `screen.pinParticipant`      | `participantId` | `tvChannel`  | Heftet einen Teilnehmer an einen TV-Kanal. Lassen Sie `tvChannel` weg, um die Zuweisung wieder aufzuheben.                                                      |
| `presentationMode.enable`    |                 |              | Schaltet den Präsentationsmodus ein.                                                                                                                            |
| `presentationMode.disable`   |                 |              | Schaltet den Präsentationsmodus aus.                                                                                                                            |
| `waitingRoom.lock`           |                 |              | Schickt neu Ankommende in den Warteraum.                                                                                                                        |
| `waitingRoom.unlock`         |                 |              | Lässt neu Ankommende wieder direkt herein.                                                                                                                      |
| `chat.clear`                 |                 |              | Leert den Gruppenchat, für alle und im Meeting-Protokoll.                                                                                                       |
| `screensharing.forceStop`    |                 |              | Beendet das laufende Screensharing.                                                                                                                             |
| `meeting.close`              |                 |              | Beendet das Meeting für alle.                                                                                                                                   |

### Parameter

| Parameter       | Typ     | Hinweise                                                                                                                                          |
| --------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `toolId`        | String  | Einer der Tool-Identifier weiter unten. Jeder andere Wert wird abgelehnt.                                                                         |
| `page`          | Integer | 1 oder grösser.                                                                                                                                   |
| `documentId`    | String  | Die Präsentation, die Ihrer Annahme nach offen ist. Ist eine andere offen, wird das Kommando abgelehnt, statt auf das falsche Dokument zu wirken. |
| `tvChannel`     | Integer | 0 oder grösser. Lassen Sie ihn weg, um eine Zuweisung aufzuheben.                                                                                 |
| `participantId` | String  | Die `participantId` eines Teilnehmers, aus dem Zustandsobjekt.                                                                                    |

### Hinweise, die Ihnen Zeit sparen

**Ihr Panel muss nicht mitzählen.** `presentation.nextSlide` und `presentation.previousSlide` bezieht die Plattform auf die Seite, auf der das Meeting gerade steht. Ein Panel muss also nicht mitzählen. Wenn Sie die Seitenzahl anzeigen möchten, lesen Sie `presentation.currentPage` aus dem Zustand.

**Zuerst muss eine Präsentation offen sein.** Um die Präsentation zu steuern, muss jemand im Meeting sie zuvor geöffnet haben. Ohne ein solches Dokument antworten die APIs mit 402.

## Tool-Identifier

`toolId` akzeptiert diese Werte und keine anderen. Es sind Identifier, keine Beschriftungen, und sie lauten in jeder Oberflächensprache gleich.

- vr-agenda
- vr-assistant
- vr-chat
- vr-dialin-numbers
- vr-documents
- vr-lobby-management
- vr-minutes
- vr-notes
- vr-participants
- vr-polls
- vr-screensharing
- vr-settings
- vr-tv-channel-manager
- vr-video
- vr-webinar-configuration
- vr-webinar-questions
- vr-whiteboard

Custom Tools heissen `vr-custom-tool-0` bis `vr-custom-tool-5`. Wie Sie Custom Tools einrichten, steht unter [Widgets im Meetingraum](/de/developer-documentation/custom-tools).

Welche Tools ein Teilnehmer überhaupt sieht, ist eine andere Frage. Das entscheiden die Meeting-Berechtigungen des Kontos. Aktivieren Sie ein Tool, das ein Teilnehmer nicht nutzen darf, bekommt er es auch nicht zu sehen.

## Das Zustandsobjekt

Beide Zustandsendpunkte und jedes Kommando liefern dieses Objekt.

| Feld                     | Typ     | Beschreibung                                                                             |
| ------------------------ | ------- | ---------------------------------------------------------------------------------------- |
| `activeToolId`           | String  | Das Tool, das gerade auf dem Bildschirm liegt. Fehlt, solange niemand eines gewählt hat. |
| `presentation`           | Objekt  | `documentId` und `currentPage` der offenen Präsentation, sonst `null`.                   |
| `presentationModeActive` | Boolean | Ob der Präsentationsmodus läuft.                                                         |
| `waitingRoomActive`      | Boolean | Ob neu Ankommende in den Warteraum gehen.                                                |
| `followMeActive`         | Boolean | Ob ein Teilnehmer den Raum mit «Folge mir» führt.                                        |
| `recordingState`         | String  | `stopped`, `requested` oder `started`.                                                   |
| `participants`           | Array   | Alle im Meeting, ausser Teilnehmern, die unsichtbar beigetreten sind.                    |

Jeder Teilnehmer enthält `participantId`, `name`, `isModerator` und `handRaised`, dazu `tvChannel`, sofern er einem TV-Kanal zugewiesen ist.

## Statuscodes und Fehler

Jede Antwort verwendet denselben Wrapper wie die REST API: `{ "responseCode": 0, "responseMessage": "", "data": { ... } }`.

| HTTP Status | `responseCode` | Bedeutung                                                                                                                                                                                                      |
| ----------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 200         | 0              | Das Kommando ist ausgeführt. `data` enthält den Zustand.                                                                                                                                                       |
| 401         | -99            | Sie sind nicht berechtigt, z.B. weil die Zugangsdaten fehlen oder ungültig sind.                                                                                                                               |
| 402         | -33            | Die Raumsystem-Funktion ist nicht aktiviert, oder das Meeting läuft nicht oder gehört Ihnen nicht, ein erforderlicher Parameter fehlt, keine Präsentation ist offen, oder der Teilnehmer ist nicht im Meeting. |
| 422         | -44            | Ein unbekanntes Kommando, eine unbekannte `toolId`, eine Seite kleiner als 1.                                                                                                                                  |

## Beispiele

Das Whiteboard auf alle Bildschirme legen:

```bash
curl -X POST "https://<DOMAIN-NAME>/api/v6/meeting-room/<MEETING-ID>/room-system/commands" \
  -H "X-API-KEY: <API-KEY>" \
  -H "Content-Type: application/json" \
  -d '{"command":"tool.activate","parameters":{"toolId":"vr-whiteboard"}}'
```

Eine Seite weiterblättern:

```bash
curl -X POST "https://<DOMAIN-NAME>/api/v6/meeting-room/<MEETING-ID>/room-system/commands" \
  -H "X-API-KEY: <API-KEY>" \
  -H "Content-Type: application/json" \
  -d '{"command":"presentation.nextSlide"}'
```

Den Zustand lesen, mit einem Moderatoren-Token statt eines Keys:

```bash
curl "https://<DOMAIN-NAME>/api/v6/meeting-room/<MEETING-ID>/room-system/moderator/state" \
  -H "X-MODERATOR-TOKEN: <MODERATOR-TOKEN>"
```

Eine erfolgreiche Antwort:

```json
{
  "responseCode": 0,
  "responseMessage": "",
  "data": {
    "activeToolId": "vr-documents",
    "presentation": { "documentId": "6710a2b4c81e4a6c8b0d2f4a", "currentPage": 7 },
    "presentationModeActive": true,
    "waitingRoomActive": false,
    "followMeActive": false,
    "recordingState": "stopped",
    "participants": [
      { "participantId": "a1b2c3", "name": "Anna Meier", "isModerator": true, "handRaised": false, "tvChannel": 1 }
    ]
  }
}
```

### Anbindung an ein Panel

Ein Panel braucht in der Regel zweierlei: eine Taste, die ein Kommando schickt, und eine Lampe, die zeigt, was im Raum läuft.

Für die Taste schicken Sie das Kommando und prüfen, ob der HTTP-Status 200 **und** `responseCode` 0 ist. Für die Lampe fragen Sie den Zustandsendpunkt regelmässig ab. Da jedes Kommando ebenfalls mit dem Zustand antwortet, können Sie den Zustand auch aus der API-Antwort übernehmen.

Legen Sie den API-Key in die Konfiguration des Panels und nicht in das Skript der einzelnen Taste. Dann müssen Sie beim Wechsel eines Keys nicht jede Taste anfassen.

## Weitere nützliche Steuerungsmöglichkeiten

Mit den [Query-Parametern](/de/developer-documentation/query-parameters) können Sie zum Beispiel festlegen, ob der angesprochene Browser Audio überhaupt empfangen soll. Das ist vor allem im TV-Modus interessant.

Gerade wenn Sie verschiedene Bildschirme über denselben Rechner steuern und die Browserinstanzen deshalb im Kioskmodus öffnen, möchten Sie sicherstellen, dass es im Raum kein Echo gibt. Deshalb ist es sinnvoll, z.B. nur in einer Browserinstanz Audio zu empfangen.

## Häufige Fehler

- Den Meeting-Token mit Bindestrichen aus dem Meeting-Link nehmen und nicht die 24 Zeichen lange `id`.
- Nur den HTTP-Status prüfen oder nur `responseCode`. Prüfen Sie beides.
- Ein Kommando an ein Meeting schicken, das noch nicht begonnen hat. Es wird nichts in eine Queue gelegt.
- `presentation.nextSlide` aufrufen, bevor jemand ein Dokument geöffnet hat.
- Den Moderatoren-Token an die Routen ohne `/moderator/` im Pfad schicken, wo er ignoriert wird.
- Eine Tool-ID erfinden oder übersetzen. Die Identifier sind in jeder Sprache englisch.
- Die Funktion auf der Instanz ausgeschaltet lassen und den 402 als kaputten Key deuten.

---

## Die übrige Dokumentation

- [Custom Tools – eigene Widgets im Meetingraum](https://www.veeting.com/de/developer-documentation/custom-tools)
- [Externer Autorisierungsdienst](https://www.veeting.com/de/developer-documentation/external-meeting-authorization-service)
- [iFrame und Web Komponenten](https://www.veeting.com/de/developer-documentation/iframe-and-web-components)
- [JavaScript APIs](https://www.veeting.com/de/developer-documentation/javascript-apis)
- [JavaScript und Typescript APIs](https://www.veeting.com/de/veeting-blocks/apis)
- [Komponenten](https://www.veeting.com/de/veeting-blocks/components)
- [Kontrolle über die Videodarstellung](https://www.veeting.com/de/developer-documentation/video-display-calculator)
- [Parameter in der URL](https://www.veeting.com/de/developer-documentation/query-parameters)
- [Veeting Blocks - Übersicht](https://www.veeting.com/de/veeting-blocks/introduction)
- [Veeting Rooms REST APIs](https://www.veeting.com/de/developer-documentation/api-usage)
- [Webhooks](https://www.veeting.com/de/developer-documentation/web-hooks)

Alles in einer Datei: https://www.veeting.com/llms-full.txt
