mirror of
https://github.com/esphome/esphome.git
synced 2025-11-17 23:35:47 +00:00
89 lines
2.8 KiB
C++
89 lines
2.8 KiB
C++
#pragma once
|
|
|
|
#include "esphome/components/text/text.h"
|
|
#include "esphome/core/automation.h"
|
|
#include "esphome/core/component.h"
|
|
#include "esphome/core/preferences.h"
|
|
#include "esphome/core/template_lambda.h"
|
|
|
|
namespace esphome {
|
|
namespace template_ {
|
|
|
|
// We keep this separate so we don't have to template and duplicate
|
|
// the text input for each different size flash allocation.
|
|
class TemplateTextSaverBase {
|
|
public:
|
|
virtual bool save(const std::string &value) { return true; }
|
|
|
|
virtual void setup(uint32_t id, std::string &value) {}
|
|
|
|
protected:
|
|
ESPPreferenceObject pref_;
|
|
std::string prev_;
|
|
};
|
|
|
|
template<uint8_t SZ> class TextSaver : public TemplateTextSaverBase {
|
|
public:
|
|
bool save(const std::string &value) override {
|
|
int diff = value.compare(this->prev_);
|
|
if (diff != 0) {
|
|
// If string is bigger than the allocation, do not save it.
|
|
// We don't need to waste ram setting prev_value either.
|
|
int size = value.size();
|
|
if (size <= SZ) {
|
|
// Make it into a length prefixed thing
|
|
unsigned char temp[SZ + 1];
|
|
memcpy(temp + 1, value.c_str(), size);
|
|
// SZ should be pre checked at the schema level, it can't go past the char range.
|
|
temp[0] = ((unsigned char) size);
|
|
this->pref_.save(&temp);
|
|
this->prev_.assign(value);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Make the preference object. Fill the provided location with the saved data
|
|
// If it is available, else leave it alone
|
|
void setup(uint32_t id, std::string &value) override {
|
|
this->pref_ = global_preferences->make_preference<uint8_t[SZ + 1]>(id);
|
|
|
|
char temp[SZ + 1];
|
|
bool hasdata = this->pref_.load(&temp);
|
|
|
|
if (hasdata) {
|
|
value.assign(temp + 1, (size_t) temp[0]);
|
|
}
|
|
|
|
this->prev_.assign(value);
|
|
}
|
|
};
|
|
|
|
class TemplateText : public text::Text, public PollingComponent {
|
|
public:
|
|
template<typename F> void set_template(F &&f) { this->f_.set(std::forward<F>(f)); }
|
|
|
|
void setup() override;
|
|
void update() override;
|
|
void dump_config() override;
|
|
float get_setup_priority() const override { return setup_priority::HARDWARE; }
|
|
|
|
Trigger<std::string> *get_set_trigger() const { return this->set_trigger_; }
|
|
void set_optimistic(bool optimistic) { this->optimistic_ = optimistic; }
|
|
void set_initial_value(const std::string &initial_value) { this->initial_value_ = initial_value; }
|
|
void set_value_saver(TemplateTextSaverBase *restore_value_saver) { this->pref_ = restore_value_saver; }
|
|
|
|
protected:
|
|
void control(const std::string &value) override;
|
|
bool optimistic_ = false;
|
|
std::string initial_value_;
|
|
Trigger<std::string> *set_trigger_ = new Trigger<std::string>();
|
|
TemplateLambda<std::string> f_{};
|
|
|
|
TemplateTextSaverBase *pref_ = nullptr;
|
|
};
|
|
|
|
} // namespace template_
|
|
} // namespace esphome
|