mirror of
				https://github.com/esphome/esphome.git
				synced 2025-11-04 00:51:49 +00:00 
			
		
		
		
	Compare commits
	
		
			2 Commits
		
	
	
		
			jesserockz
			...
			jesserockz
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					b6e0502203 | ||
| 
						 | 
					6d427bec49 | 
@@ -139,6 +139,7 @@ esphome/components/ens160_base/* @latonita @vincentscode
 | 
				
			|||||||
esphome/components/ens160_i2c/* @latonita
 | 
					esphome/components/ens160_i2c/* @latonita
 | 
				
			||||||
esphome/components/ens160_spi/* @latonita
 | 
					esphome/components/ens160_spi/* @latonita
 | 
				
			||||||
esphome/components/ens210/* @itn3rd77
 | 
					esphome/components/ens210/* @itn3rd77
 | 
				
			||||||
 | 
					esphome/components/epdiy/* @jesserockz
 | 
				
			||||||
esphome/components/es7210/* @kahrendt
 | 
					esphome/components/es7210/* @kahrendt
 | 
				
			||||||
esphome/components/es7243e/* @kbx81
 | 
					esphome/components/es7243e/* @kbx81
 | 
				
			||||||
esphome/components/es8156/* @kbx81
 | 
					esphome/components/es8156/* @kbx81
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										0
									
								
								esphome/components/epdiy/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								esphome/components/epdiy/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										107
									
								
								esphome/components/epdiy/display.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								esphome/components/epdiy/display.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,107 @@
 | 
				
			|||||||
 | 
					import esphome.codegen as cg
 | 
				
			||||||
 | 
					from esphome.components import display, esp32
 | 
				
			||||||
 | 
					import esphome.config_validation as cv
 | 
				
			||||||
 | 
					from esphome.const import (
 | 
				
			||||||
 | 
					    CONF_FULL_UPDATE_EVERY,
 | 
				
			||||||
 | 
					    CONF_ID,
 | 
				
			||||||
 | 
					    CONF_LAMBDA,
 | 
				
			||||||
 | 
					    CONF_MODEL,
 | 
				
			||||||
 | 
					    CONF_PAGES,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					from esphome.cpp_generator import MockObj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CODEOWNERS = ["@jesserockz"]
 | 
				
			||||||
 | 
					DEPENDENCIES = ["esp32", "psram"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CONF_POWER_OFF_DELAY_ENABLED = "power_off_delay_enabled"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					epdiy_ns = cg.esphome_ns.namespace("epdiy")
 | 
				
			||||||
 | 
					EPDiyDisplay = epdiy_ns.class_("EPDiyDisplay", display.Display)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class EpdBoardDefinition(MockObj):
 | 
				
			||||||
 | 
					    def __str__(self):
 | 
				
			||||||
 | 
					        return f"&{self.base}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class EpdDisplay_t(MockObj):
 | 
				
			||||||
 | 
					    def __str__(self):
 | 
				
			||||||
 | 
					        return f"&{self.base}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EpdInitOptions = cg.global_ns.enum("EpdInitOptions")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Model:
 | 
				
			||||||
 | 
					    def __init__(
 | 
				
			||||||
 | 
					        self,
 | 
				
			||||||
 | 
					        *,
 | 
				
			||||||
 | 
					        board_definition: MockObj,
 | 
				
			||||||
 | 
					        display_t: MockObj,
 | 
				
			||||||
 | 
					        init_options: MockObj,
 | 
				
			||||||
 | 
					        width: int,
 | 
				
			||||||
 | 
					        height: int,
 | 
				
			||||||
 | 
					        vcom_mv: int = 0,
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
 | 
					        self.board_definition = board_definition
 | 
				
			||||||
 | 
					        self.display_t = display_t
 | 
				
			||||||
 | 
					        self.init_options = init_options
 | 
				
			||||||
 | 
					        self.width = width
 | 
				
			||||||
 | 
					        self.height = height
 | 
				
			||||||
 | 
					        self.vcom_mv = vcom_mv
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MODELS: dict[str, Model] = {
 | 
				
			||||||
 | 
					    "lilygo_t5_4.7": Model(
 | 
				
			||||||
 | 
					        board_definition=EpdBoardDefinition("epd_board_lilygo_t5_47"),
 | 
				
			||||||
 | 
					        display_t=EpdDisplay_t("ED047TC2"),
 | 
				
			||||||
 | 
					        init_options=(EpdInitOptions.EPD_LUT_64K, EpdInitOptions.EPD_FEED_QUEUE_8),
 | 
				
			||||||
 | 
					        width=960,
 | 
				
			||||||
 | 
					        height=540,
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CONFIG_SCHEMA = cv.All(
 | 
				
			||||||
 | 
					    display.FULL_DISPLAY_SCHEMA.extend(
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            cv.GenerateID(): cv.declare_id(EPDiyDisplay),
 | 
				
			||||||
 | 
					            cv.Required(CONF_MODEL): cv.one_of(*MODELS.keys()),
 | 
				
			||||||
 | 
					            cv.Optional(CONF_FULL_UPDATE_EVERY, default=10): cv.uint32_t,
 | 
				
			||||||
 | 
					            cv.Optional(CONF_POWER_OFF_DELAY_ENABLED, default=False): cv.boolean,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ).extend(cv.polling_component_schema("60s")),
 | 
				
			||||||
 | 
					    cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA),
 | 
				
			||||||
 | 
					    cv.only_with_esp_idf,  # When trying to add library via platformio it breaks, using as an idf component works fine
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async def to_code(config):
 | 
				
			||||||
 | 
					    var = cg.new_Pvariable(config[CONF_ID])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await display.register_display(var, config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    model = MODELS[config[CONF_MODEL]]
 | 
				
			||||||
 | 
					    cg.add(
 | 
				
			||||||
 | 
					        var.set_model_details(
 | 
				
			||||||
 | 
					            model.board_definition,
 | 
				
			||||||
 | 
					            model.display_t,
 | 
				
			||||||
 | 
					            cg.RawExpression(
 | 
				
			||||||
 | 
					                f"static_cast<EpdInitOptions>({'|'.join(str(o) for o in model.init_options)})"
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            model.vcom_mv,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if CONF_LAMBDA in config:
 | 
				
			||||||
 | 
					        lambda_ = await cg.process_lambda(
 | 
				
			||||||
 | 
					            config[CONF_LAMBDA], [(display.DisplayRef, "it")], return_type=cg.void
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        cg.add(var.set_writer(lambda_))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cg.add(var.set_power_off_delay_enabled(config[CONF_POWER_OFF_DELAY_ENABLED]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    esp32.add_idf_component(
 | 
				
			||||||
 | 
					        name="vroland/epdiy",
 | 
				
			||||||
 | 
					        repo="https://github.com/vroland/epdiy",
 | 
				
			||||||
 | 
					        ref="c61e9e923ce2418150d54f88cea5d196cdc40c54",
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
							
								
								
									
										76
									
								
								esphome/components/epdiy/epdiy_display.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								esphome/components/epdiy/epdiy_display.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
				
			|||||||
 | 
					#include "epdiy_display.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "esphome/core/application.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef USE_ESP_IDF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "esphome/core/log.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace esphome::epdiy {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char *const TAG = "epdiy";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static constexpr uint8_t TEMPERATURE = 23;  // default temperature for e-paper displays
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float EPDiyDisplay::get_setup_priority() const { return esphome::setup_priority::LATE; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void EPDiyDisplay::setup() {
 | 
				
			||||||
 | 
					  epd_init(this->board_definition_, this->display_t_, this->init_options_);
 | 
				
			||||||
 | 
					  if (this->vcom_mv_ != 0) {
 | 
				
			||||||
 | 
					    epd_set_vcom(this->vcom_mv_);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  this->state_ = epd_hl_init(nullptr);
 | 
				
			||||||
 | 
					  this->framebuffer_ = epd_hl_get_framebuffer(&this->state_);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void EPDiyDisplay::update() {
 | 
				
			||||||
 | 
					  this->do_update_();
 | 
				
			||||||
 | 
					  this->defer([this]() { this->flush_screen_changes_(); });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void EPDiyDisplay::fill(Color color) {
 | 
				
			||||||
 | 
					  if (color == display::COLOR_OFF) {
 | 
				
			||||||
 | 
					    memset(this->framebuffer_, 0xFF, this->get_buffer_length());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    epd_poweron();
 | 
				
			||||||
 | 
					    epd_hl_update_screen(&this->state_, MODE_GC16, TEMPERATURE);
 | 
				
			||||||
 | 
					    epd_clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    epd_poweroff();
 | 
				
			||||||
 | 
					    App.feed_wdt();
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    Display::fill(color);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void EPDiyDisplay::flush_screen_changes_() {
 | 
				
			||||||
 | 
					  epd_poweron();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  epd_hl_update_screen(&this->state_, MODE_GC16, TEMPERATURE);
 | 
				
			||||||
 | 
					  memset(this->state_.back_fb, 0xFF, this->get_buffer_length());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  uint16_t delay = 0;
 | 
				
			||||||
 | 
					  if (this->power_off_delay_enabled_) {
 | 
				
			||||||
 | 
					    delay = 700;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  this->set_timeout("poweroff", delay, []() { epd_poweroff(); });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void EPDiyDisplay::on_shutdown() {
 | 
				
			||||||
 | 
					  epd_poweroff();
 | 
				
			||||||
 | 
					  epd_deinit();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void HOT EPDiyDisplay::draw_pixel_at(int x, int y, Color color) {
 | 
				
			||||||
 | 
					  if (color.red == 255 && color.green == 255 && color.blue == 255) {
 | 
				
			||||||
 | 
					    epd_draw_pixel(x, y, 0, this->framebuffer_);
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    int col = (0.2126 * color.red) + (0.7152 * color.green) + (0.0722 * color.blue);
 | 
				
			||||||
 | 
					    int cl = 255 - col;
 | 
				
			||||||
 | 
					    epd_draw_pixel(x, y, cl, this->framebuffer_);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace esphome::epdiy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  // USE_ESP_IDF
 | 
				
			||||||
							
								
								
									
										63
									
								
								esphome/components/epdiy/epdiy_display.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								esphome/components/epdiy/epdiy_display.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef USE_ESP_IDF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "esphome/core/component.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "esphome/components/display/display_buffer.h"
 | 
				
			||||||
 | 
					#include "esphome/components/display/display_color_utils.h"
 | 
				
			||||||
 | 
					#include "esphome/core/hal.h"
 | 
				
			||||||
 | 
					#include "esphome/core/version.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "epd_display.h"
 | 
				
			||||||
 | 
					#include "epd_highlevel.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace esphome::epdiy {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class EPDiyDisplay : public display::Display {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  float get_setup_priority() const override;
 | 
				
			||||||
 | 
					  void setup() override;
 | 
				
			||||||
 | 
					  void update() override;
 | 
				
			||||||
 | 
					  void on_shutdown() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  display::DisplayType get_display_type() override { return display::DisplayType::DISPLAY_TYPE_GRAYSCALE; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int get_width_internal() override { return this->display_t_->width; };
 | 
				
			||||||
 | 
					  int get_height_internal() override { return this->display_t_->height; };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  size_t get_buffer_length() const { return this->display_t_->width / 2 * this->display_t_->height; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void set_power_off_delay_enabled(bool power_off_delay_enabled) {
 | 
				
			||||||
 | 
					    this->power_off_delay_enabled_ = power_off_delay_enabled;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void set_model_details(const EpdBoardDefinition *board_definition, const EpdDisplay_t *display_t,
 | 
				
			||||||
 | 
					                         enum EpdInitOptions init_options, uint16_t vcom) {
 | 
				
			||||||
 | 
					    this->board_definition_ = board_definition;
 | 
				
			||||||
 | 
					    this->display_t_ = display_t;
 | 
				
			||||||
 | 
					    this->init_options_ = init_options;
 | 
				
			||||||
 | 
					    this->vcom_mv_ = vcom;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void fill(Color color) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void draw_pixel_at(int x, int y, Color color) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 protected:
 | 
				
			||||||
 | 
					  void flush_screen_changes_();
 | 
				
			||||||
 | 
					  EpdiyHighlevelState state_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  uint8_t *framebuffer_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const EpdBoardDefinition *board_definition_;
 | 
				
			||||||
 | 
					  const EpdDisplay_t *display_t_;
 | 
				
			||||||
 | 
					  enum EpdInitOptions init_options_;
 | 
				
			||||||
 | 
					  uint16_t vcom_mv_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool power_off_delay_enabled_;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace esphome::epdiy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  // USE_ESP_IDF
 | 
				
			||||||
@@ -19,3 +19,6 @@ dependencies:
 | 
				
			|||||||
      - if: "target in [esp32h2, esp32p4]"
 | 
					      - if: "target in [esp32h2, esp32p4]"
 | 
				
			||||||
  zorxx/multipart-parser:
 | 
					  zorxx/multipart-parser:
 | 
				
			||||||
    version: 1.0.1
 | 
					    version: 1.0.1
 | 
				
			||||||
 | 
					  vroland/epdiy:
 | 
				
			||||||
 | 
					    git: https://github.com/vroland/epdiy.git
 | 
				
			||||||
 | 
					    version: c61e9e923ce2418150d54f88cea5d196cdc40c54
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user