add start keys and add keys to triggers

This commit is contained in:
Samuel Sieb
2022-11-18 16:36:53 -08:00
parent c3e44910de
commit 87761ae6c2
4 changed files with 41 additions and 22 deletions

View File

@@ -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' ]
```

View File

@@ -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]))

View File

@@ -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

View File

@@ -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};
};