Last active
February 1, 2026 14:47
-
-
Save jakesOneFourSeven/64620e6b8df7d24cad17ec803a0773e6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| esphome: | |
| name: esphome-web-41bcfc | |
| friendly_name: 'CYD Pip-Boy' | |
| min_version: 2024.11.0 | |
| name_add_mac_suffix: false | |
| esp32: | |
| variant: esp32 | |
| framework: | |
| type: esp-idf | |
| logger: | |
| api: | |
| ota: | |
| - platform: esphome | |
| wifi: | |
| ssid: !secret wifi_ssid | |
| password: !secret wifi_password | |
| spi: | |
| - id: bus_display | |
| clk_pin: GPIO14 | |
| mosi_pin: GPIO13 | |
| miso_pin: GPIO12 | |
| - id: bus_touch | |
| clk_pin: GPIO25 | |
| mosi_pin: GPIO32 | |
| miso_pin: GPIO39 | |
| display: | |
| - platform: ili9xxx | |
| id: my_display | |
| model: ILI9341 | |
| spi_id: bus_display | |
| cs_pin: GPIO15 | |
| dc_pin: GPIO2 | |
| reset_pin: GPIO4 | |
| rotation: 180° | |
| invert_colors: false | |
| dimensions: | |
| width: 320 | |
| height: 240 | |
| update_interval: never | |
| auto_clear_enabled: false | |
| touchscreen: | |
| platform: xpt2046 | |
| id: ts | |
| spi_id: bus_touch | |
| cs_pin: GPIO33 | |
| interrupt_pin: GPIO36 | |
| calibration: | |
| x_min: 221 | |
| x_max: 3748 | |
| y_min: 282 | |
| y_max: 3796 | |
| transform: | |
| swap_xy: true | |
| mirror_x: true | |
| mirror_y: false | |
| output: | |
| - platform: ledc | |
| pin: GPIO21 | |
| id: backlight_pwm | |
| light: | |
| - platform: monochromatic | |
| output: backlight_pwm | |
| id: backlight | |
| name: "Display Backlight" | |
| restore_mode: ALWAYS_ON | |
| time: | |
| - platform: homeassistant | |
| id: ha_time | |
| font: | |
| - file: "gfonts://Roboto+Mono@700" | |
| id: font_large | |
| size: 24 | |
| - file: "gfonts://Roboto+Mono@400" | |
| id: font_small | |
| size: 14 | |
| - file: "gfonts://Material+Symbols+Outlined" | |
| id: icon_font | |
| size: 40 | |
| glyphs: | |
| - "\U0000E80B" # Bolt | |
| - "\U0000E1AF" # Flow | |
| - "\U0000E2BE" # Battery | |
| globals: | |
| - id: pv_prod | |
| type: float | |
| initial_value: '0.0' | |
| - id: house_load | |
| type: float | |
| initial_value: '0.0' | |
| - id: batt_soc_val | |
| type: float | |
| initial_value: '0.0' | |
| - id: inv_power | |
| type: float | |
| initial_value: '0.0' | |
| - id: batt_power | |
| type: float | |
| initial_value: '0.0' | |
| lvgl: | |
| touchscreens: | |
| - touchscreen_id: ts | |
| buffer_size: 10% | |
| style_definitions: | |
| - id: pipboy_green_text | |
| text_color: 0x00FF00 | |
| text_font: font_small | |
| - id: pipboy_green_large | |
| text_color: 0x00FF00 | |
| text_font: font_large | |
| - id: pipboy_icons | |
| text_color: 0x00FF00 | |
| text_font: icon_font | |
| - id: page_style | |
| bg_color: 0x000000 | |
| - id: header_style | |
| bg_color: 0x001A00 | |
| border_width: 0 | |
| radius: 0 | |
| - id: bar_bg_style | |
| bg_color: 0x001100 | |
| border_color: 0x00FF00 | |
| border_width: 1 | |
| - id: switch_base_style | |
| bg_color: 0x000000 | |
| border_color: 0x00FF00 | |
| border_width: 2 | |
| radius: 4 | |
| - id: pivot_style | |
| bg_color: 0x00FF00 | |
| radius: 10 | |
| pages: | |
| - id: page_main | |
| styles: page_style | |
| widgets: | |
| # Background click listener | |
| - obj: | |
| width: 100% | |
| height: 100% | |
| bg_opa: 0% | |
| clickable: true | |
| on_click: | |
| then: | |
| - lvgl.page.show: page_switches | |
| # Header | |
| - obj: | |
| width: 310 | |
| height: 28 | |
| x: 5 | |
| y: 0 | |
| styles: header_style | |
| widgets: | |
| - label: | |
| align: left_mid | |
| pad_left: 5 | |
| text: "PIP-BOY 3000 MK V" | |
| styles: pipboy_green_text | |
| - label: | |
| id: clock_label | |
| align: right_mid | |
| text: "00:00" | |
| styles: pipboy_green_text | |
| # Grid Lines | |
| - obj: { width: 320, height: 1, y: 105, bg_color: 0x00FF00, bg_opa: 15% } | |
| - obj: { width: 320, height: 1, y: 190, bg_color: 0x00FF00, bg_opa: 15% } | |
| # Column 1: LOAD | |
| - label: | |
| x: 0 | |
| y: 40 | |
| width: 106 | |
| text_align: center | |
| text: "\U0000E80B" | |
| styles: pipboy_icons | |
| - label: | |
| x: 0 | |
| y: 120 | |
| width: 106 | |
| text_align: center | |
| text: "VAULT LOAD" | |
| styles: pipboy_green_text | |
| - label: | |
| id: house_value | |
| x: 0 | |
| y: 145 | |
| width: 106 | |
| text_align: center | |
| text: "0" | |
| styles: pipboy_green_large | |
| # Column 2: RADS (Ticks only) | |
| - meter: | |
| id: pv_meter | |
| x: 115 | |
| y: 35 | |
| width: 90 | |
| height: 90 | |
| bg_opa: 0% | |
| border_width: 0 | |
| scales: | |
| - range_from: 0 | |
| range_to: 5000 | |
| angle_range: 240 | |
| rotation: 150 | |
| ticks: | |
| count: 11 | |
| length: 6 | |
| width: 2 | |
| color: 0x004400 | |
| major: | |
| stride: 2 | |
| length: 10 | |
| width: 3 | |
| color: 0x00FF00 | |
| indicators: | |
| - line: | |
| id: pv_needle | |
| width: 5 | |
| color: 0x00FF00 | |
| r_mod: -12 | |
| # Pivot Dot for Needle | |
| - obj: | |
| x: 155 | |
| y: 75 | |
| width: 10 | |
| height: 10 | |
| styles: pivot_style | |
| - label: | |
| x: 106 | |
| y: 125 | |
| width: 108 | |
| text_align: center | |
| text: "RADS" | |
| styles: pipboy_green_text | |
| - label: | |
| id: pv_value | |
| x: 106 | |
| y: 145 | |
| width: 108 | |
| text_align: center | |
| text: "0" | |
| styles: pipboy_green_large | |
| # Column 3: FLOW | |
| - label: | |
| x: 214 | |
| y: 40 | |
| width: 106 | |
| text_align: center | |
| text: "\U0000E1AF" | |
| styles: pipboy_icons | |
| - label: | |
| x: 214 | |
| y: 120 | |
| width: 106 | |
| text_align: center | |
| text: "FLOW" | |
| styles: pipboy_green_text | |
| - label: | |
| id: inv_value | |
| x: 214 | |
| y: 145 | |
| width: 106 | |
| text_align: center | |
| text: "0" | |
| styles: pipboy_green_large | |
| # Battery Core | |
| - bar: | |
| id: battery_bar | |
| width: 250 | |
| height: 18 | |
| x: 35 | |
| y: 215 | |
| styles: bar_bg_style | |
| - label: | |
| id: battery_label | |
| x: 35 | |
| y: 195 | |
| text: "CORE: 0%" | |
| styles: pipboy_green_text | |
| - id: page_switches | |
| styles: page_style | |
| widgets: | |
| - obj: | |
| width: 310 | |
| height: 28 | |
| x: 5 | |
| y: 0 | |
| styles: header_style | |
| clickable: true | |
| on_click: | |
| then: | |
| - lvgl.page.show: page_main | |
| widgets: | |
| - label: | |
| align: left_mid | |
| pad_left: 5 | |
| text: "SYSTEM CONTROL" | |
| styles: pipboy_green_text | |
| - label: | |
| id: clock_label_sw | |
| align: right_mid | |
| text: "00:00" | |
| styles: pipboy_green_text | |
| # Switch 1 | |
| - label: | |
| x: 30 | |
| y: 60 | |
| text: "MAIN GEYSER" | |
| styles: pipboy_green_text | |
| - switch: | |
| id: sw_widget_main | |
| x: 210 | |
| y: 55 | |
| width: 60 | |
| height: 30 | |
| styles: switch_base_style | |
| on_value: | |
| then: | |
| - if: | |
| condition: { lambda: 'return x;' } | |
| then: [switch.turn_on: main_geyser] | |
| else: [switch.turn_off: main_geyser] | |
| # Switch 2 | |
| - label: | |
| x: 30 | |
| y: 110 | |
| text: "KITCHEN GEYSER" | |
| styles: pipboy_green_text | |
| - switch: | |
| id: sw_widget_kitchen | |
| x: 210 | |
| y: 105 | |
| width: 60 | |
| height: 30 | |
| styles: switch_base_style | |
| on_value: | |
| then: | |
| - if: | |
| condition: { lambda: 'return x;' } | |
| then: [switch.turn_on: kitchen_geyser] | |
| else: [switch.turn_off: kitchen_geyser] | |
| # Switch 3 | |
| - label: | |
| x: 30 | |
| y: 160 | |
| text: "POOL PUMP" | |
| styles: pipboy_green_text | |
| - switch: | |
| id: sw_widget_pool | |
| x: 210 | |
| y: 155 | |
| width: 60 | |
| height: 30 | |
| styles: switch_base_style | |
| on_value: | |
| then: | |
| - if: | |
| condition: { lambda: 'return x;' } | |
| then: [switch.turn_on: pool_pump] | |
| else: [switch.turn_off: pool_pump] | |
| - button: | |
| x: 105 | |
| y: 200 | |
| width: 110 | |
| height: 35 | |
| styles: switch_base_style | |
| widgets: | |
| - label: | |
| align: center | |
| text: "RETURN" | |
| styles: pipboy_green_text | |
| on_click: | |
| then: | |
| - lvgl.page.show: page_main | |
| # HA Integration | |
| switch: | |
| - platform: homeassistant | |
| id: main_geyser | |
| entity_id: switch.sonoff_10025b0b5c | |
| on_state: | |
| then: | |
| - lambda: |- | |
| if (x) lv_obj_add_state(id(sw_widget_main), LV_STATE_CHECKED); | |
| else lv_obj_clear_state(id(sw_widget_main), LV_STATE_CHECKED); | |
| - platform: homeassistant | |
| id: kitchen_geyser | |
| entity_id: switch.sonoff_100258f71c_1 | |
| on_state: | |
| then: | |
| - lambda: |- | |
| if (x) lv_obj_add_state(id(sw_widget_kitchen), LV_STATE_CHECKED); | |
| else lv_obj_clear_state(id(sw_widget_kitchen), LV_STATE_CHECKED); | |
| - platform: homeassistant | |
| id: pool_pump | |
| entity_id: switch.sonoff_100258f5d3_1 | |
| on_state: | |
| then: | |
| - lambda: |- | |
| if (x) lv_obj_add_state(id(sw_widget_pool), LV_STATE_CHECKED); | |
| else lv_obj_clear_state(id(sw_widget_pool), LV_STATE_CHECKED); | |
| script: | |
| - id: refresh_all | |
| then: | |
| - lambda: |- | |
| char buf[32]; | |
| sprintf(buf, "%.0f W", id(pv_prod)); | |
| lv_label_set_text(id(pv_value), buf); | |
| lv_meter_set_indicator_value(id(pv_meter), id(pv_needle), (int32_t)id(pv_prod)); | |
| sprintf(buf, "%.0f W", id(house_load)); | |
| lv_label_set_text(id(house_value), buf); | |
| sprintf(buf, "%.0f W", id(inv_power)); | |
| lv_label_set_text(id(inv_value), buf); | |
| lv_bar_set_value(id(battery_bar), (int)id(batt_soc_val), LV_ANIM_ON); | |
| sprintf(buf, "CORE: %.0f%%", id(batt_soc_val)); | |
| lv_label_set_text(id(battery_label), buf); | |
| sensor: | |
| - platform: homeassistant | |
| id: sensor_pv | |
| entity_id: sensor.esphome_web_f3a4dc_inverterhoas_pv_average_power | |
| on_value: | |
| - globals.set: { id: pv_prod, value: !lambda "return x;" } | |
| - script.execute: refresh_all | |
| - platform: homeassistant | |
| id: sensor_house | |
| entity_id: sensor.electricity_energy_instant_power | |
| on_value: | |
| - globals.set: { id: house_load, value: !lambda "return x;" } | |
| - script.execute: refresh_all | |
| - platform: homeassistant | |
| id: sensor_soc | |
| entity_id: sensor.esphome_web_f3a4dc_inverterhoas_battery_state_of_charge | |
| on_value: | |
| - globals.set: { id: batt_soc_val, value: !lambda "return x;" } | |
| - script.execute: refresh_all | |
| - platform: homeassistant | |
| id: sensor_inv | |
| entity_id: sensor.esphome_web_f3a4dc_inverterhoas_average_inverter_power | |
| on_value: | |
| - globals.set: { id: inv_power, value: !lambda "return x;" } | |
| - script.execute: refresh_all | |
| interval: | |
| - interval: 15s | |
| then: | |
| - lambda: |- | |
| auto t = id(ha_time).now(); | |
| if (t.is_valid()) { | |
| char clock_buf[8]; | |
| t.strftime(clock_buf, sizeof(clock_buf), "%H:%M"); | |
| lv_label_set_text(id(clock_label), clock_buf); | |
| lv_label_set_text(id(clock_label_sw), clock_buf); | |
| } |
it looks nice
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.