Merge remote-tracking branch 'origin/montana-black-shield' into merge-probe

* origin/montana-black-shield:
  docs(bulb-map): Montana-Black-Shield (f960) ergaenzt
  chore(tools): qconnex-Migrationswerkzeug und HA-Integration ins Repo
  feat(station): Montana-Black-Produkt-ID -> Ziel ledshield_rgb
  feat(board): ledshield_rgb — Montana Black RGB-LED-Shield (analoge RGB-Streifen)
  build: tools/podman.sh — docker.sh-Pendant für podman (gleiches Image, gleicher Mount)
  Überträgt lokale Änderungen (nl_crc8 unsigned-shift, docker.sh cd -P) in neuen Top-Level-Tree und entfernt altes ninlight-w600/
  Initial commit
This commit is contained in:
Michael Sauer
2026-09-26 17:18:27 +02:00
38 changed files with 1260 additions and 26 deletions
+17 -7
View File
@@ -5,12 +5,12 @@
void setUp(void) {}
void tearDown(void) {}
static const char *IDS[] = {"evk", "e27_rgb", "e14_rgb", "gu10_rgb", "e27_cw", "e14_cw", "gu10_cw", "g95_cw"};
static const char *IDS[] = {"evk", "e27_rgb", "e14_rgb", "gu10_rgb", "e27_cw", "e14_cw", "gu10_cw", "g95_cw", "ledshield_rgb"};
static void test_all_devices_present(void)
{
TEST_ASSERT_EQUAL_UINT(8, nl_boards_count);
for (size_t i = 0; i < 8; i++) {
TEST_ASSERT_EQUAL_UINT(9, nl_boards_count);
for (size_t i = 0; i < 9; i++) {
const nl_board_t *b = nl_board_find(IDS[i]);
TEST_ASSERT_NOT_NULL_MESSAGE(b, IDS[i]);
TEST_ASSERT_EQUAL_STRING(IDS[i], b->id);
@@ -34,9 +34,12 @@ static void test_rgb_flags_and_ct_ranges(void)
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;
/* ledshield_rgb has no white LEDs at all: ct_min == ct_max is the
sentinel "white mode renders as an RGB mix" (see nl_color.c). */
bool shield = strcmp(b->id, "ledshield_rgb") == 0;
TEST_ASSERT_EQUAL_MESSAGE(rgb, b->has_rgb, b->id);
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);
TEST_ASSERT_EQUAL_UINT16_MESSAGE(shield ? 4000 : (g95 ? 2000 : 2700), b->ct_min, b->id);
TEST_ASSERT_EQUAL_UINT16_MESSAGE(shield ? 4000 : (g95 ? 5000 : 6500), b->ct_max, b->id);
}
}
@@ -47,8 +50,15 @@ static void test_pwm_boards_consistent(void)
if (b->driver != NL_DRV_PWM)
continue;
TEST_ASSERT_TRUE(b->pwm_freq_hz > 0);
TEST_ASSERT_TRUE(b->pwm[NL_CH_CW].pwm_ch >= 0);
TEST_ASSERT_TRUE(b->pwm[NL_CH_WW].pwm_ch >= 0);
if (b->ct_min == b->ct_max) {
/* RGB-only board: white is an RGB mix, no white channels wired. */
TEST_ASSERT_TRUE(b->has_rgb);
TEST_ASSERT_EQUAL(-1, b->pwm[NL_CH_CW].pwm_ch);
TEST_ASSERT_EQUAL(-1, b->pwm[NL_CH_WW].pwm_ch);
} else {
TEST_ASSERT_TRUE(b->pwm[NL_CH_CW].pwm_ch >= 0);
TEST_ASSERT_TRUE(b->pwm[NL_CH_WW].pwm_ch >= 0);
}
for (int c = NL_CH_R; c <= NL_CH_B; c++)
TEST_ASSERT_EQUAL_MESSAGE(b->has_rgb, b->pwm[c].pwm_ch >= 0, b->id);
for (int c = 0; c < NL_CH_COUNT; c++) {