esphome: name: esphome-web-4fc3ec friendly_name: oled little guy min_version: 2024.11.0 name_add_mac_suffix: false esp32: board: esp32dev framework: type: esp-idf # Enable logging logger: # Enable Home Assistant API api: ota: platform: esphome wifi: ssid: "DNTD" password: "wifipassword" # BLE Tracker and Proxy esp32_ble_tracker: scan_parameters: active: false bluetooth_proxy: active: true sensor: - platform: homeassistant id: temperature entity_id: weather.home attribute: temperature internal: true time: - platform: homeassistant id: esptime # Define global variable for the page globals: - id: page type: int restore_value: no initial_value: '0' # I2C Configuration for OLED Display i2c: sda: GPIO21 scl: GPIO22 scan: true # OLED Display Configuration display: - platform: ssd1306_i2c model: "SSD1306 128x64" address: 0x3C rotation: 0 lambda: |- if (id(page) == 0) { std::string weather_text = id(weather_condition).state.c_str(); // Wrap the weather text if it exceeds 16 characters if (weather_text.length() > 16) { it.print(0, 0, id(font1), weather_text.substr(0, 16).c_str()); it.print(0, 20, id(font1), weather_text.substr(16).c_str()); } else { it.print(0, 0, id(font1), weather_text.c_str()); } // Temperature char temp_str[20]; snprintf(temp_str, sizeof(temp_str), "%d°F", (int) id(temperature).state); if (strlen(temp_str) > 16) { it.print(0, 40, id(font1), temp_str); } else { it.print(0, 40, id(font1), temp_str); } } else if (id(page) == 1) { // Date & Time std::string time_str = id(esptime).now().strftime("%I:%M %p"); if (time_str.length() > 16) { it.print(0, 0, id(font1), time_str.substr(0, 16).c_str()); it.print(0, 20, id(font1), time_str.substr(16).c_str()); } else { it.print(0, 0, id(font1), time_str.c_str()); } } else if (id(page) == 2) { // Date (e.g., "Wed 04/03") std::string date_str = id(esptime).now().strftime("%a %m/%d"); if (date_str.length() > 16) { it.print(0, 0, id(font1), date_str.substr(0, 16).c_str()); it.print(0, 20, id(font1), date_str.substr(16).c_str()); } else { it.print(0, 0, id(font1), date_str.c_str()); } } else if (id(page) == 3) { // Retrieve the state of the sensor for today (Day 0) std::string condition_day_0 = to_string(id(home_condition_day_0).state); // Log the state for debugging ESP_LOGD("custom", "Condition Day 0: %s", condition_day_0.c_str()); // Check if the state is available and assign a default value if not if (condition_day_0.empty()) { condition_day_0 = "No data"; // Default text if the state is empty } // Create a display string for Day 0 (today) std::string display_text_0 = "Today: " + condition_day_0; // Define the maximum number of characters per line based on display width const int max_chars_per_line = 24; // Adjusted to 24 characters per line int start = 0; int y_offset = 0; // Vertical position for the next line // Loop through the display text and split it into lines if needed while (start < display_text_0.length()) { // Get the next substring (line) std::string line = display_text_0.substr(start, max_chars_per_line); it.print(0, y_offset, id(font3), line.c_str()); // Print each line at the proper position // Update start to the next portion of text start += max_chars_per_line; y_offset += 10; // Halved vertical space between lines } } else if (id(page) == 4) { // Retrieve the state of the sensor for tomorrow (Day 1) std::string condition_day_1 = to_string(id(home_condition_day_1).state); // Log the state for debugging ESP_LOGD("custom", "Condition Day 1: %s", condition_day_1.c_str()); // Check if the state is available and assign a default value if not if (condition_day_1.empty()) { condition_day_1 = "No data"; // Default text if the state is empty } // Create a display string for Day 1 (tomorrow) std::string display_text_1 = "Tomorrow: " + condition_day_1; // Define the maximum number of characters per line based on display width const int max_chars_per_line = 24; // Adjusted to 24 characters per line int start = 0; int y_offset = 0; // Vertical position for the next line // Loop through the display text and split it into lines if needed while (start < display_text_1.length()) { // Get the next substring (line) std::string line = display_text_1.substr(start, max_chars_per_line); it.print(0, y_offset, id(font3), line.c_str()); // Print each line at the proper position // Update start to the next portion of text start += max_chars_per_line; y_offset += 10; // Halved vertical space between lines } } else if (id(page) == 5) { // Media Title and Artist std::string media_title = id(media_title_sensor).state.c_str(); std::string media_artist = id(media_artist_sensor).state.c_str(); // Check if either media title or media artist is empty and display "No music playing" if (media_title.empty() || media_artist.empty()) { media_title = "No music playing"; // Default message if no music is playing media_artist.clear(); // Clear artist to prevent extra text } // Display media title if (media_title.length() > 16) { it.print(0, 0, id(font2), media_title.substr(0, 16).c_str()); it.print(0, 20, id(font2), media_title.substr(16).c_str()); } else { it.print(0, 0, id(font2), media_title.c_str()); } // Display media artist if it's not empty if (!media_artist.empty()) { if (media_artist.length() > 16) { it.print(0, 40, id(font2), media_artist.substr(0, 16).c_str()); it.print(0, 60, id(font2), media_artist.substr(16).c_str()); } else { it.print(0, 40, id(font2), media_artist.c_str()); } } } # Define Font for OLED font: - file: "gfonts://Roboto" id: font1 size: 22 - file: "gfonts://Roboto" id: font2 size: 12 - file: "gfonts://Roboto" id: font3 size: 10 # Text sensors for weather and location information text_sensor: - platform: homeassistant id: weather_condition entity_id: weather.home internal: true - platform: homeassistant id: media_title_sensor entity_id: media_player.deepthought attribute: media_title - platform: homeassistant id: media_artist_sensor entity_id: media_player.deepthought attribute: media_artist - platform: homeassistant id: home_condition_day_0 entity_id: sensor.home_condition_day_0 internal: true - platform: homeassistant id: home_condition_day_1 entity_id: sensor.home_condition_day_1 internal: true interval: - interval: 5s then: - lambda: |- id(page) = (id(page) + 1) % 6;