1
0
mirror of https://github.com/esphome/esphome.git synced 2025-11-01 23:51:47 +00:00

Compare commits

..

76 Commits

Author SHA1 Message Date
Jesse Hills
4fb0f7f8c6 Merge pull request #4323 from esphome/bump-2022.12.4
2022.12.4
2023-01-21 16:17:57 +13:00
Jesse Hills
958cadeca8 Bump version to 2022.12.4 2023-01-20 18:33:09 +13:00
J. Nick Koston
00f2655f1a Always send the MTU request for BLE v3 cached connections (#4322)
closes https://github.com/esphome/esphome/pull/4321
fixes https://github.com/esphome/issues/issues/4041
fixes https://github.com/esphome/issues/issues/3951
2023-01-20 18:33:09 +13:00
Jesse Hills
074f5029eb Fix gpio pin mode for ISR pins (#4216) 2023-01-20 18:33:09 +13:00
Jesse Hills
1691976587 Merge pull request #4214 from esphome/bump-2022.12.3
2022.12.3
2022-12-20 23:34:01 +13:00
Jesse Hills
60e6b4d21e Bump version to 2022.12.3 2022-12-20 23:15:39 +13:00
Jesse Hills
5750591df2 Fix ESP32 GPIO when using INPUT PULLUP mode (#4213) 2022-12-20 23:15:39 +13:00
Jesse Hills
a75da54455 Merge pull request #4212 from esphome/bump-2022.12.2
2022.12.2
2022-12-20 11:06:34 +13:00
Jesse Hills
de7f6c3f5f Bump version to 2022.12.2 2022-12-20 10:49:36 +13:00
J. Nick Koston
4245480656 Handle zero padding anywhere in the combined adv data (#4208)
fixes https://github.com/esphome/issues/issues/3913
2022-12-20 10:49:35 +13:00
Jesse Hills
1824c8131e Fix import_full_config for adoption configs (#4197)
* Fix git raw url

* Fix setting full config query param

* Force dashboard import urls to have a branch or tag reference for full import
2022-12-20 10:49:35 +13:00
Jesse Hills
4e9606d2e0 Merge pull request #4196 from esphome/bump-2022.12.1
2022.12.1
2022-12-16 14:05:24 +13:00
Jesse Hills
78500fa933 Bump version to 2022.12.1 2022-12-16 13:36:11 +13:00
Jesse Hills
9c69b98a49 Fix i2s_audio media_player compiling for esp32-s2 (#4195) 2022-12-16 13:36:10 +13:00
Jesse Hills
e6d8ef98d3 Mark ESP32-S2 as not having Bluetooth (#4194) 2022-12-16 13:36:10 +13:00
Stefan Agner
3f1af1690b Support non-multiarch toolchains on 32-bit ARM (#4191)
fixes https://github.com/esphome/issues/issues/3904
2022-12-16 13:36:10 +13:00
Jesse Hills
84374b6b1e Merge pull request #4186 from esphome/bump-2022.12.0
2022.12.0
2022-12-14 17:06:24 +13:00
Jesse Hills
391316c9b5 Bump version to 2022.12.0 2022-12-14 16:37:39 +13:00
Jesse Hills
705c62ebd7 Merge branch 'beta' into bump-2022.12.0 2022-12-14 16:37:39 +13:00
Jesse Hills
cb520c00a5 Merge pull request #4185 from esphome/bump-2022.12.0b6
2022.12.0b6
2022-12-14 12:24:25 +13:00
Jesse Hills
2f24138345 Bump version to 2022.12.0b6 2022-12-14 12:03:03 +13:00
Jesse Hills
96512b80cc Revert camera config change for esp-idf (#4182) 2022-12-14 12:03:03 +13:00
Jesse Hills
fcb9b51978 Remove warnings when falling through switch cases on purpose (#4181) 2022-12-14 12:03:03 +13:00
Jesse Hills
f408f1a368 Merge pull request #4180 from esphome/bump-2022.12.0b5
2022.12.0b5
2022-12-13 19:42:18 +13:00
Jesse Hills
7d8d563c62 Bump version to 2022.12.0b5 2022-12-13 13:58:44 +13:00
J. Nick Koston
0a1f705fda Speed up bluetooth proxy connections when using esp-idf (#4171) 2022-12-13 13:58:44 +13:00
Jesse Hills
1952c1880b Remove internal pin restriction from cd74hc4067 (#4179) 2022-12-13 13:58:44 +13:00
Jesse Hills
b03967dac1 Merge pull request #4178 from esphome/bump-2022.12.0b4
2022.12.0b4
2022-12-13 10:14:08 +13:00
Jesse Hills
bcae2596a6 Bump version to 2022.12.0b4 2022-12-13 09:13:28 +13:00
Jesse Hills
fc0347c86c Bump esphome-dashboard to 20221213.0 (#4176) 2022-12-13 09:13:28 +13:00
Jesse Hills
d9563d4de1 Merge pull request #4174 from esphome/bump-2022.12.0b3
2022.12.0b3
2022-12-12 17:31:44 +13:00
Jesse Hills
cc7e2bf8db Bump version to 2022.12.0b3 2022-12-12 17:19:12 +13:00
Jesse Hills
5d98e2923b Increase watchdog timeout when starting OTA (#4172) 2022-12-12 17:19:12 +13:00
Jesse Hills
07197d12f6 Merge pull request #4163 from esphome/bump-2022.12.0b2
2022.12.0b2
2022-12-08 14:04:20 +13:00
Jesse Hills
7b0a298497 Bump version to 2022.12.0b2 2022-12-08 13:42:25 +13:00
Jesse Hills
21679cf2ba Fix ble parsing with zero padded advertisements (#4162) 2022-12-08 13:42:24 +13:00
Jesse Hills
4be7cd12a1 Merge pull request #4157 from esphome/bump-2022.12.0b1
2022.12.0b1
2022-12-07 17:25:12 +13:00
Jesse Hills
dee4d0ccb7 Bump version to 2022.12.0b1 2022-12-07 17:00:10 +13:00
Jesse Hills
c6885c1bf4 Bump esphome-dashboard to 20221207.0 (#4156) 2022-12-07 16:47:45 +13:00
dependabot[bot]
8b8efb57af Bump aioesphomeapi from 12.2.1 to 13.0.1 (#4149)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-07 16:16:32 +13:00
dependabot[bot]
499e120aa4 Bump dessant/lock-threads from 3 to 4 (#4150)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-07 16:10:43 +13:00
dependabot[bot]
6f198a4736 Bump pyupgrade from 3.2.2 to 3.3.0 (#4137)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2022-12-07 16:09:21 +13:00
dependabot[bot]
f500f448b1 Bump pytest-asyncio from 0.20.1 to 0.20.2 (#4019)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-07 16:08:26 +13:00
Jesse Hills
6ad9baa870 Add API for dashboard to get boards list (#4154) 2022-12-07 16:07:51 +13:00
Jesse Hills
f843925301 ESP32 IDF: Override toolchain-esp32ulp with espressifs own published version (#4155) 2022-12-07 16:01:26 +13:00
pistifonok
4a3b628946 Fixed deep sleep for ESP32C3 (#4143)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2022-12-07 15:59:25 +13:00
Jesse Hills
4ffdc38cf5 Add sn74hc165 input shift register (#4151) 2022-12-07 12:10:25 +13:00
Dennis
f83f1bff19 Invalid config for waveshare models with no full_update_every (#4066)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2022-12-07 11:53:20 +13:00
Jesse Hills
9370ff3dfa Allow dashboard import to pull complete file from github (#3982) 2022-12-07 07:29:56 +13:00
Jesse Hills
2053b02c61 Add reports fahrenheit to tuya climate (#4032) 2022-12-07 07:29:18 +13:00
Jesse Hills
f34e797a0d Change 4 chip limit on sn74hc595 to 256 (#4108) 2022-12-07 07:23:07 +13:00
Samuel Sieb
30a2fc1273 fix switch initialization (#4153)
Co-authored-by: Samuel Sieb <samuel@sieb.net>
fixes https://github.com/esphome/issues/issues/3878
2022-12-06 23:25:19 +13:00
Matthew Schinckel
48da5ef1c4 Use ENTITY_CATEGORY_CONFIG for sprinkler config switches. (#4141)
Update esphome/components/sprinkler/__init__.py

Co-Authored-By: Keith Burzinski <kbx81x@gmail.com>

Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
2022-12-05 21:00:48 -06:00
Jesse Hills
7209dd8bae Merge pull request #4152 from esphome/bump-2022.11.5
2022.11.5
2022-12-06 13:12:57 +13:00
Jesse Hills
ab736c89bb Bump version to 2022.11.5 2022-12-06 12:52:48 +13:00
Jesse Hills
6911639617 Fix board pin alias lookup (#4147) 2022-12-06 12:52:48 +13:00
Jesse Hills
b9720d0715 Merge pull request #4130 from esphome/bump-2022.11.4
2022.11.4
2022-12-01 15:38:52 +13:00
Jesse Hills
47b3267ed4 Bump version to 2022.11.4 2022-12-01 13:47:50 +13:00
Jesse Hills
e16ba2adb5 Fix queuing scripts not compiling (#4077) 2022-12-01 13:47:50 +13:00
Nicolas Graziano
0a19b1e32c Dashboard, after login use relative url. (#4103) 2022-12-01 13:47:49 +13:00
Jesse Hills
bae9a950c0 current-based cover fix copy paste mistake (#4124) 2022-12-01 13:47:49 +13:00
Jesse Hills
72b2943332 Merge pull request #4083 from esphome/bump-2022.11.3
2022.11.3
2022-11-25 07:23:08 +13:00
Jesse Hills
4ec0ef7548 Bump version to 2022.11.3 2022-11-24 17:01:52 +13:00
Jesse Hills
25bc6761f6 Don't convert climate temperature step (#4082) 2022-11-24 17:01:52 +13:00
Brian Kaufman
81b6562c25 Fix units for refresh: never (#4048) 2022-11-24 17:01:52 +13:00
Samuel Sieb
ae74189fc2 fix missing library (#4051) 2022-11-24 17:01:51 +13:00
Jesse Hills
9e516efe10 Merge pull request #4074 from esphome/bump-2022.11.2
2022.11.2
2022-11-23 16:06:34 +13:00
Jesse Hills
366e29439e Bump version to 2022.11.2 2022-11-23 13:04:21 +13:00
J. Nick Koston
1c9c700d7f Avoid creating a new espbt::ESPBTUUID each loop when registering for notify (#4069) 2022-11-23 13:04:21 +13:00
J. Nick Koston
b2e6b9d31f Avoid 128bit uuid loop for 16/32 bit uuids (#4068) 2022-11-23 13:04:21 +13:00
Jesse Hills
7623f63846 rp2040_pwm frequency is per pair of pins (#4061) 2022-11-23 13:04:21 +13:00
Jesse Hills
2bfaf9dce3 Update web_server index (#4060) 2022-11-23 13:04:20 +13:00
Jesse Hills
5c2c1560bb Fix rp2040 pwm to use pico-sdk, not mbed (#4059) 2022-11-23 13:04:20 +13:00
Jesse Hills
f7096ab78e Merge pull request #4041 from esphome/bump-2022.11.1
2022.11.1
2022-11-17 15:40:51 +13:00
Jesse Hills
98f8feb625 Bump version to 2022.11.1 2022-11-17 13:52:15 +13:00
Jesse Hills
9944ca414e Support ADC on RP2040 (#4040) 2022-11-17 13:52:15 +13:00
49 changed files with 1510 additions and 355 deletions

View File

@@ -18,7 +18,7 @@ jobs:
lock:
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v3
- uses: dessant/lock-threads@v4
with:
pr-inactive-days: "1"
pr-lock-reason: ""

View File

@@ -27,7 +27,7 @@ repos:
- --branch=release
- --branch=beta
- repo: https://github.com/asottile/pyupgrade
rev: v3.2.2
rev: v3.3.0
hooks:
- id: pyupgrade
args: [--py39-plus]

View File

@@ -208,6 +208,7 @@ esphome/components/sim800l/* @glmnet
esphome/components/sm2135/* @BoukeHaarsma23
esphome/components/sml/* @alengwenus
esphome/components/smt100/* @piechade
esphome/components/sn74hc165/* @jesserockz
esphome/components/socket/* @esphome/core
esphome/components/sonoff_d1/* @anatoly-savchenkov
esphome/components/spi/* @esphome/core

View File

@@ -12,6 +12,9 @@ FROM debian:bullseye-20221024-slim AS base-docker
FROM base-${BASEIMGTYPE} AS base
ARG TARGETARCH
ARG TARGETVARIANT
RUN \
apt-get update \
# Use pinned versions so that we get updates with build caching
@@ -36,6 +39,14 @@ ENV \
# Store globally installed pio libs in /piolibs
PLATFORMIO_GLOBALLIB_DIR=/piolibs
# Support legacy binaries on Debian multiarch system. There is no "correct" way
# to do this, other than using properly built toolchains...
# See: https://unix.stackexchange.com/questions/553743/correct-way-to-add-lib-ld-linux-so-3-in-debian
RUN \
if [ "$TARGETARCH$TARGETVARIANT" = "armv7" ]; then \
ln -s /lib/arm-linux-gnueabihf/ld-linux.so.3 /lib/ld-linux.so.3; \
fi
RUN \
# Ubuntu python3-pip is missing wheel
pip3 install --no-cache-dir \

View File

@@ -2,11 +2,13 @@ from esphome.components import esp32_ble_tracker, esp32_ble_client
import esphome.config_validation as cv
import esphome.codegen as cg
from esphome.const import CONF_ACTIVE, CONF_ID
from esphome.components.esp32 import add_idf_sdkconfig_option
AUTO_LOAD = ["esp32_ble_client", "esp32_ble_tracker"]
DEPENDENCIES = ["api", "esp32"]
CODEOWNERS = ["@jesserockz"]
CONF_CACHE_SERVICES = "cache_services"
CONF_CONNECTIONS = "connections"
MAX_CONNECTIONS = 3
@@ -47,6 +49,9 @@ CONFIG_SCHEMA = cv.All(
{
cv.GenerateID(): cv.declare_id(BluetoothProxy),
cv.Optional(CONF_ACTIVE, default=False): cv.boolean,
cv.SplitDefault(CONF_CACHE_SERVICES, esp32_idf=True): cv.All(
cv.only_with_esp_idf, cv.boolean
),
cv.Optional(CONF_CONNECTIONS): cv.All(
cv.ensure_list(CONNECTION_SCHEMA),
cv.Length(min=1, max=MAX_CONNECTIONS),
@@ -72,4 +77,7 @@ async def to_code(config):
cg.add(var.register_connection(connection_var))
await esp32_ble_tracker.register_client(connection_var, connection_conf)
if config.get(CONF_CACHE_SERVICES):
add_idf_sdkconfig_option("CONFIG_BT_GATTC_CACHE_NVS_FLASH", True)
cg.add_define("USE_BLUETOOTH_PROXY")

View File

@@ -27,10 +27,10 @@ DEFAULT_DELAY = "2ms"
CONFIG_SCHEMA = cv.Schema(
{
cv.GenerateID(): cv.declare_id(CD74HC4067Component),
cv.Required(CONF_PIN_S0): pins.internal_gpio_output_pin_schema,
cv.Required(CONF_PIN_S1): pins.internal_gpio_output_pin_schema,
cv.Required(CONF_PIN_S2): pins.internal_gpio_output_pin_schema,
cv.Required(CONF_PIN_S3): pins.internal_gpio_output_pin_schema,
cv.Required(CONF_PIN_S0): pins.gpio_output_pin_schema,
cv.Required(CONF_PIN_S1): pins.gpio_output_pin_schema,
cv.Required(CONF_PIN_S2): pins.gpio_output_pin_schema,
cv.Required(CONF_PIN_S3): pins.gpio_output_pin_schema,
cv.Optional(
CONF_DELAY, default=DEFAULT_DELAY
): cv.positive_time_period_milliseconds,

View File

@@ -19,22 +19,22 @@ class CD74HC4067Component : public Component {
void activate_pin(uint8_t pin);
/// set the pin connected to multiplexer control pin 0
void set_pin_s0(InternalGPIOPin *pin) { this->pin_s0_ = pin; }
void set_pin_s0(GPIOPin *pin) { this->pin_s0_ = pin; }
/// set the pin connected to multiplexer control pin 1
void set_pin_s1(InternalGPIOPin *pin) { this->pin_s1_ = pin; }
void set_pin_s1(GPIOPin *pin) { this->pin_s1_ = pin; }
/// set the pin connected to multiplexer control pin 2
void set_pin_s2(InternalGPIOPin *pin) { this->pin_s2_ = pin; }
void set_pin_s2(GPIOPin *pin) { this->pin_s2_ = pin; }
/// set the pin connected to multiplexer control pin 3
void set_pin_s3(InternalGPIOPin *pin) { this->pin_s3_ = pin; }
void set_pin_s3(GPIOPin *pin) { this->pin_s3_ = pin; }
/// set the delay needed after an input switch
void set_switch_delay(uint32_t switch_delay) { this->switch_delay_ = switch_delay; }
private:
InternalGPIOPin *pin_s0_;
InternalGPIOPin *pin_s1_;
InternalGPIOPin *pin_s2_;
InternalGPIOPin *pin_s3_;
GPIOPin *pin_s0_;
GPIOPin *pin_s1_;
GPIOPin *pin_s2_;
GPIOPin *pin_s3_;
/// the currently active pin
uint8_t active_pin_;
uint32_t switch_delay_;

View File

@@ -251,7 +251,7 @@ bool DallasTemperatureSensor::check_scratch_pad() {
config_validity = ((this->scratch_pad_[4] & 0x10) == 0x10);
}
#ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
#ifdef ESPHOME_LOG_LEVEL_VERY_VERBOSE
ESP_LOGVV(TAG, "Scratch pad: %02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X (%02X)", this->scratch_pad_[0],
this->scratch_pad_[1], this->scratch_pad_[2], this->scratch_pad_[3], this->scratch_pad_[4],
this->scratch_pad_[5], this->scratch_pad_[6], this->scratch_pad_[7], this->scratch_pad_[8],

View File

@@ -1,11 +1,13 @@
from pathlib import Path
import requests
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components.packages import validate_source_shorthand
from esphome.const import CONF_WIFI
from esphome.const import CONF_WIFI, CONF_REF
from esphome.wizard import wizard_file
from esphome.yaml_util import dump
from esphome import git
dashboard_import_ns = cg.esphome_ns.namespace("dashboard_import")
@@ -19,16 +21,32 @@ CODEOWNERS = ["@esphome/core"]
def validate_import_url(value):
value = cv.string_strict(value)
value = cv.Length(max=255)(value)
# ignore result, only check if it's a valid shorthand
validate_source_shorthand(value)
return value
def validate_full_url(config):
if not config[CONF_IMPORT_FULL_CONFIG]:
return config
source = validate_source_shorthand(config[CONF_PACKAGE_IMPORT_URL])
if CONF_REF not in source:
raise cv.Invalid(
"Must specify a ref (branch or tag) to import from when importing full config"
)
return config
CONF_PACKAGE_IMPORT_URL = "package_import_url"
CONFIG_SCHEMA = cv.Schema(
{
cv.Required(CONF_PACKAGE_IMPORT_URL): validate_import_url,
}
CONF_IMPORT_FULL_CONFIG = "import_full_config"
CONFIG_SCHEMA = cv.All(
cv.Schema(
{
cv.Required(CONF_PACKAGE_IMPORT_URL): validate_import_url,
cv.Optional(CONF_IMPORT_FULL_CONFIG, default=False): cv.boolean,
}
),
validate_full_url,
)
WIFI_CONFIG = """
@@ -41,7 +59,10 @@ wifi:
async def to_code(config):
cg.add_define("USE_DASHBOARD_IMPORT")
cg.add(dashboard_import_ns.set_package_import_url(config[CONF_PACKAGE_IMPORT_URL]))
url = config[CONF_PACKAGE_IMPORT_URL]
if config[CONF_IMPORT_FULL_CONFIG]:
url += "?full_config"
cg.add(dashboard_import_ns.set_package_import_url(url))
def import_config(
@@ -64,17 +85,30 @@ def import_config(
encoding="utf8",
)
else:
config = {
"substitutions": {"name": name},
"packages": {project_name: import_url},
"esphome": {
"name": "${name}",
"name_add_mac_suffix": False,
},
}
output = dump(config)
git_file = git.GitFile.from_shorthand(import_url)
if network == CONF_WIFI:
output += WIFI_CONFIG
if git_file.query and "full_config" in git_file.query:
url = git_file.raw_url
try:
req = requests.get(url, timeout=30)
req.raise_for_status()
except requests.exceptions.RequestException as e:
raise ValueError(f"Error while fetching {url}: {e}") from e
p.write_text(output, encoding="utf8")
p.write_text(req.text, encoding="utf8")
else:
config = {
"substitutions": {"name": name},
"packages": {project_name: import_url},
"esphome": {
"name": "${name}",
"name_add_mac_suffix": False,
},
}
output = dump(config)
if network == CONF_WIFI:
output += WIFI_CONFIG
p.write_text(output, encoding="utf8")

View File

@@ -147,7 +147,7 @@ void DeepSleepComponent::begin_sleep(bool manual) {
if (this->wakeup_pin_mode_ == WAKEUP_PIN_MODE_INVERT_WAKEUP && this->wakeup_pin_->digital_read()) {
level = !level;
}
esp_deep_sleep_enable_gpio_wakeup(gpio_num_t(this->wakeup_pin_->get_pin()),
esp_deep_sleep_enable_gpio_wakeup(1 << this->wakeup_pin_->get_pin(),
static_cast<esp_deepsleep_gpio_wake_up_mode_t>(level));
}
#endif

View File

@@ -33,7 +33,7 @@ from .const import ( # noqa
VARIANT_FRIENDLY,
VARIANTS,
)
from .boards import BOARD_TO_VARIANT
from .boards import BOARDS
# force import gpio to register pin schema
from .gpio import esp32_pin_to_code # noqa
@@ -230,14 +230,14 @@ def _parse_platform_version(value):
def _detect_variant(value):
if CONF_VARIANT not in value:
board = value[CONF_BOARD]
if board not in BOARD_TO_VARIANT:
if board not in BOARDS:
raise cv.Invalid(
"This board is unknown, please set the variant manually",
path=[CONF_BOARD],
)
value = value.copy()
value[CONF_VARIANT] = BOARD_TO_VARIANT[board]
value[CONF_VARIANT] = BOARDS[board][KEY_VARIANT]
return value
@@ -327,6 +327,11 @@ async def to_code(config):
"platform_packages",
[f"platformio/framework-espidf @ {conf[CONF_SOURCE]}"],
)
# platformio/toolchain-esp32ulp does not support linux_aarch64 yet and has not been updated for over 2 years
# This is espressif's own published version which is more up to date.
cg.add_platformio_option(
"platform_packages", ["espressif/toolchain-esp32ulp @ 2.35.0-20220830"]
)
add_idf_sdkconfig_option("CONFIG_PARTITION_TABLE_SINGLE_APP", False)
add_idf_sdkconfig_option("CONFIG_PARTITION_TABLE_CUSTOM", True)
add_idf_sdkconfig_option(
@@ -393,11 +398,11 @@ spiffs, data, spiffs, 0x391000, 0x00F000
IDF_PARTITIONS_CSV = """\
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, , 0x4000,
otadata, data, ota, , 0x2000,
phy_init, data, phy, , 0x1000,
app0, app, ota_0, , 0x1C0000,
app1, app, ota_1, , 0x1C0000,
nvs, data, nvs, , 0x6d000,
"""

View File

@@ -1066,197 +1066,738 @@ ESP32_BOARD_PINS = {
}
"""
BOARD_TO_VARIANT generated with:
BOARDS generated with:
git clone https://github.com/platformio/platform-espressif32
for x in platform-espressif32/boards/*.json; do
mcu=$(jq -r .build.mcu <"$x");
name=$(jq -r .name <"$x");
fname=$(basename "$x")
board="${fname%.*}"
variant=$(echo "$mcu" | tr '[:lower:]' '[:upper:]')
echo " \"$board\": VARIANT_${variant},"
echo " \"$board\": {\"name\": \"$name\", \"variant\": VARIANT_${variant},},"
done | sort
"""
BOARD_TO_VARIANT = {
"adafruit_feather_esp32s2_tft": VARIANT_ESP32S2,
"adafruit_feather_esp32s3_nopsram": VARIANT_ESP32S3,
"adafruit_feather_esp32s3_tft": VARIANT_ESP32S3,
"adafruit_feather_esp32s3": VARIANT_ESP32S3,
"adafruit_feather_esp32_v2": VARIANT_ESP32,
"adafruit_funhouse_esp32s2": VARIANT_ESP32S2,
"adafruit_itsybitsy_esp32": VARIANT_ESP32,
"adafruit_magtag29_esp32s2": VARIANT_ESP32S2,
"adafruit_metro_esp32s2": VARIANT_ESP32S2,
"adafruit_qtpy_esp32c3": VARIANT_ESP32C3,
"adafruit_qtpy_esp32s2": VARIANT_ESP32S2,
"adafruit_qtpy_esp32s3_nopsram": VARIANT_ESP32S3,
"adafruit_qtpy_esp32": VARIANT_ESP32,
"airm2m_core_esp32c3": VARIANT_ESP32C3,
"alksesp32": VARIANT_ESP32,
"atmegazero_esp32s2": VARIANT_ESP32S2,
"az-delivery-devkit-v4": VARIANT_ESP32,
"bee_motion_mini": VARIANT_ESP32C3,
"bee_motion_s3": VARIANT_ESP32S3,
"bee_motion": VARIANT_ESP32S2,
"bee_s3": VARIANT_ESP32S3,
"bpi-bit": VARIANT_ESP32,
"briki_abc_esp32": VARIANT_ESP32,
"briki_mbc-wb_esp32": VARIANT_ESP32,
"cnrs_aw2eth": VARIANT_ESP32,
"connaxio_espoir": VARIANT_ESP32,
"d-duino-32": VARIANT_ESP32,
"deneyapkart1A": VARIANT_ESP32,
"deneyapkartg": VARIANT_ESP32C3,
"deneyapkart": VARIANT_ESP32,
"deneyapmini": VARIANT_ESP32S2,
"denky32": VARIANT_ESP32,
"denky_d4": VARIANT_ESP32,
"dfrobot_beetle_esp32c3": VARIANT_ESP32C3,
"dfrobot_firebeetle2_esp32s3": VARIANT_ESP32S3,
"dpu_esp32": VARIANT_ESP32,
"esp320": VARIANT_ESP32,
"esp32-c3-devkitm-1": VARIANT_ESP32C3,
"esp32cam": VARIANT_ESP32,
"esp32-devkitlipo": VARIANT_ESP32,
"esp32dev": VARIANT_ESP32,
"esp32doit-devkit-v1": VARIANT_ESP32,
"esp32doit-espduino": VARIANT_ESP32,
"esp32-evb": VARIANT_ESP32,
"esp32-gateway": VARIANT_ESP32,
"esp32-poe-iso": VARIANT_ESP32,
"esp32-poe": VARIANT_ESP32,
"esp32-pro": VARIANT_ESP32,
"esp32-s2-franzininho": VARIANT_ESP32S2,
"esp32-s2-kaluga-1": VARIANT_ESP32S2,
"esp32-s2-saola-1": VARIANT_ESP32S2,
"esp32s3box": VARIANT_ESP32S3,
"esp32s3camlcd": VARIANT_ESP32S3,
"esp32-s3-devkitc-1": VARIANT_ESP32S3,
"esp32thing_plus": VARIANT_ESP32,
"esp32thing": VARIANT_ESP32,
"esp32vn-iot-uno": VARIANT_ESP32,
"espea32": VARIANT_ESP32,
"espectro32": VARIANT_ESP32,
"espino32": VARIANT_ESP32,
"esp-wrover-kit": VARIANT_ESP32,
"etboard": VARIANT_ESP32,
"featheresp32-s2": VARIANT_ESP32S2,
"featheresp32": VARIANT_ESP32,
"firebeetle32": VARIANT_ESP32,
"fm-devkit": VARIANT_ESP32,
"franzininho_wifi_esp32s2": VARIANT_ESP32S2,
"franzininho_wifi_msc_esp32s2": VARIANT_ESP32S2,
"frogboard": VARIANT_ESP32,
"healthypi4": VARIANT_ESP32,
"heltec_wifi_kit_32_v2": VARIANT_ESP32,
"heltec_wifi_kit_32": VARIANT_ESP32,
"heltec_wifi_lora_32_V2": VARIANT_ESP32,
"heltec_wifi_lora_32": VARIANT_ESP32,
"heltec_wireless_stick_lite": VARIANT_ESP32,
"heltec_wireless_stick": VARIANT_ESP32,
"honeylemon": VARIANT_ESP32,
"hornbill32dev": VARIANT_ESP32,
"hornbill32minima": VARIANT_ESP32,
"imbrios-logsens-v1p1": VARIANT_ESP32,
"inex_openkb": VARIANT_ESP32,
"intorobot": VARIANT_ESP32,
"iotaap_magnolia": VARIANT_ESP32,
"iotbusio": VARIANT_ESP32,
"iotbusproteus": VARIANT_ESP32,
"kb32-ft": VARIANT_ESP32,
"kits-edu": VARIANT_ESP32,
"labplus_mpython": VARIANT_ESP32,
"lionbit": VARIANT_ESP32,
"lolin32_lite": VARIANT_ESP32,
"lolin32": VARIANT_ESP32,
"lolin_c3_mini": VARIANT_ESP32C3,
"lolin_d32_pro": VARIANT_ESP32,
"lolin_d32": VARIANT_ESP32,
"lolin_s2_mini": VARIANT_ESP32S2,
"lolin_s2_pico": VARIANT_ESP32S2,
"lolin_s3": VARIANT_ESP32S3,
"lopy4": VARIANT_ESP32,
"lopy": VARIANT_ESP32,
"m5stack-atom": VARIANT_ESP32,
"m5stack-core2": VARIANT_ESP32,
"m5stack-core-esp32": VARIANT_ESP32,
"m5stack-coreink": VARIANT_ESP32,
"m5stack-fire": VARIANT_ESP32,
"m5stack-grey": VARIANT_ESP32,
"m5stack-station": VARIANT_ESP32,
"m5stack-timer-cam": VARIANT_ESP32,
"m5stick-c": VARIANT_ESP32,
"magicbit": VARIANT_ESP32,
"mgbot-iotik32a": VARIANT_ESP32,
"mgbot-iotik32b": VARIANT_ESP32,
"mhetesp32devkit": VARIANT_ESP32,
"mhetesp32minikit": VARIANT_ESP32,
"microduino-core-esp32": VARIANT_ESP32,
"micros2": VARIANT_ESP32S2,
"minimain_esp32s2": VARIANT_ESP32S2,
"nano32": VARIANT_ESP32,
"nina_w10": VARIANT_ESP32,
"node32s": VARIANT_ESP32,
"nodemcu-32s2": VARIANT_ESP32S2,
"nodemcu-32s": VARIANT_ESP32,
"nscreen-32": VARIANT_ESP32,
"odroid_esp32": VARIANT_ESP32,
"onehorse32dev": VARIANT_ESP32,
"oroca_edubot": VARIANT_ESP32,
"pico32": VARIANT_ESP32,
"piranha_esp32": VARIANT_ESP32,
"pocket_32": VARIANT_ESP32,
"pycom_gpy": VARIANT_ESP32,
"qchip": VARIANT_ESP32,
"quantum": VARIANT_ESP32,
"seeed_xiao_esp32c3": VARIANT_ESP32C3,
"sensesiot_weizen": VARIANT_ESP32,
"sg-o_airMon": VARIANT_ESP32,
"s_odi_ultra": VARIANT_ESP32,
"sparkfun_esp32_iot_redboard": VARIANT_ESP32,
"sparkfun_esp32micromod": VARIANT_ESP32,
"sparkfun_esp32s2_thing_plus_c": VARIANT_ESP32,
"sparkfun_esp32s2_thing_plus": VARIANT_ESP32S2,
"sparkfun_lora_gateway_1-channel": VARIANT_ESP32,
"tamc_termod_s3": VARIANT_ESP32S3,
"tinypico": VARIANT_ESP32,
"trueverit-iot-driver-mk2": VARIANT_ESP32,
"trueverit-iot-driver-mk3": VARIANT_ESP32,
"trueverit-iot-driver": VARIANT_ESP32,
"ttgo-lora32-v1": VARIANT_ESP32,
"ttgo-lora32-v21": VARIANT_ESP32,
"ttgo-lora32-v2": VARIANT_ESP32,
"ttgo-t1": VARIANT_ESP32,
"ttgo-t7-v13-mini32": VARIANT_ESP32,
"ttgo-t7-v14-mini32": VARIANT_ESP32,
"ttgo-t-beam": VARIANT_ESP32,
"ttgo-t-oi-plus": VARIANT_ESP32C3,
"ttgo-t-watch": VARIANT_ESP32,
"turta_iot_node": VARIANT_ESP32,
"um_feathers2_neo": VARIANT_ESP32S2,
"um_feathers2": VARIANT_ESP32S2,
"um_feathers3": VARIANT_ESP32S3,
"um_pros3": VARIANT_ESP32S3,
"um_rmp": VARIANT_ESP32S2,
"um_tinys2": VARIANT_ESP32S2,
"um_tinys3": VARIANT_ESP32S3,
"unphone7": VARIANT_ESP32,
"unphone8": VARIANT_ESP32S3,
"unphone9": VARIANT_ESP32S3,
"upesy_wroom": VARIANT_ESP32,
"upesy_wrover": VARIANT_ESP32,
"vintlabs-devkit-v1": VARIANT_ESP32,
"watchy": VARIANT_ESP32,
"wemosbat": VARIANT_ESP32,
"wemos_d1_mini32": VARIANT_ESP32,
"wemos_d1_uno32": VARIANT_ESP32,
"wesp32": VARIANT_ESP32,
"widora-air": VARIANT_ESP32,
"wifiduino32c3": VARIANT_ESP32C3,
"wifiduino32s3": VARIANT_ESP32S3,
"wifiduino32": VARIANT_ESP32,
"wipy3": VARIANT_ESP32,
"wt32-eth01": VARIANT_ESP32,
"xinabox_cw02": VARIANT_ESP32,
BOARDS = {
"adafruit_feather_esp32s2_tft": {
"name": "Adafruit Feather ESP32-S2 TFT",
"variant": VARIANT_ESP32S2,
},
"adafruit_feather_esp32s3": {
"name": "Adafruit Feather ESP32-S3 2MB PSRAM",
"variant": VARIANT_ESP32S3,
},
"adafruit_feather_esp32s3_nopsram": {
"name": "Adafruit Feather ESP32-S3 No PSRAM",
"variant": VARIANT_ESP32S3,
},
"adafruit_feather_esp32s3_tft": {
"name": "Adafruit Feather ESP32-S3 TFT",
"variant": VARIANT_ESP32S3,
},
"adafruit_feather_esp32_v2": {
"name": "Adafruit Feather ESP32 V2",
"variant": VARIANT_ESP32,
},
"adafruit_funhouse_esp32s2": {
"name": "Adafruit FunHouse",
"variant": VARIANT_ESP32S2,
},
"adafruit_itsybitsy_esp32": {
"name": "Adafruit ItsyBitsy ESP32",
"variant": VARIANT_ESP32,
},
"adafruit_magtag29_esp32s2": {
"name": "Adafruit MagTag 2.9",
"variant": VARIANT_ESP32S2,
},
"adafruit_metro_esp32s2": {
"name": "Adafruit Metro ESP32-S2",
"variant": VARIANT_ESP32S2,
},
"adafruit_qtpy_esp32c3": {
"name": "Adafruit QT Py ESP32-C3",
"variant": VARIANT_ESP32C3,
},
"adafruit_qtpy_esp32": {
"name": "Adafruit QT Py ESP32",
"variant": VARIANT_ESP32,
},
"adafruit_qtpy_esp32s2": {
"name": "Adafruit QT Py ESP32-S2",
"variant": VARIANT_ESP32S2,
},
"adafruit_qtpy_esp32s3_nopsram": {
"name": "Adafruit QT Py ESP32-S3 No PSRAM",
"variant": VARIANT_ESP32S3,
},
"airm2m_core_esp32c3": {
"name": "AirM2M CORE ESP32C3",
"variant": VARIANT_ESP32C3,
},
"alksesp32": {
"name": "ALKS ESP32",
"variant": VARIANT_ESP32,
},
"atmegazero_esp32s2": {
"name": "EspinalLab ATMegaZero ESP32-S2",
"variant": VARIANT_ESP32S2,
},
"az-delivery-devkit-v4": {
"name": "AZ-Delivery ESP-32 Dev Kit C V4",
"variant": VARIANT_ESP32,
},
"bee_motion_mini": {
"name": "Smart Bee Motion Mini",
"variant": VARIANT_ESP32C3,
},
"bee_motion": {
"name": "Smart Bee Motion",
"variant": VARIANT_ESP32S2,
},
"bee_motion_s3": {
"name": "Smart Bee Motion S3",
"variant": VARIANT_ESP32S3,
},
"bee_s3": {
"name": "Smart Bee S3",
"variant": VARIANT_ESP32S3,
},
"bpi-bit": {
"name": "BPI-Bit",
"variant": VARIANT_ESP32,
},
"briki_abc_esp32": {
"name": "Briki ABC (MBC-WB) - ESP32",
"variant": VARIANT_ESP32,
},
"briki_mbc-wb_esp32": {
"name": "Briki MBC-WB - ESP32",
"variant": VARIANT_ESP32,
},
"cnrs_aw2eth": {
"name": "CNRS AW2ETH",
"variant": VARIANT_ESP32,
},
"connaxio_espoir": {
"name": "Connaxio's Espoir",
"variant": VARIANT_ESP32,
},
"d-duino-32": {
"name": "D-duino-32",
"variant": VARIANT_ESP32,
},
"deneyapkart1A": {
"name": "Deneyap Kart 1A",
"variant": VARIANT_ESP32,
},
"deneyapkartg": {
"name": "Deneyap Kart G",
"variant": VARIANT_ESP32C3,
},
"deneyapkart": {
"name": "Deneyap Kart",
"variant": VARIANT_ESP32,
},
"deneyapmini": {
"name": "Deneyap Mini",
"variant": VARIANT_ESP32S2,
},
"denky32": {
"name": "Denky32 (WROOM32)",
"variant": VARIANT_ESP32,
},
"denky_d4": {
"name": "Denky D4 (PICO-V3-02)",
"variant": VARIANT_ESP32,
},
"dfrobot_beetle_esp32c3": {
"name": "DFRobot Beetle ESP32-C3",
"variant": VARIANT_ESP32C3,
},
"dfrobot_firebeetle2_esp32s3": {
"name": "DFRobot Firebeetle 2 ESP32-S3",
"variant": VARIANT_ESP32S3,
},
"dpu_esp32": {
"name": "TAMC DPU ESP32",
"variant": VARIANT_ESP32,
},
"esp320": {
"name": "Electronic SweetPeas ESP320",
"variant": VARIANT_ESP32,
},
"esp32-c3-devkitm-1": {
"name": "Espressif ESP32-C3-DevKitM-1",
"variant": VARIANT_ESP32C3,
},
"esp32cam": {
"name": "AI Thinker ESP32-CAM",
"variant": VARIANT_ESP32,
},
"esp32-devkitlipo": {
"name": "OLIMEX ESP32-DevKit-LiPo",
"variant": VARIANT_ESP32,
},
"esp32dev": {
"name": "Espressif ESP32 Dev Module",
"variant": VARIANT_ESP32,
},
"esp32doit-devkit-v1": {
"name": "DOIT ESP32 DEVKIT V1",
"variant": VARIANT_ESP32,
},
"esp32doit-espduino": {
"name": "DOIT ESPduino32",
"variant": VARIANT_ESP32,
},
"esp32-evb": {
"name": "OLIMEX ESP32-EVB",
"variant": VARIANT_ESP32,
},
"esp32-gateway": {
"name": "OLIMEX ESP32-GATEWAY",
"variant": VARIANT_ESP32,
},
"esp32-poe-iso": {
"name": "OLIMEX ESP32-PoE-ISO",
"variant": VARIANT_ESP32,
},
"esp32-poe": {
"name": "OLIMEX ESP32-PoE",
"variant": VARIANT_ESP32,
},
"esp32-pro": {
"name": "OLIMEX ESP32-PRO",
"variant": VARIANT_ESP32,
},
"esp32-s2-franzininho": {
"name": "Franzininho WiFi Board",
"variant": VARIANT_ESP32S2,
},
"esp32-s2-kaluga-1": {
"name": "Espressif ESP32-S2-Kaluga-1 Kit",
"variant": VARIANT_ESP32S2,
},
"esp32-s2-saola-1": {
"name": "Espressif ESP32-S2-Saola-1",
"variant": VARIANT_ESP32S2,
},
"esp32s3box": {
"name": "Espressif ESP32-S3-Box",
"variant": VARIANT_ESP32S3,
},
"esp32s3camlcd": {
"name": "ESP32S3 CAM LCD",
"variant": VARIANT_ESP32S3,
},
"esp32-s3-devkitc-1": {
"name": "Espressif ESP32-S3-DevKitC-1-N8 (8 MB QD, No PSRAM)",
"variant": VARIANT_ESP32S3,
},
"esp32thing": {
"name": "SparkFun ESP32 Thing",
"variant": VARIANT_ESP32,
},
"esp32thing_plus": {
"name": "SparkFun ESP32 Thing Plus",
"variant": VARIANT_ESP32,
},
"esp32vn-iot-uno": {
"name": "ESP32vn IoT Uno",
"variant": VARIANT_ESP32,
},
"espea32": {
"name": "April Brother ESPea32",
"variant": VARIANT_ESP32,
},
"espectro32": {
"name": "ESPectro32",
"variant": VARIANT_ESP32,
},
"espino32": {
"name": "ESPino32",
"variant": VARIANT_ESP32,
},
"esp-wrover-kit": {
"name": "Espressif ESP-WROVER-KIT",
"variant": VARIANT_ESP32,
},
"etboard": {
"name": "ETBoard",
"variant": VARIANT_ESP32,
},
"featheresp32": {
"name": "Adafruit ESP32 Feather",
"variant": VARIANT_ESP32,
},
"featheresp32-s2": {
"name": "Adafruit ESP32-S2 Feather Development Board",
"variant": VARIANT_ESP32S2,
},
"firebeetle32": {
"name": "FireBeetle-ESP32",
"variant": VARIANT_ESP32,
},
"fm-devkit": {
"name": "ESP32 FM DevKit",
"variant": VARIANT_ESP32,
},
"franzininho_wifi_esp32s2": {
"name": "Franzininho WiFi",
"variant": VARIANT_ESP32S2,
},
"franzininho_wifi_msc_esp32s2": {
"name": "Franzininho WiFi MSC",
"variant": VARIANT_ESP32S2,
},
"frogboard": {
"name": "Frog Board ESP32",
"variant": VARIANT_ESP32,
},
"healthypi4": {
"name": "ProtoCentral HealthyPi 4",
"variant": VARIANT_ESP32,
},
"heltec_wifi_kit_32": {
"name": "Heltec WiFi Kit 32",
"variant": VARIANT_ESP32,
},
"heltec_wifi_kit_32_v2": {
"name": "Heltec WiFi Kit 32 (V2)",
"variant": VARIANT_ESP32,
},
"heltec_wifi_lora_32": {
"name": "Heltec WiFi LoRa 32",
"variant": VARIANT_ESP32,
},
"heltec_wifi_lora_32_V2": {
"name": "Heltec WiFi LoRa 32 (V2)",
"variant": VARIANT_ESP32,
},
"heltec_wireless_stick_lite": {
"name": "Heltec Wireless Stick Lite",
"variant": VARIANT_ESP32,
},
"heltec_wireless_stick": {
"name": "Heltec Wireless Stick",
"variant": VARIANT_ESP32,
},
"honeylemon": {
"name": "HONEYLemon",
"variant": VARIANT_ESP32,
},
"hornbill32dev": {
"name": "Hornbill ESP32 Dev",
"variant": VARIANT_ESP32,
},
"hornbill32minima": {
"name": "Hornbill ESP32 Minima",
"variant": VARIANT_ESP32,
},
"imbrios-logsens-v1p1": {
"name": "Imbrios LogSens V1P1",
"variant": VARIANT_ESP32,
},
"inex_openkb": {
"name": "INEX OpenKB",
"variant": VARIANT_ESP32,
},
"intorobot": {
"name": "IntoRobot Fig",
"variant": VARIANT_ESP32,
},
"iotaap_magnolia": {
"name": "IoTaaP Magnolia",
"variant": VARIANT_ESP32,
},
"iotbusio": {
"name": "oddWires IoT-Bus Io",
"variant": VARIANT_ESP32,
},
"iotbusproteus": {
"name": "oddWires IoT-Bus Proteus",
"variant": VARIANT_ESP32,
},
"kb32-ft": {
"name": "MakerAsia KB32-FT",
"variant": VARIANT_ESP32,
},
"kits-edu": {
"name": "KITS ESP32 EDU",
"variant": VARIANT_ESP32,
},
"labplus_mpython": {
"name": "Labplus mPython",
"variant": VARIANT_ESP32,
},
"lionbit": {
"name": "Lion:Bit Dev Board",
"variant": VARIANT_ESP32,
},
"lolin32_lite": {
"name": "WEMOS LOLIN32 Lite",
"variant": VARIANT_ESP32,
},
"lolin32": {
"name": "WEMOS LOLIN32",
"variant": VARIANT_ESP32,
},
"lolin_c3_mini": {
"name": "WEMOS LOLIN C3 Mini",
"variant": VARIANT_ESP32C3,
},
"lolin_d32": {
"name": "WEMOS LOLIN D32",
"variant": VARIANT_ESP32,
},
"lolin_d32_pro": {
"name": "WEMOS LOLIN D32 PRO",
"variant": VARIANT_ESP32,
},
"lolin_s2_mini": {
"name": "WEMOS LOLIN S2 Mini",
"variant": VARIANT_ESP32S2,
},
"lolin_s2_pico": {
"name": "WEMOS LOLIN S2 PICO",
"variant": VARIANT_ESP32S2,
},
"lolin_s3": {
"name": "WEMOS LOLIN S3",
"variant": VARIANT_ESP32S3,
},
"lopy4": {
"name": "Pycom LoPy4",
"variant": VARIANT_ESP32,
},
"lopy": {
"name": "Pycom LoPy",
"variant": VARIANT_ESP32,
},
"m5stack-atom": {
"name": "M5Stack-ATOM",
"variant": VARIANT_ESP32,
},
"m5stack-core2": {
"name": "M5Stack Core2",
"variant": VARIANT_ESP32,
},
"m5stack-core-esp32": {
"name": "M5Stack Core ESP32",
"variant": VARIANT_ESP32,
},
"m5stack-coreink": {
"name": "M5Stack-Core Ink",
"variant": VARIANT_ESP32,
},
"m5stack-fire": {
"name": "M5Stack FIRE",
"variant": VARIANT_ESP32,
},
"m5stack-grey": {
"name": "M5Stack GREY ESP32",
"variant": VARIANT_ESP32,
},
"m5stack-station": {
"name": "M5Stack Station",
"variant": VARIANT_ESP32,
},
"m5stack-timer-cam": {
"name": "M5Stack Timer CAM",
"variant": VARIANT_ESP32,
},
"m5stick-c": {
"name": "M5Stick-C",
"variant": VARIANT_ESP32,
},
"magicbit": {
"name": "MagicBit",
"variant": VARIANT_ESP32,
},
"mgbot-iotik32a": {
"name": "MGBOT IOTIK 32A",
"variant": VARIANT_ESP32,
},
"mgbot-iotik32b": {
"name": "MGBOT IOTIK 32B",
"variant": VARIANT_ESP32,
},
"mhetesp32devkit": {
"name": "MH ET LIVE ESP32DevKIT",
"variant": VARIANT_ESP32,
},
"mhetesp32minikit": {
"name": "MH ET LIVE ESP32MiniKit",
"variant": VARIANT_ESP32,
},
"microduino-core-esp32": {
"name": "Microduino Core ESP32",
"variant": VARIANT_ESP32,
},
"micros2": {
"name": "microS2",
"variant": VARIANT_ESP32S2,
},
"minimain_esp32s2": {
"name": "Deparment of Alchemy MiniMain ESP32-S2",
"variant": VARIANT_ESP32S2,
},
"nano32": {
"name": "MakerAsia Nano32",
"variant": VARIANT_ESP32,
},
"nina_w10": {
"name": "u-blox NINA-W10 series",
"variant": VARIANT_ESP32,
},
"node32s": {
"name": "Node32s",
"variant": VARIANT_ESP32,
},
"nodemcu-32s2": {
"name": "Ai-Thinker NodeMCU-32S2 (ESP-12K)",
"variant": VARIANT_ESP32S2,
},
"nodemcu-32s": {
"name": "NodeMCU-32S",
"variant": VARIANT_ESP32,
},
"nscreen-32": {
"name": "YeaCreate NSCREEN-32",
"variant": VARIANT_ESP32,
},
"odroid_esp32": {
"name": "ODROID-GO",
"variant": VARIANT_ESP32,
},
"onehorse32dev": {
"name": "Onehorse ESP32 Dev Module",
"variant": VARIANT_ESP32,
},
"oroca_edubot": {
"name": "OROCA EduBot",
"variant": VARIANT_ESP32,
},
"pico32": {
"name": "ESP32 Pico Kit",
"variant": VARIANT_ESP32,
},
"piranha_esp32": {
"name": "Fishino Piranha ESP-32",
"variant": VARIANT_ESP32,
},
"pocket_32": {
"name": "Dongsen Tech Pocket 32",
"variant": VARIANT_ESP32,
},
"pycom_gpy": {
"name": "Pycom GPy",
"variant": VARIANT_ESP32,
},
"qchip": {
"name": "Qchip",
"variant": VARIANT_ESP32,
},
"quantum": {
"name": "Noduino Quantum",
"variant": VARIANT_ESP32,
},
"seeed_xiao_esp32c3": {
"name": "Seeed Studio XIAO ESP32C3",
"variant": VARIANT_ESP32C3,
},
"sensesiot_weizen": {
"name": "LOGISENSES Senses Weizen",
"variant": VARIANT_ESP32,
},
"sg-o_airMon": {
"name": "SG-O AirMon",
"variant": VARIANT_ESP32,
},
"s_odi_ultra": {
"name": "S.ODI Ultra v1",
"variant": VARIANT_ESP32,
},
"sparkfun_esp32_iot_redboard": {
"name": "SparkFun ESP32 IoT RedBoard",
"variant": VARIANT_ESP32,
},
"sparkfun_esp32micromod": {
"name": "SparkFun ESP32 MicroMod",
"variant": VARIANT_ESP32,
},
"sparkfun_esp32s2_thing_plus_c": {
"name": "SparkFun ESP32 Thing Plus C",
"variant": VARIANT_ESP32,
},
"sparkfun_esp32s2_thing_plus": {
"name": "SparkFun ESP32-S2 Thing Plus",
"variant": VARIANT_ESP32S2,
},
"sparkfun_lora_gateway_1-channel": {
"name": "SparkFun LoRa Gateway 1-Channel",
"variant": VARIANT_ESP32,
},
"tamc_termod_s3": {
"name": "TAMC Termod S3",
"variant": VARIANT_ESP32S3,
},
"tinypico": {
"name": "Unexpected Maker TinyPICO",
"variant": VARIANT_ESP32,
},
"trueverit-iot-driver-mk2": {
"name": "Trueverit ESP32 Universal IoT Driver MK II",
"variant": VARIANT_ESP32,
},
"trueverit-iot-driver-mk3": {
"name": "Trueverit ESP32 Universal IoT Driver MK III",
"variant": VARIANT_ESP32,
},
"trueverit-iot-driver": {
"name": "Trueverit ESP32 Universal IoT Driver",
"variant": VARIANT_ESP32,
},
"ttgo-lora32-v1": {
"name": "TTGO LoRa32-OLED V1",
"variant": VARIANT_ESP32,
},
"ttgo-lora32-v21": {
"name": "TTGO LoRa32-OLED v2.1.6",
"variant": VARIANT_ESP32,
},
"ttgo-lora32-v2": {
"name": "TTGO LoRa32-OLED V2",
"variant": VARIANT_ESP32,
},
"ttgo-t1": {
"name": "TTGO T1",
"variant": VARIANT_ESP32,
},
"ttgo-t7-v13-mini32": {
"name": "TTGO T7 V1.3 Mini32",
"variant": VARIANT_ESP32,
},
"ttgo-t7-v14-mini32": {
"name": "TTGO T7 V1.4 Mini32",
"variant": VARIANT_ESP32,
},
"ttgo-t-beam": {
"name": "TTGO T-Beam",
"variant": VARIANT_ESP32,
},
"ttgo-t-oi-plus": {
"name": "TTGO T-OI PLUS RISC-V ESP32-C3",
"variant": VARIANT_ESP32C3,
},
"ttgo-t-watch": {
"name": "TTGO T-Watch",
"variant": VARIANT_ESP32,
},
"turta_iot_node": {
"name": "Turta IoT Node",
"variant": VARIANT_ESP32,
},
"um_feathers2": {
"name": "Unexpected Maker FeatherS2",
"variant": VARIANT_ESP32S2,
},
"um_feathers2_neo": {
"name": "Unexpected Maker FeatherS2 Neo",
"variant": VARIANT_ESP32S2,
},
"um_feathers3": {
"name": "Unexpected Maker FeatherS3",
"variant": VARIANT_ESP32S3,
},
"um_pros3": {
"name": "Unexpected Maker PROS3",
"variant": VARIANT_ESP32S3,
},
"um_rmp": {
"name": "Unexpected Maker RMP",
"variant": VARIANT_ESP32S2,
},
"um_tinys2": {
"name": "Unexpected Maker TinyS2",
"variant": VARIANT_ESP32S2,
},
"um_tinys3": {
"name": "Unexpected Maker TinyS3",
"variant": VARIANT_ESP32S3,
},
"unphone7": {
"name": "unPhone 7",
"variant": VARIANT_ESP32,
},
"unphone8": {
"name": "unPhone 8",
"variant": VARIANT_ESP32S3,
},
"unphone9": {
"name": "unPhone 9",
"variant": VARIANT_ESP32S3,
},
"upesy_wroom": {
"name": "uPesy ESP32 Wroom DevKit",
"variant": VARIANT_ESP32,
},
"upesy_wrover": {
"name": "uPesy ESP32 Wrover DevKit",
"variant": VARIANT_ESP32,
},
"vintlabs-devkit-v1": {
"name": "VintLabs ESP32 Devkit",
"variant": VARIANT_ESP32,
},
"watchy": {
"name": "SQFMI Watchy v2.0",
"variant": VARIANT_ESP32,
},
"wemosbat": {
"name": "WeMos WiFi and Bluetooth Battery",
"variant": VARIANT_ESP32,
},
"wemos_d1_mini32": {
"name": "WEMOS D1 MINI ESP32",
"variant": VARIANT_ESP32,
},
"wemos_d1_uno32": {
"name": "WEMOS D1 R32",
"variant": VARIANT_ESP32,
},
"wesp32": {
"name": "Silicognition wESP32",
"variant": VARIANT_ESP32,
},
"widora-air": {
"name": "Widora AIR",
"variant": VARIANT_ESP32,
},
"wifiduino32c3": {
"name": "Blinker WiFiduinoV2 (ESP32-C3)",
"variant": VARIANT_ESP32C3,
},
"wifiduino32": {
"name": "Blinker WiFiduino32",
"variant": VARIANT_ESP32,
},
"wifiduino32s3": {
"name": "Blinker WiFiduino32S3",
"variant": VARIANT_ESP32S3,
},
"wipy3": {
"name": "Pycom WiPy3",
"variant": VARIANT_ESP32,
},
"wt32-eth01": {
"name": "Wireless-Tag WT32-ETH01 Ethernet Module",
"variant": VARIANT_ESP32,
},
"xinabox_cw02": {
"name": "XinaBox CW02",
"variant": VARIANT_ESP32,
},
}

View File

@@ -95,7 +95,7 @@ void ESP32InternalGPIOPin::pin_mode(gpio::Flags flags) {
// can't call gpio_config here because that logs in esp-idf which may cause issues
gpio_set_direction(pin_, flags_to_mode(flags));
gpio_pull_mode_t pull_mode = GPIO_FLOATING;
if (flags & (gpio::FLAG_PULLUP | gpio::FLAG_PULLDOWN)) {
if ((flags & gpio::FLAG_PULLUP) && (flags & gpio::FLAG_PULLDOWN)) {
pull_mode = GPIO_PULLUP_PULLDOWN;
} else if (flags & gpio::FLAG_PULLUP) {
pull_mode = GPIO_PULLUP_ONLY;
@@ -128,7 +128,7 @@ void IRAM_ATTR ISRInternalGPIOPin::pin_mode(gpio::Flags flags) {
auto *arg = reinterpret_cast<ISRPinArg *>(arg_);
gpio_set_direction(arg->pin, flags_to_mode(flags));
gpio_pull_mode_t pull_mode = GPIO_FLOATING;
if (flags & (gpio::FLAG_PULLUP | gpio::FLAG_PULLDOWN)) {
if ((flags & gpio::FLAG_PULLUP) && (flags & gpio::FLAG_PULLDOWN)) {
pull_mode = GPIO_PULLUP_PULLDOWN;
} else if (flags & gpio::FLAG_PULLUP) {
pull_mode = GPIO_PULLUP_ONLY;

View File

@@ -2,12 +2,14 @@ import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.const import CONF_ID
from esphome.core import CORE
from esphome.components.esp32 import add_idf_sdkconfig_option
from esphome.components.esp32 import add_idf_sdkconfig_option, get_esp32_variant, const
DEPENDENCIES = ["esp32"]
CODEOWNERS = ["@jesserockz"]
CONFLICTS_WITH = ["esp32_ble_tracker", "esp32_ble_beacon"]
NO_BLUTOOTH_VARIANTS = [const.VARIANT_ESP32S2]
esp32_ble_ns = cg.esphome_ns.namespace("esp32_ble")
ESP32BLE = esp32_ble_ns.class_("ESP32BLE", cg.Component)
@@ -19,6 +21,15 @@ CONFIG_SCHEMA = cv.Schema(
).extend(cv.COMPONENT_SCHEMA)
def validate_variant(_):
variant = get_esp32_variant()
if variant in NO_BLUTOOTH_VARIANTS:
raise cv.Invalid(f"{variant} does not support Bluetooth")
FINAL_VALIDATE_SCHEMA = validate_variant
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)

View File

@@ -3,6 +3,7 @@ import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_TYPE, CONF_UUID, CONF_TX_POWER
from esphome.core import CORE, TimePeriod
from esphome.components.esp32 import add_idf_sdkconfig_option
from esphome.components import esp32_ble
DEPENDENCIES = ["esp32"]
CONFLICTS_WITH = ["esp32_ble_tracker"]
@@ -54,6 +55,8 @@ CONFIG_SCHEMA = cv.All(
validate_config,
)
FINAL_VALIDATE_SCHEMA = esp32_ble.validate_variant
async def to_code(config):
uuid = config[CONF_UUID].hex

View File

@@ -95,7 +95,9 @@ void BLEClientBase::release_services() {
for (auto &svc : this->services_)
delete svc; // NOLINT(cppcoreguidelines-owning-memory)
this->services_.clear();
#ifndef CONFIG_BT_GATTC_CACHE_NVS_FLASH
esp_ble_gattc_cache_clean(this->remote_bda_);
#endif
}
bool BLEClientBase::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t esp_gattc_if,
@@ -130,16 +132,16 @@ bool BLEClientBase::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
this->set_state(espbt::ClientState::IDLE);
break;
}
if (this->connection_type_ == espbt::ConnectionType::V3_WITH_CACHE) {
this->set_state(espbt::ClientState::CONNECTED);
this->state_ = espbt::ClientState::ESTABLISHED;
break;
}
auto ret = esp_ble_gattc_send_mtu_req(this->gattc_if_, param->open.conn_id);
if (ret) {
ESP_LOGW(TAG, "[%d] [%s] esp_ble_gattc_send_mtu_req failed, status=%x", this->connection_index_,
this->address_str_.c_str(), ret);
}
if (this->connection_type_ == espbt::ConnectionType::V3_WITH_CACHE) {
this->set_state(espbt::ClientState::CONNECTED);
this->state_ = espbt::ClientState::ESTABLISHED;
break;
}
esp_ble_gattc_search_service(esp_gattc_if, param->cfg_mtu.conn_id, nullptr);
break;
}
@@ -288,14 +290,17 @@ float BLEClientBase::parse_char_value(uint8_t *value, uint16_t length) {
if (length > 2) {
return (float) encode_uint16(value[1], value[2]);
}
// fall through
case 0x7: // uint24.
if (length > 3) {
return (float) encode_uint24(value[1], value[2], value[3]);
}
// fall through
case 0x8: // uint32.
if (length > 4) {
return (float) encode_uint32(value[1], value[2], value[3], value[4]);
}
// fall through
case 0xC: // int8.
return (float) ((int8_t) value[1]);
case 0xD: // int12.
@@ -303,10 +308,12 @@ float BLEClientBase::parse_char_value(uint8_t *value, uint16_t length) {
if (length > 2) {
return (float) ((int16_t)(value[1] << 8) + (int16_t) value[2]);
}
// fall through
case 0xF: // int24.
if (length > 3) {
return (float) ((int32_t)(value[1] << 16) + (int32_t)(value[2] << 8) + (int32_t)(value[3]));
}
// fall through
case 0x10: // int32.
if (length > 4) {
return (float) ((int32_t)(value[1] << 24) + (int32_t)(value[2] << 16) + (int32_t)(value[3] << 8) +

View File

@@ -17,6 +17,7 @@ from esphome.const import (
)
from esphome.core import CORE
from esphome.components.esp32 import add_idf_sdkconfig_option
from esphome.components import esp32_ble
DEPENDENCIES = ["esp32"]
@@ -187,6 +188,8 @@ CONFIG_SCHEMA = cv.Schema(
}
).extend(cv.COMPONENT_SCHEMA)
FINAL_VALIDATE_SCHEMA = esp32_ble.validate_variant
ESP_BLE_DEVICE_SCHEMA = cv.Schema(
{
cv.GenerateID(CONF_ESP32_BLE_ID): cv.use_id(ESP32BLETracker),

View File

@@ -705,8 +705,9 @@ void ESPBTDevice::parse_adv_(const esp_ble_gap_cb_param_t::ble_scan_result_evt_p
while (offset + 2 < len) {
const uint8_t field_length = payload[offset++]; // First byte is length of adv record
if (field_length == 0)
break;
if (field_length == 0) {
continue; // Possible zero padded advertisement data
}
// first byte of adv record is adv record type
const uint8_t record_type = payload[offset++];

View File

@@ -54,7 +54,11 @@ void ESP32Camera::dump_config() {
ESP_LOGCONFIG(TAG, " HREF Pin: %d", conf.pin_href);
ESP_LOGCONFIG(TAG, " Pixel Clock Pin: %d", conf.pin_pclk);
ESP_LOGCONFIG(TAG, " External Clock: Pin:%d Frequency:%u", conf.pin_xclk, conf.xclk_freq_hz);
#ifdef USE_ESP_IDF // Temporary until the espressif/esp32-camera library is updated
ESP_LOGCONFIG(TAG, " I2C Pins: SDA:%d SCL:%d", conf.pin_sscb_sda, conf.pin_sscb_scl);
#else
ESP_LOGCONFIG(TAG, " I2C Pins: SDA:%d SCL:%d", conf.pin_sccb_sda, conf.pin_sccb_scl);
#endif
ESP_LOGCONFIG(TAG, " Reset Pin: %d", conf.pin_reset);
switch (this->config_.frame_size) {
case FRAMESIZE_QQVGA:
@@ -209,8 +213,13 @@ void ESP32Camera::set_external_clock(uint8_t pin, uint32_t frequency) {
this->config_.xclk_freq_hz = frequency;
}
void ESP32Camera::set_i2c_pins(uint8_t sda, uint8_t scl) {
#ifdef USE_ESP_IDF // Temporary until the espressif/esp32-camera library is updated
this->config_.pin_sscb_sda = sda;
this->config_.pin_sscb_scl = scl;
#else
this->config_.pin_sccb_sda = sda;
this->config_.pin_sccb_scl = scl;
#endif
}
void ESP32Camera::set_reset_pin(uint8_t pin) { this->config_.pin_reset = pin; }
void ESP32Camera::set_power_down_pin(uint8_t pin) { this->config_.pin_pwdn = pin; }

View File

@@ -22,10 +22,11 @@ from .const import (
CONF_EARLY_PIN_INIT,
KEY_BOARD,
KEY_ESP8266,
KEY_FLASH_SIZE,
KEY_PIN_INITIAL_STATES,
esp8266_ns,
)
from .boards import ESP8266_FLASH_SIZES, ESP8266_LD_SCRIPTS
from .boards import BOARDS, ESP8266_LD_SCRIPTS
from .gpio import PinInitialState, add_pin_initial_states_array
@@ -218,8 +219,8 @@ async def to_code(config):
cg.RawExpression(f"VERSION_CODE({ver.major}, {ver.minor}, {ver.patch})"),
)
if config[CONF_BOARD] in ESP8266_FLASH_SIZES:
flash_size = ESP8266_FLASH_SIZES[config[CONF_BOARD]]
if config[CONF_BOARD] in BOARDS:
flash_size = BOARDS[config[CONF_BOARD]][KEY_FLASH_SIZE]
ld_scripts = ESP8266_LD_SCRIPTS[flash_size]
if ver <= cv.Version(2, 3, 0):

View File

@@ -4,50 +4,6 @@ FLASH_SIZE_2_MB = 2 * FLASH_SIZE_1_MB
FLASH_SIZE_4_MB = 4 * FLASH_SIZE_1_MB
FLASH_SIZE_16_MB = 16 * FLASH_SIZE_1_MB
ESP8266_FLASH_SIZES = {
"d1": FLASH_SIZE_4_MB,
"d1_mini": FLASH_SIZE_4_MB,
"d1_mini_lite": FLASH_SIZE_1_MB,
"d1_mini_pro": FLASH_SIZE_16_MB,
"esp01": FLASH_SIZE_512_KB,
"esp01_1m": FLASH_SIZE_1_MB,
"esp07": FLASH_SIZE_4_MB,
"esp12e": FLASH_SIZE_4_MB,
"esp210": FLASH_SIZE_4_MB,
"esp8285": FLASH_SIZE_1_MB,
"esp_wroom_02": FLASH_SIZE_2_MB,
"espduino": FLASH_SIZE_4_MB,
"espectro": FLASH_SIZE_4_MB,
"espino": FLASH_SIZE_4_MB,
"espinotee": FLASH_SIZE_4_MB,
"espmxdevkit": FLASH_SIZE_1_MB,
"espresso_lite_v1": FLASH_SIZE_4_MB,
"espresso_lite_v2": FLASH_SIZE_4_MB,
"gen4iod": FLASH_SIZE_512_KB,
"heltec_wifi_kit_8": FLASH_SIZE_4_MB,
"huzzah": FLASH_SIZE_4_MB,
"inventone": FLASH_SIZE_4_MB,
"modwifi": FLASH_SIZE_2_MB,
"nodemcu": FLASH_SIZE_4_MB,
"nodemcuv2": FLASH_SIZE_4_MB,
"oak": FLASH_SIZE_4_MB,
"phoenix_v1": FLASH_SIZE_4_MB,
"phoenix_v2": FLASH_SIZE_4_MB,
"sonoff_basic": FLASH_SIZE_1_MB,
"sonoff_s20": FLASH_SIZE_1_MB,
"sonoff_sv": FLASH_SIZE_1_MB,
"sonoff_th": FLASH_SIZE_1_MB,
"sparkfunBlynk": FLASH_SIZE_4_MB,
"thing": FLASH_SIZE_512_KB,
"thingdev": FLASH_SIZE_512_KB,
"wifi_slot": FLASH_SIZE_1_MB,
"wifiduino": FLASH_SIZE_4_MB,
"wifinfo": FLASH_SIZE_1_MB,
"wio_link": FLASH_SIZE_4_MB,
"wio_node": FLASH_SIZE_4_MB,
"xinabox_cw01": FLASH_SIZE_4_MB,
}
ESP8266_LD_SCRIPTS = {
FLASH_SIZE_512_KB: ("eagle.flash.512k0.ld", "eagle.flash.512k.ld"),
FLASH_SIZE_1_MB: ("eagle.flash.1m0.ld", "eagle.flash.1m.ld"),
@@ -206,3 +162,201 @@ ESP8266_BOARD_PINS = {
"wio_node": {"LED": 2, "GROVE": 15, "D0": 3, "D1": 5, "BUTTON": 0},
"xinabox_cw01": {"SDA": 2, "SCL": 14, "LED": 5, "LED_RED": 12, "LED_GREEN": 13},
}
"""
BOARDS generate with:
git clone https://github.com/platformio/platform-espressif8266
for x in platform-espressif8266/boards/*.json; do
max_size=$(jq -r .upload.maximum_size <"$x")
name=$(jq -r .name <"$x")
fname=$(basename "$x")
board="${fname%.*}"
size_mb=$((max_size / (1024 * 1024)))
if [[ $size_mb -gt 0 ]]; then
size="${size_mb}_MB"
else
size="${$((max_size / 1024))}_KB"
fi
echo " \"$board\": {\"name\": \"$name\", \"flash_size\": FLASH_SIZE_$size,},"
done | sort
"""
BOARDS = {
"agruminolemon": {
"name": "Lifely Agrumino Lemon v4",
"flash_size": FLASH_SIZE_4_MB,
},
"d1_mini_lite": {
"name": "WeMos D1 mini Lite",
"flash_size": FLASH_SIZE_1_MB,
},
"d1_mini": {
"name": "WeMos D1 R2 and mini",
"flash_size": FLASH_SIZE_4_MB,
},
"d1_mini_pro": {
"name": "WeMos D1 mini Pro",
"flash_size": FLASH_SIZE_16_MB,
},
"d1": {
"name": "WEMOS D1 R1",
"flash_size": FLASH_SIZE_4_MB,
},
"eduinowifi": {
"name": "Schirmilabs Eduino WiFi",
"flash_size": FLASH_SIZE_4_MB,
},
"esp01_1m": {
"name": "Espressif Generic ESP8266 ESP-01 1M",
"flash_size": FLASH_SIZE_1_MB,
},
"esp01": {
"name": "Espressif Generic ESP8266 ESP-01 512k",
"flash_size": FLASH_SIZE_512_KB,
},
"esp07": {
"name": "Espressif Generic ESP8266 ESP-07 1MB",
"flash_size": FLASH_SIZE_1_MB,
},
"esp07s": {
"name": "Espressif Generic ESP8266 ESP-07S",
"flash_size": FLASH_SIZE_4_MB,
},
"esp12e": {
"name": "Espressif ESP8266 ESP-12E",
"flash_size": FLASH_SIZE_4_MB,
},
"esp210": {
"name": "SweetPea ESP-210",
"flash_size": FLASH_SIZE_4_MB,
},
"esp8285": {
"name": "Generic ESP8285 Module",
"flash_size": FLASH_SIZE_1_MB,
},
"espduino": {
"name": "ESPDuino (ESP-13 Module)",
"flash_size": FLASH_SIZE_4_MB,
},
"espectro": {
"name": "ESPectro Core",
"flash_size": FLASH_SIZE_4_MB,
},
"espino": {
"name": "ESPino",
"flash_size": FLASH_SIZE_4_MB,
},
"espinotee": {
"name": "ThaiEasyElec ESPino",
"flash_size": FLASH_SIZE_4_MB,
},
"espmxdevkit": {
"name": "ESP-Mx DevKit (ESP8285)",
"flash_size": FLASH_SIZE_1_MB,
},
"espresso_lite_v1": {
"name": "ESPresso Lite 1.0",
"flash_size": FLASH_SIZE_4_MB,
},
"espresso_lite_v2": {
"name": "ESPresso Lite 2.0",
"flash_size": FLASH_SIZE_4_MB,
},
"esp_wroom_02": {
"name": "ESP-WROOM-02",
"flash_size": FLASH_SIZE_2_MB,
},
"gen4iod": {
"name": "4D Systems gen4 IoD Range",
"flash_size": FLASH_SIZE_512_KB,
},
"heltec_wifi_kit_8": {
"name": "Heltec Wifi kit 8",
"flash_size": FLASH_SIZE_4_MB,
},
"huzzah": {
"name": "Adafruit HUZZAH ESP8266",
"flash_size": FLASH_SIZE_4_MB,
},
"inventone": {
"name": "Invent One",
"flash_size": FLASH_SIZE_4_MB,
},
"modwifi": {
"name": "Olimex MOD-WIFI-ESP8266(-DEV)",
"flash_size": FLASH_SIZE_2_MB,
},
"nodemcu": {
"name": "NodeMCU 0.9 (ESP-12 Module)",
"flash_size": FLASH_SIZE_4_MB,
},
"nodemcuv2": {
"name": "NodeMCU 1.0 (ESP-12E Module)",
"flash_size": FLASH_SIZE_4_MB,
},
"oak": {
"name": "DigiStump Oak",
"flash_size": FLASH_SIZE_4_MB,
},
"phoenix_v1": {
"name": "Phoenix 1.0",
"flash_size": FLASH_SIZE_4_MB,
},
"phoenix_v2": {
"name": "Phoenix 2.0",
"flash_size": FLASH_SIZE_4_MB,
},
"sonoff_basic": {
"name": "Sonoff Basic",
"flash_size": FLASH_SIZE_1_MB,
},
"sonoff_s20": {
"name": "Sonoff S20",
"flash_size": FLASH_SIZE_1_MB,
},
"sonoff_sv": {
"name": "Sonoff SV",
"flash_size": FLASH_SIZE_1_MB,
},
"sonoff_th": {
"name": "Sonoff TH",
"flash_size": FLASH_SIZE_1_MB,
},
"sparkfunBlynk": {
"name": "SparkFun Blynk Board",
"flash_size": FLASH_SIZE_4_MB,
},
"thingdev": {
"name": "SparkFun ESP8266 Thing Dev",
"flash_size": FLASH_SIZE_512_KB,
},
"thing": {
"name": "SparkFun ESP8266 Thing",
"flash_size": FLASH_SIZE_512_KB,
},
"wifiduino": {
"name": "WiFiduino",
"flash_size": FLASH_SIZE_4_MB,
},
"wifinfo": {
"name": "WifInfo",
"flash_size": FLASH_SIZE_1_MB,
},
"wifi_slot": {
"name": "WiFi Slot",
"flash_size": FLASH_SIZE_4_MB,
},
"wio_link": {
"name": "Wio Link",
"flash_size": FLASH_SIZE_4_MB,
},
"wio_node": {
"name": "Wio Node",
"flash_size": FLASH_SIZE_4_MB,
},
"xinabox_cw01": {
"name": "XinaBox CW01",
"flash_size": FLASH_SIZE_4_MB,
},
}

View File

@@ -5,6 +5,7 @@ KEY_BOARD = "board"
KEY_PIN_INITIAL_STATES = "pin_initial_states"
CONF_RESTORE_FROM_FLASH = "restore_from_flash"
CONF_EARLY_PIN_INIT = "early_pin_init"
KEY_FLASH_SIZE = "flash_size"
# esp8266 namespace is already defined by arduino, manually prefix esphome
esp8266_ns = cg.global_ns.namespace("esphome").namespace("esp8266")

View File

@@ -10,7 +10,7 @@ float GPIOSwitch::get_setup_priority() const { return setup_priority::HARDWARE;
void GPIOSwitch::setup() {
ESP_LOGCONFIG(TAG, "Setting up GPIO Switch '%s'...", this->name_.c_str());
bool initial_state = Switch::get_initial_state_with_restore_mode();
bool initial_state = this->get_initial_state_with_restore_mode().value_or(false);
// write state before setup
if (initial_state) {

View File

@@ -103,9 +103,11 @@ void I2SAudioMediaPlayer::stop_() {
void I2SAudioMediaPlayer::setup() {
ESP_LOGCONFIG(TAG, "Setting up Audio...");
#if SOC_I2S_SUPPORTS_DAC
if (this->internal_dac_mode_ != I2S_DAC_CHANNEL_DISABLE) {
this->audio_ = make_unique<Audio>(true, this->internal_dac_mode_);
} else {
#endif
this->audio_ = make_unique<Audio>(false);
this->audio_->setPinout(this->bclk_pin_, this->lrclk_pin_, this->dout_pin_);
this->audio_->forceMono(this->external_dac_channels_ == 1);
@@ -113,7 +115,9 @@ void I2SAudioMediaPlayer::setup() {
this->mute_pin_->setup();
this->mute_pin_->digital_write(false);
}
#if SOC_I2S_SUPPORTS_DAC
}
#endif
this->state = media_player::MEDIA_PLAYER_STATE_IDLE;
}
@@ -137,6 +141,7 @@ void I2SAudioMediaPlayer::dump_config() {
ESP_LOGCONFIG(TAG, "Audio failed to initialize!");
return;
}
#if SOC_I2S_SUPPORTS_DAC
if (this->internal_dac_mode_ != I2S_DAC_CHANNEL_DISABLE) {
switch (this->internal_dac_mode_) {
case I2S_DAC_CHANNEL_LEFT_EN:
@@ -152,6 +157,7 @@ void I2SAudioMediaPlayer::dump_config() {
break;
}
}
#endif
}
} // namespace i2s_audio

View File

@@ -25,7 +25,9 @@ class I2SAudioMediaPlayer : public Component, public media_player::MediaPlayer {
void set_bclk_pin(uint8_t pin) { this->bclk_pin_ = pin; }
void set_lrclk_pin(uint8_t pin) { this->lrclk_pin_ = pin; }
void set_mute_pin(GPIOPin *mute_pin) { this->mute_pin_ = mute_pin; }
#if SOC_I2S_SUPPORTS_DAC
void set_internal_dac_mode(i2s_dac_mode_t mode) { this->internal_dac_mode_ = mode; }
#endif
void set_external_dac_channels(uint8_t channels) { this->external_dac_channels_ = channels; }
media_player::MediaPlayerTraits get_traits() override;
@@ -51,7 +53,9 @@ class I2SAudioMediaPlayer : public Component, public media_player::MediaPlayer {
bool muted_{false};
float unmuted_volume_{0};
#if SOC_I2S_SUPPORTS_DAC
i2s_dac_mode_t internal_dac_mode_{I2S_DAC_CHANNEL_DISABLE};
#endif
uint8_t external_dac_channels_;
HighFrequencyLoopRequester high_freq_;

View File

@@ -1,5 +1,5 @@
import esphome.codegen as cg
from esphome.components import media_player
from esphome.components import media_player, esp32
import esphome.config_validation as cv
from esphome import pins
@@ -33,6 +33,18 @@ INTERNAL_DAC_OPTIONS = {
EXTERNAL_DAC_OPTIONS = ["mono", "stereo"]
NO_INTERNAL_DAC_VARIANTS = [esp32.const.VARIANT_ESP32S2]
def validate_esp32_variant(config):
if config[CONF_DAC_TYPE] != "internal":
return config
variant = esp32.get_esp32_variant()
if variant in NO_INTERNAL_DAC_VARIANTS:
raise cv.Invalid(f"{variant} does not have an internal DAC")
return config
CONFIG_SCHEMA = cv.All(
cv.typed_schema(
{
@@ -68,6 +80,7 @@ CONFIG_SCHEMA = cv.All(
key=CONF_DAC_TYPE,
),
cv.only_with_arduino,
validate_esp32_variant,
)

View File

@@ -1,6 +1,8 @@
#include "esphome/core/defines.h"
#ifdef USE_ESP_IDF
#include <esp_task_wdt.h>
#include "ota_backend_esp_idf.h"
#include "ota_component.h"
#include <esp_ota_ops.h>
@@ -14,7 +16,9 @@ OTAResponseTypes IDFOTABackend::begin(size_t image_size) {
if (this->partition_ == nullptr) {
return OTA_RESPONSE_ERROR_NO_UPDATE_PARTITION;
}
esp_task_wdt_init(15, false); // The following function takes longer than the 5 seconds timeout of WDT
esp_err_t err = esp_ota_begin(this->partition_, image_size, &this->update_handle_);
esp_task_wdt_init(CONFIG_ESP_TASK_WDT_TIMEOUT_S, false); // Set the WDT back to the configured timeout
if (err != ESP_OK) {
esp_ota_abort(this->update_handle_);
this->update_handle_ = 0;

View File

@@ -10,7 +10,7 @@ void OutputSwitch::dump_config() { LOG_SWITCH("", "Output Switch", this); }
void OutputSwitch::setup() {
ESP_LOGCONFIG(TAG, "Setting up Output Switch '%s'...", this->name_.c_str());
bool initial_state = Switch::get_initial_state_with_restore_mode();
bool initial_state = this->get_initial_state_with_restore_mode().value_or(false);
if (initial_state) {
this->turn_on();

View File

@@ -1,23 +1,22 @@
import re
from pathlib import Path
from esphome.core import EsphomeError
from esphome.config_helpers import merge_config
import esphome.config_validation as cv
from esphome import git, yaml_util
from esphome.config_helpers import merge_config
from esphome.const import (
CONF_ESPHOME,
CONF_FILE,
CONF_FILES,
CONF_MIN_VERSION,
CONF_PACKAGES,
CONF_PASSWORD,
CONF_REF,
CONF_REFRESH,
CONF_URL,
CONF_USERNAME,
CONF_PASSWORD,
__version__ as ESPHOME_VERSION,
)
import esphome.config_validation as cv
from esphome.const import __version__ as ESPHOME_VERSION
from esphome.core import EsphomeError
DOMAIN = CONF_PACKAGES
@@ -55,23 +54,15 @@ def validate_source_shorthand(value):
if not isinstance(value, str):
raise cv.Invalid("Shorthand only for strings")
m = re.match(
r"github://([a-zA-Z0-9\-]+)/([a-zA-Z0-9\-\._]+)/([a-zA-Z0-9\-_.\./]+)(?:@([a-zA-Z0-9\-_.\./]+))?",
value,
)
if m is None:
raise cv.Invalid(
"Source is not a file system path or in expected github://username/name/[sub-folder/]file-path.yml[@branch-or-tag] format!"
)
git_file = git.GitFile.from_shorthand(value)
conf = {
CONF_URL: f"https://github.com/{m.group(1)}/{m.group(2)}.git",
CONF_FILE: m.group(3),
CONF_URL: git_file.git_url,
CONF_FILE: git_file.filename,
}
if m.group(4):
conf[CONF_REF] = m.group(4)
if git_file.ref:
conf[CONF_REF] = git_file.ref
# print(conf)
return BASE_SCHEMA(conf)

View File

@@ -17,3 +17,12 @@ RP2040_BOARD_PINS = {
"SCL1": 27,
},
}
BOARDS = {
"rpipico": {
"name": "Raspberry Pi Pico",
},
"rpipicow": {
"name": "Raspberry Pi Pico W",
},
}

View File

@@ -0,0 +1,87 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import pins
from esphome.const import (
CONF_ID,
CONF_MODE,
CONF_NUMBER,
CONF_INVERTED,
CONF_DATA_PIN,
CONF_CLOCK_PIN,
CONF_INPUT,
)
CODEOWNERS = ["@jesserockz"]
DEPENDENCIES = []
MULTI_CONF = True
sn74hc165_ns = cg.esphome_ns.namespace("sn74hc165")
SN74HC165Component = sn74hc165_ns.class_("SN74HC165Component", cg.Component)
SN74HC165GPIOPin = sn74hc165_ns.class_(
"SN74HC165GPIOPin", cg.GPIOPin, cg.Parented.template(SN74HC165Component)
)
CONF_SN74HC165 = "sn74hc165"
CONF_LOAD_PIN = "load_pin"
CONF_CLOCK_INHIBIT_PIN = "clock_inhibit_pin"
CONF_SR_COUNT = "sr_count"
CONFIG_SCHEMA = cv.Schema(
{
cv.Required(CONF_ID): cv.declare_id(SN74HC165Component),
cv.Required(CONF_DATA_PIN): pins.gpio_input_pin_schema,
cv.Required(CONF_CLOCK_PIN): pins.gpio_output_pin_schema,
cv.Required(CONF_LOAD_PIN): pins.gpio_output_pin_schema,
cv.Optional(CONF_CLOCK_INHIBIT_PIN): pins.gpio_output_pin_schema,
cv.Optional(CONF_SR_COUNT, default=1): cv.int_range(min=1, max=256),
}
).extend(cv.COMPONENT_SCHEMA)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
data_pin = await cg.gpio_pin_expression(config[CONF_DATA_PIN])
cg.add(var.set_data_pin(data_pin))
clock_pin = await cg.gpio_pin_expression(config[CONF_CLOCK_PIN])
cg.add(var.set_clock_pin(clock_pin))
load_pin = await cg.gpio_pin_expression(config[CONF_LOAD_PIN])
cg.add(var.set_load_pin(load_pin))
if CONF_CLOCK_INHIBIT_PIN in config:
clock_inhibit_pin = await cg.gpio_pin_expression(config[CONF_CLOCK_INHIBIT_PIN])
cg.add(var.set_clock_inhibit_pin(clock_inhibit_pin))
cg.add(var.set_sr_count(config[CONF_SR_COUNT]))
def _validate_input_mode(value):
if value is not True:
raise cv.Invalid("Only input mode is supported")
return value
SN74HC165_PIN_SCHEMA = cv.All(
{
cv.GenerateID(): cv.declare_id(SN74HC165GPIOPin),
cv.Required(CONF_SN74HC165): cv.use_id(SN74HC165Component),
cv.Required(CONF_NUMBER): cv.int_range(min=0, max=2048, max_included=False),
cv.Optional(CONF_MODE, default={}): cv.All(
{
cv.Optional(CONF_INPUT, default=True): cv.All(
cv.boolean, _validate_input_mode
),
},
),
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
}
)
@pins.PIN_SCHEMA_REGISTRY.register(CONF_SN74HC165, SN74HC165_PIN_SCHEMA)
async def sn74hc165_pin_to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_parented(var, config[CONF_SN74HC165])
cg.add(var.set_pin(config[CONF_NUMBER]))
cg.add(var.set_inverted(config[CONF_INVERTED]))
return var

View File

@@ -0,0 +1,67 @@
#include "sn74hc165.h"
#include "esphome/core/log.h"
namespace esphome {
namespace sn74hc165 {
static const char *const TAG = "sn74hc165";
void SN74HC165Component::setup() {
ESP_LOGCONFIG(TAG, "Setting up SN74HC165...");
// initialize pins
this->clock_pin_->setup();
this->data_pin_->setup();
this->load_pin_->setup();
this->clock_pin_->digital_write(false);
this->load_pin_->digital_write(false);
if (this->clock_inhibit_pin_ != nullptr) {
this->clock_inhibit_pin_->setup();
this->clock_inhibit_pin_->digital_write(true);
}
// read state from shift register
this->read_gpio_();
}
void SN74HC165Component::loop() { this->read_gpio_(); }
void SN74HC165Component::dump_config() { ESP_LOGCONFIG(TAG, "SN74HC165:"); }
bool SN74HC165Component::digital_read_(uint16_t pin) {
if (pin >= this->sr_count_ * 8) {
ESP_LOGE(TAG, "Pin %u is out of range! Maximum pin number with %u chips in series is %u", pin, this->sr_count_,
(this->sr_count_ * 8) - 1);
return false;
}
return this->input_bits_[pin];
}
void SN74HC165Component::read_gpio_() {
this->load_pin_->digital_write(false);
delayMicroseconds(5);
this->load_pin_->digital_write(true);
delayMicroseconds(5);
if (this->clock_inhibit_pin_ != nullptr)
this->clock_inhibit_pin_->digital_write(false);
for (int16_t i = (this->sr_count_ * 8) - 1; i >= 0; i--) {
this->input_bits_[i] = this->data_pin_->digital_read();
this->clock_pin_->digital_write(true);
this->clock_pin_->digital_write(false);
}
if (this->clock_inhibit_pin_ != nullptr)
this->clock_inhibit_pin_->digital_write(true);
}
float SN74HC165Component::get_setup_priority() const { return setup_priority::IO; }
bool SN74HC165GPIOPin::digital_read() { return this->parent_->digital_read_(this->pin_); }
std::string SN74HC165GPIOPin::dump_summary() const { return str_snprintf("%u via SN74HC165", 18, pin_); }
} // namespace sn74hc165
} // namespace esphome

View File

@@ -0,0 +1,61 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/core/hal.h"
#include "esphome/core/helpers.h"
#include <vector>
namespace esphome {
namespace sn74hc165 {
class SN74HC165Component : public Component {
public:
SN74HC165Component() = default;
void setup() override;
void loop() override;
float get_setup_priority() const override;
void dump_config() override;
void set_data_pin(GPIOPin *pin) { this->data_pin_ = pin; }
void set_clock_pin(GPIOPin *pin) { this->clock_pin_ = pin; }
void set_load_pin(GPIOPin *pin) { this->load_pin_ = pin; }
void set_clock_inhibit_pin(GPIOPin *pin) { this->clock_inhibit_pin_ = pin; }
void set_sr_count(uint8_t count) {
this->sr_count_ = count;
this->input_bits_.resize(count * 8);
}
protected:
friend class SN74HC165GPIOPin;
bool digital_read_(uint16_t pin);
void read_gpio_();
GPIOPin *data_pin_;
GPIOPin *clock_pin_;
GPIOPin *load_pin_;
GPIOPin *clock_inhibit_pin_;
uint8_t sr_count_;
std::vector<bool> input_bits_;
};
/// Helper class to expose a SC74HC165 pin as an internal input GPIO pin.
class SN74HC165GPIOPin : public GPIOPin, public Parented<SN74HC165Component> {
public:
void setup() override {}
void pin_mode(gpio::Flags flags) override {}
bool digital_read() override;
void digital_write(bool value) override{};
std::string dump_summary() const override;
void set_pin(uint16_t pin) { pin_ = pin; }
void set_inverted(bool inverted) { inverted_ = inverted; }
protected:
uint16_t pin_;
bool inverted_;
};
} // namespace sn74hc165
} // namespace esphome

View File

@@ -17,7 +17,9 @@ MULTI_CONF = True
sn74hc595_ns = cg.esphome_ns.namespace("sn74hc595")
SN74HC595Component = sn74hc595_ns.class_("SN74HC595Component", cg.Component)
SN74HC595GPIOPin = sn74hc595_ns.class_("SN74HC595GPIOPin", cg.GPIOPin)
SN74HC595GPIOPin = sn74hc595_ns.class_(
"SN74HC595GPIOPin", cg.GPIOPin, cg.Parented.template(SN74HC595Component)
)
CONF_SN74HC595 = "sn74hc595"
CONF_LATCH_PIN = "latch_pin"
@@ -30,7 +32,7 @@ CONFIG_SCHEMA = cv.Schema(
cv.Required(CONF_CLOCK_PIN): pins.gpio_output_pin_schema,
cv.Required(CONF_LATCH_PIN): pins.gpio_output_pin_schema,
cv.Optional(CONF_OE_PIN): pins.gpio_output_pin_schema,
cv.Optional(CONF_SR_COUNT, default=1): cv.int_range(1, 4),
cv.Optional(CONF_SR_COUNT, default=1): cv.int_range(min=1, max=256),
}
).extend(cv.COMPONENT_SCHEMA)
@@ -60,7 +62,7 @@ SN74HC595_PIN_SCHEMA = cv.All(
{
cv.GenerateID(): cv.declare_id(SN74HC595GPIOPin),
cv.Required(CONF_SN74HC595): cv.use_id(SN74HC595Component),
cv.Required(CONF_NUMBER): cv.int_range(min=0, max=31),
cv.Required(CONF_NUMBER): cv.int_range(min=0, max=2048, max_included=False),
cv.Optional(CONF_MODE, default={}): cv.All(
{
cv.Optional(CONF_OUTPUT, default=True): cv.All(
@@ -76,10 +78,8 @@ SN74HC595_PIN_SCHEMA = cv.All(
@pins.PIN_SCHEMA_REGISTRY.register(CONF_SN74HC595, SN74HC595_PIN_SCHEMA)
async def sn74hc595_pin_to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
parent = await cg.get_variable(config[CONF_SN74HC595])
cg.add(var.set_parent(parent))
await cg.register_parented(var, config[CONF_SN74HC595])
num = config[CONF_NUMBER]
cg.add(var.set_pin(num))
cg.add(var.set_pin(config[CONF_NUMBER]))
cg.add(var.set_inverted(config[CONF_INVERTED]))
return var

View File

@@ -28,24 +28,21 @@ void SN74HC595Component::setup() {
void SN74HC595Component::dump_config() { ESP_LOGCONFIG(TAG, "SN74HC595:"); }
bool SN74HC595Component::digital_read_(uint8_t pin) { return this->output_bits_ >> pin; }
void SN74HC595Component::digital_write_(uint8_t pin, bool value) {
uint32_t mask = 1UL << pin;
this->output_bits_ &= ~mask;
if (value)
this->output_bits_ |= mask;
void SN74HC595Component::digital_write_(uint16_t pin, bool value) {
if (pin >= this->sr_count_ * 8) {
ESP_LOGE(TAG, "Pin %u is out of range! Maximum pin number with %u chips in series is %u", pin, this->sr_count_,
(this->sr_count_ * 8) - 1);
return;
}
this->output_bits_[pin] = value;
this->write_gpio_();
}
bool SN74HC595Component::write_gpio_() {
for (int i = this->sr_count_ - 1; i >= 0; i--) {
uint8_t data = (uint8_t)(this->output_bits_ >> (8 * i) & 0xff);
for (int j = 0; j < 8; j++) {
this->data_pin_->digital_write(data & (1 << (7 - j)));
this->clock_pin_->digital_write(true);
this->clock_pin_->digital_write(false);
}
void SN74HC595Component::write_gpio_() {
for (auto bit = this->output_bits_.rbegin(); bit != this->output_bits_.rend(); bit++) {
this->data_pin_->digital_write(*bit);
this->clock_pin_->digital_write(true);
this->clock_pin_->digital_write(false);
}
// pulse latch to activate new values
@@ -56,8 +53,6 @@ bool SN74HC595Component::write_gpio_() {
if (this->have_oe_pin_) {
this->oe_pin_->digital_write(false);
}
return true;
}
float SN74HC595Component::get_setup_priority() const { return setup_priority::IO; }

View File

@@ -2,6 +2,9 @@
#include "esphome/core/component.h"
#include "esphome/core/hal.h"
#include "esphome/core/helpers.h"
#include <vector>
namespace esphome {
namespace sn74hc595 {
@@ -21,13 +24,15 @@ class SN74HC595Component : public Component {
oe_pin_ = pin;
have_oe_pin_ = true;
}
void set_sr_count(uint8_t count) { sr_count_ = count; }
void set_sr_count(uint8_t count) {
sr_count_ = count;
this->output_bits_.resize(count * 8);
}
protected:
friend class SN74HC595GPIOPin;
bool digital_read_(uint8_t pin);
void digital_write_(uint8_t pin, bool value);
bool write_gpio_();
void digital_write_(uint16_t pin, bool value);
void write_gpio_();
GPIOPin *data_pin_;
GPIOPin *clock_pin_;
@@ -35,11 +40,11 @@ class SN74HC595Component : public Component {
GPIOPin *oe_pin_;
uint8_t sr_count_;
bool have_oe_pin_{false};
uint32_t output_bits_{0x00};
std::vector<bool> output_bits_;
};
/// Helper class to expose a SC74HC595 pin as an internal output GPIO pin.
class SN74HC595GPIOPin : public GPIOPin {
class SN74HC595GPIOPin : public GPIOPin, public Parented<SN74HC595Component> {
public:
void setup() override {}
void pin_mode(gpio::Flags flags) override {}
@@ -47,13 +52,11 @@ class SN74HC595GPIOPin : public GPIOPin {
void digital_write(bool value) override;
std::string dump_summary() const override;
void set_parent(SN74HC595Component *parent) { parent_ = parent; }
void set_pin(uint8_t pin) { pin_ = pin; }
void set_pin(uint16_t pin) { pin_ = pin; }
void set_inverted(bool inverted) { inverted_ = inverted; }
protected:
SN74HC595Component *parent_;
uint8_t pin_;
uint16_t pin_;
bool inverted_;
};

View File

@@ -8,6 +8,7 @@ from esphome.const import (
CONF_NAME,
CONF_REPEAT,
CONF_RUN_DURATION,
ENTITY_CATEGORY_CONFIG,
)
AUTO_LOAD = ["switch"]
@@ -223,7 +224,9 @@ SPRINKLER_ACTION_QUEUE_VALVE_SCHEMA = cv.Schema(
SPRINKLER_VALVE_SCHEMA = cv.Schema(
{
cv.Optional(CONF_ENABLE_SWITCH): cv.maybe_simple_value(
switch.switch_schema(SprinklerControllerSwitch),
switch.switch_schema(
SprinklerControllerSwitch, entity_category=ENTITY_CATEGORY_CONFIG
),
key=CONF_NAME,
),
cv.Optional(CONF_PUMP_OFF_SWITCH_ID): cv.use_id(switch.Switch),
@@ -244,7 +247,9 @@ SPRINKLER_CONTROLLER_SCHEMA = cv.Schema(
{
cv.GenerateID(): cv.declare_id(Sprinkler),
cv.Optional(CONF_AUTO_ADVANCE_SWITCH): cv.maybe_simple_value(
switch.switch_schema(SprinklerControllerSwitch),
switch.switch_schema(
SprinklerControllerSwitch, entity_category=ENTITY_CATEGORY_CONFIG
),
key=CONF_NAME,
),
cv.Optional(CONF_MAIN_SWITCH): cv.maybe_simple_value(
@@ -252,11 +257,15 @@ SPRINKLER_CONTROLLER_SCHEMA = cv.Schema(
key=CONF_NAME,
),
cv.Optional(CONF_QUEUE_ENABLE_SWITCH): cv.maybe_simple_value(
switch.switch_schema(SprinklerControllerSwitch),
switch.switch_schema(
SprinklerControllerSwitch, entity_category=ENTITY_CATEGORY_CONFIG
),
key=CONF_NAME,
),
cv.Optional(CONF_REVERSE_SWITCH): cv.maybe_simple_value(
switch.switch_schema(SprinklerControllerSwitch),
switch.switch_schema(
SprinklerControllerSwitch, entity_category=ENTITY_CATEGORY_CONFIG
),
key=CONF_NAME,
),
cv.Optional(CONF_MANUAL_SELECTION_DELAY): cv.positive_time_period_seconds,

View File

@@ -25,6 +25,7 @@ CONF_CURRENT_TEMPERATURE_MULTIPLIER = "current_temperature_multiplier"
CONF_TARGET_TEMPERATURE_MULTIPLIER = "target_temperature_multiplier"
CONF_ECO_DATAPOINT = "eco_datapoint"
CONF_ECO_TEMPERATURE = "eco_temperature"
CONF_REPORTS_FAHRENHEIT = "reports_fahrenheit"
TuyaClimate = tuya_ns.class_("TuyaClimate", climate.Climate, cg.Component)
@@ -110,6 +111,7 @@ CONFIG_SCHEMA = cv.All(
cv.Optional(CONF_TARGET_TEMPERATURE_MULTIPLIER): cv.positive_float,
cv.Optional(CONF_ECO_DATAPOINT): cv.uint8_t,
cv.Optional(CONF_ECO_TEMPERATURE): cv.temperature,
cv.Optional(CONF_REPORTS_FAHRENHEIT, default=False): cv.boolean,
}
).extend(cv.COMPONENT_SCHEMA),
cv.has_at_least_one_key(CONF_TARGET_TEMPERATURE_DATAPOINT, CONF_SWITCH_DATAPOINT),
@@ -186,3 +188,6 @@ async def to_code(config):
cg.add(var.set_eco_id(config[CONF_ECO_DATAPOINT]))
if CONF_ECO_TEMPERATURE in config:
cg.add(var.set_eco_temperature(config[CONF_ECO_TEMPERATURE]))
if config[CONF_REPORTS_FAHRENHEIT]:
cg.add(var.set_reports_fahrenheit())

View File

@@ -1,5 +1,5 @@
#include "esphome/core/log.h"
#include "tuya_climate.h"
#include "esphome/core/log.h"
namespace esphome {
namespace tuya {
@@ -44,6 +44,10 @@ void TuyaClimate::setup() {
if (this->target_temperature_id_.has_value()) {
this->parent_->register_listener(*this->target_temperature_id_, [this](const TuyaDatapoint &datapoint) {
this->manual_temperature_ = datapoint.value_int * this->target_temperature_multiplier_;
if (this->reports_fahrenheit_) {
this->manual_temperature_ = (this->manual_temperature_ - 32) * 5 / 9;
}
ESP_LOGV(TAG, "MCU reported manual target temperature is: %.1f", this->manual_temperature_);
this->compute_target_temperature_();
this->compute_state_();
@@ -53,6 +57,10 @@ void TuyaClimate::setup() {
if (this->current_temperature_id_.has_value()) {
this->parent_->register_listener(*this->current_temperature_id_, [this](const TuyaDatapoint &datapoint) {
this->current_temperature = datapoint.value_int * this->current_temperature_multiplier_;
if (this->reports_fahrenheit_) {
this->current_temperature = (this->current_temperature - 32) * 5 / 9;
}
ESP_LOGV(TAG, "MCU reported current temperature is: %.1f", this->current_temperature);
this->compute_state_();
this->publish_state();
@@ -105,7 +113,10 @@ void TuyaClimate::control(const climate::ClimateCall &call) {
}
if (call.get_target_temperature().has_value()) {
const float target_temperature = *call.get_target_temperature();
float target_temperature = *call.get_target_temperature();
if (this->reports_fahrenheit_)
target_temperature = (target_temperature * 9 / 5) + 32;
ESP_LOGV(TAG, "Setting target temperature: %.1f", target_temperature);
this->parent_->set_integer_datapoint_value(*this->target_temperature_id_,
(int) (target_temperature / this->target_temperature_multiplier_));

View File

@@ -35,6 +35,8 @@ class TuyaClimate : public climate::Climate, public Component {
void set_eco_id(uint8_t eco_id) { this->eco_id_ = eco_id; }
void set_eco_temperature(float eco_temperature) { this->eco_temperature_ = eco_temperature; }
void set_reports_fahrenheit() { this->reports_fahrenheit_ = true; }
void set_tuya_parent(Tuya *parent) { this->parent_ = parent; }
protected:
@@ -77,6 +79,7 @@ class TuyaClimate : public climate::Climate, public Component {
bool cooling_state_{false};
float manual_temperature_;
bool eco_;
bool reports_fahrenheit_{false};
};
} // namespace tuya

View File

@@ -88,13 +88,17 @@ MODELS = {
}
def validate_full_update_every_only_type_a(value):
def validate_full_update_every_only_types_ac(value):
if CONF_FULL_UPDATE_EVERY not in value:
return value
if MODELS[value[CONF_MODEL]][0] == "b":
full_models = []
for key, val in sorted(MODELS.items()):
if val[0] != "b":
full_models.append(key)
raise cv.Invalid(
"The 'full_update_every' option is only available for models "
"'1.54in', '1.54inV2', '2.13in', '2.90in', and '2.90inV2'."
+ ", ".join(full_models)
)
return value
@@ -116,7 +120,7 @@ CONFIG_SCHEMA = cv.All(
)
.extend(cv.polling_component_schema("1s"))
.extend(spi.spi_device_schema()),
validate_full_update_every_only_type_a,
validate_full_update_every_only_types_ac,
cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA),
)

View File

@@ -1,6 +1,6 @@
"""Constants used by esphome."""
__version__ = "2022.12.0-dev"
__version__ = "2022.12.4"
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
@@ -992,6 +992,7 @@ KEY_CORE = "core"
KEY_TARGET_PLATFORM = "target_platform"
KEY_TARGET_FRAMEWORK = "target_framework"
KEY_FRAMEWORK_VERSION = "framework_version"
KEY_NAME = "name"
# Entity categories
ENTITY_CATEGORY_NONE = ""

View File

@@ -416,6 +416,10 @@ class ImportRequestHandler(BaseHandler):
self.set_status(500)
self.write("File already exists")
return
except ValueError:
self.set_status(422)
self.write("Invalid package url")
return
self.set_status(200)
self.finish()
@@ -689,6 +693,24 @@ class PrometheusServiceDiscoveryHandler(BaseHandler):
self.write(json.dumps(sd))
class BoardsRequestHandler(BaseHandler):
@authenticated
def get(self):
from esphome.components.esp32.boards import BOARDS as ESP32_BOARDS
from esphome.components.esp8266.boards import BOARDS as ESP8266_BOARDS
from esphome.components.rp2040.boards import BOARDS as RP2040_BOARDS
boards = {
"esp32": {key: val[const.KEY_NAME] for key, val in ESP32_BOARDS.items()},
"esp8266": {
key: val[const.KEY_NAME] for key, val in ESP8266_BOARDS.items()
},
"rp2040": {key: val[const.KEY_NAME] for key, val in RP2040_BOARDS.items()},
}
self.set_header("content-type", "application/json")
self.write(json.dumps(boards))
class MDNSStatusThread(threading.Thread):
def run(self):
global IMPORT_RESULT
@@ -1059,6 +1081,7 @@ def make_app(debug=get_bool_env(ENV_DEV)):
(f"{rel}json-config", JsonConfigRequestHandler),
(f"{rel}rename", EsphomeRenameHandler),
(f"{rel}prometheus-sd", PrometheusServiceDiscoveryHandler),
(f"{rel}boards", BoardsRequestHandler),
],
**app_settings,
)

View File

@@ -1,14 +1,15 @@
from pathlib import Path
import subprocess
import hashlib
import logging
from typing import Callable, Optional
import re
import subprocess
import urllib.parse
from dataclasses import dataclass
from datetime import datetime
from pathlib import Path
from typing import Callable, Optional
from esphome.core import CORE, TimePeriodSeconds
import esphome.config_validation as cv
from esphome.core import CORE, TimePeriodSeconds
_LOGGER = logging.getLogger(__name__)
@@ -103,3 +104,57 @@ def clone_or_update(
return repo_dir, revert
return repo_dir, None
GIT_DOMAINS = {
"github": "github.com",
"gitlab": "gitlab.com",
}
@dataclass(frozen=True)
class GitFile:
domain: str
owner: str
repo: str
filename: str
ref: str = None
query: str = None
@property
def git_url(self) -> str:
return f"https://{self.domain}/{self.owner}/{self.repo}.git"
@property
def raw_url(self) -> str:
if self.ref is None:
raise ValueError("URL has no ref")
if self.domain == "github.com":
return f"https://raw.githubusercontent.com/{self.owner}/{self.repo}/{self.ref}/{self.filename}"
if self.domain == "gitlab.com":
return f"https://gitlab.com/{self.owner}/{self.repo}/-/raw/{self.ref}/{self.filename}"
raise NotImplementedError(f"Git domain {self.domain} not supported")
@classmethod
def from_shorthand(cls, shorthand):
"""Parse a git shorthand URL into its components."""
if not isinstance(shorthand, str):
raise ValueError("Git shorthand must be a string")
m = re.match(
r"(?P<domain>[a-zA-Z0-9\-]+)://(?P<owner>[a-zA-Z0-9\-]+)/(?P<repo>[a-zA-Z0-9\-\._]+)/(?P<filename>[a-zA-Z0-9\-_.\./]+)(?:@(?P<ref>[a-zA-Z0-9\-_.\./]+))?(?:\?(?P<query>[a-zA-Z0-9\-_.\./]+))?",
shorthand,
)
if m is None:
raise ValueError(
"URL is not in expected github://username/name/[sub-folder/]file-path.yml[@branch-or-tag] format!"
)
if m.group("domain") not in GIT_DOMAINS:
raise ValueError(f"Unknown git domain {m.group('domain')}")
return cls(
domain=GIT_DOMAINS[m.group("domain")],
owner=m.group("owner"),
repo=m.group("repo"),
filename=m.group("filename"),
ref=m.group("ref"),
query=m.group("query"),
)

View File

@@ -9,8 +9,8 @@ pyserial==3.5
platformio==6.1.5 # When updating platformio, also update Dockerfile
esptool==4.4
click==8.1.3
esphome-dashboard==20221109.0
aioesphomeapi==12.2.1
esphome-dashboard==20221213.0
aioesphomeapi==13.0.1
zeroconf==0.39.4
# esp-idf requires this, but doesn't bundle it by default

View File

@@ -1,13 +1,13 @@
pylint==2.15.8
flake8==6.0.0 # also change in .pre-commit-config.yaml when updating
black==22.10.0 # also change in .pre-commit-config.yaml when updating
pyupgrade==3.2.2 # also change in .pre-commit-config.yaml when updating
pyupgrade==3.3.0 # also change in .pre-commit-config.yaml when updating
pre-commit
# Unit tests
pytest==7.2.0
pytest-cov==4.0.0
pytest-mock==3.10.0
pytest-asyncio==0.20.1
pytest-asyncio==0.20.2
asyncmock==0.4.2
hypothesis==5.49.0

View File

@@ -245,7 +245,7 @@ def do_esp32():
setEnum(
output["esp32"]["schemas"]["CONFIG_SCHEMA"]["schema"]["config_vars"]["board"],
list(esp32_boards.BOARD_TO_VARIANT.keys()),
list(esp32_boards.BOARDS.keys()),
)

View File

@@ -381,6 +381,7 @@ climate:
target_temperature_datapoint: 3
current_temperature_multiplier: 0.5
target_temperature_multiplier: 0.5
reports_fahrenheit: true
switch:
- platform: tuya

View File

@@ -162,6 +162,11 @@ binary_sensor:
then:
- output.turn_off: Led7
- platform: gpio
id: sn74hc165_pin_0
pin:
sn74hc165: sn74hc165_hub
number: 0
@@ -542,3 +547,11 @@ text_sensor:
- ezo_pmp.arbitrary_command:
id: hcl_pump
command: D,?
sn74hc165:
id: sn74hc165_hub
data_pin: GPIO12
clock_pin: GPIO14
load_pin: GPIO27
clock_inhibit_pin: GPIO26
sr_count: 4