mirror of
https://github.com/esphome/esphome.git
synced 2026-10-14 02:02:51 +00:00
[core] Expose the preferences storage helpers to components (#20535)
This commit is contained in:
+8
-10
@@ -19,18 +19,15 @@ STORAGE_FLASH = "flash"
|
||||
STORAGE_RTC = "rtc"
|
||||
|
||||
|
||||
def _rtc_supported() -> bool:
|
||||
"""Whether the active platform has an RTC-backed preferences backend.
|
||||
|
||||
Mirrors the C++ ``SOC_RTC_MEM_SUPPORTED`` guard in the ESP32 backend: the ESP32-C2
|
||||
and -C61 have no RTC memory at all, so RTC storage is unavailable there.
|
||||
"""
|
||||
def rtc_supported() -> bool:
|
||||
"""Whether the target has RTC-backed preferences (not ESP32-C2/C61); call at validation time."""
|
||||
if CORE.is_esp8266:
|
||||
return True
|
||||
if CORE.is_esp32:
|
||||
from esphome.components.esp32 import get_esp32_variant
|
||||
from esphome.components.esp32.const import VARIANT_ESP32C2, VARIANT_ESP32C61
|
||||
|
||||
# Mirrors the C++ SOC_RTC_MEM_SUPPORTED guard in the ESP32 backend
|
||||
return get_esp32_variant() not in (VARIANT_ESP32C2, VARIANT_ESP32C61)
|
||||
return False
|
||||
|
||||
@@ -44,9 +41,10 @@ def _default_storage() -> str:
|
||||
return STORAGE_RTC if CORE.is_esp8266 else STORAGE_FLASH
|
||||
|
||||
|
||||
def _validate_storage(value):
|
||||
def validate_storage(value: object) -> str:
|
||||
"""Validate a ``storage:`` value, ``flash`` or ``rtc`` where supported."""
|
||||
value = cv.one_of(STORAGE_FLASH, STORAGE_RTC, lower=True)(value)
|
||||
if value == STORAGE_RTC and not _rtc_supported():
|
||||
if value == STORAGE_RTC and not rtc_supported():
|
||||
raise cv.Invalid(
|
||||
f"'{STORAGE_RTC}' storage is not supported on this platform; only "
|
||||
f"'{STORAGE_FLASH}' is available"
|
||||
@@ -56,7 +54,7 @@ def _validate_storage(value):
|
||||
|
||||
def storage_schema():
|
||||
"""Return an Optional(CONF_STORAGE) entry for merging into a component schema."""
|
||||
return {cv.Optional(CONF_STORAGE, default=_default_storage): _validate_storage}
|
||||
return {cv.Optional(CONF_STORAGE, default=_default_storage): validate_storage}
|
||||
|
||||
|
||||
def request_rtc_storage() -> None:
|
||||
@@ -88,7 +86,7 @@ def validate_rtc_storage(value):
|
||||
"be disabled"
|
||||
)
|
||||
return value
|
||||
if not _rtc_supported():
|
||||
if not rtc_supported():
|
||||
raise cv.Invalid("RTC preference storage is not supported on this platform")
|
||||
return value
|
||||
|
||||
|
||||
@@ -147,3 +147,47 @@ def test_rtc_rejected_on_unsupported_platform() -> None:
|
||||
def test_flash_allowed_on_unsupported_platform() -> None:
|
||||
_set_platform(PLATFORM_RP2040)
|
||||
assert _validate({CONF_STORAGE: "flash"})[CONF_STORAGE] == preferences.STORAGE_FLASH
|
||||
|
||||
|
||||
@pytest.mark.parametrize("variant", [VARIANT_ESP32, VARIANT_ESP32C3])
|
||||
def test_rtc_supported_on_esp32_with_rtc_memory(variant: str) -> None:
|
||||
_set_esp32(variant)
|
||||
assert preferences.rtc_supported() is True
|
||||
|
||||
|
||||
@pytest.mark.parametrize("variant", [VARIANT_ESP32C2, VARIANT_ESP32C61])
|
||||
def test_rtc_supported_false_without_rtc_memory(variant: str) -> None:
|
||||
_set_esp32(variant)
|
||||
assert preferences.rtc_supported() is False
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("platform", "expected"),
|
||||
[(PLATFORM_ESP8266, True), (PLATFORM_RP2040, False)],
|
||||
)
|
||||
def test_rtc_supported_per_platform(platform: str, expected: bool) -> None:
|
||||
_set_platform(platform)
|
||||
assert preferences.rtc_supported() is expected
|
||||
|
||||
|
||||
def test_validate_storage_accepts_flash_everywhere() -> None:
|
||||
_set_platform(PLATFORM_RP2040)
|
||||
assert preferences.validate_storage("flash") == preferences.STORAGE_FLASH
|
||||
assert preferences.validate_storage("FLASH") == preferences.STORAGE_FLASH
|
||||
|
||||
|
||||
def test_validate_storage_accepts_rtc_where_supported() -> None:
|
||||
_set_esp32(VARIANT_ESP32)
|
||||
assert preferences.validate_storage("rtc") == preferences.STORAGE_RTC
|
||||
|
||||
|
||||
def test_validate_storage_rejects_rtc_without_rtc_memory() -> None:
|
||||
_set_esp32(VARIANT_ESP32C2)
|
||||
with pytest.raises(cv.Invalid, match="not supported on this platform"):
|
||||
preferences.validate_storage("rtc")
|
||||
|
||||
|
||||
def test_validate_storage_rejects_unknown_value() -> None:
|
||||
_set_esp32(VARIANT_ESP32)
|
||||
with pytest.raises(cv.Invalid):
|
||||
preferences.validate_storage("nvs")
|
||||
|
||||
Reference in New Issue
Block a user