539 lines
16 KiB
YAML
539 lines
16 KiB
YAML
opencollection: 1.0.0
|
|
info:
|
|
name: ninlight
|
|
config:
|
|
environments:
|
|
- name: EVK (mDNS)
|
|
variables:
|
|
- name: device_address
|
|
value: ninlight-681f.local
|
|
- name: device_port
|
|
value: '3333'
|
|
- name: device_token
|
|
value: aabbccddeeff0011223344
|
|
- name: ota_url
|
|
value: http://192.168.1.12:8000/ninlight_evk_ota.img
|
|
- name: Onboarding-AP
|
|
variables:
|
|
- name: device_address
|
|
value: 192.168.4.1
|
|
- name: device_port
|
|
value: '3333'
|
|
- name: device_token
|
|
value: aabbccddeeff0011223344
|
|
- name: ota_url
|
|
value: http://192.168.1.12:8000/ninlight_evk_ota.img
|
|
items:
|
|
- info:
|
|
name: Device
|
|
type: folder
|
|
seq: 1
|
|
items:
|
|
- info:
|
|
name: Get State
|
|
type: http
|
|
seq: 1
|
|
http:
|
|
method: GET
|
|
url: '{{device_address}}:{{device_port}}/api/v1/device/state'
|
|
settings:
|
|
encodeUrl: true
|
|
timeout: 0
|
|
followRedirects: true
|
|
maxRedirects: 5
|
|
- info:
|
|
name: Power On
|
|
type: http
|
|
seq: 2
|
|
http:
|
|
method: POST
|
|
url: '{{device_address}}:{{device_port}}/api/v1/device/state'
|
|
body:
|
|
type: json
|
|
data: |-
|
|
{
|
|
"on": true
|
|
}
|
|
settings:
|
|
encodeUrl: true
|
|
timeout: 0
|
|
followRedirects: true
|
|
maxRedirects: 5
|
|
- info:
|
|
name: Power Off
|
|
type: http
|
|
seq: 3
|
|
http:
|
|
method: POST
|
|
url: '{{device_address}}:{{device_port}}/api/v1/device/state'
|
|
body:
|
|
type: json
|
|
data: |-
|
|
{
|
|
"on": false
|
|
}
|
|
settings:
|
|
encodeUrl: true
|
|
timeout: 0
|
|
followRedirects: true
|
|
maxRedirects: 5
|
|
- info:
|
|
name: Brightness 50
|
|
type: http
|
|
seq: 4
|
|
http:
|
|
method: POST
|
|
url: '{{device_address}}:{{device_port}}/api/v1/device/state'
|
|
body:
|
|
type: json
|
|
data: |-
|
|
{
|
|
"brightness": 50
|
|
}
|
|
settings:
|
|
encodeUrl: true
|
|
timeout: 0
|
|
followRedirects: true
|
|
maxRedirects: 5
|
|
- info:
|
|
name: Color Red + Transition
|
|
type: http
|
|
seq: 5
|
|
http:
|
|
method: POST
|
|
url: '{{device_address}}:{{device_port}}/api/v1/device/state'
|
|
body:
|
|
type: json
|
|
data: |-
|
|
{
|
|
"color": {
|
|
"r": 255,
|
|
"g": 0,
|
|
"b": 0
|
|
},
|
|
"transition": 1500
|
|
}
|
|
settings:
|
|
encodeUrl: true
|
|
timeout: 0
|
|
followRedirects: true
|
|
maxRedirects: 5
|
|
- info:
|
|
name: Color Temp 2700 + Transition
|
|
type: http
|
|
seq: 6
|
|
http:
|
|
method: POST
|
|
url: '{{device_address}}:{{device_port}}/api/v1/device/state'
|
|
body:
|
|
type: json
|
|
data: |-
|
|
{
|
|
"color_temp": 2700,
|
|
"transition": 1500
|
|
}
|
|
settings:
|
|
encodeUrl: true
|
|
timeout: 0
|
|
followRedirects: true
|
|
maxRedirects: 5
|
|
- info:
|
|
name: Fade to 100 % in 3 s
|
|
type: http
|
|
seq: 7
|
|
http:
|
|
method: POST
|
|
url: '{{device_address}}:{{device_port}}/api/v1/device/state'
|
|
body:
|
|
type: json
|
|
data: |-
|
|
{
|
|
"on": true,
|
|
"brightness": 100,
|
|
"transition": 3000
|
|
}
|
|
settings:
|
|
encodeUrl: true
|
|
timeout: 0
|
|
followRedirects: true
|
|
maxRedirects: 5
|
|
- info:
|
|
name: Power-On Behaviour
|
|
type: http
|
|
seq: 8
|
|
http:
|
|
method: POST
|
|
url: '{{device_address}}:{{device_port}}/api/v1/device/state'
|
|
body:
|
|
type: json
|
|
data: |-
|
|
{
|
|
"power_on_behaviour": "last"
|
|
}
|
|
settings:
|
|
encodeUrl: true
|
|
timeout: 0
|
|
followRedirects: true
|
|
maxRedirects: 5
|
|
- info:
|
|
name: Fade Times
|
|
type: http
|
|
seq: 9
|
|
http:
|
|
method: POST
|
|
url: '{{device_address}}:{{device_port}}/api/v1/device/state'
|
|
body:
|
|
type: json
|
|
data: |-
|
|
{
|
|
"fade_in": 500,
|
|
"fade_out": 800
|
|
}
|
|
settings:
|
|
encodeUrl: true
|
|
timeout: 0
|
|
followRedirects: true
|
|
maxRedirects: 5
|
|
- info:
|
|
name: Default Transition + Wake Switch
|
|
type: http
|
|
seq: 10
|
|
http:
|
|
method: POST
|
|
url: '{{device_address}}:{{device_port}}/api/v1/device/state'
|
|
body:
|
|
type: json
|
|
data: |-
|
|
{
|
|
"transition_default": 300,
|
|
"wake_on_change": false
|
|
}
|
|
settings:
|
|
encodeUrl: true
|
|
timeout: 0
|
|
followRedirects: true
|
|
maxRedirects: 5
|
|
- info:
|
|
name: System
|
|
type: folder
|
|
seq: 2
|
|
items:
|
|
- info:
|
|
name: Get System Info
|
|
type: http
|
|
seq: 1
|
|
http:
|
|
method: GET
|
|
url: '{{device_address}}:{{device_port}}/api/v1/system/info'
|
|
settings:
|
|
encodeUrl: true
|
|
timeout: 0
|
|
followRedirects: true
|
|
maxRedirects: 5
|
|
docs: |-
|
|
Enthält `last_ota_error`: `null`, solange kein Update fehlgeschlagen ist, sonst einer von
|
|
`download`, `crc`, `trailer`, `device_mismatch`, `hash`, `busy` (`busy` heißt: es läuft bereits
|
|
ein Update). Kein `reset_reason` mehr im Feld-Satz.
|
|
|
|
`wifi.standalone` unterscheidet den dauerhaften eigenen Zugangspunkt vom
|
|
Onboarding-AP - `wifi.mode` ist bei beiden `"ap"`. Im AP-Betrieb steht unter
|
|
`wifi.ssid` der **laufende** AP-Name, nicht die gespeicherte Stations-SSID; der
|
|
Name des Heimnetzes steht damit nicht in dieser tokenfrei lesbaren Antwort.
|
|
|
|
`sacn.running` sagt, ob der Empfangs-Task lebt und einen Socket haelt - zusammen
|
|
mit `sacn.active` (es kommt gerade ein gueltiger Strom an) und `sacn.multicast`
|
|
(der letzte Gruppenbeitritt hat geklappt) ist damit unterscheidbar, ob niemand
|
|
sendet oder ob der Empfang tot ist.
|
|
- info:
|
|
name: Get System Settings
|
|
type: http
|
|
seq: 2
|
|
http:
|
|
method: GET
|
|
url: '{{device_address}}:{{device_port}}/api/v1/system/settings'
|
|
settings:
|
|
encodeUrl: true
|
|
timeout: 0
|
|
followRedirects: true
|
|
maxRedirects: 5
|
|
docs: |-
|
|
`wifi.source` ist `"stored"`, solange ein per PUT onboardetes WLAN gespeichert ist,
|
|
sonst `"compiled"` - dann laeuft die Lampe auf den einkompilierten
|
|
NINLIGHT_WIFI_SSID/-PASSWORD, `wifi.ssid` ist leer, und `GET system/info` kann trotzdem
|
|
eine verbundene SSID zeigen.
|
|
|
|
Der `standalone`-Block zeigt `enabled`, den **gewuenschten** AP-Namen (`ssid`: der
|
|
gespeicherte, ohne eigenen der Hostname), `channel` und `pulse`. Das AP-Passwort
|
|
steht nie darin. Der gewuenschte Name kann vom laufenden abweichen, den
|
|
`GET system/info` meldet - genau das ist das Erkennungsmerkmal fuer einen Rueckfall
|
|
auf die Vorgaben nach mehrfach gescheitertem AP-Aufbau.
|
|
- info:
|
|
name: Set WiFi
|
|
type: http
|
|
seq: 3
|
|
http:
|
|
method: PUT
|
|
url: '{{device_address}}:{{device_port}}/api/v1/system/settings'
|
|
body:
|
|
type: json
|
|
data: |-
|
|
{
|
|
"type": "wifi",
|
|
"ssid": "MeinWLAN",
|
|
"password": "geheim123"
|
|
}
|
|
settings:
|
|
encodeUrl: true
|
|
timeout: 0
|
|
followRedirects: true
|
|
maxRedirects: 5
|
|
- info:
|
|
name: Set Device Name
|
|
type: http
|
|
seq: 4
|
|
http:
|
|
method: PUT
|
|
url: '{{device_address}}:{{device_port}}/api/v1/system/settings'
|
|
body:
|
|
type: json
|
|
data: |-
|
|
{
|
|
"type": "device_name",
|
|
"name": "Wohnzimmer"
|
|
}
|
|
settings:
|
|
encodeUrl: true
|
|
timeout: 0
|
|
followRedirects: true
|
|
maxRedirects: 5
|
|
- info:
|
|
name: Set Token
|
|
type: http
|
|
seq: 5
|
|
http:
|
|
method: PUT
|
|
url: '{{device_address}}:{{device_port}}/api/v1/system/settings'
|
|
body:
|
|
type: json
|
|
data: |-
|
|
{
|
|
"type": "token",
|
|
"token": "neues-token-123"
|
|
}
|
|
settings:
|
|
encodeUrl: true
|
|
timeout: 0
|
|
followRedirects: true
|
|
maxRedirects: 5
|
|
- info:
|
|
name: Require Auth for All
|
|
type: http
|
|
seq: 6
|
|
http:
|
|
method: PUT
|
|
url: '{{device_address}}:{{device_port}}/api/v1/system/settings'
|
|
body:
|
|
type: json
|
|
data: |-
|
|
{
|
|
"type": "auth",
|
|
"all": true
|
|
}
|
|
settings:
|
|
encodeUrl: true
|
|
timeout: 0
|
|
followRedirects: true
|
|
maxRedirects: 5
|
|
- info:
|
|
name: Set sACN
|
|
type: http
|
|
seq: 7
|
|
http:
|
|
method: PUT
|
|
url: '{{device_address}}:{{device_port}}/api/v1/system/settings'
|
|
body:
|
|
type: json
|
|
data: |-
|
|
{
|
|
"type": "sacn",
|
|
"enabled": true,
|
|
"universe": 1,
|
|
"start_slot": 1,
|
|
"on_timeout": "release"
|
|
}
|
|
settings:
|
|
encodeUrl: true
|
|
timeout: 0
|
|
followRedirects: true
|
|
maxRedirects: 5
|
|
- info:
|
|
name: Standalone einschalten
|
|
type: http
|
|
seq: 8
|
|
http:
|
|
method: PUT
|
|
url: '{{device_address}}:{{device_port}}/api/v1/system/settings'
|
|
body:
|
|
type: json
|
|
data: |-
|
|
{
|
|
"type": "standalone",
|
|
"enabled": true,
|
|
"password": "geheim123",
|
|
"ssid": "Buehne",
|
|
"channel": 6,
|
|
"pulse": true
|
|
}
|
|
settings:
|
|
encodeUrl: true
|
|
timeout: 0
|
|
followRedirects: true
|
|
maxRedirects: 5
|
|
docs: |-
|
|
Die Lampe spannt dauerhaft einen eigenen Zugangspunkt auf, statt sich in ein WLAN
|
|
einzuwaehlen - danach ist sie unter `192.168.4.1` erreichbar, per mDNS als
|
|
`<hostname>.local`. Antwort **202** `{"status":"standalone"}`, nicht 200: die
|
|
Antwort muss das Geraet verlassen haben, bevor das Netz unter der Verbindung
|
|
weggezogen wird.
|
|
|
|
`password` ist beim Einschalten Pflicht, solange keines gespeichert ist (8..63
|
|
Zeichen). `ssid` (1..32), `channel` (1..13, Vorgabe 6) und `pulse` sind optional
|
|
und behalten sonst ihren gespeicherten Wert; ein leerer `ssid`-String wird mit 400
|
|
`invalid ssid` abgelehnt.
|
|
|
|
**Achtung beim Ausprobieren:** Aenderst du Name oder Passwort, waehrend du ueber
|
|
genau diesen AP verbunden bist, baut die Lampe ihn neu auf und wirft dich hinaus -
|
|
die 202 kommt noch an, danach musst du dem neuen Netz beitreten.
|
|
|
|
Anders als der unkonfigurierte Onboarding-AP ist der Standalone-AP **nicht**
|
|
token-frei: ab da gilt der Tokenschutz wie im Normalbetrieb.
|
|
- info:
|
|
name: Standalone ausschalten
|
|
type: http
|
|
seq: 9
|
|
http:
|
|
method: PUT
|
|
url: '{{device_address}}:{{device_port}}/api/v1/system/settings'
|
|
body:
|
|
type: json
|
|
data: |-
|
|
{
|
|
"type": "standalone",
|
|
"enabled": false
|
|
}
|
|
settings:
|
|
encodeUrl: true
|
|
timeout: 0
|
|
followRedirects: true
|
|
maxRedirects: 5
|
|
docs: |-
|
|
Braucht kein Passwort. Hat die Lampe gespeicherte WLAN-Daten, waehlt sie sich damit
|
|
wieder ein; ohne solche oeffnet sie den unkonfigurierten Onboarding-AP
|
|
`ninlight-<mac4>` - der ist dann wieder token-frei.
|
|
|
|
Der gespeicherte AP-Name bleibt dabei in den Einstellungen stehen und greift beim
|
|
naechsten Einschalten des Modus erneut.
|
|
- info:
|
|
name: Commands
|
|
type: folder
|
|
seq: 10
|
|
items:
|
|
- info:
|
|
name: Ping
|
|
type: http
|
|
seq: 1
|
|
http:
|
|
method: PUT
|
|
url: '{{device_address}}:{{device_port}}/api/v1/system/command'
|
|
body:
|
|
type: json
|
|
data: |-
|
|
{
|
|
"command": {
|
|
"type": "ping"
|
|
}
|
|
}
|
|
settings:
|
|
encodeUrl: true
|
|
timeout: 0
|
|
followRedirects: true
|
|
maxRedirects: 5
|
|
- info:
|
|
name: Reboot
|
|
type: http
|
|
seq: 2
|
|
http:
|
|
method: PUT
|
|
url: '{{device_address}}:{{device_port}}/api/v1/system/command'
|
|
body:
|
|
type: json
|
|
data: |-
|
|
{
|
|
"command": {
|
|
"type": "reboot"
|
|
}
|
|
}
|
|
settings:
|
|
encodeUrl: true
|
|
timeout: 0
|
|
followRedirects: true
|
|
maxRedirects: 5
|
|
- info:
|
|
name: Factory Reset
|
|
type: http
|
|
seq: 3
|
|
http:
|
|
method: PUT
|
|
url: '{{device_address}}:{{device_port}}/api/v1/system/command'
|
|
body:
|
|
type: json
|
|
data: |-
|
|
{
|
|
"command": {
|
|
"type": "factory_reset"
|
|
}
|
|
}
|
|
settings:
|
|
encodeUrl: true
|
|
timeout: 0
|
|
followRedirects: true
|
|
maxRedirects: 5
|
|
- info:
|
|
name: Firmware Update
|
|
type: http
|
|
seq: 4
|
|
http:
|
|
method: PUT
|
|
url: '{{device_address}}:{{device_port}}/api/v1/system/command'
|
|
body:
|
|
type: json
|
|
data: |-
|
|
{
|
|
"command": {
|
|
"type": "fw_update",
|
|
"url": "{{ota_url}}"
|
|
}
|
|
}
|
|
settings:
|
|
encodeUrl: true
|
|
timeout: 0
|
|
followRedirects: true
|
|
maxRedirects: 5
|
|
docs: |-
|
|
Erfolg: `202 {"status":"updating"}`, Download startet im Hintergrund. Ungültige URL (kein
|
|
`http://`-Präfix, zu kurz/lang): `400`. Läuft bereits ein Update oder scheitert der Start
|
|
sonstwie: `409` mit dem Grund im Body (gleicher Wert wie `last_ota_error`, z.B. `"busy"`).
|
|
request:
|
|
headers:
|
|
- name: Authorization
|
|
value: '{{device_token}}'
|
|
bundled: true
|
|
extensions:
|
|
bruno:
|
|
ignore:
|
|
- node_modules
|
|
- .git
|
|
presets:
|
|
requestType: http
|
|
requestUrl: '{{device_address}}:{{device_port}}/api/v1/'
|