add start keys and add keys to triggers
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
This component collects key presses from a `key_provider` like the `matrix_keypad` or `wiegand` components.
|
||||
|
||||
You need at least one of the `end_keys` or `max_length` parameters. The rest are optional.
|
||||
There is a `clear()` method with an optional `bool` (default true) parameter for whether or not to trigger the progress action.
|
||||
|
||||
Example:
|
||||
```yaml
|
||||
@@ -11,6 +12,7 @@ key_collector:
|
||||
source_id: mykeypad
|
||||
min_length: 4
|
||||
max_length: 4
|
||||
start_keys: "A"
|
||||
end_keys: "#"
|
||||
end_key_required: true # default is false
|
||||
back_keys: "*"
|
||||
@@ -19,11 +21,11 @@ key_collector:
|
||||
allowed_keys: "0123456789" # if not included, then any otherwise unused keys will be allowed
|
||||
on_progress:
|
||||
- logger.log:
|
||||
format: "input progress: '%s'"
|
||||
args: [ 'x.c_str()' ]
|
||||
format: "input progress: '%s', started by '%c'"
|
||||
args: [ 'x.c_str()', 'start' ]
|
||||
on_result:
|
||||
- logger.log:
|
||||
format: "input result: '%s'"
|
||||
args: [ 'x.c_str()' ]
|
||||
format: "input result: '%s', started by '%c', ended by '%c'"
|
||||
args: [ 'x.c_str()', 'start', 'end' ]
|
||||
```
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ from esphome import automation
|
||||
from esphome.components import key_provider
|
||||
from esphome.const import CONF_ID, CONF_MAX_LENGTH, CONF_MIN_LENGTH, CONF_SOURCE_ID, CONF_TIMEOUT
|
||||
|
||||
CONF_START_KEYS = 'start_keys'
|
||||
CONF_END_KEYS = 'end_keys'
|
||||
CONF_END_KEY_REQUIRED = 'end_key_required'
|
||||
CONF_BACK_KEYS = 'back_keys'
|
||||
@@ -24,6 +25,7 @@ CONFIG_SCHEMA = cv.All(cv.COMPONENT_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_SOURCE_ID): cv.use_id(key_provider.KeyProvider),
|
||||
cv.Optional(CONF_MIN_LENGTH): cv.int_,
|
||||
cv.Optional(CONF_MAX_LENGTH): cv.int_,
|
||||
cv.Optional(CONF_START_KEYS): cv.string,
|
||||
cv.Optional(CONF_END_KEYS): cv.string,
|
||||
cv.Optional(CONF_END_KEY_REQUIRED): cv.boolean,
|
||||
cv.Optional(CONF_BACK_KEYS): cv.string,
|
||||
@@ -55,10 +57,12 @@ async def to_code(config):
|
||||
if CONF_ALLOWED_KEYS in config:
|
||||
cg.add(var.set_allowed_keys(config[CONF_ALLOWED_KEYS]))
|
||||
if CONF_ON_PROGRESS in config:
|
||||
await automation.build_automation(var.get_progress_trigger(), [(cg.std_string, 'x')],
|
||||
await automation.build_automation(var.get_progress_trigger(),
|
||||
[(cg.std_string, 'x'), (cg.uint8, 'start')],
|
||||
config[CONF_ON_PROGRESS])
|
||||
if CONF_ON_RESULT in config:
|
||||
await automation.build_automation(var.get_result_trigger(), [(cg.std_string, 'x')],
|
||||
await automation.build_automation(var.get_result_trigger(),
|
||||
[(cg.std_string, 'x'), (cg.uint8, 'start'), (cg.uint8, 'end')],
|
||||
config[CONF_ON_RESULT])
|
||||
if CONF_TIMEOUT in config:
|
||||
cg.add(var.set_timeout(config[CONF_TIMEOUT]))
|
||||
|
||||
@@ -7,13 +7,12 @@ namespace key_collector {
|
||||
|
||||
static const char *const TAG = "key_collector";
|
||||
|
||||
KeyCollector::KeyCollector() : progress_trigger_(new Trigger<std::string>()), result_trigger_(new Trigger<std::string>()) {}
|
||||
KeyCollector::KeyCollector() : progress_trigger_(new Trigger<std::string, uint8_t>()), result_trigger_(new Trigger<std::string, uint8_t, uint8_t>()) {}
|
||||
|
||||
void KeyCollector::loop() {
|
||||
if ((this->timeout_ == 0) || (this->result_.size() == 0) || (millis() - this->last_key_time_ < this->timeout_))
|
||||
return;
|
||||
this->result_.clear();
|
||||
this->progress_trigger_->trigger(this->result_);
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void KeyCollector::dump_config() {
|
||||
@@ -42,27 +41,36 @@ void KeyCollector::set_provider(key_provider::KeyProvider *provider) {
|
||||
});
|
||||
}
|
||||
|
||||
void KeyCollector::clear(bool progress_update) {
|
||||
this->result_.clear();
|
||||
this->start_key_ = 0;
|
||||
if (progress_update)
|
||||
this->progress_trigger_->trigger(this->result_, 0);
|
||||
}
|
||||
|
||||
void KeyCollector::key_pressed_(uint8_t key) {
|
||||
this->last_key_time_ = millis();
|
||||
if (!this->start_keys_.empty() && !this->start_key_) {
|
||||
if (this->start_keys_.find(key) != std::string::npos)
|
||||
this->start_key_ = key;
|
||||
return;
|
||||
}
|
||||
if (this->back_keys_.find(key) != std::string::npos) {
|
||||
if (!this->result_.empty()) {
|
||||
this->result_.pop_back();
|
||||
this->progress_trigger_->trigger(this->result_);
|
||||
this->progress_trigger_->trigger(this->result_, this->start_key_);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (this->clear_keys_.find(key) != std::string::npos) {
|
||||
if (!this->result_.empty()) {
|
||||
this->result_.clear();
|
||||
this->progress_trigger_->trigger(this->result_);
|
||||
}
|
||||
if (!this->result_.empty())
|
||||
this->clear();
|
||||
return;
|
||||
}
|
||||
if (this->end_keys_.find(key) != std::string::npos) {
|
||||
if ((this->min_length_ == 0) || (this->result_.size() >= this->min_length_)) {
|
||||
this->result_trigger_->trigger(this->result_);
|
||||
this->result_.clear();
|
||||
this->progress_trigger_->trigger(this->result_);
|
||||
this->result_trigger_->trigger(this->result_, this->start_key_, key);
|
||||
this->clear();
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -71,10 +79,10 @@ void KeyCollector::key_pressed_(uint8_t key) {
|
||||
if ((this->max_length_ == 0) || (this->result_.size() < this->max_length_))
|
||||
this->result_.push_back(key);
|
||||
if ((this->max_length_ > 0) && (this->result_.size() == this->max_length_) && (!this->end_key_required_)) {
|
||||
this->result_trigger_->trigger(this->result_);
|
||||
this->result_.clear();
|
||||
this->result_trigger_->trigger(this->result_, this->start_key_, 0);
|
||||
this->clear(false);
|
||||
}
|
||||
this->progress_trigger_->trigger(this->result_);
|
||||
this->progress_trigger_->trigger(this->result_, this->start_key_);
|
||||
}
|
||||
|
||||
} // namespace key_collector
|
||||
|
||||
@@ -14,6 +14,7 @@ class KeyCollector : public Component {
|
||||
void set_provider(key_provider::KeyProvider *provider);
|
||||
void set_min_length(int min_length) { this->min_length_ = min_length; };
|
||||
void set_max_length(int max_length) { this->max_length_ = max_length; };
|
||||
void set_start_keys(std::string start_keys) { this->start_keys_ = start_keys; };
|
||||
void set_end_keys(std::string end_keys) { this->end_keys_ = end_keys; };
|
||||
void set_end_key_required(bool end_key_required) { this->end_key_required_ = end_key_required; };
|
||||
void set_back_keys(std::string back_keys) { this->back_keys_ = back_keys; };
|
||||
@@ -23,19 +24,23 @@ class KeyCollector : public Component {
|
||||
Trigger<std::string> *get_result_trigger() const { return this->result_trigger_; };
|
||||
void set_timeout(int timeout) { this->timeout_ = timeout; };
|
||||
|
||||
void clear(bool progress_update = true);
|
||||
|
||||
protected:
|
||||
void key_pressed_(uint8_t key);
|
||||
|
||||
int min_length_{0};
|
||||
int max_length_{0};
|
||||
std::string start_keys_;
|
||||
std::string end_keys_;
|
||||
bool end_key_required_{false};
|
||||
std::string back_keys_;
|
||||
std::string clear_keys_;
|
||||
std::string allowed_keys_;
|
||||
std::string result_;
|
||||
Trigger<std::string> *progress_trigger_;
|
||||
Trigger<std::string> *result_trigger_;
|
||||
uint8_t start_key_{0};
|
||||
Trigger<std::string, uint8_t> *progress_trigger_;
|
||||
Trigger<std::string, uint8_t, uint8_t> *result_trigger_;
|
||||
uint32_t last_key_time_;
|
||||
uint32_t timeout_{0};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user