1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-06 13:22:19 +01:00

ESP-IDF support and generic target platforms (#2303)

* Socket refactor and SSL

* esp-idf temp

* Fixes

* Echo component and noise

* Add noise API transport support

* Updates

* ESP-IDF

* Complete

* Fixes

* Fixes

* Versions update

* New i2c APIs

* Complete i2c refactor

* SPI migration

* Revert ESP Preferences migration, too complex for now

* OTA support

* Remove echo again

* Remove ssl again

* GPIOFlags updates

* Rename esphal and ICACHE_RAM_ATTR

* Make ESP32 arduino compilable again

* Fix GPIO flags

* Complete pin registry refactor and fixes

* Fixes to make test1 compile

* Remove sdkconfig file

* Ignore sdkconfig file

* Fixes in reviewing

* Make test2 compile

* Make test4 compile

* Make test5 compile

* Run clang-format

* Fix lint errors

* Use esp-idf APIs instead of btStart

* Another round of fixes

* Start implementing ESP8266

* Make test3 compile

* Guard esp8266 code

* Lint

* Reformat

* Fixes

* Fixes v2

* more fixes

* ESP-IDF tidy target

* Convert ARDUINO_ARCH_ESPxx

* Update WiFiSignalSensor

* Update time ifdefs

* OTA needs millis from hal

* RestartSwitch needs delay from hal

* ESP-IDF Uart

* Fix OTA blank password

* Allow setting sdkconfig

* Fix idf partitions and allow setting sdkconfig from yaml

* Re-add read/write compat APIs and fix esp8266 uart

* Fix esp8266 store log strings in flash

* Fix ESP32 arduino preferences not initialized

* Update ifdefs

* Change how sdkconfig change is detected

* Add checks to ci-custom and fix them

* Run clang-format

* Add esp-idf clang-tidy target and fix errors

* Fixes from clang-tidy idf round 2

* Fixes from compiling tests with esp-idf

* Run clang-format

* Switch test5.yaml to esp-idf

* Implement ESP8266 Preferences

* Lint

* Re-do PIO package version selection a bit

* Fix arduinoespressif32 package version

* Fix unit tests

* Lint

* Lint fixes

* Fix readv/writev not defined

* Fix graphing component

* Re-add all old options from core/config.py

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
Otto Winter
2021-09-20 11:47:51 +02:00
committed by GitHub
parent 1e8e471dec
commit ac0d921413
583 changed files with 9008 additions and 5420 deletions

View File

@@ -1,5 +1,6 @@
"""Helpers for config validation using voluptuous."""
from dataclasses import dataclass
import logging
import os
import re
@@ -33,6 +34,9 @@ from esphome.const import (
CONF_UPDATE_INTERVAL,
CONF_TYPE_ID,
CONF_TYPE,
KEY_CORE,
KEY_FRAMEWORK_VERSION,
KEY_TARGET_FRAMEWORK,
)
from esphome.core import (
CORE,
@@ -492,20 +496,37 @@ def templatable(other_validators):
def only_on(platforms):
"""Validate that this option can only be specified on the given ESP platforms."""
"""Validate that this option can only be specified on the given target platforms."""
if not isinstance(platforms, list):
platforms = [platforms]
def validator_(obj):
if CORE.esp_platform not in platforms:
if CORE.target_platform not in platforms:
raise Invalid(f"This feature is only available on {platforms}")
return obj
return validator_
only_on_esp32 = only_on("ESP32")
only_on_esp8266 = only_on("ESP8266")
def only_with_framework(frameworks):
"""Validate that this option can only be specified on the given frameworks."""
if not isinstance(frameworks, list):
frameworks = [frameworks]
def validator_(obj):
if CORE.target_framework not in frameworks:
raise Invalid(
f"This feature is only available with frameworks {frameworks}"
)
return obj
return validator_
only_on_esp32 = only_on("esp32")
only_on_esp8266 = only_on("esp8266")
only_with_arduino = only_with_framework("arduino")
only_with_esp_idf = only_with_framework("esp-idf")
# Adapted from:
@@ -1025,7 +1046,7 @@ def requires_component(comp):
# pylint: disable=unsupported-membership-test
def validator(value):
# pylint: disable=unsupported-membership-test
if comp not in CORE.raw_config:
if comp not in CORE.loaded_integrations:
raise Invalid(f"This option requires component {comp}")
return value
@@ -1401,18 +1422,32 @@ class GenerateID(Optional):
class SplitDefault(Optional):
"""Mark this key to have a split default for ESP8266/ESP32."""
def __init__(self, key, esp8266=vol.UNDEFINED, esp32=vol.UNDEFINED):
def __init__(
self,
key,
esp8266=vol.UNDEFINED,
esp32=vol.UNDEFINED,
esp32_arduino=vol.UNDEFINED,
esp32_idf=vol.UNDEFINED,
):
super().__init__(key)
self._esp8266_default = vol.default_factory(esp8266)
self._esp32_default = vol.default_factory(esp32)
self._esp32_arduino_default = vol.default_factory(
esp32_arduino if esp32 is vol.UNDEFINED else esp32
)
self._esp32_idf_default = vol.default_factory(
esp32_idf if esp32 is vol.UNDEFINED else esp32
)
@property
def default(self):
if CORE.is_esp8266:
return self._esp8266_default
if CORE.is_esp32:
return self._esp32_default
raise ValueError
if CORE.is_esp32 and CORE.using_arduino:
return self._esp32_arduino_default
if CORE.is_esp32 and CORE.using_esp_idf:
return self._esp32_idf_default
raise NotImplementedError
@default.setter
def default(self, value):
@@ -1431,7 +1466,7 @@ class OnlyWith(Optional):
@property
def default(self):
# pylint: disable=unsupported-membership-test
if self._component in CORE.raw_config:
if self._component in CORE.loaded_integrations:
return self._default
return vol.UNDEFINED
@@ -1613,3 +1648,73 @@ def source_refresh(value: str):
if value.lower() == "never":
return source_refresh("1000y")
return positive_time_period_seconds(value)
@dataclass(frozen=True, order=True)
class Version:
major: int
minor: int
patch: int
def __str__(self):
return f"{self.major}.{self.minor}.{self.patch}"
@classmethod
def parse(cls, value: str) -> "Version":
match = re.match(r"(\d+).(\d+).(\d+)", value)
if match is None:
raise ValueError(f"Not a valid version number {value}")
major = int(match[1])
minor = int(match[2])
patch = int(match[3])
return Version(major=major, minor=minor, patch=patch)
def version_number(value):
value = string_strict(value)
try:
return str(Version.parse(value))
except ValueError as e:
raise Invalid("Not a version number") from e
def require_framework_version(
*,
esp_idf=None,
esp32_arduino=None,
esp8266_arduino=None,
):
def validator(value):
core_data = CORE.data[KEY_CORE]
framework = core_data[KEY_TARGET_FRAMEWORK]
if framework == "esp-idf":
if esp_idf is None:
raise Invalid("This feature is incompatible with esp-idf")
required = esp_idf
elif CORE.is_esp32 and framework == "arduino":
if esp32_arduino is None:
raise Invalid(
"This feature is incompatible with ESP32 using arduino framework"
)
required = esp32_arduino
elif CORE.is_esp8266 and framework == "arduino":
if esp8266_arduino is None:
raise Invalid("This feature is incompatible with ESP8266")
required = esp8266_arduino
else:
raise NotImplementedError
if core_data[KEY_FRAMEWORK_VERSION] < required:
raise Invalid(
f"This feature requires at least framework version {required}"
)
return value
return validator
@contextmanager
def suppress_invalid():
try:
yield
except vol.Invalid:
pass