mirror of
				https://github.com/esphome/esphome.git
				synced 2025-11-04 00:51:49 +00:00 
			
		
		
		
	Compare commits
	
		
			2 Commits
		
	
	
		
			dependabot
			...
			jesserockz
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					b6e0502203 | ||
| 
						 | 
					6d427bec49 | 
@@ -139,6 +139,7 @@ esphome/components/ens160_base/* @latonita @vincentscode
 | 
			
		||||
esphome/components/ens160_i2c/* @latonita
 | 
			
		||||
esphome/components/ens160_spi/* @latonita
 | 
			
		||||
esphome/components/ens210/* @itn3rd77
 | 
			
		||||
esphome/components/epdiy/* @jesserockz
 | 
			
		||||
esphome/components/es7210/* @kahrendt
 | 
			
		||||
esphome/components/es7243e/* @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]"
 | 
			
		||||
  zorxx/multipart-parser:
 | 
			
		||||
    version: 1.0.1
 | 
			
		||||
  vroland/epdiy:
 | 
			
		||||
    git: https://github.com/vroland/epdiy.git
 | 
			
		||||
    version: c61e9e923ce2418150d54f88cea5d196cdc40c54
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user