mirror of
https://github.com/esphome/esphome.git
synced 2024-12-22 13:34:54 +01:00
EntityBase: Move ObjectId to Flash (#4569)
* Move EntityBase Object Id from memory to flash. * Sprinkler use common `setup_entity` method. * Remove `EntityBase` from Sprinkler. * Support for entity names set to None * change so gh PR picks up commit. --------- Co-authored-by: Your Name <you@example.com> Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
parent
922344811f
commit
3ac7bf3761
5 changed files with 82 additions and 8 deletions
|
@ -16,7 +16,6 @@ void EntityBase::set_name(const char *name) {
|
|||
} else {
|
||||
this->has_own_name_ = true;
|
||||
}
|
||||
this->calc_object_id_();
|
||||
}
|
||||
|
||||
// Entity Internal
|
||||
|
@ -41,13 +40,37 @@ EntityCategory EntityBase::get_entity_category() const { return this->entity_cat
|
|||
void EntityBase::set_entity_category(EntityCategory entity_category) { this->entity_category_ = entity_category; }
|
||||
|
||||
// Entity Object ID
|
||||
const std::string &EntityBase::get_object_id() { return this->object_id_; }
|
||||
std::string EntityBase::get_object_id() const {
|
||||
// Check if `App.get_friendly_name()` is constant or dynamic.
|
||||
if (!this->has_own_name_ && App.is_name_add_mac_suffix_enabled()) {
|
||||
// `App.get_friendly_name()` is dynamic.
|
||||
return str_sanitize(str_snake_case(App.get_friendly_name()));
|
||||
} else {
|
||||
// `App.get_friendly_name()` is constant.
|
||||
if (this->object_id_c_str_ == nullptr) {
|
||||
return "";
|
||||
}
|
||||
return this->object_id_c_str_;
|
||||
}
|
||||
}
|
||||
void EntityBase::set_object_id(const char *object_id) {
|
||||
this->object_id_c_str_ = object_id;
|
||||
this->calc_object_id_();
|
||||
}
|
||||
|
||||
// Calculate Object ID Hash from Entity Name
|
||||
void EntityBase::calc_object_id_() {
|
||||
this->object_id_ = str_sanitize(str_snake_case(this->name_));
|
||||
// FNV-1 hash
|
||||
this->object_id_hash_ = fnv1_hash(this->object_id_);
|
||||
// Check if `App.get_friendly_name()` is constant or dynamic.
|
||||
if (!this->has_own_name_ && App.is_name_add_mac_suffix_enabled()) {
|
||||
// `App.get_friendly_name()` is dynamic.
|
||||
const auto object_id = str_sanitize(str_snake_case(App.get_friendly_name()));
|
||||
// FNV-1 hash
|
||||
this->object_id_hash_ = fnv1_hash(object_id);
|
||||
} else {
|
||||
// `App.get_friendly_name()` is constant.
|
||||
// FNV-1 hash
|
||||
this->object_id_hash_ = fnv1_hash(this->object_id_c_str_);
|
||||
}
|
||||
}
|
||||
uint32_t EntityBase::get_object_id_hash() { return this->object_id_hash_; }
|
||||
|
||||
|
|
|
@ -22,8 +22,9 @@ class EntityBase {
|
|||
// Get whether this Entity has its own name or it should use the device friendly_name.
|
||||
bool has_own_name() const { return this->has_own_name_; }
|
||||
|
||||
// Get the sanitized name of this Entity as an ID. Caching it internally.
|
||||
const std::string &get_object_id();
|
||||
// Get the sanitized name of this Entity as an ID.
|
||||
std::string get_object_id() const;
|
||||
void set_object_id(const char *object_id);
|
||||
|
||||
// Get the unique Object ID of this Entity
|
||||
uint32_t get_object_id_hash();
|
||||
|
@ -54,7 +55,7 @@ class EntityBase {
|
|||
|
||||
StringRef name_;
|
||||
bool has_own_name_{false};
|
||||
std::string object_id_;
|
||||
const char *object_id_c_str_{nullptr};
|
||||
const char *icon_c_str_{nullptr};
|
||||
uint32_t object_id_hash_;
|
||||
bool internal_{false};
|
||||
|
|
|
@ -20,6 +20,7 @@ from esphome.types import ConfigType, ConfigFragmentType
|
|||
from esphome.cpp_generator import add, get_variable
|
||||
from esphome.cpp_types import App
|
||||
from esphome.util import Registry, RegistryEntry
|
||||
from esphome.helpers import snake_case, sanitize
|
||||
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
@ -101,6 +102,10 @@ async def register_parented(var, value):
|
|||
async def setup_entity(var, config):
|
||||
"""Set up generic properties of an Entity"""
|
||||
add(var.set_name(config[CONF_NAME]))
|
||||
if not config[CONF_NAME]:
|
||||
add(var.set_object_id(sanitize(snake_case(CORE.friendly_name))))
|
||||
else:
|
||||
add(var.set_object_id(sanitize(snake_case(config[CONF_NAME]))))
|
||||
add(var.set_disabled_by_default(config[CONF_DISABLED_BY_DEFAULT]))
|
||||
if CONF_INTERNAL in config:
|
||||
add(var.set_internal(config[CONF_INTERNAL]))
|
||||
|
|
|
@ -7,6 +7,7 @@ from pathlib import Path
|
|||
from typing import Union
|
||||
import tempfile
|
||||
from urllib.parse import urlparse
|
||||
import re
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -334,3 +335,13 @@ def add_class_to_obj(value, cls):
|
|||
if type(value) is type_: # pylint: disable=unidiomatic-typecheck
|
||||
return add_class_to_obj(func(value), cls)
|
||||
raise
|
||||
|
||||
|
||||
def snake_case(value):
|
||||
"""Same behaviour as `helpers.cpp` method `str_snake_case`."""
|
||||
return value.replace(" ", "_").lower()
|
||||
|
||||
|
||||
def sanitize(value):
|
||||
"""Same behaviour as `helpers.cpp` method `str_sanitize`."""
|
||||
return re.sub("[^-_0-9a-zA-Z]", r"", value)
|
||||
|
|
|
@ -229,3 +229,37 @@ def test_file_compare(fixture_path, file1, file2, expected):
|
|||
actual = helpers.file_compare(path1, path2)
|
||||
|
||||
assert actual == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"text, expected",
|
||||
(
|
||||
("foo", "foo"),
|
||||
("foo bar", "foo_bar"),
|
||||
("foo Bar", "foo_bar"),
|
||||
("foo BAR", "foo_bar"),
|
||||
("foo.bar", "foo.bar"),
|
||||
("fooBAR", "foobar"),
|
||||
("Foo-bar_EEK", "foo-bar_eek"),
|
||||
(" foo", "__foo"),
|
||||
),
|
||||
)
|
||||
def test_snake_case(text, expected):
|
||||
actual = helpers.snake_case(text)
|
||||
|
||||
assert actual == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"text, expected",
|
||||
(
|
||||
("foo_bar", "foo_bar"),
|
||||
('!"§$%&/()=?foo_bar', "foo_bar"),
|
||||
('foo_!"§$%&/()=?bar', "foo_bar"),
|
||||
('foo_bar!"§$%&/()=?', "foo_bar"),
|
||||
),
|
||||
)
|
||||
def test_sanitize(text, expected):
|
||||
actual = helpers.sanitize(text)
|
||||
|
||||
assert actual == expected
|
||||
|
|
Loading…
Reference in a new issue