Add the on_page_change display trigger (#1687)

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
Stanislav Meduna 2021-05-23 22:56:04 +02:00 committed by GitHub
parent cccb1a2c9e
commit 072dce340e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 68 additions and 2 deletions

View file

@ -2,7 +2,16 @@ import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import core, automation
from esphome.automation import maybe_simple_id
from esphome.const import CONF_ID, CONF_LAMBDA, CONF_PAGES, CONF_PAGE_ID, CONF_ROTATION
from esphome.const import (
CONF_ID,
CONF_LAMBDA,
CONF_PAGES,
CONF_PAGE_ID,
CONF_ROTATION,
CONF_FROM,
CONF_TO,
CONF_TRIGGER_ID,
)
from esphome.core import coroutine_with_priority
IS_PLATFORM_COMPONENT = True
@ -22,6 +31,9 @@ DisplayPageShowPrevAction = display_ns.class_(
DisplayIsDisplayingPageCondition = display_ns.class_(
"DisplayIsDisplayingPageCondition", automation.Condition
)
DisplayOnPageChangeTrigger = display_ns.class_("DisplayOnPageChangeTrigger")
CONF_ON_PAGE_CHANGE = "on_page_change"
DISPLAY_ROTATIONS = {
0: display_ns.DISPLAY_ROTATION_0_DEGREES,
@ -56,6 +68,15 @@ FULL_DISPLAY_SCHEMA = BASIC_DISPLAY_SCHEMA.extend(
),
cv.Length(min=1),
),
cv.Optional(CONF_ON_PAGE_CHANGE): automation.validate_automation(
{
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
DisplayOnPageChangeTrigger
),
cv.Optional(CONF_FROM): cv.use_id(DisplayPage),
cv.Optional(CONF_TO): cv.use_id(DisplayPage),
}
),
}
)
@ -72,6 +93,17 @@ async def setup_display_core_(var, config):
page = cg.new_Pvariable(conf[CONF_ID], lambda_)
pages.append(page)
cg.add(var.set_pages(pages))
for conf in config.get(CONF_ON_PAGE_CHANGE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
if CONF_FROM in conf:
page = await cg.get_variable(conf[CONF_FROM])
cg.add(trigger.set_from(page))
if CONF_TO in conf:
page = await cg.get_variable(conf[CONF_TO])
cg.add(trigger.set_to(page))
await automation.build_automation(
trigger, [(DisplayPagePtr, "from"), (DisplayPagePtr, "to")], conf
)
async def register_display(var, config):

View file

@ -315,7 +315,14 @@ void DisplayBuffer::set_pages(std::vector<DisplayPage *> pages) {
pages[pages.size() - 1]->set_next(pages[0]);
this->show_page(pages[0]);
}
void DisplayBuffer::show_page(DisplayPage *page) { this->page_ = page; }
void DisplayBuffer::show_page(DisplayPage *page) {
this->previous_page_ = this->page_;
this->page_ = page;
if (this->previous_page_ != this->page_) {
for (auto *t : on_page_change_triggers_)
t->process(this->previous_page_, this->page_);
}
}
void DisplayBuffer::show_next_page() { this->page_->show_next(); }
void DisplayBuffer::show_prev_page() { this->page_->show_prev(); }
void DisplayBuffer::do_update_() {
@ -326,6 +333,10 @@ void DisplayBuffer::do_update_() {
(*this->writer_)(*this);
}
}
void DisplayOnPageChangeTrigger::process(DisplayPage *from, DisplayPage *to) {
if ((this->from_ == nullptr || this->from_ == from) && (this->to_ == nullptr || this->to_ == to))
this->trigger(from, to);
}
#ifdef USE_TIME
void DisplayBuffer::strftime(int x, int y, Font *font, Color color, TextAlign align, const char *format,
time::ESPTime time) {

View file

@ -81,6 +81,7 @@ class Font;
class Image;
class DisplayBuffer;
class DisplayPage;
class DisplayOnPageChangeTrigger;
using display_writer_t = std::function<void(DisplayBuffer &)>;
@ -298,6 +299,8 @@ class DisplayBuffer {
const DisplayPage *get_active_page() const { return this->page_; }
void add_on_page_change_trigger(DisplayOnPageChangeTrigger *t) { this->on_page_change_triggers_.push_back(t); }
/// Internal method to set the display rotation with.
void set_rotation(DisplayRotation rotation);
@ -318,6 +321,8 @@ class DisplayBuffer {
DisplayRotation rotation_{DISPLAY_ROTATION_0_DEGREES};
optional<display_writer_t> writer_{};
DisplayPage *page_{nullptr};
DisplayPage *previous_page_{nullptr};
std::vector<DisplayOnPageChangeTrigger *> on_page_change_triggers_;
};
class DisplayPage {
@ -465,5 +470,17 @@ template<typename... Ts> class DisplayIsDisplayingPageCondition : public Conditi
DisplayPage *page_;
};
class DisplayOnPageChangeTrigger : public Trigger<DisplayPage *, DisplayPage *> {
public:
explicit DisplayOnPageChangeTrigger(DisplayBuffer *parent) { parent->add_on_page_change_trigger(this); }
void process(DisplayPage *from, DisplayPage *to);
void set_from(DisplayPage *p) { this->from_ = p; }
void set_to(DisplayPage *p) { this->to_ = p; }
protected:
DisplayPage *from_{nullptr};
DisplayPage *to_{nullptr};
};
} // namespace display
} // namespace esphome

View file

@ -1874,6 +1874,12 @@ display:
- id: page2
lambda: |-
// Nothing
on_page_change:
from: page1
to: page2
then:
lambda: |-
ESP_LOGD("display", "1 -> 2");
- platform: ssd1306_spi
model: 'SSD1306 128x64'
cs_pin: GPIO23