feat: Default-Transition, Weckschalter und farbfreier Ausschaltfade

Zwei neue Einstellungen, beide wie fade_in/fade_out ueber
POST /api/v1/device/state les- und schreibbar und sofort wirksam:

- transition_default (Voreinstellung 300 ms) fuellt die Transition fuer
  Farb-, Weiss- und Helligkeitswechsel bei eingeschalteter Lampe, wenn der
  Aufruf kein eigenes "transition" mitbringt. Beim Ein- und Ausschalten
  behalten fade_in/fade_out weiterhin Vorrang.
- wake_on_change (Voreinstellung aus) schaltet die Lampe bei einer Farb-,
  Weiss- oder Helligkeitsaenderung ein, wenn sie aus war. Ein
  ausdrueckliches "on": false im selben Aufruf gewinnt immer.

Beide Felder haengen am Ende von nl_settings_t, damit bestehende Lampen
ueber die Laengentoleranz von read_rec() ihre echten Voreinstellungen
bekommen statt Nullen. nl_ctrl_set_fades() heisst jetzt
nl_ctrl_set_options().

Dazu ein Treiberfehler, der erst an der migrierten GU10 RGB auffiel: der
WY-Zweig von nl_sm2135eh_set() schrieb nur Header und WY-Daten, nie die
RGB-Datenregister. Der Chip behielt also die zuletzt gesetzte Farbe, und
bei einem direkten Wechsel Farbe -> Weiss (ohne Zwischenschritt ueber
dunkel) schaelte sie sich beim Ausblenden wieder frei. Der Header sendet
jetzt die - in Weiss immer nullwertigen - RGB-Daten mit.

Die Bruno-Collection zeigt Transition jetzt zusammen mit einem Farb- und
einem Weisswechsel im selben Aufruf und hat einen Request fuer die
beiden neuen Einstellungen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Michael Sauer
2026-09-13 02:56:56 +02:00
co-authored by Claude Opus 5
parent 62a2b43175
commit 00d5a4c532
13 changed files with 256 additions and 19 deletions
+16
View File
@@ -115,6 +115,11 @@ static cJSON *state_json(const nl_api_ctx_t *ctx)
POB_NAMES[s.power_on_behaviour <= NL_POB_OFF ? s.power_on_behaviour : NL_POB_LAST]);
cJSON_AddNumberToObject(o, "fade_in", s.fade_in_ms);
cJSON_AddNumberToObject(o, "fade_out", s.fade_out_ms);
/* Named "transition_default", not "transition": the latter is already the per-call field
* above the settings section of this same request/response and a second field with the
* same key in one JSON object would collide with it. */
cJSON_AddNumberToObject(o, "transition_default", s.transition_ms);
cJSON_AddBoolToObject(o, "wake_on_change", s.wake_on_change != 0);
cap = cJSON_AddObjectToObject(o, "capabilities");
cJSON_AddBoolToObject(cap, "color", ctx->board->has_rgb);
ct[0] = ctx->board->ct_min;
@@ -193,6 +198,17 @@ static void handle_post_state(const nl_api_ctx_t *ctx, const nl_http_request_t *
case 1: s.fade_out_ms = (uint16_t)v; settings = true; break;
default: break;
}
switch (get_int(j, "transition_default", 0, NL_MAX_TRANSITION_MS, &v)) {
case -1: err = "invalid transition_default"; goto out;
case 1: s.transition_ms = (uint16_t)v; settings = true; break;
default: break;
}
it = cJSON_GetObjectItemCaseSensitive(j, "wake_on_change");
if (it) {
if (!cJSON_IsBool(it)) { err = "invalid wake_on_change"; goto out; }
s.wake_on_change = cJSON_IsTrue(it) ? 1u : 0u;
settings = true;
}
if (light) {
switch (ctx->apply(&ch)) {