#!/usr/bin/env python3 """Tests fuer die Helligkeitsregelung (verallgemeinert aus DoDimmen_V). python3 -m unittest -v test_brightness Grenzen am Geraet gemessen (2026-07-27): Mitten (1200, 2400, 3200) mit einheitlicher Hysterese 150 -> hoch bei 1350 / 2550 / 3350, runter bei 1050 / 2250 / 3050. Die Zahlen stehen bewusst ausgeschrieben statt aus brightness.* gerechnet: So faellt eine versehentliche Aenderung der Schwellen im Test auf, statt stillschweigend mitzuwandern. """ import unittest import brightness from brightness import BrightnessController class TestStufen(unittest.TestCase): def setUp(self): self.c = BrightnessController() def test_erststart_schaltet_von_0_hoch(self): self.assertEqual(self.c._next_level(1349, None), 0) self.assertEqual(self.c._next_level(1350, None), 1) self.assertEqual(self.c._next_level(2549, None), 1) self.assertEqual(self.c._next_level(2550, None), 2) self.assertEqual(self.c._next_level(3349, None), 2) self.assertEqual(self.c._next_level(3350, None), 3) # 100 % erreichbar def test_hysterese_von_stufe_1(self): self.assertEqual(self.c._next_level(1050, 1), 1) self.assertEqual(self.c._next_level(1049, 1), 0) self.assertEqual(self.c._next_level(2549, 1), 1) self.assertEqual(self.c._next_level(2550, 1), 2) def test_hysterese_von_stufe_2(self): self.assertEqual(self.c._next_level(2250, 2), 2) self.assertEqual(self.c._next_level(2249, 2), 1) self.assertEqual(self.c._next_level(3349, 2), 2) self.assertEqual(self.c._next_level(3350, 2), 3) def test_hysterese_von_stufe_3(self): self.assertEqual(self.c._next_level(3050, 3), 3) self.assertEqual(self.c._next_level(3049, 3), 2) def test_prozente(self): self.assertEqual(brightness.PERCENTS, (5, 15, 50, 100)) def test_gemessene_lagen_ergeben_die_gewollten_stufen(self): """Die am Geraet gemessenen Lichtlagen, in Stufen uebersetzt. Das ist der eigentliche Zweck der Kalibrierung: abgedeckt muss auf die dunkelste Stufe fallen, angeleuchtet auf die hellste. Beides ging mit den alten MSP430-Schwellen daneben (100 % war unerreichbar). """ self.assertEqual(self.c._next_level(0, None), 0) # abgedeckt -> 5 % self.assertEqual(self.c._next_level(3552, None), 3) # Lampe -> 100 % def test_raumlicht_liegt_dicht_an_der_grenze(self): """Bekannte Grenzlage, absichtlich festgehalten. Der gemessene Raumlichtwert 2453 liegt nur 53 Zaehler ueber HELL_HIGH (2400) und damit unter der Hysterese: Hochgeschaltet wird erst ab 2550, also bleibt Raumlicht auf Stufe 1 (15 %). Eine Stufengrenze so dicht an einem realen Betriebspunkt ist keine gute Stelle -- welche Stufe dort gewollt ist, entscheidet sich erst an den Lichtverhaeltnissen in der Sternwarte. Bis dahin haelt dieser Test das Verhalten schriftlich fest, damit es niemanden ueberrascht. """ self.assertEqual(self.c._next_level(2453, None), 1) self.assertLess(abs(2453 - brightness.HELL_HIGH), brightness.HELL_HYST) def test_hysterese_ueberdeckt_das_gemessene_rauschen(self): """Nach dem gleitenden Mittel bleiben rund 32 Zaehler Streuung (1 Sigma). Die Hysterese muss deutlich darueber liegen, sonst springt die Stufe an einer Grenze hin und her -- genau das waere mit den alten 30 passiert. """ self.assertGreaterEqual(brightness.HELL_HYST, 100) def test_kein_stufensprung_bei_rauschen_um_eine_grenze(self): """Werte, die um eine Stufengrenze streuen, duerfen die Stufe halten.""" c = BrightnessController() for _ in range(brightness.AVERAGE_WINDOW): c.update(1200) # genau auf der Grenze einschwingen stufe_vorher = c.level for delta in (+60, -60, +55, -50, +45, -60, +60, -55): stufe, _, changed = c.update(1200 + delta) self.assertFalse(changed, "Rauschen um die Grenze hat umgeschaltet") self.assertEqual(stufe, stufe_vorher) class TestUpdate(unittest.TestCase): def test_erste_aenderung_meldet_changed(self): c = BrightnessController() self.assertEqual(c.update(100), (0, 5, True)) def test_gleicher_wert_keine_aenderung(self): c = BrightnessController() c.update(100) level, percent, changed = c.update(100) self.assertFalse(changed) self.assertEqual(percent, 5) def test_dunkel_zu_hell_erreicht_100(self): c = BrightnessController() c.update(100) level = percent = None for _ in range(brightness.AVERAGE_WINDOW + 2): level, percent, _ = c.update(4000) self.assertEqual(level, 3) self.assertEqual(percent, 100) def test_gleitender_mittelwert_fenster(self): c = BrightnessController() for _ in range(20): c.update(1000) self.assertLessEqual(len(c._buf), brightness.AVERAGE_WINDOW) if __name__ == "__main__": unittest.main(verbosity=2)