Merge branch 'main' into plan-4c-migrationsstation

* main:
  fix(board): Farbtemperaturbereiche der Weiss-Varianten korrigieren
This commit is contained in:
Michael Sauer
2026-09-14 01:40:30 +02:00
4 changed files with 22 additions and 12 deletions
+2 -2
View File
@@ -62,8 +62,8 @@ Für den echten Flottenbau `NINLIGHT_RECOVERY_PASSWORD` und `NINLIGHT_TOKEN` in
- [x] SM2135EH: Standby-Bit bei allen Kanälen 0 — 2026-09-13 an migrierter GU10 RGB geprüft: **war ein echter Fehler**, die Lampe glomm im Aus weiter. Bit 5 im Kanal-Register wird jetzt gesetzt (Commit zu v0.3.8); danach beide Ausschaltwege (aus Weiß und aus Farbe) vollständig dunkel
- [ ] E27 Color (SM2135EH): RGB und WY getrennt, Ströme plausibel (nicht zu heiß) — *derselbe Treiber ist am 2026-09-13 an einer GU10 RGB geprüft (rot/grün/blau sauber getrennt, warm- und kaltweiß deutlich unterschieden); für die E27 selbst steht die Prüfung noch aus*
- [ ] E27 CW: Gegenphase CW sichtbar flackerfrei
- [x] G95: Pinbelegung WW=PB15/CW=PB13 — 2026-09-13 an einer migrierten G95 geprüft: 2500 K deutlich warm, 5000 K deutlich kühler, Dimmen auf 10 % flackerfrei, weiches Ausblenden
- [ ] Farbtemperaturbereiche aller Varianten — *g95_cw (2500–5000 K) und gu10_rgb (2700–6500 K) am 2026-09-13 an echten Lampen bestätigt; die übrigen sechs Varianten stehen aus*
- [x] G95: Pinbelegung WW=PB15/CW=PB13 — 2026-09-13 an einer migrierten G95 geprüft: unteres Bereichsende deutlich warm, oberes deutlich kühler (damals noch 2500–5000 K, inzwischen 2000–5000 K), Dimmen auf 10 % flackerfrei, weiches Ausblenden
- [ ] Farbtemperaturbereiche aller Varianten — *die Bereiche stammen seit 2026-09-13 von Michael aus den Produktdaten und stehen so in `nl_board.c`: G95 Vintage **2000–5000 K**, alle übrigen **2700–6500 K**. Vorher standen die vier Weiß-Varianten flach auf 2500–5000 K, was für die E27/E14/GU10 CW den oberen Bereich abgeschnitten und für die G95 den unteren verschenkt hat. Am Gerät gegengeprüft ist bisher nur gu10_rgb; die G95 wurde mit den alten Grenzen getestet und gehört an den neuen wiederholt.*
## Offene Beobachtung aus der EVK-Session vom 2026-09-12
+4 -4
View File
@@ -21,15 +21,15 @@ const nl_board_t nl_boards[] = {
{NONE, NONE, NONE, NONE, NONE}, NL_PB(8), NL_PB(13), 0x73},
{"gu10_rgb", "Klyqa GU10 RGB CW/WW", NL_DRV_SM2135EH, true, 2700, 6500, 0,
{NONE, NONE, NONE, NONE, NONE}, NL_PB(8), NL_PB(13), 0x63},
{"e27_cw", "Klyqa E27 CW/WW", NL_DRV_PWM, false, 2500, 5000, 600,
{"e27_cw", "Klyqa E27 CW/WW", NL_DRV_PWM, false, 2700, 6500, 600,
{NONE, NONE, NONE, CHA(1, NL_PB(13)), CH(4, NL_PB(8))}, NO_SM},
{"e14_cw", "Klyqa E14 CW/WW", NL_DRV_PWM, false, 2500, 5000, 600,
{"e14_cw", "Klyqa E14 CW/WW", NL_DRV_PWM, false, 2700, 6500, 600,
{NONE, NONE, NONE, CH(2, NL_PB(16)), CH(4, NL_PB(8))}, NO_SM},
{"gu10_cw", "Klyqa GU10 CW/WW", NL_DRV_PWM, false, 2500, 5000, 600,
{"gu10_cw", "Klyqa GU10 CW/WW", NL_DRV_PWM, false, 2700, 6500, 600,
{NONE, NONE, NONE, CH(2, NL_PB(16)), CH(4, NL_PB(8))}, NO_SM},
/* G95: current table: CW=PB13, WW=PB15 (new assignment); old bulbs may use
* PB16=WW, PB15=CW - verify on a series bulb. */
{"g95_cw", "Klyqa G95 Vintage CW/WW", NL_DRV_PWM, false, 2500, 5000, 600,
{"g95_cw", "Klyqa G95 Vintage CW/WW", NL_DRV_PWM, false, 2000, 5000, 600,
{NONE, NONE, NONE, CH(1, NL_PB(13)), CH(3, NL_PB(15))}, NO_SM},
};
+7 -2
View File
@@ -29,9 +29,14 @@ static void test_rgb_flags_and_ct_ranges(void)
for (size_t i = 0; i < nl_boards_count; i++) {
const nl_board_t *b = &nl_boards[i];
bool rgb = strstr(b->id, "rgb") != NULL || strcmp(b->id, "evk") == 0;
/* Measured on real bulbs, 2026-09-13: every lamp but the G95 covers 2700..6500 K.
The G95 Vintage is a warm bulb and reaches 2000 K at the bottom but stops at
5000 K - hard-coded per board rather than derived, because "warm variant" is a
property of that one product, not of a class of them. */
bool g95 = strcmp(b->id, "g95_cw") == 0;
TEST_ASSERT_EQUAL_MESSAGE(rgb, b->has_rgb, b->id);
TEST_ASSERT_EQUAL_UINT16(rgb ? 2700 : 2500, b->ct_min);
TEST_ASSERT_EQUAL_UINT16(rgb ? 6500 : 5000, b->ct_max);
TEST_ASSERT_EQUAL_UINT16_MESSAGE(g95 ? 2000 : 2700, b->ct_min, b->id);
TEST_ASSERT_EQUAL_UINT16_MESSAGE(g95 ? 5000 : 6500, b->ct_max, b->id);
}
}
+9 -4
View File
@@ -55,11 +55,15 @@ static void test_off_forces_off(void)
static void test_sanitizes_stored_values(void)
{
const nl_board_t *b = nl_board_find("e27_cw");
nl_light_state_t last = {true, 0, NL_MODE_COLOR, 1, 2, 3, 9000};
nl_light_state_t s = nl_boot_state(NL_POB_LAST, &last, nl_board_find("e27_cw"), false);
nl_light_state_t s = nl_boot_state(NL_POB_LAST, &last, b, false);
TEST_ASSERT_EQUAL_UINT8(100, s.brightness); /* invalid 0 -> 100 */
TEST_ASSERT_EQUAL(NL_MODE_WHITE, s.mode); /* no RGB on this board */
TEST_ASSERT_EQUAL_UINT16(5000, s.ct); /* clamped */
/* Clamped to whatever this board can do. Deliberately read from the board instead of
repeating the number: the range itself is nailed down in test_board.c, and this test
is about the clamping, not about the constant. */
TEST_ASSERT_EQUAL_UINT16(b->ct_max, s.ct);
}
/* Spec 8.2: a reboot caused by an OTA is not a power cut - the light comes back effectively as
@@ -84,12 +88,13 @@ static void test_after_ota_ignores_pob_on(void)
static void test_after_ota_still_sanitizes(void)
{
const nl_board_t *b = nl_board_find("e27_cw");
nl_light_state_t last = {true, 200, NL_MODE_COLOR, 1, 2, 3, 9000};
nl_light_state_t s = nl_boot_state(NL_POB_OFF, &last, nl_board_find("e27_cw"), true);
nl_light_state_t s = nl_boot_state(NL_POB_OFF, &last, b, true);
TEST_ASSERT_TRUE(s.on);
TEST_ASSERT_EQUAL_UINT8(100, s.brightness);
TEST_ASSERT_EQUAL(NL_MODE_WHITE, s.mode);
TEST_ASSERT_EQUAL_UINT16(5000, s.ct);
TEST_ASSERT_EQUAL_UINT16(b->ct_max, s.ct);
}
/* Nothing stored (first boot after a migration): there is no "last" to restore, so the normal