mirror of
https://github.com/esphome/esphome.git
synced 2024-12-12 08:24:55 +01:00
Add support for TextPanels grabbing their content from Sensors and TextSensors
This commit is contained in:
parent
c018ba2ac3
commit
4e37a09310
3 changed files with 89 additions and 17 deletions
|
@ -3,6 +3,8 @@
|
||||||
#include "esphome/components/display/display.h"
|
#include "esphome/components/display/display.h"
|
||||||
#include "esphome/components/display/rect.h"
|
#include "esphome/components/display/rect.h"
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
|
#include <iomanip>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace graphical_layout {
|
namespace graphical_layout {
|
||||||
|
@ -14,10 +16,47 @@ static const int TEXT_ALIGN_Y_MASK =
|
||||||
|
|
||||||
void TextPanel::dump_config(int indent_depth, int additional_level_depth) {
|
void TextPanel::dump_config(int indent_depth, int additional_level_depth) {
|
||||||
this->dump_config_base_properties(TAG, indent_depth);
|
this->dump_config_base_properties(TAG, indent_depth);
|
||||||
std::string text = this->text_.value();
|
std::string text = this->text_input_.value();
|
||||||
ESP_LOGCONFIG(TAG, "%*sText Align: %s", indent_depth, "",
|
ESP_LOGCONFIG(TAG, "%*sText Align: %s", indent_depth, "",
|
||||||
LOG_STR_ARG(display::text_align_to_string(this->text_align_)));
|
LOG_STR_ARG(display::text_align_to_string(this->text_align_)));
|
||||||
ESP_LOGCONFIG(TAG, "%*sText: %s", indent_depth, "", text.c_str());
|
ESP_LOGCONFIG(TAG, "%*sText: %s", indent_depth, "", text.c_str());
|
||||||
|
if (this->sensor_ != nullptr) {
|
||||||
|
ESP_LOGCONFIG(TAG, "%*sSensor: %s", indent_depth, "", this->sensor_->get_name());
|
||||||
|
}
|
||||||
|
if (this->text_sensor_ != nullptr) {
|
||||||
|
ESP_LOGCONFIG(TAG, "%*sText Sensor: %s", indent_depth, "", this->text_sensor_->get_name());
|
||||||
|
}
|
||||||
|
ESP_LOGCONFIG(TAG, "%*sHas Text Formatter: %s", indent_depth, "", YESNO(!this->text_formatter_.has_value()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextPanel::setup_complete() {
|
||||||
|
if (!this->text_formatter_.has_value()) {
|
||||||
|
this->text_formatter_ = [this](const std::string string) {
|
||||||
|
return string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->sensor_ != nullptr) {
|
||||||
|
// Need to setup the text callback for the sensor
|
||||||
|
this->text_ = [this]() {
|
||||||
|
std::stringstream stream;
|
||||||
|
stream << std::fixed << std::setprecision(this->sensor_->get_accuracy_decimals()) << this->sensor_->get_state();
|
||||||
|
return this->text_formatter_.value(stream.str());
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->text_sensor_ != nullptr) {
|
||||||
|
// Need to setup the text callback to the TextSensor
|
||||||
|
this->text_ = [this]() {
|
||||||
|
return this->text_formatter_.value(this->text_sensor_->get_state());
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->text_input_.has_value()) {
|
||||||
|
this->text_ = [this]() {
|
||||||
|
return this->text_formatter_.value(this->text_input_.value());
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
display::Rect TextPanel::measure_item_internal(display::Display *display) {
|
display::Rect TextPanel::measure_item_internal(display::Display *display) {
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include "esphome/components/graphical_layout/graphical_layout.h"
|
#include "esphome/components/graphical_layout/graphical_layout.h"
|
||||||
#include "esphome/components/font/font.h"
|
#include "esphome/components/font/font.h"
|
||||||
#include "esphome/core/automation.h"
|
#include "esphome/core/automation.h"
|
||||||
|
#include "esphome/components/sensor/sensor.h"
|
||||||
|
#include "esphome/components/text_sensor/text_sensor.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace graphical_layout {
|
namespace graphical_layout {
|
||||||
|
@ -15,8 +17,12 @@ class TextPanel : public LayoutItem {
|
||||||
display::Rect measure_item_internal(display::Display *display) override;
|
display::Rect measure_item_internal(display::Display *display) override;
|
||||||
void render_internal(display::Display *display, display::Rect bounds) override;
|
void render_internal(display::Display *display, display::Rect bounds) override;
|
||||||
void dump_config(int indent_depth, int additional_level_depth) override;
|
void dump_config(int indent_depth, int additional_level_depth) override;
|
||||||
|
void setup_complete() override;
|
||||||
|
|
||||||
template<typename V> void set_text(V text) { this->text_ = text; };
|
template<typename V> void set_text(V text) { this->text_input_ = text; };
|
||||||
|
void set_sensor(sensor::Sensor *sensor) { this->sensor_ = sensor; };
|
||||||
|
void set_text_sensor(text_sensor::TextSensor *text_sensor) { this->text_sensor_ = text_sensor; };
|
||||||
|
template<typename V> void set_text_formatter(V text_formatter) { this->text_formatter_ = text_formatter; };
|
||||||
void set_font(display::BaseFont *font) { this->font_ = font; };
|
void set_font(display::BaseFont *font) { this->font_ = font; };
|
||||||
void set_foreground_color(Color foreground_color) { this->foreground_color_ = foreground_color; };
|
void set_foreground_color(Color foreground_color) { this->foreground_color_ = foreground_color; };
|
||||||
void set_background_color(Color background_color) { this->background_color_ = background_color; };
|
void set_background_color(Color background_color) { this->background_color_ = background_color; };
|
||||||
|
@ -24,6 +30,10 @@ class TextPanel : public LayoutItem {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TemplatableValue<std::string> text_{};
|
TemplatableValue<std::string> text_{};
|
||||||
|
sensor::Sensor *sensor_{nullptr};
|
||||||
|
text_sensor::TextSensor *text_sensor_{nullptr};
|
||||||
|
TemplatableValue<std::string, const std::string> text_formatter_{};
|
||||||
|
TemplatableValue<std::string> text_input_{};
|
||||||
display::BaseFont *font_{nullptr};
|
display::BaseFont *font_{nullptr};
|
||||||
display::TextAlign text_align_{display::TextAlign::TOP_LEFT};
|
display::TextAlign text_align_{display::TextAlign::TOP_LEFT};
|
||||||
Color foreground_color_{COLOR_ON};
|
Color foreground_color_{COLOR_ON};
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.components import font, color
|
from esphome.components import font, color, sensor, text_sensor
|
||||||
from esphome.components.display import display_ns
|
from esphome.components.display import display_ns
|
||||||
from esphome.const import CONF_FOREGROUND_COLOR, CONF_BACKGROUND_COLOR
|
from esphome.const import CONF_FOREGROUND_COLOR, CONF_BACKGROUND_COLOR, CONST_SENSOR
|
||||||
|
|
||||||
graphical_layout_ns = cg.esphome_ns.namespace("graphical_layout")
|
graphical_layout_ns = cg.esphome_ns.namespace("graphical_layout")
|
||||||
TextPanel = graphical_layout_ns.class_("TextPanel")
|
TextPanel = graphical_layout_ns.class_("TextPanel")
|
||||||
|
@ -12,6 +12,8 @@ CONF_TEXT_PANEL = "text_panel"
|
||||||
CONF_FONT = "font"
|
CONF_FONT = "font"
|
||||||
CONF_TEXT = "text"
|
CONF_TEXT = "text"
|
||||||
CONF_TEXT_ALIGN = "text_align"
|
CONF_TEXT_ALIGN = "text_align"
|
||||||
|
CONF_TEXT_SENSOR = "text_sensor"
|
||||||
|
CONF_TEXT_FORMATTER = "text_formatter"
|
||||||
|
|
||||||
TEXT_ALIGN = {
|
TEXT_ALIGN = {
|
||||||
"TOP_LEFT": TextAlign.TOP_LEFT,
|
"TOP_LEFT": TextAlign.TOP_LEFT,
|
||||||
|
@ -30,15 +32,21 @@ TEXT_ALIGN = {
|
||||||
|
|
||||||
|
|
||||||
def get_config_schema(base_item_schema, item_type_schema):
|
def get_config_schema(base_item_schema, item_type_schema):
|
||||||
return base_item_schema.extend(
|
return cv.All(
|
||||||
{
|
base_item_schema.extend(
|
||||||
cv.GenerateID(): cv.declare_id(TextPanel),
|
{
|
||||||
cv.Required(CONF_FONT): cv.use_id(font.Font),
|
cv.GenerateID(): cv.declare_id(TextPanel),
|
||||||
cv.Optional(CONF_FOREGROUND_COLOR): cv.use_id(color.ColorStruct),
|
cv.Required(CONF_FONT): cv.use_id(font.Font),
|
||||||
cv.Optional(CONF_BACKGROUND_COLOR): cv.use_id(color.ColorStruct),
|
cv.Optional(CONF_FOREGROUND_COLOR): cv.use_id(color.ColorStruct),
|
||||||
cv.Required(CONF_TEXT): cv.templatable(cv.string),
|
cv.Optional(CONF_BACKGROUND_COLOR): cv.use_id(color.ColorStruct),
|
||||||
cv.Optional(CONF_TEXT_ALIGN): cv.enum(TEXT_ALIGN, upper=True),
|
cv.Optional(CONF_TEXT): cv.templatable(cv.string),
|
||||||
}
|
cv.Optional(CONF_TEXT_ALIGN): cv.enum(TEXT_ALIGN, upper=True),
|
||||||
|
cv.Optional(CONF_SENSOR): cv.use_id(sensor.Sensor),
|
||||||
|
cv.Optional(CONF_TEXT_SENSOR): cv.use_id(text_sensor.TextSensor),
|
||||||
|
cv.Optional(CONF_TEXT_FORMATTER): cv.returning_lambda,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
cv.has_exactly_one_key(CONF_TEXT, CONF_SENSOR, CONF_TEXT_SENSOR),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,10 +64,25 @@ async def config_to_layout_item(pvariable_builder, item_config, child_item_build
|
||||||
background_color = await cg.get_variable(background_color_config)
|
background_color = await cg.get_variable(background_color_config)
|
||||||
cg.add(var.set_background_color(background_color))
|
cg.add(var.set_background_color(background_color))
|
||||||
|
|
||||||
text = await cg.templatable(
|
if sensor_config := item_config.get(CONF_SENSOR):
|
||||||
item_config[CONF_TEXT], args=[], output_type=cg.std_string
|
sens = await cg.get_variable(sensor_config)
|
||||||
)
|
cg.add(var.set_sensor(sens))
|
||||||
cg.add(var.set_text(text))
|
elif text_sensor_config := item_config.get(CONF_TEXT_SENSOR):
|
||||||
|
text_sens = await cg.get_variable(text_sensor_config)
|
||||||
|
cg.add(var.set_text_sensor(text_sens))
|
||||||
|
else:
|
||||||
|
text = await cg.templatable(
|
||||||
|
item_config[CONF_TEXT], args=[], output_type=cg.std_string
|
||||||
|
)
|
||||||
|
cg.add(var.set_text(text))
|
||||||
|
|
||||||
|
if text_formatter_config := item_config.get(CONF_TEXT_FORMATTER):
|
||||||
|
text_formatter = await cg.process_lambda(
|
||||||
|
text_formatter_config,
|
||||||
|
[(cg.std_string, "it")],
|
||||||
|
return_type=cg.std_string,
|
||||||
|
)
|
||||||
|
cg.add(var.set_text_formatter(text_formatter))
|
||||||
|
|
||||||
if text_align := item_config.get(CONF_TEXT_ALIGN):
|
if text_align := item_config.get(CONF_TEXT_ALIGN):
|
||||||
cg.add(var.set_text_align(text_align))
|
cg.add(var.set_text_align(text_align))
|
||||||
|
|
Loading…
Reference in a new issue