mirror of
https://github.com/esphome/esphome.git
synced 2024-12-04 20:48:21 +01:00
set_text action: impl. effect duration and update-interval
This commit is contained in:
parent
3f07667a49
commit
0441dfbd5c
4 changed files with 108 additions and 37 deletions
|
@ -26,14 +26,20 @@ template<typename... Ts> class SetTextAction : public Action<Ts...> {
|
|||
TEMPLATABLE_VALUE(std::string, text_align)
|
||||
TEMPLATABLE_VALUE(std::string, text_effect)
|
||||
TEMPLATABLE_VALUE(uint8_t, text_effect_cycle_num)
|
||||
TEMPLATABLE_VALUE(uint32_t, text_effect_duration)
|
||||
TEMPLATABLE_VALUE(uint32_t, text_effect_update_interval)
|
||||
|
||||
void play(Ts... x) override {
|
||||
auto pos = this->text_position_.value(x...);
|
||||
auto cycle_num = this->text_effect_cycle_num_.value(x...);
|
||||
auto duration = this->text_effect_duration_.value(x...);
|
||||
auto update_interval = this->text_effect_update_interval_.value(x...);
|
||||
this->max9621_->display_->set_text(this->text_.value(x...),
|
||||
this->text_align_.value(x...),
|
||||
this->text_effect_.value(x...),
|
||||
pos,
|
||||
this->text_align_.value(x...),
|
||||
duration,
|
||||
this->text_effect_.value(x...),
|
||||
update_interval,
|
||||
cycle_num);
|
||||
}
|
||||
|
||||
|
|
|
@ -123,6 +123,7 @@ const uint8_t ASCII_TO_SEG[FONT_SIZE] PROGMEM = {
|
|||
|
||||
|
||||
void Display::setup(std::vector<uint8_t>& seg_to_out_map, std::vector<uint8_t>& pos_to_out_map) {
|
||||
this->restore_update_interval_ = 0;
|
||||
this->seg_to_out_map_ = seg_to_out_map;
|
||||
this->pos_to_out_map_ = pos_to_out_map;
|
||||
this->num_digits_ = pos_to_out_map.size();
|
||||
|
@ -163,8 +164,8 @@ void Display::setup(std::vector<uint8_t>& seg_to_out_map, std::vector<uint8_t>&
|
|||
1 // core
|
||||
);
|
||||
|
||||
ESP_LOGCONFIG(TAG, "Display mode: %u", this->mode);
|
||||
ESP_LOGCONFIG(TAG, "Display scroll mode: %u", this->disp_text_.effect);
|
||||
// ESP_LOGCONFIG(TAG, "Display mode: %u", this->mode);
|
||||
// ESP_LOGCONFIG(TAG, "Display text effect: %u", this->disp_text_.effect);
|
||||
}
|
||||
|
||||
void HOT Display::display_refresh_task_(void *pv) {
|
||||
|
@ -303,15 +304,29 @@ void Display::update(void) {
|
|||
set_mode(DISP_MODE_PRINT);
|
||||
break;
|
||||
}
|
||||
if (this->disp_text_.effect == TEXT_EFFECT_NONE) // effect finished?
|
||||
set_mode(DISP_MODE_PRINT); // yes -> switch back to "it" interface
|
||||
if (this->disp_text_.effect == TEXT_EFFECT_NONE) { // effect finished?
|
||||
if (this->restore_update_interval_) { // yes, polling interval changed?
|
||||
ESP_LOGD(TAG, "Restore polling interval: %" PRIu32 "ms", this->restore_update_interval_);
|
||||
this->max6921_->set_update_interval(this->restore_update_interval_);
|
||||
this->restore_update_interval_ = 0;
|
||||
}
|
||||
set_mode(DISP_MODE_PRINT); // switch back to "it" interface
|
||||
}
|
||||
}
|
||||
|
||||
// handle duration...
|
||||
if (this->duration_ms > 0) {
|
||||
if ((millis() - this->duration_ms_start_) >= this->duration_ms) {
|
||||
ESP_LOGD(TAG, "Effect duration of %" PRIu32 "ms expired", this->duration_ms);
|
||||
set_mode(DISP_MODE_PRINT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Display::set_demo_mode(demo_mode_t mode, uint8_t cycle_num) {
|
||||
uint text_idx, font_idx;
|
||||
|
||||
ESP_LOGD(TAG, "demo_mode=%i, cycle_num=%u", mode, cycle_num);
|
||||
ESP_LOGD(TAG, "Set demo mode: mode=%i, cycle_num=%u", mode, cycle_num);
|
||||
// this->display.demo_mode_cycle_num = cycle_num;
|
||||
// this->display.demo_mode = mode;
|
||||
|
||||
|
@ -328,13 +343,14 @@ void Display::set_demo_mode(demo_mode_t mode, uint8_t cycle_num) {
|
|||
}
|
||||
this->disp_text_.text[text_idx] = 0;
|
||||
ESP_LOGV(TAG, "%s(): text: %s", __func__, this->disp_text_.text);
|
||||
|
||||
// set text effect...
|
||||
this->disp_text_.set_text_effect(TEXT_EFFECT_SCROLL_LEFT, cycle_num);
|
||||
set_mode(DISP_MODE_OTHER);
|
||||
break;
|
||||
default:
|
||||
set_mode(DISP_MODE_PRINT);
|
||||
break;
|
||||
}
|
||||
set_mode(DISP_MODE_OTHER);
|
||||
clear();
|
||||
}
|
||||
|
||||
|
@ -352,17 +368,22 @@ void Display::set_demo_mode(const std::string& mode, uint8_t cycle_num) {
|
|||
* @brief Triggered by action. Shows the given text on the display.
|
||||
*
|
||||
* @param text text to display
|
||||
* @param start_pos display position 0..n
|
||||
* @param align text alignment
|
||||
* @param duration text effect duration in ms
|
||||
* @param effect text effect
|
||||
* @param start_pos display position 0..n (optional, default=0)
|
||||
* @param cycle_num text effect cycle count (optional, default=endless)
|
||||
* @param interval text effect update interval in ms
|
||||
* @param cycle_num text effect cycle count
|
||||
*
|
||||
* @return number of characters displayed
|
||||
*/
|
||||
int Display::set_text(const std::string& text, const std::string& align,
|
||||
const std::string& effect, uint8_t start_pos, uint8_t cycle_num) {
|
||||
ESP_LOGD(TAG, "set text (given): text=%s, start-pos=%u, align=%s, effect=%s, cycle-num=%u",
|
||||
text.c_str(), start_pos, align.c_str(), effect.c_str(), cycle_num);
|
||||
int Display::set_text(const std::string& text, uint8_t start_pos, const std::string& align,
|
||||
uint32_t duration, const std::string& effect, uint32_t interval,
|
||||
uint8_t cycle_num) {
|
||||
ESP_LOGD(TAG, "Set text (given): text=%s, start-pos=%u, align=%s, duration=%" PRIu32 ", "\
|
||||
"effect=%s, effect-update-interval=%" PRIu32 ", cycles=%u",
|
||||
text.c_str(), start_pos, align.c_str(), duration, effect.c_str(),
|
||||
interval, cycle_num);
|
||||
|
||||
// store new text...
|
||||
this->disp_text_.set_text(start_pos, this->num_digits_ - 1, text);
|
||||
|
@ -372,11 +393,16 @@ int Display::set_text(const std::string& text, const std::string& align,
|
|||
|
||||
// set text effect...
|
||||
this->disp_text_.set_text_effect(effect, cycle_num);
|
||||
if ((this->disp_text_.effect != TEXT_EFFECT_NONE) && (interval > 0)) {
|
||||
ESP_LOGD(TAG, "Change polling interval: %" PRIu32 "ms", interval);
|
||||
this->restore_update_interval_ = this->max6921_->get_update_interval();
|
||||
this->max6921_->set_update_interval(interval);
|
||||
}
|
||||
|
||||
// update display mode...
|
||||
set_mode(DISP_MODE_OTHER);
|
||||
set_mode(DISP_MODE_OTHER, duration);
|
||||
|
||||
ESP_LOGD(TAG, "set text (result): text=%s, start-pos=%u, vi-idx=%u, vi-len=%u",
|
||||
ESP_LOGD(TAG, "Set text (result): text=%s, start-pos=%u, vi-idx=%u, vi-len=%u",
|
||||
this->disp_text_.text, this->disp_text_.start_pos,
|
||||
this->disp_text_.visible_idx, this->disp_text_.visible_len);
|
||||
|
||||
|
@ -395,7 +421,7 @@ int Display::set_text(const char *text, uint8_t start_pos) {
|
|||
ESP_LOGVV(TAG, "%s(): str=%s, prev=%s", __func__, text, this->disp_text_.text);
|
||||
if (strncmp(text, this->disp_text_.text, sizeof(this->disp_text_.text)) == 0) // text not changed?
|
||||
return strlen(text); // yes -> exit function
|
||||
ESP_LOGV(TAG, "%s(): text changed: str=%s, prev=%s", __func__, text, this->disp_text_.text);
|
||||
ESP_LOGV(TAG, "%s(): Text changed: str=%s, prev=%s", __func__, text, this->disp_text_.text);
|
||||
|
||||
// store new text...
|
||||
std::string text_str = text;
|
||||
|
@ -580,7 +606,7 @@ void DisplayText::set_text_align(text_align_t align)
|
|||
}
|
||||
this->align = align;
|
||||
init_text_align_();
|
||||
ESP_LOGD(TAG, "set align: text=%s, align=%i, start-pos=%u, max-pos=%u, vi-idx=%u, vi-len=%u",
|
||||
ESP_LOGD(TAG, "Set align: text=%s, align=%i, start-pos=%u, max-pos=%u, vi-idx=%u, vi-len=%u",
|
||||
this->text, this->align, this->start_pos, this->max_pos, this->visible_idx, this->visible_len);
|
||||
}
|
||||
|
||||
|
@ -626,7 +652,7 @@ void DisplayText::set_text_effect(text_effect_t effect, uint8_t cycle_num)
|
|||
this->effect = effect;
|
||||
this->cycle_num = cycle_num;
|
||||
init_text_effect_();
|
||||
ESP_LOGD(TAG, "set effect: text=%s, effect=%i, cycles=%u, start-pos=%u, max-pos=%u, vi-idx=%u, vi-len=%u",
|
||||
ESP_LOGD(TAG, "Set effect: text=%s, effect=%i, cycles=%u, start-pos=%u, max-pos=%u, vi-idx=%u, vi-len=%u",
|
||||
this->text, this->effect, this->cycle_num, this->start_pos,
|
||||
this->max_pos, this->visible_idx, this->visible_len);
|
||||
}
|
||||
|
@ -681,10 +707,10 @@ void DisplayText::scroll_left(void) {
|
|||
if (this->visible_len == 0) {
|
||||
init_text_effect_();
|
||||
if (this->cycle_num > 0) {
|
||||
ESP_LOGD(TAG, "scroll cycle finished (%u left)", this->cycle_num-1);
|
||||
ESP_LOGD(TAG, "Scroll cycle finished (%u left)", this->cycle_num-1);
|
||||
if (--this->cycle_num == 0) {
|
||||
this->effect = TEXT_EFFECT_NONE;
|
||||
ESP_LOGD(TAG, "scroll finished");
|
||||
ESP_LOGD(TAG, "Scroll finished");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -739,16 +765,28 @@ void DisplayBrightness::set_brightness(float percent) {
|
|||
*/
|
||||
DisplayMode::DisplayMode() {
|
||||
this->mode = DISP_MODE_PRINT;
|
||||
this->duration_ms = 0; // endless
|
||||
}
|
||||
|
||||
void DisplayMode::set_mode(display_mode_t display_mode) {
|
||||
if (display_mode >= DISP_MODE_LAST_ENUM) {
|
||||
ESP_LOGE(TAG, "Invalid display mode: %i", display_mode);
|
||||
/**
|
||||
* @brief Sets the display mode.
|
||||
*
|
||||
* @param mode display start position of text (0..n)
|
||||
* @param duration duration in ms (optional, default=endless)
|
||||
* not applicable for "it" mode
|
||||
*/
|
||||
void DisplayMode::set_mode(display_mode_t mode, uint32_t duration_ms) {
|
||||
if (mode >= DISP_MODE_LAST_ENUM) {
|
||||
ESP_LOGE(TAG, "Invalid display mode: %i", mode);
|
||||
return;
|
||||
}
|
||||
if (display_mode != this->mode) {
|
||||
this->mode = display_mode;
|
||||
ESP_LOGD(TAG, "Set display mode: %i", this->mode);
|
||||
if (mode != this->mode) {
|
||||
this->mode = mode;
|
||||
this->duration_ms = duration_ms;
|
||||
if (duration_ms > 0)
|
||||
this->duration_ms_start_ = millis();
|
||||
ESP_LOGD(TAG, "Set display mode: mode=%i, duration=%" PRIu32 "ms, duration-start=%" PRIu32 "ms",
|
||||
this->mode, this->duration_ms, this->duration_ms_start_);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -58,11 +58,12 @@ class DisplayMode
|
|||
{
|
||||
public:
|
||||
display_mode_t mode;
|
||||
uint32_t duration_ms;
|
||||
DisplayMode();
|
||||
void set_mode(display_mode_t display_mode);
|
||||
void set_mode(display_mode_t mode, uint32_t duration_ms=0);
|
||||
|
||||
protected:
|
||||
|
||||
uint32_t duration_ms_start_;
|
||||
};
|
||||
|
||||
class DisplayText
|
||||
|
@ -102,8 +103,8 @@ class Display : public DisplayBrightness,
|
|||
void set_demo_mode(demo_mode_t mode, uint8_t cycle_num);
|
||||
void set_demo_mode(const std::string& mode, uint8_t cycle_num);
|
||||
int set_text(const char *text, uint8_t start_pos);
|
||||
int set_text(const std::string& text, const std::string& align, const std::string& effect,
|
||||
uint8_t start_pos=0, uint8_t cycle_num=0);
|
||||
int set_text(const std::string& text, uint8_t start_pos, const std::string& align,
|
||||
uint32_t duration, const std::string& effect, uint32_t interval, uint8_t cycle_num);
|
||||
void update(void);
|
||||
|
||||
protected:
|
||||
|
@ -117,6 +118,7 @@ class Display : public DisplayBrightness,
|
|||
uint seg_out_smallest_;
|
||||
uint32_t refresh_period_us_;
|
||||
DisplayText disp_text_;
|
||||
uint32_t restore_update_interval_;
|
||||
static void display_refresh_task_(void *pv);
|
||||
int update_out_buf_(void);
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ from esphome.const import (
|
|||
CONF_MODE,
|
||||
CONF_POSITION,
|
||||
CONF_EFFECT,
|
||||
CONF_DURATION,
|
||||
)
|
||||
|
||||
|
||||
|
@ -41,9 +42,10 @@ CONF_POS_10_PIN = "pos_10_pin"
|
|||
CONF_POS_11_PIN = "pos_11_pin"
|
||||
CONF_POS_12_PIN = "pos_12_pin"
|
||||
# CONF_DEMO_MODE = "demo_mode"
|
||||
CONF_CYCLE_NUM = "cycle_num"
|
||||
CONF_TEXT = "text"
|
||||
CONF_ALIGN = "align"
|
||||
CONF_CYCLE_NUM = "cycle_num"
|
||||
CONF_EFFECT_UPDATE_INTERVAL = "effect_update_interval"
|
||||
|
||||
|
||||
max6921_ns = cg.esphome_ns.namespace("max6921")
|
||||
|
@ -207,7 +209,14 @@ async def max6921_set_brightness_to_code(config, action_id, template_arg, args):
|
|||
|
||||
|
||||
def validate_action_set_text(value):
|
||||
print(f"validate_action_set_text: {value}")
|
||||
duration = value[CONF_DURATION]
|
||||
cycle_num = value.get(CONF_CYCLE_NUM)
|
||||
if isinstance(cycle_num, cv.Lambda):
|
||||
cycle_num = 1
|
||||
if duration.total_milliseconds > 0 and cycle_num > 0:
|
||||
raise cv.Invalid(
|
||||
f"Only one of following config value must be set: {CONF_CYCLE_NUM}, {CONF_DURATION}"
|
||||
)
|
||||
return value
|
||||
|
||||
|
||||
|
@ -217,11 +226,19 @@ ACTION_SET_TEXT_SCHEMA = cv.All(
|
|||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_TEXT): cv.templatable(cv.string),
|
||||
cv.Optional(CONF_POSITION): cv.templatable(
|
||||
cv.Optional(CONF_POSITION, default=0): cv.templatable(
|
||||
cv.int_range(min=0, max=13)
|
||||
),
|
||||
cv.Optional(CONF_ALIGN): cv.templatable(cv.string),
|
||||
cv.Optional(CONF_EFFECT): cv.templatable(cv.string),
|
||||
cv.Optional(CONF_ALIGN, default="center"): cv.templatable(
|
||||
cv.string
|
||||
),
|
||||
cv.Optional(CONF_DURATION, default="0ms"): cv.templatable(
|
||||
cv.positive_time_period_milliseconds
|
||||
),
|
||||
cv.Optional(CONF_EFFECT, default="none"): cv.templatable(cv.string),
|
||||
cv.Optional(
|
||||
CONF_EFFECT_UPDATE_INTERVAL, default="150ms"
|
||||
): cv.templatable(cv.positive_time_period_milliseconds),
|
||||
cv.Optional(CONF_CYCLE_NUM, default=0): cv.templatable(cv.uint8_t),
|
||||
}
|
||||
)
|
||||
|
@ -243,9 +260,17 @@ async def max6921_set_text_to_code(config, action_id, template_arg, args):
|
|||
if CONF_ALIGN in config:
|
||||
template_ = await cg.templatable(config[CONF_ALIGN], args, cg.std_string)
|
||||
cg.add(var.set_text_align(template_))
|
||||
if CONF_DURATION in config:
|
||||
template_ = await cg.templatable(config[CONF_DURATION], args, cg.uint32)
|
||||
cg.add(var.set_text_effect_duration(template_))
|
||||
if CONF_EFFECT in config:
|
||||
template_ = await cg.templatable(config[CONF_EFFECT], args, cg.std_string)
|
||||
cg.add(var.set_text_effect(template_))
|
||||
if CONF_EFFECT_UPDATE_INTERVAL in config:
|
||||
template_ = await cg.templatable(
|
||||
config[CONF_EFFECT_UPDATE_INTERVAL], args, cg.uint32
|
||||
)
|
||||
cg.add(var.set_text_effect_update_interval(template_))
|
||||
if CONF_CYCLE_NUM in config:
|
||||
template_ = await cg.templatable(config[CONF_CYCLE_NUM], args, cg.uint8)
|
||||
cg.add(var.set_text_effect_cycle_num(template_))
|
||||
|
|
Loading…
Reference in a new issue