Hi, ist ja auch ein geekmagic. Daher dachte ich, poste ich gleich hier. Habe mir heute doch noch den Ständer gedruckt und mal bei normalen Licht, was das Licht aktuell so her gibt, ein Foto gemacht, da kann man schön den Transparenz Effekt sehen.
Den Code von Dr.Big habe ich auch weiter für mich angepasst. Die Zeilen kann ich jetzt bequem über das ESP Gerät in HA einstellen und auch einen automatischen Zeilendurchlauf habe ich mit eingebaut.
Wer mag, hier der Code dazu:
esphome:
name: "giftv2"
friendly_name: GifTV2
platformio_options:
board_build.f_cpu: 160000000L
esp8266:
board: esp12e
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "DeinKEY="
ota:
- platform: esphome
password: "password"
wifi:
ssid: "WiFi"
password: "1234"
min_auth_mode: WPA2
ap:
ssid: "giftv Fallback Hotspot"
password: "12345678"
substitutions:
icon_battery: "\U000F058E"
icon_thermometer: "\U000F050F"
spi:
clk_pin: GPIO14
mosi_pin: GPIO13
interface: hardware
id: spihwd
output:
- platform: esp8266_pwm
pin: GPIO05
frequency: 1000 Hz
id: pwm_output
inverted: true
light:
- platform: monochromatic
name: "Backlight"
output: pwm_output
restore_mode: RESTORE_AND_ON
font:
- file: "gfonts://Roboto"
id: font_large
size: 55
- file: "gfonts://Roboto"
id: font_medium
size: 35
- file: "gfonts://Roboto"
id: font_small
size: 25
time:
- platform: sntp
id: esptime
timezone: Europe/Berlin
servers:
- pool.ntp.org
# GLOBALE VARIABLEN
# ---------------------------------------------------------
globals:
- id: current_page_index
type: int
initial_value: '0'
# SENSOREN
# ---------------------------------------------------------
sensor:
- platform: homeassistant
id: aussen_temp
entity_id: sensor.aussentemperatur_temperatur
internal: false
unit_of_measurement: "°C"
- platform: homeassistant
id: battery_soc
entity_id: sensor.victron_system_battery_soc
internal: false
unit_of_measurement: "%"
- platform: homeassistant
id: daily_pv_energy
entity_id: sensor.erzeugzung_taglich_kombination_solaranlagen
internal: false
unit_of_measurement: "kWh"
- platform: homeassistant
id: aktuell_pv_energy
entity_id: sensor.total_solar_power_kombiniert
internal: false
unit_of_measurement: "W"
- platform: homeassistant
id: total_grid_power_w
entity_id: sensor.total_power
internal: false
unit_of_measurement: "W"
- platform: homeassistant
id: daily_house_consumption
entity_id: sensor.stromverbrauch_taglich
internal: false
unit_of_measurement: "kWh"
- platform: wifi_signal
id: wifi_strength
name: "WiFi Signalstärke"
unit_of_measurement: "dBm"
update_interval: 60s
# SCHALTER (Auto-Rotate)
# ---------------------------------------------------------
switch:
- platform: template
name: "Automatisch Wechseln"
id: switch_auto_rotate
icon: "mdi:autorenew"
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
# INTERVAL (Auto-Rotate)
# ---------------------------------------------------------
interval:
- interval: 5s
then:
- if:
condition:
switch.is_on: switch_auto_rotate
then:
- lambda: |-
id(current_page_index) += 1;
// 5 Optionen (0 bis 4: Solar W, Solar kWh, Netz W, Netz kWh, Temp)
// Batterie und Wifi sind raus.
if (id(current_page_index) > 4) {
id(current_page_index) = 0;
}
# SELECT (Konfig Home Assistant)
# ---------------------------------------------------------
select:
- platform: template
name: "Anzeige Zeile 1"
id: disp_select_line1
optimistic: true
restore_value: true
initial_option: "Solar kW"
options:
- "Solar kW"
- "Solar kWh"
- "Netz kW"
- "Netz kWh"
- "Batterie"
- "Temperatur"
- "WiFi"
- "Leer"
- platform: template
name: "Anzeige Zeile 2"
id: disp_select_line2
optimistic: true
restore_value: true
initial_option: "Solar kWh"
options:
- "Solar kW"
- "Solar kWh"
- "Netz kW"
- "Netz kWh"
- "Batterie"
- "Temperatur"
- "WiFi"
- "Leer"
# DISPLAY
# ---------------------------------------------------------
display:
- id: my_display
platform: mipi_spi
model: st7789v
spi_id: spihwd
dimensions:
height: 240
width: 240
update_interval: 1s
buffer_size: 12.5%
invert_colors: true
dc_pin: GPIO00
reset_pin: GPIO02
color_depth: 16
spi_mode: mode3
data_rate: 40000000
auto_clear_enabled: false
transform:
swap_xy: false
mirror_x: true
mirror_y: false
lambda: |-
it.fill(Color(0, 0, 0));
// --- DEFINITIONEN ---
int box_x = 30;
int box_y = 105;
int box_w = 90;
int box_h = 30;
int r1_lbl_y = box_y + box_h + 25;
int r1_val_y = box_y + box_h + 20;
int r1_lbl_x = box_x - 20;
int r1_val_x = box_x + 135;
int r2_lbl_y = box_y + box_h + 68;
int r2_val_y = box_y + box_h + 63;
int r2_lbl_x = box_x - 20;
int r2_val_x = box_x + 135;
// LOGIK AUTO-ROTATE
// -----------------------------------------------------------
// Batterie entfernt
std::string options[] = {"Solar kW", "Solar kWh", "Netz kW", "Netz kWh", "Temperatur"};
int options_count = 5;
// *** FIX: Klammern () hinzugefügt ***
std::string val_s1 = id(disp_select_line1).current_option();
std::string val_s2 = id(disp_select_line2).current_option();
std::string s1 = val_s1;
std::string s2 = val_s2;
if (id(switch_auto_rotate).state) {
int idx1 = id(current_page_index) % options_count;
int idx2 = (id(current_page_index) + 1) % options_count;
s1 = options[idx1];
s2 = options[idx2];
}
// 1. HEADER BEREICH
// -----------------------------------------------------------
float temp = id(aussen_temp).state;
Color temp_color = Color(200, 220, 255);
if (!isnan(temp)) {
it.printf(5, 5, id(font_small), temp_color, "%.1f°C", temp);
} else {
it.print(5, 5, id(font_small), Color(100, 100, 100), "--°C");
}
it.strftime(120, 65, id(font_large), Color(0, 0, 255), TextAlign::CENTER, "%H:%M", id(esptime).now());
if (!global_api_server->is_connected()) {
it.filled_circle(230, 230, 3, Color(255, 0, 0));
}
int rssi = WiFi.RSSI();
int bars = 0;
if (rssi > -50) bars = 3;
else if (rssi > -60) bars = 2;
else if (rssi > -70) bars = 1;
int bx = 200; int by = 15; int bar_w = 6; int bar_gap = 5;
for (int i = 0; i < 3; i++) {
int h = (i + 1) * 3;
Color col = (i < bars) ? Color(0, 255, 0) : Color(40, 40, 40);
it.filled_rectangle(bx + i * (bar_w + bar_gap), by - h, bar_w, h, col);
}
// 2. BATTERIE
// -----------------------------------------------------------
float soc = id(battery_soc).state;
if (isnan(soc)) { soc = 0; }
int red = (int)(255 * (100 - soc) / 100);
int green = (int)(255 * soc / 100);
Color soc_color;
if (soc == 0 && isnan(id(battery_soc).state)) {
soc_color = Color(100, 100, 100);
} else {
soc_color = Color(red, green, 0);
}
it.rectangle(box_x, box_y, box_w, box_h, Color(255, 255, 255));
it.rectangle(box_x + box_w, box_y + 7, 6, box_h - 14, Color(255, 255, 255));
int fill_width = (int)(box_w * soc / 100.0);
if (fill_width > 0) {
it.filled_rectangle(box_x + 1, box_y + 1, fill_width - 2, box_h - 2, soc_color);
}
if (!isnan(id(battery_soc).state)) {
it.printf(box_x + box_w + 25, box_y - 2, id(font_medium), soc_color, "%.0f%%", soc);
} else {
it.print(box_x + box_w + 25, box_y - 2, id(font_medium), Color(100,100,100), "--%");
}
// 3. VARIABLE ZEILEN
// -----------------------------------------------------------
// --- ZEILE 1 RENDER ---
if (s1 == "Solar kW") {
float val = id(aktuell_pv_energy).state / 1000.0;
it.print(r1_lbl_x, r1_lbl_y, id(font_small), Color::WHITE, "Solar kW:");
if (!isnan(val)) it.printf(r1_val_x, r1_val_y, id(font_medium), Color(211, 117, 17), "%.1f", val);
else it.print(r1_val_x, r1_val_y, id(font_medium), Color(100,100,100), "--");
}
else if (s1 == "Solar kWh") {
float val = id(daily_pv_energy).state;
it.print(r1_lbl_x, r1_lbl_y, id(font_small), Color::WHITE, "Solar kWh:");
if (!isnan(val)) it.printf(r1_val_x, r1_val_y, id(font_medium), Color(72, 211, 17), "%.1f", val);
else it.print(r1_val_x, r1_val_y, id(font_medium), Color(100,100,100), "--");
}
else if (s1 == "Netz kW") {
float val = id(total_grid_power_w).state / 1000.0;
it.print(r1_lbl_x, r1_lbl_y, id(font_small), Color::WHITE, "Netz kW:");
if (!isnan(val)) it.printf(r1_val_x, r1_val_y, id(font_medium), Color(0, 255, 255), "%.1f", val);
else it.print(r1_val_x, r1_val_y, id(font_medium), Color(100,100,100), "--");
}
else if (s1 == "Netz kWh") {
float val = id(daily_house_consumption).state;
it.print(r1_lbl_x, r1_lbl_y, id(font_small), Color::WHITE, "Haus kWh:");
if (!isnan(val)) it.printf(r1_val_x, r1_val_y, id(font_medium), Color(255, 0, 255), "%.1f", val);
else it.print(r1_val_x, r1_val_y, id(font_medium), Color(100,100,100), "--");
}
else if (s1 == "Batterie") {
float val = id(battery_soc).state;
it.print(r1_lbl_x, r1_lbl_y, id(font_small), Color::WHITE, "Akku SoC:");
if (!isnan(val)) it.printf(r1_val_x, r1_val_y, id(font_medium), soc_color, "%.0f%%", val);
else it.print(r1_val_x, r1_val_y, id(font_medium), Color(100,100,100), "--");
}
else if (s1 == "Temperatur") {
float val = id(aussen_temp).state;
it.print(r1_lbl_x, r1_lbl_y, id(font_small), Color::WHITE, "Aussen:");
if (!isnan(val)) it.printf(r1_val_x, r1_val_y, id(font_medium), temp_color, "%.1f", val);
else it.print(r1_val_x, r1_val_y, id(font_medium), Color(100,100,100), "--");
}
else if (s1 == "WiFi") {
float val = id(wifi_strength).state;
it.print(r1_lbl_x, r1_lbl_y, id(font_small), Color::WHITE, "WiFi Signal:");
if (!isnan(val)) it.printf(r1_val_x, r1_val_y, id(font_medium), Color::WHITE, "%.0f", val);
}
// --- ZEILE 2 RENDER ---
if (s2 == "Solar kW") {
float val = id(aktuell_pv_energy).state / 1000.0;
it.print(r2_lbl_x, r2_lbl_y, id(font_small), Color::WHITE, "Solar kW:");
if (!isnan(val)) it.printf(r2_val_x, r2_val_y, id(font_medium), Color(211, 117, 17), "%.1f", val);
else it.print(r2_val_x, r2_val_y, id(font_medium), Color(100,100,100), "--");
}
else if (s2 == "Solar kWh") {
float val = id(daily_pv_energy).state;
it.print(r2_lbl_x, r2_lbl_y, id(font_small), Color::WHITE, "Solar kWh:");
if (!isnan(val)) it.printf(r2_val_x, r2_val_y, id(font_medium), Color(72, 211, 17), "%.1f", val);
else it.print(r2_val_x, r2_val_y, id(font_medium), Color(100,100,100), "--");
}
else if (s2 == "Netz kW") {
float val = id(total_grid_power_w).state / 1000.0;
it.print(r2_lbl_x, r2_lbl_y, id(font_small), Color::WHITE, "Netz kW:");
if (!isnan(val)) it.printf(r2_val_x, r2_val_y, id(font_medium), Color(0, 255, 255), "%.1f", val);
else it.print(r2_val_x, r2_val_y, id(font_medium), Color(100,100,100), "--");
}
else if (s2 == "Netz kWh") {
float val = id(daily_house_consumption).state;
it.print(r2_lbl_x, r2_lbl_y, id(font_small), Color::WHITE, "Haus kWh:");
if (!isnan(val)) it.printf(r2_val_x, r2_val_y, id(font_medium), Color(255, 0, 255), "%.1f", val);
else it.print(r2_val_x, r2_val_y, id(font_medium), Color(100,100,100), "--");
}
else if (s2 == "Batterie") {
float val = id(battery_soc).state;
it.print(r2_lbl_x, r2_lbl_y, id(font_small), Color::WHITE, "Akku SoC:");
if (!isnan(val)) it.printf(r2_val_x, r2_val_y, id(font_medium), soc_color, "%.0f%%", val);
else it.print(r2_val_x, r2_val_y, id(font_medium), Color(100,100,100), "--");
}
else if (s2 == "Temperatur") {
float val = id(aussen_temp).state;
it.print(r2_lbl_x, r2_lbl_y, id(font_small), Color::WHITE, "Aussen:");
if (!isnan(val)) it.printf(r2_val_x, r2_val_y, id(font_medium), temp_color, "%.1f", val);
else it.print(r2_val_x, r2_val_y, id(font_medium), Color(100,100,100), "--");
}
else if (s2 == "WiFi") {
float val = id(wifi_strength).state;
it.print(r2_lbl_x, r2_lbl_y, id(font_small), Color::WHITE, "WiFi Signal:");
if (!isnan(val)) it.printf(r2_val_x, r2_val_y, id(font_medium), Color::WHITE, "%.0f", val);
}


