Hell oder nicht hell – das ist hier die Frage
Mein Problem: Der BH1750 Helligkeitssensor sitzt leider an einer ungünstigen Stelle, die an sonnigen Tagen morgens im Schatten liegt und somit nicht die tatsächliche Umgebungshelligkeit messen kann. Der Sensor sitzt in einer selbstentwickelten Outdoor-Wetterstation und diese muss genau an der Stelle bleiben wegen der Bewölkungsmessung und dem TX20 Windmesser – dazu an anderer Stelle mehr.
Ich besitze ein kleines Balkonkraftwerk mit zwei Panels je 840W und zwei Marstek Solarbatterien mit je 2,4kWh Leistung, die über Bluetooth mit einem ESP32 und über WiFi mit Home Assistant verbunden sind. Somit stehen mir sämtliche Daten der Batterien zur Verfügung.
Die Idee war, die eingehende Gesamtleistung der Solar-Panels in einen linearen Helligkeitswert umzurechnen. Dazu normalisiere ich die gelieferten Helligkeitswerte des BH1750 und des Batteriespeichers in einen Bereich von 0-32767 lux. In Home Assistant lese ich die Entitäten der Controller über ESPHome und verwende nur die Max-Werte des jeweiligen Sensors und verwende diesen Wert, um damit die Freigaben aller LED-Lampen im Haus zu setzen – ist es draussen hell genug, werden die LED-Lampen ausgeschaltet bzw. ist es dunkel genug, werden die LED-Lampen freigegeben – sie können also durch Bewegungsmelder im Haus eingeschaltet werden. Wer mit ESPHome noch nicht vertraut ist, kann gerne den obigen Link klicken, um weitere Informationen zu erhalten.
Als erstes die Konvertierung eines Wertebereiches von 0-840W des Batteriespeichers sowie 1-65535 lux gem. Datenblatt des BH1750 nach 0-32767. Dieser Wert wurde von mir beispielhaft gewählt, es ist natürlich jeder beliebige Bereich möglich. Dazu bemühe ich die Formel:
x ist der aktuelle Eingangswert mit INmin als Min-Wert – hier 0 bzw. 1 – und INmax als maximaler Eingangswert – hier 840 bzw. 65535. OUTmax ist der gewünschte maximale Ausgangswert (hier 32767). In meiner Wetterstation mit einem ESP8266 sieht dies so aus:
- platform: bh1750
name: 'Aussenhelligkeit'
address: 0x23
filters:
- filter_out: nan
- clamp:
min_value: 1
max_value: 65535.0
ignore_out_of_range: false
- calibrate_linear:
method: least_squares
datapoints:
- 1.0 -> 0.0
- 65535.0 -> 32767.0
- sliding_window_moving_average:
window_size: 15
send_every: 15
send_first_at: 7
device_class: 'illuminance'
state_class: 'measurement'
unit_of_measurement: 'lx'
accuracy_decimals: 0
update_interval: 30s
Der Float-Rohwert aus dem Sensor im Bereich 1.0-65535.0 (clamp) wird linear nach 0.0 – 32767.0 (calibrate) umgerechnet. Im Controller zur Abfrage der Batterie-Daten erstelle ich ein eigenes Template aus dem Sensor:
- platform: template
name: 'Solarhelligkeit'
lambda: |-
return id(b2500_total_power_in).state;
filters:
- filter_out: nan
- clamp:
min_value: 0.0
max_value: 840.0
ignore_out_of_range: false
- calibrate_linear:
method: least_squares
datapoints:
- 0.0 -> 0.0
- 840.0 -> 32767.0
- sliding_window_moving_average:
window_size: 15
send_every: 15
send_first_at: 7
device_class: 'illuminance'
state_class: 'measurement'
unit_of_measurement: 'lx'
accuracy_decimals: 0
update_interval: 30s
Die Entität b2500_total_power_in des Marstek B2500D Batteriespeichers wird gelesen und der Rohwert zwischen 0.0-840.0 (clamp) in den Bereich 0.0-32767.0 linear umgerechnet (calibrate). Der Wert 840 entspricht der Maximal-Leistung in W meiner beiden Solar-Panels – hier also bitte die Werte anpassen.
Beide normalisierten Werte werden über die API an Home Assistant gesendet und werden dort in einem Sensor-Template zu einem MAX-Wert berechnet – von beiden Werten wird also immer der jeweils höchste Wert genommen. Mein Sensor-Template in Home Assistant sieht folgendermaßen aus:
- sensor:
- name: "Aussenhelligkeit"
unique_id: aussen_lux
device_class: illuminance
unit_of_measurement: "lx"
state: >
{{ [(this.state if ((states('sensor.bh1750_lux') | is_number == false) or is_state('binary_sensor.bh1750_status', 'off')) else states('sensor.bh1750_lux') | float(0)) | round(0), (this.state if ((states('sensor.solar_lux')|is_number == false) or is_state('binary_sensor.solar_status', 'off')) else states('sensor.solar_lux') | float(0)) |round(0)] | max }}
sensor_bh1750_lux = Rohwert von der Wetterstation 0 - 32767 lux
binary_sensor.bh1750_status = ON wenn die Wetterstation online ist
sensor.solar_lux = Helligkeitswert von Solar-Batterie 0 - 32767 lux
binary_sensor.solar_status = ON wenn der Controller online ist
Falls einer oder beide Sensoren offline sind, bleibt der Wert unverändert (this.state)
Als Ergebnis erhalte ich einen linearen Helligkeitswert, der von Sonnenaufgang bis Sonnenuntergang den jeweiligen maximalen Wert ergibt. An sonnigen Tagen ist hauptsächlich der Helligkeitswert aus der Solar-Batterie maßgebend, während ab den Mittagstunden der BH1750 übernimmt – der Sensor ist dann nicht mehr abgeschattet. An eher bewölkten Tagen sind die beiden Helligkeitswerte annähernd gleich.

Helligkeitswerte an einem bewölktem Tag

Helligkeitswerte an einem bewölkten aber überwiegend sonnigen Tag

Helligkeitsverlauf an einem sehr sonnigen Tag
Bei allen Grafiken ist die rote Außenlinie der oben berechnete Max-Wert aus dem Home Assistant Sensor-Template. Die gelbe bzw. blaue Fläche stellen die beiden Eingangswerte dar. Man kann in der zweiten und dritten Grafik gut erkennen wie an sonnigen Tagen morgens, wenn der BH1750 noch im Schatten liegt, die Solar-Panels die Umgebungshelligkeit messen. Irgendwann nach dem Mittag übernimmt dann der BH1750 die Messung. Somit ergibt sich über den gesamten Tage ein akkurater Wert für die Außenhelligkeit. Das Problem ist gelöst.
Update vom 19. August 2026:
Ich habe den Helligkeits-Sensor mit einem Winkel von 8° nach Norden ausgerichtet und mit einem voll-transparentem Kunststoff abgedeckt. Dadurch ergeben sich deutlich bessere Werte, die auch morgens die tatsächliche Helligkeit darstellen. Die Filterung nach Max-Wert habe ich aber – wie oben beschrieben – belassen.

Die neuen Werte nach der Neu-Ausrichtung des BH1750