Hallo, hat jemand schon einen Temperatur wert aus HA auf dem CYD ESP32-2432S028 Display erfolgreich zu Anzeige gebracht? Bei Mir wird immer „nan“ angezeigt. Der code würde mit CYD ESP32-2432S028 erzeugt.
„nan“ steht vermutlich für „not a number“. D. h. dein anzuzeigender Wert ist keine gültige Real- oder Fliesskommazahl.
Was ist das für ein Format. Bei einer Definition als Text, erschein ein Wert 1.71 bei einer Temperatur von > 20 Grad.
Hat jemand dieses Display im Einsatz, das auch korrekte Werte anzeigt.
Habe gerade festgestellt, der Wert 1.71 bleibt konstant auch wenn der Sensor wechselt.
by HarryP: Zusammenführung Doppelpost (bei Änderungen oder hinzufügen von Inhalten bitte die „Bearbeitungsfunktion“ anstatt „Antworten“ zu nutzen)
Ich nutze das Display auch um alles rund um meine PV und Wetter anzuzeigen.
- platform: homeassistant
id: garage_temp
entity_id: sensor.garage_hinten_bewegungsmelder_air_temperature
on_value:
- lvgl.label.update:
id: lbl_garage_temp
text: !lambda |-
char buf[16];
snprintf(buf, sizeof(buf), "%.1f°C", x);
return std::string(buf);
Danke für eure Unterstützung.
Ich gebe auf. Für die Programmierung reichen meine Kenntnis nicht aus.
Hast du mal openHASP versucht? Auf einem ESP32 mit einem 3,2” Display funktioniert das bei mir sehr gut.
Allerdings scheint es da Probleme mit einigen 2432S028 CYDs zu geben, weil die den falschen Displaycontroller eingebaut haben.
Ich habe auch 0 Ahnung vom Programmieren. Es ist aber recht simple.
Die Lösung für das „nan"-Problem
„nan" bedeutet not a number Der Wert vom Sensor kommt als String oder als ungültige Zahl an. Drei Dinge müssen stimmen:
Erstens, die Entity-ID muss exakt mit der in Home Assistant übereinstimmen, inklusive sensor. davor. Prüfe unter Entwicklerwerkzeuge - Zustände in HA. Zweitens, der Sensor in HA muss eine numerische device_class wie temperature haben und einen unit_of_measurement (°C) - sonst behandelt ESPHome ihn nicht als Float. Drittens, das platform: homeassistant unter sensor: benutzen (nicht unter text_sensor:). Die on_value-Aktion mit dem snprintf-Lambda, wie oben und auch im Beispiel im Thread, formatiert den Float dann korrekt als z. B. „21.3 °C".
Wenn du als text_sensor definierst, bekommst du genau das: einen festen Wert wie „1.71", weil das die Länge des Strings oder ein Speicher-Offset ist, nicht der eigentliche Wert.
Ich kann Dir meine ESP-Home Konfiguration zum testen egben.
Hallo,
habe das display selbst mit diesem teil zum laufen gebracht:
https://cheapyellowdisplay.co.uk/config-generator
ich denke, da kannst du mit deinen Entitäten “spielen”, da du selbst festlegen musst, ob es ein Textsensor oder ein numerischer Sensor ist. Du könntest also einfach ausprobieren.
Zum zweiten hatte ich ein anderes Display, das nur 2 Temperaturen anzeigen sollte. Dieses Teil hat sehr oft “nan” angezeigt. Lag in diesem Fall schlicht an der Wlan Verbindung und letztlich die Verbindung zu HA. Habe mir das dann so erklärt: das Teil läuft hoch und zeigt an, was da ist. Solange die Wlan Verbindung aber noch nicht stabil war, hat es nan statt der Temperaturen angezeigt.
Auszug aus der yaml des displays:
sensor:
- platform: homeassistant
name: "Aussen"
id: aussen
entity_id: sensor.wetter2_aussentemperatur
internal: true
- platform: homeassistant
name: "Innen"
id: innen
entity_id: sensor.kuchetemp_temperature
internal: true
- platform: wifi_signal
name: "WiFi Signal Sensor"
id: wifix
update_interval: 60s
# Auszug aus der Lambda:
lambda: |-
it.print(7,42, id(font2), yellow, "I:");
it.printf(150, 10, id(font3), white,TextAlign::TOP_RIGHT, " %.1f ", id(innen).state);
it.print(7, 96, id(font2), yellow, "O:");
it.printf(150,66, id(font3), white, TextAlign::TOP_RIGHT," %.1f ", id(aussen).state);
it.printf(7, 15, id(font2), white, "%.0f", id(wifix).state);
Wie du siehst, habe ich irgendwann das wifi signal mit anzeigen lassen…
Hoffe das hilft dir, um noch nicht aufzugeben.
Das Ganze ist schon ca 1 Jahr alt und mittlerweile nutze ich - ungern - gemini um solche Fehler zu finden. Ist nach meiner Erfahrung manchmal klüger, manchmal aber auch dümmer, als ich erwartet hätte - für mich aber effektiv “schneller”
Herzliche Grüße
Rolo
Hallo Oliver
Habe alles in Entwicklerwerkzeugen kontrolliert. Alles ist wie es sein sollte, dennoch funktioniert es nicht. Eine brauchbare anzeige habe ich mit dem Link config-generator von rolo hin bekommen.
Würde dennoch auf dein Angebot zurückkommen und deine ESP-Home Konfiguration testen
Grüße
Waldemar
substitutions:
device_name: cyd-display
friendly_name: "CYD Display"
esphome:
name: ${device_name}
friendly_name: ${friendly_name}
min_version: 2025.6.0
esp32:
board: esp32dev
framework:
type: arduino
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "CYD Display Fallback"
password: "changeme1234"
captive_portal:
logger:
level: INFO
api:
encryption:
key: !secret api_encryption_key
ota:
- platform: esphome
password: !secret ota_password
# Globale Variablen -------------------------------------------------
globals:
- id: nacht_modus
type: bool
restore_value: no
initial_value: 'false'
- id: pv_displayed
type: float
restore_value: no
initial_value: '0.0'
- id: pv_target
type: float
restore_value: no
initial_value: '0.0'
- id: verbrauch_displayed
type: float
restore_value: no
initial_value: '0.0'
- id: verbrauch_target
type: float
restore_value: no
initial_value: '0.0'
- id: bezug_displayed
type: float
restore_value: no
initial_value: '0.0'
- id: bezug_target
type: float
restore_value: no
initial_value: '0.0'
- id: einspeisung_displayed
type: float
restore_value: no
initial_value: '0.0'
- id: einspeisung_target
type: float
restore_value: no
initial_value: '0.0'
- id: anim_tick
type: int
restore_value: no
initial_value: '0'
- id: autoslide_pause
type: int
restore_value: no
initial_value: '0'
# Smooth-Wert-Animation alle 50ms -----------------------------------
interval:
- interval: 50ms
then:
- lambda: |-
auto tween = [](float displayed, float target) -> float {
float diff = target - displayed;
if (std::abs(diff) < 1.0) return target;
return displayed + diff * 0.10;
};
id(pv_displayed) = tween(id(pv_displayed), id(pv_target));
id(verbrauch_displayed) = tween(id(verbrauch_displayed), id(verbrauch_target));
id(bezug_displayed) = tween(id(bezug_displayed), id(bezug_target));
id(einspeisung_displayed) = tween(id(einspeisung_displayed), id(einspeisung_target));
- lvgl.label.update:
id: lbl_pv
text: !lambda |-
char buf[24];
float v = id(pv_displayed);
if (v < 1000) snprintf(buf, sizeof(buf), "%.0f W", v);
else snprintf(buf, sizeof(buf), "%.2f kW", v / 1000.0);
return std::string(buf);
- lvgl.label.update:
id: lbl_verbrauch
text: !lambda |-
char buf[24];
float v = std::abs(id(verbrauch_displayed));
if (v < 1000) snprintf(buf, sizeof(buf), "%.0f W", v);
else snprintf(buf, sizeof(buf), "%.2f kW", v / 1000.0);
return std::string(buf);
- lvgl.label.update:
id: lbl_netzbezug
text: !lambda |-
char buf[24];
float v = id(bezug_displayed);
if (v < 1000) snprintf(buf, sizeof(buf), "%.0f W", v);
else snprintf(buf, sizeof(buf), "%.2f kW", v / 1000.0);
return std::string(buf);
- lvgl.label.update:
id: lbl_einspeisung
text: !lambda |-
char buf[24];
float v = id(einspeisung_displayed);
if (v < 1000) snprintf(buf, sizeof(buf), "%.0f W", v);
else snprintf(buf, sizeof(buf), "%.2f kW", v / 1000.0);
return std::string(buf);
# Dauer-Animationen alle 150ms
- interval: 150ms
then:
- lambda: 'id(anim_tick) = (id(anim_tick) + 1) % 4;'
- lvgl.widget.update:
id: pulse_dot
bg_opa: !lambda |-
if (id(pv_target) < 5.0) return 30;
int t = id(anim_tick);
int values[4] = {100, 200, 255, 200};
return values[t];
- lvgl.widget.update:
id: flow_pv_dot1
bg_opa: !lambda |-
if (id(pv_target) < 5.0) return 0;
return (id(anim_tick) == 0) ? 255 : 60;
- lvgl.widget.update:
id: flow_pv_dot2
bg_opa: !lambda |-
if (id(pv_target) < 5.0) return 0;
return (id(anim_tick) == 1) ? 255 : 60;
- lvgl.widget.update:
id: flow_pv_dot3
bg_opa: !lambda |-
if (id(pv_target) < 5.0) return 0;
return (id(anim_tick) == 2) ? 255 : 60;
- lvgl.widget.update:
id: flow_pv_dot4
bg_opa: !lambda |-
if (id(pv_target) < 5.0) return 0;
return (id(anim_tick) == 3) ? 255 : 60;
- lvgl.widget.update:
id: flow_haus_dot1
bg_opa: !lambda |-
float bezug = id(bezug_target);
float ein = id(einspeisung_target);
int t = id(anim_tick);
if (ein > 5) return (t == 0) ? 255 : 60;
if (bezug > 5) return (t == 3) ? 255 : 60;
return 0;
- lvgl.widget.update:
id: flow_haus_dot2
bg_opa: !lambda |-
float bezug = id(bezug_target);
float ein = id(einspeisung_target);
int t = id(anim_tick);
if (ein > 5) return (t == 1) ? 255 : 60;
if (bezug > 5) return (t == 2) ? 255 : 60;
return 0;
- lvgl.widget.update:
id: flow_haus_dot3
bg_opa: !lambda |-
float bezug = id(bezug_target);
float ein = id(einspeisung_target);
int t = id(anim_tick);
if (ein > 5) return (t == 2) ? 255 : 60;
if (bezug > 5) return (t == 1) ? 255 : 60;
return 0;
- lvgl.widget.update:
id: flow_haus_dot4
bg_opa: !lambda |-
float bezug = id(bezug_target);
float ein = id(einspeisung_target);
int t = id(anim_tick);
if (ein > 5) return (t == 3) ? 255 : 60;
if (bezug > 5) return (t == 0) ? 255 : 60;
return 0;
# Auto-Slide alle 10 Sekunden, pausiert 30s nach Touch
- interval: 1s
then:
- lambda: |-
if (id(autoslide_pause) > 0) {
id(autoslide_pause) -= 1;
}
- if:
condition:
lambda: |-
return id(autoslide_pause) == 0;
then:
- lambda: |-
static int counter = 0;
counter += 1;
if (counter >= 10) {
counter = 0;
id(do_next_page).execute();
}
# Script: zur nächsten Seite wechseln
script:
- id: do_next_page
then:
- lvgl.page.next:
animation: OVER_LEFT
time: 300ms
# Zeitsteuerung -----------------------------------------------------
time:
- platform: homeassistant
id: ha_time
on_time:
- hours: 21
minutes: 0
seconds: 0
then:
- globals.set:
id: nacht_modus
value: 'true'
- light.turn_on:
id: backlight
brightness: 30%
transition_length: 3s
- hours: 6
minutes: 0
seconds: 0
then:
- globals.set:
id: nacht_modus
value: 'false'
- light.turn_on:
id: backlight
brightness: 100%
transition_length: 3s
on_time_sync:
then:
- if:
condition:
lambda: |-
auto t = id(ha_time).now();
if (!t.is_valid()) return false;
return (t.hour >= 21 || t.hour < 6);
then:
- globals.set:
id: nacht_modus
value: 'true'
- light.turn_on:
id: backlight
brightness: 30%
transition_length: 2s
else:
- globals.set:
id: nacht_modus
value: 'false'
- light.turn_on:
id: backlight
brightness: 100%
transition_length: 2s
# Fonts -------------------------------------------------------------
font:
- file:
type: gfonts
family: Roboto
weight: 400
id: roboto_12
size: 12
bpp: 4
glyphs: " !\"%()+=,-_.:°/?0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÄÖÜäöüß"
- file:
type: gfonts
family: Roboto
weight: 400
id: roboto_14
size: 14
bpp: 4
glyphs: " !\"%()+=,-_.:°/?0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÄÖÜäöüß"
- file:
type: gfonts
family: Roboto
weight: 400
id: roboto_18
size: 18
bpp: 4
glyphs: " !\"%()+=,-_.:°/?0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÄÖÜäöüß"
- file:
type: gfonts
family: Roboto
weight: 700
id: roboto_28
size: 28
bpp: 4
glyphs: " !\"%()+=,-_.:°/?0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÄÖÜäöüß"
- file:
type: gfonts
family: Roboto
weight: 700
id: roboto_36
size: 36
bpp: 4
glyphs: " !\"%()+=,-_.:°/?0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÄÖÜäöüß"
- file: "https://github.com/Templarian/MaterialDesign-Webfont/raw/master/fonts/materialdesignicons-webfont.ttf"
id: mdi_72
size: 72
bpp: 4
glyphs:
- "\U000F0599" # weather-sunny
- "\U000F0590" # weather-cloudy
- "\U000F0595" # weather-partly-cloudy
- "\U000F0597" # weather-rainy
- "\U000F067F" # weather-pouring
- "\U000F0598" # weather-snowy
- "\U000F067E" # weather-snowy-rainy
- "\U000F0596" # weather-night
- "\U000F0F31" # weather-night-partly-cloudy
- "\U000F0594" # weather-fog
- "\U000F0F32" # weather-windy
- "\U000F0593" # weather-lightning
- "\U000F067D" # weather-lightning-rainy
- "\U000F0F38" # weather-hail
- "\U000F0F30" # help-circle (fallback)
# SPI Busse ---------------------------------------------------------
spi:
- id: tft_spi
clk_pin: GPIO14
mosi_pin: GPIO13
miso_pin: GPIO12
- id: touch_spi
clk_pin: GPIO25
mosi_pin: GPIO32
miso_pin: GPIO39
# Display - PHYSISCH 240x320, Rotation kommt von LVGL ---------------
display:
- platform: ili9xxx
id: main_display
model: ILI9341
spi_id: tft_spi
cs_pin: GPIO15
dc_pin: GPIO2
invert_colors: false
color_palette: 8BIT
dimensions:
width: 240
height: 320
update_interval: never
auto_clear_enabled: false
# Touch - XPT2046 ---------------------------------------------------
touchscreen:
- platform: xpt2046
id: touch
spi_id: touch_spi
cs_pin: GPIO33
interrupt_pin: GPIO36
update_interval: 50ms
threshold: 400
calibration:
x_min: 280
x_max: 3860
y_min: 340
y_max: 3860
transform:
swap_xy: false
mirror_x: false
mirror_y: false
on_touch:
- lambda: 'id(autoslide_pause) = 30;'
- light.turn_on:
id: backlight
brightness: 100%
transition_length: 500ms
- delay: 30s
- if:
condition:
lambda: 'return id(nacht_modus);'
then:
- light.turn_on:
id: backlight
brightness: 30%
transition_length: 2s
# Outputs -----------------------------------------------------------
output:
- platform: ledc
pin: GPIO21
id: backlight_pwm
- platform: ledc
pin:
number: GPIO4
inverted: true
id: led_red_pwm
- platform: ledc
pin:
number: GPIO16
inverted: true
id: led_green_pwm
- platform: ledc
pin:
number: GPIO17
inverted: true
id: led_blue_pwm
light:
- platform: monochromatic
output: backlight_pwm
name: "Display Backlight"
id: backlight
restore_mode: ALWAYS_ON
default_transition_length: 1s
- platform: rgb
name: "Status LED"
id: status_led
red: led_red_pwm
green: led_green_pwm
blue: led_blue_pwm
restore_mode: ALWAYS_OFF
# PV-Sensoren -------------------------------------------------------
sensor:
- platform: homeassistant
id: pv_leistung
entity_id: sensor.solarnet_pv_leistung
on_value:
- lambda: 'id(pv_target) = x;'
- platform: homeassistant
id: verbrauch
entity_id: sensor.solarnet_leistung_verbrauch
on_value:
- lambda: 'id(verbrauch_target) = x;'
- platform: homeassistant
id: netzbezug
entity_id: sensor.solarnet_leistung_netzbezug
on_value:
- lambda: 'id(bezug_target) = x;'
- platform: homeassistant
id: einspeisung
entity_id: sensor.solarnet_leistung_netzeinspeisung
on_value:
- lambda: 'id(einspeisung_target) = x;'
- platform: homeassistant
id: ladeleistung
entity_id: sensor.solarnet_ladeleistung
on_value:
- lvgl.label.update:
id: lbl_batterie_power
text: !lambda |-
char buf[32];
float lade = id(ladeleistung).state;
float entlade = id(entladeleistung).state;
if (!isnan(lade) && lade > 5) {
if (lade < 1000) snprintf(buf, sizeof(buf), "Lädt: %.0f W", lade);
else snprintf(buf, sizeof(buf), "Lädt: %.2f kW", lade/1000.0);
} else if (!isnan(entlade) && entlade > 5) {
if (entlade < 1000) snprintf(buf, sizeof(buf), "Entlädt: %.0f W", entlade);
else snprintf(buf, sizeof(buf), "Entlädt: %.2f kW", entlade/1000.0);
} else {
snprintf(buf, sizeof(buf), "Ruht");
}
return std::string(buf);
- platform: homeassistant
id: entladeleistung
entity_id: sensor.solarnet_entladeleistung
on_value:
- lvgl.label.update:
id: lbl_batterie_power
text: !lambda |-
char buf[32];
float lade = id(ladeleistung).state;
float entlade = id(entladeleistung).state;
if (!isnan(lade) && lade > 5) {
if (lade < 1000) snprintf(buf, sizeof(buf), "Lädt: %.0f W", lade);
else snprintf(buf, sizeof(buf), "Lädt: %.2f kW", lade/1000.0);
} else if (!isnan(entlade) && entlade > 5) {
if (entlade < 1000) snprintf(buf, sizeof(buf), "Entlädt: %.0f W", entlade);
else snprintf(buf, sizeof(buf), "Entlädt: %.2f kW", entlade/1000.0);
} else {
snprintf(buf, sizeof(buf), "Ruht");
}
return std::string(buf);
- platform: homeassistant
id: batterie_soc
entity_id: sensor.byd_battery_box_premium_hv_ladezustand
on_value:
- lvgl.label.update:
id: lbl_batterie_soc
text: !lambda |-
char buf[16];
snprintf(buf, sizeof(buf), "%.0f%%", x);
return std::string(buf);
- lvgl.bar.update:
id: bar_batterie_soc
value: !lambda 'return (int) x;'
animated: true
- platform: homeassistant
id: autarkie
entity_id: sensor.solarnet_autarkiegrad
on_value:
- lvgl.label.update:
id: lbl_autarkie
text: !lambda |-
char buf[16];
snprintf(buf, sizeof(buf), "%.0f%%", x);
return std::string(buf);
- lvgl.bar.update:
id: bar_autarkie
value: !lambda 'return (int) x;'
animated: true
- platform: homeassistant
id: eigenverbrauch
entity_id: sensor.solarnet_eigenverbrauch
on_value:
- lvgl.label.update:
id: lbl_eigenverbrauch
text: !lambda |-
char buf[16];
snprintf(buf, sizeof(buf), "%.0f%%", x);
return std::string(buf);
- lvgl.bar.update:
id: bar_eigenverbrauch
value: !lambda 'return (int) x;'
animated: true
- platform: homeassistant
id: garage_temp
entity_id: sensor.garage_hinten_bewegungsmelder_air_temperature
on_value:
- lvgl.label.update:
id: lbl_garage_temp
text: !lambda |-
char buf[16];
snprintf(buf, sizeof(buf), "%.1f°C", x);
return std::string(buf);
# Wetter ------------------------------------------------------------
text_sensor:
- platform: homeassistant
id: wetter_state
entity_id: weather.forecast_home
on_value:
- lvgl.label.update:
id: lbl_wetter_icon
text: !lambda |-
std::string state = x;
if (state == "sunny") return std::string("\U000F0599");
if (state == "clear-night") return std::string("\U000F0596");
if (state == "cloudy") return std::string("\U000F0590");
if (state == "partlycloudy") return std::string("\U000F0595");
if (state == "rainy") return std::string("\U000F0597");
if (state == "pouring") return std::string("\U000F067F");
if (state == "snowy") return std::string("\U000F0598");
if (state == "snowy-rainy") return std::string("\U000F067E");
if (state == "fog") return std::string("\U000F0594");
if (state == "windy") return std::string("\U000F0F32");
if (state == "lightning") return std::string("\U000F0593");
if (state == "lightning-rainy") return std::string("\U000F067D");
if (state == "hail") return std::string("\U000F0F38");
return std::string("\U000F0F30");
- lvgl.label.update:
id: lbl_wetter_text
text: !lambda |-
std::string state = x;
if (state == "sunny") return std::string("Sonnig");
if (state == "clear-night") return std::string("Klar");
if (state == "cloudy") return std::string("Bewölkt");
if (state == "partlycloudy") return std::string("Teils bew.");
if (state == "rainy") return std::string("Regen");
if (state == "pouring") return std::string("Starkregen");
if (state == "snowy") return std::string("Schnee");
if (state == "snowy-rainy") return std::string("Schneeregen");
if (state == "fog") return std::string("Nebel");
if (state == "windy") return std::string("Windig");
if (state == "lightning") return std::string("Gewitter");
if (state == "lightning-rainy") return std::string("Gewitterreg.");
if (state == "hail") return std::string("Hagel");
return std::string(state);
# LVGL UI - QUERFORMAT 320x240 via Rotation 90 ----------------------
lvgl:
displays:
- main_display
touchscreens:
- touch
rotation: 90
style_definitions:
- id: card_style
bg_color: 0x222222
bg_opa: COVER
border_width: 0
radius: 8
pad_all: 6
text_color: 0xFFFFFF
pages:
# ===== SEITE 1: PV LIVE =====
- id: page_live
bg_color: 0x000000
on_swipe_left:
- lambda: 'id(autoslide_pause) = 30;'
- lvgl.page.next:
animation: OVER_LEFT
time: 300ms
on_swipe_right:
- lambda: 'id(autoslide_pause) = 30;'
- lvgl.page.previous:
animation: OVER_RIGHT
time: 300ms
widgets:
- label:
align: TOP_MID
y: 4
text: "PV LIVE"
text_font: roboto_18
text_color: 0xFFAA00
- obj:
id: pulse_dot
x: 280
y: 8
width: 14
height: 14
radius: 7
bg_color: 0x00FF00
bg_opa: 12%
border_width: 0
- obj:
x: 6
y: 28
width: 156
height: 130
styles: card_style
bg_color: 0x1F3D1F
widgets:
- label:
align: TOP_MID
y: 6
text: "PV-Erzeugung"
text_font: roboto_14
text_color: 0xAAFFAA
- label:
id: lbl_pv
align: CENTER
y: 8
text: "0 W"
text_font: roboto_36
text_color: 0x00FF00
- obj:
x: 168
y: 28
width: 146
height: 72
styles: card_style
widgets:
- label:
align: TOP_LEFT
x: 6
y: 4
text: "Verbrauch"
text_font: roboto_14
- label:
id: lbl_verbrauch
align: BOTTOM_RIGHT
x: -6
y: -6
text: "0 W"
text_font: roboto_28
text_color: 0xFFCC00
- obj:
x: 168
y: 106
width: 71
height: 52
styles: card_style
bg_color: 0x3D1F1F
widgets:
- label:
align: TOP_MID
y: 4
text: "Bezug"
text_font: roboto_12
text_color: 0xFF8888
- label:
id: lbl_netzbezug
align: BOTTOM_MID
y: -4
text: "0 W"
text_font: roboto_14
text_color: 0xFF6666
- obj:
x: 243
y: 106
width: 71
height: 52
styles: card_style
bg_color: 0x1F3D2F
widgets:
- label:
align: TOP_MID
y: 4
text: "Einspeis."
text_font: roboto_12
text_color: 0x88FF88
- label:
id: lbl_einspeisung
align: BOTTOM_MID
y: -4
text: "0 W"
text_font: roboto_14
text_color: 0x66FF66
- obj:
x: 6
y: 164
width: 308
height: 72
styles: card_style
bg_color: 0x1F2F4D
widgets:
- label:
align: TOP_LEFT
x: 6
y: 4
text: "Batterie"
text_font: roboto_14
text_color: 0xAACCFF
- label:
id: lbl_batterie_soc
align: TOP_RIGHT
x: -6
y: 2
text: "--%"
text_font: roboto_18
text_color: 0xFFFFFF
- bar:
id: bar_batterie_soc
align: CENTER
y: 2
width: 290
height: 10
min_value: 0
max_value: 100
value: 0
indicator:
bg_color: 0x44AAFF
- label:
id: lbl_batterie_power
align: BOTTOM_MID
y: -4
text: "Ruht"
text_font: roboto_14
text_color: 0xCCDDFF
# ===== SEITE 2: ENERGIEFLUSS =====
- id: page_fluss
bg_color: 0x000000
on_swipe_left:
- lambda: 'id(autoslide_pause) = 30;'
- lvgl.page.next:
animation: OVER_LEFT
time: 300ms
on_swipe_right:
- lambda: 'id(autoslide_pause) = 30;'
- lvgl.page.previous:
animation: OVER_RIGHT
time: 300ms
widgets:
- label:
align: TOP_MID
y: 4
text: "ENERGIEFLUSS"
text_font: roboto_18
text_color: 0xFFAA00
- obj:
x: 8
y: 80
width: 80
height: 80
styles: card_style
bg_color: 0x1F3D1F
widgets:
- label:
align: TOP_MID
y: 8
text: "PV"
text_font: roboto_18
text_color: 0xAAFFAA
- label:
align: BOTTOM_MID
y: -8
text: "Solar"
text_font: roboto_14
text_color: 0x00FF00
- obj:
x: 92
y: 117
width: 60
height: 6
bg_color: 0x222222
bg_opa: COVER
border_width: 0
radius: 0
- obj:
id: flow_pv_dot1
x: 92
y: 115
width: 10
height: 10
radius: 5
bg_color: 0x00FF00
bg_opa: 24%
border_width: 0
- obj:
id: flow_pv_dot2
x: 108
y: 115
width: 10
height: 10
radius: 5
bg_color: 0x00FF00
bg_opa: 24%
border_width: 0
- obj:
id: flow_pv_dot3
x: 124
y: 115
width: 10
height: 10
radius: 5
bg_color: 0x00FF00
bg_opa: 24%
border_width: 0
- obj:
id: flow_pv_dot4
x: 140
y: 115
width: 10
height: 10
radius: 5
bg_color: 0x00FF00
bg_opa: 24%
border_width: 0
- obj:
x: 156
y: 80
width: 80
height: 80
styles: card_style
bg_color: 0x3D2F1F
widgets:
- label:
align: TOP_MID
y: 8
text: "Haus"
text_font: roboto_18
text_color: 0xFFE0AA
- label:
align: BOTTOM_MID
y: -8
text: "Verbrauch"
text_font: roboto_12
text_color: 0xFFCC00
- obj:
x: 240
y: 117
width: 60
height: 6
bg_color: 0x222222
bg_opa: COVER
border_width: 0
radius: 0
- obj:
id: flow_haus_dot1
x: 240
y: 115
width: 10
height: 10
radius: 5
bg_color: 0xFFAA44
bg_opa: 24%
border_width: 0
- obj:
id: flow_haus_dot2
x: 256
y: 115
width: 10
height: 10
radius: 5
bg_color: 0xFFAA44
bg_opa: 24%
border_width: 0
- obj:
id: flow_haus_dot3
x: 272
y: 115
width: 10
height: 10
radius: 5
bg_color: 0xFFAA44
bg_opa: 24%
border_width: 0
- obj:
id: flow_haus_dot4
x: 288
y: 115
width: 10
height: 10
radius: 5
bg_color: 0xFFAA44
bg_opa: 24%
border_width: 0
- obj:
x: 232
y: 80
width: 80
height: 80
styles: card_style
bg_color: 0x1F2F4D
widgets:
- label:
align: TOP_MID
y: 8
text: "Netz"
text_font: roboto_18
text_color: 0xAACCFF
- label:
align: BOTTOM_MID
y: -8
text: "Stromnetz"
text_font: roboto_12
text_color: 0xCCDDFF
# ===== SEITE 3: BILANZ =====
- id: page_bilanz
bg_color: 0x000000
on_swipe_left:
- lambda: 'id(autoslide_pause) = 30;'
- lvgl.page.next:
animation: OVER_LEFT
time: 300ms
on_swipe_right:
- lambda: 'id(autoslide_pause) = 30;'
- lvgl.page.previous:
animation: OVER_RIGHT
time: 300ms
widgets:
- label:
align: TOP_MID
y: 4
text: "BILANZ"
text_font: roboto_18
text_color: 0xFFAA00
- obj:
x: 8
y: 30
width: 152
height: 200
styles: card_style
widgets:
- label:
align: TOP_MID
y: 8
text: "Autarkiegrad"
text_font: roboto_14
text_color: 0xAAFFAA
- label:
id: lbl_autarkie
align: CENTER
y: 0
text: "--%"
text_font: roboto_36
text_color: 0x00FF88
- bar:
id: bar_autarkie
align: BOTTOM_MID
y: -16
width: 130
height: 12
min_value: 0
max_value: 100
value: 0
indicator:
bg_color: 0x00FF88
- obj:
x: 168
y: 30
width: 144
height: 200
styles: card_style
widgets:
- label:
align: TOP_MID
y: 8
text: "Eigenverbrauch"
text_font: roboto_14
text_color: 0xFFE0AA
- label:
id: lbl_eigenverbrauch
align: CENTER
y: 0
text: "--%"
text_font: roboto_36
text_color: 0xFFCC44
- bar:
id: bar_eigenverbrauch
align: BOTTOM_MID
y: -16
width: 122
height: 12
min_value: 0
max_value: 100
value: 0
indicator:
bg_color: 0xFFCC44
# ===== SEITE 4: GARAGE & WETTER =====
- id: page_garage
bg_color: 0x000000
on_swipe_left:
- lambda: 'id(autoslide_pause) = 30;'
- lvgl.page.next:
animation: OVER_LEFT
time: 300ms
on_swipe_right:
- lambda: 'id(autoslide_pause) = 30;'
- lvgl.page.previous:
animation: OVER_RIGHT
time: 300ms
widgets:
- label:
align: TOP_MID
y: 4
text: "AUSSEN"
text_font: roboto_18
text_color: 0xFFAA00
- obj:
x: 8
y: 30
width: 152
height: 200
styles: card_style
bg_color: 0x1F2F4D
widgets:
- label:
align: TOP_MID
y: 8
text: "Wetter"
text_font: roboto_14
text_color: 0xAACCFF
- label:
id: lbl_wetter_icon
align: CENTER
y: -10
text: "\U000F0F30"
text_font: mdi_72
text_color: 0xFFDD44
- label:
id: lbl_wetter_text
align: BOTTOM_MID
y: -10
text: "..."
text_font: roboto_18
text_color: 0xCCDDFF
- obj:
x: 168
y: 30
width: 144
height: 200
styles: card_style
bg_color: 0x3D2F1F
widgets:
- label:
align: TOP_MID
y: 8
text: "Garage"
text_font: roboto_14
text_color: 0xFFE0AA
- label:
align: CENTER
y: -30
text: "Temperatur"
text_font: roboto_14
text_color: 0xFFCC88
- label:
id: lbl_garage_temp
align: CENTER
y: 15
text: "--°C"
text_font: roboto_36
text_color: 0xFFCC44

