REST-Ausgabe: HTTP-Requests senden
PixDrive Studio schickt HTTP-Requests an WLED, Philips Hue oder jede andere HTTP-API – aus einem REST-Gerät oder direkt aus deinen Lua-Effekten.
Aktualisiert am
Füge den Guide in einen KI-Chat ein und beschreibe danach, was das Skript tun soll.
PixDrive Studio kann nicht nur Art-Net, sACN und TPM2.Net ausgeben, sondern auch HTTP-Requests senden. Damit steuerst du Geräte, die eine HTTP-API haben: einen WLED-Controller, eine Philips-Hue-Bridge, einen Shelly, einen Medienserver oder einen eigenen Webhook.
Es gibt zwei Wege, die du auch kombinieren kannst:
- Ein REST-Gerät bekommt wie jedes andere Gerät Pixel. Ein kleines Lua-Skript macht aus deren Farben einen Request. Das passt, wenn ein HTTP-Gerät einfach mitleuchten soll.
- Effekt-Skripte senden selbst, mit
rest_get("WLED", "/pfad")oderhttp_get(url). Das passt, wenn du volle Kontrolle brauchst: Requests auf den Beat, zu bestimmten Zeitpunkten in der Show oder mit beliebigen Daten.
Diese Seite beschreibt Requests, die PixDrive verschickt. Wie du PixDrive selbst per HTTP steuerst, steht unter Externe Steuerungsschnittstelle (REST & OSC).
REST-Gerät anlegen
- Klicke in der Geräteliste auf Gerät hinzufügen.
- Wähle als Protokoll REST (HTTP).
- Gib einen Namen ein, zum Beispiel
WLED, und in das Adressfeld die Basis-URL, zum Beispielhttp://192.168.178.52. Ein Port-Feld gibt es für REST nicht; einen abweichenden Port schreibst du in die URL. - Klicke auf Hinzufügen.
Wählst du das Gerät in der Liste aus, zeigt das Panel Eigenschaften rechts alle REST-Einstellungen. Ganz oben steht, wie du das Gerät aus einem Effekt-Skript ansprichst, etwa rest_get("WLED", "/path").
Einstellungen
- Basis-URL: Adresse des Geräts. Ein
pathaus dem Skript wird angehängt.https://funktioniert ebenfalls. - Methode: GET, POST, PUT, PATCH oder DELETE. Gilt, wenn das Skript keine eigene Methode angibt.
- Timeout (ms): Wie lange PixDrive auf eine Antwort wartet (100 bis 60 000 ms).
- Modus: Stream (bei Farbänderung) sendet, sobald sich die Farben ändern. Einmalig (auf Auslösung) sendet nur, wenn du auf Jetzt senden klickst oder ein MCP-Client auslöst.
- Max. Rate (Hz): Obergrenze im Stream-Modus, 0,1 bis 60 Requests pro Sekunde. Für WLED sind 10 Hz ein guter Wert, eine Hue-Bridge verkraftet insgesamt nur etwa 10 Requests pro Sekunde.
- Header: Werden bei jedem Request mitgeschickt, zum Beispiel
Authorization: Bearer ….
Jeder Request trägt den Header User-Agent: PixDrive-Studio/<Version>, sofern du keinen eigenen User-Agent setzt.
Das Request-Skript
Das REST-Gerät ruft im Skript die Funktion build_request(pixels, fixtures) auf, sobald es etwas senden soll. Sie bekommt die aktuellen Farben der Fixtures dieses Geräts und gibt zurück, was gesendet wird.
pixels[i] ist eine Tabelle mit den Kanälen des LED-Typs, jeweils 0 bis 255 (gamma-korrigiert, wie sie auch per Art-Net hinausgehen würden):
| LED-Typ | Felder |
|---|---|
| RGB | r, g, b |
| RGBW | r, g, b, w |
| RGBCCT | r, g, b, ww, cw |
| CCT | bri, ct |
fixtures[i] beschreibt die Fixtures in der Reihenfolge des Geräts: id, name, start (Index des ersten Pixels in pixels) und count.
Das Skript gibt nil oder {} zurück, wenn nichts gesendet werden soll, eine Request-Tabelle oder eine Liste davon (höchstens 64). Alle Felder sind optional:
method: überschreibt die Methode des Gerätspath: wird an die Basis-URL angehängt, oderurlfür eine vollständige andere Adresseheaders: Tabelle wie{ ["X-Key"] = "abc" }, ergänzt oder ersetzt die Header des Gerätsbody: ein String wird unverändert gesendet, eine Tabelle als JSON (der HeaderContent-Type: application/jsonkommt dann automatisch dazu)
json_encode(wert) wandelt eine Tabelle in einen JSON-String um. Tabellen mit den Schlüsseln 1 bis n werden zu Arrays, eine leere Tabelle zu {}.
Dieses Skript setzt einen WLED-Controller über dessen HTTP-API auf die Farbe des ersten Pixels:
function build_request(pixels, fixtures)
local p = pixels[1]
if p == nil then return nil end
return {
method = "GET",
path = string.format("/win&A=255&R=%d&G=%d&B=%d", p.r, p.g, p.b),
}
end
Das Skript läuft in derselben abgesicherten Umgebung wie Effekt-Skripte: kein Dateizugriff, keine Systembefehle und ein Zeitlimit von 250 ms pro Aufruf. Ein Skript, das nicht lädt, lässt sich nicht übernehmen. Die Fehlermeldung zeigt die betroffene Zeile.
Vorlagen
Über Vorlage einfügen über dem Editor lädst du ein fertiges Skript:
- Generisches JSON sendet die Farbe des ersten Pixels als
{ "r": …, "g": …, "b": … }. - WLED (JSON-API) färbt pro Fixture ein WLED-Segment über
/json/state. - Philips Hue setzt pro Fixture eine Lampe über die API v1. Die Basis-URL lautet dann
http://<bridge-ip>/api/<username>, und jedes Fixture heißt wie die ID seiner Lampe, zum Beispiel3.
Änderungen im Editor gelten erst nach Skript übernehmen.
Vorschau und Test
Request-Vorschau zeigt Methode, URL, Header und Inhalt der Requests für die aktuellen Farben, ohne etwas zu senden. Darunter stehen die Zähler für gesendete und fehlgeschlagene Requests und der letzte Fehler. Jetzt senden schickt die aktuellen Farben sofort, in beiden Modi.
Ein REST-Gerät sendet in einem eigenen Hintergrund-Thread. Ein langsames oder nicht erreichbares Ziel bremst also weder die Vorschau noch die übrigen Ausgänge. Im Stream-Modus ist immer höchstens ein Request unterwegs; Farben, die in der Zwischenzeit anfallen, werden zusammengefasst statt aufgestaut.
Requests aus Effekt-Skripten
In jedem Effekt-Skript stehen diese Funktionen zur Verfügung:
| Funktion | Zweck |
|---|---|
rest_get(gerät, pfad [, header]) |
GET an die Basis-URL des REST-Geräts plus pfad |
rest_post(gerät, pfad, body [, header]) |
POST, body als String oder Tabelle (JSON) |
rest_put(gerät, pfad, body [, header]) |
PUT |
rest_request(gerät, { method, path, headers, body }) |
beliebige Methode, sonst die des Geräts |
http_get(url [, header]) |
GET an eine vollständige URL |
http_post(url, body [, header]), http_put(…) |
POST und PUT an eine vollständige URL |
http_request{ method, url, headers, body } |
beliebige Methode |
json_encode(wert) |
Tabelle als JSON-String |
Die rest_*-Funktionen sprechen ein REST-Gerät über seinen Namen an und übernehmen dessen Basis-URL und Header. Ändert sich die IP-Adresse, passt du sie nur im Gerät an, nicht in jedem Skript. Ein REST-Gerät ohne Fixtures dient dabei nur als Adressbuch und sendet nichts von selbst. Der Name ist groß-/kleinschreibungsabhängig. Bei einem unbekannten Namen, etwa nach dem Umbenennen eines Geräts, sendet die Funktion nichts und gibt false zurück. Der Effekt läuft weiter, und im Protokoll steht eine Warnung mit den vorhandenen REST-Geräten.
Die http_*-Funktionen brauchen kein Gerät, dafür steht die vollständige URL im Skript.
Regeln
- Die Funktionen senden im Hintergrund und warten nicht auf eine Antwort. Sie geben
truezurück, wenn der Request in die Warteschlange kam, sonstfalse. Eine Antwort bekommt das Skript nicht. - Gesendet wird nur, wenn das Bild wirklich ausgegeben wird: bei Live-Effekten und während der Sequenzer abspielt. In der Hover-Vorschau der Timeline, beim Ziehen des Abspielkopfs, bei Pause und beim Export läuft das Skript, schickt aber nichts.
- Pro Effekt gehen höchstens 20 Requests pro Sekunde hinaus, weitere werden verworfen.
render()läuft 60-mal pro Sekunde, rufe die Funktionen deshalb nie bedingungslos in jedem Frame auf, sondern nur bei einer Änderung. - Bei Skripten mit
parallel = truesendet nur der erste Worker. - Eine ungültige URL oder Methode ist ein Skriptfehler und fällt schon in der Vorschau auf.
Beispiel: WLED folgt dem Effekt
Das Skript färbt die LEDs und schickt dieselbe Farbe an das REST-Gerät WLED, höchstens zehnmal pro Sekunde und nur bei einer Änderung. sent wird erst gesetzt, wenn der Request wirklich rausging. Sonst würde ein Bild aus der Vorschau den ersten echten Request verschlucken.
local sent, sent_at = nil, -1
function render()
local r = (sin(time) * 0.5 + 0.5)
for i = 0, led_count - 1 do set_led_rgb(i, r, 0.0, 0.0) end
local path = string.format("/win&A=255&R=%d&G=0&B=0", math.floor(r * 255))
if time < sent_at then sent_at = -1 end -- Segment beginnt in einer Schleife neu
if path ~= sent and time - sent_at >= 0.1 and rest_get("WLED", path) then
sent, sent_at = path, time
end
end
Beispiel: ein Request pro Beat
local was_beat = false
function render()
if audio_beat and not was_beat then
http_post("http://10.0.0.5/api/trigger", { scene = "flash" })
end
was_beat = audio_beat
end
In Sequenzer und Presets
Effekt-Skripte mit rest_get oder http_get legst du wie jedes andere Skript als Segment in die Timeline oder speicherst sie als Preset. Ein Preset lässt sich dann auch über die externe Steuerungsschnittstelle als Cue auslösen.
Lass Segmente, die an dasselbe Gerät senden, nicht überlappen. Jedes Skript schickt seine eigene Farbe, ein Überblenden zweier Segmente würde das Gerät flackern lassen. Ein- und Ausblendungen in der Timeline wirken nur auf die Vorschau und die Pixel, nicht auf die Werte, die ein Skript per HTTP sendet.
Per MCP
Über den MCP-Server kann ein KI-Assistent REST-Ausgaben einrichten und testen:
add_devicemitprotocol: "Rest"; alsipdarf eine vollständige Basis-URL stehenset_rest_configsetzt URL, Methode, Header, Timeout, Modus, Rate und Skriptpreview_rest_requestzeigt die Requests für die aktuellen Farben, ohne zu sendensend_rest_devicesendet sofort, auch im Modus Einmaligadd_segmentmitlua_sourcelegt ein eigenes Skript in die Timeline, etwa eines mitrest_get
Hinweise und Grenzen
- Antworten werden nicht ausgewertet. Statuscodes ab 400 und Verbindungsfehler zählen als fehlgeschlagen und stehen höchstens alle 5 Sekunden pro Gerät im Protokoll (
app.log). - REST-Geräte sind nicht Teil der Exporte (
.scn,.artnet, TPM2, WLED) und tauchen in der Geräteauswahl des Export-Dialogs nicht auf. - Die Farbreihenfolge eines Fixtures gilt für REST nicht. Das Skript spricht die Kanäle über ihre Namen an.
- Tragen zwei REST-Geräte denselben Namen, verwendet
rest_getdas zuletzt angelegte. - WLED wendet unter Umständen selbst noch eine Gammakorrektur an. Wirken dunkle Töne zu dunkel, kannst du sie im Skript anheben.