Guest User

Heltec Vision Master E290 Home Assistant

a guest
Jul 30th, 2025
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
YAML 8.07 KB | None | 0 0
  1. esphome:
  2.   name: availability-display
  3.   friendly_name: Availability Display
  4.   on_boot:
  5.     priority: 550.0 # Runs after WiFi/MQTT typically connect
  6.     then:
  7.       - logger.log: "Device booted. Initial status: '${current_status}'. Waiting for MQTT or deep sleep timeout."
  8.       - switch.turn_on: eink_power_enable # Ensures E-Ink controller is powered
  9.       # E-ink power will remain ON until an MQTT message is processed or deep sleep.
  10.  
  11. logger:
  12.  # Default baud_rate is 115200. You can change it if needed.
  13.   # level: DEBUG # Uncomment for more verbose logging during troubleshooting
  14.  
  15. esp32:
  16.   board: esp32-s3-devkitc-1
  17.   framework:
  18.     type: arduino
  19.  
  20. api:
  21.   encryption:
  22.     key: "##################################"
  23.  
  24. ota:
  25.   - platform: esphome
  26.     password: "###############################"
  27.  
  28. wifi:
  29.   id: wifi_component
  30.   ssid: !secret wifi_ssid
  31.   password: !secret wifi_password
  32.   power_save_mode: HIGH
  33.  
  34. mqtt:
  35.   id: mqtt_component
  36.   broker: !secret mqtt_broker_ip
  37.   username: !secret mqtt_username
  38.   password: !secret mqtt_password
  39.  
  40.   on_message:
  41.     - topic: availability/display
  42.       then:
  43.        # Step 1: Lambda to check if status has changed and set a flag
  44.         - lambda: |-
  45.             ESP_LOGD("custom", "MQTT message received. Payload (x): '%s', Current Status: '%s'", x.c_str(), id(current_status).c_str());
  46.             if (id(current_status) != x) {
  47.               ESP_LOGI("custom", "Status changed from '%s' to '%s'. Update required.", id(current_status).c_str(), x.c_str());
  48.               id(current_status) = x; // Update the global status variable
  49.               id(display_update_required) = true;
  50.             } else {
  51.               ESP_LOGI("custom", "Status is the same ('%s'). No display update required.", x.c_str());
  52.               id(display_update_required) = false;
  53.             }
  54.         # Step 2: Conditionally perform display update actions if the flag is true
  55.         - if:
  56.             condition:
  57.               lambda: 'return id(display_update_required);'
  58.             then:
  59.               - logger.log: "Conditional update: Powering on peripherals for display update."
  60.               # Ensure eink_power_enable is on
  61.               - if:
  62.                   condition:
  63.                     lambda: 'return !id(eink_power_enable).state;'
  64.                   then:
  65.                     - switch.turn_on: eink_power_enable
  66.               - output.turn_on: battery_adc_enable    # Power on for battery reading
  67.               - delay: 200ms                          # ADC stabilization
  68.               - lambda: |-                            # Lambda to trigger raw voltage sensor update
  69.                   ESP_LOGD("custom", "Triggering battery_voltage_raw sensor update.");
  70.                   id(battery_voltage_raw).update();
  71.               - delay: 50ms                           # Allow raw voltage sensor to process
  72.               - lambda: |-                            # Lambda to trigger battery percentage sensor update
  73.                   ESP_LOGD("custom", "Triggering battery_percentage sensor update.");
  74.                   id(battery_percentage).update();
  75.               - delay: 50ms                           # Allow percentage sensor to process
  76.               - lambda: |-                            # Lambda to trigger display update
  77.                   ESP_LOGD("custom", "Triggering eink_display update.");
  78.                   id(eink_display).update();
  79.               - delay: 3s                             # Wait for E-Ink to finish updating
  80.               # Peripherals are turned off in the next step, ensuring they are off before sleep
  81.             else:
  82.               - logger.log: "Conditional update: No status change, skipping display update actions."
  83.               # If no display update was required, but eink_power was on from boot, turn it off.
  84.               # This ensures power is saved if the device just idles until deep_sleep_ctrl timeout
  85.               - if:
  86.                   condition:
  87.                     lambda: 'return id(eink_power_enable).state;'
  88.                   then:
  89.                     - switch.turn_off: eink_power_enable
  90.                     - logger.log: "Turned off E-Ink power as no update was needed."
  91.        
  92.         # Step 3: Always turn off peripherals (if they were on) and enter deep sleep
  93.         # Note: battery_adc_enable is turned on only if display_update_required is true
  94.         - logger.log: "Preparing for deep sleep. Turning off eink_power (if on) and battery_adc (if on)."
  95.         - if: # Ensure eink_power_enable is off
  96.             condition:
  97.               lambda: 'return id(eink_power_enable).state;'
  98.             then:
  99.               - switch.turn_off: eink_power_enable
  100.         - output.turn_off: battery_adc_enable
  101.         - logger.log: "Peripherals OFF. Entering deep sleep."
  102.         - deep_sleep.enter: deep_sleep_ctrl
  103.  
  104. spi:
  105.   clk_pin: GPIO2
  106.   mosi_pin: GPIO1
  107.  
  108. globals:
  109.   - id: current_status
  110.     type: std::string
  111.     restore_value: yes # Restores status from flash on boot
  112.     initial_value: '"Away"'
  113.   - id: display_update_required # Flag to indicate if a display update is needed
  114.     type: bool
  115.     initial_value: 'false'
  116.   # Removed show_loading_message global
  117.  
  118. switch:
  119.   - platform: gpio
  120.     pin: GPIO18
  121.     id: eink_power_enable
  122.     name: "E-Ink Power Enable"
  123.     restore_mode: ALWAYS_OFF # Should be off unless explicitly turned on
  124.  
  125. output:
  126.   - platform: gpio
  127.     pin: GPIO46
  128.     id: battery_adc_enable
  129.     # Default state for output is off.
  130.  
  131. font:
  132.   - file: "gfonts://Cherry Bomb One"
  133.     id: display_font
  134.     size: 46
  135.   - file: "gfonts://Cherry Bomb One"
  136.     id: medium_display_font
  137.     size: 30
  138.   - file: "gfonts://Roboto"
  139.     id: small_display_font
  140.     size: 12
  141.   - file: "gfonts://Material+Symbols+Rounded"
  142.     id: icon_font
  143.     size: 10
  144.     glyphs: ["\U0000f305"] # Example Wi-Fi icon
  145.  
  146. display:
  147.   - platform: waveshare_epaper
  148.     id: eink_display
  149.     cs_pin: GPIO3
  150.     dc_pin: GPIO4
  151.     busy_pin: GPIO6
  152.     reset_pin: GPIO5
  153.     reset_duration: 100ms
  154.     model: 2.90inv2-r2
  155.     full_update_every: 10
  156.     update_interval: never
  157.     rotation: 270
  158.     lambda: |-
  159.       // Reverted: No "Loading..." message logic here
  160.       it.print(5, 5, id(icon_font), "\U0000f305");  
  161.       if (!isnan(id(battery_percentage).state)) {
  162.         it.printf(18, 7, id(small_display_font), "%.0f%%", id(battery_percentage).state);  
  163.       } else {
  164.         it.print(18, 7, id(small_display_font), "--%");
  165.       }
  166.       std::string status_text;
  167.       esphome::display::BaseFont *current_font;
  168.       if (id(current_status) == "Home_Free") {
  169.         status_text = "Come on in!";
  170.         current_font = id(display_font);
  171.       } else if (id(current_status) == "Home_Busy") {
  172.         status_text = "Busy ;)";  
  173.         current_font = id(display_font);  
  174.       } else {
  175.         status_text = "Not home right now";
  176.         current_font = id(medium_display_font);  
  177.       }
  178.       it.print(it.get_width() / 2, it.get_height() / 2, current_font, TextAlign::CENTER, status_text.c_str());  
  179.  
  180. sensor:
  181.   - platform: adc
  182.     pin: GPIO7
  183.     name: "Battery Voltage Raw"
  184.     id: battery_voltage_raw
  185.     attenuation: 12db
  186.     update_interval: 1h
  187.     unit_of_measurement: 'V'
  188.     filters:
  189.       - multiply: 4.9
  190.   - platform: template
  191.     name: "Battery Percentage"
  192.     id: battery_percentage
  193.     unit_of_measurement: '%'
  194.     accuracy_decimals: 0
  195.     lambda: |-
  196.       if (!id(battery_voltage_raw).has_state()) {
  197.         return NAN;
  198.       }
  199.       float voltage = id(battery_voltage_raw).state;
  200.       const float BATTERY_FULL_VOLTAGE = 4.2;
  201.       const float BATTERY_EMPTY_VOLTAGE = 3.0;
  202.       float percentage = ((voltage - BATTERY_EMPTY_VOLTAGE) / (BATTERY_FULL_VOLTAGE - BATTERY_EMPTY_VOLTAGE)) * 100.0;
  203.       if (percentage > 100.0) percentage = 100.0;
  204.       if (percentage < 0.0) percentage = 0.0;
  205.       return percentage;
  206.     update_interval: 1h
  207.  
  208. deep_sleep:
  209.   id: deep_sleep_ctrl
  210.   sleep_duration: 5min
  211.   wakeup_pin:
  212.     number: GPIO21
  213.     mode: INPUT_PULLUP
  214.     inverted: True
  215.  
Advertisement
Add Comment
Please, Sign In to add comment