-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add select entity to control the operation mode (Closes: #53)
- Loading branch information
Showing
7 changed files
with
200 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import esphome.codegen as cg | ||
from esphome.components import select | ||
import esphome.config_validation as cv | ||
from esphome.const import CONF_ICON, CONF_ID | ||
|
||
from .. import ( | ||
CONF_SOYOSOURCE_DISPLAY_COMPONENT_SCHEMA, | ||
CONF_SOYOSOURCE_DISPLAY_ID, | ||
soyosource_display_ns, | ||
) | ||
|
||
DEPENDENCIES = ["soyosource_display"] | ||
|
||
CODEOWNERS = ["@syssi"] | ||
|
||
CONF_OPERATION_MODE = "operation_mode" | ||
CONF_OPTIONSMAP = "optionsmap" | ||
|
||
ICON_OPERATION_MODE = "mdi:heart-pulse" | ||
|
||
SoyosourceSelect = soyosource_display_ns.class_( | ||
"SoyosourceSelect", select.Select, cg.Component | ||
) | ||
|
||
|
||
def ensure_option_map(value): | ||
cv.check_not_templatable(value) | ||
option = cv.All(cv.int_range(0, 2**16 - 1)) | ||
mapping = cv.All(cv.string_strict) | ||
options_map_schema = cv.Schema({option: mapping}) | ||
value = options_map_schema(value) | ||
|
||
all_values = list(value.keys()) | ||
unique_values = set(value.keys()) | ||
if len(all_values) != len(unique_values): | ||
raise cv.Invalid("Mapping values must be unique.") | ||
|
||
return value | ||
|
||
|
||
SELECTS = { | ||
CONF_OPERATION_MODE: 0x0A, | ||
} | ||
|
||
SOYOSOURCE_SELECT_SCHEMA = select.SELECT_SCHEMA.extend( | ||
{ | ||
cv.GenerateID(): cv.declare_id(SoyosourceSelect), | ||
cv.Optional(CONF_ICON, default=ICON_OPERATION_MODE): select.icon, | ||
cv.Optional(CONF_OPTIONSMAP): ensure_option_map, | ||
} | ||
).extend(cv.COMPONENT_SCHEMA) | ||
|
||
CONFIG_SCHEMA = CONF_SOYOSOURCE_DISPLAY_COMPONENT_SCHEMA.extend( | ||
{ | ||
cv.Optional(CONF_OPERATION_MODE): SOYOSOURCE_SELECT_SCHEMA, | ||
} | ||
) | ||
|
||
|
||
async def to_code(config): | ||
hub = await cg.get_variable(config[CONF_SOYOSOURCE_DISPLAY_ID]) | ||
|
||
for key, address in SELECTS.items(): | ||
if key in config: | ||
conf = config[key] | ||
options_map = conf[CONF_OPTIONSMAP] | ||
var = cg.new_Pvariable(conf[CONF_ID]) | ||
await cg.register_component(var, conf) | ||
await select.register_select(var, conf, options=list(options_map.values())) | ||
cg.add(var.set_select_mappings(list(options_map.keys()))) | ||
|
||
cg.add(getattr(hub, f"set_{key}_select")(var)) | ||
cg.add(var.set_parent(hub)) | ||
cg.add(var.set_holding_register(address)) |
47 changes: 47 additions & 0 deletions
47
components/soyosource_display/select/soyosource_select.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#include "soyosource_select.h" | ||
#include "esphome/core/log.h" | ||
|
||
namespace esphome { | ||
namespace soyosource_display { | ||
|
||
static const char *const TAG = "soyosource_display.select"; | ||
|
||
void SoyosourceSelect::setup() { | ||
this->parent_->register_select_listener(this->holding_register_, [this](const uint8_t &enum_value) { | ||
ESP_LOGV(TAG, "Device reported select %u value %u", this->holding_register_, enum_value); | ||
auto mappings = this->mappings_; | ||
auto it = std::find(mappings.cbegin(), mappings.cend(), enum_value); | ||
if (it == mappings.end()) { | ||
ESP_LOGW(TAG, "Invalid value %u", enum_value); | ||
return; | ||
} | ||
size_t mapping_idx = std::distance(mappings.cbegin(), it); | ||
auto value = this->at(mapping_idx); | ||
this->publish_state(value.value()); | ||
}); | ||
} | ||
|
||
void SoyosourceSelect::dump_config() { | ||
LOG_SELECT(TAG, "SoyosourceDisplay Select", this); | ||
ESP_LOGCONFIG(TAG, " Select has register %u", this->holding_register_); | ||
ESP_LOGCONFIG(TAG, " Options are:"); | ||
auto options = this->traits.get_options(); | ||
for (auto i = 0; i < this->mappings_.size(); i++) { | ||
ESP_LOGCONFIG(TAG, " %i: %s", this->mappings_.at(i), options.at(i).c_str()); | ||
} | ||
} | ||
|
||
void SoyosourceSelect::control(const std::string &value) { | ||
auto idx = this->index_of(value); | ||
if (idx.has_value()) { | ||
uint8_t mapping = this->mappings_.at(idx.value()); | ||
ESP_LOGV(TAG, "Setting %u datapoint value to %u:%s", this->holding_register_, mapping, value.c_str()); | ||
this->parent_->update_setting(this->holding_register_, mapping); | ||
return; | ||
} | ||
|
||
ESP_LOGW(TAG, "Invalid value %s", value.c_str()); | ||
} | ||
|
||
} // namespace soyosource_display | ||
} // namespace esphome |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#pragma once | ||
|
||
#include <utility> | ||
#include <map> | ||
|
||
#include "../soyosource_display.h" | ||
#include "esphome/core/component.h" | ||
#include "esphome/components/select/select.h" | ||
|
||
namespace esphome { | ||
namespace soyosource_display { | ||
|
||
class SoyosourceDisplay; | ||
|
||
class SoyosourceSelect : public select::Select, public Component { | ||
public: | ||
void set_parent(SoyosourceDisplay *parent) { this->parent_ = parent; }; | ||
void set_holding_register(uint8_t holding_register) { this->holding_register_ = holding_register; }; | ||
void set_select_mappings(std::vector<uint8_t> mappings) { this->mappings_ = std::move(mappings); } | ||
|
||
void setup() override; | ||
void dump_config() override; | ||
|
||
protected: | ||
void control(const std::string &value) override; | ||
|
||
std::vector<uint8_t> mappings_; | ||
SoyosourceDisplay *parent_; | ||
uint8_t holding_register_; | ||
}; | ||
|
||
} // namespace soyosource_display | ||
} // namespace esphome |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters