Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- esphome:
- name: availability-display
- friendly_name: Availability Display
- on_boot:
- priority: 550.0 # Runs after WiFi/MQTT typically connect
- then:
- - logger.log: "Device booted. Initial status: '${current_status}'. Waiting for MQTT or deep sleep timeout."
- - switch.turn_on: eink_power_enable # Ensures E-Ink controller is powered
- # E-ink power will remain ON until an MQTT message is processed or deep sleep.
- logger:
- # Default baud_rate is 115200. You can change it if needed.
- # level: DEBUG # Uncomment for more verbose logging during troubleshooting
- esp32:
- board: esp32-s3-devkitc-1
- framework:
- type: arduino
- api:
- encryption:
- key: "##################################"
- ota:
- - platform: esphome
- password: "###############################"
- wifi:
- id: wifi_component
- ssid: !secret wifi_ssid
- password: !secret wifi_password
- power_save_mode: HIGH
- mqtt:
- id: mqtt_component
- broker: !secret mqtt_broker_ip
- username: !secret mqtt_username
- password: !secret mqtt_password
- on_message:
- - topic: availability/display
- then:
- # Step 1: Lambda to check if status has changed and set a flag
- - lambda: |-
- ESP_LOGD("custom", "MQTT message received. Payload (x): '%s', Current Status: '%s'", x.c_str(), id(current_status).c_str());
- if (id(current_status) != x) {
- ESP_LOGI("custom", "Status changed from '%s' to '%s'. Update required.", id(current_status).c_str(), x.c_str());
- id(current_status) = x; // Update the global status variable
- id(display_update_required) = true;
- } else {
- ESP_LOGI("custom", "Status is the same ('%s'). No display update required.", x.c_str());
- id(display_update_required) = false;
- }
- # Step 2: Conditionally perform display update actions if the flag is true
- - if:
- condition:
- lambda: 'return id(display_update_required);'
- then:
- - logger.log: "Conditional update: Powering on peripherals for display update."
- # Ensure eink_power_enable is on
- - if:
- condition:
- lambda: 'return !id(eink_power_enable).state;'
- then:
- - switch.turn_on: eink_power_enable
- - output.turn_on: battery_adc_enable # Power on for battery reading
- - delay: 200ms # ADC stabilization
- - lambda: |- # Lambda to trigger raw voltage sensor update
- ESP_LOGD("custom", "Triggering battery_voltage_raw sensor update.");
- id(battery_voltage_raw).update();
- - delay: 50ms # Allow raw voltage sensor to process
- - lambda: |- # Lambda to trigger battery percentage sensor update
- ESP_LOGD("custom", "Triggering battery_percentage sensor update.");
- id(battery_percentage).update();
- - delay: 50ms # Allow percentage sensor to process
- - lambda: |- # Lambda to trigger display update
- ESP_LOGD("custom", "Triggering eink_display update.");
- id(eink_display).update();
- - delay: 3s # Wait for E-Ink to finish updating
- # Peripherals are turned off in the next step, ensuring they are off before sleep
- else:
- - logger.log: "Conditional update: No status change, skipping display update actions."
- # If no display update was required, but eink_power was on from boot, turn it off.
- # This ensures power is saved if the device just idles until deep_sleep_ctrl timeout
- - if:
- condition:
- lambda: 'return id(eink_power_enable).state;'
- then:
- - switch.turn_off: eink_power_enable
- - logger.log: "Turned off E-Ink power as no update was needed."
- # Step 3: Always turn off peripherals (if they were on) and enter deep sleep
- # Note: battery_adc_enable is turned on only if display_update_required is true
- - logger.log: "Preparing for deep sleep. Turning off eink_power (if on) and battery_adc (if on)."
- - if: # Ensure eink_power_enable is off
- condition:
- lambda: 'return id(eink_power_enable).state;'
- then:
- - switch.turn_off: eink_power_enable
- - output.turn_off: battery_adc_enable
- - logger.log: "Peripherals OFF. Entering deep sleep."
- - deep_sleep.enter: deep_sleep_ctrl
- spi:
- clk_pin: GPIO2
- mosi_pin: GPIO1
- globals:
- - id: current_status
- type: std::string
- restore_value: yes # Restores status from flash on boot
- initial_value: '"Away"'
- - id: display_update_required # Flag to indicate if a display update is needed
- type: bool
- initial_value: 'false'
- # Removed show_loading_message global
- switch:
- - platform: gpio
- pin: GPIO18
- id: eink_power_enable
- name: "E-Ink Power Enable"
- restore_mode: ALWAYS_OFF # Should be off unless explicitly turned on
- output:
- - platform: gpio
- pin: GPIO46
- id: battery_adc_enable
- # Default state for output is off.
- font:
- - file: "gfonts://Cherry Bomb One"
- id: display_font
- size: 46
- - file: "gfonts://Cherry Bomb One"
- id: medium_display_font
- size: 30
- - file: "gfonts://Roboto"
- id: small_display_font
- size: 12
- - file: "gfonts://Material+Symbols+Rounded"
- id: icon_font
- size: 10
- glyphs: ["\U0000f305"] # Example Wi-Fi icon
- display:
- - platform: waveshare_epaper
- id: eink_display
- cs_pin: GPIO3
- dc_pin: GPIO4
- busy_pin: GPIO6
- reset_pin: GPIO5
- reset_duration: 100ms
- model: 2.90inv2-r2
- full_update_every: 10
- update_interval: never
- rotation: 270
- lambda: |-
- // Reverted: No "Loading..." message logic here
- it.print(5, 5, id(icon_font), "\U0000f305");
- if (!isnan(id(battery_percentage).state)) {
- it.printf(18, 7, id(small_display_font), "%.0f%%", id(battery_percentage).state);
- } else {
- it.print(18, 7, id(small_display_font), "--%");
- }
- std::string status_text;
- esphome::display::BaseFont *current_font;
- if (id(current_status) == "Home_Free") {
- status_text = "Come on in!";
- current_font = id(display_font);
- } else if (id(current_status) == "Home_Busy") {
- status_text = "Busy ;)";
- current_font = id(display_font);
- } else {
- status_text = "Not home right now";
- current_font = id(medium_display_font);
- }
- it.print(it.get_width() / 2, it.get_height() / 2, current_font, TextAlign::CENTER, status_text.c_str());
- sensor:
- - platform: adc
- pin: GPIO7
- name: "Battery Voltage Raw"
- id: battery_voltage_raw
- attenuation: 12db
- update_interval: 1h
- unit_of_measurement: 'V'
- filters:
- - multiply: 4.9
- - platform: template
- name: "Battery Percentage"
- id: battery_percentage
- unit_of_measurement: '%'
- accuracy_decimals: 0
- lambda: |-
- if (!id(battery_voltage_raw).has_state()) {
- return NAN;
- }
- float voltage = id(battery_voltage_raw).state;
- const float BATTERY_FULL_VOLTAGE = 4.2;
- const float BATTERY_EMPTY_VOLTAGE = 3.0;
- float percentage = ((voltage - BATTERY_EMPTY_VOLTAGE) / (BATTERY_FULL_VOLTAGE - BATTERY_EMPTY_VOLTAGE)) * 100.0;
- if (percentage > 100.0) percentage = 100.0;
- if (percentage < 0.0) percentage = 0.0;
- return percentage;
- update_interval: 1h
- deep_sleep:
- id: deep_sleep_ctrl
- sleep_duration: 5min
- wakeup_pin:
- number: GPIO21
- mode: INPUT_PULLUP
- inverted: True
Advertisement
Add Comment
Please, Sign In to add comment